Commit 94c8a223 authored by Ram Pai's avatar Ram Pai Committed by Linus Torvalds

selftests/vm/pkeys: improve checks to determine pkey support

For the pkeys subsystem to work, both the CPU and the kernel need to have
support.  So, additionally check if the kernel supports pkeys apart from
the CPU feature checks.
Signed-off-by: default avatarRam Pai <linuxram@us.ibm.com>
Signed-off-by: default avatarSandipan Das <sandipan@linux.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Acked-by: default avatarDave Hansen <dave.hansen@intel.com>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Florian Weimer <fweimer@redhat.com>
Cc: "Desnes A. Nunes do Rosario" <desnesn@linux.vnet.ibm.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Thiago Jung Bauermann <bauerman@linux.ibm.com>
Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Michal Suchanek <msuchanek@suse.de>
Cc: Shuah Khan <shuah@kernel.org>
Link: http://lkml.kernel.org/r/8fb76c63ebdadcf068ecd2d23731032e195cd364.1585646528.git.sandipan@linux.ibm.comSigned-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent b0acc5d6
...@@ -76,6 +76,8 @@ extern void abort_hooks(void); ...@@ -76,6 +76,8 @@ extern void abort_hooks(void);
__attribute__((noinline)) int read_ptr(int *ptr); __attribute__((noinline)) int read_ptr(int *ptr);
void expected_pkey_fault(int pkey); void expected_pkey_fault(int pkey);
int sys_pkey_alloc(unsigned long flags, unsigned long init_val);
int sys_pkey_free(unsigned long pkey);
#if defined(__i386__) || defined(__x86_64__) /* arch */ #if defined(__i386__) || defined(__x86_64__) /* arch */
#include "pkey-x86.h" #include "pkey-x86.h"
...@@ -186,4 +188,32 @@ static inline u32 *siginfo_get_pkey_ptr(siginfo_t *si) ...@@ -186,4 +188,32 @@ static inline u32 *siginfo_get_pkey_ptr(siginfo_t *si)
#endif #endif
} }
static inline int kernel_has_pkeys(void)
{
/* try allocating a key and see if it succeeds */
int ret = sys_pkey_alloc(0, 0);
if (ret <= 0) {
return 0;
}
sys_pkey_free(ret);
return 1;
}
static inline int is_pkeys_supported(void)
{
/* check if the cpu supports pkeys */
if (!cpu_has_pkeys()) {
dprintf1("SKIP: %s: no CPU support\n", __func__);
return 0;
}
/* check if the kernel supports pkeys */
if (!kernel_has_pkeys()) {
dprintf1("SKIP: %s: no kernel support\n", __func__);
return 0;
}
return 1;
}
#endif /* _PKEYS_HELPER_H */ #endif /* _PKEYS_HELPER_H */
...@@ -64,8 +64,9 @@ static inline void __write_pkey_reg(u64 pkey_reg) ...@@ -64,8 +64,9 @@ static inline void __write_pkey_reg(u64 pkey_reg)
__func__, __read_pkey_reg(), pkey_reg); __func__, __read_pkey_reg(), pkey_reg);
} }
static inline int cpu_has_pku(void) static inline int cpu_has_pkeys(void)
{ {
/* No simple way to determine this */
return 1; return 1;
} }
......
...@@ -97,7 +97,7 @@ static inline void __cpuid(unsigned int *eax, unsigned int *ebx, ...@@ -97,7 +97,7 @@ static inline void __cpuid(unsigned int *eax, unsigned int *ebx,
#define X86_FEATURE_PKU (1<<3) /* Protection Keys for Userspace */ #define X86_FEATURE_PKU (1<<3) /* Protection Keys for Userspace */
#define X86_FEATURE_OSPKE (1<<4) /* OS Protection Keys Enable */ #define X86_FEATURE_OSPKE (1<<4) /* OS Protection Keys Enable */
static inline int cpu_has_pku(void) static inline int cpu_has_pkeys(void)
{ {
unsigned int eax; unsigned int eax;
unsigned int ebx; unsigned int ebx;
......
...@@ -1378,7 +1378,7 @@ void test_mprotect_pkey_on_unsupported_cpu(int *ptr, u16 pkey) ...@@ -1378,7 +1378,7 @@ void test_mprotect_pkey_on_unsupported_cpu(int *ptr, u16 pkey)
int size = PAGE_SIZE; int size = PAGE_SIZE;
int sret; int sret;
if (cpu_has_pku()) { if (cpu_has_pkeys()) {
dprintf1("SKIP: %s: no CPU support\n", __func__); dprintf1("SKIP: %s: no CPU support\n", __func__);
return; return;
} }
...@@ -1447,12 +1447,13 @@ void pkey_setup_shadow(void) ...@@ -1447,12 +1447,13 @@ void pkey_setup_shadow(void)
int main(void) int main(void)
{ {
int nr_iterations = 22; int nr_iterations = 22;
int pkeys_supported = is_pkeys_supported();
setup_handlers(); setup_handlers();
printf("has pku: %d\n", cpu_has_pku()); printf("has pkeys: %d\n", pkeys_supported);
if (!cpu_has_pku()) { if (!pkeys_supported) {
int size = PAGE_SIZE; int size = PAGE_SIZE;
int *ptr; int *ptr;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment