selftests/powerpc: Add a test for PROT_SAO
authorMichael Ellerman <mpe@ellerman.id.au>
Mon, 11 Jul 2016 05:25:18 +0000 (15:25 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Thu, 14 Jul 2016 10:26:25 +0000 (20:26 +1000)
PROT_SAO is a powerpc-specific flag to mmap(), and we rely on arch
specific logic to allow it to be passed to mmap().

Add a small test to ensure mmap() accepts PROT_SAO. We don't have a good
way to test that it actually causes the mapping to be created with the
right flags, so for now we just touch the mapping so it's faulted in. In
future we might be able to do something better.

Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
tools/testing/selftests/powerpc/mm/.gitignore
tools/testing/selftests/powerpc/mm/Makefile
tools/testing/selftests/powerpc/mm/prot_sao.c [new file with mode: 0644]
tools/testing/selftests/powerpc/utils.h

index b43ade0ec861b8c5037f8329fae153f370d6cdfa..e715a3f2fbf487e631b5fbe7c312f53d25d89e70 100644 (file)
@@ -1,3 +1,4 @@
 hugetlb_vs_thp_test
 subpage_prot
 tempfile
+prot_sao
\ No newline at end of file
index ee179e22308c59bd9c206f8920bb5806f25c73fa..3bdb96eae55869e04a988f0d6cc30ef9d01fc6ce 100644 (file)
@@ -1,13 +1,15 @@
 noarg:
        $(MAKE) -C ../
 
-TEST_PROGS := hugetlb_vs_thp_test subpage_prot
+TEST_PROGS := hugetlb_vs_thp_test subpage_prot prot_sao
 TEST_FILES := tempfile
 
 all: $(TEST_PROGS) $(TEST_FILES)
 
 $(TEST_PROGS): ../harness.c
 
+prot_sao: ../utils.c
+
 include ../../lib.mk
 
 tempfile:
diff --git a/tools/testing/selftests/powerpc/mm/prot_sao.c b/tools/testing/selftests/powerpc/mm/prot_sao.c
new file mode 100644 (file)
index 0000000..611530d
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2016, Michael Ellerman, IBM Corp.
+ * Licensed under GPLv2.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+
+#include <asm/cputable.h>
+
+#include "utils.h"
+
+#define SIZE (64 * 1024)
+
+int test_prot_sao(void)
+{
+       char *p;
+
+       /* 2.06 or later should support SAO */
+       SKIP_IF(!have_hwcap(PPC_FEATURE_ARCH_2_06));
+
+       /*
+        * Ensure we can ask for PROT_SAO.
+        * We can't really verify that it does the right thing, but at least we
+        * confirm the kernel will accept it.
+        */
+       p = mmap(NULL, SIZE, PROT_READ | PROT_WRITE | PROT_SAO,
+                MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+       FAIL_IF(p == MAP_FAILED);
+
+       /* Write to the mapping, to at least cause a fault */
+       memset(p, 0xaa, SIZE);
+
+       return 0;
+}
+
+int main(void)
+{
+       return test_harness(test_prot_sao, "prot-sao");
+}
index a985cfaa535e4cd3b0426211e2dc8dec459c0b3b..fbd33e52ef8f922a6ae0f94740b8c02ea7a12397 100644 (file)
@@ -27,6 +27,11 @@ int test_harness(int (test_function)(void), char *name);
 extern void *get_auxv_entry(int type);
 int pick_online_cpu(void);
 
+static inline bool have_hwcap(unsigned long ftr)
+{
+       return ((unsigned long)get_auxv_entry(AT_HWCAP) & ftr) == ftr;
+}
+
 static inline bool have_hwcap2(unsigned long ftr2)
 {
        return ((unsigned long)get_auxv_entry(AT_HWCAP2) & ftr2) == ftr2;