[PATCH 13/14] pnv/xive: Fix problem with treating NVGC as a NVP

Michael Kowal posted 14 patches 1 year, 3 months ago
There is a newer version of this series
[PATCH 13/14] pnv/xive: Fix problem with treating NVGC as a NVP
Posted by Michael Kowal 1 year, 3 months ago
From: Glenn Miles <milesg@linux.ibm.com>

When booting with PHYP, the blk/index for a NVGC was being
mistakenly treated as the blk/index for a NVP.  Renamed
nvp_blk/nvp_idx throughout the code to nvx_blk/nvx_idx to prevent
confusion in the future and now we delay loading the NVP until
the point where we know that the block and index actually point to
a NVP.

Suggested-by: Michael Kowal <kowal@us.ibm.com>
Fixes: 6d4c4f70262 ("ppc/xive2: Support crowd-matching when looking for target")
Signed-off-by: Glenn Miles <milesg@linux.vnet.ibm.com>
Signed-off-by: Michael Kowal <kowal@linux.ibm.com>
---
 hw/intc/xive2.c | 78 ++++++++++++++++++++++++-------------------------
 1 file changed, 39 insertions(+), 39 deletions(-)

diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c
index f812ba9624..8abccd2f4b 100644
--- a/hw/intc/xive2.c
+++ b/hw/intc/xive2.c
@@ -226,8 +226,8 @@ void xive2_end_pic_print_info(Xive2End *end, uint32_t end_idx, GString *buf)
     uint32_t qsize = xive_get_field32(END2_W3_QSIZE, end->w3);
     uint32_t qentries = 1 << (qsize + 10);
 
-    uint32_t nvp_blk = xive_get_field32(END2_W6_VP_BLOCK, end->w6);
-    uint32_t nvp_idx = xive_get_field32(END2_W6_VP_OFFSET, end->w6);
+    uint32_t nvx_blk = xive_get_field32(END2_W6_VP_BLOCK, end->w6);
+    uint32_t nvx_idx = xive_get_field32(END2_W6_VP_OFFSET, end->w6);
     uint8_t priority = xive_get_field32(END2_W7_F0_PRIORITY, end->w7);
     uint8_t pq;
 
@@ -256,7 +256,7 @@ void xive2_end_pic_print_info(Xive2End *end, uint32_t end_idx, GString *buf)
                            xive2_end_is_firmware2(end)   ? 'F' : '-',
                            xive2_end_is_ignore(end) ? 'i' : '-',
                            xive2_end_is_crowd(end)  ? 'c' : '-',
