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>
next prev parent 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).