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,


Reply via email to