diff options
author | Nicholas Piggin <npiggin@gmail.com> | 2025-05-12 13:10:51 +1000 |
---|---|---|
committer | Cédric Le Goater <clg@redhat.com> | 2025-07-21 08:03:53 +0200 |
commit | 565e6d4d2151e856026ee60d16c12a61e667cd15 (patch) | |
tree | 19f7bdbbb4c7bc02bfdc4568f3b0d4004adf2b80 | |
parent | 7a40b50757b55c2d4233c304f32df5afdd1bd63a (diff) | |
download | qemu-565e6d4d2151e856026ee60d16c12a61e667cd15.zip qemu-565e6d4d2151e856026ee60d16c12a61e667cd15.tar.gz qemu-565e6d4d2151e856026ee60d16c12a61e667cd15.tar.bz2 |
ppc/xive: Redistribute phys after pulling of pool context
After pulling the pool context, if a pool irq had been presented and
was cleared in the process, there could be a pending irq in phys that
should be presented. Process the phys irq ring after pulling pool ring
to catch this case and avoid losing irqs.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Reviewed-by: Glenn Miles <milesg@linux.ibm.com>
Reviewed-by: Michael Kowal <kowal@linux.ibm.com>
Tested-by: Gautam Menghani <gautam@linux.ibm.com>
Link: https://lore.kernel.org/qemu-devel/20250512031100.439842-43-npiggin@gmail.com
Signed-off-by: Cédric Le Goater <clg@redhat.com>
-rw-r--r-- | hw/intc/xive.c | 3 | ||||
-rw-r--r-- | hw/intc/xive2.c | 16 |
2 files changed, 17 insertions, 2 deletions
diff --git a/hw/intc/xive.c b/hw/intc/xive.c index d609d55..50a38bb 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -320,6 +320,9 @@ static uint64_t xive_tm_pull_pool_ctx(XivePresenter *xptr, XiveTCTX *tctx, xive_tctx_reset_signal(tctx, TM_QW1_OS); xive_tctx_reset_signal(tctx, TM_QW2_HV_POOL); + /* Re-check phys for interrupts if pool was disabled */ + xive_tctx_pipr_recompute_from_ipb(tctx, TM_QW3_HV_PHYS); + return qw2w2; } diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c index 1123974..e3f9ff3 100644 --- a/hw/intc/xive2.c +++ b/hw/intc/xive2.c @@ -683,6 +683,8 @@ static void xive2_redistribute(Xive2Router *xrtr, XiveTCTX *tctx, uint8_t ring) xive_tctx_reset_signal(tctx, ring); } +static void xive2_tctx_process_pending(XiveTCTX *tctx, uint8_t sig_ring); + static uint64_t xive2_tm_pull_ctx(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset, unsigned size, uint8_t ring) { @@ -739,6 +741,18 @@ static uint64_t xive2_tm_pull_ctx(XivePresenter *xptr, XiveTCTX *tctx, } } + if (ring == TM_QW2_HV_POOL) { + /* Re-check phys for interrupts if pool was disabled */ + nsr = tctx->regs[TM_QW3_HV_PHYS + TM_NSR]; + if (xive_nsr_indicates_exception(TM_QW3_HV_PHYS, nsr)) { + /* Ring must be PHYS because POOL would have been redistributed */ + g_assert(xive_nsr_exception_ring(TM_QW3_HV_PHYS, nsr) == + TM_QW3_HV_PHYS); + } else { + xive2_tctx_process_pending(tctx, TM_QW3_HV_PHYS); + } + } + if (xive2_router_get_config(xrtr) & XIVE2_VP_SAVE_RESTORE && do_save) { xive2_tctx_save_ctx(xrtr, tctx, ring, nvp_blk, nvp_idx); } @@ -925,8 +939,6 @@ static uint8_t xive2_tctx_restore_ctx(Xive2Router *xrtr, XiveTCTX *tctx, return cppr; } -static void xive2_tctx_process_pending(XiveTCTX *tctx, uint8_t sig_ring); - static void xive2_tctx_need_resend(Xive2Router *xrtr, XiveTCTX *tctx, uint8_t nvp_blk, uint32_t nvp_idx, bool do_restore) |