diff options
author | Oliver O'Halloran <oohall@gmail.com> | 2020-07-20 14:39:48 +1000 |
---|---|---|
committer | Oliver O'Halloran <oohall@gmail.com> | 2020-08-07 16:00:20 +1000 |
commit | 15f56c8ddc150819e532becf026419c2d5e0bc66 (patch) | |
tree | 16d64d31d458e1268251b24dd987cfc4b142781b /hw/psi.c | |
parent | 80cb77739c42a292e33814a0361dce9f5886d41a (diff) | |
download | skiboot-15f56c8ddc150819e532becf026419c2d5e0bc66.zip skiboot-15f56c8ddc150819e532becf026419c2d5e0bc66.tar.gz skiboot-15f56c8ddc150819e532becf026419c2d5e0bc66.tar.bz2 |
hw/psi-p9: Configure IRQ offset before XIVE notify
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
pending at this point we'll send an interrupt trigger notification for
the wrong interrupt vector. This can potentially cause a checkstop since
there may not be an EAS / IVT configure for that vector.
Fix this by fixing the ordering so we setup the offset before the XIVE
notification address.
Cc: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
Diffstat (limited to 'hw/psi.c')
-rw-r--r-- | hw/psi.c | 20 |
1 files changed, 10 insertions, 10 deletions
@@ -701,16 +701,6 @@ static void psi_init_p9_interrupts(struct psi *psi) prlog(PR_DEBUG, "PSI[0x%03x]: ESB MMIO at @%p\n", psi->chip_id, psi->esb_mmio); - /* Grab and configure the notification port */ - val = xive_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 = xive_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 P9 DD2.x\n", @@ -719,6 +709,16 @@ static void psi_init_p9_interrupts(struct psi *psi) 12, psi->esb_mmio, XIVE_SRC_LSI, psi, &psi_p9_irq_ops); + /* Setup interrupt offset */ + val = xive_get_notify_base(psi->interrupt); + val <<= 32; + out_be64(psi->regs + PSIHB_IVT_OFFSET, val); + + /* Grab and configure the notification port */ + val = xive_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); |