From a84ca704d8306a949578d36c028c8e1bab3dcf0b Mon Sep 17 00:00:00 2001 From: Haowen Bai Date: Sun, 24 Apr 2022 16:26:41 +0800 Subject: selftests/powerpc/pmu: Fix unsigned function returning negative constant The function __perf_reg_mask has an unsigned return type, but returns a negative constant to indicate an error condition. So we change unsigned to int. Signed-off-by: Haowen Bai Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/1650788802-14402-1-git-send-email-baihaowen@meizu.com --- tools/testing/selftests/powerpc/pmu/sampling_tests/misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.c b/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.c index fca054bbc094..c01a31d5f4ee 100644 --- a/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.c +++ b/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.c @@ -274,7 +274,7 @@ u64 *get_intr_regs(struct event *event, void *sample_buff) return intr_regs; } -static const unsigned int __perf_reg_mask(const char *register_name) +static const int __perf_reg_mask(const char *register_name) { if (!strcmp(register_name, "R0")) return 0; -- cgit From 3527e1ab9a7990530dfb0137ddcfa64bed2915be Mon Sep 17 00:00:00 2001 From: Alistair Popple Date: Mon, 22 Jun 2020 12:18:32 +1000 Subject: selftests/powerpc: Add matrix multiply assist (MMA) test Adds a simple test of some basic matrix multiply assist (MMA) instructions. Signed-off-by: Alistair Popple Tested-by: Joel Stanley Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20200622021832.15870-1-alistair@popple.id.au --- tools/testing/selftests/powerpc/include/utils.h | 5 +++ tools/testing/selftests/powerpc/math/Makefile | 4 ++- tools/testing/selftests/powerpc/math/mma.S | 33 +++++++++++++++++ tools/testing/selftests/powerpc/math/mma.c | 48 +++++++++++++++++++++++++ 4 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/math/mma.S create mode 100644 tools/testing/selftests/powerpc/math/mma.c (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/include/utils.h b/tools/testing/selftests/powerpc/include/utils.h index b7d188fc87c7..b9fa9cd709df 100644 --- a/tools/testing/selftests/powerpc/include/utils.h +++ b/tools/testing/selftests/powerpc/include/utils.h @@ -135,6 +135,11 @@ do { \ #define PPC_FEATURE2_ARCH_3_1 0x00040000 #endif +/* POWER10 features */ +#ifndef PPC_FEATURE2_MMA +#define PPC_FEATURE2_MMA 0x00020000 +#endif + #if defined(__powerpc64__) #define UCONTEXT_NIA(UC) (UC)->uc_mcontext.gp_regs[PT_NIP] #define UCONTEXT_MSR(UC) (UC)->uc_mcontext.gp_regs[PT_MSR] diff --git a/tools/testing/selftests/powerpc/math/Makefile b/tools/testing/selftests/powerpc/math/Makefile index fcc91c205984..3948f7c510aa 100644 --- a/tools/testing/selftests/powerpc/math/Makefile +++ b/tools/testing/selftests/powerpc/math/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -TEST_GEN_PROGS := fpu_syscall fpu_preempt fpu_signal fpu_denormal vmx_syscall vmx_preempt vmx_signal vsx_preempt +TEST_GEN_PROGS := fpu_syscall fpu_preempt fpu_signal fpu_denormal vmx_syscall vmx_preempt vmx_signal vsx_preempt mma top_srcdir = ../../../../.. include ../../lib.mk @@ -17,3 +17,5 @@ $(OUTPUT)/vmx_signal: vmx_asm.S ../utils.c $(OUTPUT)/vsx_preempt: CFLAGS += -mvsx $(OUTPUT)/vsx_preempt: vsx_asm.S ../utils.c + +$(OUTPUT)/mma: mma.c mma.S ../utils.c diff --git a/tools/testing/selftests/powerpc/math/mma.S b/tools/testing/selftests/powerpc/math/mma.S new file mode 100644 index 000000000000..8528c9849565 --- /dev/null +++ b/tools/testing/selftests/powerpc/math/mma.S @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * + * Test basic matrix multiply assist (MMA) functionality if available. + * + * Copyright 2020, Alistair Popple, IBM Corp. + */ + .global test_mma +test_mma: + /* Load accumulator via VSX registers from image passed in r3 */ + lxvh8x 4,0,3 + lxvh8x 5,0,4 + + /* Clear and prime the accumulator (xxsetaccz) */ + .long 0x7c030162 + + /* Prime the accumulator with MMA VSX move to accumulator + * X-form (xxmtacc) (not needed due to above zeroing) */ + //.long 0x7c010162 + + /* xvi16ger2s */ + .long 0xec042958 + + /* Store result in image passed in r5 */ + stxvw4x 0,0,5 + addi 5,5,16 + stxvw4x 1,0,5 + addi 5,5,16 + stxvw4x 2,0,5 + addi 5,5,16 + stxvw4x 3,0,5 + addi 5,5,16 + + blr diff --git a/tools/testing/selftests/powerpc/math/mma.c b/tools/testing/selftests/powerpc/math/mma.c new file mode 100644 index 000000000000..3a71808c993f --- /dev/null +++ b/tools/testing/selftests/powerpc/math/mma.c @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Test basic matrix multiply assist (MMA) functionality if available. + * + * Copyright 2020, Alistair Popple, IBM Corp. + */ +#include +#include + +#include "utils.h" + +extern void test_mma(uint16_t (*)[8], uint16_t (*)[8], uint32_t (*)[4*4]); + +static int mma(void) +{ + int i; + int rc = 0; + uint16_t x[] = {1, 0, 2, 0, 3, 0, 4, 0}; + uint16_t y[] = {1, 0, 2, 0, 3, 0, 4, 0}; + uint32_t z[4*4]; + uint32_t exp[4*4] = {1, 2, 3, 4, + 2, 4, 6, 8, + 3, 6, 9, 12, + 4, 8, 12, 16}; + + SKIP_IF_MSG(!have_hwcap2(PPC_FEATURE2_ARCH_3_1), "Need ISAv3.1"); + SKIP_IF_MSG(!have_hwcap2(PPC_FEATURE2_MMA), "Need MMA"); + + test_mma(&x, &y, &z); + + for (i = 0; i < 16; i++) { + printf("MMA[%d] = %d ", i, z[i]); + + if (z[i] == exp[i]) { + printf(" (Correct)\n"); + } else { + printf(" (Incorrect)\n"); + rc = 1; + } + } + + return rc; +} + +int main(int argc, char *argv[]) +{ + return test_harness(mma, "mma"); +} -- cgit From e96a76ee5283d509f2bf45133d147e77f73a1b15 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Fri, 18 Mar 2022 01:39:25 +1100 Subject: selftests/powerpc: Add a test of 4PB SLB handling Add a test for a bug we had in the 4PB address space SLB handling. It was fixed in commit 4c2de74cc869 ("powerpc/64: Interrupts save PPR on stack rather than thread_struct"). Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20220317143925.1030447-1-mpe@ellerman.id.au --- tools/testing/selftests/powerpc/mm/.gitignore | 1 + tools/testing/selftests/powerpc/mm/Makefile | 4 +- .../selftests/powerpc/mm/large_vm_gpr_corruption.c | 156 +++++++++++++++++++++ 3 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/mm/large_vm_gpr_corruption.c (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/mm/.gitignore b/tools/testing/selftests/powerpc/mm/.gitignore index aac4a59f9e28..4e1a294eec35 100644 --- a/tools/testing/selftests/powerpc/mm/.gitignore +++ b/tools/testing/selftests/powerpc/mm/.gitignore @@ -12,3 +12,4 @@ pkey_exec_prot pkey_siginfo stack_expansion_ldst stack_expansion_signal +large_vm_gpr_corruption diff --git a/tools/testing/selftests/powerpc/mm/Makefile b/tools/testing/selftests/powerpc/mm/Makefile index 40253abc6208..27dc09d0bfee 100644 --- a/tools/testing/selftests/powerpc/mm/Makefile +++ b/tools/testing/selftests/powerpc/mm/Makefile @@ -4,7 +4,8 @@ noarg: TEST_GEN_PROGS := hugetlb_vs_thp_test subpage_prot prot_sao segv_errors wild_bctr \ large_vm_fork_separation bad_accesses pkey_exec_prot \ - pkey_siginfo stack_expansion_signal stack_expansion_ldst + pkey_siginfo stack_expansion_signal stack_expansion_ldst \ + large_vm_gpr_corruption TEST_PROGS := stress_code_patching.sh TEST_GEN_PROGS_EXTENDED := tlbie_test @@ -19,6 +20,7 @@ $(OUTPUT)/prot_sao: ../utils.c $(OUTPUT)/wild_bctr: CFLAGS += -m64 $(OUTPUT)/large_vm_fork_separation: CFLAGS += -m64 +$(OUTPUT)/large_vm_gpr_corruption: CFLAGS += -m64 $(OUTPUT)/bad_accesses: CFLAGS += -m64 $(OUTPUT)/pkey_exec_prot: CFLAGS += -m64 $(OUTPUT)/pkey_siginfo: CFLAGS += -m64 diff --git a/tools/testing/selftests/powerpc/mm/large_vm_gpr_corruption.c b/tools/testing/selftests/powerpc/mm/large_vm_gpr_corruption.c new file mode 100644 index 000000000000..927bfae99ed9 --- /dev/null +++ b/tools/testing/selftests/powerpc/mm/large_vm_gpr_corruption.c @@ -0,0 +1,156 @@ +// SPDX-License-Identifier: GPL-2.0+ +// +// Copyright 2022, Michael Ellerman, IBM Corp. +// +// Test that the 4PB address space SLB handling doesn't corrupt userspace registers +// (r9-r13) due to a SLB fault while saving the PPR. +// +// The bug was introduced in f384796c4 ("powerpc/mm: Add support for handling > 512TB +// address in SLB miss") and fixed in 4c2de74cc869 ("powerpc/64: Interrupts save PPR on +// stack rather than thread_struct"). +// +// To hit the bug requires the task struct and kernel stack to be in different segments. +// Usually that requires more than 1TB of RAM, or if that's not practical, boot the kernel +// with "disable_1tb_segments". +// +// The test works by creating mappings above 512TB, to trigger the large address space +// support. It creates 64 mappings, double the size of the SLB, to cause SLB faults on +// each access (assuming naive replacement). It then loops over those mappings touching +// each, and checks that r9-r13 aren't corrupted. +// +// It then forks another child and tries again, because a new child process will get a new +// kernel stack and thread struct allocated, which may be more optimally placed to trigger +// the bug. It would probably be better to leave the previous child processes hanging +// around, so that kernel stack & thread struct allocations are not reused, but that would +// amount to a 30 second fork bomb. The current design reliably triggers the bug on +// unpatched kernels. + +#include +#include +#include +#include +#include +#include +#include + +#include "utils.h" + +#ifndef MAP_FIXED_NOREPLACE +#define MAP_FIXED_NOREPLACE MAP_FIXED // "Should be safe" above 512TB +#endif + +#define BASE_ADDRESS (1ul << 50) // 1PB +#define STRIDE (2ul << 40) // 2TB +#define SLB_SIZE 32 +#define NR_MAPPINGS (SLB_SIZE * 2) + +static volatile sig_atomic_t signaled; + +static void signal_handler(int sig) +{ + signaled = 1; +} + +#define CHECK_REG(_reg) \ + if (_reg != _reg##_orig) { \ + printf(str(_reg) " corrupted! Expected 0x%lx != 0x%lx\n", _reg##_orig, \ + _reg); \ + _exit(1); \ + } + +static int touch_mappings(void) +{ + unsigned long r9_orig, r10_orig, r11_orig, r12_orig, r13_orig; + unsigned long r9, r10, r11, r12, r13; + unsigned long addr, *p; + int i; + + for (i = 0; i < NR_MAPPINGS; i++) { + addr = BASE_ADDRESS + (i * STRIDE); + p = (unsigned long *)addr; + + asm volatile("mr %0, %%r9 ;" // Read original GPR values + "mr %1, %%r10 ;" + "mr %2, %%r11 ;" + "mr %3, %%r12 ;" + "mr %4, %%r13 ;" + "std %10, 0(%11) ;" // Trigger SLB fault + "mr %5, %%r9 ;" // Save possibly corrupted values + "mr %6, %%r10 ;" + "mr %7, %%r11 ;" + "mr %8, %%r12 ;" + "mr %9, %%r13 ;" + "mr %%r9, %0 ;" // Restore original values + "mr %%r10, %1 ;" + "mr %%r11, %2 ;" + "mr %%r12, %3 ;" + "mr %%r13, %4 ;" + : "=&b"(r9_orig), "=&b"(r10_orig), "=&b"(r11_orig), + "=&b"(r12_orig), "=&b"(r13_orig), "=&b"(r9), "=&b"(r10), + "=&b"(r11), "=&b"(r12), "=&b"(r13) + : "b"(i), "b"(p) + : "r9", "r10", "r11", "r12", "r13"); + + CHECK_REG(r9); + CHECK_REG(r10); + CHECK_REG(r11); + CHECK_REG(r12); + CHECK_REG(r13); + } + + return 0; +} + +static int test(void) +{ + unsigned long page_size, addr, *p; + struct sigaction action; + bool hash_mmu; + int i, status; + pid_t pid; + + // This tests a hash MMU specific bug. + FAIL_IF(using_hash_mmu(&hash_mmu)); + SKIP_IF(!hash_mmu); + + page_size = sysconf(_SC_PAGESIZE); + + for (i = 0; i < NR_MAPPINGS; i++) { + addr = BASE_ADDRESS + (i * STRIDE); + + p = mmap((void *)addr, page_size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED_NOREPLACE, -1, 0); + if (p == MAP_FAILED) { + perror("mmap"); + printf("Error: couldn't mmap(), confirm kernel has 4PB support?\n"); + return 1; + } + } + + action.sa_handler = signal_handler; + action.sa_flags = SA_RESTART; + FAIL_IF(sigaction(SIGALRM, &action, NULL) < 0); + + // Seen to always crash in under ~10s on affected kernels. + alarm(30); + + while (!signaled) { + // Fork new processes, to increase the chance that we hit the case where + // the kernel stack and task struct are in different segments. + pid = fork(); + if (pid == 0) + exit(touch_mappings()); + + FAIL_IF(waitpid(-1, &status, 0) == -1); + FAIL_IF(WIFSIGNALED(status)); + FAIL_IF(!WIFEXITED(status)); + FAIL_IF(WEXITSTATUS(status)); + } + + return 0; +} + +int main(void) +{ + return test_harness(test, "large_vm_gpr_corruption"); +} -- cgit From dcbff9ad418497c2608d4b4d9423efc8e87e130e Mon Sep 17 00:00:00 2001 From: Russell Currey Date: Tue, 8 Jun 2021 15:48:51 +1000 Subject: selftests/powerpc: Fix typo in spectre_v2 Signed-off-by: Russell Currey Signed-off-by: Christophe Leroy Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210608054851.164659-1-ruscur@russell.cc --- tools/testing/selftests/powerpc/security/spectre_v2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/security/spectre_v2.c b/tools/testing/selftests/powerpc/security/spectre_v2.c index d42ca8c676c3..80dc97e3ec57 100644 --- a/tools/testing/selftests/powerpc/security/spectre_v2.c +++ b/tools/testing/selftests/powerpc/security/spectre_v2.c @@ -207,7 +207,7 @@ int spectre_v2_test(void) break; case COUNT_CACHE_DISABLED: if (miss_percent < 95) { - printf("Branch misses < 20%% unexpected in this configuration!\n"); + printf("Branch misses < 95%% unexpected in this configuration!\n"); printf("Possible mis-match between reported & actual mitigation\n"); return 1; } -- cgit From 48482f4dd3432e5e62873bf0f2e254cfb8ce2ac2 Mon Sep 17 00:00:00 2001 From: Russell Currey Date: Tue, 8 Jun 2021 16:48:09 +1000 Subject: selftests/powerpc: Better reporting in spectre_v2 In commit f3054ffd71b5 ("selftests/powerpc: Return skip code for spectre_v2"), the spectre_v2 selftest is updated to be aware of cases where the vulnerability status reported in sysfs is incorrect, skipping the test instead. This happens because qemu can misrepresent the mitigation status of the host to the guest. If the count cache is disabled in the host, and this is correctly reported to the guest, then the guest won't apply mitigations. If the guest is then migrated to a new host where mitigations are necessary, it is now vulnerable because it has not applied mitigations. Update the selftest to report when we see excessive misses, indicative of the count cache being disabled. If software flushing is enabled, also warn that these flushes are just wasting performance. Signed-off-by: Russell Currey [mpe: Rebase and update change log appropriately] Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210608064809.199116-1-ruscur@russell.cc --- .../selftests/powerpc/security/spectre_v2.c | 24 ++++++++++++++-------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/security/spectre_v2.c b/tools/testing/selftests/powerpc/security/spectre_v2.c index 80dc97e3ec57..0e231e89bfa4 100644 --- a/tools/testing/selftests/powerpc/security/spectre_v2.c +++ b/tools/testing/selftests/powerpc/security/spectre_v2.c @@ -182,17 +182,23 @@ int spectre_v2_test(void) case COUNT_CACHE_FLUSH_HW: // These should all not affect userspace branch prediction if (miss_percent > 15) { + if (miss_percent > 95) { + /* + * Such a mismatch may be caused by a system being unaware + * the count cache is disabled. This may be to enable + * guest migration between hosts with different settings. + * Return skip code to avoid detecting this as an error. + * We are not vulnerable and reporting otherwise, so + * missing such a mismatch is safe. + */ + printf("Branch misses > 95%% unexpected in this configuration.\n"); + printf("Count cache likely disabled without Linux knowing.\n"); + if (state == COUNT_CACHE_FLUSH_SW) + printf("WARNING: Kernel performing unnecessary flushes.\n"); + return 4; + } printf("Branch misses > 15%% unexpected in this configuration!\n"); printf("Possible mis-match between reported & actual mitigation\n"); - /* - * Such a mismatch may be caused by a guest system - * reporting as vulnerable when the host is mitigated. - * Return skip code to avoid detecting this as an error. - * We are not vulnerable and reporting otherwise, so - * missing such a mismatch is safe. - */ - if (miss_percent > 95) - return 4; return 1; } -- cgit From 079e5fd3a1e41c186c1bc4166d409d22e70729bf Mon Sep 17 00:00:00 2001 From: Madhavan Srinivasan Date: Tue, 22 Mar 2022 10:26:38 +0530 Subject: selftests/powerpc/pmu/ebb: remove fixed_instruction.S Commit 3752e453f6ba ("selftests/powerpc: Add tests of PMU EBBs") added selftest testcases to verify EBB interface. instruction_count_test.c testcase needs a fixed loop function to count overhead. Instead of using the thirty_two_instruction_loop() in fixed_instruction_loop.S in ebb folder, file is linked with thirty_two_instruction_loop() in loop.S from top folder. Since fixed_instruction_loop.S not used, patch removes the file. Signed-off-by: Madhavan Srinivasan Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20220322045638.10443-1-maddy@linux.ibm.com --- .../powerpc/pmu/ebb/fixed_instruction_loop.S | 43 ---------------------- 1 file changed, 43 deletions(-) delete mode 100644 tools/testing/selftests/powerpc/pmu/ebb/fixed_instruction_loop.S (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/pmu/ebb/fixed_instruction_loop.S b/tools/testing/selftests/powerpc/pmu/ebb/fixed_instruction_loop.S deleted file mode 100644 index 08a7b5f133b9..000000000000 --- a/tools/testing/selftests/powerpc/pmu/ebb/fixed_instruction_loop.S +++ /dev/null @@ -1,43 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright 2014, Michael Ellerman, IBM Corp. - */ - -#include - - .text - -FUNC_START(thirty_two_instruction_loop) - cmpwi r3,0 - beqlr - addi r4,r3,1 - addi r4,r4,1 - addi r4,r4,1 - addi r4,r4,1 - addi r4,r4,1 - addi r4,r4,1 - addi r4,r4,1 - addi r4,r4,1 - addi r4,r4,1 - addi r4,r4,1 - addi r4,r4,1 - addi r4,r4,1 - addi r4,r4,1 - addi r4,r4,1 - addi r4,r4,1 - addi r4,r4,1 - addi r4,r4,1 - addi r4,r4,1 - addi r4,r4,1 - addi r4,r4,1 - addi r4,r4,1 - addi r4,r4,1 - addi r4,r4,1 - addi r4,r4,1 - addi r4,r4,1 - addi r4,r4,1 - addi r4,r4,1 - addi r4,r4,1 # 28 addi's - subi r3,r3,1 - b FUNC_NAME(thirty_two_instruction_loop) -FUNC_END(thirty_two_instruction_loop) -- cgit From 7801cb1dc60f7348687ca1c3aa03a944687563f0 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Sat, 19 Mar 2022 23:20:25 +0000 Subject: selftests/powerpc/pmu: fix spelling mistake "mis-match" -> "mismatch" There are a few spelling mistakes in error messages. Fix them. Signed-off-by: Colin Ian King Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20220319232025.22067-1-colin.i.king@gmail.com --- tools/testing/selftests/powerpc/security/spectre_v2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/security/spectre_v2.c b/tools/testing/selftests/powerpc/security/spectre_v2.c index 0e231e89bfa4..5b2abb719ef2 100644 --- a/tools/testing/selftests/powerpc/security/spectre_v2.c +++ b/tools/testing/selftests/powerpc/security/spectre_v2.c @@ -198,7 +198,7 @@ int spectre_v2_test(void) return 4; } printf("Branch misses > 15%% unexpected in this configuration!\n"); - printf("Possible mis-match between reported & actual mitigation\n"); + printf("Possible mismatch between reported & actual mitigation\n"); return 1; } @@ -207,14 +207,14 @@ int spectre_v2_test(void) // This seems to affect userspace branch prediction a bit? if (miss_percent > 25) { printf("Branch misses > 25%% unexpected in this configuration!\n"); - printf("Possible mis-match between reported & actual mitigation\n"); + printf("Possible mismatch between reported & actual mitigation\n"); return 1; } break; case COUNT_CACHE_DISABLED: if (miss_percent < 95) { printf("Branch misses < 95%% unexpected in this configuration!\n"); - printf("Possible mis-match between reported & actual mitigation\n"); + printf("Possible mismatch between reported & actual mitigation\n"); return 1; } break; -- cgit