aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2022-10-10 15:28:54 +0200
committerPaolo Bonzini <pbonzini@redhat.com>2022-10-11 10:27:35 +0200
commit5d2456789ac50b11c2bd560ddf3470fe820bb0ff (patch)
tree900aa0bf02db74a0a9a0c1f38f7884ccae841009 /target
parent2796f290b5469a7f6749ea119a48bc17f489effd (diff)
downloadqemu-5d2456789ac50b11c2bd560ddf3470fe820bb0ff.zip
qemu-5d2456789ac50b11c2bd560ddf3470fe820bb0ff.tar.gz
qemu-5d2456789ac50b11c2bd560ddf3470fe820bb0ff.tar.bz2
linux-user: i386/signal: support XSAVE/XRSTOR for signal frame fpstate
Add support for saving/restoring extended save states when signals are delivered. This allows using AVX, MPX or PKRU registers in signal handlers. Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'target')
-rw-r--r--target/i386/cpu.c2
-rw-r--r--target/i386/cpu.h3
-rw-r--r--target/i386/tcg/fpu_helper.c64
3 files changed, 42 insertions, 27 deletions
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 0688417..8a11470 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1467,7 +1467,7 @@ ExtSaveArea x86_ext_save_areas[XSAVE_STATE_AREA_COUNT] = {
},
};
-static uint32_t xsave_area_size(uint64_t mask, bool compacted)
+uint32_t xsave_area_size(uint64_t mask, bool compacted)
{
uint64_t ret = x86_ext_save_areas[0].size;
const ExtSaveArea *esa;
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index d412497..9327353 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -2071,6 +2071,8 @@ void cpu_x86_fsave(CPUX86State *s, target_ulong ptr, int data32);
void cpu_x86_frstor(CPUX86State *s, target_ulong ptr, int data32);
void cpu_x86_fxsave(CPUX86State *s, target_ulong ptr);
void cpu_x86_fxrstor(CPUX86State *s, target_ulong ptr);
+void cpu_x86_xsave(CPUX86State *s, target_ulong ptr);
+void cpu_x86_xrstor(CPUX86State *s, target_ulong ptr);
/* cpu.c */
void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
@@ -2327,6 +2329,7 @@ bool cpu_is_bsp(X86CPU *cpu);
void x86_cpu_xrstor_all_areas(X86CPU *cpu, const void *buf, uint32_t buflen);
void x86_cpu_xsave_all_areas(X86CPU *cpu, void *buf, uint32_t buflen);
+uint32_t xsave_area_size(uint64_t mask, bool compacted);
void x86_update_hflags(CPUX86State* env);
static inline bool hyperv_feat_enabled(X86CPU *cpu, int feat)
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
index 30bc44f..ad58931 100644
--- a/target/i386/tcg/fpu_helper.c
+++ b/target/i386/tcg/fpu_helper.c
@@ -2502,18 +2502,6 @@ void helper_frstor(CPUX86State *env, target_ulong ptr, int data32)
do_frstor(env, ptr, data32, GETPC());
}
-#if defined(CONFIG_USER_ONLY)
-void cpu_x86_fsave(CPUX86State *env, target_ulong ptr, int data32)
-{
- do_fsave(env, ptr, data32, 0);
-}
-
-void cpu_x86_frstor(CPUX86State *env, target_ulong ptr, int data32)
-{
- do_frstor(env, ptr, data32, 0);
-}
-#endif
-
#define XO(X) offsetof(X86XSaveArea, X)
static void do_xsave_fpu(CPUX86State *env, target_ulong ptr, uintptr_t ra)
@@ -2787,21 +2775,8 @@ void helper_fxrstor(CPUX86State *env, target_ulong ptr)
do_fxrstor(env, ptr, GETPC());
}
-#if defined(CONFIG_USER_ONLY)
-void cpu_x86_fxsave(CPUX86State *env, target_ulong ptr)
+static void do_xrstor(CPUX86State *env, target_ulong ptr, uint64_t rfbm, uintptr_t ra)
{
- do_fxsave(env, ptr, 0);
-}
-
-void cpu_x86_fxrstor(CPUX86State *env, target_ulong ptr)
-{
- do_fxrstor(env, ptr, 0);
-}
-#endif
-
-void helper_xrstor(CPUX86State *env, target_ulong ptr, uint64_t rfbm)
-{
- uintptr_t ra = GETPC();
uint64_t xstate_bv, xcomp_bv, reserve0;
rfbm &= env->xcr0;
@@ -2894,6 +2869,43 @@ void helper_xrstor(CPUX86State *env, target_ulong ptr, uint64_t rfbm)
#undef XO
+void helper_xrstor(CPUX86State *env, target_ulong ptr, uint64_t rfbm)
+{
+ do_xrstor(env, ptr, rfbm, GETPC());
+}
+
+#if defined(CONFIG_USER_ONLY)
+void cpu_x86_fsave(CPUX86State *env, target_ulong ptr, int data32)
+{
+ do_fsave(env, ptr, data32, 0);
+}
+
+void cpu_x86_frstor(CPUX86State *env, target_ulong ptr, int data32)
+{
+ do_frstor(env, ptr, data32, 0);
+}
+
+void cpu_x86_fxsave(CPUX86State *env, target_ulong ptr)
+{
+ do_fxsave(env, ptr, 0);
+}
+
+void cpu_x86_fxrstor(CPUX86State *env, target_ulong ptr)
+{
+ do_fxrstor(env, ptr, 0);
+}
+
+void cpu_x86_xsave(CPUX86State *env, target_ulong ptr)
+{
+ do_xsave(env, ptr, -1, get_xinuse(env), -1, 0);
+}
+
+void cpu_x86_xrstor(CPUX86State *env, target_ulong ptr)
+{
+ do_xrstor(env, ptr, -1, 0);
+}
+#endif
+
uint64_t helper_xgetbv(CPUX86State *env, uint32_t ecx)
{
/* The OS must have enabled XSAVE. */