From 0643c69caf4d4a138a21529081ab3084963da536 Mon Sep 17 00:00:00 2001 From: Hendrik Greving <hgreving@google.com> Date: Mon, 29 Jul 2019 11:59:27 -0700 Subject: [PATCH 1/7] i#3756: Fix copying signal magic1 value. Fixes copying the current state when delivering pending signals by preserving the original magic1 value of the signal's fpstate. Re-factor AVX detection in test linux.sigcontext and add support to actually test the AVX state on supported machines. Adds new <test>_runavx and <test>_runavx512 variables to the cmake suite similar to _runcmp, in order to propagate the __AVX__ and __AVX512F__ defines to the template parsers which are usually automatically defined by the compiler. Updates a comment w.r.t. alignment of a stack variable we're declaring. Fixes #3756 --- core/unix/signal_linux_x86.c | 16 +++++++----- suite/tests/CMakeLists.txt | 12 +++++++++ suite/tests/linux/sigcontext.c | 35 ++++++--------------------- suite/tests/linux/sigcontext.template | 32 ++++++++++++++++-------- 4 files changed, 52 insertions(+), 43 deletions(-) diff --git a/core/unix/signal_linux_x86.c b/core/unix/signal_linux_x86.c index 035e14489..2ad44ebad 100644 --- a/core/unix/signal_linux_x86.c +++ b/core/unix/signal_linux_x86.c @@ -179,7 +179,8 @@ convert_fxsave_to_fpstate(kernel_fpstate_t *fpstate, struct i387_fxsave_struct * fpstate->status = fxsave->swd; fpstate->magic = X86_FXSR_MAGIC; - memcpy(&fpstate->_fxsr_env[0], fxsave, sizeof(struct i387_fxsave_struct)); + memcpy(&fpstate->_fxsr_env[0], fxsave, + sizeof(struct i387_fxsave_struct) - sizeof(fpstate->sw_reserved)); } #endif /* !X64 */ @@ -258,13 +259,14 @@ save_xmm(dcontext_t *dcontext, sigframe_rt_t *frame) void save_fpstate(dcontext_t *dcontext, sigframe_rt_t *frame) { - /* FIXME: is there a better way to align this thing? - * the __attribute__ on the struct above doesn't do it + /* The compiler may not be able to properly align stack variables even with + * __attribute__((aligned()). We maintain this array to enforce alignment. */ - char align[sizeof(union i387_union) + 16]; + char align[sizeof(union i387_union) + 16] __attribute__((aligned(16))); union i387_union *temp = (union i387_union *)((((ptr_uint_t)align) + 16) & ((ptr_uint_t)-16)); sigcontext_t *sc = get_sigcontext_from_rt_frame(frame); + LOG(THREAD, LOG_ASYNCH, 3, "save_fpstate\n"); if (sc->fpstate == NULL) { /* Nothing to do: there was no fpstate to save at the time the kernel @@ -285,7 +287,8 @@ save_fpstate(dcontext_t *dcontext, sigframe_rt_t *frame) asm volatile("fxsaveq %0 ; fnclex" : "=m"(temp->fxsave)); /* now convert into kernel_fpstate_t form */ ASSERT(sizeof(kernel_fpstate_t) == sizeof(struct i387_fxsave_struct)); - memcpy(sc->fpstate, &temp->fxsave, sizeof(struct i387_fxsave_struct)); + memcpy(sc->fpstate, &temp->fxsave, + sizeof(struct i387_fxsave_struct) - sizeof(sc->fpstate->sw_reserved)); #else /* this is "unlazy_fpu" */ asm volatile("fxsave %0 ; fnclex" : "=m"(temp->fxsave)); @@ -299,7 +302,8 @@ save_fpstate(dcontext_t *dcontext, sigframe_rt_t *frame) asm volatile("fnsave %0 ; fwait" : "=m"(temp->fsave)); /* now convert into kernel_fpstate_t form */ temp->fsave.status = temp->fsave.swd; - memcpy(sc->fpstate, &temp->fsave, sizeof(struct i387_fsave_struct)); + memcpy(sc->fpstate, &temp->fsave, + sizeof(struct i387_fsave_struct) - sizeof(sc->fpstate->sw_reserved)); } save_xmm(dcontext, frame); diff --git a/suite/tests/CMakeLists.txt b/suite/tests/CMakeLists.txt index d69274bf3..33ad80972 100644 --- a/suite/tests/CMakeLists.txt +++ b/suite/tests/CMakeLists.txt @@ -1031,6 +1031,11 @@ function(template2expect outexpect template runops key) # so currently this is unused. set(rundefs "${rundefs} -DCYGWIN") endif () + if (DEFINED ${key}_runavx512) + set(rundefs "${rundefs} -D__AVX__ -D__AVX512F__") + elseif (DEFINED ${key}_runavx) + set(rundefs "${rundefs} -D__AVX__") + endif () string(STRIP "${rundefs}" rundefs) @@ -3319,6 +3324,13 @@ if (UNIX) # FIXME i#58: port test to MacOS if (NOT ARM AND NOT AARCH64 AND NOT APPLE) tobuild(linux.sigcontext linux/sigcontext.c) + if (proc_supports_avx512) + append_property_string(TARGET linux.sigcontext COMPILE_FLAGS "${CFLAGS_AVX512}") + set(linux.sigcontext_runavx512 1) + elseif (proc_supports_avx) + append_property_string(TARGET linux.sigcontext COMPILE_FLAGS "${CFLAGS_AVX}") + set(linux.sigcontext_runavx 1) + endif () endif () if (NOT APPLE) tobuild(linux.thread linux/thread.c) diff --git a/suite/tests/linux/sigcontext.c b/suite/tests/linux/sigcontext.c index e768d5e5a..dc1aa8bb3 100644 --- a/suite/tests/linux/sigcontext.c +++ b/suite/tests/linux/sigcontext.c @@ -97,9 +97,8 @@ signal_handler(int sig, siginfo_t *siginfo, ucontext_t *ucxt) kernel_xstate_t *xstate = (kernel_xstate_t *)ucxt->uc_mcontext.fpregs; if (xstate->fpstate.sw_reserved.magic1 == FP_XSTATE_MAGIC1) { assert(xstate->fpstate.sw_reserved.xstate_size >= sizeof(*xstate)); - /* we can't print b/c not all processors have avx */ for (i = 0; i < NUM_SIMD_REGS; i++) { -#if VERBOSE +#ifdef __AVX__ print("ymmh[%d] = 0x%x 0x%x 0x%x 0x%x\n", i, xstate->ymmh.ymmh_space[i * 4], xstate->ymmh.ymmh_space[i * 4 + 1], @@ -117,28 +116,6 @@ signal_handler(int sig, siginfo_t *siginfo, ucontext_t *ucxt) } } -/* looks for "avx" flag in /proc/cpuinfo */ -static int -determine_avx(void) -{ - FILE *cpuinfo; - char line[1024]; - ulong cpu_mhz = 1, cpu_khz = 0; - - cpuinfo = fopen("/proc/cpuinfo", "r"); - assert(cpuinfo != NULL); - - while (!feof(cpuinfo)) { - if (fgets(line, sizeof(line), cpuinfo) == NULL) - break; - if (strstr(line, "flags") == line && strstr(line, "avx") != NULL) { - return 1; - } - } - fclose(cpuinfo); - return 0; -} - int main(int argc, char *argv[]) { @@ -177,12 +154,15 @@ main(int argc, char *argv[]) /* we assume xmm* won't be overwritten by this library call before the signal */ kill(getpid(), SIGUSR1); - if (determine_avx()) { +#ifdef __AVX__ + { /* put known values in ymm regs */ int buf[INTS_PER_YMM * NUM_SIMD_REGS]; char *ptr = (char *)buf; int i, j; intercept_signal(SIGUSR2, signal_handler, false); + print("Sending SIGUSR2\n"); + /* put known values in xmm regs (we assume processor has xmm) */ for (i = 0; i < NUM_SIMD_REGS; i++) { for (j = 0; j < INTS_PER_YMM; j++) @@ -197,7 +177,7 @@ main(int argc, char *argv[]) __asm("mov %0, %%" XAX "; vmovdqu 0xa0(%%" XAX "),%%ymm5" : : "m"(ptr) : "%" XAX); __asm("mov %0, %%" XAX "; vmovdqu 0xc0(%%" XAX "),%%ymm6" : : "m"(ptr) : "%" XAX); __asm("mov %0, %%" XAX "; vmovdqu 0xe0(%%" XAX "),%%ymm7" : : "m"(ptr) : "%" XAX); -#ifdef X64 +# ifdef X64 __asm("mov %0, %%" XAX "; vmovdqu 0x100(%%" XAX "),%%ymm8" : : "m"(ptr) @@ -230,10 +210,11 @@ main(int argc, char *argv[]) : : "m"(ptr) : "%" XAX); -#endif +# endif /* now make sure they show up in signal context */ kill(getpid(), SIGUSR2); } +#endif print("All done\n"); return 0; diff --git a/suite/tests/linux/sigcontext.template b/suite/tests/linux/sigcontext.template index 62d4bb308..54f60f0f8 100644 --- a/suite/tests/linux/sigcontext.template +++ b/suite/tests/linux/sigcontext.template @@ -1,5 +1,4 @@ Sending SIGUSR1 -#ifdef X64 xmm[0] = 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef xmm[1] = 0xbd5b7dde 0xbd5b7dde 0xbd5b7dde 0xbd5b7dde xmm[2] = 0x7ab6fbbc 0x7ab6fbbc 0x7ab6fbbc 0x7ab6fbbc @@ -8,6 +7,7 @@ xmm[4] = 0xeadbeef0 0xeadbeef0 0xeadbeef0 0xeadbeef0 xmm[5] = 0xd5b7dde0 0xd5b7dde0 0xd5b7dde0 0xd5b7dde0 xmm[6] = 0xab6fbbc0 0xab6fbbc0 0xab6fbbc0 0xab6fbbc0 xmm[7] = 0x56df7780 0x56df7780 0x56df7780 0x56df7780 +#ifdef X64 xmm[8] = 0xadbeef00 0xadbeef00 0xadbeef00 0xadbeef00 xmm[9] = 0x5b7dde00 0x5b7dde00 0x5b7dde00 0x5b7dde00 xmm[10] = 0xb6fbbc00 0xb6fbbc00 0xb6fbbc00 0xb6fbbc00 @@ -16,14 +16,26 @@ xmm[12] = 0xdbeef000 0xdbeef000 0xdbeef000 0xdbeef000 xmm[13] = 0xb7dde000 0xb7dde000 0xb7dde000 0xb7dde000 xmm[14] = 0x6fbbc000 0x6fbbc000 0x6fbbc000 0x6fbbc000 xmm[15] = 0xdf778000 0xdf778000 0xdf778000 0xdf778000 -#else -xmm[0] = 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef -xmm[1] = 0xbd5b7dde 0xbd5b7dde 0xbd5b7dde 0xbd5b7dde -xmm[2] = 0x7ab6fbbc 0x7ab6fbbc 0x7ab6fbbc 0x7ab6fbbc -xmm[3] = 0xf56df778 0xf56df778 0xf56df778 0xf56df778 -xmm[4] = 0xeadbeef0 0xeadbeef0 0xeadbeef0 0xeadbeef0 -xmm[5] = 0xd5b7dde0 0xd5b7dde0 0xd5b7dde0 0xd5b7dde0 -xmm[6] = 0xab6fbbc0 0xab6fbbc0 0xab6fbbc0 0xab6fbbc0 -xmm[7] = 0x56df7780 0x56df7780 0x56df7780 0x56df7780 +#endif +#ifdef __AVX__ +Sending SIGUSR2 +ymmh[0] = 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef +ymmh[1] = 0xbd5b7dde 0xbd5b7dde 0xbd5b7dde 0xbd5b7dde +ymmh[2] = 0x7ab6fbbc 0x7ab6fbbc 0x7ab6fbbc 0x7ab6fbbc +ymmh[3] = 0xf56df778 0xf56df778 0xf56df778 0xf56df778 +ymmh[4] = 0xeadbeef0 0xeadbeef0 0xeadbeef0 0xeadbeef0 +ymmh[5] = 0xd5b7dde0 0xd5b7dde0 0xd5b7dde0 0xd5b7dde0 +ymmh[6] = 0xab6fbbc0 0xab6fbbc0 0xab6fbbc0 0xab6fbbc0 +ymmh[7] = 0x56df7780 0x56df7780 0x56df7780 0x56df7780 +#ifdef X64 +ymmh[8] = 0xadbeef00 0xadbeef00 0xadbeef00 0xadbeef00 +ymmh[9] = 0x5b7dde00 0x5b7dde00 0x5b7dde00 0x5b7dde00 +ymmh[10] = 0xb6fbbc00 0xb6fbbc00 0xb6fbbc00 0xb6fbbc00 +ymmh[11] = 0x6df77800 0x6df77800 0x6df77800 0x6df77800 +ymmh[12] = 0xdbeef000 0xdbeef000 0xdbeef000 0xdbeef000 +ymmh[13] = 0xb7dde000 0xb7dde000 0xb7dde000 0xb7dde000 +ymmh[14] = 0x6fbbc000 0x6fbbc000 0x6fbbc000 0x6fbbc000 +ymmh[15] = 0xdf778000 0xdf778000 0xdf778000 0xdf778000 +#endif #endif All done -- GitLab From 5787df2d86907ee7ac7ae4dac6ab4c8a8cbfe7d7 Mon Sep 17 00:00:00 2001 From: Hendrik Greving <hgreving@google.com> Date: Mon, 29 Jul 2019 14:55:08 -0700 Subject: [PATCH 2/7] *** Temporary commit, due to only reproducible on Travis *** --- suite/runsuite_wrapper.pl | 2 +- suite/tests/linux/sigcontext.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/suite/runsuite_wrapper.pl b/suite/runsuite_wrapper.pl index a8684ff4c..55fd2c0a8 100755 --- a/suite/runsuite_wrapper.pl +++ b/suite/runsuite_wrapper.pl @@ -86,7 +86,7 @@ if ($child) { $mydir = `/usr/bin/cygpath -wi \"$mydir\"`; chomp $mydir; } - system("ctest --output-on-failure ${verbose} -S \"${mydir}/runsuite.cmake${args}\" 2>&1"); + system("ctest -R sigcontext --output-on-failure ${verbose} -S \"${mydir}/runsuite.cmake${args}\" 2>&1"); exit 0; } diff --git a/suite/tests/linux/sigcontext.c b/suite/tests/linux/sigcontext.c index dc1aa8bb3..5d1a44022 100644 --- a/suite/tests/linux/sigcontext.c +++ b/suite/tests/linux/sigcontext.c @@ -97,6 +97,9 @@ signal_handler(int sig, siginfo_t *siginfo, ucontext_t *ucxt) kernel_xstate_t *xstate = (kernel_xstate_t *)ucxt->uc_mcontext.fpregs; if (xstate->fpstate.sw_reserved.magic1 == FP_XSTATE_MAGIC1) { assert(xstate->fpstate.sw_reserved.xstate_size >= sizeof(*xstate)); + print("was here: xstate->fpstate.sw_reserved.xstate_size:%d\n", + xstate->fpstate.sw_reserved.xstate_size); + print("was here: sizeof(*xstate):%d\n", sizeof(*xstate)); for (i = 0; i < NUM_SIMD_REGS; i++) { #ifdef __AVX__ print("ymmh[%d] = 0x%x 0x%x 0x%x 0x%x\n", i, -- GitLab From b29b20721a50d47238488e4199a7195bb8319da2 Mon Sep 17 00:00:00 2001 From: Hendrik Greving <hgreving@google.com> Date: Mon, 29 Jul 2019 14:58:15 -0700 Subject: [PATCH 3/7] *** Temporary commit, due to only reproducible on Travis *** --- suite/tests/linux/sigcontext.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/suite/tests/linux/sigcontext.c b/suite/tests/linux/sigcontext.c index 5d1a44022..7a64e1ccd 100644 --- a/suite/tests/linux/sigcontext.c +++ b/suite/tests/linux/sigcontext.c @@ -96,10 +96,10 @@ signal_handler(int sig, siginfo_t *siginfo, ucontext_t *ucxt) */ kernel_xstate_t *xstate = (kernel_xstate_t *)ucxt->uc_mcontext.fpregs; if (xstate->fpstate.sw_reserved.magic1 == FP_XSTATE_MAGIC1) { - assert(xstate->fpstate.sw_reserved.xstate_size >= sizeof(*xstate)); print("was here: xstate->fpstate.sw_reserved.xstate_size:%d\n", xstate->fpstate.sw_reserved.xstate_size); print("was here: sizeof(*xstate):%d\n", sizeof(*xstate)); + assert(xstate->fpstate.sw_reserved.xstate_size >= sizeof(*xstate)); for (i = 0; i < NUM_SIMD_REGS; i++) { #ifdef __AVX__ print("ymmh[%d] = 0x%x 0x%x 0x%x 0x%x\n", i, -- GitLab From 9142cf723f23335aefb13210a1073f1f4fba16da Mon Sep 17 00:00:00 2001 From: Hendrik Greving <hgreving@google.com> Date: Mon, 29 Jul 2019 15:05:36 -0700 Subject: [PATCH 4/7] *** Temporary commit, due to only reproducible on Travis *** --- suite/tests/linux/sigcontext.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/suite/tests/linux/sigcontext.c b/suite/tests/linux/sigcontext.c index 7a64e1ccd..9dd64f53e 100644 --- a/suite/tests/linux/sigcontext.c +++ b/suite/tests/linux/sigcontext.c @@ -98,8 +98,10 @@ signal_handler(int sig, siginfo_t *siginfo, ucontext_t *ucxt) if (xstate->fpstate.sw_reserved.magic1 == FP_XSTATE_MAGIC1) { print("was here: xstate->fpstate.sw_reserved.xstate_size:%d\n", xstate->fpstate.sw_reserved.xstate_size); + print("was here: xstate->fpstate.sw_reserved.extended_size:%d\n", + xstate->fpstate.sw_reserved.extended_size); print("was here: sizeof(*xstate):%d\n", sizeof(*xstate)); - assert(xstate->fpstate.sw_reserved.xstate_size >= sizeof(*xstate)); + assert(xstate->fpstate.sw_reserved.extended_size >= sizeof(*xstate)); for (i = 0; i < NUM_SIMD_REGS; i++) { #ifdef __AVX__ print("ymmh[%d] = 0x%x 0x%x 0x%x 0x%x\n", i, -- GitLab From c92e3e0c227d6a13959fc1065a3ae50cd1c69823 Mon Sep 17 00:00:00 2001 From: Hendrik Greving <hgreving@google.com> Date: Mon, 29 Jul 2019 15:13:30 -0700 Subject: [PATCH 5/7] Fix latent bug, test assertion should be extended_size. --- suite/runsuite_wrapper.pl | 2 +- suite/tests/linux/sigcontext.c | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/suite/runsuite_wrapper.pl b/suite/runsuite_wrapper.pl index 55fd2c0a8..a8684ff4c 100755 --- a/suite/runsuite_wrapper.pl +++ b/suite/runsuite_wrapper.pl @@ -86,7 +86,7 @@ if ($child) { $mydir = `/usr/bin/cygpath -wi \"$mydir\"`; chomp $mydir; } - system("ctest -R sigcontext --output-on-failure ${verbose} -S \"${mydir}/runsuite.cmake${args}\" 2>&1"); + system("ctest --output-on-failure ${verbose} -S \"${mydir}/runsuite.cmake${args}\" 2>&1"); exit 0; } diff --git a/suite/tests/linux/sigcontext.c b/suite/tests/linux/sigcontext.c index 9dd64f53e..da4214a86 100644 --- a/suite/tests/linux/sigcontext.c +++ b/suite/tests/linux/sigcontext.c @@ -96,11 +96,6 @@ signal_handler(int sig, siginfo_t *siginfo, ucontext_t *ucxt) */ kernel_xstate_t *xstate = (kernel_xstate_t *)ucxt->uc_mcontext.fpregs; if (xstate->fpstate.sw_reserved.magic1 == FP_XSTATE_MAGIC1) { - print("was here: xstate->fpstate.sw_reserved.xstate_size:%d\n", - xstate->fpstate.sw_reserved.xstate_size); - print("was here: xstate->fpstate.sw_reserved.extended_size:%d\n", - xstate->fpstate.sw_reserved.extended_size); - print("was here: sizeof(*xstate):%d\n", sizeof(*xstate)); assert(xstate->fpstate.sw_reserved.extended_size >= sizeof(*xstate)); for (i = 0; i < NUM_SIMD_REGS; i++) { #ifdef __AVX__ -- GitLab From f48b8d7b0cc4ad60df3b3dd2df553a91ac8d6923 Mon Sep 17 00:00:00 2001 From: Hendrik Greving <hgreving@google.com> Date: Tue, 30 Jul 2019 10:22:57 -0700 Subject: [PATCH 6/7] Use offsetof for i387_fxsave_struct. Use entire sizeof(i387,fsave_struct). --- core/unix/signal_linux_x86.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/core/unix/signal_linux_x86.c b/core/unix/signal_linux_x86.c index 2ad44ebad..7cb6c7131 100644 --- a/core/unix/signal_linux_x86.c +++ b/core/unix/signal_linux_x86.c @@ -180,7 +180,7 @@ convert_fxsave_to_fpstate(kernel_fpstate_t *fpstate, struct i387_fxsave_struct * fpstate->magic = X86_FXSR_MAGIC; memcpy(&fpstate->_fxsr_env[0], fxsave, - sizeof(struct i387_fxsave_struct) - sizeof(fpstate->sw_reserved)); + offsetof(struct i387_fxsave_struct, xmm_space)); } #endif /* !X64 */ @@ -288,7 +288,7 @@ save_fpstate(dcontext_t *dcontext, sigframe_rt_t *frame) /* now convert into kernel_fpstate_t form */ ASSERT(sizeof(kernel_fpstate_t) == sizeof(struct i387_fxsave_struct)); memcpy(sc->fpstate, &temp->fxsave, - sizeof(struct i387_fxsave_struct) - sizeof(sc->fpstate->sw_reserved)); + offsetof(struct i387_fxsave_struct, xmm_space)); #else /* this is "unlazy_fpu" */ asm volatile("fxsave %0 ; fnclex" : "=m"(temp->fxsave)); @@ -302,8 +302,7 @@ save_fpstate(dcontext_t *dcontext, sigframe_rt_t *frame) asm volatile("fnsave %0 ; fwait" : "=m"(temp->fsave)); /* now convert into kernel_fpstate_t form */ temp->fsave.status = temp->fsave.swd; - memcpy(sc->fpstate, &temp->fsave, - sizeof(struct i387_fsave_struct) - sizeof(sc->fpstate->sw_reserved)); + memcpy(sc->fpstate, &temp->fsave, sizeof(struct i387_fsave_struct)); } save_xmm(dcontext, frame); -- GitLab From 28a285c8f064608ca262ff2b3dbb30b3edf5bbd8 Mon Sep 17 00:00:00 2001 From: Hendrik Greving <hgreving@google.com> Date: Tue, 30 Jul 2019 12:21:41 -0700 Subject: [PATCH 7/7] Pull in updated comments from up-to-date kernel version. --- core/unix/include/sigcontext.h | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/core/unix/include/sigcontext.h b/core/unix/include/sigcontext.h index 3945f6e39..4551fab68 100644 --- a/core/unix/include/sigcontext.h +++ b/core/unix/include/sigcontext.h @@ -25,16 +25,22 @@ * are used to extended the fpstate pointer in the sigcontext, which now * includes the extended state information along with fpstate information. * - * Presence of FP_XSTATE_MAGIC1 at the beginning of this SW reserved - * area and FP_XSTATE_MAGIC2 at the end of memory layout - * (extended_size - FP_XSTATE_MAGIC2_SIZE) indicates the presence of the - * extended state information in the memory layout pointed by the fpstate - * pointer in sigcontext. + * If sw_reserved.magic1 == FP_XSTATE_MAGIC1 then there's a + * sw_reserved.extended_size bytes large extended context area present. (The + * last 32-bit word of this extended area (at the + * fpstate+extended_size-FP_XSTATE_MAGIC2_SIZE address) is set to + * FP_XSTATE_MAGIC2 so that you can sanity check your size calculations.) + * + * This extended area typically grows with newer CPUs that have larger and + * larger XSAVE areas. */ typedef struct _kernel_fpx_sw_bytes_t { __u32 magic1; /* FP_XSTATE_MAGIC1 */ - __u32 extended_size; /* total size of the layout referred by - * fpstate pointer in the sigcontext. + __u32 extended_size; /* Total size of the fpstate area: + * + * - if magic1 == 0 then it's sizeof(struct _fpstate) + * - if magic1 == FP_XSTATE_MAGIC1 then it's sizeof(struct + * _xstate) plus extensions (if any) */ __u64 xstate_bv; /* feature bit mask (including fp/sse/extended -- GitLab