Make sure that we can reconfigure the destination of an irq from the interrupt handler. Make sure that the EOI is correctly delivered to the IOAPIC and that remote_irr is reset to 0. This tests the fix introduced by commit "KVM: x86: ioapic: Fix level-triggered EOI and IOAPIC reconfigure race". Signed-off-by: Nikita Leshenko <nikita.leshchenko@xxxxxxxxxx> Reviewed-by: Liran Alon <liran.alon@xxxxxxxxxx> Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx> --- x86/ioapic.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/x86/ioapic.c b/x86/ioapic.c index e5cc259..849add4 100644 --- a/x86/ioapic.c +++ b/x86/ioapic.c @@ -391,6 +391,43 @@ static void test_ioapic_level_retrigger_mask(void) set_mask(0x0e, false); } +static volatile int g_isr_84; + +static void ioapic_isr_84(isr_regs_t *regs) +{ + int line = 0xe; + ioapic_redir_entry_t e; + + ++g_isr_84; + set_irq_line(line, 0); + + e = ioapic_read_redir(line); + e.dest_id = 1; + + // Update only upper part of the register because we only change the + // destination, which resides in the upper part + ioapic_write_reg(0x10 + line * 2 + 1, ((u32 *)&e)[1]); + + eoi(); +} + +static void test_ioapic_self_reconfigure(void) +{ + ioapic_redir_entry_t e = { + .vector = 0x84, + .delivery_mode = 0, + .dest_mode = 0, + .dest_id = 0, + .trig_mode = TRIGGER_LEVEL, + }; + + handle_irq(0x84, ioapic_isr_84); + ioapic_write_redir(0xe, e); + set_irq_line(0x0e, 1); + e = ioapic_read_redir(0xe); + report("Reconfigure self", g_isr_84 == 1 && e.remote_irr == 0); +} + int main(void) { @@ -432,6 +469,8 @@ int main(void) test_ioapic_level_tmr_smp(false); test_ioapic_level_tmr_smp(true); test_ioapic_edge_tmr_smp(true); + + test_ioapic_self_reconfigure(); } return report_summary(); -- 2.13.3