From 5212213aa5a2359dd0474c9dab22b6220b591fe1 Mon Sep 17 00:00:00 2001 From: Ram Pai Date: Tue, 27 Mar 2018 02:09:26 -0700 Subject: [PATCH 1/9] mm, powerpc, x86: define VM_PKEY_BITx bits if CONFIG_ARCH_HAS_PKEYS is enabled VM_PKEY_BITx are defined only if CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS is enabled. Powerpc also needs these bits. Hence lets define the VM_PKEY_BITx bits for any architecture that enables CONFIG_ARCH_HAS_PKEYS. Reviewed-by: Dave Hansen Signed-off-by: Ram Pai Reviewed-by: Ingo Molnar Reviewed-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/pkeys.h | 2 ++ fs/proc/task_mmu.c | 4 ++-- include/linux/mm.h | 9 +++++---- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/include/asm/pkeys.h b/arch/powerpc/include/asm/pkeys.h index 0409c80c32c0..18ef59a9886d 100644 --- a/arch/powerpc/include/asm/pkeys.h +++ b/arch/powerpc/include/asm/pkeys.h @@ -26,6 +26,8 @@ extern u32 initial_allocation_mask; /* bits set for reserved keys */ # define VM_PKEY_BIT2 VM_HIGH_ARCH_2 # define VM_PKEY_BIT3 VM_HIGH_ARCH_3 # define VM_PKEY_BIT4 VM_HIGH_ARCH_4 +#elif !defined(VM_PKEY_BIT4) +# define VM_PKEY_BIT4 VM_HIGH_ARCH_4 #endif #define ARCH_VM_PKEY_FLAGS (VM_PKEY_BIT0 | VM_PKEY_BIT1 | VM_PKEY_BIT2 | \ diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index c486ad4b43f0..541392a62608 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -673,13 +673,13 @@ static void show_smap_vma_flags(struct seq_file *m, struct vm_area_struct *vma) [ilog2(VM_MERGEABLE)] = "mg", [ilog2(VM_UFFD_MISSING)]= "um", [ilog2(VM_UFFD_WP)] = "uw", -#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS +#ifdef CONFIG_ARCH_HAS_PKEYS /* These come out via ProtectionKey: */ [ilog2(VM_PKEY_BIT0)] = "", [ilog2(VM_PKEY_BIT1)] = "", [ilog2(VM_PKEY_BIT2)] = "", [ilog2(VM_PKEY_BIT3)] = "", -#endif +#endif /* CONFIG_ARCH_HAS_PKEYS */ }; size_t i; diff --git a/include/linux/mm.h b/include/linux/mm.h index 1ac1f06a4be6..c6a6f2492c1b 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -228,15 +228,16 @@ extern unsigned int kobjsize(const void *objp); #define VM_HIGH_ARCH_4 BIT(VM_HIGH_ARCH_BIT_4) #endif /* CONFIG_ARCH_USES_HIGH_VMA_FLAGS */ -#if defined(CONFIG_X86) -# define VM_PAT VM_ARCH_1 /* PAT reserves whole VMA at once (x86) */ -#if defined (CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS) +#ifdef CONFIG_ARCH_HAS_PKEYS # define VM_PKEY_SHIFT VM_HIGH_ARCH_BIT_0 # define VM_PKEY_BIT0 VM_HIGH_ARCH_0 /* A protection key is a 4-bit value */ # define VM_PKEY_BIT1 VM_HIGH_ARCH_1 # define VM_PKEY_BIT2 VM_HIGH_ARCH_2 # define VM_PKEY_BIT3 VM_HIGH_ARCH_3 -#endif +#endif /* CONFIG_ARCH_HAS_PKEYS */ + +#if defined(CONFIG_X86) +# define VM_PAT VM_ARCH_1 /* PAT reserves whole VMA at once (x86) */ #elif defined(CONFIG_PPC) # define VM_SAO VM_ARCH_1 /* Strong Access Ordering (powerpc) */ #elif defined(CONFIG_PARISC) From 2c9e0a6fa2bb75697981825153128f43b32f6d08 Mon Sep 17 00:00:00 2001 From: Ram Pai Date: Tue, 27 Mar 2018 02:09:27 -0700 Subject: [PATCH 2/9] mm, powerpc, x86: introduce an additional vma bit for powerpc pkey Currently only 4bits are allocated in the vma flags to hold 16 keys. This is sufficient for x86. PowerPC supports 32 keys, which needs 5bits. This patch allocates an additional bit. Reviewed-by: Ingo Molnar Acked-by: Balbir Singh Signed-off-by: Ram Pai [mpe: Fold in #if VM_PKEY_BIT4 as noticed by Dave Hansen] Signed-off-by: Michael Ellerman --- fs/proc/task_mmu.c | 3 +++ include/linux/mm.h | 7 ++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 541392a62608..c2163606e6fb 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -679,6 +679,9 @@ static void show_smap_vma_flags(struct seq_file *m, struct vm_area_struct *vma) [ilog2(VM_PKEY_BIT1)] = "", [ilog2(VM_PKEY_BIT2)] = "", [ilog2(VM_PKEY_BIT3)] = "", +#if VM_PKEY_BIT4 + [ilog2(VM_PKEY_BIT4)] = "", +#endif #endif /* CONFIG_ARCH_HAS_PKEYS */ }; size_t i; diff --git a/include/linux/mm.h b/include/linux/mm.h index c6a6f2492c1b..fc25929031c0 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -231,9 +231,14 @@ extern unsigned int kobjsize(const void *objp); #ifdef CONFIG_ARCH_HAS_PKEYS # define VM_PKEY_SHIFT VM_HIGH_ARCH_BIT_0 # define VM_PKEY_BIT0 VM_HIGH_ARCH_0 /* A protection key is a 4-bit value */ -# define VM_PKEY_BIT1 VM_HIGH_ARCH_1 +# define VM_PKEY_BIT1 VM_HIGH_ARCH_1 /* on x86 and 5-bit value on ppc64 */ # define VM_PKEY_BIT2 VM_HIGH_ARCH_2 # define VM_PKEY_BIT3 VM_HIGH_ARCH_3 +#ifdef CONFIG_PPC +# define VM_PKEY_BIT4 VM_HIGH_ARCH_4 +#else +# define VM_PKEY_BIT4 0 +#endif #endif /* CONFIG_ARCH_HAS_PKEYS */ #if defined(CONFIG_X86) From cd419a513146367af08b895a8f7d360e4e77b638 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Tue, 10 Apr 2018 13:12:20 +1000 Subject: [PATCH 3/9] mm/pkeys: Remove include of asm/mmu_context.h from pkeys.h While trying to unify the pkey handling in show_smap() between x86 and powerpc we stumbled across various build failures due to the order of includes between the two arches. Part of the problem is that linux/pkeys.h includes asm/mmu_context.h, and the relationship between asm/mmu_context.h and asm/pkeys.h is not consistent between the two arches. It would be cleaner if linux/pkeys.h only included asm/pkeys.h, creating a single integration point for the arch pkey definitions. So this patch removes the include of asm/mmu_context.h from linux/pkeys.h. We can't prove that this is safe in the general case, but it passes all the build tests I've thrown at it. Also asm/mmu_context.h is included widely while linux/pkeys.h is not, so most likely any code that is including linux/pkeys.h is already getting asm/mmu_context.h from elsewhere. Signed-off-by: Michael Ellerman --- include/linux/pkeys.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/linux/pkeys.h b/include/linux/pkeys.h index 0794ca78c379..ed06e1a67bfa 100644 --- a/include/linux/pkeys.h +++ b/include/linux/pkeys.h @@ -3,7 +3,6 @@ #define _LINUX_PKEYS_H #include -#include #ifdef CONFIG_ARCH_HAS_PKEYS #include From dbec10e58deadba596d59a0ab4a394fef271992f Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 11 Apr 2018 23:41:42 +1000 Subject: [PATCH 4/9] mm/pkeys, powerpc, x86: Provide an empty vma_pkey() in linux/pkeys.h Consolidate the pkey handling by providing a common empty definition of vma_pkey() in pkeys.h when CONFIG_ARCH_HAS_PKEYS=n. This also removes another entanglement of pkeys.h and asm/mmu_context.h. Signed-off-by: Michael Ellerman Reviewed-by: Ram Pai Reviewed-by: Dave Hansen --- arch/powerpc/include/asm/mmu_context.h | 5 ----- arch/x86/include/asm/mmu_context.h | 5 ----- include/linux/pkeys.h | 5 +++++ 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h index 1835ca1505d6..896efa559996 100644 --- a/arch/powerpc/include/asm/mmu_context.h +++ b/arch/powerpc/include/asm/mmu_context.h @@ -250,11 +250,6 @@ static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, #define thread_pkey_regs_restore(new_thread, old_thread) #define thread_pkey_regs_init(thread) -static inline int vma_pkey(struct vm_area_struct *vma) -{ - return 0; -} - static inline u64 pte_to_hpte_pkey_bits(u64 pteflags) { return 0x0UL; diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h index 57e3785d0d26..3d748bdf44a7 100644 --- a/arch/x86/include/asm/mmu_context.h +++ b/arch/x86/include/asm/mmu_context.h @@ -296,11 +296,6 @@ static inline int vma_pkey(struct vm_area_struct *vma) return (vma->vm_flags & vma_pkey_mask) >> VM_PKEY_SHIFT; } -#else -static inline int vma_pkey(struct vm_area_struct *vma) -{ - return 0; -} #endif /* diff --git a/include/linux/pkeys.h b/include/linux/pkeys.h index ed06e1a67bfa..aad54663763b 100644 --- a/include/linux/pkeys.h +++ b/include/linux/pkeys.h @@ -13,6 +13,11 @@ #define PKEY_DEDICATED_EXECUTE_ONLY 0 #define ARCH_VM_PKEY_FLAGS 0 +static inline int vma_pkey(struct vm_area_struct *vma) +{ + return 0; +} + static inline bool mm_pkey_is_allocated(struct mm_struct *mm, int pkey) { return (pkey == 0); From 555934a71bb479ce109722807b374f2d98aefe89 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 12 Apr 2018 23:54:00 +1000 Subject: [PATCH 5/9] x86/pkeys: Move vma_pkey() into asm/pkeys.h Move the last remaining pkey helper, vma_pkey() into asm/pkeys.h Signed-off-by: Michael Ellerman Reviewed-by: Dave Hansen --- arch/x86/include/asm/mmu_context.h | 10 ---------- arch/x86/include/asm/pkeys.h | 8 ++++++++ include/linux/pkeys.h | 2 +- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h index 3d748bdf44a7..59e1fadef401 100644 --- a/arch/x86/include/asm/mmu_context.h +++ b/arch/x86/include/asm/mmu_context.h @@ -288,16 +288,6 @@ static inline void arch_unmap(struct mm_struct *mm, struct vm_area_struct *vma, mpx_notify_unmap(mm, vma, start, end); } -#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS -static inline int vma_pkey(struct vm_area_struct *vma) -{ - unsigned long vma_pkey_mask = VM_PKEY_BIT0 | VM_PKEY_BIT1 | - VM_PKEY_BIT2 | VM_PKEY_BIT3; - - return (vma->vm_flags & vma_pkey_mask) >> VM_PKEY_SHIFT; -} -#endif - /* * We only want to enforce protection keys on the current process * because we effectively have no access to PKRU for other diff --git a/arch/x86/include/asm/pkeys.h b/arch/x86/include/asm/pkeys.h index a0ba1ffda0df..0e5f749158e4 100644 --- a/arch/x86/include/asm/pkeys.h +++ b/arch/x86/include/asm/pkeys.h @@ -106,4 +106,12 @@ extern int __arch_set_user_pkey_access(struct task_struct *tsk, int pkey, unsigned long init_val); extern void copy_init_pkru_to_fpregs(void); +static inline int vma_pkey(struct vm_area_struct *vma) +{ + unsigned long vma_pkey_mask = VM_PKEY_BIT0 | VM_PKEY_BIT1 | + VM_PKEY_BIT2 | VM_PKEY_BIT3; + + return (vma->vm_flags & vma_pkey_mask) >> VM_PKEY_SHIFT; +} + #endif /*_ASM_X86_PKEYS_H */ diff --git a/include/linux/pkeys.h b/include/linux/pkeys.h index aad54663763b..946cb773b79f 100644 --- a/include/linux/pkeys.h +++ b/include/linux/pkeys.h @@ -2,7 +2,7 @@ #ifndef _LINUX_PKEYS_H #define _LINUX_PKEYS_H -#include +#include #ifdef CONFIG_ARCH_HAS_PKEYS #include From 3f36c94239658a79a4deeb84a2e0ebf005f083fc Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Fri, 13 Apr 2018 23:54:36 +1000 Subject: [PATCH 6/9] x86/pkeys: Add arch_pkeys_enabled() This will be used in future patches to check for arch support for pkeys in generic code. Signed-off-by: Michael Ellerman Reviewed-by: Dave Hansen --- arch/x86/include/asm/pkeys.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/x86/include/asm/pkeys.h b/arch/x86/include/asm/pkeys.h index 0e5f749158e4..c1957f8f7c1b 100644 --- a/arch/x86/include/asm/pkeys.h +++ b/arch/x86/include/asm/pkeys.h @@ -7,6 +7,11 @@ extern int arch_set_user_pkey_access(struct task_struct *tsk, int pkey, unsigned long init_val); +static inline bool arch_pkeys_enabled(void) +{ + return boot_cpu_has(X86_FEATURE_OSPKE); +} + /* * Try to dedicate one of the protection keys to be used as an * execute-only protection key. From 4414ef9536c398ebc4e1443d59fbae8fea53732b Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Fri, 13 Apr 2018 23:54:52 +1000 Subject: [PATCH 7/9] mm/pkeys: Add an empty arch_pkeys_enabled() Add an empty arch_pkeys_enabled() in linux/pkeys.h for the CONFIG_ARCH_HAS_PKEYS=n case. Split out of a patch by Ram Pai . Signed-off-by: Michael Ellerman Reviewed-by: Dave Hansen --- include/linux/pkeys.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/linux/pkeys.h b/include/linux/pkeys.h index 946cb773b79f..2955ba976048 100644 --- a/include/linux/pkeys.h +++ b/include/linux/pkeys.h @@ -39,6 +39,11 @@ static inline int arch_set_user_pkey_access(struct task_struct *tsk, int pkey, return 0; } +static inline bool arch_pkeys_enabled(void) +{ + return false; +} + static inline void copy_init_pkru_to_fpregs(void) { } From 27cca866e3fce0961e13b38b87e5322fe153e437 Mon Sep 17 00:00:00 2001 From: Ram Pai Date: Fri, 13 Apr 2018 23:55:07 +1000 Subject: [PATCH 8/9] mm/pkeys, x86, powerpc: Display pkey in smaps if arch supports pkeys Currently the architecture specific code is expected to display the protection keys in smap for a given vma. This can lead to redundant code and possibly to divergent formats in which the key gets displayed. This patch changes the implementation. It displays the pkey only if the architecture support pkeys, i.e arch_pkeys_enabled() returns true. x86 arch_show_smap() function is not needed anymore, delete it. Signed-off-by: Thiago Jung Bauermann Signed-off-by: Ram Pai [mpe: Split out from larger patch, rebased on header changes] Signed-off-by: Michael Ellerman Reviewed-by: Dave Hansen --- arch/x86/kernel/setup.c | 8 -------- fs/proc/task_mmu.c | 8 +++----- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 5c623dfe39d1..2f86d883dd95 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -1312,11 +1312,3 @@ static int __init register_kernel_offset_dumper(void) return 0; } __initcall(register_kernel_offset_dumper); - -void arch_show_smap(struct seq_file *m, struct vm_area_struct *vma) -{ - if (!boot_cpu_has(X86_FEATURE_OSPKE)) - return; - - seq_printf(m, "ProtectionKey: %8u\n", vma_pkey(vma)); -} diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index c2163606e6fb..93cea7b07a80 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -730,10 +731,6 @@ static int smaps_hugetlb_range(pte_t *pte, unsigned long hmask, } #endif /* HUGETLB_PAGE */ -void __weak arch_show_smap(struct seq_file *m, struct vm_area_struct *vma) -{ -} - #define SEQ_PUT_DEC(str, val) \ seq_put_decimal_ull_width(m, str, (val) >> 10, 8) static int show_smap(struct seq_file *m, void *v, int is_pid) @@ -838,7 +835,8 @@ static int show_smap(struct seq_file *m, void *v, int is_pid) seq_puts(m, " kB\n"); } if (!rollup_mode) { - arch_show_smap(m, vma); + if (arch_pkeys_enabled()) + seq_printf(m, "ProtectionKey: %8u\n", vma_pkey(vma)); show_smap_vma_flags(m, vma); } m_cache_vma(m, vma); From d86a4ba02fc6bea4670b2f59b208152a4a34c3c0 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 10 May 2018 19:46:10 +1000 Subject: [PATCH 9/9] powerpc/pkeys: Drop private VM_PKEY definitions Now that we've updated the generic headers to support 5 PKEY bits for powerpc we don't need our own #defines in arch code. Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/pkeys.h | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/arch/powerpc/include/asm/pkeys.h b/arch/powerpc/include/asm/pkeys.h index 18ef59a9886d..5ba80cffb505 100644 --- a/arch/powerpc/include/asm/pkeys.h +++ b/arch/powerpc/include/asm/pkeys.h @@ -15,21 +15,6 @@ DECLARE_STATIC_KEY_TRUE(pkey_disabled); extern int pkeys_total; /* total pkeys as per device tree */ extern u32 initial_allocation_mask; /* bits set for reserved keys */ -/* - * Define these here temporarily so we're not dependent on patching linux/mm.h. - * Once it's updated we can drop these. - */ -#ifndef VM_PKEY_BIT0 -# define VM_PKEY_SHIFT VM_HIGH_ARCH_BIT_0 -# define VM_PKEY_BIT0 VM_HIGH_ARCH_0 -# define VM_PKEY_BIT1 VM_HIGH_ARCH_1 -# define VM_PKEY_BIT2 VM_HIGH_ARCH_2 -# define VM_PKEY_BIT3 VM_HIGH_ARCH_3 -# define VM_PKEY_BIT4 VM_HIGH_ARCH_4 -#elif !defined(VM_PKEY_BIT4) -# define VM_PKEY_BIT4 VM_HIGH_ARCH_4 -#endif - #define ARCH_VM_PKEY_FLAGS (VM_PKEY_BIT0 | VM_PKEY_BIT1 | VM_PKEY_BIT2 | \ VM_PKEY_BIT3 | VM_PKEY_BIT4)