Although only I386 currently uses it it is not inconceivable that other arches might find this facility useful.
Signed-off-by: Alex Bennée <alex.ben...@linaro.org> --- include/hw/core/tcg-cpu-ops.h | 5 +++++ accel/tcg/cpu-exec.c | 29 +++++++++-------------------- target/i386/tcg/tcg-cpu.c | 1 + 3 files changed, 15 insertions(+), 20 deletions(-) diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h index 66c0cecdde..8e8df8c330 100644 --- a/include/hw/core/tcg-cpu-ops.h +++ b/include/hw/core/tcg-cpu-ops.h @@ -121,6 +121,11 @@ struct TCGCPUOps { */ bool (*io_recompile_replay_branch)(CPUState *cpu, const TranslationBlock *tb); + /** + * @virtual_interrupts: IRQs that can be ignored for replay purposes + */ + int virtual_interrupts; + #else /** * record_sigsegv: diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c index 8fa19b7222..56be7956e7 100644 --- a/accel/tcg/cpu-exec.c +++ b/accel/tcg/cpu-exec.c @@ -737,22 +737,6 @@ static inline bool cpu_handle_exception(CPUState *cpu, int *ret) return false; } -#ifndef CONFIG_USER_ONLY -/* - * CPU_INTERRUPT_POLL is a virtual event which gets converted into a - * "real" interrupt event later. It does not need to be recorded for - * replay purposes. - */ -static inline bool need_replay_interrupt(int interrupt_request) -{ -#if defined(TARGET_I386) - return !(interrupt_request & CPU_INTERRUPT_POLL); -#else - return true; -#endif -} -#endif /* !CONFIG_USER_ONLY */ - static inline bool cpu_handle_interrupt(CPUState *cpu, TranslationBlock **last_tb) { @@ -808,11 +792,16 @@ static inline bool cpu_handle_interrupt(CPUState *cpu, * interrupt isn't processed, True when it is, and we should * restart on a new TB, and via longjmp via cpu_loop_exit. */ - CPUClass *cc = CPU_GET_CLASS(cpu); + struct TCGCPUOps const *tcg_ops = cpu->cc->tcg_ops; - if (cc->tcg_ops->cpu_exec_interrupt && - cc->tcg_ops->cpu_exec_interrupt(cpu, interrupt_request)) { - if (need_replay_interrupt(interrupt_request)) { + if (tcg_ops->cpu_exec_interrupt && + tcg_ops->cpu_exec_interrupt(cpu, interrupt_request)) { + /* + * Virtual events gets converted into a "real" + * interrupt event later. They do not need to be + * recorded for replay purposes. + */ + if (!(interrupt_request & tcg_ops->virtual_interrupts)) { replay_interrupt(); } /* diff --git a/target/i386/tcg/tcg-cpu.c b/target/i386/tcg/tcg-cpu.c index b942c306d6..750ae0f945 100644 --- a/target/i386/tcg/tcg-cpu.c +++ b/target/i386/tcg/tcg-cpu.c @@ -104,6 +104,7 @@ static const struct TCGCPUOps x86_tcg_ops = { .do_unaligned_access = x86_cpu_do_unaligned_access, .debug_excp_handler = breakpoint_handler, .debug_check_breakpoint = x86_debug_check_breakpoint, + .virtual_interrupts = CPU_INTERRUPT_POLL, #endif /* !CONFIG_USER_ONLY */ }; -- 2.39.2