Skip to content

Commit 16a8174

Browse files
lifeixlijinxia
authored andcommitted
hv: vioapic: bug fix update PTDEV RTE
Now the guest may change "Destination Field", "Trigger Mode", "Interrupt Input Pin Polarity" even "Interrupt Vector" when "Interrupt Mask" not masked. So we should update the pass through device interrupt pin rte in this situation. The old logic would update it only when "Interrupt Mask" or "Trigger Mode" or "Interrupt Input Pin Polarity" was changed. update ptdev native ioapic rte when (a) something changed and (b) the old rte interrupt mask is not masked or the new rte interrupt mask is not masked. Signed-off-by: Li, Fei1 <fei1.li@intel.com>
1 parent 101ab60 commit 16a8174

File tree

1 file changed

+12
-22
lines changed

1 file changed

+12
-22
lines changed

hypervisor/dm/vioapic.c

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434

3535
#define REDIR_ENTRIES_HW 120U /* SOS align with native ioapic */
3636
#define RTBL_RO_BITS (uint32_t)(IOAPIC_RTE_REM_IRR | IOAPIC_RTE_DELIVS)
37-
#define NEED_TMR_UPDATE (~(IOAPIC_RTE_INTMASK | IOAPIC_RTE_INTPOL))
37+
#define NEED_TMR_UPDATE (IOAPIC_RTE_TRGRMOD | IOAPIC_RTE_DELMOD | IOAPIC_RTE_INTVEC)
3838

3939
#define ACRN_DBG_IOAPIC 6U
4040
#define ACRN_IOAPIC_VERSION 0x11U
@@ -305,12 +305,12 @@ vioapic_indirect_write(struct vioapic *vioapic, uint32_t addr, uint32_t data)
305305
if ((regnum >= IOAPIC_REDTBL) &&
306306
(regnum < (IOAPIC_REDTBL + (pincount * 2U)))) {
307307
uint32_t addr_offset = regnum - IOAPIC_REDTBL;
308-
uint32_t rte_offset = addr_offset / 2U;
308+
uint32_t rte_offset = addr_offset >> 1U;
309309
pin = rte_offset;
310310

311311
last = vioapic->rtbl[pin];
312312
new = last;
313-
if ((addr_offset % 2U) != 0U) {
313+
if ((addr_offset & 1U) != 0U) {
314314
new.u.hi_32 = data;
315315
} else {
316316
new.u.lo_32 &= RTBL_RO_BITS;
@@ -331,8 +331,7 @@ vioapic_indirect_write(struct vioapic *vioapic, uint32_t addr, uint32_t data)
331331
/* pin0 from vpic mask/unmask */
332332
if ((pin == 0U) && ((changed & IOAPIC_RTE_INTMASK) != 0UL)) {
333333
/* mask -> umask */
334-
if (((last.full & IOAPIC_RTE_INTMASK) != 0UL) &&
335-
((new.full & IOAPIC_RTE_INTMASK) == 0UL)) {
334+
if ((last.full & IOAPIC_RTE_INTMASK) != 0UL) {
336335
if ((vioapic->vm->wire_mode ==
337336
VPIC_WIRE_NULL) ||
338337
(vioapic->vm->wire_mode ==
@@ -346,27 +345,24 @@ vioapic_indirect_write(struct vioapic *vioapic, uint32_t addr, uint32_t data)
346345
return;
347346
}
348347
/* unmask -> mask */
349-
} else if (((last.full & IOAPIC_RTE_INTMASK) == 0UL) &&
350-
((new.full & IOAPIC_RTE_INTMASK) != 0UL)) {
348+
} else {
351349
if (vioapic->vm->wire_mode ==
352350
VPIC_WIRE_IOAPIC) {
353351
vioapic->vm->wire_mode =
354352
VPIC_WIRE_INTR;
355353
dev_dbg(ACRN_DBG_IOAPIC,
356354
"vpic wire mode -> INTR");
357355
}
358-
} else {
359-
/* Can never happen since IOAPIC_RTE_INTMASK
360-
* is changed. */
361356
}
362357
}
363358
vioapic->rtbl[pin] = new;
364359
dev_dbg(ACRN_DBG_IOAPIC, "ioapic pin%hhu: redir table entry %#lx",
365360
pin, vioapic->rtbl[pin].full);
366361
/*
367-
* If any fields in the redirection table entry (except mask
368-
* or polarity) have changed then rendezvous all the vcpus
369-
* to update their vlapic trigger-mode registers.
362+
* If "Trigger Mode" or "Delivery Mode" or "Vector"
363+
* in the redirection table entry have changed then
364+
* rendezvous all the vcpus to update their vlapic
365+
* trigger-mode registers.
370366
*/
371367
if ((changed & NEED_TMR_UPDATE) != 0UL) {
372368
uint16_t i;
@@ -397,15 +393,9 @@ vioapic_indirect_write(struct vioapic *vioapic, uint32_t addr, uint32_t data)
397393
vioapic_send_intr(vioapic, pin);
398394
}
399395

400-
/* remap for active: interrupt mask -> unmask
401-
* remap for deactive: interrupt mask & vector set to 0
402-
* remap for trigger mode change
403-
* remap for polarity change
404-
*/
405-
if ( ((changed & IOAPIC_RTE_INTMASK) != 0UL) ||
406-
((changed & IOAPIC_RTE_TRGRMOD) != 0UL) ||
407-
((changed & IOAPIC_RTE_INTPOL ) != 0UL) ) {
408-
396+
/* remap for ptdev */
397+
if (((new.full & IOAPIC_RTE_INTMASK) == 0UL) ||
398+
((last.full & IOAPIC_RTE_INTMASK) == 0UL)) {
409399
/* VM enable intr */
410400
struct ptdev_intx_info intx;
411401

0 commit comments

Comments
 (0)