diff options
author | Ram Pai <linuxram@us.ibm.com> | 2018-01-18 17:50:37 -0800 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2018-01-20 22:59:03 +1100 |
commit | f2407ef3ba225665ee24965f69bc84435fb590cf (patch) | |
tree | 5883038293a5e98317f3cd8bf161f62493cd6926 /arch/powerpc/mm/pkeys.c | |
parent | a6590ca55f1f49912e17e4811ccae9a51bda8859 (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.c | 28 |
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); +} |