From c0176429b7b07893a5c1fd38baff055c919ba9e3 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 13 Aug 2020 11:34:43 +1000 Subject: selftests/powerpc: Fix TM tests when CPU 0 is offline Several of the TM tests fail spuriously if CPU 0 is offline, because they blindly try to affinitise to CPU 0. Fix them by picking any online CPU and using that instead. Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20200813013445.686464-1-mpe@ellerman.id.au --- tools/testing/selftests/powerpc/tm/tm-poison.c | 11 +++++++---- tools/testing/selftests/powerpc/tm/tm-trap.c | 10 ++++++---- tools/testing/selftests/powerpc/tm/tm-unavailable.c | 9 ++++++--- 3 files changed, 19 insertions(+), 11 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/tm/tm-poison.c b/tools/testing/selftests/powerpc/tm/tm-poison.c index 977558497c16..29e5f26af7b9 100644 --- a/tools/testing/selftests/powerpc/tm/tm-poison.c +++ b/tools/testing/selftests/powerpc/tm/tm-poison.c @@ -26,7 +26,7 @@ int tm_poison_test(void) { - int pid; + int cpu, pid; cpu_set_t cpuset; uint64_t poison = 0xdeadbeefc0dec0fe; uint64_t unknown = 0; @@ -35,10 +35,13 @@ int tm_poison_test(void) SKIP_IF(!have_htm()); - /* Attach both Child and Parent to CPU 0 */ + cpu = pick_online_cpu(); + FAIL_IF(cpu < 0); + + // Attach both Child and Parent to the same CPU CPU_ZERO(&cpuset); - CPU_SET(0, &cpuset); - sched_setaffinity(0, sizeof(cpuset), &cpuset); + CPU_SET(cpu, &cpuset); + FAIL_IF(sched_setaffinity(0, sizeof(cpuset), &cpuset) != 0); pid = fork(); if (!pid) { diff --git a/tools/testing/selftests/powerpc/tm/tm-trap.c b/tools/testing/selftests/powerpc/tm/tm-trap.c index 601f0c1d450d..c75960af8018 100644 --- a/tools/testing/selftests/powerpc/tm/tm-trap.c +++ b/tools/testing/selftests/powerpc/tm/tm-trap.c @@ -247,8 +247,7 @@ void *pong(void *not_used) int tm_trap_test(void) { uint16_t k = 1; - - int rc; + int cpu, rc; pthread_attr_t attr; cpu_set_t cpuset; @@ -267,9 +266,12 @@ int tm_trap_test(void) usr1_sa.sa_sigaction = usr1_signal_handler; sigaction(SIGUSR1, &usr1_sa, NULL); - /* Set only CPU 0 in the mask. Both threads will be bound to cpu 0. */ + cpu = pick_online_cpu(); + FAIL_IF(cpu < 0); + + // Set only one CPU in the mask. Both threads will be bound to that CPU. CPU_ZERO(&cpuset); - CPU_SET(0, &cpuset); + CPU_SET(cpu, &cpuset); /* Init pthread attribute */ rc = pthread_attr_init(&attr); diff --git a/tools/testing/selftests/powerpc/tm/tm-unavailable.c b/tools/testing/selftests/powerpc/tm/tm-unavailable.c index 2ca2fccb0a3e..a1348a5f721a 100644 --- a/tools/testing/selftests/powerpc/tm/tm-unavailable.c +++ b/tools/testing/selftests/powerpc/tm/tm-unavailable.c @@ -338,16 +338,19 @@ void test_fp_vec(int fp, int vec, pthread_attr_t *attr) int tm_unavailable_test(void) { - int rc, exception; /* FP = 0, VEC = 1, VSX = 2 */ + int cpu, rc, exception; /* FP = 0, VEC = 1, VSX = 2 */ pthread_t t1; pthread_attr_t attr; cpu_set_t cpuset; SKIP_IF(!have_htm()); - /* Set only CPU 0 in the mask. Both threads will be bound to CPU 0. */ + cpu = pick_online_cpu(); + FAIL_IF(cpu < 0); + + // Set only one CPU in the mask. Both threads will be bound to that CPU. CPU_ZERO(&cpuset); - CPU_SET(0, &cpuset); + CPU_SET(cpu, &cpuset); /* Init pthread attribute. */ rc = pthread_attr_init(&attr); -- cgit v1.2.3 From 769628710c33b18ede837bb488e1d24084b35592 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 13 Aug 2020 11:34:44 +1000 Subject: selftests/powerpc: Don't use setaffinity in tm-tmspr This test tries to set affinity to CPUs that don't exist, especially if the set of online CPUs doesn't start at 0. But there's no real reason for it to use setaffinity in the first place, it's just trying to create lots of threads to cause contention. So drop the setaffinity entirely. Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20200813013445.686464-2-mpe@ellerman.id.au --- tools/testing/selftests/powerpc/tm/tm-tmspr.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/tm/tm-tmspr.c b/tools/testing/selftests/powerpc/tm/tm-tmspr.c index 17becf3dcee4..2ff329e2fca9 100644 --- a/tools/testing/selftests/powerpc/tm/tm-tmspr.c +++ b/tools/testing/selftests/powerpc/tm/tm-tmspr.c @@ -38,14 +38,8 @@ int passed = 1; void tfiar_tfhar(void *in) { - int i, cpu; unsigned long tfhar, tfhar_rd, tfiar, tfiar_rd; - cpu_set_t cpuset; - - CPU_ZERO(&cpuset); - cpu = (unsigned long)in >> 1; - CPU_SET(cpu, &cpuset); - sched_setaffinity(0, sizeof(cpuset), &cpuset); + int i; /* TFIAR: Last bit has to be high so userspace can read register */ tfiar = ((unsigned long)in) + 1; -- cgit v1.2.3 From b5a646a681f5d67ea5190a71d6e84a91efe63b7a Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 13 Aug 2020 11:34:45 +1000 Subject: selftests/powerpc: Run tm-tmspr test for longer This test creates some threads, which write to TM SPRs, and then makes sure the registers maintain the correct values across context switches and contention with other threads. But currently the test finishes almost instantaneously, which reduces the chance of it hitting an interesting condition. So increase the number of loops, so it runs a bit longer, though still less than 2s on a Power8. Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20200813013445.686464-3-mpe@ellerman.id.au --- tools/testing/selftests/powerpc/tm/tm-tmspr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/tm/tm-tmspr.c b/tools/testing/selftests/powerpc/tm/tm-tmspr.c index 2ff329e2fca9..794d574db784 100644 --- a/tools/testing/selftests/powerpc/tm/tm-tmspr.c +++ b/tools/testing/selftests/powerpc/tm/tm-tmspr.c @@ -33,7 +33,7 @@ #include "utils.h" #include "tm.h" -int num_loops = 10000; +int num_loops = 1000000; int passed = 1; void tfiar_tfhar(void *in) -- cgit v1.2.3 From 34c103342be3f9397e656da7c5cc86e97b91f514 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 19 Aug 2020 11:57:19 +1000 Subject: selftests/powerpc: Make using_hash_mmu() work on Cell & PowerMac These platforms don't show the MMU in /proc/cpuinfo, but they always use hash, so teach using_hash_mmu() that. Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20200819015727.1977134-1-mpe@ellerman.id.au --- tools/testing/selftests/powerpc/utils.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/utils.c b/tools/testing/selftests/powerpc/utils.c index 18b6a773d5c7..638ffacc90aa 100644 --- a/tools/testing/selftests/powerpc/utils.c +++ b/tools/testing/selftests/powerpc/utils.c @@ -318,7 +318,9 @@ int using_hash_mmu(bool *using_hash) rc = 0; while (fgets(line, sizeof(line), f) != NULL) { - if (strcmp(line, "MMU : Hash\n") == 0) { + if (!strcmp(line, "MMU : Hash\n") || + !strcmp(line, "platform : Cell\n") || + !strcmp(line, "platform : PowerMac\n")) { *using_hash = true; goto out; } -- cgit v1.2.3 From 17c98a541dc9bb1162877af41cddbdca043f9a59 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 19 Aug 2020 11:57:20 +1000 Subject: selftests/powerpc: Give the bad_accesses test longer to run On older systems this test takes longer to run (duh), give it five minutes which is long enough on a G5 970FX @ 1.6GHz. Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20200819015727.1977134-2-mpe@ellerman.id.au --- tools/testing/selftests/powerpc/mm/bad_accesses.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/mm/bad_accesses.c b/tools/testing/selftests/powerpc/mm/bad_accesses.c index a864ed7e2008..fd747b2ffcfc 100644 --- a/tools/testing/selftests/powerpc/mm/bad_accesses.c +++ b/tools/testing/selftests/powerpc/mm/bad_accesses.c @@ -139,5 +139,6 @@ static int test(void) int main(void) { + test_harness_set_timeout(300); return test_harness(test, "bad_accesses"); } -- cgit v1.2.3 From d89002397cfb2b65267d6688fe671ee1cf7c5f0d Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 19 Aug 2020 11:57:21 +1000 Subject: selftests/powerpc: Move set_dscr() into rfi_flush.c This version of set_dscr() was added for the RFI flush test, and is fairly specific to it. It also clashes with the version of set_dscr() in dscr/dscr.h. So move it into the RFI flush test where it's used. Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20200819015727.1977134-3-mpe@ellerman.id.au --- tools/testing/selftests/powerpc/include/utils.h | 1 - .../testing/selftests/powerpc/security/rfi_flush.c | 35 ++++++++++++++++++++++ tools/testing/selftests/powerpc/utils.c | 35 ---------------------- 3 files changed, 35 insertions(+), 36 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/include/utils.h b/tools/testing/selftests/powerpc/include/utils.h index 71d2924f5b8b..bba400d1bb90 100644 --- a/tools/testing/selftests/powerpc/include/utils.h +++ b/tools/testing/selftests/powerpc/include/utils.h @@ -35,7 +35,6 @@ int pick_online_cpu(void); int read_debugfs_file(char *debugfs_file, int *result); int write_debugfs_file(char *debugfs_file, int result); int read_sysfs_file(char *debugfs_file, char *result, size_t result_size); -void set_dscr(unsigned long val); int perf_event_open_counter(unsigned int type, unsigned long config, int group_fd); int perf_event_enable(int fd); diff --git a/tools/testing/selftests/powerpc/security/rfi_flush.c b/tools/testing/selftests/powerpc/security/rfi_flush.c index 0a7d0afb26b8..fd37ff9b1c45 100644 --- a/tools/testing/selftests/powerpc/security/rfi_flush.c +++ b/tools/testing/selftests/powerpc/security/rfi_flush.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -41,6 +42,40 @@ static void syscall_loop(char *p, unsigned long iterations, } } +static void sigill_handler(int signr, siginfo_t *info, void *unused) +{ + static int warned = 0; + ucontext_t *ctx = (ucontext_t *)unused; + unsigned long *pc = &UCONTEXT_NIA(ctx); + + /* mtspr 3,RS to check for move to DSCR below */ + if ((*((unsigned int *)*pc) & 0xfc1fffff) == 0x7c0303a6) { + if (!warned++) + printf("WARNING: Skipping over dscr setup. Consider running 'ppc64_cpu --dscr=1' manually.\n"); + *pc += 4; + } else { + printf("SIGILL at %p\n", pc); + abort(); + } +} + +static void set_dscr(unsigned long val) +{ + static int init = 0; + struct sigaction sa; + + if (!init) { + memset(&sa, 0, sizeof(sa)); + sa.sa_sigaction = sigill_handler; + sa.sa_flags = SA_SIGINFO; + if (sigaction(SIGILL, &sa, NULL)) + perror("sigill_handler"); + init = 1; + } + + asm volatile("mtspr %1,%0" : : "r" (val), "i" (SPRN_DSCR)); +} + int rfi_flush_test(void) { char *p; diff --git a/tools/testing/selftests/powerpc/utils.c b/tools/testing/selftests/powerpc/utils.c index 638ffacc90aa..1f36ee1a909a 100644 --- a/tools/testing/selftests/powerpc/utils.c +++ b/tools/testing/selftests/powerpc/utils.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -273,40 +272,6 @@ int perf_event_reset(int fd) return 0; } -static void sigill_handler(int signr, siginfo_t *info, void *unused) -{ - static int warned = 0; - ucontext_t *ctx = (ucontext_t *)unused; - unsigned long *pc = &UCONTEXT_NIA(ctx); - - /* mtspr 3,RS to check for move to DSCR below */ - if ((*((unsigned int *)*pc) & 0xfc1fffff) == 0x7c0303a6) { - if (!warned++) - printf("WARNING: Skipping over dscr setup. Consider running 'ppc64_cpu --dscr=1' manually.\n"); - *pc += 4; - } else { - printf("SIGILL at %p\n", pc); - abort(); - } -} - -void set_dscr(unsigned long val) -{ - static int init = 0; - struct sigaction sa; - - if (!init) { - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = sigill_handler; - sa.sa_flags = SA_SIGINFO; - if (sigaction(SIGILL, &sa, NULL)) - perror("sigill_handler"); - init = 1; - } - - asm volatile("mtspr %1,%0" : : "r" (val), "i" (SPRN_DSCR)); -} - int using_hash_mmu(bool *using_hash) { char line[128]; -- cgit v1.2.3 From 178282a054dced1a08a9683d41ac08cbace2b2fe Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 19 Aug 2020 11:57:22 +1000 Subject: selftests/powerpc: Include asm/cputable.h from utils.h utils.h provides have_hwcap() and have_hwcap2() which check for a feature bit. Those bits are defined in asm/cputable.h, so include it in utils.h so users of utils.h don't have to do it manually. Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20200819015727.1977134-4-mpe@ellerman.id.au --- tools/testing/selftests/powerpc/alignment/alignment_handler.c | 2 -- tools/testing/selftests/powerpc/include/utils.h | 1 + tools/testing/selftests/powerpc/pmu/count_stcx_fail.c | 1 - tools/testing/selftests/powerpc/pmu/per_event_excludes.c | 2 -- tools/testing/selftests/powerpc/stringloops/memcmp.c | 2 +- tools/testing/selftests/powerpc/tm/tm.h | 3 +-- 6 files changed, 3 insertions(+), 8 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/alignment/alignment_handler.c b/tools/testing/selftests/powerpc/alignment/alignment_handler.c index 55ef15184057..e4063eba4a5b 100644 --- a/tools/testing/selftests/powerpc/alignment/alignment_handler.c +++ b/tools/testing/selftests/powerpc/alignment/alignment_handler.c @@ -55,8 +55,6 @@ #include #include -#include - #include "utils.h" #include "instructions.h" diff --git a/tools/testing/selftests/powerpc/include/utils.h b/tools/testing/selftests/powerpc/include/utils.h index bba400d1bb90..052b5a775dc2 100644 --- a/tools/testing/selftests/powerpc/include/utils.h +++ b/tools/testing/selftests/powerpc/include/utils.h @@ -12,6 +12,7 @@ #include #include #include +#include #include "reg.h" /* Avoid headaches with PRI?64 - just use %ll? always */ diff --git a/tools/testing/selftests/powerpc/pmu/count_stcx_fail.c b/tools/testing/selftests/powerpc/pmu/count_stcx_fail.c index 2980abca31e0..2070a1e2b3a5 100644 --- a/tools/testing/selftests/powerpc/pmu/count_stcx_fail.c +++ b/tools/testing/selftests/powerpc/pmu/count_stcx_fail.c @@ -9,7 +9,6 @@ #include #include #include -#include #include "event.h" #include "utils.h" diff --git a/tools/testing/selftests/powerpc/pmu/per_event_excludes.c b/tools/testing/selftests/powerpc/pmu/per_event_excludes.c index 2d37942bf72b..ad32a09a6540 100644 --- a/tools/testing/selftests/powerpc/pmu/per_event_excludes.c +++ b/tools/testing/selftests/powerpc/pmu/per_event_excludes.c @@ -12,8 +12,6 @@ #include #include -#include - #include "event.h" #include "lib.h" #include "utils.h" diff --git a/tools/testing/selftests/powerpc/stringloops/memcmp.c b/tools/testing/selftests/powerpc/stringloops/memcmp.c index 979df3d98368..cb2f18855c8d 100644 --- a/tools/testing/selftests/powerpc/stringloops/memcmp.c +++ b/tools/testing/selftests/powerpc/stringloops/memcmp.c @@ -4,7 +4,7 @@ #include #include #include -#include + #include "utils.h" #define SIZE 256 diff --git a/tools/testing/selftests/powerpc/tm/tm.h b/tools/testing/selftests/powerpc/tm/tm.h index c402464b038f..c5a1e5c163fc 100644 --- a/tools/testing/selftests/powerpc/tm/tm.h +++ b/tools/testing/selftests/powerpc/tm/tm.h @@ -6,9 +6,8 @@ #ifndef _SELFTESTS_POWERPC_TM_TM_H #define _SELFTESTS_POWERPC_TM_TM_H -#include -#include #include +#include #include "utils.h" -- cgit v1.2.3 From 4c3c3c502575556c4bc1b401235e641863b1bce6 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 19 Aug 2020 11:57:23 +1000 Subject: selftests/powerpc: Don't run DSCR tests on old systems The DSCR tests fail on systems that don't have DSCR, so check for the DSCR in hwcap and skip if it's not present. Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20200819015727.1977134-5-mpe@ellerman.id.au --- tools/testing/selftests/powerpc/dscr/Makefile | 2 +- tools/testing/selftests/powerpc/dscr/dscr_default_test.c | 2 ++ tools/testing/selftests/powerpc/dscr/dscr_explicit_test.c | 2 ++ tools/testing/selftests/powerpc/dscr/dscr_inherit_exec_test.c | 2 ++ tools/testing/selftests/powerpc/dscr/dscr_inherit_test.c | 2 ++ tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c | 2 ++ tools/testing/selftests/powerpc/dscr/dscr_sysfs_thread_test.c | 2 ++ tools/testing/selftests/powerpc/dscr/dscr_user_test.c | 2 ++ 8 files changed, 15 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/dscr/Makefile b/tools/testing/selftests/powerpc/dscr/Makefile index cfa6eedcb66c..845db6273a1b 100644 --- a/tools/testing/selftests/powerpc/dscr/Makefile +++ b/tools/testing/selftests/powerpc/dscr/Makefile @@ -10,4 +10,4 @@ include ../../lib.mk $(OUTPUT)/dscr_default_test: LDLIBS += -lpthread -$(TEST_GEN_PROGS): ../harness.c +$(TEST_GEN_PROGS): ../harness.c ../utils.c diff --git a/tools/testing/selftests/powerpc/dscr/dscr_default_test.c b/tools/testing/selftests/powerpc/dscr/dscr_default_test.c index 288a4e2ad156..e76611e608af 100644 --- a/tools/testing/selftests/powerpc/dscr/dscr_default_test.c +++ b/tools/testing/selftests/powerpc/dscr/dscr_default_test.c @@ -63,6 +63,8 @@ int dscr_default(void) unsigned long i, *status[THREADS]; unsigned long orig_dscr_default; + SKIP_IF(!have_hwcap2(PPC_FEATURE2_DSCR)); + orig_dscr_default = get_default_dscr(); /* Initial DSCR default */ diff --git a/tools/testing/selftests/powerpc/dscr/dscr_explicit_test.c b/tools/testing/selftests/powerpc/dscr/dscr_explicit_test.c index aefcd8d8759b..32fcf2b324b1 100644 --- a/tools/testing/selftests/powerpc/dscr/dscr_explicit_test.c +++ b/tools/testing/selftests/powerpc/dscr/dscr_explicit_test.c @@ -21,6 +21,8 @@ int dscr_explicit(void) { unsigned long i, dscr = 0; + SKIP_IF(!have_hwcap2(PPC_FEATURE2_DSCR)); + srand(getpid()); set_dscr(dscr); diff --git a/tools/testing/selftests/powerpc/dscr/dscr_inherit_exec_test.c b/tools/testing/selftests/powerpc/dscr/dscr_inherit_exec_test.c index 7c1cb46397c6..c6a81b2d6b91 100644 --- a/tools/testing/selftests/powerpc/dscr/dscr_inherit_exec_test.c +++ b/tools/testing/selftests/powerpc/dscr/dscr_inherit_exec_test.c @@ -44,6 +44,8 @@ int dscr_inherit_exec(void) unsigned long i, dscr = 0; pid_t pid; + SKIP_IF(!have_hwcap2(PPC_FEATURE2_DSCR)); + for (i = 0; i < COUNT; i++) { dscr++; if (dscr > DSCR_MAX) diff --git a/tools/testing/selftests/powerpc/dscr/dscr_inherit_test.c b/tools/testing/selftests/powerpc/dscr/dscr_inherit_test.c index 04297a69ab59..f9dfd3d3c2d5 100644 --- a/tools/testing/selftests/powerpc/dscr/dscr_inherit_test.c +++ b/tools/testing/selftests/powerpc/dscr/dscr_inherit_test.c @@ -22,6 +22,8 @@ int dscr_inherit(void) unsigned long i, dscr = 0; pid_t pid; + SKIP_IF(!have_hwcap2(PPC_FEATURE2_DSCR)); + srand(getpid()); set_dscr(dscr); diff --git a/tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c b/tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c index 02f6b4efde14..fbbdffdb2e5d 100644 --- a/tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c +++ b/tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c @@ -77,6 +77,8 @@ int dscr_sysfs(void) unsigned long orig_dscr_default; int i, j; + SKIP_IF(!have_hwcap2(PPC_FEATURE2_DSCR)); + orig_dscr_default = get_default_dscr(); for (i = 0; i < COUNT; i++) { for (j = 0; j < DSCR_MAX; j++) { diff --git a/tools/testing/selftests/powerpc/dscr/dscr_sysfs_thread_test.c b/tools/testing/selftests/powerpc/dscr/dscr_sysfs_thread_test.c index 37be2c25f277..191ed126f118 100644 --- a/tools/testing/selftests/powerpc/dscr/dscr_sysfs_thread_test.c +++ b/tools/testing/selftests/powerpc/dscr/dscr_sysfs_thread_test.c @@ -56,6 +56,8 @@ int dscr_sysfs_thread(void) unsigned long orig_dscr_default; int i, j; + SKIP_IF(!have_hwcap2(PPC_FEATURE2_DSCR)); + orig_dscr_default = get_default_dscr(); for (i = 0; i < COUNT; i++) { for (j = 0; j < DSCR_MAX; j++) { diff --git a/tools/testing/selftests/powerpc/dscr/dscr_user_test.c b/tools/testing/selftests/powerpc/dscr/dscr_user_test.c index eaf785d11eed..e09072446dd3 100644 --- a/tools/testing/selftests/powerpc/dscr/dscr_user_test.c +++ b/tools/testing/selftests/powerpc/dscr/dscr_user_test.c @@ -36,6 +36,8 @@ int dscr_user(void) { int i; + SKIP_IF(!have_hwcap2(PPC_FEATURE2_DSCR)); + check_dscr(""); for (i = 0; i < COUNT; i++) { -- cgit v1.2.3 From 3a31518a242dcb262b008d3bb5d4b1cf50cf4026 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 19 Aug 2020 11:57:24 +1000 Subject: selftests/powerpc: Skip security tests on older CPUs Both these tests use PMU events that only work on newer CPUs, so skip them on older CPUs. Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20200819015727.1977134-6-mpe@ellerman.id.au --- tools/testing/selftests/powerpc/security/rfi_flush.c | 3 +++ tools/testing/selftests/powerpc/security/spectre_v2.c | 3 +++ 2 files changed, 6 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/security/rfi_flush.c b/tools/testing/selftests/powerpc/security/rfi_flush.c index fd37ff9b1c45..93a65bd1f231 100644 --- a/tools/testing/selftests/powerpc/security/rfi_flush.c +++ b/tools/testing/selftests/powerpc/security/rfi_flush.c @@ -89,6 +89,9 @@ int rfi_flush_test(void) SKIP_IF(geteuid() != 0); + // The PMU event we use only works on Power7 or later + SKIP_IF(!have_hwcap(PPC_FEATURE_ARCH_2_06)); + if (read_debugfs_file("powerpc/rfi_flush", &rfi_flush_org)) { perror("Unable to read powerpc/rfi_flush debugfs file"); SKIP_IF(1); diff --git a/tools/testing/selftests/powerpc/security/spectre_v2.c b/tools/testing/selftests/powerpc/security/spectre_v2.c index c8d82b784102..adc2b7294e5f 100644 --- a/tools/testing/selftests/powerpc/security/spectre_v2.c +++ b/tools/testing/selftests/powerpc/security/spectre_v2.c @@ -134,6 +134,9 @@ int spectre_v2_test(void) s64 miss_percent; bool is_p9; + // The PMU events we use only work on Power8 or later + SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_2_07)); + state = get_sysfs_state(); if (state == UNKNOWN) { printf("Error: couldn't determine spectre_v2 mitigation state?\n"); -- cgit v1.2.3 From 4871a10b7b5f6b0632bff229884dad1cb1e8dc37 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 19 Aug 2020 11:57:25 +1000 Subject: selftests/powerpc: Skip L3 bank test on older CPUs This is a test of specific piece of logic in isa207-common.c, which is only used on Power8 or later. So skip it on older CPUs. Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20200819015727.1977134-7-mpe@ellerman.id.au --- tools/testing/selftests/powerpc/pmu/l3_bank_test.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/pmu/l3_bank_test.c b/tools/testing/selftests/powerpc/pmu/l3_bank_test.c index a96d512a18c4..a5dfa9bf3b9f 100644 --- a/tools/testing/selftests/powerpc/pmu/l3_bank_test.c +++ b/tools/testing/selftests/powerpc/pmu/l3_bank_test.c @@ -20,6 +20,9 @@ static int l3_bank_test(void) char *p; int i; + // The L3 bank logic is only used on Power8 or later + SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_2_07)); + p = malloc(MALLOC_SIZE); FAIL_IF(!p); -- cgit v1.2.3 From 09275d717d1b2d7d5ed91f2140bb34246514a1b4 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 19 Aug 2020 11:57:26 +1000 Subject: selftests/powerpc: Don't touch VMX/VSX on older CPUs If we're running on a CPU without VMX/VSX then don't touch them. This is fragile, the compiler could spill a VMX/VSX register and break the test anyway. But in practice it seems to work, ie. the test runs to completion on a system without VSX with this change. Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20200819015727.1977134-8-mpe@ellerman.id.au --- tools/testing/selftests/powerpc/benchmarks/context_switch.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/benchmarks/context_switch.c b/tools/testing/selftests/powerpc/benchmarks/context_switch.c index d50cc05df495..96554e2794d1 100644 --- a/tools/testing/selftests/powerpc/benchmarks/context_switch.c +++ b/tools/testing/selftests/powerpc/benchmarks/context_switch.c @@ -481,6 +481,12 @@ int main(int argc, char *argv[]) else printf("futex"); + if (!have_hwcap(PPC_FEATURE_HAS_ALTIVEC)) + touch_altivec = 0; + + if (!have_hwcap(PPC_FEATURE_HAS_VSX)) + touch_vector = 0; + printf(" on cpus %d/%d touching FP:%s altivec:%s vector:%s vdso:%s\n", cpu1, cpu2, touch_fp ? "yes" : "no", touch_altivec ? "yes" : "no", touch_vector ? "yes" : "no", touch_vdso ? "yes" : "no"); -- cgit v1.2.3 From 003d6f5fd2cc3b529f3e6c529bc4bb0792930212 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 19 Aug 2020 11:57:27 +1000 Subject: selftests/powerpc: Properly handle failure in switch_endian_test On older CPUs the switch_endian() syscall doesn't work. Currently that causes the switch_endian_test to just crash. Instead detect the failure and properly exit with a failure message. Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20200819015727.1977134-9-mpe@ellerman.id.au --- .../powerpc/switch_endian/switch_endian_test.S | 23 ++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/switch_endian/switch_endian_test.S b/tools/testing/selftests/powerpc/switch_endian/switch_endian_test.S index cc4930467235..7887f78cf072 100644 --- a/tools/testing/selftests/powerpc/switch_endian/switch_endian_test.S +++ b/tools/testing/selftests/powerpc/switch_endian/switch_endian_test.S @@ -3,9 +3,13 @@ .data .balign 8 -message: +success_message: .ascii "success: switch_endian_test\n\0" + .balign 8 +failure_message: + .ascii "failure: switch_endian_test\n\0" + .section ".toc" .balign 8 pattern: @@ -64,6 +68,9 @@ FUNC_START(_start) li r0, __NR_switch_endian sc + tdi 0, 0, 0x48 // b +8 if the endian was switched + b .Lfail // exit if endian didn't switch + #include "check-reversed.S" /* Flip back, r0 already has the switch syscall number */ @@ -71,12 +78,20 @@ FUNC_START(_start) #include "check.S" + ld r4, success_message@got(%r2) + li r5, 28 // strlen(success_message) + li r14, 0 // exit status +.Lout: li r0, __NR_write li r3, 1 /* stdout */ - ld r4, message@got(%r2) - li r5, 28 /* strlen(message3) */ sc li r0, __NR_exit - li r3, 0 + mr r3, r14 sc b . + +.Lfail: + ld r4, failure_message@got(%r2) + li r5, 28 // strlen(failure_message) + li r14, 1 + b .Lout -- cgit v1.2.3 From db96221a683342fd4775fd820a4d5376cd2f2ed0 Mon Sep 17 00:00:00 2001 From: Jordan Niethe Date: Mon, 24 Aug 2020 23:12:31 +1000 Subject: selftests/powerpc: Fix prefixes in alignment_handler signal handler The signal handler in the alignment handler self test has the ability to jump over the instruction that triggered the signal. It does this by incrementing the PT_NIP in the user context by 4. If it were a prefixed instruction this will mean that the suffix is then executed which is incorrect. Instead check if the major opcode indicates a prefixed instruction (e.g. it is 1) and if so increment PT_NIP by 8. If ISA v3.1 is not available treat it as a word instruction even if the major opcode is 1. Fixes: 620a6473df36 ("selftests/powerpc: Add prefixed loads/stores to alignment_handler test") Signed-off-by: Jordan Niethe [mpe: Fix 32-bit build, rename haveprefixes to prefixes_enabled] Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20200824131231.14008-1-jniethe5@gmail.com --- tools/testing/selftests/powerpc/alignment/alignment_handler.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/alignment/alignment_handler.c b/tools/testing/selftests/powerpc/alignment/alignment_handler.c index e4063eba4a5b..2a0503bc7e49 100644 --- a/tools/testing/selftests/powerpc/alignment/alignment_handler.c +++ b/tools/testing/selftests/powerpc/alignment/alignment_handler.c @@ -62,6 +62,7 @@ int bufsize; int debug; int testing; volatile int gotsig; +bool prefixes_enabled; char *cipath = "/dev/fb0"; long cioffset; @@ -75,7 +76,12 @@ void sighandler(int sig, siginfo_t *info, void *ctx) } gotsig = sig; #ifdef __powerpc64__ - ucp->uc_mcontext.gp_regs[PT_NIP] += 4; + if (prefixes_enabled) { + u32 inst = *(u32 *)ucp->uc_mcontext.gp_regs[PT_NIP]; + ucp->uc_mcontext.gp_regs[PT_NIP] += ((inst >> 26 == 1) ? 8 : 4); + } else { + ucp->uc_mcontext.gp_regs[PT_NIP] += 4; + } #else ucp->uc_mcontext.uc_regs->gregs[PT_NIP] += 4; #endif @@ -646,6 +652,8 @@ int main(int argc, char *argv[]) exit(1); } + prefixes_enabled = have_hwcap2(PPC_FEATURE2_ARCH_3_1); + rc |= test_harness(test_alignment_handler_vsx_206, "test_alignment_handler_vsx_206"); rc |= test_harness(test_alignment_handler_vsx_207, -- cgit v1.2.3 From ac234524056da4e0c081f682da3ea25cdaab737a Mon Sep 17 00:00:00 2001 From: Ravi Bangoria Date: Wed, 2 Sep 2020 09:59:45 +0530 Subject: selftests/powerpc: Tests for kernel accessing user memory Introduce tests to cover simple scenarios where user is watching memory which can be accessed by kernel as well. We also support _MODE_EXACT with _SETHWDEBUG interface. Move those testcases outside of _BP_RANGE condition. This will help to test _MODE_EXACT scenarios when CONFIG_HAVE_HW_BREAKPOINT is not set, eg: $ ./ptrace-hwbreak ... PTRACE_SET_DEBUGREG, Kernel Access Userspace, len: 8: Ok PPC_PTRACE_SETHWDEBUG, MODE_EXACT, WO, len: 1: Ok PPC_PTRACE_SETHWDEBUG, MODE_EXACT, RO, len: 1: Ok PPC_PTRACE_SETHWDEBUG, MODE_EXACT, RW, len: 1: Ok PPC_PTRACE_SETHWDEBUG, MODE_EXACT, Kernel Access Userspace, len: 1: Ok success: ptrace-hwbreak Suggested-by: Pedro Miraglia Franco de Carvalho Signed-off-by: Ravi Bangoria Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20200902042945.129369-9-ravi.bangoria@linux.ibm.com --- .../selftests/powerpc/ptrace/ptrace-hwbreak.c | 48 +++++++++++++++++++++- 1 file changed, 46 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace-hwbreak.c b/tools/testing/selftests/powerpc/ptrace/ptrace-hwbreak.c index fc477dfe86a2..2e0d86e0687e 100644 --- a/tools/testing/selftests/powerpc/ptrace/ptrace-hwbreak.c +++ b/tools/testing/selftests/powerpc/ptrace/ptrace-hwbreak.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include "ptrace.h" #define SPRN_PVR 0x11F @@ -44,6 +46,7 @@ struct gstruct { }; static volatile struct gstruct gstruct __attribute__((aligned(512))); +static volatile char cwd[PATH_MAX] __attribute__((aligned(8))); static void get_dbginfo(pid_t child_pid, struct ppc_debug_info *dbginfo) { @@ -138,6 +141,9 @@ static void test_workload(void) write_var(len); } + /* PTRACE_SET_DEBUGREG, Kernel Access Userspace test */ + syscall(__NR_getcwd, &cwd, PATH_MAX); + /* PPC_PTRACE_SETHWDEBUG, MODE_EXACT, WO test */ write_var(1); @@ -150,6 +156,9 @@ static void test_workload(void) else read_var(1); + /* PPC_PTRACE_SETHWDEBUG, MODE_EXACT, Kernel Access Userspace test */ + syscall(__NR_getcwd, &cwd, PATH_MAX); + /* PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW ALIGNED, WO test */ gstruct.a[rand() % A_LEN] = 'a'; @@ -293,6 +302,24 @@ static int test_set_debugreg(pid_t child_pid) return 0; } +static int test_set_debugreg_kernel_userspace(pid_t child_pid) +{ + unsigned long wp_addr = (unsigned long)cwd; + char *name = "PTRACE_SET_DEBUGREG"; + + /* PTRACE_SET_DEBUGREG, Kernel Access Userspace test */ + wp_addr &= ~0x7UL; + wp_addr |= (1Ul << DABR_READ_SHIFT); + wp_addr |= (1UL << DABR_WRITE_SHIFT); + wp_addr |= (1UL << DABR_TRANSLATION_SHIFT); + ptrace_set_debugreg(child_pid, wp_addr); + ptrace(PTRACE_CONT, child_pid, NULL, 0); + check_success(child_pid, name, "Kernel Access Userspace", wp_addr, 8); + + ptrace_set_debugreg(child_pid, 0); + return 0; +} + static void get_ppc_hw_breakpoint(struct ppc_hw_breakpoint *info, int type, unsigned long addr, int len) { @@ -338,6 +365,22 @@ static void test_sethwdebug_exact(pid_t child_pid) ptrace_delhwdebug(child_pid, wh); } +static void test_sethwdebug_exact_kernel_userspace(pid_t child_pid) +{ + struct ppc_hw_breakpoint info; + unsigned long wp_addr = (unsigned long)&cwd; + char *name = "PPC_PTRACE_SETHWDEBUG, MODE_EXACT"; + int len = 1; /* hardcoded in kernel */ + int wh; + + /* PPC_PTRACE_SETHWDEBUG, MODE_EXACT, Kernel Access Userspace test */ + get_ppc_hw_breakpoint(&info, PPC_BREAKPOINT_TRIGGER_WRITE, wp_addr, 0); + wh = ptrace_sethwdebug(child_pid, &info); + ptrace(PTRACE_CONT, child_pid, NULL, 0); + check_success(child_pid, name, "Kernel Access Userspace", wp_addr, len); + ptrace_delhwdebug(child_pid, wh); +} + static void test_sethwdebug_range_aligned(pid_t child_pid) { struct ppc_hw_breakpoint info; @@ -452,9 +495,10 @@ static void run_tests(pid_t child_pid, struct ppc_debug_info *dbginfo, bool dawr) { test_set_debugreg(child_pid); + test_set_debugreg_kernel_userspace(child_pid); + test_sethwdebug_exact(child_pid); + test_sethwdebug_exact_kernel_userspace(child_pid); if (dbginfo->features & PPC_DEBUG_FEATURE_DATA_BP_RANGE) { - test_sethwdebug_exact(child_pid); - test_sethwdebug_range_aligned(child_pid); if (dawr || is_8xx) { test_sethwdebug_range_unaligned(child_pid); -- cgit v1.2.3 From dc9af82ea0614bb138705d1f5230d53b3b1dfb83 Mon Sep 17 00:00:00 2001 From: Andrew Donnellan Date: Thu, 20 Aug 2020 14:45:14 +1000 Subject: selftests/powerpc: Add a rtas_filter selftest Add a selftest to test the basic functionality of CONFIG_RTAS_FILTER. Signed-off-by: Andrew Donnellan [mpe: Change rmo_start/end to 32-bit to avoid build errors on ppc64] Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20200820044512.7543-2-ajd@linux.ibm.com --- tools/testing/selftests/powerpc/syscalls/Makefile | 2 +- .../selftests/powerpc/syscalls/rtas_filter.c | 285 +++++++++++++++++++++ 2 files changed, 286 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/syscalls/rtas_filter.c (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/syscalls/Makefile b/tools/testing/selftests/powerpc/syscalls/Makefile index 01b22775ca87..b63f8459c704 100644 --- a/tools/testing/selftests/powerpc/syscalls/Makefile +++ b/tools/testing/selftests/powerpc/syscalls/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only -TEST_GEN_PROGS := ipc_unmuxed +TEST_GEN_PROGS := ipc_unmuxed rtas_filter CFLAGS += -I../../../../../usr/include diff --git a/tools/testing/selftests/powerpc/syscalls/rtas_filter.c b/tools/testing/selftests/powerpc/syscalls/rtas_filter.c new file mode 100644 index 000000000000..03b487f18d00 --- /dev/null +++ b/tools/testing/selftests/powerpc/syscalls/rtas_filter.c @@ -0,0 +1,285 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2005-2020 IBM Corporation. + * + * Includes code from librtas (https://github.com/ibm-power-utilities/librtas/) + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "utils.h" + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +#define cpu_to_be32(x) bswap_32(x) +#define be32_to_cpu(x) bswap_32(x) +#else +#define cpu_to_be32(x) (x) +#define be32_to_cpu(x) (x) +#endif + +#define RTAS_IO_ASSERT -1098 /* Unexpected I/O Error */ +#define RTAS_UNKNOWN_OP -1099 /* No Firmware Implementation of Function */ +#define BLOCK_SIZE 4096 +#define PAGE_SIZE 4096 +#define MAX_PAGES 64 + +static const char *ofdt_rtas_path = "/proc/device-tree/rtas"; + +typedef __be32 uint32_t; +struct rtas_args { + __be32 token; + __be32 nargs; + __be32 nret; + __be32 args[16]; + __be32 *rets; /* Pointer to return values in args[]. */ +}; + +struct region { + uint64_t addr; + uint32_t size; + struct region *next; +}; + +int read_entire_file(int fd, char **buf, size_t *len) +{ + size_t buf_size = 0; + size_t off = 0; + int rc; + + *buf = NULL; + do { + buf_size += BLOCK_SIZE; + if (*buf == NULL) + *buf = malloc(buf_size); + else + *buf = realloc(*buf, buf_size); + + if (*buf == NULL) + return -ENOMEM; + + rc = read(fd, *buf + off, BLOCK_SIZE); + if (rc < 0) + return -EIO; + + off += rc; + } while (rc == BLOCK_SIZE); + + if (len) + *len = off; + + return 0; +} + +static int open_prop_file(const char *prop_path, const char *prop_name, int *fd) +{ + char *path; + int len; + + /* allocate enough for two string, a slash and trailing NULL */ + len = strlen(prop_path) + strlen(prop_name) + 1 + 1; + path = malloc(len); + if (path == NULL) + return -ENOMEM; + + snprintf(path, len, "%s/%s", prop_path, prop_name); + + *fd = open(path, O_RDONLY); + free(path); + if (*fd < 0) + return -errno; + + return 0; +} + +static int get_property(const char *prop_path, const char *prop_name, + char **prop_val, size_t *prop_len) +{ + int rc, fd; + + rc = open_prop_file(prop_path, prop_name, &fd); + if (rc) + return rc; + + rc = read_entire_file(fd, prop_val, prop_len); + close(fd); + + return rc; +} + +int rtas_token(const char *call_name) +{ + char *prop_buf = NULL; + size_t len; + int rc; + + rc = get_property(ofdt_rtas_path, call_name, &prop_buf, &len); + if (rc < 0) { + rc = RTAS_UNKNOWN_OP; + goto err; + } + + rc = be32_to_cpu(*(int *)prop_buf); + +err: + free(prop_buf); + return rc; +} + +static int read_kregion_bounds(struct region *kregion) +{ + char *buf; + int fd; + int rc; + + fd = open("/proc/ppc64/rtas/rmo_buffer", O_RDONLY); + if (fd < 0) { + printf("Could not open rmo_buffer file\n"); + return RTAS_IO_ASSERT; + } + + rc = read_entire_file(fd, &buf, NULL); + close(fd); + if (rc) { + free(buf); + return rc; + } + + sscanf(buf, "%" SCNx64 " %x", &kregion->addr, &kregion->size); + free(buf); + + if (!(kregion->size && kregion->addr) || + (kregion->size > (PAGE_SIZE * MAX_PAGES))) { + printf("Unexpected kregion bounds\n"); + return RTAS_IO_ASSERT; + } + + return 0; +} + +static int rtas_call(const char *name, int nargs, + int nrets, ...) +{ + struct rtas_args args; + __be32 *rets[16]; + int i, rc, token; + va_list ap; + + va_start(ap, nrets); + + token = rtas_token(name); + if (token == RTAS_UNKNOWN_OP) { + // We don't care if the call doesn't exist + printf("call '%s' not available, skipping...", name); + rc = RTAS_UNKNOWN_OP; + goto err; + } + + args.token = cpu_to_be32(token); + args.nargs = cpu_to_be32(nargs); + args.nret = cpu_to_be32(nrets); + + for (i = 0; i < nargs; i++) + args.args[i] = (__be32) va_arg(ap, unsigned long); + + for (i = 0; i < nrets; i++) + rets[i] = (__be32 *) va_arg(ap, unsigned long); + + rc = syscall(__NR_rtas, &args); + if (rc) { + rc = -errno; + goto err; + } + + if (nrets) { + *(rets[0]) = be32_to_cpu(args.args[nargs]); + + for (i = 1; i < nrets; i++) { + *(rets[i]) = args.args[nargs + i]; + } + } + +err: + va_end(ap); + return rc; +} + +static int test(void) +{ + struct region rmo_region; + uint32_t rmo_start; + uint32_t rmo_end; + __be32 rets[1]; + int rc; + + // Test a legitimate harmless call + // Expected: call succeeds + printf("Test a permitted call, no parameters... "); + rc = rtas_call("get-time-of-day", 0, 1, rets); + printf("rc: %d\n", rc); + FAIL_IF(rc != 0 && rc != RTAS_UNKNOWN_OP); + + // Test a prohibited call + // Expected: call returns -EINVAL + printf("Test a prohibited call... "); + rc = rtas_call("nvram-fetch", 0, 1, rets); + printf("rc: %d\n", rc); + FAIL_IF(rc != -EINVAL && rc != RTAS_UNKNOWN_OP); + + // Get RMO + rc = read_kregion_bounds(&rmo_region); + if (rc) { + printf("Couldn't read RMO region bounds, skipping remaining cases\n"); + return 0; + } + rmo_start = rmo_region.addr; + rmo_end = rmo_start + rmo_region.size - 1; + printf("RMO range: %08x - %08x\n", rmo_start, rmo_end); + + // Test a permitted call, user-supplied size, buffer inside RMO + // Expected: call succeeds + printf("Test a permitted call, user-supplied size, buffer inside RMO... "); + rc = rtas_call("ibm,get-system-parameter", 3, 1, 0, cpu_to_be32(rmo_start), + cpu_to_be32(rmo_end - rmo_start + 1), rets); + printf("rc: %d\n", rc); + FAIL_IF(rc != 0 && rc != RTAS_UNKNOWN_OP); + + // Test a permitted call, user-supplied size, buffer start outside RMO + // Expected: call returns -EINVAL + printf("Test a permitted call, user-supplied size, buffer start outside RMO... "); + rc = rtas_call("ibm,get-system-parameter", 3, 1, 0, cpu_to_be32(rmo_end + 1), + cpu_to_be32(4000), rets); + printf("rc: %d\n", rc); + FAIL_IF(rc != -EINVAL && rc != RTAS_UNKNOWN_OP); + + // Test a permitted call, user-supplied size, buffer end outside RMO + // Expected: call returns -EINVAL + printf("Test a permitted call, user-supplied size, buffer end outside RMO... "); + rc = rtas_call("ibm,get-system-parameter", 3, 1, 0, cpu_to_be32(rmo_start), + cpu_to_be32(rmo_end - rmo_start + 2), rets); + printf("rc: %d\n", rc); + FAIL_IF(rc != -EINVAL && rc != RTAS_UNKNOWN_OP); + + // Test a permitted call, fixed size, buffer end outside RMO + // Expected: call returns -EINVAL + printf("Test a permitted call, fixed size, buffer end outside RMO... "); + rc = rtas_call("ibm,configure-connector", 2, 1, cpu_to_be32(rmo_end - 4000), 0, rets); + printf("rc: %d\n", rc); + FAIL_IF(rc != -EINVAL && rc != RTAS_UNKNOWN_OP); + + return 0; +} + +int main(int argc, char *argv[]) +{ + return test_harness(test, "rtas_filter"); +} -- cgit v1.2.3 From 996f9e0f93f16211945c8d5f18f296a88cb32f91 Mon Sep 17 00:00:00 2001 From: Oliver O'Halloran Date: Wed, 14 Oct 2020 13:47:11 +1100 Subject: selftests/powerpc: Fix eeh-basic.sh exit codes The kselftests test running infrastructure expects tests to finish with an exit code of 4 if the test decided it should be skipped. Currently eeh-basic.sh exits with the number of devices that failed to recover, so if four devices didn't recover we'll report a skip instead of a fail. Fix this by checking if the return code is non-zero and report success and failure by returning 0 or 1 respectively. For the cases where should actually skip return 4. Fixes: 85d86c8aa52e ("selftests/powerpc: Add basic EEH selftest") Signed-off-by: Oliver O'Halloran Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20201014024711.1138386-1-oohall@gmail.com --- tools/testing/selftests/powerpc/eeh/eeh-basic.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/eeh/eeh-basic.sh b/tools/testing/selftests/powerpc/eeh/eeh-basic.sh index 8a8d0f456946..0d783e1065c8 100755 --- a/tools/testing/selftests/powerpc/eeh/eeh-basic.sh +++ b/tools/testing/selftests/powerpc/eeh/eeh-basic.sh @@ -1,17 +1,19 @@ #!/bin/sh # SPDX-License-Identifier: GPL-2.0-only +KSELFTESTS_SKIP=4 + . ./eeh-functions.sh if ! eeh_supported ; then echo "EEH not supported on this system, skipping" - exit 0; + exit $KSELFTESTS_SKIP; fi if [ ! -e "/sys/kernel/debug/powerpc/eeh_dev_check" ] && \ [ ! -e "/sys/kernel/debug/powerpc/eeh_dev_break" ] ; then echo "debugfs EEH testing files are missing. Is debugfs mounted?" - exit 1; + exit $KSELFTESTS_SKIP; fi pre_lspci=`mktemp` @@ -84,4 +86,5 @@ echo "$failed devices failed to recover ($dev_count tested)" lspci | diff -u $pre_lspci - rm -f $pre_lspci -exit $failed +test "$failed" == 0 +exit $? -- cgit v1.2.3