selftests/vm/pkeys: improve checks to determine pkey support
authorRam Pai <linuxram@us.ibm.com>
Thu, 4 Jun 2020 23:52:25 +0000 (16:52 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 5 Jun 2020 02:06:27 +0000 (19:06 -0700)
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: Ram Pai <linuxram@us.ibm.com>
Signed-off-by: Sandipan Das <sandipan@linux.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Acked-by: Dave 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.com
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
tools/testing/selftests/vm/pkey-helpers.h
tools/testing/selftests/vm/pkey-powerpc.h
tools/testing/selftests/vm/pkey-x86.h
tools/testing/selftests/vm/protection_keys.c

index 2f4b1eb3a680ab70b472fee93525887b84a475c8..59ccdff18214f6e96d6904a175bfc17dba3b99c8 100644 (file)
@@ -76,6 +76,8 @@ extern void abort_hooks(void);
 
 __attribute__((noinline)) int read_ptr(int *ptr);
 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 */
 #include "pkey-x86.h"
@@ -186,4 +188,32 @@ static inline u32 *siginfo_get_pkey_ptr(siginfo_t *si)
 #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 */
index 7ad283d4524e52ea4261247355317f1438e65363..1f82caa6293b12086ce12808a5bc20871164045e 100644 (file)
@@ -64,8 +64,9 @@ static inline void __write_pkey_reg(u64 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;
 }
 
index a0c59d4f7af2ec48c7bdf10670f70a20dc002883..6421b846aa169c86670eea08f0e85e45cef3556b 100644 (file)
@@ -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_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 ebx;
index 5fcbbc525364ef897e3be8fa2d5c1d286f4e5307..95f173049f43fabd34e42c5502805b3db835ee67 100644 (file)
@@ -1378,7 +1378,7 @@ void test_mprotect_pkey_on_unsupported_cpu(int *ptr, u16 pkey)
        int size = PAGE_SIZE;
        int sret;
 
-       if (cpu_has_pku()) {
+       if (cpu_has_pkeys()) {
                dprintf1("SKIP: %s: no CPU support\n", __func__);
                return;
        }
@@ -1447,12 +1447,13 @@ void pkey_setup_shadow(void)
 int main(void)
 {
        int nr_iterations = 22;
+       int pkeys_supported = is_pkeys_supported();
 
        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 *ptr;