diff options
Diffstat (limited to 'target/i386/helper.c')
-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 */ |