qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 00/14] XIVE2 changes for TIMA operations
@ 2024-09-09 21:10 Michael Kowal
  2024-09-09 21:10 ` [PATCH v2 01/14] pnv/xive: TIMA patch sets pre-req alignment and formatting changes Michael Kowal
                   ` (13 more replies)
  0 siblings, 14 replies; 23+ messages in thread
From: Michael Kowal @ 2024-09-09 21:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, clg, fbarrat, npiggin, milesg

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=yes, Size: 3465 bytes --]

In XIVE Gen 2 there are many operations that were not modeled and are
needed for PowerVM.  These changes are associated with the following Thread
Interrupt Management Area subjects:
 - OS context
 - Thread context
 - Pulling contexts to 'cache lines'
 - Pool targets
 - Enhaced trace data for XIVE Gen2

version 2:
- use dma_memory_write() instead of cpu_physical_memory_write()
- use ternery operator in NVG/NVC pnv_xive2_vst_read/write()
- removed xive2_nvgc_set_backlog() until it is needed
- re-defined word 2 valid bits since it is the same in each Reporting
- provided better fix for possible NSR operation overflow
- moved changes for operations that can occur on ring, in a new patch set (10/13)
- version 1 reviewed-by tags:
$b4 am 20240801203008.11224-1-kowal@linux.ibm.com
Analyzing 35 messages in the thread
Analyzing 0 code-review messages
---
  [PATCH 1/13] pnv/xive: TIMA patch sets pre-req alignment and formatting changes
    + Reviewed-by: Cédric Le Goater <clg@redhat.com>
  [PATCH 2/13] pnv/xive2: Define OGEN field in the TIMA
    + Reviewed-by: Cédric Le Goater <clg@redhat.com>
  [PATCH 3/13] ppc/xive2: Support TIMA "Pull OS Context to Odd Thread Reporting Line"
  [PATCH 4/13] pnv/xive2: Support for "OS LGS Push" TIMA operation
    + Reviewed-by: Cédric Le Goater <clg@redhat.com>
  [PATCH 5/13] ppc/xive2: Dump more NVP state with 'info pic'
  [PATCH 6/13] ppc/xive2: Dump the VP-group and crowd tables with 'info pic'
  [PATCH 7/13] ppc/xive2: Allow 1-byte write of Target field in TIMA
    + Reviewed-by: Cédric Le Goater <clg@redhat.com>
  [PATCH 8/13] ppc/xive2: Support "Pull Thread Context to Register" operation
    + Reviewed-by: Cédric Le Goater <clg@redhat.com>
  [PATCH 9/13] ppc/xive2: Support "Pull Thread Context to Odd Thread Reporting Line"
  [PATCH 10/13] pnv/xive: Add special handling for pool targets
  [PATCH 11/13] pnv/xive: Update PIPR when updating CPPR
  [PATCH 12/13] pnv/xive2: TIMA support for 8-byte OS context push for PHYP
    + Reviewed-by: Cédric Le Goater <clg@redhat.com>
  [PATCH 13/13] pnv/xive2: TIMA CI ops using alternative offsets or byte lengths
    + Reviewed-by: Cédric Le Goater <clg@redhat.com>


Frederic Barrat (4):
  pnv/xive2: Define OGEN field in the TIMA
  ppc/xive2: Support TIMA "Pull OS Context to Odd Thread Reporting Line"
  ppc/xive2: Dump more NVP state with 'info pic'
  ppc/xive2: Dump the VP-group and crowd tables with 'info pic'

Glenn Miles (7):
  pnv/xive2: Support for "OS LGS Push" TIMA operation
  ppc/xive2: Allow 1-byte write of Target field in TIMA
  ppc/xive2: Support "Pull Thread Context to Register" operation
  ppc/xive2: Support "Pull Thread Context to Odd Thread Reporting Line"
  pnv/xive: Add special handling for pool targets
  pnv/xive: Update PIPR when updating CPPR
  pnv/xive2: TIMA support for 8-byte OS context push for PHYP

Michael Kowal (3):
  pnv/xive: TIMA patch sets pre-req alignment and formatting changes
  ppc/xive2: Change context/ring specific functions to be generic
  pnv/xive2: TIMA CI ops using alternative offsets or byte lengths

 include/hw/ppc/xive.h       |   2 +-
 include/hw/ppc/xive2.h      |  18 ++
 include/hw/ppc/xive2_regs.h |  25 ++-
 include/hw/ppc/xive_regs.h  |  45 +++--
 hw/intc/pnv_xive2.c         |  44 ++++-
 hw/intc/xive.c              | 201 ++++++++++++++++++-----
 hw/intc/xive2.c             | 317 ++++++++++++++++++++++++++++++------
 7 files changed, 537 insertions(+), 115 deletions(-)

--
2.43.0



^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v2 01/14] pnv/xive: TIMA patch sets pre-req alignment and formatting changes
  2024-09-09 21:10 [PATCH v2 00/14] XIVE2 changes for TIMA operations Michael Kowal
@ 2024-09-09 21:10 ` Michael Kowal
  2024-09-09 21:10 ` [PATCH v2 02/14] pnv/xive2: Define OGEN field in the TIMA Michael Kowal
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 23+ messages in thread
From: Michael Kowal @ 2024-09-09 21:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, clg, fbarrat, npiggin, milesg

From: Michael Kowal <kowal@linux.vnet.ibm.com>

Making some pre-requisite alignment changes ahead of the following patch
sets.  Making these changes now will ease the review of the patch sets.

Checkpatch wants the closing comment '*/' on a separate line, unless it is
on the same line as the starting comment '/*'.

There are also changes to prevent lines from spanning 80 columns.

Changed block of defines from:
   #define A 1  /* original define comment is not
                 * preferred, but not flagged... */
   #define B 2  /* Newly added define comment
                 * is flagged with a warning */
To:
   #define A 1  /* original define comment is */
                /* now fine, no warning...    */
   #define B 2  /* Newly added define comment */
                /* is fine...                 */

Signed-off-by: Michael Kowal <kowal@linux.vnet.ibm.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
---
 include/hw/ppc/xive_regs.h | 32 ++++++++---------
 hw/intc/xive.c             | 72 +++++++++++++++++++++++++-------------
 2 files changed, 64 insertions(+), 40 deletions(-)

diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h
index b9db7abc2e..9d52d464d9 100644
--- a/include/hw/ppc/xive_regs.h
+++ b/include/hw/ppc/xive_regs.h
@@ -114,23 +114,23 @@
  * Then we have all these "special" CI ops at these offset that trigger
  * all sorts of side effects:
  */
-#define TM_SPC_ACK_EBB          0x800   /* Load8 ack EBB to reg*/
-#define TM_SPC_ACK_OS_REG       0x810   /* Load16 ack OS irq to reg */
+#define TM_SPC_ACK_EBB          0x800   /* Load8 ack EBB to reg               */
+#define TM_SPC_ACK_OS_REG       0x810   /* Load16 ack OS irq to reg           */
 #define TM_SPC_PUSH_USR_CTX     0x808   /* Store32 Push/Validate user context */
