diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2024-04-08 14:51:54 -1000 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2024-05-26 15:45:27 -0700 |
commit | 7973eb943e670ea66a19e04868e01803c7594246 (patch) | |
tree | bd2919e58ffa4312f904e4e9d924f72a3611d58f /linux-user/i386 | |
parent | a7365e984d27b961f381cf3be46682e4da5ab6f7 (diff) |
linux-user/i386: Honor xfeatures in xrstor_sigcontext
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'linux-user/i386')
-rw-r--r-- | linux-user/i386/signal.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/linux-user/i386/signal.c b/linux-user/i386/signal.c index 47e6c0ff0d..e716ec8989 100644 --- a/linux-user/i386/signal.c +++ b/linux-user/i386/signal.c @@ -613,6 +613,7 @@ static bool xrstor_sigcontext(CPUX86State *env, FPStateKind fpkind, struct target_fpx_sw_bytes *sw = (void *)&fxstate->sw_reserved; uint32_t magic1, magic2; uint32_t extended_size, xstate_size, min_size, max_size; + uint64_t xfeatures; switch (fpkind) { case FPSTATE_XSAVE: @@ -629,10 +630,25 @@ static bool xrstor_sigcontext(CPUX86State *env, FPStateKind fpkind, xstate_size > extended_size) { break; } + + /* + * Restore the features indicated in the frame, masked by + * those currently enabled. Re-check the frame size. + * ??? It is not clear where the kernel does this, but it + * is not in check_xstate_in_sigframe, and so (probably) + * does not fall back to fxrstor. + */ + xfeatures = tswap64(sw->xfeatures) & env->xcr0; + min_size = xsave_area_size(xfeatures, false); + if (xstate_size < min_size) { + return false; + } + if (!access_ok(env_cpu(env), VERIFY_READ, fxstate_addr, xstate_size + TARGET_FP_XSTATE_MAGIC2_SIZE)) { return false; } + /* * Check for the presence of second magic word at the end of memory * layout. This detects the case where the user just copied the legacy @@ -645,7 +661,8 @@ static bool xrstor_sigcontext(CPUX86State *env, FPStateKind fpkind, if (magic2 != TARGET_FP_XSTATE_MAGIC2) { break; } - cpu_x86_xrstor(env, fxstate_addr, -1); + + cpu_x86_xrstor(env, fxstate_addr, xfeatures); return true; default: |