summaryrefslogtreecommitdiff
path: root/arch/powerpc/mm/pkeys.c
diff options
context:
space:
mode:
authorRam Pai <linuxram@us.ibm.com>2018-01-18 17:50:37 -0800
committerMichael Ellerman <mpe@ellerman.id.au>2018-01-20 22:59:03 +1100
commitf2407ef3ba225665ee24965f69bc84435fb590cf (patch)
tree5883038293a5e98317f3cd8bf161f62493cd6926 /arch/powerpc/mm/pkeys.c
parenta6590ca55f1f49912e17e4811ccae9a51bda8859 (diff)
powerpc: helper to validate key-access permissions of a pte
helper function that checks if the read/write/execute is allowed on the pte. Signed-off-by: Ram Pai <linuxram@us.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc/mm/pkeys.c')
-rw-r--r--arch/powerpc/mm/pkeys.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/arch/powerpc/mm/pkeys.c b/arch/powerpc/mm/pkeys.c
index 010c90c1f5da..5071778fdd20 100644
--- a/arch/powerpc/mm/pkeys.c
+++ b/arch/powerpc/mm/pkeys.c
@@ -358,3 +358,31 @@ int __arch_override_mprotect_pkey(struct vm_area_struct *vma, int prot,
/* Nothing to override. */
return vma_pkey(vma);
}
+
+static bool pkey_access_permitted(int pkey, bool write, bool execute)
+{
+ int pkey_shift;
+ u64 amr;
+
+ if (!pkey)
+ return true;
+
+ if (!is_pkey_enabled(pkey))
+ return true;
+
+ pkey_shift = pkeyshift(pkey);
+ if (execute && !(read_iamr() & (IAMR_EX_BIT << pkey_shift)))
+ return true;
+
+ amr = read_amr(); /* Delay reading amr until absolutely needed */
+ return ((!write && !(amr & (AMR_RD_BIT << pkey_shift))) ||
+ (write && !(amr & (AMR_WR_BIT << pkey_shift))));
+}
+
+bool arch_pte_access_permitted(u64 pte, bool write, bool execute)
+{
+ if (static_branch_likely(&pkey_disabled))
+ return true;
+
+ return pkey_access_permitted(pte_to_pkey_bits(pte), write, execute);
+}