-#define TM_SPC_PULL_USR_CTX     0x808   /* Load32 Pull/Invalidate user
-                                         * context */
-#define TM_SPC_SET_OS_PENDING   0x812   /* Store8 Set OS irq pending bit */
-#define TM_SPC_PULL_OS_CTX      0x818   /* Load32/Load64 Pull/Invalidate OS
-                                         * context to reg */
-#define TM_SPC_PULL_POOL_CTX    0x828   /* Load32/Load64 Pull/Invalidate Pool
-                                         * context to reg*/
-#define TM_SPC_ACK_HV_REG       0x830   /* Load16 ack HV irq to reg */
-#define TM_SPC_PULL_USR_CTX_OL  0xc08   /* Store8 Pull/Inval usr ctx to odd
-                                         * line */
-#define TM_SPC_ACK_OS_EL        0xc10   /* Store8 ack OS irq to even line */
-#define TM_SPC_ACK_HV_POOL_EL   0xc20   /* Store8 ack HV evt pool to even
-                                         * line */
-#define TM_SPC_ACK_HV_EL        0xc30   /* Store8 ack HV irq to even line */
+#define TM_SPC_PULL_USR_CTX     0x808   /* Load32 Pull/Invalidate user        */
+                                        /* context                            */
+#define TM_SPC_SET_OS_PENDING   0x812   /* Store8 Set OS irq pending bit      */
+#define TM_SPC_PULL_OS_CTX      0x818   /* Load32/Load64 Pull/Invalidate OS   */
+                                        /* context to reg                     */
+#define TM_SPC_PULL_POOL_CTX    0x828   /* Load32/Load64 Pull/Invalidate Pool */
+                                        /* context to reg                     */
+#define TM_SPC_ACK_HV_REG       0x830   /* Load16 ack HV irq to reg           */
+#define TM_SPC_PULL_USR_CTX_OL  0xc08   /* Store8 Pull/Inval usr ctx to odd   */
+                                        /* line                               */
+#define TM_SPC_ACK_OS_EL        0xc10   /* Store8 ack OS irq to even line     */
+#define TM_SPC_ACK_HV_POOL_EL   0xc20   /* Store8 ack HV evt pool to even     */
+                                        /* line                               */
+#define TM_SPC_ACK_HV_EL        0xc30   /* Store8 ack HV irq to even line     */
 /* XXX more... */
 
 /* NSR fields for the various QW ack types */
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 5a02dd8e02..2fb38e2102 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -488,20 +488,32 @@ static const XiveTmOp xive_tm_operations[] = {
      * MMIOs below 2K : raw values and special operations without side
      * effects
      */
-    { XIVE_TM_OS_PAGE, TM_QW1_OS + TM_CPPR,   1, xive_tm_set_os_cppr, NULL },
-    { XIVE_TM_HV_PAGE, TM_QW1_OS + TM_WORD2,     4, xive_tm_push_os_ctx, NULL },
-    { XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_CPPR, 1, xive_tm_set_hv_cppr, NULL },
-    { XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_WORD2, 1, xive_tm_vt_push, NULL },
-    { XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_WORD2, 1, NULL, xive_tm_vt_poll },
+    { XIVE_TM_OS_PAGE, TM_QW1_OS + TM_CPPR,       1, xive_tm_set_os_cppr,
+                                                     NULL },
+    { XIVE_TM_HV_PAGE, TM_QW1_OS + TM_WORD2,      4, xive_tm_push_os_ctx,
+                                                     NULL },
+    { XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_CPPR,  1, xive_tm_set_hv_cppr,
+                                                     NULL },
+    { XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_WORD2, 1, xive_tm_vt_push,
+                                                     NULL },
+    { XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_WORD2, 1, NULL,
+                                                     xive_tm_vt_poll },
 
     /* MMIOs above 2K : special operations with side effects */
-    { XIVE_TM_OS_PAGE, TM_SPC_ACK_OS_REG,     2, NULL, xive_tm_ack_os_reg },
-    { XIVE_TM_OS_PAGE, TM_SPC_SET_OS_PENDING, 1, xive_tm_set_os_pending, NULL },
-    { XIVE_TM_HV_PAGE, TM_SPC_PULL_OS_CTX,    4, NULL, xive_tm_pull_os_ctx },
-    { XIVE_TM_HV_PAGE, TM_SPC_PULL_OS_CTX,    8, NULL, xive_tm_pull_os_ctx },
-    { XIVE_TM_HV_PAGE, TM_SPC_ACK_HV_REG,     2, NULL, xive_tm_ack_hv_reg },
-    { XIVE_TM_HV_PAGE, TM_SPC_PULL_POOL_CTX,  4, NULL, xive_tm_pull_pool_ctx },
-    { XIVE_TM_HV_PAGE, TM_SPC_PULL_POOL_CTX,  8, NULL, xive_tm_pull_pool_ctx },
+    { XIVE_TM_OS_PAGE, TM_SPC_ACK_OS_REG,         2, NULL,
+                                                     xive_tm_ack_os_reg },
+    { XIVE_TM_OS_PAGE, TM_SPC_SET_OS_PENDING,     1, xive_tm_set_os_pending,
+                                                     NULL },
+    { XIVE_TM_HV_PAGE, TM_SPC_PULL_OS_CTX,        4, NULL,
+                                                     xive_tm_pull_os_ctx },
+    { XIVE_TM_HV_PAGE, TM_SPC_PULL_OS_CTX,        8, NULL,
+                                                     xive_tm_pull_os_ctx },
+    { XIVE_TM_HV_PAGE, TM_SPC_ACK_HV_REG,         2, NULL,
+                                                     xive_tm_ack_hv_reg },
+    { XIVE_TM_HV_PAGE, TM_SPC_PULL_POOL_CTX,      4, NULL,
+                                                     xive_tm_pull_pool_ctx },
+    { XIVE_TM_HV_PAGE, TM_SPC_PULL_POOL_CTX,      8, NULL,
+                                                     xive_tm_pull_pool_ctx },
 };
 
 static const XiveTmOp xive2_tm_operations[] = {
@@ -509,20 +521,32 @@ static const XiveTmOp xive2_tm_operations[] = {
      * MMIOs below 2K : raw values and special operations without side
      * effects
      */
-    { XIVE_TM_OS_PAGE, TM_QW1_OS + TM_CPPR,   1, xive_tm_set_os_cppr, NULL },
-    { XIVE_TM_HV_PAGE, TM_QW1_OS + TM_WORD2,  4, xive2_tm_push_os_ctx, NULL },
-    { XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_CPPR, 1, xive_tm_set_hv_cppr, NULL },
-    { XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_WORD2, 1, xive_tm_vt_push, NULL },
-    { XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_WORD2, 1, NULL, xive_tm_vt_poll },
+    { XIVE_TM_OS_PAGE, TM_QW1_OS + TM_CPPR,       1, xive_tm_set_os_cppr,
+                                                     NULL },
+    { XIVE_TM_HV_PAGE, TM_QW1_OS + TM_WORD2,      4, xive2_tm_push_os_ctx,
+                                                     NULL },
+    { XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_CPPR,  1, xive_tm_set_hv_cppr,
+                                                     NULL },
+    { XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_WORD2, 1, xive_tm_vt_push,
+                                                     NULL },
+    { XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_WORD2, 1, NULL,
+                                                     xive_tm_vt_poll },
 
     /* MMIOs above 2K : special operations with side effects */
-    { XIVE_TM_OS_PAGE, TM_SPC_ACK_OS_REG,     2, NULL, xive_tm_ack_os_reg },
-    { XIVE_TM_OS_PAGE, TM_SPC_SET_OS_PENDING, 1, xive_tm_set_os_pending, NULL },
-    { XIVE_TM_HV_PAGE, TM_SPC_PULL_OS_CTX,    4, NULL, xive2_tm_pull_os_ctx },
-    { XIVE_TM_HV_PAGE, TM_SPC_PULL_OS_CTX,    8, NULL, xive2_tm_pull_os_ctx },
-    { XIVE_TM_HV_PAGE, TM_SPC_ACK_HV_REG,     2, NULL, xive_tm_ack_hv_reg },
-    { XIVE_TM_HV_PAGE, TM_SPC_PULL_POOL_CTX,  4, NULL, xive_tm_pull_pool_ctx },
-    { XIVE_TM_HV_PAGE, TM_SPC_PULL_POOL_CTX,  8, NULL, xive_tm_pull_pool_ctx },
+    { XIVE_TM_OS_PAGE, TM_SPC_ACK_OS_REG,         2, NULL,
+                                                     xive_tm_ack_os_reg },
+    { XIVE_TM_OS_PAGE, TM_SPC_SET_OS_PENDING,     1, xive_tm_set_os_pending,
+                                                     NULL },
+    { XIVE_TM_HV_PAGE, TM_SPC_PULL_OS_CTX,        4, NULL,
+                                                     xive2_tm_pull_os_ctx },
+    { XIVE_TM_HV_PAGE, TM_SPC_PULL_OS_CTX,        8, NULL,
+                                                     xive2_tm_pull_os_ctx },
+    { XIVE_TM_HV_PAGE, TM_SPC_ACK_HV_REG,         2, NULL,
+                                                     xive_tm_ack_hv_reg },
+    { XIVE_TM_HV_PAGE, TM_SPC_PULL_POOL_CTX,      4, NULL,
+                                                     xive_tm_pull_pool_ctx },
+    { XIVE_TM_HV_PAGE, TM_SPC_PULL_POOL_CTX,      8, NULL,
+                                                     xive_tm_pull_pool_ctx },
 };
 
 static const XiveTmOp *xive_tm_find_op(XivePresenter *xptr, hwaddr offset,
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 02/14] pnv/xive2: Define OGEN field in the TIMA
  2024-09-09 21:10 [PATCH v2 00/14] XIVE2 changes for TIMA operations Michael Kowal
  2024-09-09 21:10 ` [PATCH v2 01/14] pnv/xive: TIMA patch sets pre-req alignment and formatting changes Michael Kowal
@ 2024-09-09 21:10 ` Michael Kowal
  2024-09-09 21:10 ` [PATCH v2 03/14] ppc/xive2: Support TIMA "Pull OS Context to Odd Thread Reporting Line" Michael Kowal
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 23+ messages in thread
From: Michael Kowal @ 2024-09-09 21:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, clg, fbarrat, npiggin, milesg

From: Frederic Barrat <fbarrat@linux.ibm.com>

The OGEN field at offset 0x1F is a new field for Gen2 TIMA. This
patch defines it.

Signed-off-by: Frederic Barrat <fbarrat@linux.ibm.com>
Signed-off-by: Michael Kowal <kowal@linux.vnet.ibm.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
---
 include/hw/ppc/xive_regs.h | 1 +
 hw/intc/xive.c             | 4 ++++
 2 files changed, 5 insertions(+)

diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h
index 9d52d464d9..9062c6abf6 100644
--- a/include/hw/ppc/xive_regs.h
+++ b/include/hw/ppc/xive_regs.h
@@ -79,6 +79,7 @@
 #define TM_INC                  0x5  /*  -   +   -   +  */
 #define TM_AGE                  0x6  /*  -   +   -   +  */
 #define TM_PIPR                 0x7  /*  -   +   -   +  */
+#define TM_OGEN                 0xF  /*  -   +   -   -  */ /* P10 only */
 
 #define TM_WORD0                0x0
 #define TM_WORD1                0x4
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 2fb38e2102..136d82338a 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -742,6 +742,10 @@ void xive_tctx_reset(XiveTCTX *tctx)
     tctx->regs[TM_QW1_OS + TM_LSMFB] = 0xFF;
     tctx->regs[TM_QW1_OS + TM_ACK_CNT] = 0xFF;
     tctx->regs[TM_QW1_OS + TM_AGE] = 0xFF;
+    if (!(xive_presenter_get_config(tctx->xptr) &
+          XIVE_PRESENTER_GEN1_TIMA_OS)) {
+        tctx->regs[TM_QW1_OS + TM_OGEN] = 2;
+    }
 
     /*
      * Initialize PIPR to 0xFF to avoid phantom interrupts when the
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 03/14] ppc/xive2: Support TIMA "Pull OS Context to Odd Thread Reporting Line"
  2024-09-09 21:10 [PATCH v2 00/14] XIVE2 changes for TIMA operations Michael Kowal
  2024-09-09 21:10 ` [PATCH v2 01/14] pnv/xive: TIMA patch sets pre-req alignment and formatting changes Michael Kowal
  2024-09-09 21:10 ` [PATCH v2 02/14] pnv/xive2: Define OGEN field in the TIMA Michael Kowal
@ 2024-09-09 21:10 ` Michael Kowal
  2024-09-10 17:21   ` Cédric Le Goater
  2024-09-09 21:10 ` [PATCH v2 04/14] pnv/xive2: Support for "OS LGS Push" TIMA operation Michael Kowal
                   ` (10 subsequent siblings)
  13 siblings, 1 reply; 23+ messages in thread
From: Michael Kowal @ 2024-09-09 21:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, clg, fbarrat, npiggin, milesg

From: Frederic Barrat <fbarrat@linux.ibm.com>

Adds support for single byte writes to offset 0xC18 of the TIMA address
space.  When this offset is written to, the hardware disables the OS
context and copies the current state information to the odd cache line
of the pair specified by the NVT structure indexed by the OS CAM entry.

Signed-off-by: Frederic Barrat <fbarrat@linux.ibm.com>
Signed-off-by: Michael Kowal <kowal@linux.vnet.ibm.com>
---
 include/hw/ppc/xive2.h      |   2 +
 include/hw/ppc/xive2_regs.h |   2 +
 include/hw/ppc/xive_regs.h  |   3 +
 hw/intc/xive.c              |   2 +
 hw/intc/xive2.c             | 160 ++++++++++++++++++++++++++++++------
 5 files changed, 142 insertions(+), 27 deletions(-)

diff --git a/include/hw/ppc/xive2.h b/include/hw/ppc/xive2.h
index ab68f8d157..654f485e9b 100644
--- a/include/hw/ppc/xive2.h
+++ b/include/hw/ppc/xive2.h
@@ -107,5 +107,7 @@ 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,
                                hwaddr offset, unsigned size);
+void xive2_tm_pull_os_ctx_ol(XivePresenter *xptr, XiveTCTX *tctx,
+                             hwaddr offset, uint64_t value, unsigned size);
 
 #endif /* PPC_XIVE2_H */
diff --git a/include/hw/ppc/xive2_regs.h b/include/hw/ppc/xive2_regs.h
index 4349d009d0..7acf7dccf3 100644
--- a/include/hw/ppc/xive2_regs.h
+++ b/include/hw/ppc/xive2_regs.h
@@ -171,7 +171,9 @@ typedef struct Xive2Nvp {
 #define NVP2_W5_VP_END_BLOCK       PPC_BITMASK32(4, 7)
 #define NVP2_W5_VP_END_INDEX       PPC_BITMASK32(8, 31)
         uint32_t       w6;
+#define NVP2_W6_REPORTING_LINE     PPC_BITMASK32(4, 31)
         uint32_t       w7;
+#define NVP2_W7_REPORTING_LINE     PPC_BITMASK32(0, 23)
 } Xive2Nvp;
 
 #define xive2_nvp_is_valid(nvp)    (be32_to_cpu((nvp)->w0) & NVP2_W0_VALID)
diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h
index 9062c6abf6..27a744d50d 100644
--- a/include/hw/ppc/xive_regs.h
+++ b/include/hw/ppc/xive_regs.h
@@ -77,6 +77,7 @@
 #define TM_LSMFB                0x3  /*  -   +   +   +  */
 #define TM_ACK_CNT              0x4  /*  -   +   -   -  */
 #define TM_INC                  0x5  /*  -   +   -   +  */
+#define TM_LGS                  0x5  /*  +   +   +   +  */ /* Rename P10 */
 #define TM_AGE                  0x6  /*  -   +   -   +  */
 #define TM_PIPR                 0x7  /*  -   +   -   +  */
 #define TM_OGEN                 0xF  /*  -   +   -   -  */ /* P10 only */
@@ -129,6 +130,8 @@
 #define TM_SPC_PULL_USR_CTX_OL  0xc08   /* Store8 Pull/Inval usr ctx to odd   */
                                         /* line                               */
 #define TM_SPC_ACK_OS_EL        0xc10   /* Store8 ack OS irq to even line     */
+#define TM_SPC_PULL_OS_CTX_OL   0xc18   /* Pull/Invalidate OS context to      */
+                                        /* odd Thread reporting line          */
 #define TM_SPC_ACK_HV_POOL_EL   0xc20   /* Store8 ack HV evt pool to even     */
                                         /* line                               */
 #define TM_SPC_ACK_HV_EL        0xc30   /* Store8 ack HV irq to even line     */
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 136d82338a..8e62c7e75f 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -547,6 +547,8 @@ static const XiveTmOp xive2_tm_operations[] = {
                                                      xive_tm_pull_pool_ctx },
     { XIVE_TM_HV_PAGE, TM_SPC_PULL_POOL_CTX,      8, NULL,
                                                      xive_tm_pull_pool_ctx },
+    { XIVE_TM_HV_PAGE, TM_SPC_PULL_OS_CTX_OL,     1, xive2_tm_pull_os_ctx_ol,
+                                                     NULL },
 };
 
 static const XiveTmOp *xive_tm_find_op(XivePresenter *xptr, hwaddr offset,
diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c
index 1f150685bf..fbd05aa9f5 100644
--- a/hw/intc/xive2.c
+++ b/hw/intc/xive2.c
@@ -26,6 +26,23 @@ uint32_t xive2_router_get_config(Xive2Router *xrtr)
     return xrc->get_config(xrtr);
 }
 
+static int xive2_router_get_block_id(Xive2Router *xrtr)
+{
+   Xive2RouterClass *xrc = XIVE2_ROUTER_GET_CLASS(xrtr);
+
+   return xrc->get_block_id(xrtr);
+}
+
+static uint64_t xive2_nvp_reporting_addr(Xive2Nvp *nvp)
+{
+    uint64_t cache_addr;
+
+    cache_addr = xive_get_field32(NVP2_W6_REPORTING_LINE, nvp->w6) << 24 |
+        xive_get_field32(NVP2_W7_REPORTING_LINE, nvp->w7);
+    cache_addr <<= 8; /* aligned on a cache line pair */
+    return cache_addr;
+}
+
 void xive2_eas_pic_print_info(Xive2Eas *eas, uint32_t lisn, GString *buf)
 {
     if (!xive2_eas_is_valid(eas)) {
@@ -270,6 +287,27 @@ static void xive2_os_cam_decode(uint32_t cam, uint8_t *nvp_blk,
     *ho = !!(cam & TM2_QW1W2_HO);
 }
 
+
+/*
+ * Encode the HW CAM line with 7bit or 8bit thread id. The thread id
+ * width and block id width is configurable at the IC level.
+ *
+ *    chipid << 24 | 0000 0000 0000 0000 1 threadid (7Bit)
+ *    chipid << 24 | 0000 0000 0000 0001 threadid   (8Bit)
+ */
+static uint32_t xive2_tctx_hw_cam_line(XivePresenter *xptr, XiveTCTX *tctx)
+{
+    Xive2Router *xrtr = XIVE2_ROUTER(xptr);
+    CPUPPCState *env = &POWERPC_CPU(tctx->cs)->env;
+    uint32_t pir = env->spr_cb[SPR_PIR].default_value;
+    uint8_t blk = xive2_router_get_block_id(xrtr);
+    uint8_t tid_shift =
+        xive2_router_get_config(xrtr) & XIVE2_THREADID_8BITS ? 8 : 7;
+    uint8_t tid_mask = (1 << tid_shift) - 1;
+
+    return xive2_nvp_cam_line(blk, 1 << tid_shift | (pir & tid_mask));
+}
+
 uint64_t xive2_tm_pull_os_ctx(XivePresenter *xptr, XiveTCTX *tctx,
                               hwaddr offset, unsigned size)
 {
@@ -301,6 +339,101 @@ uint64_t xive2_tm_pull_os_ctx(XivePresenter *xptr, XiveTCTX *tctx,
     return qw1w2;
 }
 
+#define REPORT_LINE_GEN1_SIZE       16
+
+static void xive2_tm_report_line_gen1(XiveTCTX *tctx, uint8_t *data,
+                                      uint8_t size)
+{
+    uint8_t *regs = tctx->regs;
+
+    g_assert(size == REPORT_LINE_GEN1_SIZE);
+    memset(data, 0, size);
+    /*
+     * See xive architecture for description of what is saved. It is
+     * hand-picked information to fit in 16 bytes.
+     */
+    data[0x0] = regs[TM_QW3_HV_PHYS + TM_NSR];
+    data[0x1] = regs[TM_QW3_HV_PHYS + TM_CPPR];
+    data[0x2] = regs[TM_QW3_HV_PHYS + TM_IPB];
+    data[0x3] = regs[TM_QW2_HV_POOL + TM_IPB];
+    data[0x4] = regs[TM_QW1_OS + TM_ACK_CNT];
+    data[0x5] = regs[TM_QW3_HV_PHYS + TM_LGS];
+    data[0x6] = 0xFF;
+    data[0x7] = regs[TM_QW3_HV_PHYS + TM_WORD2] & 0x80;
+    data[0x7] |= (regs[TM_QW2_HV_POOL + TM_WORD2] & 0x80) >> 1;
+    data[0x7] |= (regs[TM_QW1_OS + TM_WORD2] & 0x80) >> 2;
+    data[0x7] |= (regs[TM_QW3_HV_PHYS + TM_WORD2] & 0x3);
+    data[0x8] = regs[TM_QW1_OS + TM_NSR];
+    data[0x9] = regs[TM_QW1_OS + TM_CPPR];
+    data[0xA] = regs[TM_QW1_OS + TM_IPB];
+    data[0xB] = regs[TM_QW1_OS + TM_LGS];
+    if (regs[TM_QW0_USER + TM_WORD2] & 0x80) {
+        /*
+         * Logical server extension, except VU bit replaced by EB bit
+         * from NSR
+         */
+        data[0xC] = regs[TM_QW0_USER + TM_WORD2];
+        data[0xC] &= ~0x80;
+        data[0xC] |= regs[TM_QW0_USER + TM_NSR] & 0x80;
+        data[0xD] = regs[TM_QW0_USER + TM_WORD2 + 1];
+        data[0xE] = regs[TM_QW0_USER + TM_WORD2 + 2];
+        data[0xF] = regs[TM_QW0_USER + TM_WORD2 + 3];
+    }
+}
+
+void xive2_tm_pull_os_ctx_ol(XivePresenter *xptr, XiveTCTX *tctx,
+                             hwaddr offset, uint64_t value, unsigned size)
+{
+    Xive2Router *xrtr = XIVE2_ROUTER(xptr);
+    uint32_t hw_cam, nvp_idx, xive2_cfg, reserved;
+    uint8_t nvp_blk;
+    Xive2Nvp nvp;
+    uint64_t phys_addr;
+    MemTxResult result;
+
+    hw_cam = xive2_tctx_hw_cam_line(xptr, tctx);
+    nvp_blk = xive2_nvp_blk(hw_cam);
+    nvp_idx = xive2_nvp_idx(hw_cam);
+
+    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: invalid NVP %x/%x\n",
+                      nvp_blk, nvp_idx);
+        return;
+    }
+
+    xive2_cfg = xive2_router_get_config(xrtr);
+
+    phys_addr = xive2_nvp_reporting_addr(&nvp) + 0x80; /* odd line */
+    if (xive2_cfg & XIVE2_GEN1_TIMA_OS) {
+        uint8_t pull_ctxt[REPORT_LINE_GEN1_SIZE];
+
+        xive2_tm_report_line_gen1(tctx, pull_ctxt, REPORT_LINE_GEN1_SIZE);
+        result = dma_memory_write(&address_space_memory, phys_addr,
+                                  pull_ctxt, REPORT_LINE_GEN1_SIZE,
+                                  MEMTXATTRS_UNSPECIFIED);
+        assert(result == MEMTX_OK);
+    } else {
+        result = dma_memory_write(&address_space_memory, phys_addr,
+                                  &tctx->regs, sizeof(tctx->regs),
+                                  MEMTXATTRS_UNSPECIFIED);
+        assert(result == MEMTX_OK);
+        reserved = 0xFFFFFFFF;
+        result = dma_memory_write(&address_space_memory, phys_addr + 12,
+                                  &reserved, sizeof(reserved),
+                                  MEMTXATTRS_UNSPECIFIED);
+        assert(result == MEMTX_OK);
+    }
+
+    /* the rest is similar to pull OS context to registers */
+    xive2_tm_pull_os_ctx(xptr, tctx, offset, size);
+}
+
 static uint8_t xive2_tctx_restore_os_ctx(Xive2Router *xrtr, XiveTCTX *tctx,
                                         uint8_t nvp_blk, uint32_t nvp_idx,
                                         Xive2Nvp *nvp)
@@ -471,33 +604,6 @@ int xive2_router_write_nvp(Xive2Router *xrtr, uint8_t nvp_blk, uint32_t nvp_idx,
    return xrc->write_nvp(xrtr, nvp_blk, nvp_idx, nvp, word_number);
 }
 
-static int xive2_router_get_block_id(Xive2Router *xrtr)
-{
-   Xive2RouterClass *xrc = XIVE2_ROUTER_GET_CLASS(xrtr);
-
-   return xrc->get_block_id(xrtr);
-}
-
-/*
- * Encode the HW CAM line with 7bit or 8bit thread id. The thread id
- * width and block id width is configurable at the IC level.
- *
- *    chipid << 24 | 0000 0000 0000 0000 1 threadid (7Bit)
- *    chipid << 24 | 0000 0000 0000 0001 threadid   (8Bit)
- */
-static uint32_t xive2_tctx_hw_cam_line(XivePresenter *xptr, XiveTCTX *tctx)
-{
-    Xive2Router *xrtr = XIVE2_ROUTER(xptr);
-    CPUPPCState *env = &POWERPC_CPU(tctx->cs)->env;
-    uint32_t pir = env->spr_cb[SPR_PIR].default_value;
-    uint8_t blk = xive2_router_get_block_id(xrtr);
-    uint8_t tid_shift =
-        xive2_router_get_config(xrtr) & XIVE2_THREADID_8BITS ? 8 : 7;
-    uint8_t tid_mask = (1 << tid_shift) - 1;
-
-    return xive2_nvp_cam_line(blk, 1 << tid_shift | (pir & tid_mask));
-}
-
 /*
  * The thread context register words are in big-endian format.
  */
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 04/14] pnv/xive2: Support for "OS LGS Push" TIMA operation
  2024-09-09 21:10 [PATCH v2 00/14] XIVE2 changes for TIMA operations Michael Kowal
                   ` (2 preceding siblings ...)
  2024-09-09 21:10 ` [PATCH v2 03/14] ppc/xive2: Support TIMA "Pull OS Context to Odd Thread Reporting Line" Michael Kowal
@ 2024-09-09 21:10 ` Michael Kowal
  2024-09-09 21:10 ` [PATCH v2 05/14] ppc/xive2: Dump more NVP state with 'info pic' Michael Kowal
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 23+ messages in thread
From: Michael Kowal @ 2024-09-09 21:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, clg, fbarrat, npiggin, milesg

From: Glenn Miles <milesg@linux.vnet.ibm.com>

Adds support for single byte writes to offset 0x15 of the TIMA address
space.  This offset holds the Logical Server Group Size (LGS) field.
The field is used to evenly distribute the interrupt load among the
members of a group, but is unused in the current implementation so we
just support the writing of the value for now.

Signed-off-by: Glenn Miles <milesg@linux.vnet.ibm.com>
Signed-off-by: Michael Kowal <kowal@linux.ibm.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
---
 hw/intc/xive.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 8e62c7e75f..8605dd618f 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -341,6 +341,19 @@ static void xive_tm_set_os_cppr(XivePresenter *xptr, XiveTCTX *tctx,
     xive_tctx_set_cppr(tctx, TM_QW1_OS, value & 0xff);
 }
 
+static void xive_tctx_set_lgs(XiveTCTX *tctx, uint8_t ring, uint8_t lgs)
+{
+    uint8_t *regs = &tctx->regs[ring];
+
+    regs[TM_LGS] = lgs;
+}
+
+static void xive_tm_set_os_lgs(XivePresenter *xptr, XiveTCTX *tctx,
+                          hwaddr offset, uint64_t value, unsigned size)
+{
+    xive_tctx_set_lgs(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.
@@ -525,6 +538,8 @@ static const XiveTmOp xive2_tm_operations[] = {
                                                      NULL },
     { XIVE_TM_HV_PAGE, TM_QW1_OS + TM_WORD2,      4, xive2_tm_push_os_ctx,
                                                      NULL },
+    { XIVE_TM_OS_PAGE, TM_QW1_OS + TM_LGS,        1, xive_tm_set_os_lgs,
+                                                     NULL },
     { XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_CPPR,  1, xive_tm_set_hv_cppr,
                                                      NULL },
     { XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_WORD2, 1, xive_tm_vt_push,
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 05/14] ppc/xive2: Dump more NVP state with 'info pic'
  2024-09-09 21:10 [PATCH v2 00/14] XIVE2 changes for TIMA operations Michael Kowal
                   ` (3 preceding siblings ...)
  2024-09-09 21:10 ` [PATCH v2 04/14] pnv/xive2: Support for "OS LGS Push" TIMA operation Michael Kowal
@ 2024-09-09 21:10 ` Michael Kowal
  2024-09-10 17:23   ` Cédric Le Goater
  2024-09-09 21:10 ` [PATCH v2 06/14] ppc/xive2: Dump the VP-group and crowd tables " Michael Kowal
                   ` (8 subsequent siblings)
  13 siblings, 1 reply; 23+ messages in thread
From: Michael Kowal @ 2024-09-09 21:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, clg, fbarrat, npiggin, milesg

From: Frederic Barrat <fbarrat@linux.ibm.com>

The 'PGoFirst' field of a Notify Virtual Processor tells if the NVP
belongs to a VP group.

Also, print the Reporting Cache Line address, if defined.

Signed-off-by: Frederic Barrat <fbarrat@linux.ibm.com>
Signed-off-by: Michael Kowal <kowal@linux.ibm.com>
---
 include/hw/ppc/xive2_regs.h |  1 +
 hw/intc/xive2.c             | 10 ++++++++--
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/include/hw/ppc/xive2_regs.h b/include/hw/ppc/xive2_regs.h
index 7acf7dccf3..d71a54f9ff 100644
--- a/include/hw/ppc/xive2_regs.h
+++ b/include/hw/ppc/xive2_regs.h
@@ -151,6 +151,7 @@ typedef struct Xive2Nvp {
 #define NVP2_W0_VALID              PPC_BIT32(0)
 #define NVP2_W0_HW                 PPC_BIT32(7)
 #define NVP2_W0_ESC_END            PPC_BIT32(25) /* 'N' bit 0:ESB  1:END */
+#define NVP2_W0_PGOFIRST           PPC_BITMASK32(26, 31)
         uint32_t       w1;
 #define NVP2_W1_CO                 PPC_BIT32(13)
 #define NVP2_W1_CO_PRIV            PPC_BITMASK32(14, 15)
diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c
index fbd05aa9f5..ac581fa195 100644
--- a/hw/intc/xive2.c
+++ b/hw/intc/xive2.c
@@ -161,14 +161,20 @@ void xive2_nvp_pic_print_info(Xive2Nvp *nvp, uint32_t nvp_idx, GString *buf)
 {
     uint8_t  eq_blk = xive_get_field32(NVP2_W5_VP_END_BLOCK, nvp->w5);
     uint32_t eq_idx = xive_get_field32(NVP2_W5_VP_END_INDEX, nvp->w5);
+    uint64_t cache_line = xive2_nvp_reporting_addr(nvp);
 
     if (!xive2_nvp_is_valid(nvp)) {
         return;
     }
 
-    g_string_append_printf(buf, "  %08x end:%02x/%04x IPB:%02x",
+    g_string_append_printf(buf, "  %08x end:%02x/%04x IPB:%02x PGoFirst:%02x",
                            nvp_idx, eq_blk, eq_idx,
-                           xive_get_field32(NVP2_W2_IPB, nvp->w2));
+                           xive_get_field32(NVP2_W2_IPB, nvp->w2),
+                           xive_get_field32(NVP2_W0_PGOFIRST, nvp->w0));
+    if (cache_line) {
+        g_string_append_printf(buf, "  reporting CL:%016"PRIx64, cache_line);
+    }
+
     /*
      * When the NVP is HW controlled, more fields are updated
      */
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 06/14] ppc/xive2: Dump the VP-group and crowd tables with 'info pic'
  2024-09-09 21:10 [PATCH v2 00/14] XIVE2 changes for TIMA operations Michael Kowal
                   ` (4 preceding siblings ...)
  2024-09-09 21:10 ` [PATCH v2 05/14] ppc/xive2: Dump more NVP state with 'info pic' Michael Kowal
@ 2024-09-09 21:10 ` Michael Kowal
  2024-09-10 17:25   ` Cédric Le Goater
  2024-09-09 21:10 ` [PATCH v2 07/14] ppc/xive2: Allow 1-byte write of Target field in TIMA Michael Kowal
                   ` (7 subsequent siblings)
  13 siblings, 1 reply; 23+ messages in thread
From: Michael Kowal @ 2024-09-09 21:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, clg, fbarrat, npiggin, milesg

From: Frederic Barrat <fbarrat@linux.ibm.com>

The 'info pic' HMP command dumps the state of the interrupt controller.
Add the dump of the NVG and NVC tables to its output to ease debug.

Signed-off-by: Frederic Barrat <fbarrat@linux.ibm.com>
Signed-off-by: Michael Kowal <kowal@linux.ibm.com>
---
 include/hw/ppc/xive2.h      | 12 ++++++++
 include/hw/ppc/xive2_regs.h |  6 ++++
 hw/intc/pnv_xive2.c         | 44 +++++++++++++++++++++++++++--
 hw/intc/xive2.c             | 55 +++++++++++++++++++++++++++++++++++++
 4 files changed, 114 insertions(+), 3 deletions(-)

diff --git a/include/hw/ppc/xive2.h b/include/hw/ppc/xive2.h
index 654f485e9b..b7a7c33ddd 100644
--- a/include/hw/ppc/xive2.h
+++ b/include/hw/ppc/xive2.h
@@ -53,6 +53,12 @@ typedef struct Xive2RouterClass {
                    Xive2Nvp *nvp);
     int (*write_nvp)(Xive2Router *xrtr, uint8_t nvp_blk, uint32_t nvp_idx,
                      Xive2Nvp *nvp, uint8_t word_number);
+    int (*get_nvgc)(Xive2Router *xrtr, bool crowd,
+                    uint8_t nvgc_blk, uint32_t nvgc_idx,
+                    Xive2Nvgc *nvgc);
+    int (*write_nvgc)(Xive2Router *xrtr, bool crowd,
+                      uint8_t nvgc_blk, uint32_t nvgc_idx,
+                      Xive2Nvgc *nvgc);
     uint8_t (*get_block_id)(Xive2Router *xrtr);
     uint32_t (*get_config)(Xive2Router *xrtr);
 } Xive2RouterClass;
@@ -67,6 +73,12 @@ int xive2_router_get_nvp(Xive2Router *xrtr, uint8_t nvp_blk, uint32_t nvp_idx,
                         Xive2Nvp *nvp);
 int xive2_router_write_nvp(Xive2Router *xrtr, uint8_t nvp_blk, uint32_t nvp_idx,
                           Xive2Nvp *nvp, uint8_t word_number);
+int xive2_router_get_nvgc(Xive2Router *xrtr, bool crowd,
+                          uint8_t nvgc_blk, uint32_t nvgc_idx,
+                          Xive2Nvgc *nvgc);
+int xive2_router_write_nvgc(Xive2Router *xrtr, bool crowd,
+                            uint8_t nvgc_blk, uint32_t nvgc_idx,
+                            Xive2Nvgc *nvgc);
 uint32_t xive2_router_get_config(Xive2Router *xrtr);
 
 void xive2_router_notify(XiveNotifier *xn, uint32_t lisn, bool pq_checked);
diff --git a/include/hw/ppc/xive2_regs.h b/include/hw/ppc/xive2_regs.h
index d71a54f9ff..99840e88a8 100644
--- a/include/hw/ppc/xive2_regs.h
+++ b/include/hw/ppc/xive2_regs.h
@@ -212,6 +212,7 @@ void xive2_nvp_pic_print_info(Xive2Nvp *nvp, uint32_t nvp_idx, GString *buf);
 typedef struct Xive2Nvgc {
         uint32_t        w0;
 #define NVGC2_W0_VALID             PPC_BIT32(0)
+#define NVGC2_W0_PGONEXT           PPC_BITMASK32(26, 31)
         uint32_t        w1;
         uint32_t        w2;
         uint32_t        w3;
@@ -221,4 +222,9 @@ typedef struct Xive2Nvgc {
         uint32_t        w7;
 } Xive2Nvgc;
 
+#define xive2_nvgc_is_valid(nvgc)    (be32_to_cpu((nvgc)->w0) & NVGC2_W0_VALID)
+
+void xive2_nvgc_pic_print_info(Xive2Nvgc *nvgc, uint32_t nvgc_idx,
+                               GString *buf);
+
 #endif /* PPC_XIVE2_REGS_H */
diff --git a/hw/intc/pnv_xive2.c b/hw/intc/pnv_xive2.c
index 78609105a8..834d32287b 100644
--- a/hw/intc/pnv_xive2.c
+++ b/hw/intc/pnv_xive2.c
@@ -490,6 +490,23 @@ static int pnv_xive2_write_nvp(Xive2Router *xrtr, uint8_t blk, uint32_t idx,
                               word_number);
 }
 
+static int pnv_xive2_get_nvgc(Xive2Router *xrtr, bool crowd,
+                              uint8_t blk, uint32_t idx,
+                              Xive2Nvgc *nvgc)
+{
+    return pnv_xive2_vst_read(PNV_XIVE2(xrtr), crowd ? VST_NVC : VST_NVG,
+                              blk, idx, nvgc);
+}
+
+static int pnv_xive2_write_nvgc(Xive2Router *xrtr, bool crowd,
+                                uint8_t blk, uint32_t idx,
+                                Xive2Nvgc *nvgc)
+{
+    return pnv_xive2_vst_write(PNV_XIVE2(xrtr), crowd ? VST_NVC : VST_NVG,
+                               blk, idx, nvgc,
+                               XIVE_VST_WORD_ALL);
+}
+
 static int pnv_xive2_nxc_to_table_type(uint8_t nxc_type, uint32_t *table_type)
 {
     switch (nxc_type) {
@@ -2407,6 +2424,8 @@ static void pnv_xive2_class_init(ObjectClass *klass, void *data)
     xrc->write_end = pnv_xive2_write_end;
     xrc->get_nvp   = pnv_xive2_get_nvp;
     xrc->write_nvp = pnv_xive2_write_nvp;
+    xrc->get_nvgc   = pnv_xive2_get_nvgc;
+    xrc->write_nvgc = pnv_xive2_write_nvgc;
     xrc->get_config  = pnv_xive2_get_config;
     xrc->get_block_id = pnv_xive2_get_block_id;
 
@@ -2497,8 +2516,9 @@ void pnv_xive2_pic_print_info(PnvXive2 *xive, GString *buf)
     Xive2Eas eas;
     Xive2End end;
     Xive2Nvp nvp;
+    Xive2Nvgc nvgc;
     int i;
-    uint64_t xive_nvp_per_subpage;
+    uint64_t entries_per_subpage;
 
     g_string_append_printf(buf, "XIVE[%x] Source %08x .. %08x\n",
                            blk, srcno0, srcno0 + nr_esbs - 1);
@@ -2530,10 +2550,28 @@ void pnv_xive2_pic_print_info(PnvXive2 *xive, GString *buf)
 
     g_string_append_printf(buf, "XIVE[%x] #%d NVPT %08x .. %08x\n",
                            chip_id, blk, 0, XIVE2_NVP_COUNT - 1);
-    xive_nvp_per_subpage = pnv_xive2_vst_per_subpage(xive, VST_NVP);
-    for (i = 0; i < XIVE2_NVP_COUNT; i += xive_nvp_per_subpage) {
+    entries_per_subpage = pnv_xive2_vst_per_subpage(xive, VST_NVP);
+    for (i = 0; i < XIVE2_NVP_COUNT; i += entries_per_subpage) {
         while (!xive2_router_get_nvp(xrtr, blk, i, &nvp)) {
             xive2_nvp_pic_print_info(&nvp, i++, buf);
         }
     }
+
+    g_string_append_printf(buf, "XIVE[%x] #%d NVGT %08x .. %08x\n",
+                           chip_id, blk, 0, XIVE2_NVP_COUNT - 1);
+    entries_per_subpage = pnv_xive2_vst_per_subpage(xive, VST_NVG);
+    for (i = 0; i < XIVE2_NVP_COUNT; i += entries_per_subpage) {
+        while (!xive2_router_get_nvgc(xrtr, false, blk, i, &nvgc)) {
+            xive2_nvgc_pic_print_info(&nvgc, i++, buf);
+        }
+    }
+
+    g_string_append_printf(buf, "XIVE[%x] #%d NVCT %08x .. %08x\n",
+                          chip_id, blk, 0, XIVE2_NVP_COUNT - 1);
+    entries_per_subpage = pnv_xive2_vst_per_subpage(xive, VST_NVC);
+    for (i = 0; i < XIVE2_NVP_COUNT; i += entries_per_subpage) {
+        while (!xive2_router_get_nvgc(xrtr, true, blk, i, &nvgc)) {
+            xive2_nvgc_pic_print_info(&nvgc, i++, buf);
+        }
+    }
 }
diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c
index ac581fa195..26b6e72129 100644
--- a/hw/intc/xive2.c
+++ b/hw/intc/xive2.c
@@ -43,6 +43,26 @@ static uint64_t xive2_nvp_reporting_addr(Xive2Nvp *nvp)
     return cache_addr;
 }
 
+static uint32_t xive2_nvgc_get_backlog(Xive2Nvgc *nvgc, uint8_t priority)
+{
+    uint32_t val = 0;
+    uint8_t *ptr, i;
+
+    if (priority > 7) {
+        return 0;
+    }
+
+    /*
+     * The per-priority backlog counters are 24-bit and the structure
+     * is stored in big endian
+     */
+    ptr = (uint8_t *)&nvgc->w2 + priority * 3;
+    for (i = 0; i < 3; i++, ptr++) {
+        val = (val << 8) + *ptr;
+    }
+    return val;
+}
+
 void xive2_eas_pic_print_info(Xive2Eas *eas, uint32_t lisn, GString *buf)
 {
     if (!xive2_eas_is_valid(eas)) {
@@ -189,6 +209,23 @@ void xive2_nvp_pic_print_info(Xive2Nvp *nvp, uint32_t nvp_idx, GString *buf)
     g_string_append_c(buf, '\n');
 }
 
+void xive2_nvgc_pic_print_info(Xive2Nvgc *nvgc, uint32_t nvgc_idx, GString *buf)
+{
+    uint8_t i;
+
+    if (!xive2_nvgc_is_valid(nvgc)) {
+        return;
+    }
+
+    g_string_append_printf(buf, "  %08x PGoNext:%02x bklog: ", nvgc_idx,
+                           xive_get_field32(NVGC2_W0_PGONEXT, nvgc->w0));
+    for (i = 0; i <= XIVE_PRIORITY_MAX; i++) {
+        g_string_append_printf(buf, "[%d]=0x%x ",
+                               i, xive2_nvgc_get_backlog(nvgc, i));
+    }
+    g_string_append_printf(buf, "\n");
+}
+
 static void xive2_end_enqueue(Xive2End *end, uint32_t data)
 {
     uint64_t qaddr_base = xive2_end_qaddr(end);
@@ -610,6 +647,24 @@ int xive2_router_write_nvp(Xive2Router *xrtr, uint8_t nvp_blk, uint32_t nvp_idx,
    return xrc->write_nvp(xrtr, nvp_blk, nvp_idx, nvp, word_number);
 }
 
+int xive2_router_get_nvgc(Xive2Router *xrtr, bool crowd,
+                          uint8_t nvgc_blk, uint32_t nvgc_idx,
+                          Xive2Nvgc *nvgc)
+{
+   Xive2RouterClass *xrc = XIVE2_ROUTER_GET_CLASS(xrtr);
+
+   return xrc->get_nvgc(xrtr, crowd, nvgc_blk, nvgc_idx, nvgc);
+}
+
+int xive2_router_write_nvgc(Xive2Router *xrtr, bool crowd,
+                            uint8_t nvgc_blk, uint32_t nvgc_idx,
+                            Xive2Nvgc *nvgc)
+{
+   Xive2RouterClass *xrc = XIVE2_ROUTER_GET_CLASS(xrtr);
+
+   return xrc->write_nvgc(xrtr, crowd, nvgc_blk, nvgc_idx, nvgc);
+}
+
 /*
  * The thread context register words are in big-endian format.
  */
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 07/14] ppc/xive2: Allow 1-byte write of Target field in TIMA
  2024-09-09 21:10 [PATCH v2 00/14] XIVE2 changes for TIMA operations Michael Kowal
                   ` (5 preceding siblings ...)
  2024-09-09 21:10 ` [PATCH v2 06/14] ppc/xive2: Dump the VP-group and crowd tables " Michael Kowal
@ 2024-09-09 21:10 ` Michael Kowal
  2024-09-09 21:10 ` [PATCH v2 08/14] ppc/xive2: Support "Pull Thread Context to Register" operation Michael Kowal
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 23+ messages in thread
From: Michael Kowal @ 2024-09-09 21:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, clg, fbarrat, npiggin, milesg

From: Glenn Miles <milesg@linux.vnet.ibm.com>

When running PowerVM, the console is littered with XIVE traces regarding
invalid writes to TIMA address 0x100b6 due to a lack of support for writes
to the "TARGET" field which was added for XIVE GEN2.  To fix this, we add
special op support for 1-byte writes to this field.

Signed-off-by: Glenn Miles <milesg@linux.vnet.ibm.com>
Signed-off-by: Michael Kowal <kowal@linux.ibm.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
---
 include/hw/ppc/xive2.h     |  2 ++
 include/hw/ppc/xive_regs.h |  1 +
 hw/intc/xive.c             |  2 ++
 hw/intc/xive2.c            | 13 +++++++++++++
 4 files changed, 18 insertions(+)

diff --git a/include/hw/ppc/xive2.h b/include/hw/ppc/xive2.h
index b7a7c33ddd..36bd0e747f 100644
--- a/include/hw/ppc/xive2.h
+++ b/include/hw/ppc/xive2.h
@@ -121,5 +121,7 @@ uint64_t xive2_tm_pull_os_ctx(XivePresenter *xptr, XiveTCTX *tctx,
                                hwaddr offset, unsigned size);
 void xive2_tm_pull_os_ctx_ol(XivePresenter *xptr, XiveTCTX *tctx,
                              hwaddr offset, uint64_t value, unsigned size);
+void xive2_tm_set_hv_target(XivePresenter *xptr, XiveTCTX *tctx,
+                            hwaddr offset, uint64_t value, unsigned size);
 
 #endif /* PPC_XIVE2_H */
diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h
index 27a744d50d..f8f05deafd 100644
--- a/include/hw/ppc/xive_regs.h
+++ b/include/hw/ppc/xive_regs.h
@@ -79,6 +79,7 @@
 #define TM_INC                  0x5  /*  -   +   -   +  */
 #define TM_LGS                  0x5  /*  +   +   +   +  */ /* Rename P10 */
 #define TM_AGE                  0x6  /*  -   +   -   +  */
+#define TM_T                    0x6  /*  -   +   -   +  */ /* Rename P10 */
 #define TM_PIPR                 0x7  /*  -   +   -   +  */
 #define TM_OGEN                 0xF  /*  -   +   -   -  */ /* P10 only */
 
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 8605dd618f..6229a6f870 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -546,6 +546,8 @@ static const XiveTmOp xive2_tm_operations[] = {
                                                      NULL },
     { XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_WORD2, 1, NULL,
                                                      xive_tm_vt_poll },
+    { XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_T,     1, xive2_tm_set_hv_target,
+                                                     NULL },
 
     /* MMIOs above 2K : special operations with side effects */
     { XIVE_TM_OS_PAGE, TM_SPC_ACK_OS_REG,         2, NULL,
diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c
index 26b6e72129..8d3d69a0db 100644
--- a/hw/intc/xive2.c
+++ b/hw/intc/xive2.c
@@ -585,6 +585,19 @@ void xive2_tm_push_os_ctx(XivePresenter *xptr, XiveTCTX *tctx,
     }
 }
 
+static void xive2_tctx_set_target(XiveTCTX *tctx, uint8_t ring, uint8_t target)
+{
+    uint8_t *regs = &tctx->regs[ring];
+
+    regs[TM_T] = target;
+}
+
+void xive2_tm_set_hv_target(XivePresenter *xptr, XiveTCTX *tctx,
+                            hwaddr offset, uint64_t value, unsigned size)
+{
+    xive2_tctx_set_target(tctx, TM_QW3_HV_PHYS, value & 0xff);
+}
+
 /*
  * XIVE Router (aka. Virtualization Controller or IVRE)
  */
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 08/14] ppc/xive2: Support "Pull Thread Context to Register" operation
  2024-09-09 21:10 [PATCH v2 00/14] XIVE2 changes for TIMA operations Michael Kowal
                   ` (6 preceding siblings ...)
  2024-09-09 21:10 ` [PATCH v2 07/14] ppc/xive2: Allow 1-byte write of Target field in TIMA Michael Kowal
@ 2024-09-09 21:10 ` Michael Kowal
  2024-09-09 21:10 ` [PATCH v2 09/14] ppc/xive2: Change context/ring specific functions to be generic Michael Kowal
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 23+ messages in thread
From: Michael Kowal @ 2024-09-09 21:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, clg, fbarrat, npiggin, milesg

From: Glenn Miles <milesg@linux.vnet.ibm.com>

Adds support for single byte read of offset 0x838 of the TIMA address
space.  According to the XIVE2 Specification, this causes the hardware
to atomically:
  1. Read the number of bytes requested (lbz or lhz are supported).
  2. Reset the valid bit of the thread context.
  3. Return the number of bytes requested in step 1 to a register.

Signed-off-by: Glenn Miles <milesg@linux.vnet.ibm.com>
Signed-off-by: Michael Kowal <kowal@linux.ibm.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
---
 include/hw/ppc/xive_regs.h |  2 ++
 hw/intc/xive.c             | 15 +++++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h
index f8f05deafd..558a5ae742 100644
--- a/include/hw/ppc/xive_regs.h
+++ b/include/hw/ppc/xive_regs.h
@@ -101,6 +101,7 @@
 #define   TM_QW3W2_LP           PPC_BIT32(6)
 #define   TM_QW3W2_LE           PPC_BIT32(7)
 #define   TM_QW3W2_T            PPC_BIT32(31)
+#define   TM_QW3B8_VT           PPC_BIT8(0)
 
 /*
  * In addition to normal loads to "peek" and writes (only when invalid)
@@ -128,6 +129,7 @@
 #define TM_SPC_PULL_POOL_CTX    0x828   /* Load32/Load64 Pull/Invalidate Pool */
                                         /* context to reg                     */
 #define TM_SPC_ACK_HV_REG       0x830   /* Load16 ack HV irq to reg           */
+#define TM_SPC_PULL_PHYS_CTX    0x838   /* Pull phys ctx to reg               */
 #define TM_SPC_PULL_USR_CTX_OL  0xc08   /* Store8 Pull/Inval usr ctx to odd   */
                                         /* line                               */
 #define TM_SPC_ACK_OS_EL        0xc10   /* Store8 ack OS irq to even line     */
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 6229a6f870..5b66a3aec5 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -179,6 +179,17 @@ static uint64_t xive_tm_pull_pool_ctx(XivePresenter *xptr, XiveTCTX *tctx,
     return qw2w2;
 }
 
+static uint64_t xive_tm_pull_phys_ctx(XivePresenter *xptr, XiveTCTX *tctx,
+                                      hwaddr offset, unsigned size)
+{
+    uint8_t qw3b8_prev = tctx->regs[TM_QW3_HV_PHYS + TM_WORD2];
+    uint8_t qw3b8;
+
+    qw3b8 = qw3b8_prev & ~TM_QW3B8_VT;
+    tctx->regs[TM_QW3_HV_PHYS + TM_WORD2] = qw3b8;
+    return qw3b8;
+}
+
 static void xive_tm_vt_push(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset,
                             uint64_t value, unsigned size)
 {
@@ -527,6 +538,8 @@ static const XiveTmOp xive_tm_operations[] = {
                                                      xive_tm_pull_pool_ctx },
     { XIVE_TM_HV_PAGE, TM_SPC_PULL_POOL_CTX,      8, NULL,
                                                      xive_tm_pull_pool_ctx },
+    { XIVE_TM_HV_PAGE, TM_SPC_PULL_PHYS_CTX,      1, NULL,
+                                                     xive_tm_pull_phys_ctx },
 };
 
 static const XiveTmOp xive2_tm_operations[] = {
@@ -566,6 +579,8 @@ static const XiveTmOp xive2_tm_operations[] = {
                                                      xive_tm_pull_pool_ctx },
     { XIVE_TM_HV_PAGE, TM_SPC_PULL_OS_CTX_OL,     1, xive2_tm_pull_os_ctx_ol,
                                                      NULL },
+    { XIVE_TM_HV_PAGE, TM_SPC_PULL_PHYS_CTX,      1, NULL,
+                                                     xive_tm_pull_phys_ctx },
 };
 
 static const XiveTmOp *xive_tm_find_op(XivePresenter *xptr, hwaddr offset,
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 09/14] ppc/xive2: Change context/ring specific functions to be generic
  2024-09-09 21:10 [PATCH v2 00/14] XIVE2 changes for TIMA operations Michael Kowal
                   ` (7 preceding siblings ...)
  2024-09-09 21:10 ` [PATCH v2 08/14] ppc/xive2: Support "Pull Thread Context to Register" operation Michael Kowal
@ 2024-09-09 21:10 ` Michael Kowal
  2024-09-12  6:27   ` Cédric Le Goater
  2024-09-09 21:10 ` [PATCH v2 10/14] ppc/xive2: Support "Pull Thread Context to Odd Thread Reporting Line" Michael Kowal
                   ` (4 subsequent siblings)
  13 siblings, 1 reply; 23+ messages in thread
From: Michael Kowal @ 2024-09-09 21:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, clg, fbarrat, npiggin, milesg

Some the functions that have been created are specific to a ring or context. Some
of these same functions are being changed to operate on any ring/context. This  will
simplify the next patch sets that are adding additional ring/context operations.

Signed-off-by: Michael Kowal <kowal@linux.ibm.com>
---
 include/hw/ppc/xive.h |  2 +-
 hw/intc/xive.c        |  6 ++--
 hw/intc/xive2.c       | 77 ++++++++++++++++++++++++++++---------------
 3 files changed, 55 insertions(+), 30 deletions(-)

diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
index 28c181faa2..31242f0406 100644
--- a/include/hw/ppc/xive.h
+++ b/include/hw/ppc/xive.h
@@ -533,7 +533,7 @@ Object *xive_tctx_create(Object *cpu, XivePresenter *xptr, Error **errp);
 void xive_tctx_reset(XiveTCTX *tctx);
 void xive_tctx_destroy(XiveTCTX *tctx);
 void xive_tctx_ipb_update(XiveTCTX *tctx, uint8_t ring, uint8_t ipb);
-void xive_tctx_reset_os_signal(XiveTCTX *tctx);
+void xive_tctx_reset_signal(XiveTCTX *tctx, uint8_t ring);
 
 /*
  * KVM XIVE device helpers
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 5b66a3aec5..f1d007d9a6 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -114,7 +114,7 @@ static void xive_tctx_notify(XiveTCTX *tctx, uint8_t ring)
     }
 }
 
-void xive_tctx_reset_os_signal(XiveTCTX *tctx)
+void xive_tctx_reset_signal(XiveTCTX *tctx, uint8_t ring)
 {
     /*
      * Lower the External interrupt. Used when pulling an OS
@@ -122,7 +122,7 @@ void xive_tctx_reset_os_signal(XiveTCTX *tctx)
      * context. It should be raised again when re-pushing the OS
      * context.
      */
-    qemu_irq_lower(xive_tctx_output(tctx, TM_QW1_OS));
+    qemu_irq_lower(xive_tctx_output(tctx, ring));
 }
 
 static void xive_tctx_set_cppr(XiveTCTX *tctx, uint8_t ring, uint8_t cppr)
@@ -424,7 +424,7 @@ static uint64_t xive_tm_pull_os_ctx(XivePresenter *xptr, XiveTCTX *tctx,
     qw1w2_new = xive_set_field32(TM_QW1W2_VO, qw1w2, 0);
     xive_tctx_set_os_cam(tctx, qw1w2_new);
 
-    xive_tctx_reset_os_signal(tctx);
+    xive_tctx_reset_signal(tctx, TM_QW1_OS);
     return qw1w2;
 }
 
diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c
index 8d3d69a0db..38a4b0ff68 100644
--- a/hw/intc/xive2.c
+++ b/hw/intc/xive2.c
@@ -270,13 +270,14 @@ static void xive2_end_enqueue(Xive2End *end, uint32_t data)
  *     the NVP by changing the H bit while the context is enabled
  */
 
-static void xive2_tctx_save_os_ctx(Xive2Router *xrtr, XiveTCTX *tctx,
-                                   uint8_t nvp_blk, uint32_t nvp_idx)
+static void xive2_tctx_save_ctx(Xive2Router *xrtr, XiveTCTX *tctx,
+                                uint8_t nvp_blk, uint32_t nvp_idx,
+                                uint8_t ring)
 {
     CPUPPCState *env = &POWERPC_CPU(tctx->cs)->env;
     uint32_t pir = env->spr_cb[SPR_PIR].default_value;
     Xive2Nvp nvp;
-    uint8_t *regs = &tctx->regs[TM_QW1_OS];
+    uint8_t *regs = &tctx->regs[ring];
 
     if (xive2_router_get_nvp(xrtr, nvp_blk, nvp_idx, &nvp)) {
         qemu_log_mask(LOG_GUEST_ERROR, "XIVE: No NVP %x/%x\n",
@@ -321,13 +322,13 @@ static void xive2_tctx_save_os_ctx(Xive2Router *xrtr, XiveTCTX *tctx,
     xive2_router_write_nvp(xrtr, nvp_blk, nvp_idx, &nvp, 1);
 }
 
-static void xive2_os_cam_decode(uint32_t cam, uint8_t *nvp_blk,
-                                uint32_t *nvp_idx, bool *vo, bool *ho)
+static void xive2_cam_decode(uint32_t cam, uint8_t *nvp_blk,
+                             uint32_t *nvp_idx, bool *valid, bool *hw)
 {
     *nvp_blk = xive2_nvp_blk(cam);
     *nvp_idx = xive2_nvp_idx(cam);
-    *vo = !!(cam & TM2_QW1W2_VO);
-    *ho = !!(cam & TM2_QW1W2_HO);
+    *valid = !!(cam & TM2_QW1W2_VO);
+    *hw = !!(cam & TM2_QW1W2_HO);
 }
 
 
@@ -351,37 +352,54 @@ static uint32_t xive2_tctx_hw_cam_line(XivePresenter *xptr, XiveTCTX *tctx)
     return xive2_nvp_cam_line(blk, 1 << tid_shift | (pir & tid_mask));
 }
 
-uint64_t xive2_tm_pull_os_ctx(XivePresenter *xptr, XiveTCTX *tctx,
-                              hwaddr offset, unsigned size)
+static uint64_t xive2_tm_pull_ctx(XivePresenter *xptr, XiveTCTX *tctx,
+                                  hwaddr offset, unsigned size, uint8_t ring)
 {
     Xive2Router *xrtr = XIVE2_ROUTER(xptr);
-    uint32_t qw1w2 = xive_tctx_word2(&tctx->regs[TM_QW1_OS]);
-    uint32_t qw1w2_new;
-    uint32_t cam = be32_to_cpu(qw1w2);
+    uint32_t target_ringw2 = xive_tctx_word2(&tctx->regs[ring]);
+    uint32_t cam = be32_to_cpu(target_ringw2);
     uint8_t nvp_blk;
     uint32_t nvp_idx;
-    bool vo;
+    uint8_t cur_ring;
+    bool valid;
     bool do_save;
 
-    xive2_os_cam_decode(cam, &nvp_blk, &nvp_idx, &vo, &do_save);
+    xive2_cam_decode(cam, &nvp_blk, &nvp_idx, &valid, &do_save);
 
-    if (!vo) {
+    if (!valid) {
         qemu_log_mask(LOG_GUEST_ERROR, "XIVE: pulling invalid NVP %x/%x !?\n",
                       nvp_blk, nvp_idx);
     }
 
-    /* Invalidate CAM line */
-    qw1w2_new = xive_set_field32(TM2_QW1W2_VO, qw1w2, 0);
-    memcpy(&tctx->regs[TM_QW1_OS + TM_WORD2], &qw1w2_new, 4);
+    /* Invalidate CAM line of requested ring and all lower rings */
+    for (cur_ring = TM_QW0_USER; cur_ring <= ring;
+         cur_ring += XIVE_TM_RING_SIZE) {
+        uint32_t ringw2 = xive_tctx_word2(&tctx->regs[cur_ring]);
+        uint32_t ringw2_new = xive_set_field32(TM2_QW1W2_VO, ringw2, 0);
+        memcpy(&tctx->regs[cur_ring + TM_WORD2], &ringw2_new, 4);
+    }
 
     if (xive2_router_get_config(xrtr) & XIVE2_VP_SAVE_RESTORE && do_save) {
-        xive2_tctx_save_os_ctx(xrtr, tctx, nvp_blk, nvp_idx);
+        xive2_tctx_save_ctx(xrtr, tctx, nvp_blk, nvp_idx, ring);
     }
 
-    xive_tctx_reset_os_signal(tctx);
-    return qw1w2;
+    /*
+     * Lower external interrupt line of requested ring and below except for
+     * USER, which doesn't exist.
+     */
+    for (cur_ring = TM_QW1_OS; cur_ring <= ring;
+         cur_ring += XIVE_TM_RING_SIZE) {
+        xive_tctx_reset_signal(tctx, cur_ring);
+    }
+    return target_ringw2;
 }
 
+uint64_t xive2_tm_pull_os_ctx(XivePresenter *xptr, XiveTCTX *tctx,
+                              hwaddr offset, unsigned size)
+{
+    return xive2_tm_pull_ctx(xptr, tctx, offset, size, TM_QW1_OS);
+ }
+
 #define REPORT_LINE_GEN1_SIZE       16
 
 static void xive2_tm_report_line_gen1(XiveTCTX *tctx, uint8_t *data,
@@ -424,8 +442,9 @@ static void xive2_tm_report_line_gen1(XiveTCTX *tctx, uint8_t *data,
     }
 }
 
-void xive2_tm_pull_os_ctx_ol(XivePresenter *xptr, XiveTCTX *tctx,
-                             hwaddr offset, uint64_t value, unsigned size)
+static void xive2_tm_pull_ctx_ol(XivePresenter *xptr, XiveTCTX *tctx,
+                                 hwaddr offset, uint64_t value,
+                                 unsigned size, uint8_t ring)
 {
     Xive2Router *xrtr = XIVE2_ROUTER(xptr);
     uint32_t hw_cam, nvp_idx, xive2_cfg, reserved;
@@ -473,8 +492,14 @@ void xive2_tm_pull_os_ctx_ol(XivePresenter *xptr, XiveTCTX *tctx,
         assert(result == MEMTX_OK);
     }
 
-    /* the rest is similar to pull OS context to registers */
-    xive2_tm_pull_os_ctx(xptr, tctx, offset, size);
+    /* the rest is similar to pull context to registers */
+    xive2_tm_pull_ctx(xptr, tctx, offset, size, ring);
+}
+
+void xive2_tm_pull_os_ctx_ol(XivePresenter *xptr, XiveTCTX *tctx,
+                             hwaddr offset, uint64_t value, unsigned size)
+{
+    xive2_tm_pull_ctx_ol(xptr, tctx, offset, value, size, TM_QW1_OS);
 }
 
 static uint8_t xive2_tctx_restore_os_ctx(Xive2Router *xrtr, XiveTCTX *tctx,
@@ -573,7 +598,7 @@ void xive2_tm_push_os_ctx(XivePresenter *xptr, XiveTCTX *tctx,
     bool vo;
     bool do_restore;
 
-    xive2_os_cam_decode(cam, &nvp_blk, &nvp_idx, &vo, &do_restore);
+    xive2_cam_decode(cam, &nvp_blk, &nvp_idx, &vo, &do_restore);
 
     /* First update the thead context */
     memcpy(&tctx->regs[TM_QW1_OS + TM_WORD2], &qw1w2, 4);
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 10/14] ppc/xive2: Support "Pull Thread Context to Odd Thread Reporting Line"
  2024-09-09 21:10 [PATCH v2 00/14] XIVE2 changes for TIMA operations Michael Kowal
                   ` (8 preceding siblings ...)
  2024-09-09 21:10 ` [PATCH v2 09/14] ppc/xive2: Change context/ring specific functions to be generic Michael Kowal
@ 2024-09-09 21:10 ` Michael Kowal
  2024-09-12  6:24   ` Cédric Le Goater
  2024-09-09 21:10 ` [PATCH v2 11/14] pnv/xive: Add special handling for pool targets Michael Kowal
                   ` (3 subsequent siblings)
  13 siblings, 1 reply; 23+ messages in thread
From: Michael Kowal @ 2024-09-09 21:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, clg, fbarrat, npiggin, milesg

From: Glenn Miles <milesg@linux.vnet.ibm.com>

Adds support for single byte writes to offset 0xC38 of the TIMA address
space.  When this offset is written to, the hardware disables the thread
context and copies the current state information to the odd cache line of
the pair specified by the NVT structure indexed by the THREAD CAM entry.

Note that this operation is almost identical to what we are already doing
for the "Pull OS Context to Odd Thread Reporting Line" operation except
that it also invalidates the Pool and Thread Contexts.

Signed-off-by: Glenn Miles <milesg@linux.vnet.ibm.com>
Signed-off-by: Michael Kowal <kowal@linux.ibm.com>
---
 include/hw/ppc/xive2.h      |  2 ++
 include/hw/ppc/xive2_regs.h | 16 +++++++++-------
 include/hw/ppc/xive_regs.h  |  1 +
 hw/intc/xive.c              |  9 +++++----
 hw/intc/xive2.c             | 12 +++++++++---
 5 files changed, 26 insertions(+), 14 deletions(-)

diff --git a/include/hw/ppc/xive2.h b/include/hw/ppc/xive2.h
index 36bd0e747f..5bccf41159 100644
--- a/include/hw/ppc/xive2.h
+++ b/include/hw/ppc/xive2.h
@@ -123,5 +123,7 @@ void xive2_tm_pull_os_ctx_ol(XivePresenter *xptr, XiveTCTX *tctx,
                              hwaddr offset, uint64_t value, unsigned size);
 void xive2_tm_set_hv_target(XivePresenter *xptr, XiveTCTX *tctx,
                             hwaddr offset, uint64_t value, unsigned size);
+void xive2_tm_pull_phys_ctx_ol(XivePresenter *xptr, XiveTCTX *tctx,
+                               hwaddr offset, uint64_t value, unsigned size);
 
 #endif /* PPC_XIVE2_H */
diff --git a/include/hw/ppc/xive2_regs.h b/include/hw/ppc/xive2_regs.h
index 99840e88a8..1d00c8df64 100644
--- a/include/hw/ppc/xive2_regs.h
+++ b/include/hw/ppc/xive2_regs.h
@@ -19,16 +19,18 @@
  * mode (P10), the CAM line is slightly different as the VP space was
  * increased.
  */
-#define   TM2_QW0W2_VU           PPC_BIT32(0)
+#define   TM2_W2_VALID           PPC_BIT32(0)
+#define   TM2_W2_HW              PPC_BIT32(1)
+#define   TM2_QW0W2_VU           TM2_W2_VALID
 #define   TM2_QW0W2_LOGIC_SERV   PPC_BITMASK32(4, 31)
-#define   TM2_QW1W2_VO           PPC_BIT32(0)
-#define   TM2_QW1W2_HO           PPC_BIT32(1)
+#define   TM2_QW1W2_VO           TM2_W2_VALID
+#define   TM2_QW1W2_HO           TM2_W2_HW
 #define   TM2_QW1W2_OS_CAM       PPC_BITMASK32(4, 31)
-#define   TM2_QW2W2_VP           PPC_BIT32(0)
-#define   TM2_QW2W2_HP           PPC_BIT32(1)
+#define   TM2_QW2W2_VP           TM2_W2_VALID
+#define   TM2_QW2W2_HP           TM2_W2_HW
 #define   TM2_QW2W2_POOL_CAM     PPC_BITMASK32(4, 31)
-#define   TM2_QW3W2_VT           PPC_BIT32(0)
-#define   TM2_QW3W2_HT           PPC_BIT32(1)
+#define   TM2_QW3W2_VT           TM2_W2_VALID
+#define   TM2_QW3W2_HT           TM2_W2_HW
 #define   TM2_QW3W2_LP           PPC_BIT32(6)
 #define   TM2_QW3W2_LE           PPC_BIT32(7)
 
diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h
index 558a5ae742..5b11463777 100644
--- a/include/hw/ppc/xive_regs.h
+++ b/include/hw/ppc/xive_regs.h
@@ -138,6 +138,7 @@
 #define TM_SPC_ACK_HV_POOL_EL   0xc20   /* Store8 ack HV evt pool to even     */
                                         /* line                               */
 #define TM_SPC_ACK_HV_EL        0xc30   /* Store8 ack HV irq to even line     */
+#define TM_SPC_PULL_PHYS_CTX_OL 0xc38   /* Pull phys ctx to odd cache line    */
 /* XXX more... */
 
 /* NSR fields for the various QW ack types */
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index f1d007d9a6..9d85da0999 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -117,10 +117,9 @@ static void xive_tctx_notify(XiveTCTX *tctx, uint8_t ring)
 void xive_tctx_reset_signal(XiveTCTX *tctx, uint8_t ring)
 {
     /*
-     * Lower the External interrupt. Used when pulling an OS
-     * context. It is necessary to avoid catching it in the hypervisor
-     * context. It should be raised again when re-pushing the OS
-     * context.
+     * Lower the External interrupt. Used when pulling a context. It is
+     * necessary to avoid catching it in the higher privilege context. It
+     * should be raised again when re-pushing the lower privilege context.
      */
     qemu_irq_lower(xive_tctx_output(tctx, ring));
 }
@@ -581,6 +580,8 @@ static const XiveTmOp xive2_tm_operations[] = {
                                                      NULL },
     { XIVE_TM_HV_PAGE, TM_SPC_PULL_PHYS_CTX,      1, NULL,
                                                      xive_tm_pull_phys_ctx },
+    { XIVE_TM_HV_PAGE, TM_SPC_PULL_PHYS_CTX_OL,   1, xive2_tm_pull_phys_ctx_ol,
+                                                     NULL },
 };
 
 static const XiveTmOp *xive_tm_find_op(XivePresenter *xptr, hwaddr offset,
diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c
index 38a4b0ff68..10fcbd04f1 100644
--- a/hw/intc/xive2.c
+++ b/hw/intc/xive2.c
@@ -327,8 +327,8 @@ static void xive2_cam_decode(uint32_t cam, uint8_t *nvp_blk,
 {
     *nvp_blk = xive2_nvp_blk(cam);
     *nvp_idx = xive2_nvp_idx(cam);
-    *valid = !!(cam & TM2_QW1W2_VO);
-    *hw = !!(cam & TM2_QW1W2_HO);
+    *valid = !!(cam & TM2_W2_VALID);
+    *hw = !!(cam & TM2_W2_HW);
 }
 
 
@@ -398,7 +398,7 @@ uint64_t xive2_tm_pull_os_ctx(XivePresenter *xptr, XiveTCTX *tctx,
                               hwaddr offset, unsigned size)
 {
     return xive2_tm_pull_ctx(xptr, tctx, offset, size, TM_QW1_OS);
- }
+}
 
 #define REPORT_LINE_GEN1_SIZE       16
 
@@ -502,6 +502,12 @@ void xive2_tm_pull_os_ctx_ol(XivePresenter *xptr, XiveTCTX *tctx,
     xive2_tm_pull_ctx_ol(xptr, tctx, offset, value, size, TM_QW1_OS);
 }
 
+void xive2_tm_pull_phys_ctx_ol(XivePresenter *xptr, XiveTCTX *tctx,
+                               hwaddr offset, uint64_t value, unsigned size)
+{
+    xive2_tm_pull_ctx_ol(xptr, tctx, offset, value, size, TM_QW3_HV_PHYS);
+}
+
 static uint8_t xive2_tctx_restore_os_ctx(Xive2Router *xrtr, XiveTCTX *tctx,
                                         uint8_t nvp_blk, uint32_t nvp_idx,
                                         Xive2Nvp *nvp)
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 11/14] pnv/xive: Add special handling for pool targets
  2024-09-09 21:10 [PATCH v2 00/14] XIVE2 changes for TIMA operations Michael Kowal
                   ` (9 preceding siblings ...)
  2024-09-09 21:10 ` [PATCH v2 10/14] ppc/xive2: Support "Pull Thread Context to Odd Thread Reporting Line" Michael Kowal
@ 2024-09-09 21:10 ` Michael Kowal
  2024-09-10 17:32   ` Cédric Le Goater
  2024-09-09 21:10 ` [PATCH v2 12/14] pnv/xive: Update PIPR when updating CPPR Michael Kowal
                   ` (2 subsequent siblings)
  13 siblings, 1 reply; 23+ messages in thread
From: Michael Kowal @ 2024-09-09 21:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, clg, fbarrat, npiggin, milesg

From: Glenn Miles <milesg@linux.vnet.ibm.com>

Hypervisor "pool" targets do not get their own interrupt line and instead
must share an interrupt line with the hypervisor "physical" targets.
This also means that the pool ring must use some of the registers from the
physical ring in the TIMA.  Specifically, the NSR, PIPR and CPPR registers:

  NSR = Notification Source Register
  PIPR = Post Interrupt Priority Register
  CPPR = Current Processor Priority Register

The NSR specifies that there is an active interrupt.  The CPPR
specifies the priority of the context and the PIPR specifies the
priority of the interrupt.  For an interrupt to be presented to
a context, the priority of the interrupt must be higher than the
priority of the context it is interrupting (value must be lower).

The existing code was not aware of the sharing of these registers.
This commit adds that support.

Signed-off-by: Glenn Miles <milesg@linux.vnet.ibm.com>
Signed-off-by: Michael Kowal <kowal@linux.ibm.com>
---
 hw/intc/xive.c | 36 ++++++++++++++++++++++++++----------
 1 file changed, 26 insertions(+), 10 deletions(-)

diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 9d85da0999..5c5c3a2dd6 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -74,33 +74,49 @@ static uint64_t xive_tctx_accept(XiveTCTX *tctx, uint8_t ring)
 
     if (regs[TM_NSR] & mask) {
         uint8_t cppr = regs[TM_PIPR];
+        uint8_t alt_ring;
+        uint8_t *alt_regs;
+
+        /* POOL interrupt uses IPB in QW2, POOL ring */
+        if ((ring == TM_QW3_HV_PHYS) && (nsr & (TM_QW3_NSR_HE_POOL << 6))) {
+            alt_ring = TM_QW2_HV_POOL;
+        } else {
+            alt_ring = ring;
+        }
+        alt_regs = &tctx->regs[alt_ring];
 
         regs[TM_CPPR] = cppr;
 
         /* Reset the pending buffer bit */
-        regs[TM_IPB] &= ~xive_priority_to_ipb(cppr);
-        regs[TM_PIPR] = ipb_to_pipr(regs[TM_IPB]);
+        alt_regs[TM_IPB] &= ~xive_priority_to_ipb(cppr);
+        regs[TM_PIPR] = ipb_to_pipr(alt_regs[TM_IPB]);
 
         /* Drop Exception bit */
         regs[TM_NSR] &= ~mask;
 
-        trace_xive_tctx_accept(tctx->cs->cpu_index, ring,
-                               regs[TM_IPB], regs[TM_PIPR],
+        trace_xive_tctx_accept(tctx->cs->cpu_index, alt_ring,
+                               alt_regs[TM_IPB], regs[TM_PIPR],
                                regs[TM_CPPR], regs[TM_NSR]);
     }
 
-    return (nsr << 8) | regs[TM_CPPR];
+    return ((uint64_t)nsr << 8) | regs[TM_CPPR];
 }
 
 static void xive_tctx_notify(XiveTCTX *tctx, uint8_t ring)
 {
+    /* HV_POOL ring uses HV_PHYS NSR, CPPR and PIPR registers */
+    uint8_t alt_ring = (ring == TM_QW2_HV_POOL) ? TM_QW3_HV_PHYS : ring;
+    uint8_t *alt_regs = &tctx->regs[alt_ring];
     uint8_t *regs = &tctx->regs[ring];
 
-    if (regs[TM_PIPR] < regs[TM_CPPR]) {
+    if (alt_regs[TM_PIPR] < alt_regs[TM_CPPR]) {
         switch (ring) {
         case TM_QW1_OS:
             regs[TM_NSR] |= TM_QW1_NSR_EO;
             break;
+        case TM_QW2_HV_POOL:
+            alt_regs[TM_NSR] = (TM_QW3_NSR_HE_POOL << 6);
+            break;
         case TM_QW3_HV_PHYS:
             regs[TM_NSR] |= (TM_QW3_NSR_HE_PHYS << 6);
             break;
@@ -108,8 +124,8 @@ static void xive_tctx_notify(XiveTCTX *tctx, uint8_t ring)
             g_assert_not_reached();
         }
         trace_xive_tctx_notify(tctx->cs->cpu_index, ring,
-                               regs[TM_IPB], regs[TM_PIPR],
-                               regs[TM_CPPR], regs[TM_NSR]);
+                               regs[TM_IPB], alt_regs[TM_PIPR],
+                               alt_regs[TM_CPPR], alt_regs[TM_NSR]);
         qemu_irq_raise(xive_tctx_output(tctx, ring));
     }
 }
@@ -217,14 +233,14 @@ static uint64_t xive_tm_vt_poll(XivePresenter *xptr, XiveTCTX *tctx,
 static const uint8_t xive_tm_hw_view[] = {
     3, 0, 0, 0,   0, 0, 0, 0,   3, 3, 3, 3,   0, 0, 0, 0, /* QW-0 User */
     3, 3, 3, 3,   3, 3, 0, 2,   3, 3, 3, 3,   0, 0, 0, 0, /* QW-1 OS   */
-    0, 0, 3, 3,   0, 0, 0, 0,   3, 3, 3, 3,   0, 0, 0, 0, /* QW-2 POOL */
+    0, 0, 3, 3,   0, 3, 3, 0,   3, 3, 3, 3,   0, 0, 0, 0, /* QW-2 POOL */
     3, 3, 3, 3,   0, 3, 0, 2,   3, 0, 0, 3,   3, 3, 3, 0, /* QW-3 PHYS */
 };
 
 static const uint8_t xive_tm_hv_view[] = {
     3, 0, 0, 0,   0, 0, 0, 0,   3, 3, 3, 3,   0, 0, 0, 0, /* QW-0 User */
     3, 3, 3, 3,   3, 3, 0, 2,   3, 3, 3, 3,   0, 0, 0, 0, /* QW-1 OS   */
-    0, 0, 3, 3,   0, 0, 0, 0,   0, 3, 3, 3,   0, 0, 0, 0, /* QW-2 POOL */
+    0, 0, 3, 3,   0, 3, 3, 0,   0, 3, 3, 3,   0, 0, 0, 0, /* QW-2 POOL */
     3, 3, 3, 3,   0, 3, 0, 2,   3, 0, 0, 3,   0, 0, 0, 0, /* QW-3 PHYS */
 };
 
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 12/14] pnv/xive: Update PIPR when updating CPPR
  2024-09-09 21:10 [PATCH v2 00/14] XIVE2 changes for TIMA operations Michael Kowal
                   ` (10 preceding siblings ...)
  2024-09-09 21:10 ` [PATCH v2 11/14] pnv/xive: Add special handling for pool targets Michael Kowal
@ 2024-09-09 21:10 ` Michael Kowal
  2024-09-10 17:30   ` Cédric Le Goater
  2024-09-09 21:10 ` [PATCH v2 13/14] pnv/xive2: TIMA support for 8-byte OS context push for PHYP Michael Kowal
  2024-09-09 21:10 ` [PATCH v2 14/14] pnv/xive2: TIMA CI ops using alternative offsets or byte lengths Michael Kowal
  13 siblings, 1 reply; 23+ messages in thread
From: Michael Kowal @ 2024-09-09 21:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, clg, fbarrat, npiggin, milesg

From: Glenn Miles <milesg@linux.ibm.com>

Current code was updating the PIPR inside the xive_tctx_accept() function
instead of the xive_tctx_set_cppr function, which is where the HW would
have it updated.

Moved the update to the xive_tctx_set_cppr function which required
additional support for pool interrupts.

Fixes: cdd4de68edb6 ("ppc/xive: notify the CPU when the interrupt priority is more privileged")
Signed-off-by: Glenn Miles <milesg@linux.vnet.ibm.com>
Signed-off-by: Michael Kowal <kowal@linux.ibm.com>
---
 hw/intc/xive.c | 34 ++++++++++++++++++++++++++++++++--
 1 file changed, 32 insertions(+), 2 deletions(-)

diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 5c5c3a2dd6..738eaf624d 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -89,7 +89,6 @@ static uint64_t xive_tctx_accept(XiveTCTX *tctx, uint8_t ring)
 
         /* Reset the pending buffer bit */
         alt_regs[TM_IPB] &= ~xive_priority_to_ipb(cppr);
-        regs[TM_PIPR] = ipb_to_pipr(alt_regs[TM_IPB]);
 
         /* Drop Exception bit */
         regs[TM_NSR] &= ~mask;
@@ -143,6 +142,8 @@ void xive_tctx_reset_signal(XiveTCTX *tctx, uint8_t ring)
 static void xive_tctx_set_cppr(XiveTCTX *tctx, uint8_t ring, uint8_t cppr)
 {
     uint8_t *regs = &tctx->regs[ring];
+    uint8_t pipr_min;
+    uint8_t ring_min;
 
     trace_xive_tctx_set_cppr(tctx->cs->cpu_index, ring,
                              regs[TM_IPB], regs[TM_PIPR],
@@ -154,8 +155,37 @@ static void xive_tctx_set_cppr(XiveTCTX *tctx, uint8_t ring, uint8_t cppr)
 
     tctx->regs[ring + TM_CPPR] = cppr;
 
+    /*
+     * Recompute the PIPR based on local pending interrupts.  The PHYS
+     * ring must take the minimum of both the PHYS and POOL PIPR values.
+     */
+    pipr_min = ipb_to_pipr(regs[TM_IPB]);
+    ring_min = ring;
+
+    /* PHYS updates also depend on POOL values */
+    if (ring == TM_QW3_HV_PHYS) {
+        uint8_t *pool_regs = &tctx->regs[TM_QW2_HV_POOL];
+
+        /* POOL values only matter if POOL ctx is valid */
+        if (pool_regs[TM_WORD2] & 0x80) {
+
+            uint8_t pool_pipr = ipb_to_pipr(pool_regs[TM_IPB]);
+
+            /*
+             * Determine highest priority interrupt and
+             * remember which ring has it.
+             */
+            if (pool_pipr < pipr_min) {
+                pipr_min = pool_pipr;
+                ring_min = TM_QW2_HV_POOL;
+            }
+        }
+    }
+
+    regs[TM_PIPR] = pipr_min;
+
     /* CPPR has changed, check if we need to raise a pending exception */
-    xive_tctx_notify(tctx, ring);
+    xive_tctx_notify(tctx, ring_min);
 }
 
 void xive_tctx_ipb_update(XiveTCTX *tctx, uint8_t ring, uint8_t ipb)
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 13/14] pnv/xive2: TIMA support for 8-byte OS context push for PHYP
  2024-09-09 21:10 [PATCH v2 00/14] XIVE2 changes for TIMA operations Michael Kowal
                   ` (11 preceding siblings ...)
  2024-09-09 21:10 ` [PATCH v2 12/14] pnv/xive: Update PIPR when updating CPPR Michael Kowal
@ 2024-09-09 21:10 ` Michael Kowal
  2024-09-09 21:10 ` [PATCH v2 14/14] pnv/xive2: TIMA CI ops using alternative offsets or byte lengths Michael Kowal
  13 siblings, 0 replies; 23+ messages in thread
From: Michael Kowal @ 2024-09-09 21:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, clg, fbarrat, npiggin, milesg

From: Glenn Miles <milesg@linux.vnet.ibm.com>

PHYP uses 8-byte writes to the 2nd doubleword of the OS context
line when dispatching an OS level virtual processor.  This
support was not used by OPAL/Linux and so was never added.

Without this support, the XIVE code doesn't notice that a new
context is being pushed and fails to check for unpresented
pending interrupts for that context.

Signed-off-by: Glenn Miles <milesg@linux.vnet.ibm.com>
Signed-off-by: Michael Kowal <kowal@linux.ibm.com>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
---
 hw/intc/xive.c  |  2 ++
 hw/intc/xive2.c | 24 +++++++++++++++++++-----
 2 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 738eaf624d..3ce86b6895 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -596,6 +596,8 @@ static const XiveTmOp xive2_tm_operations[] = {
                                                      NULL },
     { XIVE_TM_HV_PAGE, TM_QW1_OS + TM_WORD2,      4, xive2_tm_push_os_ctx,
                                                      NULL },
+    { XIVE_TM_HV_PAGE, TM_QW1_OS + TM_WORD2,      8, xive2_tm_push_os_ctx,
+                                                     NULL },
     { XIVE_TM_OS_PAGE, TM_QW1_OS + TM_LGS,        1, xive_tm_set_os_lgs,
                                                      NULL },
     { XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_CPPR,  1, xive_tm_set_hv_cppr,
diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c
index 10fcbd04f1..b86e051d22 100644
--- a/hw/intc/xive2.c
+++ b/hw/intc/xive2.c
@@ -597,17 +597,31 @@ static void xive2_tctx_need_resend(Xive2Router *xrtr, XiveTCTX *tctx,
 void xive2_tm_push_os_ctx(XivePresenter *xptr, XiveTCTX *tctx,
                           hwaddr offset, uint64_t value, unsigned size)
 {
-    uint32_t cam = value;
-    uint32_t qw1w2 = cpu_to_be32(cam);
+    uint32_t cam;
+    uint32_t qw1w2;
+    uint64_t qw1dw1;
     uint8_t nvp_blk;
     uint32_t nvp_idx;
     bool vo;
     bool do_restore;
 
-    xive2_cam_decode(cam, &nvp_blk, &nvp_idx, &vo, &do_restore);
-
     /* First update the thead context */
-    memcpy(&tctx->regs[TM_QW1_OS + TM_WORD2], &qw1w2, 4);
+    switch (size) {
+    case 4:
+        cam = value;
+        qw1w2 = cpu_to_be32(cam);
+        memcpy(&tctx->regs[TM_QW1_OS + TM_WORD2], &qw1w2, 4);
+        break;
+    case 8:
+        cam = value >> 32;
+        qw1dw1 = cpu_to_be64(value);
+        memcpy(&tctx->regs[TM_QW1_OS + TM_WORD2], &qw1dw1, 8);
+        break;
+    default:
+        g_assert_not_reached();
+    }
+
+    xive2_cam_decode(cam, &nvp_blk, &nvp_idx, &vo, &do_restore);
 
     /* Check the interrupt pending bits */
     if (vo) {
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 14/14] pnv/xive2: TIMA CI ops using alternative offsets or byte lengths
  2024-09-09 21:10 [PATCH v2 00/14] XIVE2 changes for TIMA operations Michael Kowal
                   ` (12 preceding siblings ...)
  2024-09-09 21:10 ` [PATCH v2 13/14] pnv/xive2: TIMA support for 8-byte OS context push for PHYP Michael Kowal
@ 2024-09-09 21:10 ` Michael Kowal
  13 siblings, 0 replies; 23+ messages in thread
From: Michael Kowal @ 2024-09-09 21:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, clg, fbarrat, npiggin, milesg

Some of the TIMA Special CI operations perform the same operation at
alternative byte offsets and lengths.  The following
xive2_tm_opertions[] table entries are missing when they exist for
other offsets/sizes and have been added:
- lwz@0x810 Pull/Invalidate O/S Context to register    added
  lwz@0x818                                            exists
  ld @0x818                                            exists
- lwz@0x820 Pull Pool Context to register              added
  lwz@0x828                                            exists
  ld @0x828                                            exists
- lwz@0x830 Pull Thread Context to register            added
  lbz@0x838                                            exists

Signed-off-by: Michael Kowal <kowal@linux.ibm.com>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
---
 include/hw/ppc/xive_regs.h | 7 ++++++-
 hw/intc/xive.c             | 6 ++++++
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h
index 5b11463777..326327fc79 100644
--- a/include/hw/ppc/xive_regs.h
+++ b/include/hw/ppc/xive_regs.h
@@ -124,12 +124,17 @@
 #define TM_SPC_PULL_USR_CTX     0x808   /* Load32 Pull/Invalidate user        */
                                         /* context                            */
 #define TM_SPC_SET_OS_PENDING   0x812   /* Store8 Set OS irq pending bit      */
+#define TM_SPC_PULL_OS_CTX_G2   0x810   /* Load32/Load64 Pull/Invalidate OS   */
+                                        /* context to reg                     */
 #define TM_SPC_PULL_OS_CTX      0x818   /* Load32/Load64 Pull/Invalidate OS   */
                                         /* context to reg                     */
+#define TM_SPC_PULL_POOL_CTX_G2 0x820   /* Load32/Load64 Pull/Invalidate Pool */
+                                        /* context to reg                     */
 #define TM_SPC_PULL_POOL_CTX    0x828   /* Load32/Load64 Pull/Invalidate Pool */
                                         /* context to reg                     */
 #define TM_SPC_ACK_HV_REG       0x830   /* Load16 ack HV irq to reg           */
-#define TM_SPC_PULL_PHYS_CTX    0x838   /* Pull phys ctx to reg               */
+#define TM_SPC_PULL_PHYS_CTX_G2 0x830   /* Load32 Pull phys ctx to reg        */
+#define TM_SPC_PULL_PHYS_CTX    0x838   /* Load8  Pull phys ctx to reg        */
 #define TM_SPC_PULL_USR_CTX_OL  0xc08   /* Store8 Pull/Inval usr ctx to odd   */
                                         /* line                               */
 #define TM_SPC_ACK_OS_EL        0xc10   /* Store8 ack OS irq to even line     */
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 3ce86b6895..efcb63e8aa 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -614,18 +614,24 @@ static const XiveTmOp xive2_tm_operations[] = {
                                                      xive_tm_ack_os_reg },
     { XIVE_TM_OS_PAGE, TM_SPC_SET_OS_PENDING,     1, xive_tm_set_os_pending,
                                                      NULL },
+    { XIVE_TM_HV_PAGE, TM_SPC_PULL_OS_CTX_G2,     4, NULL,
+                                                     xive2_tm_pull_os_ctx },
     { XIVE_TM_HV_PAGE, TM_SPC_PULL_OS_CTX,        4, NULL,
                                                      xive2_tm_pull_os_ctx },
     { XIVE_TM_HV_PAGE, TM_SPC_PULL_OS_CTX,        8, NULL,
                                                      xive2_tm_pull_os_ctx },
     { XIVE_TM_HV_PAGE, TM_SPC_ACK_HV_REG,         2, NULL,
                                                      xive_tm_ack_hv_reg },
+    { XIVE_TM_HV_PAGE, TM_SPC_PULL_POOL_CTX_G2,   4, NULL,
+                                                     xive_tm_pull_pool_ctx },
     { XIVE_TM_HV_PAGE, TM_SPC_PULL_POOL_CTX,      4, NULL,
                                                      xive_tm_pull_pool_ctx },
     { XIVE_TM_HV_PAGE, TM_SPC_PULL_POOL_CTX,      8, NULL,
                                                      xive_tm_pull_pool_ctx },
     { XIVE_TM_HV_PAGE, TM_SPC_PULL_OS_CTX_OL,     1, xive2_tm_pull_os_ctx_ol,
                                                      NULL },
+    { XIVE_TM_HV_PAGE, TM_SPC_PULL_PHYS_CTX_G2,   4, NULL,
+                                                     xive_tm_pull_phys_ctx },
     { XIVE_TM_HV_PAGE, TM_SPC_PULL_PHYS_CTX,      1, NULL,
                                                      xive_tm_pull_phys_ctx },
     { XIVE_TM_HV_PAGE, TM_SPC_PULL_PHYS_CTX_OL,   1, xive2_tm_pull_phys_ctx_ol,
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 03/14] ppc/xive2: Support TIMA "Pull OS Context to Odd Thread Reporting Line"
  2024-09-09 21:10 ` [PATCH v2 03/14] ppc/xive2: Support TIMA "Pull OS Context to Odd Thread Reporting Line" Michael Kowal
@ 2024-09-10 17:21   ` Cédric Le Goater
  0 siblings, 0 replies; 23+ messages in thread
From: Cédric Le Goater @ 2024-09-10 17:21 UTC (permalink / raw)
  To: Michael Kowal, qemu-devel; +Cc: qemu-ppc, fbarrat, npiggin, milesg

On 9/9/24 23:10, Michael Kowal wrote:
> From: Frederic Barrat <fbarrat@linux.ibm.com>
> 
> Adds support for single byte writes to offset 0xC18 of the TIMA address
> space.  When this offset is written to, the hardware disables the OS
> context and copies the current state information to the odd cache line
> of the pair specified by the NVT structure indexed by the OS CAM entry.
> 
> Signed-off-by: Frederic Barrat <fbarrat@linux.ibm.com>
> Signed-off-by: Michael Kowal <kowal@linux.vnet.ibm.com>


Reviewed-by: Cédric Le Goater <clg@redhat.com>

Thanks,

C.


> ---
>   include/hw/ppc/xive2.h      |   2 +
>   include/hw/ppc/xive2_regs.h |   2 +
>   include/hw/ppc/xive_regs.h  |   3 +
>   hw/intc/xive.c              |   2 +
>   hw/intc/xive2.c             | 160 ++++++++++++++++++++++++++++++------
>   5 files changed, 142 insertions(+), 27 deletions(-)
> 
> diff --git a/include/hw/ppc/xive2.h b/include/hw/ppc/xive2.h
> index ab68f8d157..654f485e9b 100644
> --- a/include/hw/ppc/xive2.h
> +++ b/include/hw/ppc/xive2.h
> @@ -107,5 +107,7 @@ 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,
>                                  hwaddr offset, unsigned size);
> +void xive2_tm_pull_os_ctx_ol(XivePresenter *xptr, XiveTCTX *tctx,
> +                             hwaddr offset, uint64_t value, unsigned size);
>   
>   #endif /* PPC_XIVE2_H */
> diff --git a/include/hw/ppc/xive2_regs.h b/include/hw/ppc/xive2_regs.h
> index 4349d009d0..7acf7dccf3 100644
> --- a/include/hw/ppc/xive2_regs.h
> +++ b/include/hw/ppc/xive2_regs.h
> @@ -171,7 +171,9 @@ typedef struct Xive2Nvp {
>   #define NVP2_W5_VP_END_BLOCK       PPC_BITMASK32(4, 7)
>   #define NVP2_W5_VP_END_INDEX       PPC_BITMASK32(8, 31)
>           uint32_t       w6;
> +#define NVP2_W6_REPORTING_LINE     PPC_BITMASK32(4, 31)
>           uint32_t       w7;
> +#define NVP2_W7_REPORTING_LINE     PPC_BITMASK32(0, 23)
>   } Xive2Nvp;
>   
>   #define xive2_nvp_is_valid(nvp)    (be32_to_cpu((nvp)->w0) & NVP2_W0_VALID)
> diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h
> index 9062c6abf6..27a744d50d 100644
> --- a/include/hw/ppc/xive_regs.h
> +++ b/include/hw/ppc/xive_regs.h
> @@ -77,6 +77,7 @@
>   #define TM_LSMFB                0x3  /*  -   +   +   +  */
>   #define TM_ACK_CNT              0x4  /*  -   +   -   -  */
>   #define TM_INC                  0x5  /*  -   +   -   +  */
> +#define TM_LGS                  0x5  /*  +   +   +   +  */ /* Rename P10 */
>   #define TM_AGE                  0x6  /*  -   +   -   +  */
>   #define TM_PIPR                 0x7  /*  -   +   -   +  */
>   #define TM_OGEN                 0xF  /*  -   +   -   -  */ /* P10 only */
> @@ -129,6 +130,8 @@
>   #define TM_SPC_PULL_USR_CTX_OL  0xc08   /* Store8 Pull/Inval usr ctx to odd   */
>                                           /* line                               */
>   #define TM_SPC_ACK_OS_EL        0xc10   /* Store8 ack OS irq to even line     */
> +#define TM_SPC_PULL_OS_CTX_OL   0xc18   /* Pull/Invalidate OS context to      */
> +                                        /* odd Thread reporting line          */
>   #define TM_SPC_ACK_HV_POOL_EL   0xc20   /* Store8 ack HV evt pool to even     */
>                                           /* line                               */
>   #define TM_SPC_ACK_HV_EL        0xc30   /* Store8 ack HV irq to even line     */
> diff --git a/hw/intc/xive.c b/hw/intc/xive.c
> index 136d82338a..8e62c7e75f 100644
> --- a/hw/intc/xive.c
> +++ b/hw/intc/xive.c
> @@ -547,6 +547,8 @@ static const XiveTmOp xive2_tm_operations[] = {
>                                                        xive_tm_pull_pool_ctx },
>       { XIVE_TM_HV_PAGE, TM_SPC_PULL_POOL_CTX,      8, NULL,
>                                                        xive_tm_pull_pool_ctx },
> +    { XIVE_TM_HV_PAGE, TM_SPC_PULL_OS_CTX_OL,     1, xive2_tm_pull_os_ctx_ol,
> +                                                     NULL },
>   };
>   
>   static const XiveTmOp *xive_tm_find_op(XivePresenter *xptr, hwaddr offset,
> diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c
> index 1f150685bf..fbd05aa9f5 100644
> --- a/hw/intc/xive2.c
> +++ b/hw/intc/xive2.c
> @@ -26,6 +26,23 @@ uint32_t xive2_router_get_config(Xive2Router *xrtr)
>       return xrc->get_config(xrtr);
>   }
>   
> +static int xive2_router_get_block_id(Xive2Router *xrtr)
> +{
> +   Xive2RouterClass *xrc = XIVE2_ROUTER_GET_CLASS(xrtr);
> +
> +   return xrc->get_block_id(xrtr);
> +}
> +
> +static uint64_t xive2_nvp_reporting_addr(Xive2Nvp *nvp)
> +{
> +    uint64_t cache_addr;
> +
> +    cache_addr = xive_get_field32(NVP2_W6_REPORTING_LINE, nvp->w6) << 24 |
> +        xive_get_field32(NVP2_W7_REPORTING_LINE, nvp->w7);
> +    cache_addr <<= 8; /* aligned on a cache line pair */
> +    return cache_addr;
> +}
> +
>   void xive2_eas_pic_print_info(Xive2Eas *eas, uint32_t lisn, GString *buf)
>   {
>       if (!xive2_eas_is_valid(eas)) {
> @@ -270,6 +287,27 @@ static void xive2_os_cam_decode(uint32_t cam, uint8_t *nvp_blk,
>       *ho = !!(cam & TM2_QW1W2_HO);
>   }
>   
> +
> +/*
> + * Encode the HW CAM line with 7bit or 8bit thread id. The thread id
> + * width and block id width is configurable at the IC level.
> + *
> + *    chipid << 24 | 0000 0000 0000 0000 1 threadid (7Bit)
> + *    chipid << 24 | 0000 0000 0000 0001 threadid   (8Bit)
> + */
> +static uint32_t xive2_tctx_hw_cam_line(XivePresenter *xptr, XiveTCTX *tctx)
> +{
> +    Xive2Router *xrtr = XIVE2_ROUTER(xptr);
> +    CPUPPCState *env = &POWERPC_CPU(tctx->cs)->env;
> +    uint32_t pir = env->spr_cb[SPR_PIR].default_value;
> +    uint8_t blk = xive2_router_get_block_id(xrtr);
> +    uint8_t tid_shift =
> +        xive2_router_get_config(xrtr) & XIVE2_THREADID_8BITS ? 8 : 7;
> +    uint8_t tid_mask = (1 << tid_shift) - 1;
> +
> +    return xive2_nvp_cam_line(blk, 1 << tid_shift | (pir & tid_mask));
> +}
> +
>   uint64_t xive2_tm_pull_os_ctx(XivePresenter *xptr, XiveTCTX *tctx,
>                                 hwaddr offset, unsigned size)
>   {
> @@ -301,6 +339,101 @@ uint64_t xive2_tm_pull_os_ctx(XivePresenter *xptr, XiveTCTX *tctx,
>       return qw1w2;
>   }
>   
> +#define REPORT_LINE_GEN1_SIZE       16
> +
> +static void xive2_tm_report_line_gen1(XiveTCTX *tctx, uint8_t *data,
> +                                      uint8_t size)
> +{
> +    uint8_t *regs = tctx->regs;
> +
> +    g_assert(size == REPORT_LINE_GEN1_SIZE);
> +    memset(data, 0, size);
> +    /*
> +     * See xive architecture for description of what is saved. It is
> +     * hand-picked information to fit in 16 bytes.
> +     */
> +    data[0x0] = regs[TM_QW3_HV_PHYS + TM_NSR];
> +    data[0x1] = regs[TM_QW3_HV_PHYS + TM_CPPR];
> +    data[0x2] = regs[TM_QW3_HV_PHYS + TM_IPB];
> +    data[0x3] = regs[TM_QW2_HV_POOL + TM_IPB];
> +    data[0x4] = regs[TM_QW1_OS + TM_ACK_CNT];
> +    data[0x5] = regs[TM_QW3_HV_PHYS + TM_LGS];
> +    data[0x6] = 0xFF;
> +    data[0x7] = regs[TM_QW3_HV_PHYS + TM_WORD2] & 0x80;
> +    data[0x7] |= (regs[TM_QW2_HV_POOL + TM_WORD2] & 0x80) >> 1;
> +    data[0x7] |= (regs[TM_QW1_OS + TM_WORD2] & 0x80) >> 2;
> +    data[0x7] |= (regs[TM_QW3_HV_PHYS + TM_WORD2] & 0x3);
> +    data[0x8] = regs[TM_QW1_OS + TM_NSR];
> +    data[0x9] = regs[TM_QW1_OS + TM_CPPR];
> +    data[0xA] = regs[TM_QW1_OS + TM_IPB];
> +    data[0xB] = regs[TM_QW1_OS + TM_LGS];
> +    if (regs[TM_QW0_USER + TM_WORD2] & 0x80) {
> +        /*
> +         * Logical server extension, except VU bit replaced by EB bit
> +         * from NSR
> +         */
> +        data[0xC] = regs[TM_QW0_USER + TM_WORD2];
> +        data[0xC] &= ~0x80;
> +        data[0xC] |= regs[TM_QW0_USER + TM_NSR] & 0x80;
> +        data[0xD] = regs[TM_QW0_USER + TM_WORD2 + 1];
> +        data[0xE] = regs[TM_QW0_USER + TM_WORD2 + 2];
> +        data[0xF] = regs[TM_QW0_USER + TM_WORD2 + 3];
> +    }
> +}
> +
> +void xive2_tm_pull_os_ctx_ol(XivePresenter *xptr, XiveTCTX *tctx,
> +                             hwaddr offset, uint64_t value, unsigned size)
> +{
> +    Xive2Router *xrtr = XIVE2_ROUTER(xptr);
> +    uint32_t hw_cam, nvp_idx, xive2_cfg, reserved;
> +    uint8_t nvp_blk;
> +    Xive2Nvp nvp;
> +    uint64_t phys_addr;
> +    MemTxResult result;
> +
> +    hw_cam = xive2_tctx_hw_cam_line(xptr, tctx);
> +    nvp_blk = xive2_nvp_blk(hw_cam);
> +    nvp_idx = xive2_nvp_idx(hw_cam);
> +
> +    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: invalid NVP %x/%x\n",
> +                      nvp_blk, nvp_idx);
> +        return;
> +    }
> +
> +    xive2_cfg = xive2_router_get_config(xrtr);
> +
> +    phys_addr = xive2_nvp_reporting_addr(&nvp) + 0x80; /* odd line */
> +    if (xive2_cfg & XIVE2_GEN1_TIMA_OS) {
> +        uint8_t pull_ctxt[REPORT_LINE_GEN1_SIZE];
> +
> +        xive2_tm_report_line_gen1(tctx, pull_ctxt, REPORT_LINE_GEN1_SIZE);
> +        result = dma_memory_write(&address_space_memory, phys_addr,
> +                                  pull_ctxt, REPORT_LINE_GEN1_SIZE,
> +                                  MEMTXATTRS_UNSPECIFIED);
> +        assert(result == MEMTX_OK);
> +    } else {
> +        result = dma_memory_write(&address_space_memory, phys_addr,
> +                                  &tctx->regs, sizeof(tctx->regs),
> +                                  MEMTXATTRS_UNSPECIFIED);
> +        assert(result == MEMTX_OK);
> +        reserved = 0xFFFFFFFF;
> +        result = dma_memory_write(&address_space_memory, phys_addr + 12,
> +                                  &reserved, sizeof(reserved),
> +                                  MEMTXATTRS_UNSPECIFIED);
> +        assert(result == MEMTX_OK);
> +    }
> +
> +    /* the rest is similar to pull OS context to registers */
> +    xive2_tm_pull_os_ctx(xptr, tctx, offset, size);
> +}
> +
>   static uint8_t xive2_tctx_restore_os_ctx(Xive2Router *xrtr, XiveTCTX *tctx,
>                                           uint8_t nvp_blk, uint32_t nvp_idx,
>                                           Xive2Nvp *nvp)
> @@ -471,33 +604,6 @@ int xive2_router_write_nvp(Xive2Router *xrtr, uint8_t nvp_blk, uint32_t nvp_idx,
>      return xrc->write_nvp(xrtr, nvp_blk, nvp_idx, nvp, word_number);
>   }
>   
> -static int xive2_router_get_block_id(Xive2Router *xrtr)
> -{
> -   Xive2RouterClass *xrc = XIVE2_ROUTER_GET_CLASS(xrtr);
> -
> -   return xrc->get_block_id(xrtr);
> -}
> -
> -/*
> - * Encode the HW CAM line with 7bit or 8bit thread id. The thread id
> - * width and block id width is configurable at the IC level.
> - *
> - *    chipid << 24 | 0000 0000 0000 0000 1 threadid (7Bit)
> - *    chipid << 24 | 0000 0000 0000 0001 threadid   (8Bit)
> - */
> -static uint32_t xive2_tctx_hw_cam_line(XivePresenter *xptr, XiveTCTX *tctx)
> -{
> -    Xive2Router *xrtr = XIVE2_ROUTER(xptr);
> -    CPUPPCState *env = &POWERPC_CPU(tctx->cs)->env;
> -    uint32_t pir = env->spr_cb[SPR_PIR].default_value;
> -    uint8_t blk = xive2_router_get_block_id(xrtr);
> -    uint8_t tid_shift =
> -        xive2_router_get_config(xrtr) & XIVE2_THREADID_8BITS ? 8 : 7;
> -    uint8_t tid_mask = (1 << tid_shift) - 1;
> -
> -    return xive2_nvp_cam_line(blk, 1 << tid_shift | (pir & tid_mask));
> -}
> -
>   /*
>    * The thread context register words are in big-endian format.
>    */



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 05/14] ppc/xive2: Dump more NVP state with 'info pic'
  2024-09-09 21:10 ` [PATCH v2 05/14] ppc/xive2: Dump more NVP state with 'info pic' Michael Kowal
@ 2024-09-10 17:23   ` Cédric Le Goater
  0 siblings, 0 replies; 23+ messages in thread
