x86_cpu_has_work() may run without the BQL, but currently reads
CPUState::interrupt_request directly. Other threads update this
field with qatomic_or() in cpu_set_interrupt(), so the direct
read races with an atomic access.

Load the interrupt request with qatomic_load_acquire(), matching
cpu_test_interrupt(). This provides the acquire ordering required
before x86_cpu_pending_interrupt() inspects the CPU state.

Suggested-by: Paolo Bonzini <[email protected]>
Signed-off-by: Philippe Mathieu-Daudé <[email protected]>
Reviewed-by: Richard Henderson <[email protected]>
Message-Id: <[email protected]>
---
 target/i386/cpu.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index b97f144aea5..f3bc6911c10 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -10640,7 +10640,9 @@ int x86_cpu_pending_interrupt(const CPUState *cs, int 
interrupt_request)
 
 static bool x86_cpu_has_work(CPUState *cs)
 {
-    return x86_cpu_pending_interrupt(cs, cs->interrupt_request) != 0;
+    uint32_t pending_interrupts = qatomic_load_acquire(&cs->interrupt_request);
+
+    return x86_cpu_pending_interrupt(cs, pending_interrupts) != 0;
 }
 #endif /* !CONFIG_USER_ONLY */
 
-- 
2.53.0


Reply via email to