diff options
author | Richard Henderson | 2022-10-24 14:45:29 +0200 |
---|---|---|
committer | Richard Henderson | 2022-10-31 22:31:37 +0100 |
commit | f484f213c9f4ae1cd30ebdaadc7b539d745d39fb (patch) | |
tree | dd52d1ae01a7a885417ad5fc80fe395c27f2fe81 /target | |
parent | accel/tcg: Introduce cpu_unwind_state_data (diff) | |
download | qemu-f484f213c9f4ae1cd30ebdaadc7b539d745d39fb.tar.gz qemu-f484f213c9f4ae1cd30ebdaadc7b539d745d39fb.tar.xz qemu-f484f213c9f4ae1cd30ebdaadc7b539d745d39fb.zip |
target/i386: Use cpu_unwind_state_data for tpr access
Avoid cpu_restore_state, and modifying env->eip out from
underneath the translator with TARGET_TB_PCREL. There is
some slight duplication from x86_restore_state_to_opc,
but it's just a few lines.
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1269
Reviewed-by: Claudio Fontana <cfontana@suse.de>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'target')
-rw-r--r-- | target/i386/helper.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/target/i386/helper.c b/target/i386/helper.c index b62a1e48e2..0ac2da066d 100644 --- a/target/i386/helper.c +++ b/target/i386/helper.c @@ -509,6 +509,27 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank, } } +static inline target_ulong get_memio_eip(CPUX86State *env) +{ +#ifdef CONFIG_TCG + uint64_t data[TARGET_INSN_START_WORDS]; + CPUState *cs = env_cpu(env); + + if (!cpu_unwind_state_data(cs, cs->mem_io_pc, data)) { + return env->eip; + } + + /* Per x86_restore_state_to_opc. */ + if (TARGET_TB_PCREL) { + return (env->eip & TARGET_PAGE_MASK) | data[0]; + } else { + return data[0] - env->segs[R_CS].base; + } +#else + qemu_build_not_reached(); +#endif +} + void cpu_report_tpr_access(CPUX86State *env, TPRAccess access) { X86CPU *cpu = env_archcpu(env); @@ -519,9 +540,9 @@ void cpu_report_tpr_access(CPUX86State *env, TPRAccess access) cpu_interrupt(cs, CPU_INTERRUPT_TPR); } else if (tcg_enabled()) { - cpu_restore_state(cs, cs->mem_io_pc, false); + target_ulong eip = get_memio_eip(env); - apic_handle_tpr_access_report(cpu->apic_state, env->eip, access); + apic_handle_tpr_access_report(cpu->apic_state, eip, access); } } #endif /* !CONFIG_USER_ONLY */ |