Reviewed-by: Glenn Miles <mil...@linux.ibm.com>
On Mon, 2025-05-12 at 13:10 +1000, Nicholas Piggin wrote:
> xive2 must take into account redistribution of group interrupts if
> the VP directed priority exceeds the group interrupt priority after
> this operation. The xive1 code is not group aware so implement this
> for xive2.
>
> Signed-off-by: Nicholas Piggin <npig...@gmail.com>
> ---
> hw/intc/xive.c | 2 ++
> hw/intc/xive2.c | 28 ++++++++++++++++++++++++++++
> include/hw/ppc/xive2.h | 2 ++
> 3 files changed, 32 insertions(+)
>
> diff --git a/hw/intc/xive.c b/hw/intc/xive.c
> index 979031a587..dc64edf13d 100644
> --- a/hw/intc/xive.c
> +++ b/hw/intc/xive.c
> @@ -747,6 +747,8 @@ static const XiveTmOp xive2_tm_operations[] = {
> /* MMIOs above 2K : special operations with side effects */
> { XIVE_TM_OS_PAGE, TM_SPC_ACK_OS_REG, 2, true, false,
> NULL, xive_tm_ack_os_reg },
> + { XIVE_TM_OS_PAGE, TM_SPC_SET_OS_PENDING, 1, true, false,
> + xive2_tm_set_os_pending, NULL },
> { XIVE_TM_HV_PAGE, TM_SPC_PULL_OS_CTX_G2, 4, true, false,
> NULL, xive2_tm_pull_os_ctx },
> { XIVE_TM_HV_PAGE, TM_SPC_PULL_OS_CTX, 4, true, false,
> diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c
> index 392ac6077e..de1ccad685 100644
> --- a/hw/intc/xive2.c
> +++ b/hw/intc/xive2.c
> @@ -1323,6 +1323,34 @@ void xive2_tm_set_os_cppr(XivePresenter *xptr,
> XiveTCTX *tctx,
> xive2_tctx_set_cppr(tctx, TM_QW1_OS, value & 0xff);
> }
>
> +/*
> + * Adjust the IPB to allow a CPU to process event queues of other
> + * priorities during one physical interrupt cycle.
> + */
> +void xive2_tm_set_os_pending(XivePresenter *xptr, XiveTCTX *tctx,
> + hwaddr offset, uint64_t value, unsigned size)
> +{
> + Xive2Router *xrtr = XIVE2_ROUTER(xptr);
> + uint8_t ring = TM_QW1_OS;
> + uint8_t *regs = &tctx->regs[ring];
> + uint8_t priority = value & 0xff;
> +
> + /*
> + * XXX: should this simply set a bit in IPB and wait for it to be picked
> + * up next cycle, or is it supposed to present it now? We implement the
> + * latter here.
> + */
> + regs[TM_IPB] |= xive_priority_to_ipb(priority);
> + if (xive_ipb_to_pipr(regs[TM_IPB]) >= regs[TM_PIPR]) {
> + return;
> + }
> + if (xive_nsr_indicates_group_exception(ring, regs[TM_NSR])) {
> + xive2_redistribute(xrtr, tctx, ring);
> + }
> +
> + xive_tctx_pipr_present(tctx, ring, priority, 0);
> +}
> +
> static void xive2_tctx_set_target(XiveTCTX *tctx, uint8_t ring, uint8_t
> target)
> {
> uint8_t *regs = &tctx->regs[ring];
> diff --git a/include/hw/ppc/xive2.h b/include/hw/ppc/xive2.h
> index c1ab06a55a..45266c2a8b 100644
> --- a/include/hw/ppc/xive2.h
> +++ b/include/hw/ppc/xive2.h
> @@ -130,6 +130,8 @@ void xive2_tm_set_hv_cppr(XivePresenter *xptr, XiveTCTX
> *tctx,
> hwaddr offset, uint64_t value, unsigned size);
> void xive2_tm_set_os_cppr(XivePresenter *xptr, XiveTCTX *tctx,
> hwaddr offset, uint64_t value, unsigned size);
> +void xive2_tm_set_os_pending(XivePresenter *xptr, XiveTCTX *tctx,
> + hwaddr offset, uint64_t value, unsigned size);
> void xive2_tm_push_os_ctx(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset,
> uint64_t value, unsigned size);
> uint64_t xive2_tm_pull_os_ctx(XivePresenter *xptr, XiveTCTX *tctx,