aboutsummaryrefslogtreecommitdiff
path: root/linux-user
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2024-04-08 14:51:54 -1000
committerRichard Henderson <richard.henderson@linaro.org>2024-05-26 15:45:27 -0700
commit7973eb943e670ea66a19e04868e01803c7594246 (patch)
treebd2919e58ffa4312f904e4e9d924f72a3611d58f /linux-user
parenta7365e984d27b961f381cf3be46682e4da5ab6f7 (diff)
downloadqemu-7973eb943e670ea66a19e04868e01803c7594246.zip
qemu-7973eb943e670ea66a19e04868e01803c7594246.tar.gz
qemu-7973eb943e670ea66a19e04868e01803c7594246.tar.bz2
linux-user/i386: Honor xfeatures in xrstor_sigcontext
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'linux-user')
-rw-r--r--linux-user/i386/signal.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/linux-user/i386/signal.c b/linux-user/i386/signal.c
index 47e6c0f..e716ec8 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: