This patch provides the implementation for
arch_vma_access_permitted(). Returns true if the
requested access is allowed by pkey associated with the
vma.

Signed-off-by: Ram Pai <linux...@us.ibm.com>
---
 arch/powerpc/include/asm/mmu_context.h |    5 ++++
 arch/powerpc/mm/pkeys.c                |   40 ++++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/include/asm/mmu_context.h 
b/arch/powerpc/include/asm/mmu_context.h
index da7e943..bf69ff9 100644
--- a/arch/powerpc/include/asm/mmu_context.h
+++ b/arch/powerpc/include/asm/mmu_context.h
@@ -175,11 +175,16 @@ static inline void arch_bprm_mm_init(struct mm_struct *mm,
 {
 }
 
+#ifdef CONFIG_PPC64_MEMORY_PROTECTION_KEYS
+bool arch_vma_access_permitted(struct vm_area_struct *vma,
+                       bool write, bool execute, bool foreign);
+#else /* CONFIG_PPC64_MEMORY_PROTECTION_KEYS */
 static inline bool arch_vma_access_permitted(struct vm_area_struct *vma,
                bool write, bool execute, bool foreign)
 {
        /* by default, allow everything */
        return true;
 }
+#endif /* CONFIG_PPC64_MEMORY_PROTECTION_KEYS */
 #endif /* __KERNEL__ */
 #endif /* __ASM_POWERPC_MMU_CONTEXT_H */
diff --git a/arch/powerpc/mm/pkeys.c b/arch/powerpc/mm/pkeys.c
index 044a17d..f89a048 100644
--- a/arch/powerpc/mm/pkeys.c
+++ b/arch/powerpc/mm/pkeys.c
@@ -201,3 +201,43 @@ bool arch_pte_access_permitted(u64 pte, bool write, bool 
execute)
        return pkey_access_permitted(pte_to_pkey_bits(pte),
                        write, execute);
 }
+
+/*
+ * We only want to enforce protection keys on the current process
+ * because we effectively have no access to AMR/IAMR for other
+ * processes or any way to tell *which * AMR/IAMR in a threaded
+ * process we could use.
+ *
+ * So do not enforce things if the VMA is not from the current
+ * mm, or if we are in a kernel thread.
+ */
+static inline bool vma_is_foreign(struct vm_area_struct *vma)
+{
+       if (!current->mm)
+               return true;
+       /*
+        * if the VMA is from another process, then AMR/IAMR has no
+        * relevance and should not be enforced.
+        */
+       if (current->mm != vma->vm_mm)
+               return true;
+
+       return false;
+}
+
+bool arch_vma_access_permitted(struct vm_area_struct *vma,
+               bool write, bool execute, bool foreign)
+{
+       int pkey;
+
+       /* allow access if the VMA is not one from this process */
+       if (foreign || vma_is_foreign(vma))
+               return true;
+
+       pkey = vma_pkey(vma);
+
+       if (!pkey)
+               return true;
+
+       return pkey_access_permitted(pkey, write, execute);
+}
-- 
1.7.1

Reply via email to