The IOAPIC does not do anything if a level-triggered interrupt is asserted while its REMOTE_IRR bit is set in the redirection table, and this can cause a race condition between test_ioapic_physical_destination_mode and test_ioapic_logical_destination_mode. If CPU 1 is still running in ioapic_isr_85 and has not sent the EOI, while CPU 0 has already reached the set_irq_line(0x0e, 1) line of test_ioapic_logical_destination_mode, the interrupt is dropped and the test hangs. For some reason, this has started to occur about 20-30% of the time with a 5.20-rc0 debug kernel. With this patch, the ioapic test has survived 100 iterations without failing. Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx> --- x86/ioapic.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/x86/ioapic.c b/x86/ioapic.c index 7cbccd7..4f578ce 100644 --- a/x86/ioapic.c +++ b/x86/ioapic.c @@ -6,6 +6,12 @@ #include "isr.h" #include "delay.h" +static void poll_remote_irr(unsigned line) +{ + while (ioapic_read_redir(line).remote_irr) + cpu_relax(); +} + static void toggle_irq_line(unsigned line) { set_irq_line(line, 1); @@ -214,6 +220,7 @@ static void test_ioapic_level_tmr_smp(bool expected_tmr_before) report(tmr_before == expected_tmr_before && g_tmr_79, "TMR for ioapic level interrupts (expected %s)", expected_tmr_before ? "true" : "false"); + poll_remote_irr(0xe); } static int g_isr_98; @@ -402,6 +409,7 @@ static void test_ioapic_self_reconfigure(void) set_irq_line(0x0e, 1); e = ioapic_read_redir(0xe); report(g_isr_84 == 1 && e.remote_irr == 0, "Reconfigure self"); + poll_remote_irr(0xe); } static volatile int g_isr_85; @@ -429,6 +437,7 @@ static void test_ioapic_physical_destination_mode(void) pause(); } while(g_isr_85 != 1); report(g_isr_85 == 1, "ioapic physical destination mode"); + poll_remote_irr(0xe); } static volatile int g_isr_86; @@ -461,6 +470,7 @@ static void test_ioapic_logical_destination_mode(void) pause(); } while(g_isr_86 < nr_vcpus); report(g_isr_86 == nr_vcpus, "ioapic logical destination mode"); + poll_remote_irr(0xe); } int main(void) -- 2.31.1