Sorry for the delay in this update.
Changes from v1: * Improve the skip message along with the changelog massage (Suah Khan). * Simplify the feature support check (Suah Khan).
=== Cover Letter ===
A couple of test updates are included:
* With the STRICT_SIGALTSTACK_SIZE option [1,2], the kernel's altstack check becomes stringent. The x86 sigaltstack test is ignorant about this. Adjust the test now. This check was established [3] to ensure every AMX task's altstack is sufficient (regardless of that option) [4].
* The AMX test wrongly fails on non-AMX machines. Fix the code to skip the test instead.
The series is available in this repository: git://github.com/intel/amx-linux.git selftest
[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch... [2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Docu... [3] 3aac3ebea08f ("x86/signal: Implement sigaltstack size validation") [4] 4b7ca609a33d ("x86/signal: Use fpu::__state_user_size for sigalt stack validation")
Chang S. Bae (2): selftests/x86/signal: Adjust the test to the kernel's altstack check selftests/x86/amx: Fix the test to avoid failure when AMX is unavailable
tools/testing/selftests/x86/amx.c | 31 ++++++++--------------- tools/testing/selftests/x86/sigaltstack.c | 14 +++++++++- 2 files changed, 23 insertions(+), 22 deletions(-)
base-commit: 32346491ddf24599decca06190ebca03ff9de7f8
The test assumes an insufficient altstack is allowed. Then it raises a signal to test the delivery failure due to an altstack overflow.
The kernel now provides the STRICT_SIGALTSTACK_SIZE option to tweak sigaltstack()'s sanity check to prevent an insufficient altstack. ENOMEM is returned on the check failure.
Adjust the code to skip the test when this option is on.
Signed-off-by: Chang S. Bae chang.seok.bae@intel.com Reviewed-by: Shuah Khan skhan@linuxfoundation.org Cc: linux-kselftest@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- Changes from v1: * Call out the config name (Shuah Khan). * Massage the print message (Shuah Khan). --- tools/testing/selftests/x86/sigaltstack.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/x86/sigaltstack.c b/tools/testing/selftests/x86/sigaltstack.c index f689af75e979..0e9842e69ca4 100644 --- a/tools/testing/selftests/x86/sigaltstack.c +++ b/tools/testing/selftests/x86/sigaltstack.c @@ -88,8 +88,20 @@ static void sigalrm(int sig, siginfo_t *info, void *ctx_void)
static void test_sigaltstack(void *altstack, unsigned long size) { - if (setup_altstack(altstack, size)) + if (setup_altstack(altstack, size)) { + /* + * If the kernel rejects an insufficient altstack with + * ENOMEM, then skip the test. + */ + if (errno == ENOMEM && size < at_minstack_size) { + printf("[SKIP]\tThe running kernel disallows an insufficient altstack with " + "the STRICT_SIGALTSTACK_SIZE option. As the altstack was already " + "measured, the overflow test is not needed.\n"); + return; + } + err(1, "sigaltstack()"); + }
sigalrm_expected = (size > at_minstack_size) ? true : false;
When a CPU does not have AMX, the test fails. But this is wrong as it should be runnable regardless. Skip the test instead.
Also, simplify the feature check using arch_prctl() instead of CPUID. The syscall is more trustworthy as the kernel controls the feature permission.
Reported-by: Thomas Gleixner tglx@linutronix.de Fixes: 6a3e0651b4a ("selftests/x86/amx: Add test cases for AMX state management") Signed-off-by: Chang S. Bae chang.seok.bae@intel.com Cc: linux-kselftest@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- Changes from v1: * Simplify the feature check code (Shuah Khan). --- tools/testing/selftests/x86/amx.c | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-)
diff --git a/tools/testing/selftests/x86/amx.c b/tools/testing/selftests/x86/amx.c index 625e42901237..52e7dec50018 100644 --- a/tools/testing/selftests/x86/amx.c +++ b/tools/testing/selftests/x86/amx.c @@ -99,24 +99,6 @@ static void clearhandler(int sig) #define XFEATURE_MASK_XTILEDATA (1 << XFEATURE_XTILEDATA) #define XFEATURE_MASK_XTILE (XFEATURE_MASK_XTILECFG | XFEATURE_MASK_XTILEDATA)
-#define CPUID_LEAF1_ECX_XSAVE_MASK (1 << 26) -#define CPUID_LEAF1_ECX_OSXSAVE_MASK (1 << 27) -static inline void check_cpuid_xsave(void) -{ - uint32_t eax, ebx, ecx, edx; - - /* - * CPUID.1:ECX.XSAVE[bit 26] enumerates general - * support for the XSAVE feature set, including - * XGETBV. - */ - __cpuid_count(1, 0, eax, ebx, ecx, edx); - if (!(ecx & CPUID_LEAF1_ECX_XSAVE_MASK)) - fatal_error("cpuid: no CPU xsave support"); - if (!(ecx & CPUID_LEAF1_ECX_OSXSAVE_MASK)) - fatal_error("cpuid: no OS xsave support"); -} - static uint32_t xbuf_size;
static struct { @@ -348,6 +330,7 @@ enum expected_result { FAIL_EXPECTED, SUCCESS_EXPECTED };
/* arch_prctl() and sigaltstack() test */
+#define ARCH_GET_XCOMP_SUPP 0x1021 #define ARCH_GET_XCOMP_PERM 0x1022 #define ARCH_REQ_XCOMP_PERM 0x1023
@@ -828,10 +811,16 @@ static void test_context_switch(void)
int main(void) { - /* Check hardware availability at first */ - check_cpuid_xsave(); - check_cpuid_xtiledata(); + unsigned long features; + long rc;
+ rc = syscall(SYS_arch_prctl, ARCH_GET_XCOMP_SUPP, &features); + if (rc || (features & XFEATURE_MASK_XTILE) != XFEATURE_MASK_XTILE) { + printf("[SKIP]\tno AMX support.\n"); + exit(KSFT_FAIL); + } + + check_cpuid_xtiledata(); init_stashed_xsave(); sethandler(SIGILL, handle_noperm, 0);
Dear maintainers,
Let me follow up on the last posting [5] with these two small changes: * Clean up unused code in the AMX test. * Fix the subsystem name in the patch1 subject.
Here is a summary of the included test code changes:
* With the STRICT_SIGALTSTACK_SIZE option [1,2], the kernel's altstack check becomes stringent. The x86 sigaltstack test is ignorant about this. Adjust the test. This check was established [3] to ensure every AMX task's altstack is sufficient (regardless of that option) [4].
* The AMX test wrongly fails on non-AMX machines. Fix the code to skip the test instead.
* It also has some unused code. Remove them where at this.
The series is available in this repository: git://github.com/intel/amx-linux.git selftest
Thanks, Chang
[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch... [2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Docu... [3] 3aac3ebea08f ("x86/signal: Implement sigaltstack size validation") [4] 4b7ca609a33d ("x86/signal: Use fpu::__state_user_size for sigalt stack validation") [5] https://lore.kernel.org/lkml/20220711170330.27138-1-chang.seok.bae@intel.com...
Chang S. Bae (3): selftests/x86/sigaltstack: Adjust the test to the kernel's altstack check selftests/x86/amx: Fix the test to avoid failure when AMX is unavailable selftests/x86/amx: Remove unneeded code
tools/testing/selftests/x86/amx.c | 51 +++++------------------ tools/testing/selftests/x86/sigaltstack.c | 12 +++++- 2 files changed, 21 insertions(+), 42 deletions(-)
base-commit: 197b6b60ae7bc51dd0814953c562833143b292aa
The test assumes an insufficient altstack is allowed. Then it raises a signal to test the delivery failure due to an altstack overflow.
The kernel now provides the STRICT_SIGALTSTACK_SIZE option to tweak sigaltstack()'s sanity check to prevent an insufficient altstack. ENOMEM is returned on the check failure.
Adjust the code to skip the test when this option is on.
Signed-off-by: Chang S. Bae chang.seok.bae@intel.com Reviewed-by: Shuah Khan skhan@linuxfoundation.org Cc: Shuah Khan shuah@kernel.org Cc: Thomas Gleixner tglx@linutronix.de Cc: Borislav Petkov bp@alien8.de Cc: Dave Hansen dave.hansen@linux.intel.com Cc: linux-kselftest@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- Changes from v2: * Fix the subsystem name in the subject.
Changes from v1: * Call out the config name (Shuah Khan). * Massage the print message (Shuah Khan). --- tools/testing/selftests/x86/sigaltstack.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/x86/sigaltstack.c b/tools/testing/selftests/x86/sigaltstack.c index f689af75e979..22a88b764a8e 100644 --- a/tools/testing/selftests/x86/sigaltstack.c +++ b/tools/testing/selftests/x86/sigaltstack.c @@ -88,8 +88,18 @@ static void sigalrm(int sig, siginfo_t *info, void *ctx_void)
static void test_sigaltstack(void *altstack, unsigned long size) { - if (setup_altstack(altstack, size)) + if (setup_altstack(altstack, size)) { + /* + * The kernel may return ENOMEM when the altstack size + * is insufficient. Skip the test in this case. + */ + if (errno == ENOMEM && size < at_minstack_size) { + printf("[SKIP]\tThe running kernel disallows an insufficient size.\n"); + return; + } + err(1, "sigaltstack()"); + }
sigalrm_expected = (size > at_minstack_size) ? true : false;
When a CPU does not have AMX, the test fails. But this is wrong as it should be runnable regardless. Skip the test instead.
Also, simplify the feature check using arch_prctl() instead of CPUID. The syscall is more trustworthy as the kernel controls the feature permission.
Reported-by: Thomas Gleixner tglx@linutronix.de Fixes: 6a3e0651b4a ("selftests/x86/amx: Add test cases for AMX state management") Signed-off-by: Chang S. Bae chang.seok.bae@intel.com Cc: Shuah Khan shuah@kernel.org Cc: Thomas Gleixner tglx@linutronix.de Cc: Dave Hansen dave.hansen@linux.intel.com Cc: linux-kselftest@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- Changes from v2: None
Changes from v1: * Simplify the feature check code (Shuah Khan). --- tools/testing/selftests/x86/amx.c | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-)
diff --git a/tools/testing/selftests/x86/amx.c b/tools/testing/selftests/x86/amx.c index d884fd69dd51..f0b1efe89ef7 100644 --- a/tools/testing/selftests/x86/amx.c +++ b/tools/testing/selftests/x86/amx.c @@ -101,24 +101,6 @@ static void clearhandler(int sig) #define XFEATURE_MASK_XTILEDATA (1 << XFEATURE_XTILEDATA) #define XFEATURE_MASK_XTILE (XFEATURE_MASK_XTILECFG | XFEATURE_MASK_XTILEDATA)
-#define CPUID_LEAF1_ECX_XSAVE_MASK (1 << 26) -#define CPUID_LEAF1_ECX_OSXSAVE_MASK (1 << 27) -static inline void check_cpuid_xsave(void) -{ - uint32_t eax, ebx, ecx, edx; - - /* - * CPUID.1:ECX.XSAVE[bit 26] enumerates general - * support for the XSAVE feature set, including - * XGETBV. - */ - __cpuid_count(1, 0, eax, ebx, ecx, edx); - if (!(ecx & CPUID_LEAF1_ECX_XSAVE_MASK)) - fatal_error("cpuid: no CPU xsave support"); - if (!(ecx & CPUID_LEAF1_ECX_OSXSAVE_MASK)) - fatal_error("cpuid: no OS xsave support"); -} - static uint32_t xbuf_size;
static struct { @@ -350,6 +332,7 @@ enum expected_result { FAIL_EXPECTED, SUCCESS_EXPECTED };
/* arch_prctl() and sigaltstack() test */
+#define ARCH_GET_XCOMP_SUPP 0x1021 #define ARCH_GET_XCOMP_PERM 0x1022 #define ARCH_REQ_XCOMP_PERM 0x1023
@@ -928,10 +911,16 @@ static void test_ptrace(void)
int main(void) { - /* Check hardware availability at first */ - check_cpuid_xsave(); - check_cpuid_xtiledata(); + unsigned long features; + long rc;
+ rc = syscall(SYS_arch_prctl, ARCH_GET_XCOMP_SUPP, &features); + if (rc || (features & XFEATURE_MASK_XTILE) != XFEATURE_MASK_XTILE) { + printf("[SKIP]\tno AMX support.\n"); + exit(KSFT_FAIL); + } + + check_cpuid_xtiledata(); init_stashed_xsave(); sethandler(SIGILL, handle_noperm, 0);
Remove some unused helper code. Also, get rid of the redundant permission request.
Signed-off-by: Chang S. Bae chang.seok.bae@intel.com Cc: Shuah Khan shuah@kernel.org Cc: Thomas Gleixner tglx@linutronix.de Cc: Dave Hansen dave.hansen@linux.intel.com Cc: linux-kselftest@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- Changes from v2: * Add as a new patch --- tools/testing/selftests/x86/amx.c | 20 -------------------- 1 file changed, 20 deletions(-)
diff --git a/tools/testing/selftests/x86/amx.c b/tools/testing/selftests/x86/amx.c index f0b1efe89ef7..854f7d61be89 100644 --- a/tools/testing/selftests/x86/amx.c +++ b/tools/testing/selftests/x86/amx.c @@ -39,16 +39,6 @@ struct xsave_buffer { }; };
-static inline uint64_t xgetbv(uint32_t index) -{ - uint32_t eax, edx; - - asm volatile("xgetbv;" - : "=a" (eax), "=d" (edx) - : "c" (index)); - return eax + ((uint64_t)edx << 32); -} - static inline void xsave(struct xsave_buffer *xbuf, uint64_t rfbm) { uint32_t rfbm_lo = rfbm; @@ -110,8 +100,6 @@ static struct {
#define CPUID_LEAF_XSTATE 0xd #define CPUID_SUBLEAF_XSTATE_USER 0x0 -#define TILE_CPUID 0x1d -#define TILE_PALETTE_ID 0x1
static void check_cpuid_xtiledata(void) { @@ -161,12 +149,6 @@ static inline void clear_xstate_header(struct xsave_buffer *buffer) memset(&buffer->header, 0, sizeof(buffer->header)); }
-static inline uint64_t get_xstatebv(struct xsave_buffer *buffer) -{ - /* XSTATE_BV is at the beginning of the header: */ - return *(uint64_t *)&buffer->header; -} - static inline void set_xstatebv(struct xsave_buffer *buffer, uint64_t bv) { /* XSTATE_BV is at the beginning of the header: */ @@ -769,8 +751,6 @@ static void test_context_switch(void) /* Affinitize to one CPU to force context switches */ affinitize_cpu0();
- req_xtiledata_perm(); - printf("[RUN]\tCheck tiledata context switches, %d iterations, %d threads.\n", ctxtswtest_config.iterations, ctxtswtest_config.num_threads);
linux-kselftest-mirror@lists.linaro.org