diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c index 0e6a156bcd..2ef01ba861 100644 --- a/accel/tcg/cpu-exec.c +++ b/accel/tcg/cpu-exec.c @@ -169,6 +169,8 @@ static void init_delay_params(SyncClocks *sc, const CPUState *cpu) #include "latx-options.h" #include "latx-signal.h" #include "reg-map.h" + +#define LBT_FCSR_TOP_MODE_MASK (1U << 6) #endif /* Execute a TB, and fix up the CPU state afterwards if necessary */ @@ -1154,6 +1156,20 @@ int cpu_exec(CPUState *cpu) g_assert(cpu == current_cpu); #endif +#ifdef CONFIG_LATX + CPUArchState *env = cpu->env_ptr; + + /* + * Some exits bypass the translated cleanup and siglongjmp restores a + * possibly active LBT TOP mapping. Clear both copies after the jump, + * before physical FPRs are loaded on the next entry. + */ + if (!option_softfpu && (env->fcsr & LBT_FCSR_TOP_MODE_MASK)) { + env->fcsr &= ~LBT_FCSR_TOP_MODE_MASK; + __asm__ volatile("x86clrtm" : : : "memory"); + } +#endif + #ifndef CONFIG_SOFTMMU tcg_debug_assert(!have_mmap_lock()); #endif diff --git a/target/i386/latx/translator/tr-misc.c b/target/i386/latx/translator/tr-misc.c index 12c9e8b663..e7747f962e 100644 --- a/target/i386/latx/translator/tr-misc.c +++ b/target/i386/latx/translator/tr-misc.c @@ -1244,6 +1244,7 @@ bool translate_int_syscall(IR1_INST *pir1) la_label(label_traditionanl); /* 1. store gpr as they will be used in do_syscall */ tr_save_registers_to_env(0xff, 0, 0, options_to_save()); + tr_save_fcsr_to_env(); /* 2. store intno to CPUState */ IR2_OPND intno = ra_alloc_itemp(); @@ -1297,13 +1298,13 @@ bool translate_int(IR1_INST *pir1) tr_save_x64_8_registers_to_env(0xff, option_save_xmm); la_label(not_64); #endif - tr_save_fcsr_to_env(); #ifdef CONFIG_LATX_SYSCALL_TUNNEL if (ir1_get_opnd(pir1, 0)->imm == 0x80) { return translate_int_syscall(pir1); } #endif tr_save_registers_to_env(0xff, 0xff, 0xff, options_to_save()); + tr_save_fcsr_to_env(); /* * store intno to CPUState */ IR2_OPND intno = ra_alloc_itemp(); @@ -1342,9 +1343,9 @@ bool translate_syscall(IR1_INST *pir1) #else bool translate_syscall(IR1_INST *pir1) { - tr_save_fcsr_to_env(); tr_save_registers_to_env(0xff, 0xff, 0xff, options_to_save()); tr_save_x64_8_registers_to_env(0xff, 0xff); + tr_save_fcsr_to_env(); /* store exception index(EXCP_SYSCALL) to CPUState */ IR2_OPND exception_index = ra_alloc_itemp();