-                           priority, nvp_blk, nvp_idx);
+                           priority, nvx_blk, nvx_idx);
 
     if (qaddr_base) {
         g_string_append_printf(buf, " eq:@%08"PRIx64"% 6d/%5d ^%d",
@@ -401,7 +401,7 @@ static void xive2_pgofnext(uint8_t *nvgc_blk, uint32_t *nvgc_idx,
  * level of pending group interrupts.
  */
 static uint8_t xive2_presenter_backlog_check(XivePresenter *xptr,
-                                             uint8_t nvp_blk, uint32_t nvp_idx,
+                                             uint8_t nvx_blk, uint32_t nvx_idx,
                                              uint8_t first_group,
                                              uint8_t *out_level)
 {
@@ -413,8 +413,8 @@ static uint8_t xive2_presenter_backlog_check(XivePresenter *xptr,
 
     for (prio = 0; prio <= XIVE_PRIORITY_MAX; prio++) {
         current_level = first_group & 0x3F;
-        nvgc_blk = nvp_blk;
-        nvgc_idx = nvp_idx;
+        nvgc_blk = nvx_blk;
+        nvgc_idx = nvx_idx;
 
         while (current_level) {
             xive2_pgofnext(&nvgc_blk, &nvgc_idx, current_level);
@@ -443,7 +443,7 @@ static uint8_t xive2_presenter_backlog_check(XivePresenter *xptr,
 }
 
 static void xive2_presenter_backlog_decr(XivePresenter *xptr,
-                                         uint8_t nvp_blk, uint32_t nvp_idx,
+                                         uint8_t nvx_blk, uint32_t nvx_idx,
                                          uint8_t group_prio,
                                          uint8_t group_level)
 {
@@ -452,8 +452,8 @@ static void xive2_presenter_backlog_decr(XivePresenter *xptr,
     uint8_t nvgc_blk;
     Xive2Nvgc nvgc;
 
-    nvgc_blk = nvp_blk;
-    nvgc_idx = nvp_idx;
+    nvgc_blk = nvx_blk;
+    nvgc_idx = nvx_idx;
     xive2_pgofnext(&nvgc_blk, &nvgc_idx, group_level);
 
     if (xive2_router_get_nvgc(xrtr, NVx_CROWD_LVL(group_level),
@@ -1317,9 +1317,8 @@ static void xive2_router_end_notify(Xive2Router *xrtr, uint8_t end_blk,
     uint8_t priority;
     uint8_t format;
     bool found, precluded;
-    Xive2Nvp nvp;
-    uint8_t nvp_blk;
-    uint32_t nvp_idx;
+    uint8_t nvx_blk;
+    uint32_t nvx_idx;
 
     /* END cache lookup */
     if (xive2_router_get_end(xrtr, end_blk, end_idx, &end)) {
@@ -1384,23 +1383,10 @@ static void xive2_router_end_notify(Xive2Router *xrtr, uint8_t end_blk,
     /*
      * Follows IVPE notification
      */
-    nvp_blk = xive_get_field32(END2_W6_VP_BLOCK, end.w6);
-    nvp_idx = xive_get_field32(END2_W6_VP_OFFSET, end.w6);
-
-    /* NVP cache lookup */
-    if (xive2_router_get_nvp(xrtr, nvp_blk, nvp_idx, &nvp)) {
-        qemu_log_mask(LOG_GUEST_ERROR, "XIVE: no NVP %x/%x\n",
-                      nvp_blk, nvp_idx);
-        return;
-    }
-
-    if (!xive2_nvp_is_valid(&nvp)) {
-        qemu_log_mask(LOG_GUEST_ERROR, "XIVE: NVP %x/%x is invalid\n",
-                      nvp_blk, nvp_idx);
-        return;
-    }
+    nvx_blk = xive_get_field32(END2_W6_VP_BLOCK, end.w6);
+    nvx_idx = xive_get_field32(END2_W6_VP_OFFSET, end.w6);
 
-    found = xive_presenter_notify(xrtr->xfb, format, nvp_blk, nvp_idx,
+    found = xive_presenter_notify(xrtr->xfb, format, nvx_blk, nvx_idx,
                           xive2_end_is_crowd(&end), xive2_end_is_ignore(&end),
                           priority,
                           xive_get_field32(END2_W7_F1_LOG_SERVER_ID, end.w7),
@@ -1428,6 +1414,21 @@ static void xive2_router_end_notify(Xive2Router *xrtr, uint8_t end_blk,
 
         if (!xive2_end_is_ignore(&end)) {
             uint8_t ipb;
+            Xive2Nvp nvp;
+
+            /* NVP cache lookup */
+            if (xive2_router_get_nvp(xrtr, nvx_blk, nvx_idx, &nvp)) {
+                qemu_log_mask(LOG_GUEST_ERROR, "XIVE: no NVP %x/%x\n",
+                              nvx_blk, nvx_idx);
+                return;
+            }
+
+            if (!xive2_nvp_is_valid(&nvp)) {
+                qemu_log_mask(LOG_GUEST_ERROR, "XIVE: NVP %x/%x is invalid\n",
+                              nvx_blk, nvx_idx);
+                return;
+            }
+
             /*
              * Record the IPB in the associated NVP structure for later
              * use. The presenter will resend the interrupt when the vCPU
@@ -1436,7 +1437,7 @@ static void xive2_router_end_notify(Xive2Router *xrtr, uint8_t end_blk,
             ipb = xive_get_field32(NVP2_W2_IPB, nvp.w2) |
                 xive_priority_to_ipb(priority);
             nvp.w2 = xive_set_field32(NVP2_W2_IPB, nvp.w2, ipb);
-            xive2_router_write_nvp(xrtr, nvp_blk, nvp_idx, &nvp, 2);
+            xive2_router_write_nvp(xrtr, nvx_blk, nvx_idx, &nvp, 2);
         } else {
             Xive2Nvgc nvgc;
             uint32_t backlog;
@@ -1449,32 +1450,31 @@ static void xive2_router_end_notify(Xive2Router *xrtr, uint8_t end_blk,
              * counters are stored in the NVG/NVC structures
              */
             if (xive2_router_get_nvgc(xrtr, crowd,
-                                      nvp_blk, nvp_idx, &nvgc)) {
+                                      nvx_blk, nvx_idx, &nvgc)) {
                 qemu_log_mask(LOG_GUEST_ERROR, "XIVE: no %s %x/%x\n",
-                              crowd ? "NVC" : "NVG", nvp_blk, nvp_idx);
+                              crowd ? "NVC" : "NVG", nvx_blk, nvx_idx);
                 return;
             }
 
             if (!xive2_nvgc_is_valid(&nvgc)) {
                 qemu_log_mask(LOG_GUEST_ERROR, "XIVE: NVG %x/%x is invalid\n",
-                              nvp_blk, nvp_idx);
+                              nvx_blk, nvx_idx);
                 return;
             }
 
             /*
              * Increment the backlog counter for that priority.
-             * For the precluded case, we only call broadcast the
-             * first time the counter is incremented. broadcast will
-             * set the LSMFB field of the TIMA of relevant threads so
-             * that they know an interrupt is pending.
+             * We only call broadcast the first time the counter is
+             * incremented. broadcast will set the LSMFB field of the TIMA of
+             * relevant threads so that they know an interrupt is pending.
              */
             backlog = xive2_nvgc_get_backlog(&nvgc, priority) + 1;
             xive2_nvgc_set_backlog(&nvgc, priority, backlog);
-            xive2_router_write_nvgc(xrtr, crowd, nvp_blk, nvp_idx, &nvgc);
+            xive2_router_write_nvgc(xrtr, crowd, nvx_blk, nvx_idx, &nvgc);
 
-            if (precluded && backlog == 1) {
+            if (backlog == 1) {
                 XiveFabricClass *xfc = XIVE_FABRIC_GET_CLASS(xrtr->xfb);
-                xfc->broadcast(xrtr->xfb, nvp_blk, nvp_idx,
+                xfc->broadcast(xrtr->xfb, nvx_blk, nvx_idx,
                                xive2_end_is_crowd(&end),
                                xive2_end_is_ignore(&end),
                                priority);
-- 
2.43.0
Re: [PATCH 13/14] pnv/xive: Fix problem with treating NVGC as a NVP
Posted by Nicholas Piggin 1 year, 2 months ago
On Wed Oct 16, 2024 at 7:13 AM AEST, Michael Kowal wrote:
> From: Glenn Miles <milesg@linux.ibm.com>
>
> When booting with PHYP, the blk/index for a NVGC was being
> mistakenly treated as the blk/index for a NVP.  Renamed
> nvp_blk/nvp_idx throughout the code to nvx_blk/nvx_idx to prevent
> confusion in the future and now we delay loading the NVP until
> the point where we know that the block and index actually point to
> a NVP.
>
> Suggested-by: Michael Kowal <kowal@us.ibm.com>
> Fixes: 6d4c4f70262 ("ppc/xive2: Support crowd-matching when looking for target")

Mechanical renaming should be moved to the start of the series,
and the fix should be merged into patch 3. Commit tags should only
be used if they exist in upstream repo.

Thanks,
Nick