replay: don't record interrupt poll

Interrupt poll is not a real interrupt event. It is needed only for
thread safety. This interrupt is used for i386 and converted
to hardware interrupt by cpu_handle_interrupt function.
Therefore it is not needed to be recorded, because hardware
interrupt will be recorded after converting.

Signed-off-by: Pavel Dovgalyuk <Pavel.Dovgalyuk@ispras.ru>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>

--

v4 changes:
 - Condition check refactoring (suggested by Alex Bennée)
Message-Id: <160174517124.12451.12983410242461131737.stgit@pasha-ThinkPad-X280>

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Pavel Dovgalyuk 2020-10-03 20:12:51 +03:00 committed by Paolo Bonzini
parent cb8baa7720
commit 4084893ddc

View File

@ -436,8 +436,7 @@ static inline bool cpu_handle_halt(CPUState *cpu)
{ {
if (cpu->halted) { if (cpu->halted) {
#if defined(TARGET_I386) && !defined(CONFIG_USER_ONLY) #if defined(TARGET_I386) && !defined(CONFIG_USER_ONLY)
if ((cpu->interrupt_request & CPU_INTERRUPT_POLL) if (cpu->interrupt_request & CPU_INTERRUPT_POLL) {
&& replay_interrupt()) {
X86CPU *x86_cpu = X86_CPU(cpu); X86CPU *x86_cpu = X86_CPU(cpu);
qemu_mutex_lock_iothread(); qemu_mutex_lock_iothread();
apic_poll_irq(x86_cpu->apic_state); apic_poll_irq(x86_cpu->apic_state);
@ -533,6 +532,20 @@ static inline bool cpu_handle_exception(CPUState *cpu, int *ret)
return false; return false;
} }
/*
* 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
}
static inline bool cpu_handle_interrupt(CPUState *cpu, static inline bool cpu_handle_interrupt(CPUState *cpu,
TranslationBlock **last_tb) TranslationBlock **last_tb)
{ {
@ -594,7 +607,9 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
and via longjmp via cpu_loop_exit. */ and via longjmp via cpu_loop_exit. */
else { else {
if (cc->cpu_exec_interrupt(cpu, interrupt_request)) { if (cc->cpu_exec_interrupt(cpu, interrupt_request)) {
replay_interrupt(); if (need_replay_interrupt(interrupt_request)) {
replay_interrupt();
}
/* /*
* After processing the interrupt, ensure an EXCP_DEBUG is * After processing the interrupt, ensure an EXCP_DEBUG is
* raised when single-stepping so that GDB doesn't miss the * raised when single-stepping so that GDB doesn't miss the