From: Maciej Wieczor-Retman <[email protected]> While the user should expect 4 bit tags from the lam interface current hardware supports 6 bit tags. Such tag width is also used internally by the kernel so the kernel-hardware treatment of addresses that came from userspace is consistent.
Add a procfs file with the hardware supported untag mask. It may be used by debuggers to recreate hardware or kernel handling of user pointers. At the same time the returned value from this file shouldn't be relied on by regular lam user programs since it might change with future hardware. For a stable interface they should use the ARCH_GET_UNTAG_MASK arch_prctl() syscall instead. Signed-off-by: Maciej Wieczor-Retman <[email protected]> --- Changelog v7: - Add the patch to the series. arch/x86/Kconfig | 1 + arch/x86/kernel/process_64.c | 18 ++++++++++++++++++ fs/proc/Kconfig | 4 ++++ fs/proc/base.c | 6 ++++++ include/linux/uaccess.h | 5 +++++ 5 files changed, 34 insertions(+) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index e2df1b147184..1ec303cca1ab 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -2194,6 +2194,7 @@ config ADDRESS_MASKING bool "Linear Address Masking support" depends on X86_64 depends on COMPILE_TEST || !CPU_MITIGATIONS # wait for LASS + select PROC_ADDRESS_MASKING if PROC_FS help Linear Address Masking (LAM) modifies the checking that is applied to 64-bit linear addresses, allowing software to use of the diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 8b8aaf1d740b..44c4a80fc658 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -800,6 +800,24 @@ static long prctl_map_vdso(const struct vdso_image *image, unsigned long addr) #define LAM_TAG_BITS 4 #define LAM_UNTAG_MASK ~GENMASK(60, 57) +#ifdef CONFIG_PROC_ADDRESS_MASKING + +int proc_address_mask(struct seq_file *s, struct pid_namespace *ns, + struct pid *pid, struct task_struct *tsk) +{ + struct mm_struct *mm; + + mm = get_task_mm(tsk); + if (mm) { + seq_printf(s, "0x%llx\n", mm->context.untag_mask); + mmput(mm); + } + + return 0; +} + +#endif + static void enable_lam_func(void *__mm) { struct mm_struct *mm = __mm; diff --git a/fs/proc/Kconfig b/fs/proc/Kconfig index 6ae966c561e7..0094e185a7b2 100644 --- a/fs/proc/Kconfig +++ b/fs/proc/Kconfig @@ -127,3 +127,7 @@ config PROC_PID_ARCH_STATUS config PROC_CPU_RESCTRL def_bool n depends on PROC_FS + +config PROC_ADDRESS_MASKING + def_bool n + depends on PROC_FS diff --git a/fs/proc/base.c b/fs/proc/base.c index 4c863d17dfb4..9483ad4197e1 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -3421,6 +3421,9 @@ static const struct pid_entry tgid_base_stuff[] = { ONE("ksm_merging_pages", S_IRUSR, proc_pid_ksm_merging_pages), ONE("ksm_stat", S_IRUSR, proc_pid_ksm_stat), #endif +#ifdef CONFIG_PROC_ADDRESS_MASKING + ONE("address_mask", S_IRUSR, proc_address_mask), +#endif }; static int proc_tgid_base_readdir(struct file *file, struct dir_context *ctx) @@ -3755,6 +3758,9 @@ static const struct pid_entry tid_base_stuff[] = { ONE("ksm_merging_pages", S_IRUSR, proc_pid_ksm_merging_pages), ONE("ksm_stat", S_IRUSR, proc_pid_ksm_stat), #endif +#ifdef CONFIG_PROC_ADDRESS_MASKING + ONE("address_mask", S_IRUSR, proc_address_mask), +#endif }; static int proc_tid_base_readdir(struct file *file, struct dir_context *ctx) diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h index 4fe63169d5a2..c02d254a1a1e 100644 --- a/include/linux/uaccess.h +++ b/include/linux/uaccess.h @@ -869,4 +869,9 @@ void __noreturn usercopy_abort(const char *name, const char *detail, unsigned long len); #endif +#ifdef CONFIG_PROC_ADDRESS_MASKING +int proc_address_mask(struct seq_file *s, struct pid_namespace *ns, + struct pid *pid, struct task_struct *tsk); +#endif + #endif /* __LINUX_UACCESS_H__ */ -- 2.53.0

