qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Nicholas Piggin" <npiggin@gmail.com>
To: "Michael Kowal" <kowal@linux.ibm.com>, <qemu-devel@nongnu.org>
Cc: <qemu-ppc@nongnu.org>, <fbarrat@linux.ibm.com>,
	<milesg@linux.ibm.com>, <danielhb413@gmail.com>,
	<david@gibson.dropbear.id.au>, <harshpb@linux.ibm.com>,
	<thuth@redhat.com>, <lvivier@redhat.com>, <pbonzini@redhat.com>
Subject: Re: [PATCH v2 10/14] ppc/xive2: Support crowd-matching when looking for target
Date: Mon, 10 Mar 2025 17:31:27 +1000	[thread overview]
Message-ID: <D8CESS2HNORM.1B2HHIPE39WD1@gmail.com> (raw)
In-Reply-To: <20241210000527.9541-20-kowal@linux.ibm.com>

On Tue Dec 10, 2024 at 10:05 AM AEST, Michael Kowal wrote:
> From: Frederic Barrat <fbarrat@linux.ibm.com>
>
> XIVE crowd sizes are encoded into a 2-bit field as follows:
>   0: 0b00
>   2: 0b01
>   4: 0b10
>  16: 0b11
>
> A crowd size of 8 is not supported.
>
> If an END is defined with the 'crowd' bit set, then a target can be
> running on different blocks. It means that some bits from the block
> VP are masked when looking for a match. It is similar to groups, but
> on the block instead of the VP index.
>
> Most of the changes are due to passing the extra argument 'crowd' all
> the way to the function checking for matches.
>
> Signed-off-by: Frederic Barrat <fbarrat@linux.ibm.com>
> Signed-off-by: Glenn Miles <milesg@linux.vnet.ibm.com>
> Signed-off-by: Michael Kowal <kowal@linux.ibm.com>
> ---
>  include/hw/ppc/xive.h  | 10 +++---
>  include/hw/ppc/xive2.h |  3 +-
>  hw/intc/pnv_xive.c     | 10 +++---
>  hw/intc/pnv_xive2.c    | 12 +++----
>  hw/intc/spapr_xive.c   |  8 ++---
>  hw/intc/xive.c         | 40 ++++++++++++++++++----
>  hw/intc/xive2.c        | 78 +++++++++++++++++++++++++++++++++---------
>  hw/ppc/pnv.c           | 15 ++++----
>  hw/ppc/spapr.c         |  7 ++--
>  9 files changed, 131 insertions(+), 52 deletions(-)
>
> diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
> index f443a39cf1..8317fde0db 100644
> --- a/include/hw/ppc/xive.h
> +++ b/include/hw/ppc/xive.h
> @@ -438,13 +438,13 @@ struct XivePresenterClass {
>      InterfaceClass parent;
>      int (*match_nvt)(XivePresenter *xptr, uint8_t format,
>                       uint8_t nvt_blk, uint32_t nvt_idx,
> -                     bool cam_ignore, uint8_t priority,
> +                     bool crowd, bool cam_ignore, uint8_t priority,
>                       uint32_t logic_serv, XiveTCTXMatch *match);
>      bool (*in_kernel)(const XivePresenter *xptr);
>      uint32_t (*get_config)(XivePresenter *xptr);
>      int (*broadcast)(XivePresenter *xptr,
>                       uint8_t nvt_blk, uint32_t nvt_idx,
> -                     uint8_t priority);
> +                     bool crowd, bool cam_ignore, uint8_t priority);
>  };
>  
>  int xive_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx,
> @@ -453,7 +453,7 @@ int xive_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx,
>                                bool cam_ignore, uint32_t logic_serv);
>  bool xive_presenter_notify(XiveFabric *xfb, uint8_t format,
>                             uint8_t nvt_blk, uint32_t nvt_idx,
> -                           bool cam_ignore, uint8_t priority,
> +                           bool crowd, bool cam_ignore, uint8_t priority,
>                             uint32_t logic_serv, bool *precluded);
>  
>  uint32_t xive_get_vpgroup_size(uint32_t nvp_index);
> @@ -473,10 +473,10 @@ struct XiveFabricClass {
>      InterfaceClass parent;
>      int (*match_nvt)(XiveFabric *xfb, uint8_t format,
>                       uint8_t nvt_blk, uint32_t nvt_idx,
> -                     bool cam_ignore, uint8_t priority,
> +                     bool crowd, bool cam_ignore, uint8_t priority,
>                       uint32_t logic_serv, XiveTCTXMatch *match);
>      int (*broadcast)(XiveFabric *xfb, uint8_t nvt_blk, uint32_t nvt_idx,
> -                     uint8_t priority);
> +                     bool crowd, bool cam_ignore, uint8_t priority);
>  };
>  
>  /*
> diff --git a/include/hw/ppc/xive2.h b/include/hw/ppc/xive2.h
> index c07e23e1d3..8cdf819174 100644
> --- a/include/hw/ppc/xive2.h
> +++ b/include/hw/ppc/xive2.h
> @@ -88,7 +88,8 @@ void xive2_router_notify(XiveNotifier *xn, uint32_t lisn, bool pq_checked);
>  int xive2_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx,
>                                 uint8_t format,
>                                 uint8_t nvt_blk, uint32_t nvt_idx,
> -                               bool cam_ignore, uint32_t logic_serv);
> +                               bool crowd, bool cam_ignore,
> +                               uint32_t logic_serv);
>  
>  uint64_t xive2_presenter_nvp_backlog_op(XivePresenter *xptr,
>                                          uint8_t blk, uint32_t idx,
> diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
> index 5bacbce6a4..d4796ab5a6 100644
> --- a/hw/intc/pnv_xive.c
> +++ b/hw/intc/pnv_xive.c
> @@ -1,10 +1,9 @@
>  /*
>   * QEMU PowerPC XIVE interrupt controller model
>   *
> - * Copyright (c) 2017-2019, IBM Corporation.
> + * Copyright (c) 2017-2024, IBM Corporation.
>   *
> - * This code is licensed under the GPL version 2 or later. See the
> - * COPYING file in the top-level directory.
> + * SPDX-License-Identifier: GPL-2.0-or-later
>   */
>  
>  #include "qemu/osdep.h"
> @@ -473,7 +472,7 @@ static bool pnv_xive_is_cpu_enabled(PnvXive *xive, PowerPCCPU *cpu)
>  
>  static int pnv_xive_match_nvt(XivePresenter *xptr, uint8_t format,
>                                uint8_t nvt_blk, uint32_t nvt_idx,
> -                              bool cam_ignore, uint8_t priority,
> +                              bool crowd, bool cam_ignore, uint8_t priority,
>                                uint32_t logic_serv, XiveTCTXMatch *match)
>  {
>      PnvXive *xive = PNV_XIVE(xptr);
> @@ -500,7 +499,8 @@ static int pnv_xive_match_nvt(XivePresenter *xptr, uint8_t format,
>               * Check the thread context CAM lines and record matches.
>               */
>              ring = xive_presenter_tctx_match(xptr, tctx, format, nvt_blk,
> -                                             nvt_idx, cam_ignore, logic_serv);
> +                                             nvt_idx, cam_ignore,
> +                                             logic_serv);
>              /*
>               * Save the context and follow on to catch duplicates, that we
>               * don't support yet.
> diff --git a/hw/intc/pnv_xive2.c b/hw/intc/pnv_xive2.c
> index 54abfe3947..91f3514f93 100644
> --- a/hw/intc/pnv_xive2.c
> +++ b/hw/intc/pnv_xive2.c
> @@ -624,7 +624,7 @@ static bool pnv_xive2_is_cpu_enabled(PnvXive2 *xive, PowerPCCPU *cpu)
>  
>  static int pnv_xive2_match_nvt(XivePresenter *xptr, uint8_t format,
>                                 uint8_t nvt_blk, uint32_t nvt_idx,
> -                               bool cam_ignore, uint8_t priority,
> +                               bool crowd, bool cam_ignore, uint8_t priority,
>                                 uint32_t logic_serv, XiveTCTXMatch *match)
>  {
>      PnvXive2 *xive = PNV_XIVE2(xptr);
> @@ -655,8 +655,8 @@ static int pnv_xive2_match_nvt(XivePresenter *xptr, uint8_t format,
>                                                   logic_serv);
>              } else {
>                  ring = xive2_presenter_tctx_match(xptr, tctx, format, nvt_blk,
> -                                                   nvt_idx, cam_ignore,
> -                                                   logic_serv);
> +                                                  nvt_idx, crowd, cam_ignore,
> +                                                  logic_serv);
>              }
>  
>              if (ring != -1) {
> @@ -707,7 +707,7 @@ static uint32_t pnv_xive2_presenter_get_config(XivePresenter *xptr)
>  
>  static int pnv_xive2_broadcast(XivePresenter *xptr,
>                                 uint8_t nvt_blk, uint32_t nvt_idx,
> -                               uint8_t priority)
> +                               bool crowd, bool ignore, uint8_t priority)
>  {
>      PnvXive2 *xive = PNV_XIVE2(xptr);
>      PnvChip *chip = xive->chip;
> @@ -732,10 +732,10 @@ static int pnv_xive2_broadcast(XivePresenter *xptr,
>  
>              if (gen1_tima_os) {
>                  ring = xive_presenter_tctx_match(xptr, tctx, 0, nvt_blk,
> -                                                 nvt_idx, true, 0);
> +                                                 nvt_idx, ignore, 0);
>              } else {
>                  ring = xive2_presenter_tctx_match(xptr, tctx, 0, nvt_blk,
> -                                                  nvt_idx, true, 0);
> +                                                  nvt_idx, crowd, ignore, 0);
>              }
>  
>              if (ring != -1) {
> diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
> index 283a6b8fd2..0477fdd594 100644
> --- a/hw/intc/spapr_xive.c
> +++ b/hw/intc/spapr_xive.c
> @@ -1,10 +1,9 @@
>  /*
>   * QEMU PowerPC sPAPR XIVE interrupt controller model
>   *
> - * Copyright (c) 2017-2018, IBM Corporation.
> + * Copyright (c) 2017-2024, IBM Corporation.
>   *
> - * This code is licensed under the GPL version 2 or later. See the
> - * COPYING file in the top-level directory.
> + * SPDX-License-Identifier: GPL-2.0-or-later
>   */
>  
>  #include "qemu/osdep.h"
> @@ -431,7 +430,8 @@ static int spapr_xive_write_nvt(XiveRouter *xrtr, uint8_t nvt_blk,
>  
>  static int spapr_xive_match_nvt(XivePresenter *xptr, uint8_t format,
>                                  uint8_t nvt_blk, uint32_t nvt_idx,
> -                                bool cam_ignore, uint8_t priority,
> +                                bool crowd, bool cam_ignore,
> +                                uint8_t priority,
>                                  uint32_t logic_serv, XiveTCTXMatch *match)
>  {
>      CPUState *cs;
> diff --git a/hw/intc/xive.c b/hw/intc/xive.c
> index 308de5aefc..97d1c42bb2 100644
> --- a/hw/intc/xive.c
> +++ b/hw/intc/xive.c
> @@ -1667,10 +1667,37 @@ uint32_t xive_get_vpgroup_size(uint32_t nvp_index)
>      return 1 << (ctz32(~nvp_index) + 1);
>  }
>  
> -static uint8_t xive_get_group_level(uint32_t nvp_index)
> +static uint8_t xive_get_group_level(bool crowd, bool ignore,
> +                                    uint32_t nvp_blk, uint32_t nvp_index)
>  {
> -    /* FIXME add crowd encoding */
> -    return ctz32(~nvp_index) + 1;
> +    uint8_t level = 0;
> +
> +    if (crowd) {
> +        /* crowd level is bit position of first 0 from the right in nvp_blk */
> +        level = ctz32(~nvp_blk) + 1;
> +
> +        /*
> +         * Supported crowd sizes are 2^1, 2^2, and 2^4. 2^3 is not supported.
> +         * HW will encode level 4 as the value 3.  See xive2_pgofnext().
> +         */
> +        switch (level) {
> +        case 1:
> +        case 2:
> +            break;
> +        case 4:
> +            level = 3;
> +            break;
> +        default:
> +            g_assert_not_reached();
> +        }
> +
> +        /* Crowd level bits reside in upper 2 bits of the 6 bit group level */
> +        level <<= 4;
> +    }
> +    if (ignore) {
> +        level |= (ctz32(~nvp_index) + 1) & 0b1111;
> +    }
> +    return level;
>  }
>  
>  /*

Crowd implies ignore I think? So it might read better if if (ignore) {
branch was at the top level with the bottom bits calculated first, then
if (crowd) { inside that branch.

> @@ -1742,7 +1769,7 @@ int xive_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx,
>   */
>  bool xive_presenter_notify(XiveFabric *xfb, uint8_t format,
>                             uint8_t nvt_blk, uint32_t nvt_idx,
> -                           bool cam_ignore, uint8_t priority,
> +                           bool crowd, bool cam_ignore, uint8_t priority,
>                             uint32_t logic_serv, bool *precluded)
>  {
>      XiveFabricClass *xfc = XIVE_FABRIC_GET_CLASS(xfb);
> @@ -1773,7 +1800,7 @@ bool xive_presenter_notify(XiveFabric *xfb, uint8_t format,
>       * a new command to the presenters (the equivalent of the "assign"
>       * power bus command in the documented full notify sequence.
>       */
> -    count = xfc->match_nvt(xfb, format, nvt_blk, nvt_idx, cam_ignore,
> +    count = xfc->match_nvt(xfb, format, nvt_blk, nvt_idx, crowd, cam_ignore,
>                             priority, logic_serv, &match);
>      if (count < 0) {
>          return false;
> @@ -1781,7 +1808,7 @@ bool xive_presenter_notify(XiveFabric *xfb, uint8_t format,
>  
>      /* handle CPU exception delivery */
>      if (count) {
> -        group_level = cam_ignore ? xive_get_group_level(nvt_idx) : 0;
> +        group_level = xive_get_group_level(crowd, cam_ignore, nvt_blk, nvt_idx);
>          trace_xive_presenter_notify(nvt_blk, nvt_idx, match.ring, group_level);
>          xive_tctx_pipr_update(match.tctx, match.ring, priority, group_level);
>      } else {
> @@ -1906,6 +1933,7 @@ void xive_router_end_notify(XiveRouter *xrtr, XiveEAS *eas)
>      }
>  
>      found = xive_presenter_notify(xrtr->xfb, format, nvt_blk, nvt_idx,
> +                          false /* crowd */,
>                            xive_get_field32(END_W7_F0_IGNORE, end.w7),
>                            priority,
>                            xive_get_field32(END_W7_F1_LOG_SERVER_ID, end.w7),
> diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c
> index f4621bdd02..20d63e8f6e 100644
> --- a/hw/intc/xive2.c
> +++ b/hw/intc/xive2.c
> @@ -1120,13 +1120,42 @@ static bool xive2_vp_match_mask(uint32_t cam1, uint32_t cam2,
>      return (cam1 & vp_mask) == (cam2 & vp_mask);
>  }
>  
> +static uint8_t xive2_get_vp_block_mask(uint32_t nvt_blk, bool crowd)
> +{
> +    uint8_t size, block_mask = 0b1111;
> +
> +    /* 3 supported crowd sizes: 2, 4, 16 */
> +    if (crowd) {
> +        size = xive_get_vpgroup_size(nvt_blk);
> +        if (size == 8) {
> +            qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid crowd size of 8n");
> +            return block_mask;
> +        }
> +        block_mask = ~(size - 1);
> +        block_mask &= 0b1111;

This could just be block_mask &= ~(size - 1) ?

> +    }
> +    return block_mask;
> +}
> +
> +static uint32_t xive2_get_vp_index_mask(uint32_t nvt_index, bool cam_ignore)
> +{
> +    uint32_t index_mask = 0xFFFFFF; /* 24 bits */
> +
> +    if (cam_ignore) {
> +        index_mask = ~(xive_get_vpgroup_size(nvt_index) - 1);
> +        index_mask &= 0xFFFFFF;

Similar here.

> +    }
> +    return index_mask;
> +}
> +
>  /*
>   * The thread context register words are in big-endian format.
>   */
>  int xive2_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx,
>                                 uint8_t format,
>                                 uint8_t nvt_blk, uint32_t nvt_idx,
> -                               bool cam_ignore, uint32_t logic_serv)
> +                               bool crowd, bool cam_ignore,
> +                               uint32_t logic_serv)
>  {
>      uint32_t cam =   xive2_nvp_cam_line(nvt_blk, nvt_idx);
>      uint32_t qw3w2 = xive_tctx_word2(&tctx->regs[TM_QW3_HV_PHYS]);
> @@ -1134,7 +1163,8 @@ int xive2_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx,
>      uint32_t qw1w2 = xive_tctx_word2(&tctx->regs[TM_QW1_OS]);
>      uint32_t qw0w2 = xive_tctx_word2(&tctx->regs[TM_QW0_USER]);
>  
> -    uint32_t vp_mask = 0xFFFFFFFF;
> +    uint32_t index_mask, vp_mask;
> +    uint8_t block_mask;
>  
>      if (format == 0) {
>          /*
> @@ -1142,9 +1172,9 @@ int xive2_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx,
>           * i=1: VP-group notification (bits ignored at the end of the
>           *      NVT identifier)
>           */
> -        if (cam_ignore) {
> -            vp_mask = ~(xive_get_vpgroup_size(nvt_idx) - 1);
> -        }
> +        block_mask = xive2_get_vp_block_mask(nvt_blk, crowd);
> +        index_mask = xive2_get_vp_index_mask(nvt_idx, cam_ignore);
> +        vp_mask = xive2_nvp_cam_line(block_mask, index_mask);

Just a small thing but you could have all these be a single function,

 vp_mask = xive2_get_vp_mask(nvt_blk, nvt_idx, crowd, cam_ignore);

Reviewed-by: Nicholas Piggin <npiggin@gmail.com>



  reply	other threads:[~2025-03-10  7:32 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-12-10  0:05 [PATCH v2 00/14] XIVE2 changes to support Group and Crowd operations Michael Kowal
2024-12-10  0:05 ` [PATCH v2 01/14] ppc/xive2: Update NVP save/restore for group attributes Michael Kowal
2025-03-10  3:22   ` Nicholas Piggin
2024-12-10  0:05 ` [PATCH v2 02/14] ppc/xive2: Add grouping level to notification Michael Kowal
2025-03-10  3:27   ` Nicholas Piggin
2024-12-10  0:05 ` [PATCH v2 02/14] ppc/xive: Rename ipb_to_pipr() to xive_ipb_to_pipr() Michael Kowal
2025-03-10  3:45   ` Nicholas Piggin
2024-12-10  0:05 ` [PATCH v2 03/14] ppc/xive2: Add grouping level to notification Michael Kowal
2025-03-10  3:43   ` Nicholas Piggin
2024-12-10  0:05 ` [PATCH v2 03/14] ppc/xive2: Support group-matching when looking for target Michael Kowal
2025-03-10  3:52   ` Nicholas Piggin
2024-12-10  0:05 ` [PATCH v2 04/14] ppc/xive2: Add undelivered group interrupt to backlog Michael Kowal
2024-12-10  0:05 ` [PATCH v2 04/14] ppc/xive2: Support group-matching when looking for target Michael Kowal
2024-12-10  0:05 ` [PATCH v2 05/14] ppc/xive2: Add undelivered group interrupt to backlog Michael Kowal
2025-03-10  4:07   ` Nicholas Piggin
2024-12-10  0:05 ` [PATCH v2 05/14] ppc/xive2: Process group backlog when pushing an OS context Michael Kowal
2024-12-10  0:05 ` [PATCH v2 06/14] " Michael Kowal
2024-12-10  0:05 ` [PATCH v2 06/14] ppc/xive2: Process group backlog when updating the CPPR Michael Kowal
2024-12-10  0:05 ` [PATCH v2 07/14] " Michael Kowal
2025-03-10  4:35   ` Nicholas Piggin
2024-12-10  0:05 ` [PATCH v2 07/14] qtest/xive: Add group-interrupt test Michael Kowal
2024-12-10  0:05 ` [PATCH v2 08/14] Add support for MMIO operations on the NVPG/NVC BAR Michael Kowal
2024-12-10  0:05 ` [PATCH v2 08/14] qtest/xive: Add group-interrupt test Michael Kowal
2025-03-10  4:46   ` Nicholas Piggin
2024-12-10  0:05 ` [PATCH v2 09/14] ppc/xive2: Add support for MMIO operations on the NVPG/NVC BAR Michael Kowal
2025-03-10  5:10   ` Nicholas Piggin
2024-12-10  0:05 ` [PATCH v2 09/14] ppc/xive2: Support crowd-matching when looking for target Michael Kowal
2024-12-10  0:05 ` [PATCH v2 10/14] ppc/xive2: Check crowd backlog when scanning group backlog Michael Kowal
2024-12-10  0:05 ` [PATCH v2 10/14] ppc/xive2: Support crowd-matching when looking for target Michael Kowal
2025-03-10  7:31   ` Nicholas Piggin [this message]
2024-12-10  0:05 ` [PATCH v2 11/14] pnv/xive: Only support crowd size of 0, 2, 4 and 16 Michael Kowal
2025-03-10  5:15   ` Nicholas Piggin
2024-12-10  0:05 ` [PATCH v2 11/14] ppc/xive2: Check crowd backlog when scanning group backlog Michael Kowal
2025-03-10  7:32   ` Nicholas Piggin
2024-12-10  0:05 ` [PATCH v2 12/14] pnv/xive: Support ESB Escalation Michael Kowal
2025-03-10  8:07   ` Nicholas Piggin
2024-12-10  0:05 ` [PATCH v2 13/14] pnv/xive: Fix problem with treating NVGC as a NVP Michael Kowal
2025-03-10  5:19   ` Nicholas Piggin
2024-12-10  0:05 ` [PATCH v2 14/14] qtest/xive: Add test of pool interrupts Michael Kowal
2025-03-10  8:20   ` Nicholas Piggin
2025-03-11 13:16 ` [PATCH v2 00/14] XIVE2 changes to support Group and Crowd operations Nicholas Piggin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=D8CESS2HNORM.1B2HHIPE39WD1@gmail.com \
    --to=npiggin@gmail.com \
    --cc=danielhb413@gmail.com \
    --cc=david@gibson.dropbear.id.au \
    --cc=fbarrat@linux.ibm.com \
    --cc=harshpb@linux.ibm.com \
    --cc=kowal@linux.ibm.com \
    --cc=lvivier@redhat.com \
    --cc=milesg@linux.ibm.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    --cc=thuth@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).