#define _GNU_SOURCE #include #include #include #include #include #include "../kselftest.h" enum test_membarrier_status { TEST_MEMBARRIER_PASS = 0, TEST_MEMBARRIER_FAIL, TEST_MEMBARRIER_SKIP, }; static int sys_membarrier(int cmd, int flags) { return syscall(__NR_membarrier, cmd, flags); } static enum test_membarrier_status test_membarrier_cmd_fail(void) { int cmd = -1, flags = 0; if (sys_membarrier(cmd, flags) != -1) { printf("membarrier: Wrong command should fail but passed.\n"); return TEST_MEMBARRIER_FAIL; } return TEST_MEMBARRIER_PASS; } static enum test_membarrier_status test_membarrier_flags_fail(void) { int cmd = MEMBARRIER_CMD_QUERY, flags = 1; if (sys_membarrier(cmd, flags) != -1) { printf("membarrier: Wrong flags should fail but passed.\n"); return TEST_MEMBARRIER_FAIL; } return TEST_MEMBARRIER_PASS; } static enum test_membarrier_status test_membarrier_success(void) { int cmd = MEMBARRIER_CMD_SHARED, flags = 0; if (sys_membarrier(cmd, flags) != 0) { printf("membarrier: Executing MEMBARRIER_CMD_SHARED failed. %s.\n", strerror(errno)); return TEST_MEMBARRIER_FAIL; } printf("membarrier: MEMBARRIER_CMD_SHARED success.\n"); return TEST_MEMBARRIER_PASS; } static enum test_membarrier_status test_membarrier(void) { enum test_membarrier_status status; status = test_membarrier_cmd_fail(); if (status) return status; status = test_membarrier_flags_fail(); if (status) return status; status = test_membarrier_success(); if (status) return status; return TEST_MEMBARRIER_PASS; } static enum test_membarrier_status test_membarrier_query(void) { int flags = 0, ret; printf("membarrier MEMBARRIER_CMD_QUERY "); ret = sys_membarrier(MEMBARRIER_CMD_QUERY, flags); if (ret < 0) { printf("failed. %s.\n", strerror(errno)); switch (errno) { case ENOSYS: /* * It is valid to build a kernel with * CONFIG_MEMBARRIER=n. However, this skips the tests. */ return TEST_MEMBARRIER_SKIP; case EINVAL: default: return TEST_MEMBARRIER_FAIL; } } if (!(ret & MEMBARRIER_CMD_SHARED)) { printf("command MEMBARRIER_CMD_SHARED is not supported.\n"); return TEST_MEMBARRIER_FAIL; } printf("syscall available.\n"); return TEST_MEMBARRIER_PASS; } int main(int argc, char **argv) { switch (test_membarrier_query()) { case TEST_MEMBARRIER_FAIL: return ksft_exit_fail(); case TEST_MEMBARRIER_SKIP: return ksft_exit_skip(); } switch (test_membarrier()) { case TEST_MEMBARRIER_FAIL: return ksft_exit_fail(); case TEST_MEMBARRIER_SKIP: return ksft_exit_skip(); } printf("membarrier: tests done!\n"); return ksft_exit_pass(); } 443cd5f67fc6ee7c05a88e4996e8177f91b'>root/sound/oss/dev_table.h
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2017-02-03 17:10:28 +1100
committerMichael Ellerman <mpe@ellerman.id.au>2017-02-08 23:36:29 +1100
commitd7df2443cd5f67fc6ee7c05a88e4996e8177f91b (patch)
tree098a7c0ca4fceb8a65cb1f693c9d71990388933d /sound/oss/dev_table.h
parenta0615a16f7d0ceb5804d295203c302d496d8ee91 (diff)
powerpc/mm: Fix spurrious segfaults on radix with autonuma
When autonuma (Automatic NUMA balancing) marks a PTE inaccessible it clears all the protection bits but leave the PTE valid. With the Radix MMU, an attempt at executing from such a PTE will take a fault with bit 35 of SRR1 set "SRR1_ISI_N_OR_G". It is thus incorrect to treat all such faults as errors. We should pass them to handle_mm_fault() for autonuma to deal with. The case of pages that are really not executable is handled by the existing test for VM_EXEC further down. That leaves us with catching the kernel attempts at executing user pages. We can catch that earlier, even before we do find_vma. It is never valid on powerpc for the kernel to take an exec fault to begin with. So fold that test with the existing test for the kernel faulting on kernel addresses to bail out early. Fixes: 1d18ad026844 ("powerpc/mm: Detect instruction fetch denied and report") Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Acked-by: Balbir Singh <bsingharora@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'sound/oss/dev_table.h')