Commit 428e106a authored by Kirill A. Shutemov's avatar Kirill A. Shutemov Committed by Dave Hansen
Browse files

mm: Introduce untagged_addr_remote()



untagged_addr() removes tags/metadata from the address and brings it to
the canonical form. The helper is implemented on arm64 and sparc. Both of
them do untagging based on global rules.

However, Linear Address Masking (LAM) on x86 introduces per-process
settings for untagging. As a result, untagged_addr() is now only
suitable for untagging addresses for the current proccess.

The new helper untagged_addr_remote() has to be used when the address
targets remote process. It requires the mmap lock for target mm to be
taken.

Signed-off-by: default avatarKirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: default avatarDave Hansen <dave.hansen@linux.intel.com>
Acked-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Tested-by: default avatarAlexander Potapenko <glider@google.com>
Link: https://lore.kernel.org/all/20230312112612.31869-6-kirill.shutemov%40linux.intel.com
parent 82721d8b
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -8,8 +8,10 @@

#include <linux/compiler.h>
#include <linux/string.h>
#include <linux/mm_types.h>
#include <asm/asi.h>
#include <asm/spitfire.h>
#include <asm/pgtable.h>

#include <asm/processor.h>
#include <asm-generic/access_ok.h>
+1 −1
Original line number Diff line number Diff line
@@ -580,7 +580,7 @@ static int vaddr_get_pfns(struct mm_struct *mm, unsigned long vaddr,
		goto done;
	}

	vaddr = untagged_addr(vaddr);
	vaddr = untagged_addr_remote(mm, vaddr);

retry:
	vma = vma_lookup(mm, vaddr);
+7 −2
Original line number Diff line number Diff line
@@ -1689,8 +1689,13 @@ static ssize_t pagemap_read(struct file *file, char __user *buf,

	/* watch out for wraparound */
	start_vaddr = end_vaddr;
	if (svpfn <= (ULONG_MAX >> PAGE_SHIFT))
		start_vaddr = untagged_addr(svpfn << PAGE_SHIFT);
	if (svpfn <= (ULONG_MAX >> PAGE_SHIFT)) {
		ret = mmap_read_lock_killable(mm);
		if (ret)
			goto out_free;
		start_vaddr = untagged_addr_remote(mm, svpfn << PAGE_SHIFT);
		mmap_read_unlock(mm);
	}

	/* Ensure the address is inside the task */
	if (start_vaddr > mm->task_size)
+0 −11
Original line number Diff line number Diff line
@@ -96,17 +96,6 @@ extern int mmap_rnd_compat_bits __read_mostly;
#include <asm/page.h>
#include <asm/processor.h>

/*
 * Architectures that support memory tagging (assigning tags to memory regions,
 * embedding these tags into addresses that point to these memory regions, and
 * checking that the memory and the pointer tags match on memory accesses)
 * redefine this macro to strip tags from pointers.
 * It's defined as noop for architectures that don't support memory tagging.
 */
#ifndef untagged_addr
#define untagged_addr(addr) (addr)
#endif

#ifndef __pa_symbol
#define __pa_symbol(x)  __pa(RELOC_HIDE((unsigned long)(x), 0))
#endif
+22 −0
Original line number Diff line number Diff line
@@ -10,6 +10,28 @@

#include <asm/uaccess.h>

/*
 * Architectures that support memory tagging (assigning tags to memory regions,
 * embedding these tags into addresses that point to these memory regions, and
 * checking that the memory and the pointer tags match on memory accesses)
 * redefine this macro to strip tags from pointers.
 *
 * Passing down mm_struct allows to define untagging rules on per-process
 * basis.
 *
 * It's defined as noop for architectures that don't support memory tagging.
 */
#ifndef untagged_addr
#define untagged_addr(addr) (addr)
#endif

#ifndef untagged_addr_remote
#define untagged_addr_remote(mm, addr)	({		\
	mmap_assert_locked(mm);				\
	untagged_addr(addr);				\
})
#endif

/*
 * Architectures should provide two primitives (raw_copy_{to,from}_user())
 * and get rid of their private instances of copy_{to,from}_user() and
Loading