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 <yu1.wang@intel.com>
Acked-by: Anthony Xu <anthony.xu@intel.com>
This commit is contained in:
Yu Wang 2018-08-01 13:29:50 +08:00 committed by lijinxia
parent 1e1886794e
commit 6e86d4841d
1 changed files with 10 additions and 0 deletions

View File

@ -313,6 +313,16 @@ vioapic_indirect_write(struct vioapic *vioapic, uint32_t addr, uint32_t data)
new.u.lo_32 |= (data & ~RTBL_RO_BITS); 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; changed = last.full ^ new.full;
/* pin0 from vpic mask/unmask */ /* pin0 from vpic mask/unmask */
if (pin == 0U && (changed & IOAPIC_RTE_INTMASK) != 0UL) { if (pin == 0U && (changed & IOAPIC_RTE_INTMASK) != 0UL) {