[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 17/28] linux-user/i386: Replace target_fpstate_fxsave with X86
From: |
Richard Henderson |
Subject: |
[PATCH v2 17/28] linux-user/i386: Replace target_fpstate_fxsave with X86LegacyXSaveArea |
Date: |
Mon, 8 Apr 2024 19:02:51 -1000 |
Use the structure definition from target/i386/cpu.h.
The only minor quirk is re-casting the sw_reserved
area to the OS specific struct target_fpx_sw_bytes.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/i386/signal.c | 71 +++++++++++++++-------------------------
1 file changed, 26 insertions(+), 45 deletions(-)
diff --git a/linux-user/i386/signal.c b/linux-user/i386/signal.c
index a4748b743d..ed98b4d073 100644
--- a/linux-user/i386/signal.c
+++ b/linux-user/i386/signal.c
@@ -33,16 +33,6 @@ struct target_fpreg {
uint16_t exponent;
};
-struct target_fpxreg {
- uint16_t significand[4];
- uint16_t exponent;
- uint16_t padding[3];
-};
-
-struct target_xmmreg {
- uint32_t element[4];
-};
-
struct target_fpx_sw_bytes {
uint32_t magic1;
uint32_t extended_size;
@@ -52,25 +42,6 @@ struct target_fpx_sw_bytes {
};
QEMU_BUILD_BUG_ON(sizeof(struct target_fpx_sw_bytes) != 12*4);
-struct target_fpstate_fxsave {
- /* FXSAVE format */
- uint16_t cw;
- uint16_t sw;
- uint16_t twd;
- uint16_t fop;
- uint64_t rip;
- uint64_t rdp;
- uint32_t mxcsr;
- uint32_t mxcsr_mask;
- uint32_t st_space[32];
- uint32_t xmm_space[64];
- uint32_t hw_reserved[12];
- struct target_fpx_sw_bytes sw_reserved;
-};
-#define TARGET_FXSAVE_SIZE sizeof(struct target_fpstate_fxsave)
-QEMU_BUILD_BUG_ON(TARGET_FXSAVE_SIZE != 512);
-QEMU_BUILD_BUG_ON(offsetof(struct target_fpstate_fxsave, sw_reserved) != 464);
-
struct target_fpstate_32 {
/* Regular FPU environment */
uint32_t cw;
@@ -83,7 +54,7 @@ struct target_fpstate_32 {
struct target_fpreg st[8];
uint16_t status;
uint16_t magic; /* 0xffff = regular FPU data only */
- struct target_fpstate_fxsave fxsave;
+ X86LegacyXSaveArea fxsave;
};
/*
@@ -96,7 +67,7 @@ QEMU_BUILD_BUG_ON(offsetof(struct target_fpstate_32, fxsave)
& 15);
# define target_fpstate target_fpstate_32
# define TARGET_FPSTATE_FXSAVE_OFFSET offsetof(struct target_fpstate_32,
fxsave)
#else
-# define target_fpstate target_fpstate_fxsave
+# define target_fpstate X86LegacyXSaveArea
# define TARGET_FPSTATE_FXSAVE_OFFSET 0
#endif
@@ -240,15 +211,17 @@ struct rt_sigframe {
* Set up a signal frame.
*/
-static void xsave_sigcontext(CPUX86State *env, struct target_fpstate_fxsave
*fxsave,
+static void xsave_sigcontext(CPUX86State *env, X86LegacyXSaveArea *fxsave,
abi_ulong fxsave_addr)
{
+ struct target_fpx_sw_bytes *sw = (void *)&fxsave->sw_reserved;
+
if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE)) {
/* fxsave_addr must be 16 byte aligned for fxsave */
assert(!(fxsave_addr & 0xf));
cpu_x86_fxsave(env, fxsave_addr);
- __put_user(0, &fxsave->sw_reserved.magic1);
+ __put_user(0, &sw->magic1);
} else {
uint32_t xstate_size = xsave_area_size(env->xcr0, false);
@@ -266,10 +239,10 @@ static void xsave_sigcontext(CPUX86State *env, struct
target_fpstate_fxsave *fxs
/* Zero the header, XSAVE *adds* features to an existing save state.
*/
memset(fxsave + 1, 0, sizeof(X86XSaveHeader));
cpu_x86_xsave(env, fxsave_addr, -1);
- __put_user(TARGET_FP_XSTATE_MAGIC1, &fxsave->sw_reserved.magic1);
- __put_user(extended_size, &fxsave->sw_reserved.extended_size);
- __put_user(env->xcr0, &fxsave->sw_reserved.xfeatures);
- __put_user(xstate_size, &fxsave->sw_reserved.xstate_size);
+ __put_user(TARGET_FP_XSTATE_MAGIC1, &sw->magic1);
+ __put_user(extended_size, &sw->extended_size);
+ __put_user(env->xcr0, &sw->xfeatures);
+ __put_user(xstate_size, &sw->xstate_size);
__put_user(TARGET_FP_XSTATE_MAGIC2,
(uint32_t *)((void *)fxsave + xstate_size));
}
@@ -383,9 +356,9 @@ get_sigframe(struct target_sigaction *ka, CPUX86State *env,
size_t fxsave_offset
}
if (!(env->features[FEAT_1_EDX] & CPUID_FXSR)) {
- return (esp - (fxsave_offset + TARGET_FXSAVE_SIZE)) & -8ul;
+ return (esp - (fxsave_offset + sizeof(X86LegacyXSaveArea))) & -8ul;
} else if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE)) {
- return ((esp - TARGET_FXSAVE_SIZE) & -16ul) - fxsave_offset;
+ return ((esp - sizeof(X86LegacyXSaveArea)) & -16ul) - fxsave_offset;
} else {
size_t xstate_size =
xsave_area_size(env->xcr0, false) +
TARGET_FP_XSTATE_MAGIC2_SIZE;
@@ -551,21 +524,29 @@ give_sigsegv:
force_sigsegv(sig);
}
-static int xrstor_sigcontext(CPUX86State *env, struct target_fpstate_fxsave
*fxsave,
+static int xrstor_sigcontext(CPUX86State *env, X86LegacyXSaveArea *fxsave,
abi_ulong fxsave_addr)
{
+ struct target_fpx_sw_bytes *sw = (void *)&fxsave->sw_reserved;
+
if (env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE) {
- uint32_t extended_size = tswapl(fxsave->sw_reserved.extended_size);
- uint32_t xstate_size = tswapl(fxsave->sw_reserved.xstate_size);
+ uint32_t magic1 = tswapl(sw->magic1);
+ uint32_t extended_size = tswapl(sw->extended_size);
+ uint32_t xstate_size = tswapl(sw->xstate_size);
+ uint32_t minimum_size = (TARGET_FPSTATE_FXSAVE_OFFSET
+ + TARGET_FP_XSTATE_MAGIC2_SIZE
+ + xstate_size);
+ uint32_t magic2;
/* Linux checks MAGIC2 using xstate_size, not extended_size. */
- if (tswapl(fxsave->sw_reserved.magic1) == TARGET_FP_XSTATE_MAGIC1 &&
- extended_size >= TARGET_FPSTATE_FXSAVE_OFFSET + xstate_size +
TARGET_FP_XSTATE_MAGIC2_SIZE) {
+ if (magic1 == TARGET_FP_XSTATE_MAGIC1
+ && extended_size >= minimum_size) {
if (!access_ok(env_cpu(env), VERIFY_READ, fxsave_addr,
extended_size - TARGET_FPSTATE_FXSAVE_OFFSET)) {
return 1;
}
- if (tswapl(*(uint32_t *)((void *)fxsave + xstate_size)) ==
TARGET_FP_XSTATE_MAGIC2) {
+ magic2 = tswapl(*(uint32_t *)((void *)fxsave + xstate_size));
+ if (magic2 == TARGET_FP_XSTATE_MAGIC2) {
cpu_x86_xrstor(env, fxsave_addr, -1);
return 0;
}
--
2.34.1
- [PATCH v2 07/28] target/i386: Convert do_xsave_{fpu, mxcr, sse} to X86Access, (continued)
- [PATCH v2 07/28] target/i386: Convert do_xsave_{fpu, mxcr, sse} to X86Access, Richard Henderson, 2024/04/09
- [PATCH v2 08/28] target/i386: Convert do_xrstor_{fpu, mxcr, sse} to X86Access, Richard Henderson, 2024/04/09
- [PATCH v2 09/28] tagret/i386: Convert do_fxsave, do_fxrstor to X86Access, Richard Henderson, 2024/04/09
- [PATCH v2 10/28] target/i386: Convert do_xsave_* to X86Access, Richard Henderson, 2024/04/09
- [PATCH v2 11/28] target/i386: Convert do_xrstor_* to X86Access, Richard Henderson, 2024/04/09
- [PATCH v2 12/28] target/i386: Split out do_xsave_chk, Richard Henderson, 2024/04/09
- [PATCH v2 13/28] target/i386: Add rbfm argument to cpu_x86_{xsave, xrstor}, Richard Henderson, 2024/04/09
- [PATCH v2 15/28] linux-user/i386: Drop xfeatures_size from sigcontext arithmetic, Richard Henderson, 2024/04/09
- [PATCH v2 14/28] target/i386: Add {hw, sw}_reserved to X86LegacyXSaveArea, Richard Henderson, 2024/04/09
- [PATCH v2 16/28] linux-user/i386: Remove xfeatures from target_fpstate_fxsave, Richard Henderson, 2024/04/09
- [PATCH v2 17/28] linux-user/i386: Replace target_fpstate_fxsave with X86LegacyXSaveArea,
Richard Henderson <=
- [PATCH v2 18/28] linux-user/i386: Split out struct target_fregs_state, Richard Henderson, 2024/04/09
- [PATCH v2 20/28] linux-user/i386: Return boolean success from restore_sigcontext, Richard Henderson, 2024/04/09
- [PATCH v2 19/28] linux-user/i386: Fix -mregparm=3 for signal delivery, Richard Henderson, 2024/04/09
- [PATCH v2 21/28] linux-user/i386: Return boolean success from xrstor_sigcontext, Richard Henderson, 2024/04/09
- [PATCH v2 23/28] target/i386: Honor xfeatures in xrstor_sigcontext, Richard Henderson, 2024/04/09
- [PATCH v2 22/28] linux-user/i386: Fix allocation and alignment of fp state, Richard Henderson, 2024/04/09