diff mbox series

[41/61] hw/psi-p10: Configure interrupt offset before notify addr

Message ID 20210719132012.150948-42-hegdevasant@linux.vnet.ibm.com
State Superseded
Headers show
Series P10 Enablement | expand

Commit Message

Vasant Hegde July 19, 2021, 1:19 p.m. UTC
From: Oliver O'Halloran <oohall@gmail.com>

When configuring the XIVE notification address any currently pending
interrupts will be delivered once the the valid bit in the BAR is
set.

Currently we enable the notify BAR before we've configured the global
interrupt number offset for the PSI interrupts. If any PSI interrupt is
we'll send an interrupt trigger notification to the XIVE with the wrong
interrupt vector (0..15). This can potentially cause a checkstop since
there may not be an EAS / IVT configure for that vector. Fix this by
registering and masking all the PSI interrupts after we've configured
the ESB BAR, but before configuring the notification address and offset.

Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
Signed-off-by: C├ędric Le Goater <clg@kaod.org>
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
---
 hw/psi.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)
diff mbox series

Patch

diff --git a/hw/psi.c b/hw/psi.c
index 954b7bf68..de074ce4a 100644
--- a/hw/psi.c
+++ b/hw/psi.c
@@ -796,16 +796,6 @@  static void psi_init_p10_interrupts(struct psi *psi)
 		flags |= XIVE_SRC_STORE_EOI;
 	}
 
-	/* Grab and configure the notification port */
-	val = xive2_get_notify_port(psi->chip_id, XIVE_HW_SRC_PSI);
-	val |= PSIHB_ESB_NOTIF_VALID;
-	out_be64(psi->regs + PSIHB_ESB_NOTIF_ADDR, val);
-
-	/* Setup interrupt offset */
-	val = xive2_get_notify_base(psi->interrupt);
-	val <<= 32;
-	out_be64(psi->regs + PSIHB_IVT_OFFSET, val);
-
 	/* Register sources */
 	prlog(PR_DEBUG,
 	      "PSI[0x%03x]: Interrupts sources registered for P10 DD%i.%i\n",
@@ -820,6 +810,16 @@  static void psi_init_p10_interrupts(struct psi *psi)
 	for (isn = is->start; isn < is->end; isn++)
 		xive2_source_mask(is, isn);
 
+	/* Setup interrupt offset */
+	val = xive2_get_notify_base(psi->interrupt);
+	val <<= 32;
+	out_be64(psi->regs + PSIHB_IVT_OFFSET, val);
+
+	/* Grab and configure the notification port */
+	val = xive2_get_notify_port(psi->chip_id, XIVE_HW_SRC_PSI);
+	val |= PSIHB_ESB_NOTIF_VALID;
+	out_be64(psi->regs + PSIHB_ESB_NOTIF_ADDR, val);
+
 	/* Reset irq handling and switch to ESB mode */
 	out_be64(psi->regs + PSIHB_INTERRUPT_CONTROL, PSIHB_IRQ_RESET);
 	out_be64(psi->regs + PSIHB_INTERRUPT_CONTROL, 0);