Check that a syscall made during an active transaction will fail with the correct failure code and that one made during a suspended transaction will succeed.
Signed-off-by: Sam Bobroff <sam.bobr...@au1.ibm.com> --- tools/testing/selftests/powerpc/tm/Makefile | 3 +- tools/testing/selftests/powerpc/tm/tm-syscall.c | 113 +++++++++++++++++++++++ 2 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/tm/tm-syscall.c diff --git a/tools/testing/selftests/powerpc/tm/Makefile b/tools/testing/selftests/powerpc/tm/Makefile index 2cede23..d8dab0d 100644 --- a/tools/testing/selftests/powerpc/tm/Makefile +++ b/tools/testing/selftests/powerpc/tm/Makefile @@ -1,4 +1,5 @@ -PROGS := tm-resched-dscr +PROGS := tm-resched-dscr tm-syscall +CFLAGS:=$(CFLAGS) -mhtm -Wl,-z,now all: $(PROGS) diff --git a/tools/testing/selftests/powerpc/tm/tm-syscall.c b/tools/testing/selftests/powerpc/tm/tm-syscall.c new file mode 100644 index 0000000..7c60e53 --- /dev/null +++ b/tools/testing/selftests/powerpc/tm/tm-syscall.c @@ -0,0 +1,113 @@ +/* Test the kernel's system call code to ensure that a system call + * made from within an active HTM transaction is aborted with the + * correct failure code. + * Conversely, ensure that a system call made from within a + * suspended transaction can succeed. + * + * It is important to compile with -Wl,-z,now to prevent + * lazy symbol resolution from affecting the results. + */ + +#include <stdio.h> +#include <unistd.h> +#include <asm/tm.h> +#include <asm/cputable.h> +#include <linux/auxvec.h> + +#include "utils.h" + +#define TM_RETRIES 10 +#define TM_TEST_RUNS 1000 + +int t_failure_persistent(void) +{ + long texasr = __builtin_get_texasr(); + long failure_code = (texasr >> 56) & 0xff; + + return failure_code & TM_CAUSE_PERSISTENT; +} + +int t_failure_code_syscall(void) +{ + long texasr = __builtin_get_texasr(); + long failure_code = (texasr >> 56) & 0xff; + + return (failure_code & TM_CAUSE_SYSCALL) == TM_CAUSE_SYSCALL; +} + +int t_active_getppid(void) +{ + int i; + + for (i = 0; i < TM_RETRIES; i++) { + if (__builtin_tbegin(0)) { + getppid(); + __builtin_tend(0); + return 1; + } + if (t_failure_persistent()) + return 0; + } + return 0; +} + +int t_active_getppid_test(void) +{ + int i; + + for (i = 0; i < TM_TEST_RUNS; i++) { + if (t_active_getppid()) + return 0; + if (!t_failure_persistent()) + return 0; + if (!t_failure_code_syscall()) + return 0; + } + return 1; +} + +int t_suspended_getppid(void) +{ + int i; + + for (i = 0; i < TM_RETRIES; i++) { + if (__builtin_tbegin(0)) { + __builtin_tsuspend(); + getppid(); + __builtin_tresume(); + __builtin_tend(0); + return 1; + } + if (t_failure_persistent()) + return 0; + } + return 0; +} + +int t_suspended_getppid_test(void) +{ + int i; + + for (i = 0; i < TM_TEST_RUNS; i++) { + if (!t_suspended_getppid()) + return 0; + } + return 1; +} + +int tm_syscall(void) +{ + SKIP_IF(!((long)get_auxv_entry(AT_HWCAP2) & PPC_FEATURE2_HTM)); + setbuf(stdout, 0); + FAIL_IF(!t_active_getppid_test()); + printf("%d active transactions correctly aborted.\n", TM_TEST_RUNS); + FAIL_IF(!t_suspended_getppid_test()); + printf("%d suspended transactions succeeded.\n", TM_TEST_RUNS); + return 0; +} + +int main(void) +{ + return test_harness(tm_syscall, "tm_syscall"); +} + -- 1.7.10.4 _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev