summaryrefslogtreecommitdiff
path: root/tools/testing/selftests
diff options
context:
space:
mode:
Diffstat (limited to 'tools/testing/selftests')
-rw-r--r--tools/testing/selftests/powerpc/mm/pkey_exec_prot.c84
1 files changed, 41 insertions, 43 deletions
diff --git a/tools/testing/selftests/powerpc/mm/pkey_exec_prot.c b/tools/testing/selftests/powerpc/mm/pkey_exec_prot.c
index 18ebfe6bae1c..9e5c7f3f498a 100644
--- a/tools/testing/selftests/powerpc/mm/pkey_exec_prot.c
+++ b/tools/testing/selftests/powerpc/mm/pkey_exec_prot.c
@@ -237,55 +237,53 @@ static int test(void)
*fault_addr = PPC_INST_NOP;
FAIL_IF(remaining_faults != 0 || fault_code != SEGV_ACCERR);
- /*
- * Jump to the executable region when AMR bits are set i.e.
- * the pkey permits neither read nor write access.
- *
- * This should generate a pkey fault based on IAMR bits which
- * are set to not permit execution. AMR bits should not affect
- * execution.
- *
- * This also checks if the overwrite of the first instruction
- * word from a trap to a no-op succeeded.
- */
- fault_addr = insns;
- fault_type = PKEY_DISABLE_EXECUTE;
- fault_pkey = pkey;
- remaining_faults = 1;
- FAIL_IF(sys_pkey_mprotect(insns, pgsize, PROT_EXEC, pkey) != 0);
- pkey_set_rights(pkey, PKEY_DISABLE_ACCESS);
- printf("execute at %p, pkey permissions are %s\n", fault_addr,
- pkey_rights(rights));
- asm volatile("mtctr %0; bctrl" : : "r"(insns));
- FAIL_IF(remaining_faults != 0 || fault_code != SEGV_PKUERR);
-
- /*
- * Free the current pkey and allocate a new one that is
- * fully permissive.
- */
+ /* Free the current pkey */
sys_pkey_free(pkey);
+
rights = 0;
- pkey = sys_pkey_alloc(0, rights);
+ do {
+ /*
+ * Allocate pkeys with all valid combinations of read,
+ * write and execute restrictions.
+ */
+ pkey = sys_pkey_alloc(0, rights);
+ FAIL_IF(pkey < 0);
+
+ /*
+ * Jump to the executable region. AMR bits may or may not
+ * be set but they should not affect execution.
+ *
+ * This should generate pkey faults based on IAMR bits which
+ * may be set to restrict execution.
+ *
+ * The first iteration also checks if the overwrite of the
+ * first instruction word from a trap to a no-op succeeded.
+ */
+ fault_pkey = pkey;
+ fault_type = -1;
+ remaining_faults = 0;
+ if (rights & PKEY_DISABLE_EXECUTE) {
+ fault_type = PKEY_DISABLE_EXECUTE;
+ remaining_faults = 1;
+ }
- /*
- * Jump to the executable region when AMR bits are not set
- * i.e. the pkey permits read and write access.
- *
- * This should not generate any faults as the IAMR bits are
- * also not set and hence will the pkey will not restrict
- * execution.
- */
- fault_pkey = pkey;
- remaining_faults = 0;
- FAIL_IF(sys_pkey_mprotect(insns, pgsize, PROT_EXEC, pkey) != 0);
- printf("execute at %p, pkey permissions are %s\n", fault_addr,
- pkey_rights(rights));
- asm volatile("mtctr %0; bctrl" : : "r"(insns));
- FAIL_IF(remaining_faults != 0);
+ FAIL_IF(sys_pkey_mprotect(insns, pgsize, PROT_EXEC, pkey) != 0);
+ printf("execute at %p, pkey permissions are %s\n", fault_addr,
+ pkey_rights(rights));
+ asm volatile("mtctr %0; bctrl" : : "r"(insns));
+ FAIL_IF(remaining_faults != 0);
+ if (rights & PKEY_DISABLE_EXECUTE)
+ FAIL_IF(fault_code != SEGV_PKUERR);
+
+ /* Free the current pkey */
+ sys_pkey_free(pkey);
+
+ /* Find next valid combination of pkey rights */
+ rights = next_pkey_rights(rights);
+ } while (rights);
/* Cleanup */
munmap((void *) insns, pgsize);
- sys_pkey_free(pkey);
return 0;
}