From 6e86d4841d0ec8ec5c7f3f8cc3f9a710d95e28bb Mon Sep 17 00:00:00 2001 From: Yu Wang Date: Wed, 1 Aug 2018 13:29:50 +0800 Subject: [PATCH] hv: vioapic: set remote IRR to zero once trigger mode switch to edge In some special scenarios, the LAPIC somehow hasn't send EOI to IOAPIC which cause the Remote IRR bit can't be clear. To clear it, some OSes will use EOI Register to clear it for 0x20 version IOAPIC, otherwise use switch Trigger Mode to Edge Sensitive to clear it. This patch emulate this IOAPIC behavior to satisfy this requirement. Signed-off-by: Yu Wang Acked-by: Anthony Xu --- hypervisor/arch/x86/guest/vioapic.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/hypervisor/arch/x86/guest/vioapic.c b/hypervisor/arch/x86/guest/vioapic.c index 0072316f2..4e87106c9 100644 --- a/hypervisor/arch/x86/guest/vioapic.c +++ b/hypervisor/arch/x86/guest/vioapic.c @@ -313,6 +313,16 @@ vioapic_indirect_write(struct vioapic *vioapic, uint32_t addr, uint32_t data) new.u.lo_32 |= (data & ~RTBL_RO_BITS); } + /* In some special scenarios, the LAPIC somehow hasn't send + * EOI to IOAPIC which cause the Remote IRR bit can't be clear. + * To clear it, some OSes will use EOI Register to clear it for + * 0x20 version IOAPIC, otherwise use switch Trigger Mode to + * Edge Sensitive to clear it. + */ + if ((new.full & IOAPIC_RTE_TRGRLVL) == 0U) { + new.full &= ~IOAPIC_RTE_REM_IRR; + } + changed = last.full ^ new.full; /* pin0 from vpic mask/unmask */ if (pin == 0U && (changed & IOAPIC_RTE_INTMASK) != 0UL) {