aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Piggin <npiggin@gmail.com>2025-05-12 13:10:38 +1000
committerCédric Le Goater <clg@redhat.com>2025-07-21 08:03:52 +0200
commitcc15d50b6e8a4090d667755259ea36144b79d22f (patch)
tree7df4e1ee207b1a54e2e6482de2f48b62bd6e5a2a
parent1319cb8997b9d0fdaae04a79398a2ed06d4cb5e1 (diff)
downloadqemu-cc15d50b6e8a4090d667755259ea36144b79d22f.zip
qemu-cc15d50b6e8a4090d667755259ea36144b79d22f.tar.gz
qemu-cc15d50b6e8a4090d667755259ea36144b79d22f.tar.bz2
ppc/xive2: Redistribute group interrupt preempted by higher priority interrupt
A group interrupt that gets preempted by a higher priority interrupt delivery must be redistributed otherwise it would get lost. 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-30-npiggin@gmail.com Signed-off-by: Cédric Le Goater <clg@redhat.com>
-rw-r--r--hw/intc/xive2.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c
index 602b23d..f51fd38 100644
--- a/hw/intc/xive2.c
+++ b/hw/intc/xive2.c
@@ -1638,11 +1638,21 @@ static void xive2_router_end_notify(Xive2Router *xrtr, uint8_t end_blk,
crowd, cam_ignore, priority,
xive_get_field32(END2_W7_F1_LOG_SERVER_ID, end.w7),
&match)) {
+ XiveTCTX *tctx = match.tctx;
+ uint8_t ring = match.ring;
+ uint8_t alt_ring = (ring == TM_QW2_HV_POOL) ? TM_QW3_HV_PHYS : ring;
+ uint8_t *aregs = &tctx->regs[alt_ring];
+ uint8_t nsr = aregs[TM_NSR];
uint8_t group_level;
+ if (priority < aregs[TM_PIPR] &&
+ xive_nsr_indicates_group_exception(alt_ring, nsr)) {
+ xive2_redistribute(xrtr, tctx, alt_ring);
+ }
+
group_level = xive_get_group_level(crowd, cam_ignore, nvx_blk, nvx_idx);
- trace_xive_presenter_notify(nvx_blk, nvx_idx, match.ring, group_level);
- xive_tctx_pipr_update(match.tctx, match.ring, priority, group_level);
+ trace_xive_presenter_notify(nvx_blk, nvx_idx, ring, group_level);
+ xive_tctx_pipr_update(tctx, ring, priority, group_level);
return;
}