powerpc: implementation for arch_vma_access_permitted()
authorRam Pai <linuxram@us.ibm.com>
Fri, 19 Jan 2018 01:50:39 +0000 (17:50 -0800)
committerMichael Ellerman <mpe@ellerman.id.au>
Sat, 20 Jan 2018 11:59:04 +0000 (22:59 +1100)
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 <linuxram@us.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/include/asm/mmu_context.h
arch/powerpc/mm/pkeys.c

index 209f12705fbb3edc6037b82e601433cc59523b21..cd2bd739c0dfbe61c3fcdef881f099c81c25ac74 100644 (file)
@@ -186,6 +186,10 @@ static inline void arch_bprm_mm_init(struct mm_struct *mm,
 {
 }
 
+#ifdef CONFIG_PPC_MEM_KEYS
+bool arch_vma_access_permitted(struct vm_area_struct *vma, bool write,
+                              bool execute, bool foreign);
+#else /* CONFIG_PPC_MEM_KEYS */
 static inline bool arch_vma_access_permitted(struct vm_area_struct *vma,
                bool write, bool execute, bool foreign)
 {
@@ -193,7 +197,6 @@ static inline bool arch_vma_access_permitted(struct vm_area_struct *vma,
        return true;
 }
 
-#ifndef CONFIG_PPC_MEM_KEYS
 #define pkey_mm_init(mm)
 #define thread_pkey_regs_save(thread)
 #define thread_pkey_regs_restore(new_thread, old_thread)
index 5071778fdd20482992f31a1a3ed24cdfb7112809..4a885cc165e54c9c8182c280239bf502db723871 100644 (file)
@@ -386,3 +386,37 @@ 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 thread because we
+ * effectively have no access to AMR/IAMR for other threads 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 it is not our ->mm, it has to be foreign */
+       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)
+{
+       if (static_branch_likely(&pkey_disabled))
+               return true;
+       /*
+        * Do not enforce our key-permissions on a foreign vma.
+        */
+       if (foreign || vma_is_foreign(vma))
+               return true;
+
+       return pkey_access_permitted(vma_pkey(vma), write, execute);
+}