From: Cédric Le Goater @ 2024-09-10 17:23 UTC (permalink / raw)
  To: Michael Kowal, qemu-devel; +Cc: qemu-ppc, fbarrat, npiggin, milesg

On 9/9/24 23:10, Michael Kowal wrote:
> From: Frederic Barrat <fbarrat@linux.ibm.com>
> 
> The 'PGoFirst' field of a Notify Virtual Processor tells if the NVP
> belongs to a VP group.
> 
> Also, print the Reporting Cache Line address, if defined.
> 
> Signed-off-by: Frederic Barrat <fbarrat@linux.ibm.com>
> Signed-off-by: Michael Kowal <kowal@linux.ibm.com>


Reviewed-by: Cédric Le Goater <clg@redhat.com>

Thanks,

C.


> ---
>   include/hw/ppc/xive2_regs.h |  1 +
>   hw/intc/xive2.c             | 10 ++++++++--
>   2 files changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/include/hw/ppc/xive2_regs.h b/include/hw/ppc/xive2_regs.h
> index 7acf7dccf3..d71a54f9ff 100644
> --- a/include/hw/ppc/xive2_regs.h
> +++ b/include/hw/ppc/xive2_regs.h
> @@ -151,6 +151,7 @@ typedef struct Xive2Nvp {
>   #define NVP2_W0_VALID              PPC_BIT32(0)
>   #define NVP2_W0_HW                 PPC_BIT32(7)
>   #define NVP2_W0_ESC_END            PPC_BIT32(25) /* 'N' bit 0:ESB  1:END */
> +#define NVP2_W0_PGOFIRST           PPC_BITMASK32(26, 31)
>           uint32_t       w1;
>   #define NVP2_W1_CO                 PPC_BIT32(13)
>   #define NVP2_W1_CO_PRIV            PPC_BITMASK32(14, 15)
> diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c
> index fbd05aa9f5..ac581fa195 100644
> --- a/hw/intc/xive2.c
> +++ b/hw/intc/xive2.c
> @@ -161,14 +161,20 @@ void xive2_nvp_pic_print_info(Xive2Nvp *nvp, uint32_t nvp_idx, GString *buf)
>   {
>       uint8_t  eq_blk = xive_get_field32(NVP2_W5_VP_END_BLOCK, nvp->w5);
>       uint32_t eq_idx = xive_get_field32(NVP2_W5_VP_END_INDEX, nvp->w5);
> +    uint64_t cache_line = xive2_nvp_reporting_addr(nvp);
>   
>       if (!xive2_nvp_is_valid(nvp)) {
>           return;
>       }
>   
> -    g_string_append_printf(buf, "  %08x end:%02x/%04x IPB:%02x",
> +    g_string_append_printf(buf, "  %08x end:%02x/%04x IPB:%02x PGoFirst:%02x",
>                              nvp_idx, eq_blk, eq_idx,
> -                           xive_get_field32(NVP2_W2_IPB, nvp->w2));
> +                           xive_get_field32(NVP2_W2_IPB, nvp->w2),
> +                           xive_get_field32(NVP2_W0_PGOFIRST, nvp->w0));
> +    if (cache_line) {
> +        g_string_append_printf(buf, "  reporting CL:%016"PRIx64, cache_line);
> +    }
> +
>       /*
>        * When the NVP is HW controlled, more fields are updated
>        */



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 06/14] ppc/xive2: Dump the VP-group and crowd tables with 'info pic'
  2024-09-09 21:10 ` [PATCH v2 06/14] ppc/xive2: Dump the VP-group and crowd tables " Michael Kowal
@ 2024-09-10 17:25   ` Cédric Le Goater
  0 siblings, 0 replies; 23+ messages in thread
From: Cédric Le Goater @ 2024-09-10 17:25 UTC (permalink / raw)
  To: Michael Kowal, qemu-devel; +Cc: qemu-ppc, fbarrat, npiggin, milesg

On 9/9/24 23:10, Michael Kowal wrote:
> From: Frederic Barrat <fbarrat@linux.ibm.com>
> 
> The 'info pic' HMP command dumps the state of the interrupt controller.
> Add the dump of the NVG and NVC tables to its output to ease debug.
> 
> Signed-off-by: Frederic Barrat <fbarrat@linux.ibm.com>
> Signed-off-by: Michael Kowal <kowal@linux.ibm.com>


Reviewed-by: Cédric Le Goater <clg@redhat.com>

Thanks,

C.


> ---
>   include/hw/ppc/xive2.h      | 12 ++++++++
>   include/hw/ppc/xive2_regs.h |  6 ++++
>   hw/intc/pnv_xive2.c         | 44 +++++++++++++++++++++++++++--
>   hw/intc/xive2.c             | 55 +++++++++++++++++++++++++++++++++++++
>   4 files changed, 114 insertions(+), 3 deletions(-)
> 
> diff --git a/include/hw/ppc/xive2.h b/include/hw/ppc/xive2.h
> index 654f485e9b..b7a7c33ddd 100644
> --- a/include/hw/ppc/xive2.h
> +++ b/include/hw/ppc/xive2.h
> @@ -53,6 +53,12 @@ typedef struct Xive2RouterClass {
>                      Xive2Nvp *nvp);
>       int (*write_nvp)(Xive2Router *xrtr, uint8_t nvp_blk, uint32_t nvp_idx,
>                        Xive2Nvp *nvp, uint8_t word_number);
> +    int (*get_nvgc)(Xive2Router *xrtr, bool crowd,
> +                    uint8_t nvgc_blk, uint32_t nvgc_idx,
> +                    Xive2Nvgc *nvgc);
> +    int (*write_nvgc)(Xive2Router *xrtr, bool crowd,
> +                      uint8_t nvgc_blk, uint32_t nvgc_idx,
> +                      Xive2Nvgc *nvgc);
>       uint8_t (*get_block_id)(Xive2Router *xrtr);
>       uint32_t (*get_config)(Xive2Router *xrtr);
>   } Xive2RouterClass;
> @@ -67,6 +73,12 @@ int xive2_router_get_nvp(Xive2Router *xrtr, uint8_t nvp_blk, uint32_t nvp_idx,
>                           Xive2Nvp *nvp);
>   int xive2_router_write_nvp(Xive2Router *xrtr, uint8_t nvp_blk, uint32_t nvp_idx,
>                             Xive2Nvp *nvp, uint8_t word_number);
> +int xive2_router_get_nvgc(Xive2Router *xrtr, bool crowd,
> +                          uint8_t nvgc_blk, uint32_t nvgc_idx,
> +                          Xive2Nvgc *nvgc);
> +int xive2_router_write_nvgc(Xive2Router *xrtr, bool crowd,
> +                            uint8_t nvgc_blk, uint32_t nvgc_idx,
> +                            Xive2Nvgc *nvgc);
>   uint32_t xive2_router_get_config(Xive2Router *xrtr);
>   
>   void xive2_router_notify(XiveNotifier *xn, uint32_t lisn, bool pq_checked);
> diff --git a/include/hw/ppc/xive2_regs.h b/include/hw/ppc/xive2_regs.h
> index d71a54f9ff..99840e88a8 100644
> --- a/include/hw/ppc/xive2_regs.h
> +++ b/include/hw/ppc/xive2_regs.h
> @@ -212,6 +212,7 @@ void xive2_nvp_pic_print_info(Xive2Nvp *nvp, uint32_t nvp_idx, GString *buf);
>   typedef struct Xive2Nvgc {
>           uint32_t        w0;
>   #define NVGC2_W0_VALID             PPC_BIT32(0)
> +#define NVGC2_W0_PGONEXT           PPC_BITMASK32(26, 31)
>           uint32_t        w1;
>           uint32_t        w2;
>           uint32_t        w3;
> @@ -221,4 +222,9 @@ typedef struct Xive2Nvgc {
>           uint32_t        w7;
>   } Xive2Nvgc;
>   
> +#define xive2_nvgc_is_valid(nvgc)    (be32_to_cpu((nvgc)->w0) & NVGC2_W0_VALID)
> +
> +void xive2_nvgc_pic_print_info(Xive2Nvgc *nvgc, uint32_t nvgc_idx,
> +                               GString *buf);
> +
>   #endif /* PPC_XIVE2_REGS_H */
> diff --git a/hw/intc/pnv_xive2.c b/hw/intc/pnv_xive2.c
> index 78609105a8..834d32287b 100644
> --- a/hw/intc/pnv_xive2.c
> +++ b/hw/intc/pnv_xive2.c
> @@ -490,6 +490,23 @@ static int pnv_xive2_write_nvp(Xive2Router *xrtr, uint8_t blk, uint32_t idx,
>                                 word_number);
>   }
>   
> +static int pnv_xive2_get_nvgc(Xive2Router *xrtr, bool crowd,
> +                              uint8_t blk, uint32_t idx,
> +                              Xive2Nvgc *nvgc)
> +{
> +    return pnv_xive2_vst_read(PNV_XIVE2(xrtr), crowd ? VST_NVC : VST_NVG,
> +                              blk, idx, nvgc);
> +}
> +
> +static int pnv_xive2_write_nvgc(Xive2Router *xrtr, bool crowd,
> +                                uint8_t blk, uint32_t idx,
> +                                Xive2Nvgc *nvgc)
> +{
> +    return pnv_xive2_vst_write(PNV_XIVE2(xrtr), crowd ? VST_NVC : VST_NVG,
> +                               blk, idx, nvgc,
> +                               XIVE_VST_WORD_ALL);
> +}
> +
>   static int pnv_xive2_nxc_to_table_type(uint8_t nxc_type, uint32_t *table_type)
>   {
>       switch (nxc_type) {
> @@ -2407,6 +2424,8 @@ static void pnv_xive2_class_init(ObjectClass *klass, void *data)
>       xrc->write_end = pnv_xive2_write_end;
>       xrc->get_nvp   = pnv_xive2_get_nvp;
>       xrc->write_nvp = pnv_xive2_write_nvp;
> +    xrc->get_nvgc   = pnv_xive2_get_nvgc;
> +    xrc->write_nvgc = pnv_xive2_write_nvgc;
>       xrc->get_config  = pnv_xive2_get_config;
>       xrc->get_block_id = pnv_xive2_get_block_id;
>   
> @@ -2497,8 +2516,9 @@ void pnv_xive2_pic_print_info(PnvXive2 *xive, GString *buf)
>       Xive2Eas eas;
>       Xive2End end;
>       Xive2Nvp nvp;
> +    Xive2Nvgc nvgc;
>       int i;
> -    uint64_t xive_nvp_per_subpage;
> +    uint64_t entries_per_subpage;
>   
>       g_string_append_printf(buf, "XIVE[%x] Source %08x .. %08x\n",
>                              blk, srcno0, srcno0 + nr_esbs - 1);
> @@ -2530,10 +2550,28 @@ void pnv_xive2_pic_print_info(PnvXive2 *xive, GString *buf)
>   
>       g_string_append_printf(buf, "XIVE[%x] #%d NVPT %08x .. %08x\n",
>                              chip_id, blk, 0, XIVE2_NVP_COUNT - 1);
> -    xive_nvp_per_subpage = pnv_xive2_vst_per_subpage(xive, VST_NVP);
> -    for (i = 0; i < XIVE2_NVP_COUNT; i += xive_nvp_per_subpage) {
> +    entries_per_subpage = pnv_xive2_vst_per_subpage(xive, VST_NVP);
> +    for (i = 0; i < XIVE2_NVP_COUNT; i += entries_per_subpage) {
>           while (!xive2_router_get_nvp(xrtr, blk, i, &nvp)) {
>               xive2_nvp_pic_print_info(&nvp, i++, buf);
>           }
>       }
> +
> +    g_string_append_printf(buf, "XIVE[%x] #%d NVGT %08x .. %08x\n",
> +                           chip_id, blk, 0, XIVE2_NVP_COUNT - 1);
> +    entries_per_subpage = pnv_xive2_vst_per_subpage(xive, VST_NVG);
> +    for (i = 0; i < XIVE2_NVP_COUNT; i += entries_per_subpage) {
> +        while (!xive2_router_get_nvgc(xrtr, false, blk, i, &nvgc)) {
> +            xive2_nvgc_pic_print_info(&nvgc, i++, buf);
> +        }
> +    }
> +
> +    g_string_append_printf(buf, "XIVE[%x] #%d NVCT %08x .. %08x\n",
> +                          chip_id, blk, 0, XIVE2_NVP_COUNT - 1);
> +    entries_per_subpage = pnv_xive2_vst_per_subpage(xive, VST_NVC);
> +    for (i = 0; i < XIVE2_NVP_COUNT; i += entries_per_subpage) {
> +        while (!xive2_router_get_nvgc(xrtr, true, blk, i, &nvgc)) {
> +            xive2_nvgc_pic_print_info(&nvgc, i++, buf);
> +        }
> +    }
>   }
> diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c
> index ac581fa195..26b6e72129 100644
> --- a/hw/intc/xive2.c
> +++ b/hw/intc/xive2.c
> @@ -43,6 +43,26 @@ static uint64_t xive2_nvp_reporting_addr(Xive2Nvp *nvp)
>       return cache_addr;
>   }
>   
> +static uint32_t xive2_nvgc_get_backlog(Xive2Nvgc *nvgc, uint8_t priority)
> +{
> +    uint32_t val = 0;
> +    uint8_t *ptr, i;
> +
> +    if (priority > 7) {
> +        return 0;
> +    }
> +
> +    /*
> +     * The per-priority backlog counters are 24-bit and the structure
> +     * is stored in big endian
> +     */
> +    ptr = (uint8_t *)&nvgc->w2 + priority * 3;
> +    for (i = 0; i < 3; i++, ptr++) {
> +        val = (val << 8) + *ptr;
> +    }
> +    return val;
> +}
> +
>   void xive2_eas_pic_print_info(Xive2Eas *eas, uint32_t lisn, GString *buf)
>   {
>       if (!xive2_eas_is_valid(eas)) {
> @@ -189,6 +209,23 @@ void xive2_nvp_pic_print_info(Xive2Nvp *nvp, uint32_t nvp_idx, GString *buf)
>       g_string_append_c(buf, '\n');
>   }
>   
> +void xive2_nvgc_pic_print_info(Xive2Nvgc *nvgc, uint32_t nvgc_idx, GString *buf)
> +{
> +    uint8_t i;
> +
> +    if (!xive2_nvgc_is_valid(nvgc)) {
> +        return;
> +    }
> +
> +    g_string_append_printf(buf, "  %08x PGoNext:%02x bklog: ", nvgc_idx,
> +                           xive_get_field32(NVGC2_W0_PGONEXT, nvgc->w0));
> +    for (i = 0; i <= XIVE_PRIORITY_MAX; i++) {
> +        g_string_append_printf(buf, "[%d]=0x%x ",
> +                               i, xive2_nvgc_get_backlog(nvgc, i));
> +    }
> +    g_string_append_printf(buf, "\n");
> +}
> +
>   static void xive2_end_enqueue(Xive2End *end, uint32_t data)
>   {
>       uint64_t qaddr_base = xive2_end_qaddr(end);
> @@ -610,6 +647,24 @@ int xive2_router_write_nvp(Xive2Router *xrtr, uint8_t nvp_blk, uint32_t nvp_idx,
>      return xrc->write_nvp(xrtr, nvp_blk, nvp_idx, nvp, word_number);
>   }
>   
> +int xive2_router_get_nvgc(Xive2Router *xrtr, bool crowd,
> +                          uint8_t nvgc_blk, uint32_t nvgc_idx,
> +                          Xive2Nvgc *nvgc)
> +{
> +   Xive2RouterClass *xrc = XIVE2_ROUTER_GET_CLASS(xrtr);
> +
> +   return xrc->get_nvgc(xrtr, crowd, nvgc_blk, nvgc_idx, nvgc);
> +}
> +
> +int xive2_router_write_nvgc(Xive2Router *xrtr, bool crowd,
> +                            uint8_t nvgc_blk, uint32_t nvgc_idx,
> +                            Xive2Nvgc *nvgc)
> +{
> +   Xive2RouterClass *xrc = XIVE2_ROUTER_GET_CLASS(xrtr);
> +
> +   return xrc->write_nvgc(xrtr, crowd, nvgc_blk, nvgc_idx, nvgc);
> +}
> +
>   /*
>    * The thread context register words are in big-endian format.
>    */



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 12/14] pnv/xive: Update PIPR when updating CPPR
  2024-09-09 21:10 ` [PATCH v2 12/14] pnv/xive: Update PIPR when updating CPPR Michael Kowal
@ 2024-09-10 17:30   ` Cédric Le Goater
  0 siblings, 0 replies; 23+ messages in thread
From: Cédric Le Goater @ 2024-09-10 17:30 UTC (permalink / raw)
  To: Michael Kowal, qemu-devel; +Cc: qemu-ppc, fbarrat, npiggin, milesg

On 9/9/24 23:10, Michael Kowal wrote:
> From: Glenn Miles <milesg@linux.ibm.com>
> 
> Current code was updating the PIPR inside the xive_tctx_accept() function
> instead of the xive_tctx_set_cppr function, which is where the HW would
> have it updated.
> 
> Moved the update to the xive_tctx_set_cppr function which required
> additional support for pool interrupts.
> 
> Fixes: cdd4de68edb6 ("ppc/xive: notify the CPU when the interrupt priority is more privileged")
> Signed-off-by: Glenn Miles <milesg@linux.vnet.ibm.com>
> Signed-off-by: Michael Kowal <kowal@linux.ibm.com>


Reviewed-by: Cédric Le Goater <clg@redhat.com>

Thanks,

C.


> ---
>   hw/intc/xive.c | 34 ++++++++++++++++++++++++++++++++--
>   1 file changed, 32 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/intc/xive.c b/hw/intc/xive.c
> index 5c5c3a2dd6..738eaf624d 100644
> --- a/hw/intc/xive.c
> +++ b/hw/intc/xive.c
> @@ -89,7 +89,6 @@ static uint64_t xive_tctx_accept(XiveTCTX *tctx, uint8_t ring)
>   
>           /* Reset the pending buffer bit */
>           alt_regs[TM_IPB] &= ~xive_priority_to_ipb(cppr);
> -        regs[TM_PIPR] = ipb_to_pipr(alt_regs[TM_IPB]);
>   
>           /* Drop Exception bit */
>           regs[TM_NSR] &= ~mask;
> @@ -143,6 +142,8 @@ void xive_tctx_reset_signal(XiveTCTX *tctx, uint8_t ring)
>   static void xive_tctx_set_cppr(XiveTCTX *tctx, uint8_t ring, uint8_t cppr)
>   {
>       uint8_t *regs = &tctx->regs[ring];
> +    uint8_t pipr_min;
> +    uint8_t ring_min;
>   
>       trace_xive_tctx_set_cppr(tctx->cs->cpu_index, ring,
>                                regs[TM_IPB], regs[TM_PIPR],
> @@ -154,8 +155,37 @@ static void xive_tctx_set_cppr(XiveTCTX *tctx, uint8_t ring, uint8_t cppr)
>   
>       tctx->regs[ring + TM_CPPR] = cppr;
>   
> +    /*
> +     * Recompute the PIPR based on local pending interrupts.  The PHYS
> +     * ring must take the minimum of both the PHYS and POOL PIPR values.
> +     */
> +    pipr_min = ipb_to_pipr(regs[TM_IPB]);
> +    ring_min = ring;
> +
> +    /* PHYS updates also depend on POOL values */
> +    if (ring == TM_QW3_HV_PHYS) {
> +        uint8_t *pool_regs = &tctx->regs[TM_QW2_HV_POOL];
> +
> +        /* POOL values only matter if POOL ctx is valid */
> +        if (pool_regs[TM_WORD2] & 0x80) {
> +
> +            uint8_t pool_pipr = ipb_to_pipr(pool_regs[TM_IPB]);
> +
> +            /*
> +             * Determine highest priority interrupt and
> +             * remember which ring has it.
> +             */
> +            if (pool_pipr < pipr_min) {
> +                pipr_min = pool_pipr;
> +                ring_min = TM_QW2_HV_POOL;
> +            }
> +        }
> +    }
> +
> +    regs[TM_PIPR] = pipr_min;
> +
>       /* CPPR has changed, check if we need to raise a pending exception */
> -    xive_tctx_notify(tctx, ring);
> +    xive_tctx_notify(tctx, ring_min);
>   }
>   
>   void xive_tctx_ipb_update(XiveTCTX *tctx, uint8_t ring, uint8_t ipb)



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 11/14] pnv/xive: Add special handling for pool targets
  2024-09-09 21:10 ` [PATCH v2 11/14] pnv/xive: Add special handling for pool targets Michael Kowal
@ 2024-09-10 17:32   ` Cédric Le Goater
  0 siblings, 0 replies; 23+ messages in thread
From: Cédric Le Goater @ 2024-09-10 17:32 UTC (permalink / raw)
  To: Michael Kowal, qemu-devel; +Cc: qemu-ppc, fbarrat, npiggin, milesg

On 9/9/24 23:10, Michael Kowal wrote:
> From: Glenn Miles <milesg@linux.vnet.ibm.com>
> 
> Hypervisor "pool" targets do not get their own interrupt line and instead
> must share an interrupt line with the hypervisor "physical" targets.
> This also means that the pool ring must use some of the registers from the
> physical ring in the TIMA.  Specifically, the NSR, PIPR and CPPR registers:
> 
>    NSR = Notification Source Register
>    PIPR = Post Interrupt Priority Register
>    CPPR = Current Processor Priority Register
> 
> The NSR specifies that there is an active interrupt.  The CPPR
> specifies the priority of the context and the PIPR specifies the
> priority of the interrupt.  For an interrupt to be presented to
> a context, the priority of the interrupt must be higher than the
> priority of the context it is interrupting (value must be lower).
> 
> The existing code was not aware of the sharing of these registers.
> This commit adds that support.
> 
> Signed-off-by: Glenn Miles <milesg@linux.vnet.ibm.com>
> Signed-off-by: Michael Kowal <kowal@linux.ibm.com>


Reviewed-by: Cédric Le Goater <clg@redhat.com>

Thanks,

C.


> ---
>   hw/intc/xive.c | 36 ++++++++++++++++++++++++++----------
>   1 file changed, 26 insertions(+), 10 deletions(-)
> 
> diff --git a/hw/intc/xive.c b/hw/intc/xive.c
> index 9d85da0999..5c5c3a2dd6 100644
> --- a/hw/intc/xive.c
> +++ b/hw/intc/xive.c
> @@ -74,33 +74,49 @@ static uint64_t xive_tctx_accept(XiveTCTX *tctx, uint8_t ring)
>   
>       if (regs[TM_NSR] & mask) {
>           uint8_t cppr = regs[TM_PIPR];
> +        uint8_t alt_ring;
> +        uint8_t *alt_regs;
> +
> +        /* POOL interrupt uses IPB in QW2, POOL ring */
> +        if ((ring == TM_QW3_HV_PHYS) && (nsr & (TM_QW3_NSR_HE_POOL << 6))) {
> +            alt_ring = TM_QW2_HV_POOL;
> +        } else {
> +            alt_ring = ring;
> +        }
> +        alt_regs = &tctx->regs[alt_ring];
>   
>           regs[TM_CPPR] = cppr;
>   
>           /* Reset the pending buffer bit */
> -        regs[TM_IPB] &= ~xive_priority_to_ipb(cppr);
> -        regs[TM_PIPR] = ipb_to_pipr(regs[TM_IPB]);
> +        alt_regs[TM_IPB] &= ~xive_priority_to_ipb(cppr);
> +        regs[TM_PIPR] = ipb_to_pipr(alt_regs[TM_IPB]);
>   
>           /* Drop Exception bit */
>           regs[TM_NSR] &= ~mask;
>   
> -        trace_xive_tctx_accept(tctx->cs->cpu_index, ring,
> -                               regs[TM_IPB], regs[TM_PIPR],
> +        trace_xive_tctx_accept(tctx->cs->cpu_index, alt_ring,
> +                               alt_regs[TM_IPB], regs[TM_PIPR],
>                                  regs[TM_CPPR], regs[TM_NSR]);
>       }
>   
> -    return (nsr << 8) | regs[TM_CPPR];
> +    return ((uint64_t)nsr << 8) | regs[TM_CPPR];
>   }
>   
>   static void xive_tctx_notify(XiveTCTX *tctx, uint8_t ring)
>   {
> +    /* HV_POOL ring uses HV_PHYS NSR, CPPR and PIPR registers */
> +    uint8_t alt_ring = (ring == TM_QW2_HV_POOL) ? TM_QW3_HV_PHYS : ring;
> +    uint8_t *alt_regs = &tctx->regs[alt_ring];
>       uint8_t *regs = &tctx->regs[ring];
>   
> -    if (regs[TM_PIPR] < regs[TM_CPPR]) {
> +    if (alt_regs[TM_PIPR] < alt_regs[TM_CPPR]) {
>           switch (ring) {
>           case TM_QW1_OS:
>               regs[TM_NSR] |= TM_QW1_NSR_EO;
>               break;
> +        case TM_QW2_HV_POOL:
> +            alt_regs[TM_NSR] = (TM_QW3_NSR_HE_POOL << 6);
> +            break;
>           case TM_QW3_HV_PHYS:
>               regs[TM_NSR] |= (TM_QW3_NSR_HE_PHYS << 6);
>               break;
> @@ -108,8 +124,8 @@ static void xive_tctx_notify(XiveTCTX *tctx, uint8_t ring)
>               g_assert_not_reached();
>           }
>           trace_xive_tctx_notify(tctx->cs->cpu_index, ring,
> -                               regs[TM_IPB], regs[TM_PIPR],
> -                               regs[TM_CPPR], regs[TM_NSR]);
> +                               regs[TM_IPB], alt_regs[TM_PIPR],
> +                               alt_regs[TM_CPPR], alt_regs[TM_NSR]);
>           qemu_irq_raise(xive_tctx_output(tctx, ring));
>       }
>   }
> @@ -217,14 +233,14 @@ static uint64_t xive_tm_vt_poll(XivePresenter *xptr, XiveTCTX *tctx,
>   static const uint8_t xive_tm_hw_view[] = {
>       3, 0, 0, 0,   0, 0, 0, 0,   3, 3, 3, 3,   0, 0, 0, 0, /* QW-0 User */
>       3, 3, 3, 3,   3, 3, 0, 2,   3, 3, 3, 3,   0, 0, 0, 0, /* QW-1 OS   */
> -    0, 0, 3, 3,   0, 0, 0, 0,   3, 3, 3, 3,   0, 0, 0, 0, /* QW-2 POOL */
> +    0, 0, 3, 3,   0, 3, 3, 0,   3, 3, 3, 3,   0, 0, 0, 0, /* QW-2 POOL */
>       3, 3, 3, 3,   0, 3, 0, 2,   3, 0, 0, 3,   3, 3, 3, 0, /* QW-3 PHYS */
>   };
>   
>   static const uint8_t xive_tm_hv_view[] = {
>       3, 0, 0, 0,   0, 0, 0, 0,   3, 3, 3, 3,   0, 0, 0, 0, /* QW-0 User */
>       3, 3, 3, 3,   3, 3, 0, 2,   3, 3, 3, 3,   0, 0, 0, 0, /* QW-1 OS   */
> -    0, 0, 3, 3,   0, 0, 0, 0,   0, 3, 3, 3,   0, 0, 0, 0, /* QW-2 POOL */
> +    0, 0, 3, 3,   0, 3, 3, 0,   0, 3, 3, 3,   0, 0, 0, 0, /* QW-2 POOL */
>       3, 3, 3, 3,   0, 3, 0, 2,   3, 0, 0, 3,   0, 0, 0, 0, /* QW-3 PHYS */
>   };
>   



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 10/14] ppc/xive2: Support "Pull Thread Context to Odd Thread Reporting Line"
  2024-09-09 21:10 ` [PATCH v2 10/14] ppc/xive2: Support "Pull Thread Context to Odd Thread Reporting Line" Michael Kowal
@ 2024-09-12  6:24   ` Cédric Le Goater
  0 siblings, 0 replies; 23+ messages in thread
From: Cédric Le Goater @ 2024-09-12  6:24 UTC (permalink / raw)
  To: Michael Kowal, qemu-devel; +Cc: qemu-ppc, fbarrat, npiggin, milesg

On 9/9/24 23:10, Michael Kowal wrote:
> From: Glenn Miles <milesg@linux.vnet.ibm.com>
> 
> Adds support for single byte writes to offset 0xC38 of the TIMA address
> space.  When this offset is written to, the hardware disables the thread
> context and copies the current state information to the odd cache line of
> the pair specified by the NVT structure indexed by the THREAD CAM entry.
> 
> Note that this operation is almost identical to what we are already doing
> for the "Pull OS Context to Odd Thread Reporting Line" operation except
> that it also invalidates the Pool and Thread Contexts.
> 
> Signed-off-by: Glenn Miles <milesg@linux.vnet.ibm.com>
> Signed-off-by: Michael Kowal <kowal@linux.ibm.com>
> ---
>   include/hw/ppc/xive2.h      |  2 ++
>   include/hw/ppc/xive2_regs.h | 16 +++++++++-------
>   include/hw/ppc/xive_regs.h  |  1 +
>   hw/intc/xive.c              |  9 +++++----
>   hw/intc/xive2.c             | 12 +++++++++---
>   5 files changed, 26 insertions(+), 14 deletions(-)
> 
> diff --git a/include/hw/ppc/xive2.h b/include/hw/ppc/xive2.h
> index 36bd0e747f..5bccf41159 100644
> --- a/include/hw/ppc/xive2.h
> +++ b/include/hw/ppc/xive2.h
> @@ -123,5 +123,7 @@ void xive2_tm_pull_os_ctx_ol(XivePresenter *xptr, XiveTCTX *tctx,
>                                hwaddr offset, uint64_t value, unsigned size);
>   void xive2_tm_set_hv_target(XivePresenter *xptr, XiveTCTX *tctx,
>                               hwaddr offset, uint64_t value, unsigned size);
> +void xive2_tm_pull_phys_ctx_ol(XivePresenter *xptr, XiveTCTX *tctx,
> +                               hwaddr offset, uint64_t value, unsigned size);
>   
>   #endif /* PPC_XIVE2_H */
> diff --git a/include/hw/ppc/xive2_regs.h b/include/hw/ppc/xive2_regs.h
> index 99840e88a8..1d00c8df64 100644
> --- a/include/hw/ppc/xive2_regs.h
> +++ b/include/hw/ppc/xive2_regs.h
> @@ -19,16 +19,18 @@
>    * mode (P10), the CAM line is slightly different as the VP space was
>    * increased.
>    */
> -#define   TM2_QW0W2_VU           PPC_BIT32(0)
> +#define   TM2_W2_VALID           PPC_BIT32(0)
> +#define   TM2_W2_HW              PPC_BIT32(1)
> +#define   TM2_QW0W2_VU           TM2_W2_VALID
>   #define   TM2_QW0W2_LOGIC_SERV   PPC_BITMASK32(4, 31)
> -#define   TM2_QW1W2_VO           PPC_BIT32(0)
> -#define   TM2_QW1W2_HO           PPC_BIT32(1)
> +#define   TM2_QW1W2_VO           TM2_W2_VALID
> +#define   TM2_QW1W2_HO           TM2_W2_HW
>   #define   TM2_QW1W2_OS_CAM       PPC_BITMASK32(4, 31)
> -#define   TM2_QW2W2_VP           PPC_BIT32(0)
> -#define   TM2_QW2W2_HP           PPC_BIT32(1)
> +#define   TM2_QW2W2_VP           TM2_W2_VALID
> +#define   TM2_QW2W2_HP           TM2_W2_HW
>   #define   TM2_QW2W2_POOL_CAM     PPC_BITMASK32(4, 31)
> -#define   TM2_QW3W2_VT           PPC_BIT32(0)
> -#define   TM2_QW3W2_HT           PPC_BIT32(1)
> +#define   TM2_QW3W2_VT           TM2_W2_VALID
> +#define   TM2_QW3W2_HT           TM2_W2_HW
>   #define   TM2_QW3W2_LP           PPC_BIT32(6)
>   #define   TM2_QW3W2_LE           PPC_BIT32(7)
>   
> diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h
> index 558a5ae742..5b11463777 100644
> --- a/include/hw/ppc/xive_regs.h
> +++ b/include/hw/ppc/xive_regs.h
> @@ -138,6 +138,7 @@
>   #define TM_SPC_ACK_HV_POOL_EL   0xc20   /* Store8 ack HV evt pool to even     */
>                                           /* line                               */
>   #define TM_SPC_ACK_HV_EL        0xc30   /* Store8 ack HV irq to even line     */
> +#define TM_SPC_PULL_PHYS_CTX_OL 0xc38   /* Pull phys ctx to odd cache line    */
>   /* XXX more... */
>   
>   /* NSR fields for the various QW ack types */
> diff --git a/hw/intc/xive.c b/hw/intc/xive.c
> index f1d007d9a6..9d85da0999 100644
> --- a/hw/intc/xive.c
> +++ b/hw/intc/xive.c
> @@ -117,10 +117,9 @@ static void xive_tctx_notify(XiveTCTX *tctx, uint8_t ring)
>   void xive_tctx_reset_signal(XiveTCTX *tctx, uint8_t ring)
>   {
>       /*
> -     * Lower the External interrupt. Used when pulling an OS
> -     * context. It is necessary to avoid catching it in the hypervisor
> -     * context. It should be raised again when re-pushing the OS
> -     * context.
> +     * Lower the External interrupt. Used when pulling a context. It is
> +     * necessary to avoid catching it in the higher privilege context. It
> +     * should be raised again when re-pushing the lower privilege context.
>        */
>       qemu_irq_lower(xive_tctx_output(tctx, ring));
>   }
> @@ -581,6 +580,8 @@ static const XiveTmOp xive2_tm_operations[] = {
>                                                        NULL },
>       { XIVE_TM_HV_PAGE, TM_SPC_PULL_PHYS_CTX,      1, NULL,
>                                                        xive_tm_pull_phys_ctx },
> +    { XIVE_TM_HV_PAGE, TM_SPC_PULL_PHYS_CTX_OL,   1, xive2_tm_pull_phys_ctx_ol,
> +                                                     NULL },
>   };
>   
>   static const XiveTmOp *xive_tm_find_op(XivePresenter *xptr, hwaddr offset,
> diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c
> index 38a4b0ff68..10fcbd04f1 100644
> --- a/hw/intc/xive2.c
> +++ b/hw/intc/xive2.c
> @@ -327,8 +327,8 @@ static void xive2_cam_decode(uint32_t cam, uint8_t *nvp_blk,
>   {
>       *nvp_blk = xive2_nvp_blk(cam);
>       *nvp_idx = xive2_nvp_idx(cam);
> -    *valid = !!(cam & TM2_QW1W2_VO);
> -    *hw = !!(cam & TM2_QW1W2_HO);
> +    *valid = !!(cam & TM2_W2_VALID);
> +    *hw = !!(cam & TM2_W2_HW);
>   }
>   
>   
> @@ -398,7 +398,7 @@ uint64_t xive2_tm_pull_os_ctx(XivePresenter *xptr, XiveTCTX *tctx,
>                                 hwaddr offset, unsigned size)
>   {
>       return xive2_tm_pull_ctx(xptr, tctx, offset, size, TM_QW1_OS);
> - }
> +}

This should be avoided in patch 9.


>   #define REPORT_LINE_GEN1_SIZE       16
>   
> @@ -502,6 +502,12 @@ void xive2_tm_pull_os_ctx_ol(XivePresenter *xptr, XiveTCTX *tctx,
>       xive2_tm_pull_ctx_ol(xptr, tctx, offset, value, size, TM_QW1_OS);
>   }
>   
> +void xive2_tm_pull_phys_ctx_ol(XivePresenter *xptr, XiveTCTX *tctx,
> +                               hwaddr offset, uint64_t value, unsigned size)
> +{
> +    xive2_tm_pull_ctx_ol(xptr, tctx, offset, value, size, TM_QW3_HV_PHYS);
> +}
> +
>   static uint8_t xive2_tctx_restore_os_ctx(Xive2Router *xrtr, XiveTCTX *tctx,
>                                           uint8_t nvp_blk, uint32_t nvp_idx,
>                                           Xive2Nvp *nvp)



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 09/14] ppc/xive2: Change context/ring specific functions to be generic
  2024-09-09 21:10 ` [PATCH v2 09/14] ppc/xive2: Change context/ring specific functions to be generic Michael Kowal
@ 2024-09-12  6:27   ` Cédric Le Goater
  2024-09-12 16:41     ` Mike Kowal
  0 siblings, 1 reply; 23+ messages in thread
From: Cédric Le Goater @ 2024-09-12  6:27 UTC (permalink / raw)
  To: Michael Kowal, qemu-devel; +Cc: qemu-ppc, fbarrat, npiggin, milesg

On 9/9/24 23:10, Michael Kowal wrote:
> Some the functions that have been created are specific to a ring or context. Some
> of these same functions are being changed to operate on any ring/context. This  will
> simplify the next patch sets that are adding additional ring/context operations.
>
> Signed-off-by: Michael Kowal <kowal@linux.ibm.com>
> ---
>   include/hw/ppc/xive.h |  2 +-
>   hw/intc/xive.c        |  6 ++--
>   hw/intc/xive2.c       | 77 ++++++++++++++++++++++++++++---------------
>   3 files changed, 55 insertions(+), 30 deletions(-)
> 
> diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
> index 28c181faa2..31242f0406 100644
> --- a/include/hw/ppc/xive.h
> +++ b/include/hw/ppc/xive.h
> @@ -533,7 +533,7 @@ Object *xive_tctx_create(Object *cpu, XivePresenter *xptr, Error **errp);
>   void xive_tctx_reset(XiveTCTX *tctx);
>   void xive_tctx_destroy(XiveTCTX *tctx);
>   void xive_tctx_ipb_update(XiveTCTX *tctx, uint8_t ring, uint8_t ipb);
> -void xive_tctx_reset_os_signal(XiveTCTX *tctx);
> +void xive_tctx_reset_signal(XiveTCTX *tctx, uint8_t ring);
>   
>   /*
>    * KVM XIVE device helpers
> diff --git a/hw/intc/xive.c b/hw/intc/xive.c
> index 5b66a3aec5..f1d007d9a6 100644
> --- a/hw/intc/xive.c
> +++ b/hw/intc/xive.c
> @@ -114,7 +114,7 @@ static void xive_tctx_notify(XiveTCTX *tctx, uint8_t ring)
>       }
>   }
>   
> -void xive_tctx_reset_os_signal(XiveTCTX *tctx)
> +void xive_tctx_reset_signal(XiveTCTX *tctx, uint8_t ring)
>   {
>       /*
>        * Lower the External interrupt. Used when pulling an OS
> @@ -122,7 +122,7 @@ void xive_tctx_reset_os_signal(XiveTCTX *tctx)
>        * context. It should be raised again when re-pushing the OS
>        * context.
>        */
> -    qemu_irq_lower(xive_tctx_output(tctx, TM_QW1_OS));
> +    qemu_irq_lower(xive_tctx_output(tctx, ring));
>   }
>   
>   static void xive_tctx_set_cppr(XiveTCTX *tctx, uint8_t ring, uint8_t cppr)
> @@ -424,7 +424,7 @@ static uint64_t xive_tm_pull_os_ctx(XivePresenter *xptr, XiveTCTX *tctx,
>       qw1w2_new = xive_set_field32(TM_QW1W2_VO, qw1w2, 0);
>       xive_tctx_set_os_cam(tctx, qw1w2_new);
>   
> -    xive_tctx_reset_os_signal(tctx);
> +    xive_tctx_reset_signal(tctx, TM_QW1_OS);
>       return qw1w2;
>   }
>   
> diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c
> index 8d3d69a0db..38a4b0ff68 100644
> --- a/hw/intc/xive2.c
> +++ b/hw/intc/xive2.c
> @@ -270,13 +270,14 @@ static void xive2_end_enqueue(Xive2End *end, uint32_t data)
>    *     the NVP by changing the H bit while the context is enabled
>    */
>   
> -static void xive2_tctx_save_os_ctx(Xive2Router *xrtr, XiveTCTX *tctx,
> -                                   uint8_t nvp_blk, uint32_t nvp_idx)
> +static void xive2_tctx_save_ctx(Xive2Router *xrtr, XiveTCTX *tctx,
> +                                uint8_t nvp_blk, uint32_t nvp_idx,
> +                                uint8_t ring)
>   {
>       CPUPPCState *env = &POWERPC_CPU(tctx->cs)->env;
>       uint32_t pir = env->spr_cb[SPR_PIR].default_value;
>       Xive2Nvp nvp;
> -    uint8_t *regs = &tctx->regs[TM_QW1_OS];
> +    uint8_t *regs = &tctx->regs[ring];
>   
>       if (xive2_router_get_nvp(xrtr, nvp_blk, nvp_idx, &nvp)) {
>           qemu_log_mask(LOG_GUEST_ERROR, "XIVE: No NVP %x/%x\n",
> @@ -321,13 +322,13 @@ static void xive2_tctx_save_os_ctx(Xive2Router *xrtr, XiveTCTX *tctx,
>       xive2_router_write_nvp(xrtr, nvp_blk, nvp_idx, &nvp, 1);
>   }
>   
> -static void xive2_os_cam_decode(uint32_t cam, uint8_t *nvp_blk,
> -                                uint32_t *nvp_idx, bool *vo, bool *ho)
> +static void xive2_cam_decode(uint32_t cam, uint8_t *nvp_blk,
> +                             uint32_t *nvp_idx, bool *valid, bool *hw)
>   {
>       *nvp_blk = xive2_nvp_blk(cam);
>       *nvp_idx = xive2_nvp_idx(cam);
> -    *vo = !!(cam & TM2_QW1W2_VO);
> -    *ho = !!(cam & TM2_QW1W2_HO);
> +    *valid = !!(cam & TM2_QW1W2_VO);
> +    *hw = !!(cam & TM2_QW1W2_HO);
>   }
>   
>   
> @@ -351,37 +352,54 @@ static uint32_t xive2_tctx_hw_cam_line(XivePresenter *xptr, XiveTCTX *tctx)
>       return xive2_nvp_cam_line(blk, 1 << tid_shift | (pir & tid_mask));
>   }
>   
> -uint64_t xive2_tm_pull_os_ctx(XivePresenter *xptr, XiveTCTX *tctx,
> -                              hwaddr offset, unsigned size)
> +static uint64_t xive2_tm_pull_ctx(XivePresenter *xptr, XiveTCTX *tctx,
> +                                  hwaddr offset, unsigned size, uint8_t ring)

The changes below are not strictly adding a ring parameter. Some belong
to another patch.


Thanks,

C.



>   {
>       Xive2Router *xrtr = XIVE2_ROUTER(xptr);
> -    uint32_t qw1w2 = xive_tctx_word2(&tctx->regs[TM_QW1_OS]);
> -    uint32_t qw1w2_new;
> -    uint32_t cam = be32_to_cpu(qw1w2);
> +    uint32_t target_ringw2 = xive_tctx_word2(&tctx->regs[ring]);
> +    uint32_t cam = be32_to_cpu(target_ringw2);
>       uint8_t nvp_blk;
>       uint32_t nvp_idx;
> -    bool vo;
> +    uint8_t cur_ring;
> +    bool valid;
>       bool do_save;
>   
> -    xive2_os_cam_decode(cam, &nvp_blk, &nvp_idx, &vo, &do_save);
> +    xive2_cam_decode(cam, &nvp_blk, &nvp_idx, &valid, &do_save);
>   
> -    if (!vo) {
> +    if (!valid) {
>           qemu_log_mask(LOG_GUEST_ERROR, "XIVE: pulling invalid NVP %x/%x !?\n",
>                         nvp_blk, nvp_idx);
>       }
>   
> -    /* Invalidate CAM line */
> -    qw1w2_new = xive_set_field32(TM2_QW1W2_VO, qw1w2, 0);
> -    memcpy(&tctx->regs[TM_QW1_OS + TM_WORD2], &qw1w2_new, 4);
> +    /* Invalidate CAM line of requested ring and all lower rings */
> +    for (cur_ring = TM_QW0_USER; cur_ring <= ring;
> +         cur_ring += XIVE_TM_RING_SIZE) {
> +        uint32_t ringw2 = xive_tctx_word2(&tctx->regs[cur_ring]);
> +        uint32_t ringw2_new = xive_set_field32(TM2_QW1W2_VO, ringw2, 0);
> +        memcpy(&tctx->regs[cur_ring + TM_WORD2], &ringw2_new, 4);
> +    }
>   
>       if (xive2_router_get_config(xrtr) & XIVE2_VP_SAVE_RESTORE && do_save) {
> -        xive2_tctx_save_os_ctx(xrtr, tctx, nvp_blk, nvp_idx);
> +        xive2_tctx_save_ctx(xrtr, tctx, nvp_blk, nvp_idx, ring);
>       }
>   
> -    xive_tctx_reset_os_signal(tctx);
> -    return qw1w2;
> +    /*
> +     * Lower external interrupt line of requested ring and below except for
> +     * USER, which doesn't exist.
> +     */
> +    for (cur_ring = TM_QW1_OS; cur_ring <= ring;
> +         cur_ring += XIVE_TM_RING_SIZE) {
> +        xive_tctx_reset_signal(tctx, cur_ring);
> +    }
> +    return target_ringw2;
>   }
>   
> +uint64_t xive2_tm_pull_os_ctx(XivePresenter *xptr, XiveTCTX *tctx,
> +                              hwaddr offset, unsigned size)
> +{
> +    return xive2_tm_pull_ctx(xptr, tctx, offset, size, TM_QW1_OS);
> + }
> +
>   #define REPORT_LINE_GEN1_SIZE       16
>   
>   static void xive2_tm_report_line_gen1(XiveTCTX *tctx, uint8_t *data,
> @@ -424,8 +442,9 @@ static void xive2_tm_report_line_gen1(XiveTCTX *tctx, uint8_t *data,
>       }
>   }
>   
> -void xive2_tm_pull_os_ctx_ol(XivePresenter *xptr, XiveTCTX *tctx,
> -                             hwaddr offset, uint64_t value, unsigned size)
> +static void xive2_tm_pull_ctx_ol(XivePresenter *xptr, XiveTCTX *tctx,
> +                                 hwaddr offset, uint64_t value,
> +                                 unsigned size, uint8_t ring)
>   {
>       Xive2Router *xrtr = XIVE2_ROUTER(xptr);
>       uint32_t hw_cam, nvp_idx, xive2_cfg, reserved;
> @@ -473,8 +492,14 @@ void xive2_tm_pull_os_ctx_ol(XivePresenter *xptr, XiveTCTX *tctx,
>           assert(result == MEMTX_OK);
>       }
>   
> -    /* the rest is similar to pull OS context to registers */
> -    xive2_tm_pull_os_ctx(xptr, tctx, offset, size);
> +    /* the rest is similar to pull context to registers */
> +    xive2_tm_pull_ctx(xptr, tctx, offset, size, ring);
> +}
> +
> +void xive2_tm_pull_os_ctx_ol(XivePresenter *xptr, XiveTCTX *tctx,
> +                             hwaddr offset, uint64_t value, unsigned size)
> +{
> +    xive2_tm_pull_ctx_ol(xptr, tctx, offset, value, size, TM_QW1_OS);
>   }
>   
>   static uint8_t xive2_tctx_restore_os_ctx(Xive2Router *xrtr, XiveTCTX *tctx,
> @@ -573,7 +598,7 @@ void xive2_tm_push_os_ctx(XivePresenter *xptr, XiveTCTX *tctx,
>       bool vo;
>       bool do_restore;
>   
> -    xive2_os_cam_decode(cam, &nvp_blk, &nvp_idx, &vo, &do_restore);
> +    xive2_cam_decode(cam, &nvp_blk, &nvp_idx, &vo, &do_restore);
>   
>       /* First update the thead context */
>       memcpy(&tctx->regs[TM_QW1_OS + TM_WORD2], &qw1w2, 4);



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 09/14] ppc/xive2: Change context/ring specific functions to be generic
  2024-09-12  6:27   ` Cédric Le Goater
@ 2024-09-12 16:41     ` Mike Kowal
  0 siblings, 0 replies; 23+ messages in thread
From: Mike Kowal @ 2024-09-12 16:41 UTC (permalink / raw)
  To: Cédric Le Goater, qemu-devel; +Cc: qemu-ppc, fbarrat, npiggin, milesg


On 9/12/2024 1:27 AM, Cédric Le Goater wrote:
> On 9/9/24 23:10, Michael Kowal wrote:
>> Some the functions that have been created are specific to a ring or 
>> context. Some
>> of these same functions are being changed to operate on any 
>> ring/context. This  will
>> simplify the next patch sets that are adding additional ring/context 
>> operations.
>>
>> Signed-off-by: Michael Kowal <kowal@linux.ibm.com>
>> ---
>>   include/hw/ppc/xive.h |  2 +-
>>   hw/intc/xive.c        |  6 ++--
>>   hw/intc/xive2.c       | 77 ++++++++++++++++++++++++++++---------------
>>   3 files changed, 55 insertions(+), 30 deletions(-)
>>
>> diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
>> index 28c181faa2..31242f0406 100644
>> --- a/include/hw/ppc/xive.h
>> +++ b/include/hw/ppc/xive.h
>> @@ -533,7 +533,7 @@ Object *xive_tctx_create(Object *cpu, 
>> XivePresenter *xptr, Error **errp);
>>   void xive_tctx_reset(XiveTCTX *tctx);
>>   void xive_tctx_destroy(XiveTCTX *tctx);
>>   void xive_tctx_ipb_update(XiveTCTX *tctx, uint8_t ring, uint8_t ipb);
>> -void xive_tctx_reset_os_signal(XiveTCTX *tctx);
>> +void xive_tctx_reset_signal(XiveTCTX *tctx, uint8_t ring);
>>     /*
>>    * KVM XIVE device helpers
>> diff --git a/hw/intc/xive.c b/hw/intc/xive.c
>> index 5b66a3aec5..f1d007d9a6 100644
>> --- a/hw/intc/xive.c
>> +++ b/hw/intc/xive.c
>> @@ -114,7 +114,7 @@ static void xive_tctx_notify(XiveTCTX *tctx, 
>> uint8_t ring)
>>       }
>>   }
>>   -void xive_tctx_reset_os_signal(XiveTCTX *tctx)
>> +void xive_tctx_reset_signal(XiveTCTX *tctx, uint8_t ring)
>>   {
>>       /*
>>        * Lower the External interrupt. Used when pulling an OS
>> @@ -122,7 +122,7 @@ void xive_tctx_reset_os_signal(XiveTCTX *tctx)
>>        * context. It should be raised again when re-pushing the OS
>>        * context.
>>        */
>> -    qemu_irq_lower(xive_tctx_output(tctx, TM_QW1_OS));
>> +    qemu_irq_lower(xive_tctx_output(tctx, ring));
>>   }
>>     static void xive_tctx_set_cppr(XiveTCTX *tctx, uint8_t ring, 
>> uint8_t cppr)
>> @@ -424,7 +424,7 @@ static uint64_t xive_tm_pull_os_ctx(XivePresenter 
>> *xptr, XiveTCTX *tctx,
>>       qw1w2_new = xive_set_field32(TM_QW1W2_VO, qw1w2, 0);
>>       xive_tctx_set_os_cam(tctx, qw1w2_new);
>>   -    xive_tctx_reset_os_signal(tctx);
>> +    xive_tctx_reset_signal(tctx, TM_QW1_OS);
>>       return qw1w2;
>>   }
>>   diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c
>> index 8d3d69a0db..38a4b0ff68 100644
>> --- a/hw/intc/xive2.c
>> +++ b/hw/intc/xive2.c
>> @@ -270,13 +270,14 @@ static void xive2_end_enqueue(Xive2End *end, 
>> uint32_t data)
>>    *     the NVP by changing the H bit while the context is enabled
>>    */
>>   -static void xive2_tctx_save_os_ctx(Xive2Router *xrtr, XiveTCTX *tctx,
>> -                                   uint8_t nvp_blk, uint32_t nvp_idx)
>> +static void xive2_tctx_save_ctx(Xive2Router *xrtr, XiveTCTX *tctx,
>> +                                uint8_t nvp_blk, uint32_t nvp_idx,
>> +                                uint8_t ring)
>>   {
>>       CPUPPCState *env = &POWERPC_CPU(tctx->cs)->env;
>>       uint32_t pir = env->spr_cb[SPR_PIR].default_value;
>>       Xive2Nvp nvp;
>> -    uint8_t *regs = &tctx->regs[TM_QW1_OS];
>> +    uint8_t *regs = &tctx->regs[ring];
>>         if (xive2_router_get_nvp(xrtr, nvp_blk, nvp_idx, &nvp)) {
>>           qemu_log_mask(LOG_GUEST_ERROR, "XIVE: No NVP %x/%x\n",
>> @@ -321,13 +322,13 @@ static void xive2_tctx_save_os_ctx(Xive2Router 
>> *xrtr, XiveTCTX *tctx,
>>       xive2_router_write_nvp(xrtr, nvp_blk, nvp_idx, &nvp, 1);
>>   }
>>   -static void xive2_os_cam_decode(uint32_t cam, uint8_t *nvp_blk,
>> -                                uint32_t *nvp_idx, bool *vo, bool *ho)
>> +static void xive2_cam_decode(uint32_t cam, uint8_t *nvp_blk,
>> +                             uint32_t *nvp_idx, bool *valid, bool *hw)
>>   {
>>       *nvp_blk = xive2_nvp_blk(cam);
>>       *nvp_idx = xive2_nvp_idx(cam);
>> -    *vo = !!(cam & TM2_QW1W2_VO);
>> -    *ho = !!(cam & TM2_QW1W2_HO);
>> +    *valid = !!(cam & TM2_QW1W2_VO);
>> +    *hw = !!(cam & TM2_QW1W2_HO);
>>   }
>>     @@ -351,37 +352,54 @@ static uint32_t 
>> xive2_tctx_hw_cam_line(XivePresenter *xptr, XiveTCTX *tctx)
>>       return xive2_nvp_cam_line(blk, 1 << tid_shift | (pir & tid_mask));
>>   }
>>   -uint64_t xive2_tm_pull_os_ctx(XivePresenter *xptr, XiveTCTX *tctx,
>> -                              hwaddr offset, unsigned size)
>> +static uint64_t xive2_tm_pull_ctx(XivePresenter *xptr, XiveTCTX *tctx,
>> +                                  hwaddr offset, unsigned size, 
>> uint8_t ring)
>
> The changes below are not strictly adding a ring parameter. Some belong
> to another patch.
>
>
> Thanks,
>
> C.
>
The two patch sets go together and the functions added the ring parm so 
I included those changes here.   I can move some of the changes from 
here to patch set 10.

MAK


>
>>   {
>>       Xive2Router *xrtr = XIVE2_ROUTER(xptr);
>> -    uint32_t qw1w2 = xive_tctx_word2(&tctx->regs[TM_QW1_OS]);
>> -    uint32_t qw1w2_new;
>> -    uint32_t cam = be32_to_cpu(qw1w2);
>> +    uint32_t target_ringw2 = xive_tctx_word2(&tctx->regs[ring]);
>> +    uint32_t cam = be32_to_cpu(target_ringw2);
>>       uint8_t nvp_blk;
>>       uint32_t nvp_idx;
>> -    bool vo;
>> +    uint8_t cur_ring;
>> +    bool valid;
>>       bool do_save;
>>   -    xive2_os_cam_decode(cam, &nvp_blk, &nvp_idx, &vo, &do_save);
>> +    xive2_cam_decode(cam, &nvp_blk, &nvp_idx, &valid, &do_save);
>>   -    if (!vo) {
>> +    if (!valid) {
>>           qemu_log_mask(LOG_GUEST_ERROR, "XIVE: pulling invalid NVP 
>> %x/%x !?\n",
>>                         nvp_blk, nvp_idx);
>>       }
>>   -    /* Invalidate CAM line */
>> -    qw1w2_new = xive_set_field32(TM2_QW1W2_VO, qw1w2, 0);
>> -    memcpy(&tctx->regs[TM_QW1_OS + TM_WORD2], &qw1w2_new, 4);
>> +    /* Invalidate CAM line of requested ring and all lower rings */
>> +    for (cur_ring = TM_QW0_USER; cur_ring <= ring;
>> +         cur_ring += XIVE_TM_RING_SIZE) {
>> +        uint32_t ringw2 = xive_tctx_word2(&tctx->regs[cur_ring]);
>> +        uint32_t ringw2_new = xive_set_field32(TM2_QW1W2_VO, ringw2, 
>> 0);
>> +        memcpy(&tctx->regs[cur_ring + TM_WORD2], &ringw2_new, 4);
>> +    }
>>         if (xive2_router_get_config(xrtr) & XIVE2_VP_SAVE_RESTORE && 
>> do_save) {
>> -        xive2_tctx_save_os_ctx(xrtr, tctx, nvp_blk, nvp_idx);
>> +        xive2_tctx_save_ctx(xrtr, tctx, nvp_blk, nvp_idx, ring);
>>       }
>>   -    xive_tctx_reset_os_signal(tctx);
>> -    return qw1w2;
>> +    /*
>> +     * Lower external interrupt line of requested ring and below 
>> except for
>> +     * USER, which doesn't exist.
>> +     */
>> +    for (cur_ring = TM_QW1_OS; cur_ring <= ring;
>> +         cur_ring += XIVE_TM_RING_SIZE) {
>> +        xive_tctx_reset_signal(tctx, cur_ring);
>> +    }
>> +    return target_ringw2;
>>   }
>>   +uint64_t xive2_tm_pull_os_ctx(XivePresenter *xptr, XiveTCTX *tctx,
>> +                              hwaddr offset, unsigned size)
>> +{
>> +    return xive2_tm_pull_ctx(xptr, tctx, offset, size, TM_QW1_OS);
>> + }
>> +
>>   #define REPORT_LINE_GEN1_SIZE       16
>>     static void xive2_tm_report_line_gen1(XiveTCTX *tctx, uint8_t *data,
>> @@ -424,8 +442,9 @@ static void xive2_tm_report_line_gen1(XiveTCTX 
>> *tctx, uint8_t *data,
>>       }
>>   }
>>   -void xive2_tm_pull_os_ctx_ol(XivePresenter *xptr, XiveTCTX *tctx,
>> -                             hwaddr offset, uint64_t value, unsigned 
>> size)
>> +static void xive2_tm_pull_ctx_ol(XivePresenter *xptr, XiveTCTX *tctx,
>> +                                 hwaddr offset, uint64_t value,
>> +                                 unsigned size, uint8_t ring)
>>   {
>>       Xive2Router *xrtr = XIVE2_ROUTER(xptr);
>>       uint32_t hw_cam, nvp_idx, xive2_cfg, reserved;
>> @@ -473,8 +492,14 @@ void xive2_tm_pull_os_ctx_ol(XivePresenter 
>> *xptr, XiveTCTX *tctx,
>>           assert(result == MEMTX_OK);
>>       }
>>   -    /* the rest is similar to pull OS context to registers */
>> -    xive2_tm_pull_os_ctx(xptr, tctx, offset, size);
>> +    /* the rest is similar to pull context to registers */
>> +    xive2_tm_pull_ctx(xptr, tctx, offset, size, ring);
>> +}
>> +
>> +void xive2_tm_pull_os_ctx_ol(XivePresenter *xptr, XiveTCTX *tctx,
>> +                             hwaddr offset, uint64_t value, unsigned 
>> size)
>> +{
>> +    xive2_tm_pull_ctx_ol(xptr, tctx, offset, value, size, TM_QW1_OS);
>>   }
>>     static uint8_t xive2_tctx_restore_os_ctx(Xive2Router *xrtr, 
>> XiveTCTX *tctx,
>> @@ -573,7 +598,7 @@ void xive2_tm_push_os_ctx(XivePresenter *xptr, 
>> XiveTCTX *tctx,
>>       bool vo;
>>       bool do_restore;
>>   -    xive2_os_cam_decode(cam, &nvp_blk, &nvp_idx, &vo, &do_restore);
>> +    xive2_cam_decode(cam, &nvp_blk, &nvp_idx, &vo, &do_restore);
>>         /* First update the thead context */
>>       memcpy(&tctx->regs[TM_QW1_OS + TM_WORD2], &qw1w2, 4);
>


^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2024-09-12 16:42 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-09-09 21:10 [PATCH v2 00/14] XIVE2 changes for TIMA operations Michael Kowal
2024-09-09 21:10 ` [PATCH v2 01/14] pnv/xive: TIMA patch sets pre-req alignment and formatting changes Michael Kowal
2024-09-09 21:10 ` [PATCH v2 02/14] pnv/xive2: Define OGEN field in the TIMA Michael Kowal
2024-09-09 21:10 ` [PATCH v2 03/14] ppc/xive2: Support TIMA "Pull OS Context to Odd Thread Reporting Line" Michael Kowal
2024-09-10 17:21   ` Cédric Le Goater
2024-09-09 21:10 ` [PATCH v2 04/14] pnv/xive2: Support for "OS LGS Push" TIMA operation Michael Kowal
2024-09-09 21:10 ` [PATCH v2 05/14] ppc/xive2: Dump more NVP state with 'info pic' Michael Kowal
2024-09-10 17:23   ` Cédric Le Goater
2024-09-09 21:10 ` [PATCH v2 06/14] ppc/xive2: Dump the VP-group and crowd tables " Michael Kowal
2024-09-10 17:25   ` Cédric Le Goater
2024-09-09 21:10 ` [PATCH v2 07/14] ppc/xive2: Allow 1-byte write of Target field in TIMA Michael Kowal
2024-09-09 21:10 ` [PATCH v2 08/14] ppc/xive2: Support "Pull Thread Context to Register" operation Michael Kowal
2024-09-09 21:10 ` [PATCH v2 09/14] ppc/xive2: Change context/ring specific functions to be generic Michael Kowal
2024-09-12  6:27   ` Cédric Le Goater
2024-09-12 16:41     ` Mike Kowal
2024-09-09 21:10 ` [PATCH v2 10/14] ppc/xive2: Support "Pull Thread Context to Odd Thread Reporting Line" Michael Kowal
2024-09-12  6:24   ` Cédric Le Goater
2024-09-09 21:10 ` [PATCH v2 11/14] pnv/xive: Add special handling for pool targets Michael Kowal
2024-09-10 17:32   ` Cédric Le Goater
2024-09-09 21:10 ` [PATCH v2 12/14] pnv/xive: Update PIPR when updating CPPR Michael Kowal
2024-09-10 17:30   ` Cédric Le Goater
2024-09-09 21:10 ` [PATCH v2 13/14] pnv/xive2: TIMA support for 8-byte OS context push for PHYP Michael Kowal
2024-09-09 21:10 ` [PATCH v2 14/14] pnv/xive2: TIMA CI ops using alternative offsets or byte lengths Michael Kowal

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).