From 0c7c237b1c35011ef0b8d30c1d5c20bc6ae7b69b Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 20 Jul 2023 19:38:59 +0100 Subject: kselftest/arm64: Add a test case for SVE VL changes with SME active We just fixed an issue where changing the SVE VL while SME was active could result in us attempting to save the streaming mode SVE vectors without any backing storage. Add a test case which provokes that issue, ideally we should also verify that the contents of ZA are unaffected by any of what we did. Note that since we need to keep streaming mode enabled we can't use any syscalls to trigger the issue, we have to sit in a loop in usersapce and hope to be preempted. The chosen numbers trigger with defconfig on all the virtual platforms for me, this won't be 100% on all systems but avoid an overcomplicated test implementation. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20230720-arm64-fix-sve-sme-vl-change-v2-2-8eea06b82d57@kernel.org Signed-off-by: Will Deacon --- tools/testing/selftests/arm64/fp/vec-syscfg.c | 105 +++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 3 deletions(-) diff --git a/tools/testing/selftests/arm64/fp/vec-syscfg.c b/tools/testing/selftests/arm64/fp/vec-syscfg.c index 9bcfcdc34ee9..58ea4bde5be7 100644 --- a/tools/testing/selftests/arm64/fp/vec-syscfg.c +++ b/tools/testing/selftests/arm64/fp/vec-syscfg.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -39,9 +40,11 @@ struct vec_data { int max_vl; }; +#define VEC_SVE 0 +#define VEC_SME 1 static struct vec_data vec_data[] = { - { + [VEC_SVE] = { .name = "SVE", .hwcap_type = AT_HWCAP, .hwcap = HWCAP_SVE, @@ -51,7 +54,7 @@ static struct vec_data vec_data[] = { .prctl_set = PR_SVE_SET_VL, .default_vl_file = "/proc/sys/abi/sve_default_vector_length", }, - { + [VEC_SME] = { .name = "SME", .hwcap_type = AT_HWCAP2, .hwcap = HWCAP2_SME, @@ -644,18 +647,107 @@ static const test_type tests[] = { prctl_set_all_vqs, }; +static inline void smstart(void) +{ + asm volatile("msr S0_3_C4_C7_3, xzr"); +} + +static inline void smstart_sm(void) +{ + asm volatile("msr S0_3_C4_C3_3, xzr"); +} + +static inline void smstop(void) +{ + asm volatile("msr S0_3_C4_C6_3, xzr"); +} + + +/* + * Verify we can change the SVE vector length while SME is active and + * continue to use SME afterwards. + */ +static void change_sve_with_za(void) +{ + struct vec_data *sve_data = &vec_data[VEC_SVE]; + bool pass = true; + int ret, i; + + if (sve_data->min_vl == sve_data->max_vl) { + ksft_print_msg("Only one SVE VL supported, can't change\n"); + ksft_test_result_skip("change_sve_while_sme\n"); + return; + } + + /* Ensure we will trigger a change when we set the maximum */ + ret = prctl(sve_data->prctl_set, sve_data->min_vl); + if (ret != sve_data->min_vl) { + ksft_print_msg("Failed to set SVE VL %d: %d\n", + sve_data->min_vl, ret); + pass = false; + } + + /* Enable SM and ZA */ + smstart(); + + /* Trigger another VL change */ + ret = prctl(sve_data->prctl_set, sve_data->max_vl); + if (ret != sve_data->max_vl) { + ksft_print_msg("Failed to set SVE VL %d: %d\n", + sve_data->max_vl, ret); + pass = false; + } + + /* + * Spin for a bit with SM enabled to try to trigger another + * save/restore. We can't use syscalls without exiting + * streaming mode. + */ + for (i = 0; i < 100000000; i++) + smstart_sm(); + + /* + * TODO: Verify that ZA was preserved over the VL change and + * spin. + */ + + /* Clean up after ourselves */ + smstop(); + ret = prctl(sve_data->prctl_set, sve_data->default_vl); + if (ret != sve_data->default_vl) { + ksft_print_msg("Failed to restore SVE VL %d: %d\n", + sve_data->default_vl, ret); + pass = false; + } + + ksft_test_result(pass, "change_sve_with_za\n"); +} + +typedef void (*test_all_type)(void); + +static const struct { + const char *name; + test_all_type test; +} all_types_tests[] = { + { "change_sve_with_za", change_sve_with_za }, +}; + int main(void) { + bool all_supported = true; int i, j; ksft_print_header(); - ksft_set_plan(ARRAY_SIZE(tests) * ARRAY_SIZE(vec_data)); + ksft_set_plan(ARRAY_SIZE(tests) * ARRAY_SIZE(vec_data) + + ARRAY_SIZE(all_types_tests)); for (i = 0; i < ARRAY_SIZE(vec_data); i++) { struct vec_data *data = &vec_data[i]; unsigned long supported; supported = getauxval(data->hwcap_type) & data->hwcap; + if (!supported) + all_supported = false; for (j = 0; j < ARRAY_SIZE(tests); j++) { if (supported) @@ -666,5 +758,12 @@ int main(void) } } + for (i = 0; i < ARRAY_SIZE(all_types_tests); i++) { + if (all_supported) + all_types_tests[i].test(); + else + ksft_test_result_skip("%s\n", all_types_tests[i].name); + } + ksft_exit_pass(); } -- cgit v1.2.3 From 0aeead9bb240a6965ede2bed68096c4381fd46a3 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 20 Jul 2023 19:39:00 +0100 Subject: kselftest/arm64: Validate that changing one VL type does not affect another On a system with both SVE and SME when we change one of the VLs this should not result in a change in the other VL. Add a check that this is in fact the case to vec-syscfg. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20230720-arm64-fix-sve-sme-vl-change-v2-3-8eea06b82d57@kernel.org Signed-off-by: Will Deacon --- tools/testing/selftests/arm64/fp/vec-syscfg.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/arm64/fp/vec-syscfg.c b/tools/testing/selftests/arm64/fp/vec-syscfg.c index 58ea4bde5be7..5f648b97a06f 100644 --- a/tools/testing/selftests/arm64/fp/vec-syscfg.c +++ b/tools/testing/selftests/arm64/fp/vec-syscfg.c @@ -554,7 +554,8 @@ static void prctl_set_onexec(struct vec_data *data) /* For each VQ verify that setting via prctl() does the right thing */ static void prctl_set_all_vqs(struct vec_data *data) { - int ret, vq, vl, new_vl; + int ret, vq, vl, new_vl, i; + int orig_vls[ARRAY_SIZE(vec_data)]; int errors = 0; if (!data->min_vl || !data->max_vl) { @@ -563,6 +564,9 @@ static void prctl_set_all_vqs(struct vec_data *data) return; } + for (i = 0; i < ARRAY_SIZE(vec_data); i++) + orig_vls[i] = vec_data[i].rdvl(); + for (vq = SVE_VQ_MIN; vq <= SVE_VQ_MAX; vq++) { vl = sve_vl_from_vq(vq); @@ -585,6 +589,22 @@ static void prctl_set_all_vqs(struct vec_data *data) errors++; } + /* Did any other VLs change? */ + for (i = 0; i < ARRAY_SIZE(vec_data); i++) { + if (&vec_data[i] == data) + continue; + + if (!(getauxval(vec_data[i].hwcap_type) & vec_data[i].hwcap)) + continue; + + if (vec_data[i].rdvl() != orig_vls[i]) { + ksft_print_msg("%s VL changed from %d to %d\n", + vec_data[i].name, orig_vls[i], + vec_data[i].rdvl()); + errors++; + } + } + /* Was that the VL we asked for? */ if (new_vl == vl) continue; -- cgit v1.2.3 From d1890517ac751a427b962caddda91ecc2bbf21d0 Mon Sep 17 00:00:00 2001 From: Zeng Heng Date: Thu, 3 Aug 2023 21:39:05 +0800 Subject: kselftest/arm64: add RCpc load-acquire to hwcap test Add the RCpc and various features check in the set of hwcap tests. Signed-off-by: Zeng Heng Reviewed-by: Mark Brown Link: https://lore.kernel.org/r/20230803133905.971697-1-zengheng4@huawei.com Signed-off-by: Will Deacon --- tools/testing/selftests/arm64/abi/hwcap.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tools/testing/selftests/arm64/abi/hwcap.c b/tools/testing/selftests/arm64/abi/hwcap.c index d4ad813fed10..6a0adf916028 100644 --- a/tools/testing/selftests/arm64/abi/hwcap.c +++ b/tools/testing/selftests/arm64/abi/hwcap.c @@ -39,6 +39,18 @@ static void cssc_sigill(void) asm volatile(".inst 0xdac01c00" : : : "x0"); } +static void ilrcpc_sigill(void) +{ + /* LDAPUR W0, [SP, #8] */ + asm volatile(".inst 0x994083e0" : : : ); +} + +static void lrcpc_sigill(void) +{ + /* LDAPR W0, [SP, #0] */ + asm volatile(".inst 0xb8bfc3e0" : : : ); +} + static void mops_sigill(void) { char dst[1], src[1]; @@ -223,6 +235,20 @@ static const struct hwcap_data { .cpuinfo = "cssc", .sigill_fn = cssc_sigill, }, + { + .name = "LRCPC", + .at_hwcap = AT_HWCAP, + .hwcap_bit = HWCAP_LRCPC, + .cpuinfo = "lrcpc", + .sigill_fn = lrcpc_sigill, + }, + { + .name = "LRCPC2", + .at_hwcap = AT_HWCAP, + .hwcap_bit = HWCAP_ILRCPC, + .cpuinfo = "ilrcpc", + .sigill_fn = ilrcpc_sigill, + }, { .name = "MOPS", .at_hwcap = AT_HWCAP2, -- cgit v1.2.3 From d6da04b6fbabf4b464bfe29e34ff10c62024d1e4 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 28 Jul 2023 00:26:12 +0100 Subject: kselftest/arm64: Exit streaming mode after collecting signal context When we collect a signal context with one of the SME modes enabled we will have enabled that mode behind the compiler and libc's back so they may issue some instructions not valid in streaming mode, causing spurious failures. For the code prior to issuing the BRK to trigger signal handling we need to stay in streaming mode if we were already there since that's a part of the signal context the caller is trying to collect. Unfortunately this code includes a memset() which is likely to be heavily optimised and is likely to use FP instructions incompatible with streaming mode. We can avoid this happening by open coding the memset(), inserting a volatile assembly statement to avoid the compiler recognising what's being done and doing something in optimisation. This code is not performance critical so the inefficiency should not be an issue. After collecting the context we can simply exit streaming mode, avoiding these issues. Use a full SMSTOP for safety to prevent any issues appearing with ZA. Reported-by: Will Deacon Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20230728-arm64-signal-memcpy-fix-v4-1-0c1290db5d46@kernel.org Signed-off-by: Will Deacon --- .../selftests/arm64/signal/test_signals_utils.h | 25 +++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.h b/tools/testing/selftests/arm64/signal/test_signals_utils.h index 222093f51b67..c7f5627171dd 100644 --- a/tools/testing/selftests/arm64/signal/test_signals_utils.h +++ b/tools/testing/selftests/arm64/signal/test_signals_utils.h @@ -60,13 +60,25 @@ static __always_inline bool get_current_context(struct tdescr *td, size_t dest_sz) { static volatile bool seen_already; + int i; + char *uc = (char *)dest_uc; assert(td && dest_uc); /* it's a genuine invocation..reinit */ seen_already = 0; td->live_uc_valid = 0; td->live_sz = dest_sz; - memset(dest_uc, 0x00, td->live_sz); + + /* + * This is a memset() but we don't want the compiler to + * optimise it into either instructions or a library call + * which might be incompatible with streaming mode. + */ + for (i = 0; i < td->live_sz; i++) { + uc[i] = 0; + __asm__ ("" : "=r" (uc[i]) : "0" (uc[i])); + } + td->live_uc = dest_uc; /* * Grab ucontext_t triggering a SIGTRAP. @@ -103,6 +115,17 @@ static __always_inline bool get_current_context(struct tdescr *td, : : "memory"); + /* + * If we were grabbing a streaming mode context then we may + * have entered streaming mode behind the system's back and + * libc or compiler generated code might decide to do + * something invalid in streaming mode, or potentially even + * the state of ZA. Issue a SMSTOP to exit both now we have + * grabbed the state. + */ + if (td->feats_supported & FEAT_SME) + asm volatile("msr S0_3_C4_C6_3, xzr"); + /* * If we get here with seen_already==1 it implies the td->live_uc * context has been used to get back here....this probably means -- cgit v1.2.3 From e5d51a6650211baf38daa894d06c47748978e141 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 28 Jul 2023 00:26:13 +0100 Subject: tools compiler.h: Add OPTIMIZER_HIDE_VAR() Port over the definition of OPTIMIZER_HIDE_VAR() so we can use it in kselftests. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20230728-arm64-signal-memcpy-fix-v4-2-0c1290db5d46@kernel.org Signed-off-by: Will Deacon --- tools/include/linux/compiler.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/include/linux/compiler.h b/tools/include/linux/compiler.h index 9d36c8ce1fe7..f75cced41d59 100644 --- a/tools/include/linux/compiler.h +++ b/tools/include/linux/compiler.h @@ -190,4 +190,10 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s #define ___PASTE(a, b) a##b #define __PASTE(a, b) ___PASTE(a, b) +#ifndef OPTIMIZER_HIDE_VAR +/* Make the optimizer believe the variable can be manipulated arbitrarily. */ +#define OPTIMIZER_HIDE_VAR(var) \ + __asm__ ("" : "=r" (var) : "0" (var)) +#endif + #endif /* _TOOLS_LINUX_COMPILER_H */ -- cgit v1.2.3 From 51e6ac1fa45160d400321fa06d7808b30d9d453c Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 28 Jul 2023 00:26:14 +0100 Subject: tools include: Add some common function attributes We don't have definitions of __always_unused or __noreturn in the tools version of compiler.h, add them so we can use them in kselftests. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20230728-arm64-signal-memcpy-fix-v4-3-0c1290db5d46@kernel.org Signed-off-by: Will Deacon --- tools/include/linux/compiler.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tools/include/linux/compiler.h b/tools/include/linux/compiler.h index f75cced41d59..1684216e826a 100644 --- a/tools/include/linux/compiler.h +++ b/tools/include/linux/compiler.h @@ -42,6 +42,18 @@ # define __always_inline inline __attribute__((always_inline)) #endif +#ifndef __always_unused +#define __always_unused __attribute__((__unused__)) +#endif + +#ifndef __noreturn +#define __noreturn __attribute__((__noreturn__)) +#endif + +#ifndef unreachable +#define unreachable() __builtin_unreachable() +#endif + #ifndef noinline #define noinline #endif -- cgit v1.2.3 From 35d7bc983a74db7067d874be2708a7d3bc269f13 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 28 Jul 2023 00:26:15 +0100 Subject: kselftest/arm64: Make the tools/include headers available Make the generic tools/include headers available to the arm64 selftests so we can reduce some duplication. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20230728-arm64-signal-memcpy-fix-v4-4-0c1290db5d46@kernel.org Signed-off-by: Will Deacon --- tools/testing/selftests/arm64/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/testing/selftests/arm64/Makefile b/tools/testing/selftests/arm64/Makefile index ace8b67fb22d..28b93cab8c0d 100644 --- a/tools/testing/selftests/arm64/Makefile +++ b/tools/testing/selftests/arm64/Makefile @@ -19,6 +19,8 @@ CFLAGS += -I$(top_srcdir)/tools/testing/selftests/ CFLAGS += $(KHDR_INCLUDES) +CFLAGS += -I$(top_srcdir)/tools/include + export CFLAGS export top_srcdir -- cgit v1.2.3 From db7a89f706d6080121b61099b1d69a752ce0c61e Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 28 Jul 2023 00:26:16 +0100 Subject: kselftest/arm64: Use shared OPTIMZER_HIDE_VAR() definiton We had open coded the definition of OPTIMIZER_HIDE_VAR() as a fix but now that we have the generic tools/include available and that has had a definition of OPTIMIZER_HIDE_VAR() we can switch to the define. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20230728-arm64-signal-memcpy-fix-v4-5-0c1290db5d46@kernel.org Signed-off-by: Will Deacon --- tools/testing/selftests/arm64/signal/test_signals_utils.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.h b/tools/testing/selftests/arm64/signal/test_signals_utils.h index c7f5627171dd..762c8fe9c54a 100644 --- a/tools/testing/selftests/arm64/signal/test_signals_utils.h +++ b/tools/testing/selftests/arm64/signal/test_signals_utils.h @@ -8,6 +8,8 @@ #include #include +#include + #include "test_signals.h" int test_init(struct tdescr *td); @@ -76,7 +78,7 @@ static __always_inline bool get_current_context(struct tdescr *td, */ for (i = 0; i < td->live_sz; i++) { uc[i] = 0; - __asm__ ("" : "=r" (uc[i]) : "0" (uc[i])); + OPTIMIZER_HIDE_VAR(uc[0]); } td->live_uc = dest_uc; -- cgit v1.2.3 From 672dbf97f6123ffe61ee46bd8bfbbe1cae6de815 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 28 Jul 2023 00:26:17 +0100 Subject: kselftest/arm64: Use the tools/include compiler.h rather than our own The BTI test program started life as standalone programs outside the kselftest suite so provided it's own compiler.h. Now that we have updated the tools/include compiler.h to have all the definitions that we are using and the arm64 selftsets pull in tools/includes let's drop our custom version. __unreachable() is named unreachable() there requiring an update in the code. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20230728-arm64-signal-memcpy-fix-v4-6-0c1290db5d46@kernel.org Signed-off-by: Will Deacon --- tools/testing/selftests/arm64/bti/compiler.h | 21 --------------------- tools/testing/selftests/arm64/bti/system.c | 4 +--- tools/testing/selftests/arm64/bti/system.h | 4 ++-- tools/testing/selftests/arm64/bti/test.c | 1 - 4 files changed, 3 insertions(+), 27 deletions(-) delete mode 100644 tools/testing/selftests/arm64/bti/compiler.h diff --git a/tools/testing/selftests/arm64/bti/compiler.h b/tools/testing/selftests/arm64/bti/compiler.h deleted file mode 100644 index ebb6204f447a..000000000000 --- a/tools/testing/selftests/arm64/bti/compiler.h +++ /dev/null @@ -1,21 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (C) 2019 Arm Limited - * Original author: Dave Martin - */ - -#ifndef COMPILER_H -#define COMPILER_H - -#define __always_unused __attribute__((__unused__)) -#define __noreturn __attribute__((__noreturn__)) -#define __unreachable() __builtin_unreachable() - -/* curse(e) has value e, but the compiler cannot assume so */ -#define curse(e) ({ \ - __typeof__(e) __curse_e = (e); \ - asm ("" : "+r" (__curse_e)); \ - __curse_e; \ -}) - -#endif /* ! COMPILER_H */ diff --git a/tools/testing/selftests/arm64/bti/system.c b/tools/testing/selftests/arm64/bti/system.c index 6385d8d4973b..93d772b00bfe 100644 --- a/tools/testing/selftests/arm64/bti/system.c +++ b/tools/testing/selftests/arm64/bti/system.c @@ -8,12 +8,10 @@ #include -#include "compiler.h" - void __noreturn exit(int n) { syscall(__NR_exit, n); - __unreachable(); + unreachable(); } ssize_t write(int fd, const void *buf, size_t size) diff --git a/tools/testing/selftests/arm64/bti/system.h b/tools/testing/selftests/arm64/bti/system.h index aca118589705..2e9ee1284a0c 100644 --- a/tools/testing/selftests/arm64/bti/system.h +++ b/tools/testing/selftests/arm64/bti/system.h @@ -14,12 +14,12 @@ typedef __kernel_size_t size_t; typedef __kernel_ssize_t ssize_t; #include +#include + #include #include #include -#include "compiler.h" - long syscall(int nr, ...); void __noreturn exit(int n); diff --git a/tools/testing/selftests/arm64/bti/test.c b/tools/testing/selftests/arm64/bti/test.c index 2cd8dcee5aec..28a8e8a28a84 100644 --- a/tools/testing/selftests/arm64/bti/test.c +++ b/tools/testing/selftests/arm64/bti/test.c @@ -17,7 +17,6 @@ typedef struct ucontext ucontext_t; #include "btitest.h" -#include "compiler.h" #include "signal.h" #define EXPECTED_TESTS 18 -- cgit v1.2.3 From eb27c76ac9e1cf5e278703db8f2fea1ed5d3f78a Mon Sep 17 00:00:00 2001 From: Zeng Heng Date: Tue, 8 Aug 2023 21:40:32 +0800 Subject: kselftest/arm64: add float-point feature to hwcap test Add the FP feature check in the set of hwcap tests. Signed-off-by: Zeng Heng Reviewed-by: Mark Brown Link: https://lore.kernel.org/r/20230808134036.668954-2-zengheng4@huawei.com Signed-off-by: Will Deacon --- tools/testing/selftests/arm64/abi/hwcap.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tools/testing/selftests/arm64/abi/hwcap.c b/tools/testing/selftests/arm64/abi/hwcap.c index 6a0adf916028..ec247587f2bf 100644 --- a/tools/testing/selftests/arm64/abi/hwcap.c +++ b/tools/testing/selftests/arm64/abi/hwcap.c @@ -39,6 +39,11 @@ static void cssc_sigill(void) asm volatile(".inst 0xdac01c00" : : : "x0"); } +static void fp_sigill(void) +{ + asm volatile("fmov s0, #1"); +} + static void ilrcpc_sigill(void) { /* LDAPUR W0, [SP, #8] */ @@ -235,6 +240,13 @@ static const struct hwcap_data { .cpuinfo = "cssc", .sigill_fn = cssc_sigill, }, + { + .name = "FP", + .at_hwcap = AT_HWCAP, + .hwcap_bit = HWCAP_FP, + .cpuinfo = "fp", + .sigill_fn = fp_sigill, + }, { .name = "LRCPC", .at_hwcap = AT_HWCAP, -- cgit v1.2.3 From 09d2e95a04ad6fd258082ea3ba9a5bf52bbd5229 Mon Sep 17 00:00:00 2001 From: Zeng Heng Date: Tue, 8 Aug 2023 21:40:33 +0800 Subject: kselftest/arm64: add crc32 feature to hwcap test Add the CRC32 feature check in the set of hwcap tests. Signed-off-by: Zeng Heng Reviewed-by: Mark Brown Link: https://lore.kernel.org/r/20230808134036.668954-3-zengheng4@huawei.com Signed-off-by: Will Deacon --- tools/testing/selftests/arm64/abi/hwcap.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tools/testing/selftests/arm64/abi/hwcap.c b/tools/testing/selftests/arm64/abi/hwcap.c index ec247587f2bf..70850bdb0e35 100644 --- a/tools/testing/selftests/arm64/abi/hwcap.c +++ b/tools/testing/selftests/arm64/abi/hwcap.c @@ -33,6 +33,11 @@ */ typedef void (*sigill_fn)(void); +static void crc32_sigill(void) +{ + asm volatile("crc32w w0, w0, w1"); +} + static void cssc_sigill(void) { /* CNT x0, x0 */ @@ -233,6 +238,13 @@ static const struct hwcap_data { sigill_fn sigill_fn; bool sigill_reliable; } hwcaps[] = { + { + .name = "CRC32", + .at_hwcap = AT_HWCAP, + .hwcap_bit = HWCAP_CRC32, + .cpuinfo = "crc32", + .sigill_fn = crc32_sigill, + }, { .name = "CSSC", .at_hwcap = AT_HWCAP2, -- cgit v1.2.3 From 71b634aba36201fa24e214db1be7ce50cf6e1863 Mon Sep 17 00:00:00 2001 From: Zeng Heng Date: Tue, 8 Aug 2023 21:40:34 +0800 Subject: kselftest/arm64: add DEF_SIGHANDLER_FUNC() and DEF_INST_RAISE_SIG() helpers Add macro definition functions DEF_SIGHANDLER_FUNC() and DEF_INST_RAISE_SIG() helpers. Furthermore, there is no need to modify the default SIGILL handling function throughout the entire testing lifecycle in the main() function. It is reasonable to narrow the scope to the context of the sig_fn function only. This is a pre-patch for the subsequent SIGBUS handler patch. Signed-off-by: Zeng Heng Reviewed-by: Mark Brown Link: https://lore.kernel.org/r/20230808134036.668954-4-zengheng4@huawei.com Signed-off-by: Will Deacon --- tools/testing/selftests/arm64/abi/hwcap.c | 118 +++++++++++++++++++----------- 1 file changed, 75 insertions(+), 43 deletions(-) diff --git a/tools/testing/selftests/arm64/abi/hwcap.c b/tools/testing/selftests/arm64/abi/hwcap.c index 70850bdb0e35..141e50c16f21 100644 --- a/tools/testing/selftests/arm64/abi/hwcap.c +++ b/tools/testing/selftests/arm64/abi/hwcap.c @@ -438,18 +438,21 @@ static const struct hwcap_data { }, }; -static bool seen_sigill; - -static void handle_sigill(int sig, siginfo_t *info, void *context) -{ - ucontext_t *uc = context; - - seen_sigill = true; - - /* Skip over the offending instruction */ - uc->uc_mcontext.pc += 4; +typedef void (*sighandler_fn)(int, siginfo_t *, void *); + +#define DEF_SIGHANDLER_FUNC(SIG, NUM) \ +static bool seen_##SIG; \ +static void handle_##SIG(int sig, siginfo_t *info, void *context) \ +{ \ + ucontext_t *uc = context; \ + \ + seen_##SIG = true; \ + /* Skip over the offending instruction */ \ + uc->uc_mcontext.pc += 4; \ } +DEF_SIGHANDLER_FUNC(sigill, SIGILL); + bool cpuinfo_present(const char *name) { FILE *f; @@ -492,25 +495,77 @@ bool cpuinfo_present(const char *name) return false; } -int main(void) +static int install_sigaction(int signum, sighandler_fn handler) { - const struct hwcap_data *hwcap; - int i, ret; - bool have_cpuinfo, have_hwcap; + int ret; struct sigaction sa; - ksft_print_header(); - ksft_set_plan(ARRAY_SIZE(hwcaps) * TESTS_PER_HWCAP); - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handle_sigill; + sa.sa_sigaction = handler; sa.sa_flags = SA_RESTART | SA_SIGINFO; sigemptyset(&sa.sa_mask); - ret = sigaction(SIGILL, &sa, NULL); + ret = sigaction(signum, &sa, NULL); if (ret < 0) ksft_exit_fail_msg("Failed to install SIGILL handler: %s (%d)\n", strerror(errno), errno); + return ret; +} + +static void uninstall_sigaction(int signum) +{ + if (sigaction(signum, NULL, NULL) < 0) + ksft_exit_fail_msg("Failed to uninstall SIGILL handler: %s (%d)\n", + strerror(errno), errno); +} + +#define DEF_INST_RAISE_SIG(SIG, NUM) \ +static bool inst_raise_##SIG(const struct hwcap_data *hwcap, \ + bool have_hwcap) \ +{ \ + if (!hwcap->SIG##_fn) { \ + ksft_test_result_skip(#SIG"_%s\n", hwcap->name); \ + /* assume that it would raise exception in default */ \ + return true; \ + } \ + \ + install_sigaction(NUM, handle_##SIG); \ + \ + seen_##SIG = false; \ + hwcap->SIG##_fn(); \ + \ + if (have_hwcap) { \ + /* Should be able to use the extension */ \ + ksft_test_result(!seen_##SIG, \ + #SIG"_%s\n", hwcap->name); \ + } else if (hwcap->SIG##_reliable) { \ + /* Guaranteed a SIGNAL */ \ + ksft_test_result(seen_##SIG, \ + #SIG"_%s\n", hwcap->name); \ + } else { \ + /* Missing SIGNAL might be fine */ \ + ksft_print_msg(#SIG"_%sreported for %s\n", \ + seen_##SIG ? "" : "not ", \ + hwcap->name); \ + ksft_test_result_skip(#SIG"_%s\n", \ + hwcap->name); \ + } \ + \ + uninstall_sigaction(NUM); \ + return seen_##SIG; \ +} + +DEF_INST_RAISE_SIG(sigill, SIGILL); + +int main(void) +{ + int i; + const struct hwcap_data *hwcap; + bool have_cpuinfo, have_hwcap; + + ksft_print_header(); + ksft_set_plan(ARRAY_SIZE(hwcaps) * TESTS_PER_HWCAP); + for (i = 0; i < ARRAY_SIZE(hwcaps); i++) { hwcap = &hwcaps[i]; @@ -523,30 +578,7 @@ int main(void) ksft_test_result(have_hwcap == have_cpuinfo, "cpuinfo_match_%s\n", hwcap->name); - if (hwcap->sigill_fn) { - seen_sigill = false; - hwcap->sigill_fn(); - - if (have_hwcap) { - /* Should be able to use the extension */ - ksft_test_result(!seen_sigill, "sigill_%s\n", - hwcap->name); - } else if (hwcap->sigill_reliable) { - /* Guaranteed a SIGILL */ - ksft_test_result(seen_sigill, "sigill_%s\n", - hwcap->name); - } else { - /* Missing SIGILL might be fine */ - ksft_print_msg("SIGILL %sreported for %s\n", - seen_sigill ? "" : "not ", - hwcap->name); - ksft_test_result_skip("sigill_%s\n", - hwcap->name); - } - } else { - ksft_test_result_skip("sigill_%s\n", - hwcap->name); - } + inst_raise_sigill(hwcap, have_hwcap); } ksft_print_cnts(); -- cgit v1.2.3 From fd49cf088867f8fad7515b5424d301ca5d147070 Mon Sep 17 00:00:00 2001 From: Zeng Heng Date: Tue, 8 Aug 2023 21:40:35 +0800 Subject: kselftest/arm64: add test item that support to capturing the SIGBUS signal Some enhanced features, such as the LSE2 feature, do not result in SILLILL if LSE2 is missing and LSE is present, but will generate a SIGBUS exception when atomic access unaligned. Therefore, we add test item to test this type of features. Notice that testing for SIGBUS only makes sense after make sure that the instruction does not cause a SIGILL signal. Signed-off-by: Zeng Heng Reviewed-by: Mark Brown Link: https://lore.kernel.org/r/20230808134036.668954-5-zengheng4@huawei.com Signed-off-by: Will Deacon --- tools/testing/selftests/arm64/abi/hwcap.c | 33 +++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/tools/testing/selftests/arm64/abi/hwcap.c b/tools/testing/selftests/arm64/abi/hwcap.c index 141e50c16f21..69234a8e8c59 100644 --- a/tools/testing/selftests/arm64/abi/hwcap.c +++ b/tools/testing/selftests/arm64/abi/hwcap.c @@ -19,19 +19,20 @@ #include "../../kselftest.h" -#define TESTS_PER_HWCAP 2 +#define TESTS_PER_HWCAP 3 /* - * Function expected to generate SIGILL when the feature is not - * supported and return when it is supported. If SIGILL is generated - * then the handler must be able to skip over the instruction safely. + * Function expected to generate exception when the feature is not + * supported and return when it is supported. If the specific exception + * is generated then the handler must be able to skip over the + * instruction safely. * * Note that it is expected that for many architecture extensions * there are no specific traps due to no architecture state being * added so we may not fault if running on a kernel which doesn't know * to add the hwcap. */ -typedef void (*sigill_fn)(void); +typedef void (*sig_fn)(void); static void crc32_sigill(void) { @@ -235,8 +236,10 @@ static const struct hwcap_data { unsigned long at_hwcap; unsigned long hwcap_bit; const char *cpuinfo; - sigill_fn sigill_fn; + sig_fn sigill_fn; bool sigill_reliable; + sig_fn sigbus_fn; + bool sigbus_reliable; } hwcaps[] = { { .name = "CRC32", @@ -452,6 +455,7 @@ static void handle_##SIG(int sig, siginfo_t *info, void *context) \ } DEF_SIGHANDLER_FUNC(sigill, SIGILL); +DEF_SIGHANDLER_FUNC(sigbus, SIGBUS); bool cpuinfo_present(const char *name) { @@ -506,7 +510,7 @@ static int install_sigaction(int signum, sighandler_fn handler) sigemptyset(&sa.sa_mask); ret = sigaction(signum, &sa, NULL); if (ret < 0) - ksft_exit_fail_msg("Failed to install SIGILL handler: %s (%d)\n", + ksft_exit_fail_msg("Failed to install SIGNAL handler: %s (%d)\n", strerror(errno), errno); return ret; @@ -515,7 +519,7 @@ static int install_sigaction(int signum, sighandler_fn handler) static void uninstall_sigaction(int signum) { if (sigaction(signum, NULL, NULL) < 0) - ksft_exit_fail_msg("Failed to uninstall SIGILL handler: %s (%d)\n", + ksft_exit_fail_msg("Failed to uninstall SIGNAL handler: %s (%d)\n", strerror(errno), errno); } @@ -556,12 +560,13 @@ static bool inst_raise_##SIG(const struct hwcap_data *hwcap, \ } DEF_INST_RAISE_SIG(sigill, SIGILL); +DEF_INST_RAISE_SIG(sigbus, SIGBUS); int main(void) { int i; const struct hwcap_data *hwcap; - bool have_cpuinfo, have_hwcap; + bool have_cpuinfo, have_hwcap, raise_sigill; ksft_print_header(); ksft_set_plan(ARRAY_SIZE(hwcaps) * TESTS_PER_HWCAP); @@ -578,7 +583,15 @@ int main(void) ksft_test_result(have_hwcap == have_cpuinfo, "cpuinfo_match_%s\n", hwcap->name); - inst_raise_sigill(hwcap, have_hwcap); + /* + * Testing for SIGBUS only makes sense after make sure + * that the instruction does not cause a SIGILL signal. + */ + raise_sigill = inst_raise_sigill(hwcap, have_hwcap); + if (!raise_sigill) + inst_raise_sigbus(hwcap, have_hwcap); + else + ksft_test_result_skip("sigbus_%s\n", hwcap->name); } ksft_print_cnts(); -- cgit v1.2.3 From 82e7882b141c177b1b09ae66e1b2ae791a9a3918 Mon Sep 17 00:00:00 2001 From: Zeng Heng Date: Tue, 8 Aug 2023 21:40:36 +0800 Subject: kselftest/arm64: add lse and lse2 features to hwcap test Add the LSE and various features check in the set of hwcap tests. As stated in the ARM manual, the LSE2 feature allows for atomic access to unaligned memory. Therefore, for processors that only have the LSE feature, we register .sigbus_fn to test their ability to perform unaligned access. Signed-off-by: Zeng Heng Reviewed-by: Mark Brown Link: https://lore.kernel.org/r/20230808134036.668954-6-zengheng4@huawei.com Signed-off-by: Will Deacon --- tools/testing/selftests/arm64/abi/hwcap.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tools/testing/selftests/arm64/abi/hwcap.c b/tools/testing/selftests/arm64/abi/hwcap.c index 69234a8e8c59..112b6a219382 100644 --- a/tools/testing/selftests/arm64/abi/hwcap.c +++ b/tools/testing/selftests/arm64/abi/hwcap.c @@ -34,6 +34,12 @@ */ typedef void (*sig_fn)(void); +static void atomics_sigill(void) +{ + /* STADD W0, [SP] */ + asm volatile(".inst 0xb82003ff" : : : ); +} + static void crc32_sigill(void) { asm volatile("crc32w w0, w0, w1"); @@ -231,6 +237,14 @@ static void svebf16_sigill(void) asm volatile(".inst 0x658aa000" : : : "z0"); } +static void uscat_sigbus(void) +{ + /* unaligned atomic access */ + asm volatile("ADD x1, sp, #2" : : : ); + /* STADD W0, [X1] */ + asm volatile(".inst 0xb820003f" : : : ); +} + static const struct hwcap_data { const char *name; unsigned long at_hwcap; @@ -276,6 +290,22 @@ static const struct hwcap_data { .cpuinfo = "ilrcpc", .sigill_fn = ilrcpc_sigill, }, + { + .name = "LSE", + .at_hwcap = AT_HWCAP, + .hwcap_bit = HWCAP_ATOMICS, + .cpuinfo = "atomics", + .sigill_fn = atomics_sigill, + }, + { + .name = "LSE2", + .at_hwcap = AT_HWCAP, + .hwcap_bit = HWCAP_USCAT, + .cpuinfo = "uscat", + .sigill_fn = atomics_sigill, + .sigbus_fn = uscat_sigbus, + .sigbus_reliable = true, + }, { .name = "MOPS", .at_hwcap = AT_HWCAP2, -- cgit v1.2.3 From 358b763ee64b11f45287c286e1f6145729ed49ab Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 10 Aug 2023 12:39:19 +0100 Subject: kselftest/arm64: Size sycall-abi buffers for the actual maximum VL Our ABI opts to provide future proofing by defining a much larger SVE_VQ_MAX than the architecture actually supports. Since we use this define to control the size of our vector data buffers this results in a lot of overhead when we initialise which can be a very noticable problem in emulation, we fill buffers that are orders of magnitude larger than we will ever actually use even with virtual platforms that provide the full range of architecturally supported vector lengths. Define and use the actual architecture maximum to mitigate this. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20230810-arm64-syscall-abi-perf-v1-1-6a0d7656359c@kernel.org Signed-off-by: Will Deacon --- tools/testing/selftests/arm64/abi/syscall-abi.c | 38 +++++++++++++++---------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/tools/testing/selftests/arm64/abi/syscall-abi.c b/tools/testing/selftests/arm64/abi/syscall-abi.c index 18cc123e2347..d704511a0955 100644 --- a/tools/testing/selftests/arm64/abi/syscall-abi.c +++ b/tools/testing/selftests/arm64/abi/syscall-abi.c @@ -20,12 +20,20 @@ #include "syscall-abi.h" +/* + * The kernel defines a much larger SVE_VQ_MAX than is expressable in + * the architecture, this creates a *lot* of overhead filling the + * buffers (especially ZA) on emulated platforms so use the actual + * architectural maximum instead. + */ +#define ARCH_SVE_VQ_MAX 16 + static int default_sme_vl; static int sve_vl_count; -static unsigned int sve_vls[SVE_VQ_MAX]; +static unsigned int sve_vls[ARCH_SVE_VQ_MAX]; static int sme_vl_count; -static unsigned int sme_vls[SVE_VQ_MAX]; +static unsigned int sme_vls[ARCH_SVE_VQ_MAX]; extern void do_syscall(int sve_vl, int sme_vl); @@ -130,9 +138,9 @@ static int check_fpr(struct syscall_cfg *cfg, int sve_vl, int sme_vl, #define SVE_Z_SHARED_BYTES (128 / 8) -static uint8_t z_zero[__SVE_ZREG_SIZE(SVE_VQ_MAX)]; -uint8_t z_in[SVE_NUM_ZREGS * __SVE_ZREG_SIZE(SVE_VQ_MAX)]; -uint8_t z_out[SVE_NUM_ZREGS * __SVE_ZREG_SIZE(SVE_VQ_MAX)]; +static uint8_t z_zero[__SVE_ZREG_SIZE(ARCH_SVE_VQ_MAX)]; +uint8_t z_in[SVE_NUM_ZREGS * __SVE_ZREG_SIZE(ARCH_SVE_VQ_MAX)]; +uint8_t z_out[SVE_NUM_ZREGS * __SVE_ZREG_SIZE(ARCH_SVE_VQ_MAX)]; static void setup_z(struct syscall_cfg *cfg, int sve_vl, int sme_vl, uint64_t svcr) @@ -190,8 +198,8 @@ static int check_z(struct syscall_cfg *cfg, int sve_vl, int sme_vl, return errors; } -uint8_t p_in[SVE_NUM_PREGS * __SVE_PREG_SIZE(SVE_VQ_MAX)]; -uint8_t p_out[SVE_NUM_PREGS * __SVE_PREG_SIZE(SVE_VQ_MAX)]; +uint8_t p_in[SVE_NUM_PREGS * __SVE_PREG_SIZE(ARCH_SVE_VQ_MAX)]; +uint8_t p_out[SVE_NUM_PREGS * __SVE_PREG_SIZE(ARCH_SVE_VQ_MAX)]; static void setup_p(struct syscall_cfg *cfg, int sve_vl, int sme_vl, uint64_t svcr) @@ -222,8 +230,8 @@ static int check_p(struct syscall_cfg *cfg, int sve_vl, int sme_vl, return errors; } -uint8_t ffr_in[__SVE_PREG_SIZE(SVE_VQ_MAX)]; -uint8_t ffr_out[__SVE_PREG_SIZE(SVE_VQ_MAX)]; +uint8_t ffr_in[__SVE_PREG_SIZE(ARCH_SVE_VQ_MAX)]; +uint8_t ffr_out[__SVE_PREG_SIZE(ARCH_SVE_VQ_MAX)]; static void setup_ffr(struct syscall_cfg *cfg, int sve_vl, int sme_vl, uint64_t svcr) @@ -300,8 +308,8 @@ static int check_svcr(struct syscall_cfg *cfg, int sve_vl, int sme_vl, return errors; } -uint8_t za_in[ZA_SIG_REGS_SIZE(SVE_VQ_MAX)]; -uint8_t za_out[ZA_SIG_REGS_SIZE(SVE_VQ_MAX)]; +uint8_t za_in[ZA_SIG_REGS_SIZE(ARCH_SVE_VQ_MAX)]; +uint8_t za_out[ZA_SIG_REGS_SIZE(ARCH_SVE_VQ_MAX)]; static void setup_za(struct syscall_cfg *cfg, int sve_vl, int sme_vl, uint64_t svcr) @@ -470,9 +478,9 @@ void sve_count_vls(void) return; /* - * Enumerate up to SVE_VQ_MAX vector lengths + * Enumerate up to ARCH_SVE_VQ_MAX vector lengths */ - for (vq = SVE_VQ_MAX; vq > 0; vq /= 2) { + for (vq = ARCH_SVE_VQ_MAX; vq > 0; vq /= 2) { vl = prctl(PR_SVE_SET_VL, vq * 16); if (vl == -1) ksft_exit_fail_msg("PR_SVE_SET_VL failed: %s (%d)\n", @@ -496,9 +504,9 @@ void sme_count_vls(void) return; /* - * Enumerate up to SVE_VQ_MAX vector lengths + * Enumerate up to ARCH_SVE_VQ_MAX vector lengths */ - for (vq = SVE_VQ_MAX; vq > 0; vq /= 2) { + for (vq = ARCH_SVE_VQ_MAX; vq > 0; vq /= 2) { vl = prctl(PR_SME_SET_VL, vq * 16); if (vl == -1) ksft_exit_fail_msg("PR_SME_SET_VL failed: %s (%d)\n", -- cgit v1.2.3 From 46862da15e37efedb7d2d21e167f506c0b533772 Mon Sep 17 00:00:00 2001 From: Ding Xiang Date: Tue, 15 Aug 2023 15:49:15 +0800 Subject: kselftest/arm64: fix a memleak in zt_regs_run() If memcmp() does not return 0, "zeros" need to be freed to prevent memleak Signed-off-by: Ding Xiang Link: https://lore.kernel.org/r/20230815074915.245528-1-dingxiang@cmss.chinamobile.com Signed-off-by: Will Deacon --- tools/testing/selftests/arm64/signal/testcases/zt_regs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/testing/selftests/arm64/signal/testcases/zt_regs.c b/tools/testing/selftests/arm64/signal/testcases/zt_regs.c index e1eb4d5c027a..2e384d731618 100644 --- a/tools/testing/selftests/arm64/signal/testcases/zt_regs.c +++ b/tools/testing/selftests/arm64/signal/testcases/zt_regs.c @@ -65,6 +65,7 @@ int zt_regs_run(struct tdescr *td, siginfo_t *si, ucontext_t *uc) if (memcmp(zeros, (char *)zt + ZT_SIG_REGS_OFFSET, ZT_SIG_REGS_SIZE(zt->nregs)) != 0) { fprintf(stderr, "ZT data invalid\n"); + free(zeros); return 1; } -- cgit v1.2.3 From e08302ee46c9a5101e3902350ba5e27fcb18894b Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Tue, 15 Aug 2023 15:59:31 +0100 Subject: kselftest/arm64: build BTI tests in output directory The arm64 BTI selftests are currently built in the source directory, then the generated binaries are copied to the output directory. This leaves the object files around in a potentially otherwise pristine source tree, tainting it for out-of-tree kernel builds. Prepend $(OUTPUT) to every reference to an object file in the Makefile, and remove the extra handling and copying. This puts all generated files under the output directory. Signed-off-by: Andre Przywara Reviewed-by: Mark Brown Link: https://lore.kernel.org/r/20230815145931.2522557-1-andre.przywara@arm.com Signed-off-by: Will Deacon --- tools/testing/selftests/arm64/bti/Makefile | 45 +++++++++++------------- tools/testing/selftests/arm64/bti/gen/.gitignore | 2 -- 2 files changed, 20 insertions(+), 27 deletions(-) delete mode 100644 tools/testing/selftests/arm64/bti/gen/.gitignore diff --git a/tools/testing/selftests/arm64/bti/Makefile b/tools/testing/selftests/arm64/bti/Makefile index ccdac414ad94..05e4ee523a53 100644 --- a/tools/testing/selftests/arm64/bti/Makefile +++ b/tools/testing/selftests/arm64/bti/Makefile @@ -2,8 +2,6 @@ TEST_GEN_PROGS := btitest nobtitest -PROGS := $(patsubst %,gen/%,$(TEST_GEN_PROGS)) - # These tests are built as freestanding binaries since otherwise BTI # support in ld.so is required which is not currently widespread; when # it is available it will still be useful to test this separately as the @@ -18,44 +16,41 @@ CFLAGS_COMMON = -ffreestanding -Wall -Wextra $(CFLAGS) BTI_CC_COMMAND = $(CC) $(CFLAGS_BTI) $(CFLAGS_COMMON) -c -o $@ $< NOBTI_CC_COMMAND = $(CC) $(CFLAGS_NOBTI) $(CFLAGS_COMMON) -c -o $@ $< -%-bti.o: %.c +$(OUTPUT)/%-bti.o: %.c $(BTI_CC_COMMAND) -%-bti.o: %.S +$(OUTPUT)/%-bti.o: %.S $(BTI_CC_COMMAND) -%-nobti.o: %.c +$(OUTPUT)/%-nobti.o: %.c $(NOBTI_CC_COMMAND) -%-nobti.o: %.S +$(OUTPUT)/%-nobti.o: %.S $(NOBTI_CC_COMMAND) BTI_OBJS = \ - test-bti.o \ - signal-bti.o \ - start-bti.o \ - syscall-bti.o \ - system-bti.o \ - teststubs-bti.o \ - trampoline-bti.o -gen/btitest: $(BTI_OBJS) + $(OUTPUT)/test-bti.o \ + $(OUTPUT)/signal-bti.o \ + $(OUTPUT)/start-bti.o \ + $(OUTPUT)/syscall-bti.o \ + $(OUTPUT)/system-bti.o \ + $(OUTPUT)/teststubs-bti.o \ + $(OUTPUT)/trampoline-bti.o +$(OUTPUT)/btitest: $(BTI_OBJS) $(CC) $(CFLAGS_BTI) $(CFLAGS_COMMON) -nostdlib -static -o $@ $^ NOBTI_OBJS = \ - test-nobti.o \ - signal-nobti.o \ - start-nobti.o \ - syscall-nobti.o \ - system-nobti.o \ - teststubs-nobti.o \ - trampoline-nobti.o -gen/nobtitest: $(NOBTI_OBJS) + $(OUTPUT)/test-nobti.o \ + $(OUTPUT)/signal-nobti.o \ + $(OUTPUT)/start-nobti.o \ + $(OUTPUT)/syscall-nobti.o \ + $(OUTPUT)/system-nobti.o \ + $(OUTPUT)/teststubs-nobti.o \ + $(OUTPUT)/trampoline-nobti.o +$(OUTPUT)/nobtitest: $(NOBTI_OBJS) $(CC) $(CFLAGS_BTI) $(CFLAGS_COMMON) -nostdlib -static -o $@ $^ # Including KSFT lib.mk here will also mangle the TEST_GEN_PROGS list # to account for any OUTPUT target-dirs optionally provided by # the toplevel makefile include ../../lib.mk - -$(TEST_GEN_PROGS): $(PROGS) - cp $(PROGS) $(OUTPUT)/ diff --git a/tools/testing/selftests/arm64/bti/gen/.gitignore b/tools/testing/selftests/arm64/bti/gen/.gitignore deleted file mode 100644 index 73869fabada4..000000000000 --- a/tools/testing/selftests/arm64/bti/gen/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -btitest -nobtitest -- cgit v1.2.3 From 7eb4ee66739ea187d3855f6dbf2ab48a512b4ae0 Mon Sep 17 00:00:00 2001 From: Zeng Heng Date: Tue, 15 Aug 2023 12:09:12 +0800 Subject: kselftest/arm64: add SHA1 and related features to hwcap test Add the SHA1 and related features check in the set of hwcap tests. Signed-off-by: Zeng Heng Reviewed-by: Mark Brown Link: https://lore.kernel.org/r/20230815040915.3966955-2-zengheng4@huawei.com Signed-off-by: Will Deacon --- tools/testing/selftests/arm64/abi/hwcap.c | 39 +++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/tools/testing/selftests/arm64/abi/hwcap.c b/tools/testing/selftests/arm64/abi/hwcap.c index 112b6a219382..83d3b6dcc0d8 100644 --- a/tools/testing/selftests/arm64/abi/hwcap.c +++ b/tools/testing/selftests/arm64/abi/hwcap.c @@ -87,6 +87,24 @@ static void rng_sigill(void) asm volatile("mrs x0, S3_3_C2_C4_0" : : : "x0"); } +static void sha1_sigill(void) +{ + /* SHA1H S0, S0 */ + asm volatile(".inst 0x5e280800" : : : ); +} + +static void sha2_sigill(void) +{ + /* SHA256H Q0, Q0, V0.4S */ + asm volatile(".inst 0x5e004000" : : : ); +} + +static void sha512_sigill(void) +{ + /* SHA512H Q0, Q0, V0.2D */ + asm volatile(".inst 0xce608000" : : : ); +} + static void sme_sigill(void) { /* RDSVL x0, #0 */ @@ -327,6 +345,27 @@ static const struct hwcap_data { .hwcap_bit = HWCAP2_RPRFM, .cpuinfo = "rprfm", }, + { + .name = "SHA1", + .at_hwcap = AT_HWCAP, + .hwcap_bit = HWCAP_SHA1, + .cpuinfo = "sha1", + .sigill_fn = sha1_sigill, + }, + { + .name = "SHA2", + .at_hwcap = AT_HWCAP, + .hwcap_bit = HWCAP_SHA2, + .cpuinfo = "sha2", + .sigill_fn = sha2_sigill, + }, + { + .name = "SHA512", + .at_hwcap = AT_HWCAP, + .hwcap_bit = HWCAP_SHA512, + .cpuinfo = "sha512", + .sigill_fn = sha512_sigill, + }, { .name = "SME", .at_hwcap = AT_HWCAP2, -- cgit v1.2.3 From 3fc3c0d1246cfe440d9c44f2134fde432b311ab3 Mon Sep 17 00:00:00 2001 From: Zeng Heng Date: Tue, 15 Aug 2023 12:09:13 +0800 Subject: kselftest/arm64: add AES feature check to hwcap test Add the AES feature check in the set of hwcap tests. Signed-off-by: Zeng Heng Reviewed-by: Mark Brown Link: https://lore.kernel.org/r/20230815040915.3966955-3-zengheng4@huawei.com Signed-off-by: Will Deacon --- tools/testing/selftests/arm64/abi/hwcap.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tools/testing/selftests/arm64/abi/hwcap.c b/tools/testing/selftests/arm64/abi/hwcap.c index 83d3b6dcc0d8..96c2611f1ac0 100644 --- a/tools/testing/selftests/arm64/abi/hwcap.c +++ b/tools/testing/selftests/arm64/abi/hwcap.c @@ -34,6 +34,12 @@ */ typedef void (*sig_fn)(void); +static void aes_sigill(void) +{ + /* AESE V0.16B, V0.16B */ + asm volatile(".inst 0x4e284800" : : : ); +} + static void atomics_sigill(void) { /* STADD W0, [SP] */ @@ -273,6 +279,13 @@ static const struct hwcap_data { sig_fn sigbus_fn; bool sigbus_reliable; } hwcaps[] = { + { + .name = "AES", + .at_hwcap = AT_HWCAP, + .hwcap_bit = HWCAP_AES, + .cpuinfo = "aes", + .sigill_fn = aes_sigill, + }, { .name = "CRC32", .at_hwcap = AT_HWCAP, -- cgit v1.2.3 From 2c3ce0e7dd5154ffa017cd4dab3b14c09272c4a5 Mon Sep 17 00:00:00 2001 From: Zeng Heng Date: Tue, 15 Aug 2023 12:09:14 +0800 Subject: kselftest/arm64: add pmull feature to hwcap test Add the pmull feature check in the set of hwcap tests. Signed-off-by: Zeng Heng Reviewed-by: Mark Brown Link: https://lore.kernel.org/r/20230815040915.3966955-4-zengheng4@huawei.com Signed-off-by: Will Deacon --- tools/testing/selftests/arm64/abi/hwcap.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tools/testing/selftests/arm64/abi/hwcap.c b/tools/testing/selftests/arm64/abi/hwcap.c index 96c2611f1ac0..b3492a944503 100644 --- a/tools/testing/selftests/arm64/abi/hwcap.c +++ b/tools/testing/selftests/arm64/abi/hwcap.c @@ -88,6 +88,12 @@ static void mops_sigill(void) : "cc", "memory"); } +static void pmull_sigill(void) +{ + /* PMULL V0.1Q, V0.1D, V0.1D */ + asm volatile(".inst 0x0ee0e000" : : : ); +} + static void rng_sigill(void) { asm volatile("mrs x0, S3_3_C2_C4_0" : : : "x0"); @@ -345,6 +351,13 @@ static const struct hwcap_data { .sigill_fn = mops_sigill, .sigill_reliable = true, }, + { + .name = "PMULL", + .at_hwcap = AT_HWCAP, + .hwcap_bit = HWCAP_PMULL, + .cpuinfo = "pmull", + .sigill_fn = pmull_sigill, + }, { .name = "RNG", .at_hwcap = AT_HWCAP2, -- cgit v1.2.3 From fcb0b51a5dca1f69f408dfe5fd970cf167d41538 Mon Sep 17 00:00:00 2001 From: Zeng Heng Date: Tue, 15 Aug 2023 12:09:15 +0800 Subject: kselftest/arm64: add jscvt feature to hwcap test Add the jscvt feature check in the set of hwcap tests. Due to the requirement of jscvt feature, a compiler configuration of v8.3 or above is needed to support assembly. Therefore, hand encode is used here instead. Signed-off-by: Zeng Heng Reviewed-by: Mark Brown Link: https://lore.kernel.org/r/20230815040915.3966955-5-zengheng4@huawei.com Signed-off-by: Will Deacon --- tools/testing/selftests/arm64/abi/hwcap.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tools/testing/selftests/arm64/abi/hwcap.c b/tools/testing/selftests/arm64/abi/hwcap.c index b3492a944503..fe844b825a1e 100644 --- a/tools/testing/selftests/arm64/abi/hwcap.c +++ b/tools/testing/selftests/arm64/abi/hwcap.c @@ -68,6 +68,12 @@ static void ilrcpc_sigill(void) asm volatile(".inst 0x994083e0" : : : ); } +static void jscvt_sigill(void) +{ + /* FJCVTZS W0, D0 */ + asm volatile(".inst 0x1e7e0000" : : : ); +} + static void lrcpc_sigill(void) { /* LDAPR W0, [SP, #0] */ @@ -313,6 +319,13 @@ static const struct hwcap_data { .cpuinfo = "fp", .sigill_fn = fp_sigill, }, + { + .name = "JSCVT", + .at_hwcap = AT_HWCAP, + .hwcap_bit = HWCAP_JSCVT, + .cpuinfo = "jscvt", + .sigill_fn = jscvt_sigill, + }, { .name = "LRCPC", .at_hwcap = AT_HWCAP, -- cgit v1.2.3 From 94f23ac36f8b3c2140b00d78131c8df41cd9ac5d Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 16 Aug 2023 19:39:32 +0100 Subject: kselftest/arm64: Fix hwcaps selftest build The hwcaps selftest currently relies on the assembler being able to assemble the crc32w instruction but this is not in the base v8.0 so is not accepted by the standard GCC configurations used by many distributions. Switch to manually encoding to fix the build. Fixes: 09d2e95a04ad ("kselftest/arm64: add crc32 feature to hwcap test") Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20230816-arm64-fix-crc32-build-v1-1-40165c1290f2@kernel.org Signed-off-by: Will Deacon --- tools/testing/selftests/arm64/abi/hwcap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/arm64/abi/hwcap.c b/tools/testing/selftests/arm64/abi/hwcap.c index fe844b825a1e..0593192c0753 100644 --- a/tools/testing/selftests/arm64/abi/hwcap.c +++ b/tools/testing/selftests/arm64/abi/hwcap.c @@ -48,7 +48,8 @@ static void atomics_sigill(void) static void crc32_sigill(void) { - asm volatile("crc32w w0, w0, w1"); + /* CRC32W W0, W0, W1 */ + asm volatile(".inst 0x1ac14800" : : : ); } static void cssc_sigill(void) -- cgit v1.2.3