All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v3 00/18] ppc/pnv: add XIVE support for KVM guests
@ 2019-07-31 14:12 Cédric Le Goater
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 01/18] ppc/pnv: Introduce PowerNV machines with fixed CPU models Cédric Le Goater
                   ` (18 more replies)
  0 siblings, 19 replies; 26+ messages in thread
From: Cédric Le Goater @ 2019-07-31 14:12 UTC (permalink / raw)
  To: David Gibson; +Cc: Cédric Le Goater, qemu-ppc, Greg Kurz, qemu-devel

Hello,

The QEMU PowerNV machine emulates a baremetal OpenPOWER system and
acts as an hypervisor (L0). Supporting emulation of KVM to run guests
(L1) requires a few more extensions, among which guest support for the
XIVE interrupt controller on POWER9 processor.

The following changes add new per-CPU PowerNV machines and extend the
XIVE models with the new XiveFabric and XivePresenter interfaces to
provide support for XIVE escalations and interrupt resend. This
mechanism is used by XIVE to notify the hypervisor that a vCPU is not
dispatched on a HW thread. Tested on a QEMU PowerNV machine and a
simple QEMU pseries guest doing network on a local bridge.

The XIVE interrupt controller offers a way to increase the XIVE
resources per chip by configuring multiple XIVE blocks on a chip. This
is not currently supported by the model. However, some configurations,
such as OPAL/skiboot, use one block-per-chip configuration with some
optimizations. One of them is to override the hardwired chip ID by the
block id in the PowerBUS operations and for CAM line compares. This
patchset improves the support for this setup. Tested with 4 chips.

A series from Suraj adding guest support in the Radix MMU model of the
QEMU PowerNV machine is still required and will be send later. The
whole patchset can be found under :

  https://github.com/legoater/qemu/tree/powernv-4.1

Thanks,

C.

Changes since v2:

 - introduced the XiveFabric and XivePresenter interfaces
 - removed the need of a XiveRouter pointer under XiveTCTX

Changes since v1:

 - minor extra fixes 
 - split the escalation support in different patches
 - kept the XiveRouter type for XiveTCTX back pointer (will address
   this in P10)
 - removed pnv_xive_vst_size(). Really broken on indirect tables.
 - improved the dump of the NVT table
 - introduce pnv_xive_get_block_id()


Cédric Le Goater (18):
  ppc/pnv: Introduce PowerNV machines with fixed CPU models
  tests/boot-serial-test: add support for all the PowerNV machines
  ppc/xive: Introduce the XiveFabric and XivePresenter interfaces
  ppc/pnv: Implement the XiveFabric and XivePresenter interfaces
  ppc/spapr: Implement the XiveFabric and XivePresenter interfaces
  ppc/xive: Use the XiveFabric and XivePresenter interfaces
  ppc/xive: Extend the TIMA operation with a XivePresenter parameter
  ppc/pnv: Clarify how the TIMA is accessed on a multichip system
  ppc/xive: Move the TIMA operations to the controller model
  ppc/xive: Introduce a xive_tctx_ipb_update() helper
  ppc/xive: Synthesize interrupt from the saved IPB in the NVT
  ppc/pnv: Remove pnv_xive_vst_size() routine
  ppc/pnv: Dump the XIVE NVT table
  ppc/pnv: Skip empty slots of the XIVE NVT table
  ppc/pnv: Introduce a pnv_xive_block_id() helper
  ppc/pnv: Extend XivePresenter with a get_block_id() handler
  ppc/pnv: Quiesce some XIVE errors
  ppc/xive: Introduce a xive_os_cam_decode() helper

 include/hw/ppc/pnv.h       |  13 ++
 include/hw/ppc/pnv_xive.h  |   3 -
 include/hw/ppc/spapr_irq.h |   6 +
 include/hw/ppc/xive.h      |  71 ++++++--
 include/hw/ppc/xive_regs.h |  24 +++
 hw/intc/pnv_xive.c         | 356 ++++++++++++++++++++++++-------------
 hw/intc/spapr_xive.c       |  80 ++++++++-
 hw/intc/xive.c             | 319 ++++++++++++++++++---------------
 hw/ppc/pnv.c               | 102 ++++++++++-
 hw/ppc/spapr.c             |  34 ++++
 hw/ppc/spapr_irq.c         |  25 +++
 tests/boot-serial-test.c   |   3 +-
 12 files changed, 743 insertions(+), 293 deletions(-)

-- 
2.21.0



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

* [Qemu-devel] [PATCH v3 01/18] ppc/pnv: Introduce PowerNV machines with fixed CPU models
  2019-07-31 14:12 [Qemu-devel] [PATCH v3 00/18] ppc/pnv: add XIVE support for KVM guests Cédric Le Goater
@ 2019-07-31 14:12 ` Cédric Le Goater
  2019-08-05 10:46   ` David Gibson
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 02/18] tests/boot-serial-test: add support for all the PowerNV machines Cédric Le Goater
                   ` (17 subsequent siblings)
  18 siblings, 1 reply; 26+ messages in thread
From: Cédric Le Goater @ 2019-07-31 14:12 UTC (permalink / raw)
  To: David Gibson; +Cc: Cédric Le Goater, qemu-ppc, Greg Kurz, qemu-devel

Make the current "powernv" machine an abstract type and derive from it
new machines with specific CPU models: power8 and power9.

The "powernv" machine is now an alias on the "powernv9" machine.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/ppc/pnv.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 63 insertions(+), 7 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 4570ce8afe6a..18602b9e9bcd 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -602,9 +602,20 @@ static void pnv_chip_power9_pic_print_info(PnvChip *chip, Monitor *mon)
     pnv_psi_pic_print_info(&chip9->psi, mon);
 }
 
+static bool pnv_match_cpu(const char *default_type, const char *cpu_type)
+{
+    PowerPCCPUClass *ppc_default =
+        POWERPC_CPU_CLASS(object_class_by_name(default_type));
+    PowerPCCPUClass *ppc =
+        POWERPC_CPU_CLASS(object_class_by_name(cpu_type));
+
+    return ppc_default->pvr_match(ppc_default, ppc->pvr);
+}
+
 static void pnv_init(MachineState *machine)
 {
     PnvMachineState *pnv = PNV_MACHINE(machine);
+    MachineClass *mc = MACHINE_GET_CLASS(machine);
     MemoryRegion *ram;
     char *fw_filename;
     long fw_size;
@@ -664,13 +675,23 @@ static void pnv_init(MachineState *machine)
         }
     }
 
+    /*
+     * Check compatibility of the specified CPU with the machine
+     * default.
+     */
+    if (!pnv_match_cpu(mc->default_cpu_type, machine->cpu_type)) {
+        error_report("invalid CPU model '%s' for %s machine",
+                     machine->cpu_type, mc->name);
+        exit(1);
+    }
+
     /* Create the processor chips */
     i = strlen(machine->cpu_type) - strlen(POWERPC_CPU_TYPE_SUFFIX);
     chip_typename = g_strdup_printf(PNV_CHIP_TYPE_NAME("%.*s"),
                                     i, machine->cpu_type);
     if (!object_class_by_name(chip_typename)) {
-        error_report("invalid CPU model '%.*s' for %s machine",
-                     i, machine->cpu_type, MACHINE_GET_CLASS(machine)->name);
+        error_report("invalid chip model '%.*s' for %s machine",
+                     i, machine->cpu_type, mc->name);
         exit(1);
     }
 
@@ -1348,25 +1369,43 @@ static void pnv_machine_class_props_init(ObjectClass *oc)
                               NULL);
 }
 
-static void pnv_machine_class_init(ObjectClass *oc, void *data)
+static void pnv_machine_power8_class_init(ObjectClass *oc, void *data)
 {
     MachineClass *mc = MACHINE_CLASS(oc);
     XICSFabricClass *xic = XICS_FABRIC_CLASS(oc);
+
+    mc->desc = "IBM PowerNV (Non-Virtualized) POWER8";
+    mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power8_v2.0");
+
+    xic->icp_get = pnv_icp_get;
+    xic->ics_get = pnv_ics_get;
+    xic->ics_resend = pnv_ics_resend;
+}
+
+static void pnv_machine_power9_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+
+    mc->desc = "IBM PowerNV (Non-Virtualized) POWER9";
+    mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power9_v2.0");
+
+    mc->alias = "powernv";
+}
+
+static void pnv_machine_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
     InterruptStatsProviderClass *ispc = INTERRUPT_STATS_PROVIDER_CLASS(oc);
 
     mc->desc = "IBM PowerNV (Non-Virtualized)";
     mc->init = pnv_init;
     mc->reset = pnv_reset;
     mc->max_cpus = MAX_CPUS;
-    mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power8_v2.0");
     mc->block_default_type = IF_IDE; /* Pnv provides a AHCI device for
                                       * storage */
     mc->no_parallel = 1;
     mc->default_boot_order = NULL;
     mc->default_ram_size = 2 * GiB;
-    xic->icp_get = pnv_icp_get;
-    xic->ics_get = pnv_ics_get;
-    xic->ics_resend = pnv_ics_resend;
     ispc->print_info = pnv_pic_print_info;
 
     pnv_machine_class_props_init(oc);
@@ -1386,10 +1425,27 @@ static void pnv_machine_class_init(ObjectClass *oc, void *data)
         .parent        = TYPE_PNV9_CHIP,          \
     }
 
+#define DEFINE_PNV_MACHINE_TYPE(cpu, class_initfn)      \
+    {                                                   \
+        .name          = MACHINE_TYPE_NAME(cpu),        \
+        .parent        = TYPE_PNV_MACHINE,              \
+        .instance_size = sizeof(PnvMachineState),       \
+        .instance_init = pnv_machine_instance_init,     \
+        .class_init    = class_initfn,                  \
+        .interfaces = (InterfaceInfo[]) {               \
+            { TYPE_XICS_FABRIC },                       \
+            { TYPE_INTERRUPT_STATS_PROVIDER },          \
+            { },                                        \
+        },                                              \
+    }
+
 static const TypeInfo types[] = {
+    DEFINE_PNV_MACHINE_TYPE("powernv8", pnv_machine_power8_class_init),
+    DEFINE_PNV_MACHINE_TYPE("powernv9", pnv_machine_power9_class_init),
     {
         .name          = TYPE_PNV_MACHINE,
         .parent        = TYPE_MACHINE,
+        .abstract       = true,
         .instance_size = sizeof(PnvMachineState),
         .instance_init = pnv_machine_instance_init,
         .class_init    = pnv_machine_class_init,
-- 
2.21.0



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

* [Qemu-devel] [PATCH v3 02/18] tests/boot-serial-test: add support for all the PowerNV machines
  2019-07-31 14:12 [Qemu-devel] [PATCH v3 00/18] ppc/pnv: add XIVE support for KVM guests Cédric Le Goater
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 01/18] ppc/pnv: Introduce PowerNV machines with fixed CPU models Cédric Le Goater
@ 2019-07-31 14:12 ` Cédric Le Goater
  2019-08-05 12:30   ` David Gibson
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 03/18] ppc/xive: Introduce the XiveFabric and XivePresenter interfaces Cédric Le Goater
                   ` (16 subsequent siblings)
  18 siblings, 1 reply; 26+ messages in thread
From: Cédric Le Goater @ 2019-07-31 14:12 UTC (permalink / raw)
  To: David Gibson; +Cc: Cédric Le Goater, qemu-ppc, Greg Kurz, qemu-devel

Use the machine names specifiying the CPU type, POWER8 and POWER9.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 tests/boot-serial-test.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tests/boot-serial-test.c b/tests/boot-serial-test.c
index 24852d4c7d0b..a54d007298f7 100644
--- a/tests/boot-serial-test.c
+++ b/tests/boot-serial-test.c
@@ -103,7 +103,8 @@ static testdef_t tests[] = {
     { "ppc64", "pseries",
       "-machine cap-cfpc=broken,cap-sbbc=broken,cap-ibs=broken",
       "Open Firmware" },
-    { "ppc64", "powernv", "-cpu POWER8", "OPAL" },
+    { "ppc64", "powernv8", "", "OPAL" },
+    { "ppc64", "powernv9", "", "OPAL" },
     { "ppc64", "sam460ex", "-device e1000", "8086  100e" },
     { "i386", "isapc", "-cpu qemu32 -device sga", "SGABIOS" },
     { "i386", "pc", "-device sga", "SGABIOS" },
-- 
2.21.0



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

* [Qemu-devel] [PATCH v3 03/18] ppc/xive: Introduce the XiveFabric and XivePresenter interfaces
  2019-07-31 14:12 [Qemu-devel] [PATCH v3 00/18] ppc/pnv: add XIVE support for KVM guests Cédric Le Goater
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 01/18] ppc/pnv: Introduce PowerNV machines with fixed CPU models Cédric Le Goater
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 02/18] tests/boot-serial-test: add support for all the PowerNV machines Cédric Le Goater
@ 2019-07-31 14:12 ` Cédric Le Goater
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 04/18] ppc/pnv: Implement " Cédric Le Goater
                   ` (15 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Cédric Le Goater @ 2019-07-31 14:12 UTC (permalink / raw)
  To: David Gibson; +Cc: Cédric Le Goater, qemu-ppc, Greg Kurz, qemu-devel

When the XIVE IVRE sub-engine (XiveRouter) looks for a Notification
Virtual Target (NVT) to notify, it broadcasts a message on the
PowerBUS to find an XIVE IVPE sub-engine (Presenter) which has the NVT
dispatched on one of its HW threads, and then forwards the
notification if any response was received.

The current XIVE presenter model is sufficient for the pseries machine
because it has a single interrupt controller device, but the PowerNV
machine can have multiple chips each having its own interrupt
controller. In this case, the XIVE presenter model is too simple and
the CAM line matching should scan all chips of the system.

We introduce a XiveFabric QOM interface which needs to be implemented
by the machine. It acts as the PowerBUS interface between the
interrupt controller and the system. On HW, the XIVE sub-engine
responsible for the communication with the other chip is the Common
Queue (CQ) bridge unit. This interface offers a 'match_nvt' handler to
perform the CAM line matching when looking for a XIVE Presenter with a
dispatched NVT.

We also introduce a XivePresenter QOM interface to represent the XIVE
Presenter (PC) sub-engine of the XIVE controller with a similar
'match_nvt' handler to perform the CAM line matching. This interface
could be merged in the XiveRouter but as it is stateless and performs
the XIVE IVPE sub-engine tasks, it makes sense to keep it independent.
It should have its use in POWER10.

Fixes: af53dbf6227a ("ppc/xive: introduce a simplified XIVE presenter")
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 include/hw/ppc/xive.h | 54 +++++++++++++++++++++++++++++++++++++++++++
 hw/intc/xive.c        | 36 +++++++++++++++++++++--------
 2 files changed, 81 insertions(+), 9 deletions(-)

diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
index 4851ff87e795..165134ce52a5 100644
--- a/include/hw/ppc/xive.h
+++ b/include/hw/ppc/xive.h
@@ -368,6 +368,60 @@ int xive_router_write_nvt(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx,
 XiveTCTX *xive_router_get_tctx(XiveRouter *xrtr, CPUState *cs);
 void xive_router_notify(XiveNotifier *xn, uint32_t lisn);
 
+/*
+ * XIVE Presenter
+ */
+
+typedef struct XiveTCTXMatch {
+    XiveTCTX *tctx;
+    uint8_t ring;
+} XiveTCTXMatch;
+
+typedef struct XivePresenter XivePresenter;
+
+#define TYPE_XIVE_PRESENTER "xive-presenter"
+#define XIVE_PRESENTER(obj)                                     \
+    INTERFACE_CHECK(XivePresenter, (obj), TYPE_XIVE_PRESENTER)
+#define XIVE_PRESENTER_CLASS(klass)                                     \
+    OBJECT_CLASS_CHECK(XivePresenterClass, (klass), TYPE_XIVE_PRESENTER)
+#define XIVE_PRESENTER_GET_CLASS(obj)                                   \
+    OBJECT_GET_CLASS(XivePresenterClass, (obj), TYPE_XIVE_PRESENTER)
+
+typedef struct XivePresenterClass {
+    InterfaceClass parent;
+    int (*match_nvt)(XivePresenter *xptr, uint8_t format,
+                     uint8_t nvt_blk, uint32_t nvt_idx,
+                     bool cam_ignore, uint8_t priority,
+                     uint32_t logic_serv, XiveTCTXMatch *match);
+} XivePresenterClass;
+
+int xive_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx,
+                              uint8_t format,
+                              uint8_t nvt_blk, uint32_t nvt_idx,
+                              bool cam_ignore, uint32_t logic_serv);
+
+/*
+ * XIVE Fabric (Interface between Interrupt Controller and Machine)
+ */
+
+typedef struct XiveFabric XiveFabric;
+
+#define TYPE_XIVE_FABRIC "xive-fabric"
+#define XIVE_FABRIC(obj)                                     \
+    INTERFACE_CHECK(XiveFabric, (obj), TYPE_XIVE_FABRIC)
+#define XIVE_FABRIC_CLASS(klass)                                     \
+    OBJECT_CLASS_CHECK(XiveFabricClass, (klass), TYPE_XIVE_FABRIC)
+#define XIVE_FABRIC_GET_CLASS(obj)                                   \
+    OBJECT_GET_CLASS(XiveFabricClass, (obj), TYPE_XIVE_FABRIC)
+
+typedef struct XiveFabricClass {
+    InterfaceClass parent;
+    int (*match_nvt)(XiveFabric *xfb, uint8_t format,
+                     uint8_t nvt_blk, uint32_t nvt_idx,
+                     bool cam_ignore, uint8_t priority,
+                     uint32_t logic_serv, XiveTCTXMatch *match);
+} XiveFabricClass;
+
 /*
  * XIVE END ESBs
  */
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 88f2e560db0f..4bdedab13047 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -1294,9 +1294,10 @@ static uint32_t xive_tctx_hw_cam_line(XiveTCTX *tctx)
 /*
  * The thread context register words are in big-endian format.
  */
-static int xive_presenter_tctx_match(XiveTCTX *tctx, uint8_t format,
-                                     uint8_t nvt_blk, uint32_t nvt_idx,
-                                     bool cam_ignore, uint32_t logic_serv)
+int xive_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx,
+                              uint8_t format,
+                              uint8_t nvt_blk, uint32_t nvt_idx,
+                              bool cam_ignore, uint32_t logic_serv)
 {
     uint32_t cam = xive_nvt_cam_line(nvt_blk, nvt_idx);
     uint32_t qw3w2 = xive_tctx_word2(&tctx->regs[TM_QW3_HV_PHYS]);
@@ -1353,11 +1354,6 @@ static int xive_presenter_tctx_match(XiveTCTX *tctx, uint8_t format,
     return -1;
 }
 
-typedef struct XiveTCTXMatch {
-    XiveTCTX *tctx;
-    uint8_t ring;
-} XiveTCTXMatch;
-
 static bool xive_presenter_match(XiveRouter *xrtr, uint8_t format,
                                  uint8_t nvt_blk, uint32_t nvt_idx,
                                  bool cam_ignore, uint8_t priority,
@@ -1383,7 +1379,8 @@ static bool xive_presenter_match(XiveRouter *xrtr, uint8_t format,
          * Check the thread context CAM lines and record matches. We
          * will handle CPU exception delivery later
          */
-        ring = xive_presenter_tctx_match(tctx, format, nvt_blk, nvt_idx,
+        ring = xive_presenter_tctx_match(XIVE_PRESENTER(xrtr), tctx, format,
+                                         nvt_blk, nvt_idx,
                                          cam_ignore, logic_serv);
         /*
          * Save the context and follow on to catch duplicates, that we
@@ -1670,6 +1667,7 @@ static const TypeInfo xive_router_info = {
     .class_init    = xive_router_class_init,
     .interfaces    = (InterfaceInfo[]) {
         { TYPE_XIVE_NOTIFIER },
+        { TYPE_XIVE_PRESENTER },
         { }
     }
 };
@@ -1841,10 +1839,30 @@ static const TypeInfo xive_notifier_info = {
     .class_size = sizeof(XiveNotifierClass),
 };
 
+/*
+ * XIVE Presenter
+ */
+static const TypeInfo xive_presenter_info = {
+    .name = TYPE_XIVE_PRESENTER,
+    .parent = TYPE_INTERFACE,
+    .class_size = sizeof(XivePresenterClass),
+};
+
+/*
+ * XIVE Fabric
+ */
+static const TypeInfo xive_fabric_info = {
+    .name = TYPE_XIVE_FABRIC,
+    .parent = TYPE_INTERFACE,
+    .class_size = sizeof(XiveFabricClass),
+};
+
 static void xive_register_types(void)
 {
     type_register_static(&xive_source_info);
     type_register_static(&xive_notifier_info);
+    type_register_static(&xive_presenter_info);
+    type_register_static(&xive_fabric_info);
     type_register_static(&xive_router_info);
     type_register_static(&xive_end_source_info);
     type_register_static(&xive_tctx_info);
-- 
2.21.0



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

* [Qemu-devel] [PATCH v3 04/18] ppc/pnv: Implement the XiveFabric and XivePresenter interfaces
  2019-07-31 14:12 [Qemu-devel] [PATCH v3 00/18] ppc/pnv: add XIVE support for KVM guests Cédric Le Goater
                   ` (2 preceding siblings ...)
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 03/18] ppc/xive: Introduce the XiveFabric and XivePresenter interfaces Cédric Le Goater
@ 2019-07-31 14:12 ` Cédric Le Goater
  2019-07-31 14:21   ` Cédric Le Goater
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 05/18] ppc/spapr: " Cédric Le Goater
                   ` (14 subsequent siblings)
  18 siblings, 1 reply; 26+ messages in thread
From: Cédric Le Goater @ 2019-07-31 14:12 UTC (permalink / raw)
  To: David Gibson; +Cc: Cédric Le Goater, qemu-ppc, Greg Kurz, qemu-devel

The CAM line matching on the PowerNV machine now scans all chips of
the system and all CPUs of a chip to find a dispatched NVT in the
thread contexts.

As there is now easy way to loop on the CPUs belonging to a chip, the
PowerNV handler loops on all CPUs and filter out the external CPUs.

Fixes: af53dbf6227a ("ppc/xive: introduce a simplified XIVE presenter")
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/intc/pnv_xive.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++
 hw/ppc/pnv.c       | 32 +++++++++++++++++++
 2 files changed, 108 insertions(+)

diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
index ff1226485983..183798b81496 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -390,6 +390,80 @@ static int pnv_xive_get_eas(XiveRouter *xrtr, uint8_t blk, uint32_t idx,
     return pnv_xive_vst_read(xive, VST_TSEL_IVT, blk, idx, eas);
 }
 
+static int cpu_pir(PowerPCCPU *cpu)
+{
+    CPUPPCState *env = &cpu->env;
+    return env->spr_cb[SPR_PIR].default_value;
+}
+
+static int cpu_chip_id(PowerPCCPU *cpu)
+{
+    int pir = cpu_pir(cpu);
+    return (pir >> 8) & 0x7f;
+}
+
+static bool pnv_xive_is_cpu_enabled(PnvXive *xive, PowerPCCPU *cpu)
+{
+    int pir = cpu_pir(cpu);
+    int thrd_id = pir & 0x7f;
+
+    return xive->regs[PC_THREAD_EN_REG0 >> 3] & PPC_BIT(thrd_id);
+}
+
+static bool pnv_xive_is_ignored(PnvChip *chip, CPUState *cs)
+{
+    return chip->chip_id != cpu_chip_id(POWERPC_CPU(cs));
+}
+
+#define PNV_CHIP_CPU_FOREACH(chip, cs)                                  \
+    CPU_FOREACH(cs)                                                     \
+        if (pnv_xive_is_ignored(chip, cs)) {} else
+
+static int pnv_xive_match_nvt(XivePresenter *xptr, uint8_t format,
+                              uint8_t nvt_blk, uint32_t nvt_idx,
+                              bool cam_ignore, uint8_t priority,
+                              uint32_t logic_serv, XiveTCTXMatch *match)
+{
+    PnvXive *xive = PNV_XIVE(xptr);
+    CPUState *cs;
+    int count = 0;
+
+    /*
+     * Loop on all CPUs of the machine and filter out the CPUs
+     * belonging to another chip.
+     */
+    PNV_CHIP_CPU_FOREACH(xive->chip, cs) {
+        PowerPCCPU *cpu = POWERPC_CPU(cs);
+        XiveTCTX *tctx = XIVE_TCTX(pnv_cpu_state(cpu)->intc);
+        int ring;
+
+        if (!pnv_xive_is_cpu_enabled(xive, cpu)) {
+            continue;
+        }
+
+        ring = xive_presenter_tctx_match(xptr, tctx, format, nvt_blk, nvt_idx,
+                                         cam_ignore, logic_serv);
+        /*
+         * Save the context and follow on to catch duplicates, that we
+         * don't support yet.
+         */
+        if (ring != -1) {
+            if (match->tctx) {
+                qemu_log_mask(LOG_GUEST_ERROR, "XIVE: already found a "
+                              "thread context NVT %x/%x\n",
+                              nvt_blk, nvt_idx);
+                return -1;
+            }
+
+            match->ring = ring;
+            match->tctx = tctx;
+            count++;
+        }
+    }
+
+    return count;
+}
+
 static XiveTCTX *pnv_xive_get_tctx(XiveRouter *xrtr, CPUState *cs)
 {
     PowerPCCPU *cpu = POWERPC_CPU(cs);
@@ -1795,6 +1869,7 @@ static void pnv_xive_class_init(ObjectClass *klass, void *data)
     PnvXScomInterfaceClass *xdc = PNV_XSCOM_INTERFACE_CLASS(klass);
     XiveRouterClass *xrc = XIVE_ROUTER_CLASS(klass);
     XiveNotifierClass *xnc = XIVE_NOTIFIER_CLASS(klass);
+    XivePresenterClass *xpc = XIVE_PRESENTER_CLASS(klass);
 
     xdc->dt_xscom = pnv_xive_dt_xscom;
 
@@ -1810,6 +1885,7 @@ static void pnv_xive_class_init(ObjectClass *klass, void *data)
     xrc->get_tctx = pnv_xive_get_tctx;
 
     xnc->notify = pnv_xive_notify;
+    xpc->match_nvt  = pnv_xive_match_nvt;
 };
 
 static const TypeInfo pnv_xive_info = {
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 18602b9e9bcd..3f6796831b68 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1322,6 +1322,35 @@ static void pnv_pic_print_info(InterruptStatsProvider *obj,
     }
 }
 
+static int pnv_xive_match_nvt(XiveFabric *xfb, uint8_t format,
+                               uint8_t nvt_blk, uint32_t nvt_idx,
+                               bool cam_ignore, uint8_t priority,
+                               uint32_t logic_serv,
+                               XiveTCTXMatch *match)
+{
+    PnvMachineState *pnv = PNV_MACHINE(xfb);
+    int total_count = 0;
+    int i;
+
+    for (i = 0; i < pnv->num_chips; i++) {
+        Pnv9Chip *chip9 = PNV9_CHIP(pnv->chips[i]);
+        XivePresenter *xptr = XIVE_PRESENTER(&chip9->xive);
+        XivePresenterClass *xpc = XIVE_PRESENTER_GET_CLASS(xptr);
+        int count;
+
+        count = xpc->match_nvt(xptr, format, nvt_blk, nvt_idx, cam_ignore,
+                               priority, logic_serv, match);
+
+        if (count < 0) {
+            return count;
+        }
+
+        total_count += count;
+    }
+
+    return total_count;
+}
+
 static void pnv_get_num_chips(Object *obj, Visitor *v, const char *name,
                               void *opaque, Error **errp)
 {
@@ -1385,9 +1414,11 @@ static void pnv_machine_power8_class_init(ObjectClass *oc, void *data)
 static void pnv_machine_power9_class_init(ObjectClass *oc, void *data)
 {
     MachineClass *mc = MACHINE_CLASS(oc);
+    XiveFabricClass *xfc = XIVE_FABRIC_CLASS(oc);
 
     mc->desc = "IBM PowerNV (Non-Virtualized) POWER9";
     mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power9_v2.0");
+    xfc->match_nvt = pnv_xive_match_nvt;
 
     mc->alias = "powernv";
 }
@@ -1435,6 +1466,7 @@ static void pnv_machine_class_init(ObjectClass *oc, void *data)
         .interfaces = (InterfaceInfo[]) {               \
             { TYPE_XICS_FABRIC },                       \
             { TYPE_INTERRUPT_STATS_PROVIDER },          \
+            { TYPE_XIVE_FABRIC },                       \
             { },                                        \
         },                                              \
     }
-- 
2.21.0



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

* [Qemu-devel] [PATCH v3 05/18] ppc/spapr: Implement the XiveFabric and XivePresenter interfaces
  2019-07-31 14:12 [Qemu-devel] [PATCH v3 00/18] ppc/pnv: add XIVE support for KVM guests Cédric Le Goater
                   ` (3 preceding siblings ...)
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 04/18] ppc/pnv: Implement " Cédric Le Goater
@ 2019-07-31 14:12 ` Cédric Le Goater
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 06/18] ppc/xive: Use " Cédric Le Goater
                   ` (13 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Cédric Le Goater @ 2019-07-31 14:12 UTC (permalink / raw)
  To: David Gibson; +Cc: Cédric Le Goater, qemu-ppc, Greg Kurz, qemu-devel

The CAM line matching sequence in the pseries machine does not change
much apart from the use of the new QOM interfaces.

Fixes: af53dbf6227a ("ppc/xive: introduce a simplified XIVE presenter")
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 include/hw/ppc/spapr_irq.h |  6 ++++++
 hw/intc/spapr_xive.c       | 41 ++++++++++++++++++++++++++++++++++++++
 hw/ppc/spapr.c             | 34 +++++++++++++++++++++++++++++++
 hw/ppc/spapr_irq.c         | 25 +++++++++++++++++++++++
 4 files changed, 106 insertions(+)

diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index f965a58f8954..8c99b0680f97 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -30,6 +30,8 @@ int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align,
 void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, uint32_t num);
 void spapr_irq_msi_reset(SpaprMachineState *spapr);
 
+struct XiveTCTXMatch;
+
 typedef struct SpaprIrq {
     uint32_t    nr_irqs;
     uint32_t    nr_msis;
@@ -49,6 +51,10 @@ typedef struct SpaprIrq {
     void (*set_irq)(void *opaque, int srcno, int val);
     const char *(*get_nodename)(SpaprMachineState *spapr);
     void (*init_kvm)(SpaprMachineState *spapr, Error **errp);
+    int (*match_nvt)(SpaprMachineState *spapr, uint8_t format,
+                     uint8_t nvt_blk, uint32_t nvt_idx,
+                     bool cam_ignore, uint8_t priority,
+                     uint32_t logic_serv, struct XiveTCTXMatch *match);
 } SpaprIrq;
 
 extern SpaprIrq spapr_irq_xics;
diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index ba012c7b0fdc..beb5049ad9da 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -419,6 +419,44 @@ static XiveTCTX *spapr_xive_get_tctx(XiveRouter *xrtr, CPUState *cs)
     return spapr_cpu_state(cpu)->tctx;
 }
 
+static int spapr_xive_match_nvt(XivePresenter *xptr, uint8_t format,
+                                uint8_t nvt_blk, uint32_t nvt_idx,
+                                bool cam_ignore, uint8_t priority,
+                                uint32_t logic_serv, XiveTCTXMatch *match)
+{
+    CPUState *cs;
+    int count = 0;
+
+    CPU_FOREACH(cs) {
+        PowerPCCPU *cpu = POWERPC_CPU(cs);
+        XiveTCTX *tctx = spapr_cpu_state(cpu)->tctx;
+        int ring;
+
+        /*
+         * Check the thread context CAM lines and record matches.
+         */
+        ring = xive_presenter_tctx_match(xptr, tctx, format, nvt_blk, nvt_idx,
+                                         cam_ignore, logic_serv);
+        /*
+         * Save the matching thread interrupt context and follow on to
+         * check for duplicates which are invalid.
+         */
+        if (ring != -1) {
+            if (match->tctx) {
+                qemu_log_mask(LOG_GUEST_ERROR, "XIVE: already found a thread "
+                              "context NVT %x/%x\n", nvt_blk, nvt_idx);
+                return -1;
+            }
+
+            match->ring = ring;
+            match->tctx = tctx;
+            count++;
+        }
+    }
+
+    return count;
+}
+
 static const VMStateDescription vmstate_spapr_xive_end = {
     .name = TYPE_SPAPR_XIVE "/end",
     .version_id = 1,
@@ -496,6 +534,7 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
     XiveRouterClass *xrc = XIVE_ROUTER_CLASS(klass);
+    XivePresenterClass *xpc = XIVE_PRESENTER_CLASS(klass);
 
     dc->desc    = "sPAPR XIVE Interrupt Controller";
     dc->props   = spapr_xive_properties;
@@ -508,6 +547,8 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data)
     xrc->get_nvt = spapr_xive_get_nvt;
     xrc->write_nvt = spapr_xive_write_nvt;
     xrc->get_tctx = spapr_xive_get_tctx;
+
+    xpc->match_nvt  = spapr_xive_match_nvt;
 }
 
 static const TypeInfo spapr_xive_info = {
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 115bbfb0e788..631db719f41f 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -4302,6 +4302,37 @@ static void spapr_pic_print_info(InterruptStatsProvider *obj,
     spapr->irq->print_info(spapr, mon);
 }
 
+static int spapr_xive_match_nvt(XiveFabric *xfb, uint8_t format,
+                                uint8_t nvt_blk, uint32_t nvt_idx,
+                                bool cam_ignore, uint8_t priority,
+                                uint32_t logic_serv, XiveTCTXMatch *match)
+{
+    SpaprMachineState *spapr = SPAPR_MACHINE(xfb);
+    int count;
+
+    count = spapr->irq->match_nvt(spapr, format, nvt_blk, nvt_idx, cam_ignore,
+                                  priority, logic_serv, match);
+    if (count < 0) {
+        return count;
+    }
+
+    /*
+     * When we implement the save and restore of the thread interrupt
+     * contexts in the enter/exit CPU handlers of the machine and the
+     * escalations in QEMU, we should be able to handle non dispatched
+     * vCPUs.
+     *
+     * Until this is done, the sPAPR machine should find at least one
+     * matching context always.
+     */
+    if (count == 0) {
+        qemu_log_mask(LOG_GUEST_ERROR, "XIVE: NVT %x/%x is not dispatched\n",
+                      nvt_blk, nvt_idx);
+    }
+
+    return count;
+}
+
 int spapr_get_vcpu_id(PowerPCCPU *cpu)
 {
     return cpu->vcpu_id;
@@ -4398,6 +4429,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
     PPCVirtualHypervisorClass *vhc = PPC_VIRTUAL_HYPERVISOR_CLASS(oc);
     XICSFabricClass *xic = XICS_FABRIC_CLASS(oc);
     InterruptStatsProviderClass *ispc = INTERRUPT_STATS_PROVIDER_CLASS(oc);
+    XiveFabricClass *xfc = XIVE_FABRIC_CLASS(oc);
 
     mc->desc = "pSeries Logical Partition (PAPR compliant)";
     mc->ignore_boot_device_suffixes = true;
@@ -4456,6 +4488,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
      */
     mc->numa_mem_align_shift = 28;
     mc->numa_mem_supported = true;
+    xfc->match_nvt = spapr_xive_match_nvt;
 
     smc->default_caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_OFF;
     smc->default_caps.caps[SPAPR_CAP_VSX] = SPAPR_CAP_ON;
@@ -4488,6 +4521,7 @@ static const TypeInfo spapr_machine_info = {
         { TYPE_PPC_VIRTUAL_HYPERVISOR },
         { TYPE_XICS_FABRIC },
         { TYPE_INTERRUPT_STATS_PROVIDER },
+        { TYPE_XIVE_FABRIC },
         { }
     },
 };
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index ff3df0bbd8cf..ff824d950f05 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -262,6 +262,7 @@ SpaprIrq spapr_irq_xics = {
     .set_irq     = spapr_irq_set_irq_xics,
     .get_nodename = spapr_irq_get_nodename_xics,
     .init_kvm    = spapr_irq_init_kvm_xics,
+    .match_nvt   = NULL, /* should not be used */
 };
 
 /*
@@ -411,6 +412,18 @@ static void spapr_irq_init_kvm_xive(SpaprMachineState *spapr, Error **errp)
     }
 }
 
+static int spapr_irq_match_nvt_xive(SpaprMachineState *spapr, uint8_t format,
+                                    uint8_t nvt_blk, uint32_t nvt_idx,
+                                    bool cam_ignore, uint8_t priority,
+                                    uint32_t logic_serv, XiveTCTXMatch *match)
+{
+    XivePresenter *xptr = XIVE_PRESENTER(spapr->xive);
+    XivePresenterClass *xpc = XIVE_PRESENTER_GET_CLASS(xptr);
+
+    return xpc->match_nvt(xptr, format, nvt_blk, nvt_idx, cam_ignore,
+                          priority, logic_serv, match);
+}
+
 /*
  * XIVE uses the full IRQ number space. Set it to 8K to be compatible
  * with XICS.
@@ -436,6 +449,7 @@ SpaprIrq spapr_irq_xive = {
     .set_irq     = spapr_irq_set_irq_xive,
     .get_nodename = spapr_irq_get_nodename_xive,
     .init_kvm    = spapr_irq_init_kvm_xive,
+    .match_nvt   = spapr_irq_match_nvt_xive,
 };
 
 /*
@@ -590,6 +604,15 @@ static const char *spapr_irq_get_nodename_dual(SpaprMachineState *spapr)
     return spapr_irq_current(spapr)->get_nodename(spapr);
 }
 
+static int spapr_irq_match_nvt_dual(SpaprMachineState *spapr, uint8_t format,
+                                    uint8_t nvt_blk, uint32_t nvt_idx,
+                                    bool cam_ignore, uint8_t priority,
+                                    uint32_t logic_serv, XiveTCTXMatch *match)
+{
+    return spapr_irq_current(spapr)->match_nvt(spapr, format, nvt_blk, nvt_idx,
+                                     cam_ignore, priority, logic_serv, match);
+}
+
 /*
  * Define values in sync with the XIVE and XICS backend
  */
@@ -613,6 +636,7 @@ SpaprIrq spapr_irq_dual = {
     .set_irq     = spapr_irq_set_irq_dual,
     .get_nodename = spapr_irq_get_nodename_dual,
     .init_kvm    = NULL, /* should not be used */
+    .match_nvt   = spapr_irq_match_nvt_dual,
 };
 
 
@@ -828,4 +852,5 @@ SpaprIrq spapr_irq_xics_legacy = {
     .set_irq     = spapr_irq_set_irq_xics,
     .get_nodename = spapr_irq_get_nodename_xics,
     .init_kvm    = spapr_irq_init_kvm_xics,
+    .match_nvt   = NULL, /* should not be used */
 };
-- 
2.21.0



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

* [Qemu-devel] [PATCH v3 06/18] ppc/xive: Use the XiveFabric and XivePresenter interfaces
  2019-07-31 14:12 [Qemu-devel] [PATCH v3 00/18] ppc/pnv: add XIVE support for KVM guests Cédric Le Goater
                   ` (4 preceding siblings ...)
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 05/18] ppc/spapr: " Cédric Le Goater
@ 2019-07-31 14:12 ` Cédric Le Goater
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 07/18] ppc/xive: Extend the TIMA operation with a XivePresenter parameter Cédric Le Goater
                   ` (12 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Cédric Le Goater @ 2019-07-31 14:12 UTC (permalink / raw)
  To: David Gibson; +Cc: Cédric Le Goater, qemu-ppc, Greg Kurz, qemu-devel

Now that the machines have handlers implemented for the XiveFabric and
XivePresenter interfaces, remove xive_presenter_match() and make use of
the 'match_nvt' handler of the machine.

Fixes: af53dbf6227a ("ppc/xive: introduce a simplified XIVE presenter")
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/intc/xive.c | 77 +++++++++++---------------------------------------
 1 file changed, 17 insertions(+), 60 deletions(-)

diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 4bdedab13047..bec0c878705c 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -1354,59 +1354,6 @@ int xive_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx,
     return -1;
 }
 
-static bool xive_presenter_match(XiveRouter *xrtr, uint8_t format,
-                                 uint8_t nvt_blk, uint32_t nvt_idx,
-                                 bool cam_ignore, uint8_t priority,
-                                 uint32_t logic_serv, XiveTCTXMatch *match)
-{
-    CPUState *cs;
-
-    /*
-     * TODO (PowerNV): handle chip_id overwrite of block field for
-     * hardwired CAM compares
-     */
-
-    CPU_FOREACH(cs) {
-        XiveTCTX *tctx = xive_router_get_tctx(xrtr, cs);
-        int ring;
-
-        /*
-         * HW checks that the CPU is enabled in the Physical Thread
-         * Enable Register (PTER).
-         */
-
-        /*
-         * Check the thread context CAM lines and record matches. We
-         * will handle CPU exception delivery later
-         */
-        ring = xive_presenter_tctx_match(XIVE_PRESENTER(xrtr), tctx, format,
-                                         nvt_blk, nvt_idx,
-                                         cam_ignore, logic_serv);
-        /*
-         * Save the context and follow on to catch duplicates, that we
-         * don't support yet.
-         */
-        if (ring != -1) {
-            if (match->tctx) {
-                qemu_log_mask(LOG_GUEST_ERROR, "XIVE: already found a thread "
-                              "context NVT %x/%x\n", nvt_blk, nvt_idx);
-                return false;
-            }
-
-            match->ring = ring;
-            match->tctx = tctx;
-        }
-    }
-
-    if (!match->tctx) {
-        qemu_log_mask(LOG_UNIMP, "XIVE: NVT %x/%x is not dispatched\n",
-                      nvt_blk, nvt_idx);
-        return false;
-    }
-
-    return true;
-}
-
 /*
  * This is our simple Xive Presenter Engine model. It is merged in the
  * Router as it does not require an extra object.
@@ -1422,22 +1369,32 @@ static bool xive_presenter_match(XiveRouter *xrtr, uint8_t format,
  *
  * The parameters represent what is sent on the PowerBus
  */
-static bool xive_presenter_notify(XiveRouter *xrtr, uint8_t format,
+static bool xive_presenter_notify(uint8_t format,
                                   uint8_t nvt_blk, uint32_t nvt_idx,
                                   bool cam_ignore, uint8_t priority,
                                   uint32_t logic_serv)
 {
+    XiveFabric *xfb = XIVE_FABRIC(qdev_get_machine());
+    XiveFabricClass *xfc = XIVE_FABRIC_GET_CLASS(xfb);
     XiveTCTXMatch match = { .tctx = NULL, .ring = 0 };
-    bool found;
+    int count;
 
-    found = xive_presenter_match(xrtr, format, nvt_blk, nvt_idx, cam_ignore,
-                                 priority, logic_serv, &match);
-    if (found) {
+    /*
+     * Ask the machine to scan the interrupt controllers for a match
+     */
+    count = xfc->match_nvt(xfb, format, nvt_blk, nvt_idx, cam_ignore,
+                           priority, logic_serv, &match);
+    if (count < 0) {
+        return false;
+    }
+
+    /* handle CPU exception delivery */
+    if (count) {
         ipb_update(&match.tctx->regs[match.ring], priority);
         xive_tctx_notify(match.tctx, match.ring);
     }
 
-    return found;
+    return count;
 }
 
 /*
@@ -1550,7 +1507,7 @@ static void xive_router_end_notify(XiveRouter *xrtr, uint8_t end_blk,
         return;
     }
 
-    found = xive_presenter_notify(xrtr, format, nvt_blk, nvt_idx,
+    found = xive_presenter_notify(format, nvt_blk, nvt_idx,
                           xive_get_field32(END_W7_F0_IGNORE, end.w7),
                           priority,
                           xive_get_field32(END_W7_F1_LOG_SERVER_ID, end.w7));
-- 
2.21.0



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

* [Qemu-devel] [PATCH v3 07/18] ppc/xive: Extend the TIMA operation with a XivePresenter parameter
  2019-07-31 14:12 [Qemu-devel] [PATCH v3 00/18] ppc/pnv: add XIVE support for KVM guests Cédric Le Goater
                   ` (5 preceding siblings ...)
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 06/18] ppc/xive: Use " Cédric Le Goater
@ 2019-07-31 14:12 ` Cédric Le Goater
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 08/18] ppc/pnv: Clarify how the TIMA is accessed on a multichip system Cédric Le Goater
                   ` (11 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Cédric Le Goater @ 2019-07-31 14:12 UTC (permalink / raw)
  To: David Gibson; +Cc: Cédric Le Goater, qemu-ppc, Greg Kurz, qemu-devel

The TIMA operations are performed on behalf of the XIVE IVPE
sub-engine (Presenter) on the thread interrupt context registers. The
current operations the model supports are simple and do not require
access to the controller but more complex operations we will add will
need access to the controller NVT table and to its configuration.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 include/hw/ppc/xive.h |  7 +++---
 hw/intc/pnv_xive.c    |  4 +--
 hw/intc/xive.c        | 58 ++++++++++++++++++++++++-------------------
 3 files changed, 38 insertions(+), 31 deletions(-)

diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
index 165134ce52a5..ba43a4a129d9 100644
--- a/include/hw/ppc/xive.h
+++ b/include/hw/ppc/xive.h
@@ -464,9 +464,10 @@ typedef struct XiveENDSource {
 #define XIVE_TM_USER_PAGE       0x3
 
 extern const MemoryRegionOps xive_tm_ops;
-void xive_tctx_tm_write(XiveTCTX *tctx, hwaddr offset, uint64_t value,
-                        unsigned size);
-uint64_t xive_tctx_tm_read(XiveTCTX *tctx, hwaddr offset, unsigned size);
+void xive_tctx_tm_write(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset,
+                        uint64_t value, unsigned size);
+uint64_t xive_tctx_tm_read(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset,
+                           unsigned size);
 
 void xive_tctx_pic_print_info(XiveTCTX *tctx, Monitor *mon);
 Object *xive_tctx_create(Object *cpu, XiveRouter *xrtr, Error **errp);
diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
index 183798b81496..6f53a2abbb6a 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -1444,7 +1444,7 @@ static void xive_tm_indirect_write(void *opaque, hwaddr offset,
 {
     XiveTCTX *tctx = pnv_xive_get_indirect_tctx(PNV_XIVE(opaque));
 
-    xive_tctx_tm_write(tctx, offset, value, size);
+    xive_tctx_tm_write(XIVE_PRESENTER(opaque), tctx, offset, value, size);
 }
 
 static uint64_t xive_tm_indirect_read(void *opaque, hwaddr offset,
@@ -1452,7 +1452,7 @@ static uint64_t xive_tm_indirect_read(void *opaque, hwaddr offset,
 {
     XiveTCTX *tctx = pnv_xive_get_indirect_tctx(PNV_XIVE(opaque));
 
-    return xive_tctx_tm_read(tctx, offset, size);
+    return xive_tctx_tm_read(XIVE_PRESENTER(opaque), tctx, offset, size);
 }
 
 static const MemoryRegionOps xive_tm_indirect_ops = {
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index bec0c878705c..9ca015969143 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -141,19 +141,20 @@ static inline uint32_t xive_tctx_word2(uint8_t *ring)
  * XIVE Thread Interrupt Management Area (TIMA)
  */
 
-static void xive_tm_set_hv_cppr(XiveTCTX *tctx, hwaddr offset,
-                                uint64_t value, unsigned size)
+static void xive_tm_set_hv_cppr(XivePresenter *xptr, XiveTCTX *tctx,
+                                hwaddr offset, uint64_t value, unsigned size)
 {
     xive_tctx_set_cppr(tctx, TM_QW3_HV_PHYS, value & 0xff);
 }
 
-static uint64_t xive_tm_ack_hv_reg(XiveTCTX *tctx, hwaddr offset, unsigned size)
+static uint64_t xive_tm_ack_hv_reg(XivePresenter *xptr, XiveTCTX *tctx,
+                                   hwaddr offset, unsigned size)
 {
     return xive_tctx_accept(tctx, TM_QW3_HV_PHYS);
 }
 
-static uint64_t xive_tm_pull_pool_ctx(XiveTCTX *tctx, hwaddr offset,
-                                      unsigned size)
+static uint64_t xive_tm_pull_pool_ctx(XivePresenter *xptr, XiveTCTX *tctx,
+                                      hwaddr offset, unsigned size)
 {
     uint32_t qw2w2_prev = xive_tctx_word2(&tctx->regs[TM_QW2_HV_POOL]);
     uint32_t qw2w2;
@@ -163,13 +164,14 @@ static uint64_t xive_tm_pull_pool_ctx(XiveTCTX *tctx, hwaddr offset,
     return qw2w2;
 }
 
-static void xive_tm_vt_push(XiveTCTX *tctx, hwaddr offset,
+static void xive_tm_vt_push(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset,
                             uint64_t value, unsigned size)
 {
     tctx->regs[TM_QW3_HV_PHYS + TM_WORD2] = value & 0xff;
 }
 
-static uint64_t xive_tm_vt_poll(XiveTCTX *tctx, hwaddr offset, unsigned size)
+static uint64_t xive_tm_vt_poll(XivePresenter *xptr, XiveTCTX *tctx,
+                                hwaddr offset, unsigned size)
 {
     return tctx->regs[TM_QW3_HV_PHYS + TM_WORD2] & 0xff;
 }
@@ -312,13 +314,14 @@ static uint64_t xive_tm_raw_read(XiveTCTX *tctx, hwaddr offset, unsigned size)
  * state changes (side effects) in addition to setting/returning the
  * interrupt management area context of the processor thread.
  */
-static uint64_t xive_tm_ack_os_reg(XiveTCTX *tctx, hwaddr offset, unsigned size)
+static uint64_t xive_tm_ack_os_reg(XivePresenter *xptr, XiveTCTX *tctx,
+                                   hwaddr offset, unsigned size)
 {
     return xive_tctx_accept(tctx, TM_QW1_OS);
 }
 
-static void xive_tm_set_os_cppr(XiveTCTX *tctx, hwaddr offset,
-                                uint64_t value, unsigned size)
+static void xive_tm_set_os_cppr(XivePresenter *xptr, XiveTCTX *tctx,
+                                hwaddr offset, uint64_t value, unsigned size)
 {
     xive_tctx_set_cppr(tctx, TM_QW1_OS, value & 0xff);
 }
@@ -327,15 +330,15 @@ static void xive_tm_set_os_cppr(XiveTCTX *tctx, hwaddr offset,
  * Adjust the IPB to allow a CPU to process event queues of other
  * priorities during one physical interrupt cycle.
  */
-static void xive_tm_set_os_pending(XiveTCTX *tctx, hwaddr offset,
-                                   uint64_t value, unsigned size)
+static void xive_tm_set_os_pending(XivePresenter *xptr, XiveTCTX *tctx,
+                                   hwaddr offset, uint64_t value, unsigned size)
 {
     ipb_update(&tctx->regs[TM_QW1_OS], value & 0xff);
     xive_tctx_notify(tctx, TM_QW1_OS);
 }
 
-static uint64_t xive_tm_pull_os_ctx(XiveTCTX *tctx, hwaddr offset,
-                                    unsigned size)
+static uint64_t xive_tm_pull_os_ctx(XivePresenter *xptr, XiveTCTX *tctx,
+                                    hwaddr offset, unsigned size)
 {
     uint32_t qw1w2_prev = xive_tctx_word2(&tctx->regs[TM_QW1_OS]);
     uint32_t qw1w2;
@@ -353,9 +356,11 @@ typedef struct XiveTmOp {
     uint8_t  page_offset;
     uint32_t op_offset;
     unsigned size;
-    void     (*write_handler)(XiveTCTX *tctx, hwaddr offset, uint64_t value,
-                              unsigned size);
-    uint64_t (*read_handler)(XiveTCTX *tctx, hwaddr offset, unsigned size);
+    void     (*write_handler)(XivePresenter *xptr, XiveTCTX *tctx,
+                              hwaddr offset,
+                              uint64_t value, unsigned size);
+    uint64_t (*read_handler)(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset,
+                             unsigned size);
 } XiveTmOp;
 
 static const XiveTmOp xive_tm_operations[] = {
@@ -401,8 +406,8 @@ static const XiveTmOp *xive_tm_find_op(hwaddr offset, unsigned size, bool write)
 /*
  * TIMA MMIO handlers
  */
-void xive_tctx_tm_write(XiveTCTX *tctx, hwaddr offset, uint64_t value,
-                        unsigned size)
+void xive_tctx_tm_write(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset,
+                        uint64_t value, unsigned size)
 {
     const XiveTmOp *xto;
 
@@ -419,7 +424,7 @@ void xive_tctx_tm_write(XiveTCTX *tctx, hwaddr offset, uint64_t value,
             qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid write access at TIMA "
                           "@%"HWADDR_PRIx"\n", offset);
         } else {
-            xto->write_handler(tctx, offset, value, size);
+            xto->write_handler(xptr, tctx, offset, value, size);
         }
         return;
     }
@@ -429,7 +434,7 @@ void xive_tctx_tm_write(XiveTCTX *tctx, hwaddr offset, uint64_t value,
      */
     xto = xive_tm_find_op(offset, size, true);
     if (xto) {
-        xto->write_handler(tctx, offset, value, size);
+        xto->write_handler(xptr, tctx, offset, value, size);
         return;
     }
 
@@ -439,7 +444,8 @@ void xive_tctx_tm_write(XiveTCTX *tctx, hwaddr offset, uint64_t value,
     xive_tm_raw_write(tctx, offset, value, size);
 }
 
-uint64_t xive_tctx_tm_read(XiveTCTX *tctx, hwaddr offset, unsigned size)
+uint64_t xive_tctx_tm_read(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset,
+                           unsigned size)
 {
     const XiveTmOp *xto;
 
@@ -457,7 +463,7 @@ uint64_t xive_tctx_tm_read(XiveTCTX *tctx, hwaddr offset, unsigned size)
                           "@%"HWADDR_PRIx"\n", offset);
             return -1;
         }
-        return xto->read_handler(tctx, offset, size);
+        return xto->read_handler(xptr, tctx, offset, size);
     }
 
     /*
@@ -465,7 +471,7 @@ uint64_t xive_tctx_tm_read(XiveTCTX *tctx, hwaddr offset, unsigned size)
      */
     xto = xive_tm_find_op(offset, size, false);
     if (xto) {
-        return xto->read_handler(tctx, offset, size);
+        return xto->read_handler(xptr, tctx, offset, size);
     }
 
     /*
@@ -479,14 +485,14 @@ static void xive_tm_write(void *opaque, hwaddr offset,
 {
     XiveTCTX *tctx = xive_router_get_tctx(XIVE_ROUTER(opaque), current_cpu);
 
-    xive_tctx_tm_write(tctx, offset, value, size);
+    xive_tctx_tm_write(XIVE_PRESENTER(opaque), tctx, offset, value, size);
 }
 
 static uint64_t xive_tm_read(void *opaque, hwaddr offset, unsigned size)
 {
     XiveTCTX *tctx = xive_router_get_tctx(XIVE_ROUTER(opaque), current_cpu);
 
-    return xive_tctx_tm_read(tctx, offset, size);
+    return xive_tctx_tm_read(XIVE_PRESENTER(opaque), tctx, offset, size);
 }
 
 const MemoryRegionOps xive_tm_ops = {
-- 
2.21.0



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

* [Qemu-devel] [PATCH v3 08/18] ppc/pnv: Clarify how the TIMA is accessed on a multichip system
  2019-07-31 14:12 [Qemu-devel] [PATCH v3 00/18] ppc/pnv: add XIVE support for KVM guests Cédric Le Goater
                   ` (6 preceding siblings ...)
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 07/18] ppc/xive: Extend the TIMA operation with a XivePresenter parameter Cédric Le Goater
@ 2019-07-31 14:12 ` Cédric Le Goater
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 09/18] ppc/xive: Move the TIMA operations to the controller model Cédric Le Goater
                   ` (10 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Cédric Le Goater @ 2019-07-31 14:12 UTC (permalink / raw)
  To: David Gibson; +Cc: Cédric Le Goater, qemu-ppc, Greg Kurz, qemu-devel

The TIMA MMIO space is shared among the chips and to identify the chip
from which the access is being done, the PowerBUS uses a chip field in
the load/store messages. QEMU does not model these messages, so
instead, we extract the chip id from the CPU PIR and do a lookup at
the machine level to fetch the targeted interrupt controller.

Introduce pnv_get_chip() and pnv_xive_tm_get_xive() helpers to clarify
this process in pnv_xive_get_tctx(). The latter will be removed in the
subsequent patches but the same principle will be kept.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 include/hw/ppc/pnv.h | 13 +++++++++++++
 hw/intc/pnv_xive.c   | 40 +++++++++++++++++++++++-----------------
 2 files changed, 36 insertions(+), 17 deletions(-)

diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index fb123edc4e5a..72b5cbb606b5 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -182,6 +182,19 @@ static inline bool pnv_is_power9(PnvMachineState *pnv)
     return pnv_chip_is_power9(pnv->chips[0]);
 }
 
+static inline PnvChip *pnv_get_chip(PnvMachineState *pnv, uint32_t chip_id)
+{
+    int i;
+
+    for (i = 0; i < pnv->num_chips; i++) {
+        PnvChip *chip = pnv->chips[i];
+        if (chip->chip_id == chip_id) {
+            return chip;
+        }
+    }
+    return NULL;
+}
+
 #define PNV_FDT_ADDR          0x01000000
 #define PNV_TIMEBASE_FREQ     512000000ULL
 
diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
index 6f53a2abbb6a..e598857359d8 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -464,31 +464,37 @@ static int pnv_xive_match_nvt(XivePresenter *xptr, uint8_t format,
     return count;
 }
 
+/*
+ * The TIMA MMIO space is shared among the chips and to identify the
+ * chip from which the access is being done, we extract the chip id
+ * from the PIR.
+ */
+static PnvXive *pnv_xive_tm_get_xive(PowerPCCPU *cpu)
+{
+    PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine());
+    PnvChip *chip;
+    PnvXive *xive;
+
+    chip = pnv_get_chip(pnv, cpu_chip_id(cpu));
+    assert(chip);
+    xive = &PNV9_CHIP(chip)->xive;
+
+    if (!pnv_xive_is_cpu_enabled(xive, cpu)) {
+        xive_error(xive, "IC: CPU %x is not enabled", cpu_pir(cpu));
+    }
+    return xive;
+}
+
 static XiveTCTX *pnv_xive_get_tctx(XiveRouter *xrtr, CPUState *cs)
 {
     PowerPCCPU *cpu = POWERPC_CPU(cs);
-    XiveTCTX *tctx = XIVE_TCTX(pnv_cpu_state(cpu)->intc);
-    PnvXive *xive = NULL;
-    CPUPPCState *env = &cpu->env;
-    int pir = env->spr_cb[SPR_PIR].default_value;
+    PnvXive *xive = pnv_xive_tm_get_xive(cpu);
 
-    /*
-     * Perform an extra check on the HW thread enablement.
-     *
-     * The TIMA is shared among the chips and to identify the chip
-     * from which the access is being done, we extract the chip id
-     * from the PIR.
-     */
-    xive = pnv_xive_get_ic((pir >> 8) & 0xf);
     if (!xive) {
         return NULL;
     }
 
-    if (!(xive->regs[PC_THREAD_EN_REG0 >> 3] & PPC_BIT(pir & 0x3f))) {
-        xive_error(PNV_XIVE(xrtr), "IC: CPU %x is not enabled", pir);
-    }
-
-    return tctx;
+    return XIVE_TCTX(pnv_cpu_state(cpu)->intc);
 }
 
 /*
-- 
2.21.0



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

* [Qemu-devel] [PATCH v3 09/18] ppc/xive: Move the TIMA operations to the controller model
  2019-07-31 14:12 [Qemu-devel] [PATCH v3 00/18] ppc/pnv: add XIVE support for KVM guests Cédric Le Goater
                   ` (7 preceding siblings ...)
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 08/18] ppc/pnv: Clarify how the TIMA is accessed on a multichip system Cédric Le Goater
@ 2019-07-31 14:12 ` Cédric Le Goater
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 10/18] ppc/xive: Introduce a xive_tctx_ipb_update() helper Cédric Le Goater
                   ` (9 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Cédric Le Goater @ 2019-07-31 14:12 UTC (permalink / raw)
  To: David Gibson; +Cc: Cédric Le Goater, qemu-ppc, Greg Kurz, qemu-devel

This also removes the need of the get_tctx() XiveRouter handler in the
core XIVE framework.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 include/hw/ppc/xive.h |  3 ---
 hw/intc/pnv_xive.c    | 48 ++++++++++++++++++++++++++++++-------------
 hw/intc/spapr_xive.c  | 41 +++++++++++++++++++++++++++---------
 hw/intc/xive.c        | 36 --------------------------------
 4 files changed, 65 insertions(+), 63 deletions(-)

diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
index ba43a4a129d9..b34e2ad43a82 100644
--- a/include/hw/ppc/xive.h
+++ b/include/hw/ppc/xive.h
@@ -352,7 +352,6 @@ typedef struct XiveRouterClass {
                    XiveNVT *nvt);
     int (*write_nvt)(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx,
                      XiveNVT *nvt, uint8_t word_number);
-    XiveTCTX *(*get_tctx)(XiveRouter *xrtr, CPUState *cs);
 } XiveRouterClass;
 
 int xive_router_get_eas(XiveRouter *xrtr, uint8_t eas_blk, uint32_t eas_idx,
@@ -365,7 +364,6 @@ int xive_router_get_nvt(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx,
                         XiveNVT *nvt);
 int xive_router_write_nvt(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx,
                           XiveNVT *nvt, uint8_t word_number);
-XiveTCTX *xive_router_get_tctx(XiveRouter *xrtr, CPUState *cs);
 void xive_router_notify(XiveNotifier *xn, uint32_t lisn);
 
 /*
@@ -463,7 +461,6 @@ typedef struct XiveENDSource {
 #define XIVE_TM_OS_PAGE         0x2
 #define XIVE_TM_USER_PAGE       0x3
 
-extern const MemoryRegionOps xive_tm_ops;
 void xive_tctx_tm_write(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset,
                         uint64_t value, unsigned size);
 uint64_t xive_tctx_tm_read(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset,
diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
index e598857359d8..982f5eef380c 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -485,18 +485,6 @@ static PnvXive *pnv_xive_tm_get_xive(PowerPCCPU *cpu)
     return xive;
 }
 
-static XiveTCTX *pnv_xive_get_tctx(XiveRouter *xrtr, CPUState *cs)
-{
-    PowerPCCPU *cpu = POWERPC_CPU(cs);
-    PnvXive *xive = pnv_xive_tm_get_xive(cpu);
-
-    if (!xive) {
-        return NULL;
-    }
-
-    return XIVE_TCTX(pnv_cpu_state(cpu)->intc);
-}
-
 /*
  * The internal sources (IPIs) of the interrupt controller have no
  * knowledge of the XIVE chip on which they reside. Encode the block
@@ -1475,6 +1463,39 @@ static const MemoryRegionOps xive_tm_indirect_ops = {
     },
 };
 
+static void pnv_xive_tm_write(void *opaque, hwaddr offset,
+                              uint64_t value, unsigned size)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(current_cpu);
+    PnvXive *xive = pnv_xive_tm_get_xive(cpu);
+    XiveTCTX *tctx = XIVE_TCTX(pnv_cpu_state(cpu)->intc);
+
+    xive_tctx_tm_write(XIVE_PRESENTER(xive), tctx, offset, value, size);
+}
+
+static uint64_t pnv_xive_tm_read(void *opaque, hwaddr offset, unsigned size)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(current_cpu);
+    PnvXive *xive = pnv_xive_tm_get_xive(cpu);
+    XiveTCTX *tctx = XIVE_TCTX(pnv_cpu_state(cpu)->intc);
+
+    return xive_tctx_tm_read(XIVE_PRESENTER(xive), tctx, offset, size);
+}
+
+const MemoryRegionOps pnv_xive_tm_ops = {
+    .read = pnv_xive_tm_read,
+    .write = pnv_xive_tm_write,
+    .endianness = DEVICE_BIG_ENDIAN,
+    .valid = {
+        .min_access_size = 1,
+        .max_access_size = 8,
+    },
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 8,
+    },
+};
+
 /*
  * Interrupt controller XSCOM region.
  */
@@ -1832,7 +1853,7 @@ static void pnv_xive_realize(DeviceState *dev, Error **errp)
                           "xive-pc", PNV9_XIVE_PC_SIZE);
 
     /* Thread Interrupt Management Area (Direct) */
-    memory_region_init_io(&xive->tm_mmio, OBJECT(xive), &xive_tm_ops,
+    memory_region_init_io(&xive->tm_mmio, OBJECT(xive), &pnv_xive_tm_ops,
                           xive, "xive-tima", PNV9_XIVE_TM_SIZE);
 
     qemu_register_reset(pnv_xive_reset, dev);
@@ -1888,7 +1909,6 @@ static void pnv_xive_class_init(ObjectClass *klass, void *data)
     xrc->write_end = pnv_xive_write_end;
     xrc->get_nvt = pnv_xive_get_nvt;
     xrc->write_nvt = pnv_xive_write_nvt;
-    xrc->get_tctx = pnv_xive_get_tctx;
 
     xnc->notify = pnv_xive_notify;
     xpc->match_nvt  = pnv_xive_match_nvt;
diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index beb5049ad9da..4abb099d341c 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -219,6 +219,35 @@ void spapr_xive_set_tctx_os_cam(XiveTCTX *tctx)
     memcpy(&tctx->regs[TM_QW1_OS + TM_WORD2], &nvt_cam, 4);
 }
 
+static void spapr_xive_tm_write(void *opaque, hwaddr offset,
+                          uint64_t value, unsigned size)
+{
+    XiveTCTX *tctx = spapr_cpu_state(POWERPC_CPU(current_cpu))->tctx;
+
+    xive_tctx_tm_write(XIVE_PRESENTER(opaque), tctx, offset, value, size);
+}
+
+static uint64_t spapr_xive_tm_read(void *opaque, hwaddr offset, unsigned size)
+{
+    XiveTCTX *tctx = spapr_cpu_state(POWERPC_CPU(current_cpu))->tctx;
+
+    return xive_tctx_tm_read(XIVE_PRESENTER(opaque), tctx, offset, size);
+}
+
+const MemoryRegionOps spapr_xive_tm_ops = {
+    .read = spapr_xive_tm_read,
+    .write = spapr_xive_tm_write,
+    .endianness = DEVICE_BIG_ENDIAN,
+    .valid = {
+        .min_access_size = 1,
+        .max_access_size = 8,
+    },
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 8,
+    },
+};
+
 static void spapr_xive_end_reset(XiveEND *end)
 {
     memset(end, 0, sizeof(*end));
@@ -328,8 +357,8 @@ static void spapr_xive_realize(DeviceState *dev, Error **errp)
     qemu_register_reset(spapr_xive_reset, dev);
 
     /* TIMA initialization */
-    memory_region_init_io(&xive->tm_mmio, OBJECT(xive), &xive_tm_ops, xive,
-                          "xive.tima", 4ull << TM_SHIFT);
+    memory_region_init_io(&xive->tm_mmio, OBJECT(xive), &spapr_xive_tm_ops,
+                          xive, "xive.tima", 4ull << TM_SHIFT);
     sysbus_init_mmio(SYS_BUS_DEVICE(xive), &xive->tm_mmio);
 
     /*
@@ -412,13 +441,6 @@ static int spapr_xive_write_nvt(XiveRouter *xrtr, uint8_t nvt_blk,
     g_assert_not_reached();
 }
 
-static XiveTCTX *spapr_xive_get_tctx(XiveRouter *xrtr, CPUState *cs)
-{
-    PowerPCCPU *cpu = POWERPC_CPU(cs);
-
-    return spapr_cpu_state(cpu)->tctx;
-}
-
 static int spapr_xive_match_nvt(XivePresenter *xptr, uint8_t format,
                                 uint8_t nvt_blk, uint32_t nvt_idx,
                                 bool cam_ignore, uint8_t priority,
@@ -546,7 +568,6 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data)
     xrc->write_end = spapr_xive_write_end;
     xrc->get_nvt = spapr_xive_get_nvt;
     xrc->write_nvt = spapr_xive_write_nvt;
-    xrc->get_tctx = spapr_xive_get_tctx;
 
     xpc->match_nvt  = spapr_xive_match_nvt;
 }
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 9ca015969143..6f74b4dcbbd4 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -480,35 +480,6 @@ uint64_t xive_tctx_tm_read(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset,
     return xive_tm_raw_read(tctx, offset, size);
 }
 
-static void xive_tm_write(void *opaque, hwaddr offset,
-                          uint64_t value, unsigned size)
-{
-    XiveTCTX *tctx = xive_router_get_tctx(XIVE_ROUTER(opaque), current_cpu);
-
-    xive_tctx_tm_write(XIVE_PRESENTER(opaque), tctx, offset, value, size);
-}
-
-static uint64_t xive_tm_read(void *opaque, hwaddr offset, unsigned size)
-{
-    XiveTCTX *tctx = xive_router_get_tctx(XIVE_ROUTER(opaque), current_cpu);
-
-    return xive_tctx_tm_read(XIVE_PRESENTER(opaque), tctx, offset, size);
-}
-
-const MemoryRegionOps xive_tm_ops = {
-    .read = xive_tm_read,
-    .write = xive_tm_write,
-    .endianness = DEVICE_BIG_ENDIAN,
-    .valid = {
-        .min_access_size = 1,
-        .max_access_size = 8,
-    },
-    .impl = {
-        .min_access_size = 1,
-        .max_access_size = 8,
-    },
-};
-
 static char *xive_tctx_ring_print(uint8_t *ring)
 {
     uint32_t w2 = xive_tctx_word2(ring);
@@ -1277,13 +1248,6 @@ int xive_router_write_nvt(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx,
    return xrc->write_nvt(xrtr, nvt_blk, nvt_idx, nvt, word_number);
 }
 
-XiveTCTX *xive_router_get_tctx(XiveRouter *xrtr, CPUState *cs)
-{
-    XiveRouterClass *xrc = XIVE_ROUTER_GET_CLASS(xrtr);
-
-    return xrc->get_tctx(xrtr, cs);
-}
-
 /*
  * Encode the HW CAM line in the block group mode format :
  *
-- 
2.21.0



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

* [Qemu-devel] [PATCH v3 10/18] ppc/xive: Introduce a xive_tctx_ipb_update() helper
  2019-07-31 14:12 [Qemu-devel] [PATCH v3 00/18] ppc/pnv: add XIVE support for KVM guests Cédric Le Goater
                   ` (8 preceding siblings ...)
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 09/18] ppc/xive: Move the TIMA operations to the controller model Cédric Le Goater
@ 2019-07-31 14:12 ` Cédric Le Goater
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 11/18] ppc/xive: Synthesize interrupt from the saved IPB in the NVT Cédric Le Goater
                   ` (8 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Cédric Le Goater @ 2019-07-31 14:12 UTC (permalink / raw)
  To: David Gibson; +Cc: Cédric Le Goater, qemu-ppc, Greg Kurz, qemu-devel

We will use it to resend missed interrupts when a vCPU context is
pushed a HW thread.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 include/hw/ppc/xive.h |  1 +
 hw/intc/xive.c        | 15 +++++++++++----
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
index b34e2ad43a82..4233773bae11 100644
--- a/include/hw/ppc/xive.h
+++ b/include/hw/ppc/xive.h
@@ -468,6 +468,7 @@ uint64_t xive_tctx_tm_read(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset,
 
 void xive_tctx_pic_print_info(XiveTCTX *tctx, Monitor *mon);
 Object *xive_tctx_create(Object *cpu, XiveRouter *xrtr, Error **errp);
+void xive_tctx_ipb_update(XiveTCTX *tctx, uint8_t ring, uint8_t ipb);
 
 static inline uint32_t xive_nvt_cam_line(uint8_t nvt_blk, uint32_t nvt_idx)
 {
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 6f74b4dcbbd4..8f6a29ff1f47 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -132,6 +132,15 @@ static void xive_tctx_set_cppr(XiveTCTX *tctx, uint8_t ring, uint8_t cppr)
     xive_tctx_notify(tctx, ring);
 }
 
+void xive_tctx_ipb_update(XiveTCTX *tctx, uint8_t ring, uint8_t ipb)
+{
+    uint8_t *regs = &tctx->regs[ring];
+
+    regs[TM_IPB] |= ipb;
+    regs[TM_PIPR] = ipb_to_pipr(regs[TM_IPB]);
+    xive_tctx_notify(tctx, ring);
+}
+
 static inline uint32_t xive_tctx_word2(uint8_t *ring)
 {
     return *((uint32_t *) &ring[TM_WORD2]);
@@ -333,8 +342,7 @@ static void xive_tm_set_os_cppr(XivePresenter *xptr, XiveTCTX *tctx,
 static void xive_tm_set_os_pending(XivePresenter *xptr, XiveTCTX *tctx,
                                    hwaddr offset, uint64_t value, unsigned size)
 {
-    ipb_update(&tctx->regs[TM_QW1_OS], value & 0xff);
-    xive_tctx_notify(tctx, TM_QW1_OS);
+    xive_tctx_ipb_update(tctx, TM_QW1_OS, priority_to_ipb(value & 0xff));
 }
 
 static uint64_t xive_tm_pull_os_ctx(XivePresenter *xptr, XiveTCTX *tctx,
@@ -1360,8 +1368,7 @@ static bool xive_presenter_notify(uint8_t format,
 
     /* handle CPU exception delivery */
     if (count) {
-        ipb_update(&match.tctx->regs[match.ring], priority);
-        xive_tctx_notify(match.tctx, match.ring);
+        xive_tctx_ipb_update(match.tctx, match.ring, priority_to_ipb(priority));
     }
 
     return count;
-- 
2.21.0



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

* [Qemu-devel] [PATCH v3 11/18] ppc/xive: Synthesize interrupt from the saved IPB in the NVT
  2019-07-31 14:12 [Qemu-devel] [PATCH v3 00/18] ppc/pnv: add XIVE support for KVM guests Cédric Le Goater
                   ` (9 preceding siblings ...)
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 10/18] ppc/xive: Introduce a xive_tctx_ipb_update() helper Cédric Le Goater
@ 2019-07-31 14:12 ` Cédric Le Goater
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 12/18] ppc/pnv: Remove pnv_xive_vst_size() routine Cédric Le Goater
                   ` (7 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Cédric Le Goater @ 2019-07-31 14:12 UTC (permalink / raw)
  To: David Gibson; +Cc: Cédric Le Goater, qemu-ppc, Greg Kurz, qemu-devel

When an interrupt can not be presented to a vCPU, the XIVE presenter
updates the Interrupt Pending Buffer of the XIVE NVT if backlog is
activated in the END.

Later, when the same vCPU is dispatched, its context is pushed in the
thread context registers and the VO bit is set in the CAM line word to
activate the context. The HW grabs the associated NVT to pull the
pending bits, and merges them with the IPB of the TIMA. If interrupts
were missed while the vCPU was not dispatched, these are synthesized
in this sequence.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 include/hw/ppc/xive.h      |  5 ---
 include/hw/ppc/xive_regs.h | 22 +++++++++++++
 hw/intc/xive.c             | 67 +++++++++++++++++++++++++++++++++-----
 3 files changed, 81 insertions(+), 13 deletions(-)

diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
index 4233773bae11..e16c3b63fc44 100644
--- a/include/hw/ppc/xive.h
+++ b/include/hw/ppc/xive.h
@@ -470,11 +470,6 @@ void xive_tctx_pic_print_info(XiveTCTX *tctx, Monitor *mon);
 Object *xive_tctx_create(Object *cpu, XiveRouter *xrtr, Error **errp);
 void xive_tctx_ipb_update(XiveTCTX *tctx, uint8_t ring, uint8_t ipb);
 
-static inline uint32_t xive_nvt_cam_line(uint8_t nvt_blk, uint32_t nvt_idx)
-{
-    return (nvt_blk << 19) | nvt_idx;
-}
-
 /*
  * KVM XIVE device helpers
  */
diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h
index 3fdf1a83b9b6..92ff80d25456 100644
--- a/include/hw/ppc/xive_regs.h
+++ b/include/hw/ppc/xive_regs.h
@@ -232,6 +232,7 @@ typedef struct XiveNVT {
         uint32_t        w2;
         uint32_t        w3;
         uint32_t        w4;
+#define NVT_W4_IPB               PPC_BITMASK32(16, 23)
         uint32_t        w5;
         uint32_t        w6;
         uint32_t        w7;
@@ -248,4 +249,25 @@ typedef struct XiveNVT {
 
 #define xive_nvt_is_valid(nvt)    (be32_to_cpu((nvt)->w0) & NVT_W0_VALID)
 
+/*
+ * The VP number space in a block is defined by the END_W6_NVT_INDEX
+ * field of the XIVE END
+ */
+#define XIVE_NVT_SHIFT                19
+
+static inline uint32_t xive_nvt_cam_line(uint8_t nvt_blk, uint32_t nvt_idx)
+{
+    return (nvt_blk << XIVE_NVT_SHIFT) | nvt_idx;
+}
+
+static inline uint32_t xive_nvt_idx(uint32_t cam_line)
+{
+    return cam_line & ((1 << XIVE_NVT_SHIFT) - 1);
+}
+
+static inline uint32_t xive_nvt_blk(uint32_t cam_line)
+{
+    return (cam_line >> XIVE_NVT_SHIFT) & 0xf;
+}
+
 #endif /* PPC_XIVE_REGS_H */
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 8f6a29ff1f47..9b02ce423d66 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -44,12 +44,6 @@ static uint8_t ipb_to_pipr(uint8_t ibp)
     return ibp ? clz32((uint32_t)ibp << 24) : 0xff;
 }
 
-static void ipb_update(uint8_t *regs, uint8_t priority)
-{
-    regs[TM_IPB] |= priority_to_ipb(priority);
-    regs[TM_PIPR] = ipb_to_pipr(regs[TM_IPB]);
-}
-
 static uint8_t exception_mask(uint8_t ring)
 {
     switch (ring) {
@@ -356,6 +350,55 @@ static uint64_t xive_tm_pull_os_ctx(XivePresenter *xptr, XiveTCTX *tctx,
     return qw1w2;
 }
 
+static void xive_tctx_need_resend(XiveRouter *xrtr, XiveTCTX *tctx,
+                                  uint8_t nvt_blk, uint32_t nvt_idx)
+{
+    XiveNVT nvt;
+    uint8_t ipb;
+
+    /*
+     * Grab the associated NVT to pull the pending bits, and merge
+     * them with the IPB of the thread interrupt context registers
+     */
+    if (xive_router_get_nvt(xrtr, nvt_blk, nvt_idx, &nvt)) {
+        qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid NVT %x/%x\n",
+                          nvt_blk, nvt_idx);
+        return;
+    }
+
+    ipb = xive_get_field32(NVT_W4_IPB, nvt.w4);
+
+    if (ipb) {
+        /* Reset the NVT value */
+        nvt.w4 = xive_set_field32(NVT_W4_IPB, nvt.w4, 0);
+        xive_router_write_nvt(xrtr, nvt_blk, nvt_idx, &nvt, 4);
+
+        /* Merge in current context */
+        xive_tctx_ipb_update(tctx, TM_QW1_OS, ipb);
+    }
+}
+
+/*
+ * Updating the OS CAM line can trigger a resend of interrupt
+ */
+static void xive_tm_push_os_ctx(XivePresenter *xptr, XiveTCTX *tctx,
+                                hwaddr offset, uint64_t value, unsigned size)
+{
+    uint32_t qw1w2 = value;
+    uint8_t nvt_blk = xive_nvt_blk(qw1w2);
+    uint32_t nvt_idx = xive_nvt_idx(qw1w2);
+    bool vo = !!(qw1w2 & TM_QW1W2_VO);
+
+    /* First update the registers */
+    qw1w2 = cpu_to_be32(qw1w2);
+    memcpy(&tctx->regs[TM_QW1_OS + TM_WORD2], &qw1w2, 4);
+
+    /* Check the interrupt pending bits */
+    if (vo) {
+        xive_tctx_need_resend(XIVE_ROUTER(xptr), tctx, nvt_blk, nvt_idx);
+    }
+}
+
 /*
  * Define a mapping of "special" operations depending on the TIMA page
  * offset and the size of the operation.
@@ -377,6 +420,7 @@ static const XiveTmOp xive_tm_operations[] = {
      * 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 },
@@ -1501,14 +1545,21 @@ static void xive_router_end_notify(XiveRouter *xrtr, uint8_t end_blk,
      * - logical server : forward request to IVPE (not supported)
      */
     if (xive_end_is_backlog(&end)) {
+        uint8_t ipb;
+
         if (format == 1) {
             qemu_log_mask(LOG_GUEST_ERROR,
                           "XIVE: END %x/%x invalid config: F1 & backlog\n",
                           end_blk, end_idx);
             return;
         }
-        /* Record the IPB in the associated NVT structure */
-        ipb_update((uint8_t *) &nvt.w4, priority);
+        /*
+         * Record the IPB in the associated NVT structure for later
+         * use. The presenter will resend the interrupt when the vCPU
+         * is dispatched again on a HW thread.
+         */
+        ipb = xive_get_field32(NVT_W4_IPB, nvt.w4) | priority_to_ipb(priority);
+        nvt.w4 = xive_set_field32(NVT_W4_IPB, nvt.w4, ipb);
         xive_router_write_nvt(xrtr, nvt_blk, nvt_idx, &nvt, 4);
 
         /*
-- 
2.21.0



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

* [Qemu-devel] [PATCH v3 12/18] ppc/pnv: Remove pnv_xive_vst_size() routine
  2019-07-31 14:12 [Qemu-devel] [PATCH v3 00/18] ppc/pnv: add XIVE support for KVM guests Cédric Le Goater
                   ` (10 preceding siblings ...)
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 11/18] ppc/xive: Synthesize interrupt from the saved IPB in the NVT Cédric Le Goater
@ 2019-07-31 14:12 ` Cédric Le Goater
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 13/18] ppc/pnv: Dump the XIVE NVT table Cédric Le Goater
                   ` (6 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Cédric Le Goater @ 2019-07-31 14:12 UTC (permalink / raw)
  To: David Gibson; +Cc: Cédric Le Goater, qemu-ppc, Greg Kurz, qemu-devel

pnv_xive_vst_size() tries to compute the size of a VSD table from the
information given by FW. The number of entries of the table are
deduced from the result and the MMIO regions of the ESBs and the ENDS
are also resized with the computed value.

But for indirect tables, the result is incorrect. An indirect table is
a one page array of VSDs pointing to subpages containing XIVE virtual
structures. The number of first level VSD entries is page aligned and
the overall computed size of the table is too large. It can also be
completely wrong when the first VSD entry is not yet initialized.

Remove pnv_xive_vst_size() and use a simpler form for direct tables.
This is only useful when outputting the XIVE sources on the monitor
and to resize the ESB MMIO window.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/intc/pnv_xive.c | 112 +++++++++++++++++----------------------------
 1 file changed, 43 insertions(+), 69 deletions(-)

diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
index 982f5eef380c..aba7a3f83dab 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -121,36 +121,22 @@ static uint64_t pnv_xive_vst_page_size_allowed(uint32_t page_shift)
          page_shift == 21 || page_shift == 24;
 }
 
-static uint64_t pnv_xive_vst_size(uint64_t vsd)
-{
-    uint64_t vst_tsize = 1ull << (GETFIELD(VSD_TSIZE, vsd) + 12);
-
-    /*
-     * Read the first descriptor to get the page size of the indirect
-     * table.
-     */
-    if (VSD_INDIRECT & vsd) {
-        uint32_t nr_pages = vst_tsize / XIVE_VSD_SIZE;
-        uint32_t page_shift;
-
-        vsd = ldq_be_dma(&address_space_memory, vsd & VSD_ADDRESS_MASK);
-        page_shift = GETFIELD(VSD_TSIZE, vsd) + 12;
-
-        if (!pnv_xive_vst_page_size_allowed(page_shift)) {
-            return 0;
-        }
-
-        return nr_pages * (1ull << page_shift);
-    }
-
-    return vst_tsize;
-}
-
 static uint64_t pnv_xive_vst_addr_direct(PnvXive *xive, uint32_t type,
                                          uint64_t vsd, uint32_t idx)
 {
     const XiveVstInfo *info = &vst_infos[type];
     uint64_t vst_addr = vsd & VSD_ADDRESS_MASK;
+    uint64_t vst_tsize = 1ull << (GETFIELD(VSD_TSIZE, vsd) + 12);
+    uint32_t idx_max;
+
+    idx_max = vst_tsize / info->size - 1;
+    if (idx > idx_max) {
+#ifdef XIVE_DEBUG
+        xive_error(xive, "VST: %s entry %x out of range [ 0 .. %x ] !?",
+                   info->name, idx, idx_max);
+#endif
+        return 0;
+    }
 
     return vst_addr + idx * info->size;
 }
@@ -213,7 +199,6 @@ static uint64_t pnv_xive_vst_addr(PnvXive *xive, uint32_t type, uint8_t blk,
 {
     const XiveVstInfo *info = &vst_infos[type];
     uint64_t vsd;
-    uint32_t idx_max;
 
     if (blk >= info->max_blocks) {
         xive_error(xive, "VST: invalid block id %d for VST %s %d !?",
@@ -230,15 +215,6 @@ static uint64_t pnv_xive_vst_addr(PnvXive *xive, uint32_t type, uint8_t blk,
         return xive ? pnv_xive_vst_addr(xive, type, blk, idx) : 0;
     }
 
-    idx_max = pnv_xive_vst_size(vsd) / info->size - 1;
-    if (idx > idx_max) {
-#ifdef XIVE_DEBUG
-        xive_error(xive, "VST: %s entry %x/%x out of range [ 0 .. %x ] !?",
-                   info->name, blk, idx, idx_max);
-#endif
-        return 0;
-    }
-
     if (VSD_INDIRECT & vsd) {
         return pnv_xive_vst_addr_indirect(xive, type, vsd, idx);
     }
@@ -519,19 +495,12 @@ static uint64_t pnv_xive_pc_size(PnvXive *xive)
     return (~xive->regs[CQ_PC_BARM >> 3] + 1) & CQ_PC_BARM_MASK;
 }
 
-static uint32_t pnv_xive_nr_ipis(PnvXive *xive)
+static uint32_t pnv_xive_nr_ipis(PnvXive *xive, uint8_t blk)
 {
-    uint8_t blk = xive->chip->chip_id;
-
-    return pnv_xive_vst_size(xive->vsds[VST_TSEL_SBE][blk]) * SBE_PER_BYTE;
-}
-
-static uint32_t pnv_xive_nr_ends(PnvXive *xive)
-{
-    uint8_t blk = xive->chip->chip_id;
+    uint64_t vsd = xive->vsds[VST_TSEL_SBE][blk];
+    uint64_t vst_tsize = 1ull << (GETFIELD(VSD_TSIZE, vsd) + 12);
 
-    return pnv_xive_vst_size(xive->vsds[VST_TSEL_EQDT][blk])
-        / vst_infos[VST_TSEL_EQDT].size;
+    return VSD_INDIRECT & vsd ? 0 : vst_tsize * SBE_PER_BYTE;
 }
 
 /*
@@ -664,6 +633,7 @@ static void pnv_xive_vst_set_exclusive(PnvXive *xive, uint8_t type,
     XiveSource *xsrc = &xive->ipi_source;
     const XiveVstInfo *info = &vst_infos[type];
     uint32_t page_shift = GETFIELD(VSD_TSIZE, vsd) + 12;
+    uint64_t vst_tsize = 1ull << page_shift;
     uint64_t vst_addr = vsd & VSD_ADDRESS_MASK;
 
     /* Basic checks */
@@ -699,11 +669,16 @@ static void pnv_xive_vst_set_exclusive(PnvXive *xive, uint8_t type,
 
     case VST_TSEL_EQDT:
         /*
-         * Backing store pages for the END. Compute the number of ENDs
-         * provisioned by FW and resize the END ESB window accordingly.
+         * Backing store pages for the END.
+         *
+         * If the table is direct, we can compute the number of PQ
+         * entries provisioned by FW (such as skiboot) and resize the
+         * END ESB window accordingly.
          */
-        memory_region_set_size(&end_xsrc->esb_mmio, pnv_xive_nr_ends(xive) *
-                               (1ull << (end_xsrc->esb_shift + 1)));
+        if (!(VSD_INDIRECT & vsd)) {
+            memory_region_set_size(&end_xsrc->esb_mmio, (vst_tsize / info->size)
+                                   * (1ull << xsrc->esb_shift));
+        }
         memory_region_add_subregion(&xive->end_edt_mmio, 0,
                                     &end_xsrc->esb_mmio);
         break;
@@ -712,11 +687,16 @@ static void pnv_xive_vst_set_exclusive(PnvXive *xive, uint8_t type,
         /*
          * Backing store pages for the source PQ bits. The model does
          * not use these PQ bits backed in RAM because the XiveSource
-         * model has its own. Compute the number of IRQs provisioned
-         * by FW and resize the IPI ESB window accordingly.
+         * model has its own.
+         *
+         * If the table is direct, we can compute the number of PQ
+         * entries provisioned by FW (such as skiboot) and resize the
+         * ESB window accordingly.
          */
-        memory_region_set_size(&xsrc->esb_mmio, pnv_xive_nr_ipis(xive) *
-                               (1ull << xsrc->esb_shift));
+        if (!(VSD_INDIRECT & vsd)) {
+            memory_region_set_size(&xsrc->esb_mmio, vst_tsize * SBE_PER_BYTE
+                                   * (1ull << xsrc->esb_shift));
+        }
         memory_region_add_subregion(&xive->ipi_edt_mmio, 0, &xsrc->esb_mmio);
         break;
 
@@ -1666,8 +1646,7 @@ void pnv_xive_pic_print_info(PnvXive *xive, Monitor *mon)
     XiveRouter *xrtr = XIVE_ROUTER(xive);
     uint8_t blk = xive->chip->chip_id;
     uint32_t srcno0 = XIVE_SRCNO(blk, 0);
-    uint32_t nr_ipis = pnv_xive_nr_ipis(xive);
-    uint32_t nr_ends = pnv_xive_nr_ends(xive);
+    uint32_t nr_ipis = pnv_xive_nr_ipis(xive, blk);
     XiveEAS eas;
     XiveEND end;
     int i;
@@ -1687,21 +1666,16 @@ void pnv_xive_pic_print_info(PnvXive *xive, Monitor *mon)
         }
     }
 
-    monitor_printf(mon, "XIVE[%x] ENDT %08x .. %08x\n", blk, 0, nr_ends - 1);
-    for (i = 0; i < nr_ends; i++) {
-        if (xive_router_get_end(xrtr, blk, i, &end)) {
-            break;
-        }
-        xive_end_pic_print_info(&end, i, mon);
+    monitor_printf(mon, "XIVE[%x] ENDT\n", blk);
+    i = 0;
+    while (!xive_router_get_end(xrtr, blk, i, &end)) {
+        xive_end_pic_print_info(&end, i++, mon);
     }
 
-    monitor_printf(mon, "XIVE[%x] END Escalation %08x .. %08x\n", blk, 0,
-                   nr_ends - 1);
-    for (i = 0; i < nr_ends; i++) {
-        if (xive_router_get_end(xrtr, blk, i, &end)) {
-            break;
-        }
-        xive_end_eas_pic_print_info(&end, i, mon);
+    monitor_printf(mon, "XIVE[%x] END Escalation EAT\n", blk);
+    i = 0;
+    while (!xive_router_get_end(xrtr, blk, i, &end)) {
+        xive_end_eas_pic_print_info(&end, i++, mon);
     }
 }
 
-- 
2.21.0



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

* [Qemu-devel] [PATCH v3 13/18] ppc/pnv: Dump the XIVE NVT table
  2019-07-31 14:12 [Qemu-devel] [PATCH v3 00/18] ppc/pnv: add XIVE support for KVM guests Cédric Le Goater
                   ` (11 preceding siblings ...)
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 12/18] ppc/pnv: Remove pnv_xive_vst_size() routine Cédric Le Goater
@ 2019-07-31 14:12 ` Cédric Le Goater
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 14/18] ppc/pnv: Skip empty slots of " Cédric Le Goater
                   ` (5 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Cédric Le Goater @ 2019-07-31 14:12 UTC (permalink / raw)
  To: David Gibson; +Cc: Cédric Le Goater, qemu-ppc, Greg Kurz, qemu-devel

This is to track the configuration of the base END index of the vCPU
and the Interrupt Pending Buffer. The NVT IPB is updated when an
interrupt can not be presented to a vCPU.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 include/hw/ppc/xive_regs.h |  2 ++
 hw/intc/pnv_xive.c         | 22 ++++++++++++++++++++++
 2 files changed, 24 insertions(+)

diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h
index 92ff80d25456..b228ab0ba3ea 100644
--- a/include/hw/ppc/xive_regs.h
+++ b/include/hw/ppc/xive_regs.h
@@ -229,6 +229,8 @@ typedef struct XiveNVT {
         uint32_t        w0;
 #define NVT_W0_VALID             PPC_BIT32(0)
         uint32_t        w1;
+#define NVT_W1_EQ_BLOCK          PPC_BITMASK32(0, 3)
+#define NVT_W1_EQ_INDEX          PPC_BITMASK32(4, 31)
         uint32_t        w2;
         uint32_t        w3;
         uint32_t        w4;
diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
index aba7a3f83dab..849291ee683e 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -1641,6 +1641,21 @@ static const MemoryRegionOps pnv_xive_pc_ops = {
     },
 };
 
+static void xive_nvt_pic_print_info(XiveNVT *nvt, uint32_t nvt_idx,
+                                    Monitor *mon)
+{
+    uint8_t  eq_blk = xive_get_field32(NVT_W1_EQ_BLOCK, nvt->w1);
+    uint32_t eq_idx = xive_get_field32(NVT_W1_EQ_INDEX, nvt->w1);
+
+    if (!xive_nvt_is_valid(nvt)) {
+        return;
+    }
+
+    monitor_printf(mon, "  %08x end:%02x/%04x IPB:%02x\n", nvt_idx,
+                   eq_blk, eq_idx,
+                   xive_get_field32(NVT_W4_IPB, nvt->w4));
+}
+
 void pnv_xive_pic_print_info(PnvXive *xive, Monitor *mon)
 {
     XiveRouter *xrtr = XIVE_ROUTER(xive);
@@ -1649,6 +1664,7 @@ void pnv_xive_pic_print_info(PnvXive *xive, Monitor *mon)
     uint32_t nr_ipis = pnv_xive_nr_ipis(xive, blk);
     XiveEAS eas;
     XiveEND end;
+    XiveNVT nvt;
     int i;
 
     monitor_printf(mon, "XIVE[%x] Source %08x .. %08x\n", blk, srcno0,
@@ -1677,6 +1693,12 @@ void pnv_xive_pic_print_info(PnvXive *xive, Monitor *mon)
     while (!xive_router_get_end(xrtr, blk, i, &end)) {
         xive_end_eas_pic_print_info(&end, i++, mon);
     }
+
+    monitor_printf(mon, "XIVE[%x] NVTT\n", blk);
+    i = 0;
+    while (!xive_router_get_nvt(xrtr, blk, i, &nvt)) {
+        xive_nvt_pic_print_info(&nvt, i++, mon);
+    }
 }
 
 static void pnv_xive_reset(void *dev)
-- 
2.21.0



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

* [Qemu-devel] [PATCH v3 14/18] ppc/pnv: Skip empty slots of the XIVE NVT table
  2019-07-31 14:12 [Qemu-devel] [PATCH v3 00/18] ppc/pnv: add XIVE support for KVM guests Cédric Le Goater
                   ` (12 preceding siblings ...)
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 13/18] ppc/pnv: Dump the XIVE NVT table Cédric Le Goater
@ 2019-07-31 14:12 ` Cédric Le Goater
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 15/18] ppc/pnv: Introduce a pnv_xive_block_id() helper Cédric Le Goater
                   ` (4 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Cédric Le Goater @ 2019-07-31 14:12 UTC (permalink / raw)
  To: David Gibson; +Cc: Cédric Le Goater, qemu-ppc, Greg Kurz, qemu-devel

We try to loop on the full table skipping empty indirect pages which
are not necessarily allocated. This is useful to dump the contexts of
the KVM vCPUs.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/intc/pnv_xive.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
index 849291ee683e..84fbfd8e27b0 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -1641,6 +1641,12 @@ static const MemoryRegionOps pnv_xive_pc_ops = {
     },
 };
 
+/*
+ * skiboot uses an indirect NVT table with 64k subpages
+ */
+#define XIVE_NVT_COUNT          (1 << XIVE_NVT_SHIFT)
+#define XIVE_NVT_PER_PAGE       (0x10000 / sizeof(XiveNVT))
+
 static void xive_nvt_pic_print_info(XiveNVT *nvt, uint32_t nvt_idx,
                                     Monitor *mon)
 {
@@ -1694,10 +1700,12 @@ void pnv_xive_pic_print_info(PnvXive *xive, Monitor *mon)
         xive_end_eas_pic_print_info(&end, i++, mon);
     }
 
-    monitor_printf(mon, "XIVE[%x] NVTT\n", blk);
-    i = 0;
-    while (!xive_router_get_nvt(xrtr, blk, i, &nvt)) {
-        xive_nvt_pic_print_info(&nvt, i++, mon);
+    monitor_printf(mon, "XIVE[%x] NVTT %08x .. %08x\n", blk, 0,
+                   XIVE_NVT_COUNT - 1);
+    for (i = 0; i < XIVE_NVT_COUNT; i += XIVE_NVT_PER_PAGE) {
+        while (!xive_router_get_nvt(xrtr, blk, i, &nvt)) {
+            xive_nvt_pic_print_info(&nvt, i++, mon);
+        }
     }
 }
 
-- 
2.21.0



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

* [Qemu-devel] [PATCH v3 15/18] ppc/pnv: Introduce a pnv_xive_block_id() helper
  2019-07-31 14:12 [Qemu-devel] [PATCH v3 00/18] ppc/pnv: add XIVE support for KVM guests Cédric Le Goater
                   ` (13 preceding siblings ...)
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 14/18] ppc/pnv: Skip empty slots of " Cédric Le Goater
@ 2019-07-31 14:12 ` Cédric Le Goater
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 16/18] ppc/pnv: Extend XivePresenter with a get_block_id() handler Cédric Le Goater
                   ` (3 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Cédric Le Goater @ 2019-07-31 14:12 UTC (permalink / raw)
  To: David Gibson; +Cc: Cédric Le Goater, qemu-ppc, Greg Kurz, qemu-devel

When PC_TCTXT_CHIPID_OVERRIDE is configured, the PC_TCTXT_CHIPID field
overrides the hardwired chip ID in the Powerbus operations and for CAM
compares. This is typically used in the one block-per-chip configuration
to associate a unique block id number to each IC of the system.

Simplify the model with a pnv_xive_block_id() helper and remove
'tctx_chipid' which becomes useless.

The model does support multiple blocks per chip.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 include/hw/ppc/pnv_xive.h |  3 --
 hw/intc/pnv_xive.c        | 68 ++++++++++++++++++++-------------------
 2 files changed, 35 insertions(+), 36 deletions(-)

diff --git a/include/hw/ppc/pnv_xive.h b/include/hw/ppc/pnv_xive.h
index 4fdaa9247d65..f4c7caad40ee 100644
--- a/include/hw/ppc/pnv_xive.h
+++ b/include/hw/ppc/pnv_xive.h
@@ -72,9 +72,6 @@ typedef struct PnvXive {
     /* Interrupt controller registers */
     uint64_t      regs[0x300];
 
-    /* Can be configured by FW */
-    uint32_t      tctx_chipid;
-
     /*
      * Virtual Structure Descriptor tables : EAT, SBE, ENDT, NVTT, IRQ
      * These are in a SRAM protected by ECC.
diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
index 84fbfd8e27b0..6b7078aa4fde 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -83,13 +83,30 @@ static inline uint64_t SETFIELD(uint64_t mask, uint64_t word,
     return (word & ~mask) | ((value << ctz64(mask)) & mask);
 }
 
+/*
+ * When PC_TCTXT_CHIPID_OVERRIDE is configured, the PC_TCTXT_CHIPID
+ * field overrides the hardwired chip ID in the Powerbus operations
+ * and for CAM compares
+ */
+static uint8_t pnv_xive_block_id(PnvXive *xive)
+{
+    uint8_t blk = xive->chip->chip_id;
+    uint64_t cfg_val = xive->regs[PC_TCTXT_CFG >> 3];
+
+    if (cfg_val & PC_TCTXT_CHIPID_OVERRIDE) {
+        blk = GETFIELD(PC_TCTXT_CHIPID, cfg_val);
+    }
+
+    return blk;
+}
+
 /*
  * Remote access to controllers. HW uses MMIOs. For now, a simple scan
  * of the chips is good enough.
  *
  * TODO: Block scope support
  */
-static PnvXive *pnv_xive_get_ic(uint8_t blk)
+static PnvXive *pnv_xive_get_remote(uint8_t blk)
 {
     PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine());
     int i;
@@ -98,7 +115,7 @@ static PnvXive *pnv_xive_get_ic(uint8_t blk)
         Pnv9Chip *chip9 = PNV9_CHIP(pnv->chips[i]);
         PnvXive *xive = &chip9->xive;
 
-        if (xive->chip->chip_id == blk) {
+        if (pnv_xive_block_id(xive) == blk) {
             return xive;
         }
     }
@@ -210,7 +227,7 @@ static uint64_t pnv_xive_vst_addr(PnvXive *xive, uint32_t type, uint8_t blk,
 
     /* Remote VST access */
     if (GETFIELD(VSD_MODE, vsd) == VSD_MODE_FORWARD) {
-        xive = pnv_xive_get_ic(blk);
+        xive = pnv_xive_get_remote(blk);
 
         return xive ? pnv_xive_vst_addr(xive, type, blk, idx) : 0;
     }
@@ -358,7 +375,10 @@ static int pnv_xive_get_eas(XiveRouter *xrtr, uint8_t blk, uint32_t idx,
 {
     PnvXive *xive = PNV_XIVE(xrtr);
 
-    if (pnv_xive_get_ic(blk) != xive) {
+    /*
+     * EAT lookups should be local to the IC
+     */
+    if (pnv_xive_block_id(xive) != blk) {
         xive_error(xive, "VST: EAS %x is remote !?", XIVE_SRCNO(blk, idx));
         return -1;
     }
@@ -471,7 +491,7 @@ static PnvXive *pnv_xive_tm_get_xive(PowerPCCPU *cpu)
 static void pnv_xive_notify(XiveNotifier *xn, uint32_t srcno)
 {
     PnvXive *xive = PNV_XIVE(xn);
-    uint8_t blk = xive->chip->chip_id;
+    uint8_t blk = pnv_xive_block_id(xive);
 
     xive_router_notify(xn, XIVE_SRCNO(blk, srcno));
 }
@@ -835,20 +855,7 @@ static void pnv_xive_ic_reg_write(void *opaque, hwaddr offset,
     case PC_TCTXT_CFG:
         /*
          * TODO: block group support
-         *
-         * PC_TCTXT_CFG_BLKGRP_EN
-         * PC_TCTXT_CFG_HARD_CHIPID_BLK :
-         *   Moves the chipid into block field for hardwired CAM compares.
-         *   Block offset value is adjusted to 0b0..01 & ThrdId
-         *
-         *   Will require changes in xive_presenter_tctx_match(). I am
-         *   not sure how to handle that yet.
          */
-
-        /* Overrides hardwired chip ID with the chip ID field */
-        if (val & PC_TCTXT_CHIPID_OVERRIDE) {
-            xive->tctx_chipid = GETFIELD(PC_TCTXT_CHIPID, val);
-        }
         break;
     case PC_TCTXT_TRACK:
         /*
@@ -1665,7 +1672,8 @@ static void xive_nvt_pic_print_info(XiveNVT *nvt, uint32_t nvt_idx,
 void pnv_xive_pic_print_info(PnvXive *xive, Monitor *mon)
 {
     XiveRouter *xrtr = XIVE_ROUTER(xive);
-    uint8_t blk = xive->chip->chip_id;
+    uint8_t blk = pnv_xive_block_id(xive);
+    uint8_t chip_id = xive->chip->chip_id;
     uint32_t srcno0 = XIVE_SRCNO(blk, 0);
     uint32_t nr_ipis = pnv_xive_nr_ipis(xive, blk);
     XiveEAS eas;
@@ -1673,12 +1681,12 @@ void pnv_xive_pic_print_info(PnvXive *xive, Monitor *mon)
     XiveNVT nvt;
     int i;
 
-    monitor_printf(mon, "XIVE[%x] Source %08x .. %08x\n", blk, srcno0,
-                   srcno0 + nr_ipis - 1);
+    monitor_printf(mon, "XIVE[%x] #%d Source %08x .. %08x\n", chip_id, blk,
+                   srcno0, srcno0 + nr_ipis - 1);
     xive_source_pic_print_info(&xive->ipi_source, srcno0, mon);
 
-    monitor_printf(mon, "XIVE[%x] EAT %08x .. %08x\n", blk, srcno0,
-                   srcno0 + nr_ipis - 1);
+    monitor_printf(mon, "XIVE[%x] #%d EAT %08x .. %08x\n", chip_id, blk,
+                   srcno0, srcno0 + nr_ipis - 1);
     for (i = 0; i < nr_ipis; i++) {
         if (xive_router_get_eas(xrtr, blk, i, &eas)) {
             break;
@@ -1688,20 +1696,20 @@ void pnv_xive_pic_print_info(PnvXive *xive, Monitor *mon)
         }
     }
 
-    monitor_printf(mon, "XIVE[%x] ENDT\n", blk);
+    monitor_printf(mon, "XIVE[%x] #%d ENDT\n", chip_id, blk);
     i = 0;
     while (!xive_router_get_end(xrtr, blk, i, &end)) {
         xive_end_pic_print_info(&end, i++, mon);
     }
 
-    monitor_printf(mon, "XIVE[%x] END Escalation EAT\n", blk);
+    monitor_printf(mon, "XIVE[%x] #%d END Escalation EAT\n", chip_id, blk);
     i = 0;
     while (!xive_router_get_end(xrtr, blk, i, &end)) {
         xive_end_eas_pic_print_info(&end, i++, mon);
     }
 
-    monitor_printf(mon, "XIVE[%x] NVTT %08x .. %08x\n", blk, 0,
-                   XIVE_NVT_COUNT - 1);
+    monitor_printf(mon, "XIVE[%x] #%d NVTT %08x .. %08x\n", chip_id, blk,
+                   0, XIVE_NVT_COUNT - 1);
     for (i = 0; i < XIVE_NVT_COUNT; i += XIVE_NVT_PER_PAGE) {
         while (!xive_router_get_nvt(xrtr, blk, i, &nvt)) {
             xive_nvt_pic_print_info(&nvt, i++, mon);
@@ -1715,12 +1723,6 @@ static void pnv_xive_reset(void *dev)
     XiveSource *xsrc = &xive->ipi_source;
     XiveENDSource *end_xsrc = &xive->end_source;
 
-    /*
-     * Use the PnvChip id to identify the XIVE interrupt controller.
-     * It can be overriden by configuration at runtime.
-     */
-    xive->tctx_chipid = xive->chip->chip_id;
-
     /* Default page size (Should be changed at runtime to 64k) */
     xive->ic_shift = xive->vc_shift = xive->pc_shift = 12;
 
-- 
2.21.0



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

* [Qemu-devel] [PATCH v3 16/18] ppc/pnv: Extend XivePresenter with a get_block_id() handler
  2019-07-31 14:12 [Qemu-devel] [PATCH v3 00/18] ppc/pnv: add XIVE support for KVM guests Cédric Le Goater
                   ` (14 preceding siblings ...)
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 15/18] ppc/pnv: Introduce a pnv_xive_block_id() helper Cédric Le Goater
@ 2019-07-31 14:12 ` Cédric Le Goater
  2019-09-02  8:49   ` Cédric Le Goater
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 17/18] ppc/pnv: Quiesce some XIVE errors Cédric Le Goater
                   ` (2 subsequent siblings)
  18 siblings, 1 reply; 26+ messages in thread
From: Cédric Le Goater @ 2019-07-31 14:12 UTC (permalink / raw)
  To: David Gibson; +Cc: Cédric Le Goater, qemu-ppc, Greg Kurz, qemu-devel

When doing CAM line compares, fetch the block id from the interrupt
controller which can have set the PC_TCTXT_CHIPID field.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 include/hw/ppc/xive.h | 1 +
 hw/intc/pnv_xive.c    | 6 ++++++
 hw/intc/spapr_xive.c  | 6 ++++++
 hw/intc/xive.c        | 8 +++++---
 4 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
index e16c3b63fc44..d68fb6eea46e 100644
--- a/include/hw/ppc/xive.h
+++ b/include/hw/ppc/xive.h
@@ -391,6 +391,7 @@ typedef struct XivePresenterClass {
                      uint8_t nvt_blk, uint32_t nvt_idx,
                      bool cam_ignore, uint8_t priority,
                      uint32_t logic_serv, XiveTCTXMatch *match);
+    uint8_t (*get_block_id)(XivePresenter *xptr);
 } XivePresenterClass;
 
 int xive_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx,
diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
index 6b7078aa4fde..8e3ba23788f7 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -460,6 +460,11 @@ static int pnv_xive_match_nvt(XivePresenter *xptr, uint8_t format,
     return count;
 }
 
+static uint8_t pnv_xive_get_block_id(XivePresenter *xptr)
+{
+    return pnv_xive_block_id(PNV_XIVE(xptr));
+}
+
 /*
  * The TIMA MMIO space is shared among the chips and to identify the
  * chip from which the access is being done, we extract the chip id
@@ -1918,6 +1923,7 @@ static void pnv_xive_class_init(ObjectClass *klass, void *data)
 
     xnc->notify = pnv_xive_notify;
     xpc->match_nvt  = pnv_xive_match_nvt;
+    xpc->get_block_id = pnv_xive_get_block_id;
 };
 
 static const TypeInfo pnv_xive_info = {
diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index 4abb099d341c..26fc815d3931 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -479,6 +479,11 @@ static int spapr_xive_match_nvt(XivePresenter *xptr, uint8_t format,
     return count;
 }
 
+static uint8_t spapr_xive_get_block_id(XivePresenter *xrtr)
+{
+    return SPAPR_XIVE_BLOCK_ID;
+}
+
 static const VMStateDescription vmstate_spapr_xive_end = {
     .name = TYPE_SPAPR_XIVE "/end",
     .version_id = 1,
@@ -570,6 +575,7 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data)
     xrc->write_nvt = spapr_xive_write_nvt;
 
     xpc->match_nvt  = spapr_xive_match_nvt;
+    xpc->get_block_id = spapr_xive_get_block_id;
 }
 
 static const TypeInfo spapr_xive_info = {
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 9b02ce423d66..e79439f6b940 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -1305,12 +1305,14 @@ int xive_router_write_nvt(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx,
  *
  *   chip << 19 | 0000000 0 0001 thread (7Bit)
  */
-static uint32_t xive_tctx_hw_cam_line(XiveTCTX *tctx)
+static uint32_t xive_tctx_hw_cam_line(XivePresenter *xptr, XiveTCTX *tctx)
 {
     CPUPPCState *env = &POWERPC_CPU(tctx->cs)->env;
     uint32_t pir = env->spr_cb[SPR_PIR].default_value;
+    XivePresenterClass *xpc = XIVE_PRESENTER_GET_CLASS(xptr);
+    uint8_t blk = xpc->get_block_id(xptr);
 
-    return xive_nvt_cam_line((pir >> 8) & 0xf, 1 << 7 | (pir & 0x7f));
+    return xive_nvt_cam_line(blk, 1 << 7 | (pir & 0x7f));
 }
 
 /*
@@ -1347,7 +1349,7 @@ int xive_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx,
 
         /* PHYS ring */
         if ((be32_to_cpu(qw3w2) & TM_QW3W2_VT) &&
-            cam == xive_tctx_hw_cam_line(tctx)) {
+            cam == xive_tctx_hw_cam_line(xptr, tctx)) {
             return TM_QW3_HV_PHYS;
         }
 
-- 
2.21.0



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

* [Qemu-devel] [PATCH v3 17/18] ppc/pnv: Quiesce some XIVE errors
  2019-07-31 14:12 [Qemu-devel] [PATCH v3 00/18] ppc/pnv: add XIVE support for KVM guests Cédric Le Goater
                   ` (15 preceding siblings ...)
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 16/18] ppc/pnv: Extend XivePresenter with a get_block_id() handler Cédric Le Goater
@ 2019-07-31 14:12 ` Cédric Le Goater
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 18/18] ppc/xive: Introduce a xive_os_cam_decode() helper Cédric Le Goater
  2019-09-17 11:54 ` [Qemu-devel] [PATCH v3 00/18] ppc/pnv: add XIVE support for KVM guests Cédric Le Goater
  18 siblings, 0 replies; 26+ messages in thread
From: Cédric Le Goater @ 2019-07-31 14:12 UTC (permalink / raw)
  To: David Gibson; +Cc: Cédric Le Goater, qemu-ppc, Greg Kurz, qemu-devel

When dumping the END and NVT tables, the error logging is too noisy.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/intc/pnv_xive.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
index 8e3ba23788f7..df0b17772c0d 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -27,7 +27,7 @@
 
 #include "pnv_xive_regs.h"
 
-#define XIVE_DEBUG
+#undef XIVE_DEBUG
 
 /*
  * Virtual structures table (VST)
@@ -172,7 +172,9 @@ static uint64_t pnv_xive_vst_addr_indirect(PnvXive *xive, uint32_t type,
     vsd = ldq_be_dma(&address_space_memory, vsd_addr);
 
     if (!(vsd & VSD_ADDRESS_MASK)) {
+#ifdef XIVE_DEBUG
         xive_error(xive, "VST: invalid %s entry %x !?", info->name, idx);
+#endif
         return 0;
     }
 
@@ -193,7 +195,9 @@ static uint64_t pnv_xive_vst_addr_indirect(PnvXive *xive, uint32_t type,
         vsd = ldq_be_dma(&address_space_memory, vsd_addr);
 
         if (!(vsd & VSD_ADDRESS_MASK)) {
+#ifdef XIVE_DEBUG
             xive_error(xive, "VST: invalid %s entry %x !?", info->name, idx);
+#endif
             return 0;
         }
 
-- 
2.21.0



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

* [Qemu-devel] [PATCH v3 18/18] ppc/xive: Introduce a xive_os_cam_decode() helper
  2019-07-31 14:12 [Qemu-devel] [PATCH v3 00/18] ppc/pnv: add XIVE support for KVM guests Cédric Le Goater
                   ` (16 preceding siblings ...)
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 17/18] ppc/pnv: Quiesce some XIVE errors Cédric Le Goater
@ 2019-07-31 14:12 ` Cédric Le Goater
  2019-09-17 11:54 ` [Qemu-devel] [PATCH v3 00/18] ppc/pnv: add XIVE support for KVM guests Cédric Le Goater
  18 siblings, 0 replies; 26+ messages in thread
From: Cédric Le Goater @ 2019-07-31 14:12 UTC (permalink / raw)
  To: David Gibson; +Cc: Cédric Le Goater, qemu-ppc, Greg Kurz, qemu-devel

The OS CAM line has a special encoding exploited by the HW. Provide a
helper routine to hide the details to the TIMA command handlers. This
also clarifies the endianness of different variables : 'qw1w2' is
big-endian and 'cam' is native.

Also add a check on the V bit in the TM_PULL_POOL_CTX special
operation.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/intc/xive.c | 40 +++++++++++++++++++++++++++++++---------
 1 file changed, 31 insertions(+), 9 deletions(-)

diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index e79439f6b940..bdc36f2a1b0b 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -339,14 +339,34 @@ static void xive_tm_set_os_pending(XivePresenter *xptr, XiveTCTX *tctx,
     xive_tctx_ipb_update(tctx, TM_QW1_OS, priority_to_ipb(value & 0xff));
 }
 
+static void xive_os_cam_decode(uint32_t cam, uint8_t *nvt_blk,
+                               uint32_t *nvt_idx, bool *vo)
+{
+    *nvt_blk = xive_nvt_blk(cam);
+    *nvt_idx = xive_nvt_idx(cam);
+    *vo = !!(cam & TM_QW1W2_VO);
+}
+
 static uint64_t xive_tm_pull_os_ctx(XivePresenter *xptr, XiveTCTX *tctx,
                                     hwaddr offset, unsigned size)
 {
-    uint32_t qw1w2_prev = xive_tctx_word2(&tctx->regs[TM_QW1_OS]);
-    uint32_t qw1w2;
+    uint32_t qw1w2 = xive_tctx_word2(&tctx->regs[TM_QW1_OS]);
+    uint32_t qw1w2_new;
+    uint32_t cam = be32_to_cpu(qw1w2);
+    uint8_t nvt_blk;
+    uint32_t nvt_idx;
+    bool vo;
 
-    qw1w2 = xive_set_field32(TM_QW1W2_VO, qw1w2_prev, 0);
-    memcpy(&tctx->regs[TM_QW1_OS + TM_WORD2], &qw1w2, 4);
+    xive_os_cam_decode(cam, &nvt_blk, &nvt_idx, &vo);
+
+    if (!vo) {
+        qemu_log_mask(LOG_GUEST_ERROR, "XIVE: pulling invalid NVT %x/%x !?\n",
+                      nvt_blk, nvt_idx);
+    }
+
+    /* Invalidate CAM line */
+    qw1w2_new = xive_set_field32(TM_QW1W2_VO, qw1w2, 0);
+    memcpy(&tctx->regs[TM_QW1_OS + TM_WORD2], &qw1w2_new, 4);
     return qw1w2;
 }
 
@@ -384,13 +404,15 @@ static void xive_tctx_need_resend(XiveRouter *xrtr, XiveTCTX *tctx,
 static void xive_tm_push_os_ctx(XivePresenter *xptr, XiveTCTX *tctx,
                                 hwaddr offset, uint64_t value, unsigned size)
 {
-    uint32_t qw1w2 = value;
-    uint8_t nvt_blk = xive_nvt_blk(qw1w2);
-    uint32_t nvt_idx = xive_nvt_idx(qw1w2);
-    bool vo = !!(qw1w2 & TM_QW1W2_VO);
+    uint32_t cam = value;
+    uint32_t qw1w2 = cpu_to_be32(cam);
+    uint8_t nvt_blk;
+    uint32_t nvt_idx;
+    bool vo;
+
+    xive_os_cam_decode(cam, &nvt_blk, &nvt_idx, &vo);
 
     /* First update the registers */
-    qw1w2 = cpu_to_be32(qw1w2);
     memcpy(&tctx->regs[TM_QW1_OS + TM_WORD2], &qw1w2, 4);
 
     /* Check the interrupt pending bits */
-- 
2.21.0



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

* Re: [Qemu-devel] [PATCH v3 04/18] ppc/pnv: Implement the XiveFabric and XivePresenter interfaces
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 04/18] ppc/pnv: Implement " Cédric Le Goater
@ 2019-07-31 14:21   ` Cédric Le Goater
  0 siblings, 0 replies; 26+ messages in thread
From: Cédric Le Goater @ 2019-07-31 14:21 UTC (permalink / raw)
  To: David Gibson; +Cc: Peter Maydell, qemu-ppc, Greg Kurz, qemu-devel

On 31/07/2019 16:12, Cédric Le Goater wrote:
> The CAM line matching on the PowerNV machine now scans all chips of
> the system and all CPUs of a chip to find a dispatched NVT in the
> thread contexts.
> 
> As there is now easy way to loop on the CPUs belonging to a chip, the
> PowerNV handler loops on all CPUs and filter out the external CPUs.
> 
> Fixes: af53dbf6227a ("ppc/xive: introduce a simplified XIVE presenter")
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
>  hw/intc/pnv_xive.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++
>  hw/ppc/pnv.c       | 32 +++++++++++++++++++
>  2 files changed, 108 insertions(+)
> 
> diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
> index ff1226485983..183798b81496 100644
> --- a/hw/intc/pnv_xive.c
> +++ b/hw/intc/pnv_xive.c
> @@ -390,6 +390,80 @@ static int pnv_xive_get_eas(XiveRouter *xrtr, uint8_t blk, uint32_t idx,
>      return pnv_xive_vst_read(xive, VST_TSEL_IVT, blk, idx, eas);
>  }
>  
> +static int cpu_pir(PowerPCCPU *cpu)
> +{
> +    CPUPPCState *env = &cpu->env;
> +    return env->spr_cb[SPR_PIR].default_value;
> +}
> +
> +static int cpu_chip_id(PowerPCCPU *cpu)
> +{
> +    int pir = cpu_pir(cpu);
> +    return (pir >> 8) & 0x7f;
> +}
> +
> +static bool pnv_xive_is_cpu_enabled(PnvXive *xive, PowerPCCPU *cpu)
> +{
> +    int pir = cpu_pir(cpu);
> +    int thrd_id = pir & 0x7f;
> +
> +    return xive->regs[PC_THREAD_EN_REG0 >> 3] & PPC_BIT(thrd_id);
> +}
> +
> +static bool pnv_xive_is_ignored(PnvChip *chip, CPUState *cs)
> +{
> +    return chip->chip_id != cpu_chip_id(POWERPC_CPU(cs));
> +}
> +
> +#define PNV_CHIP_CPU_FOREACH(chip, cs)                                  \
> +    CPU_FOREACH(cs)                                                     \
> +        if (pnv_xive_is_ignored(chip, cs)) {} else

patchew will complain here but I think we can consider it as an exception
since it is inspired from the macros in migration/ram.c ?

Thanks, 

C. 




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

* Re: [Qemu-devel] [PATCH v3 01/18] ppc/pnv: Introduce PowerNV machines with fixed CPU models
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 01/18] ppc/pnv: Introduce PowerNV machines with fixed CPU models Cédric Le Goater
@ 2019-08-05 10:46   ` David Gibson
  0 siblings, 0 replies; 26+ messages in thread
From: David Gibson @ 2019-08-05 10:46 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, Greg Kurz, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 5859 bytes --]

On Wed, Jul 31, 2019 at 04:12:16PM +0200, Cédric Le Goater wrote:
> Make the current "powernv" machine an abstract type and derive from it
> new machines with specific CPU models: power8 and power9.
> 
> The "powernv" machine is now an alias on the "powernv9" machine.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Applied to ppc-for-4.2.

> ---
>  hw/ppc/pnv.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++------
>  1 file changed, 63 insertions(+), 7 deletions(-)
> 
> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
> index 4570ce8afe6a..18602b9e9bcd 100644
> --- a/hw/ppc/pnv.c
> +++ b/hw/ppc/pnv.c
> @@ -602,9 +602,20 @@ static void pnv_chip_power9_pic_print_info(PnvChip *chip, Monitor *mon)
>      pnv_psi_pic_print_info(&chip9->psi, mon);
>  }
>  
> +static bool pnv_match_cpu(const char *default_type, const char *cpu_type)
> +{
> +    PowerPCCPUClass *ppc_default =
> +        POWERPC_CPU_CLASS(object_class_by_name(default_type));
> +    PowerPCCPUClass *ppc =
> +        POWERPC_CPU_CLASS(object_class_by_name(cpu_type));
> +
> +    return ppc_default->pvr_match(ppc_default, ppc->pvr);
> +}
> +
>  static void pnv_init(MachineState *machine)
>  {
>      PnvMachineState *pnv = PNV_MACHINE(machine);
> +    MachineClass *mc = MACHINE_GET_CLASS(machine);
>      MemoryRegion *ram;
>      char *fw_filename;
>      long fw_size;
> @@ -664,13 +675,23 @@ static void pnv_init(MachineState *machine)
>          }
>      }
>  
> +    /*
> +     * Check compatibility of the specified CPU with the machine
> +     * default.
> +     */
> +    if (!pnv_match_cpu(mc->default_cpu_type, machine->cpu_type)) {
> +        error_report("invalid CPU model '%s' for %s machine",
> +                     machine->cpu_type, mc->name);
> +        exit(1);
> +    }
> +
>      /* Create the processor chips */
>      i = strlen(machine->cpu_type) - strlen(POWERPC_CPU_TYPE_SUFFIX);
>      chip_typename = g_strdup_printf(PNV_CHIP_TYPE_NAME("%.*s"),
>                                      i, machine->cpu_type);
>      if (!object_class_by_name(chip_typename)) {
> -        error_report("invalid CPU model '%.*s' for %s machine",
> -                     i, machine->cpu_type, MACHINE_GET_CLASS(machine)->name);
> +        error_report("invalid chip model '%.*s' for %s machine",
> +                     i, machine->cpu_type, mc->name);
>          exit(1);
>      }
>  
> @@ -1348,25 +1369,43 @@ static void pnv_machine_class_props_init(ObjectClass *oc)
>                                NULL);
>  }
>  
> -static void pnv_machine_class_init(ObjectClass *oc, void *data)
> +static void pnv_machine_power8_class_init(ObjectClass *oc, void *data)
>  {
>      MachineClass *mc = MACHINE_CLASS(oc);
>      XICSFabricClass *xic = XICS_FABRIC_CLASS(oc);
> +
> +    mc->desc = "IBM PowerNV (Non-Virtualized) POWER8";
> +    mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power8_v2.0");
> +
> +    xic->icp_get = pnv_icp_get;
> +    xic->ics_get = pnv_ics_get;
> +    xic->ics_resend = pnv_ics_resend;
> +}
> +
> +static void pnv_machine_power9_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +
> +    mc->desc = "IBM PowerNV (Non-Virtualized) POWER9";
> +    mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power9_v2.0");
> +
> +    mc->alias = "powernv";
> +}
> +
> +static void pnv_machine_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
>      InterruptStatsProviderClass *ispc = INTERRUPT_STATS_PROVIDER_CLASS(oc);
>  
>      mc->desc = "IBM PowerNV (Non-Virtualized)";
>      mc->init = pnv_init;
>      mc->reset = pnv_reset;
>      mc->max_cpus = MAX_CPUS;
> -    mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power8_v2.0");
>      mc->block_default_type = IF_IDE; /* Pnv provides a AHCI device for
>                                        * storage */
>      mc->no_parallel = 1;
>      mc->default_boot_order = NULL;
>      mc->default_ram_size = 2 * GiB;
> -    xic->icp_get = pnv_icp_get;
> -    xic->ics_get = pnv_ics_get;
> -    xic->ics_resend = pnv_ics_resend;
>      ispc->print_info = pnv_pic_print_info;
>  
>      pnv_machine_class_props_init(oc);
> @@ -1386,10 +1425,27 @@ static void pnv_machine_class_init(ObjectClass *oc, void *data)
>          .parent        = TYPE_PNV9_CHIP,          \
>      }
>  
> +#define DEFINE_PNV_MACHINE_TYPE(cpu, class_initfn)      \
> +    {                                                   \
> +        .name          = MACHINE_TYPE_NAME(cpu),        \
> +        .parent        = TYPE_PNV_MACHINE,              \
> +        .instance_size = sizeof(PnvMachineState),       \
> +        .instance_init = pnv_machine_instance_init,     \
> +        .class_init    = class_initfn,                  \
> +        .interfaces = (InterfaceInfo[]) {               \
> +            { TYPE_XICS_FABRIC },                       \
> +            { TYPE_INTERRUPT_STATS_PROVIDER },          \
> +            { },                                        \
> +        },                                              \
> +    }
> +
>  static const TypeInfo types[] = {
> +    DEFINE_PNV_MACHINE_TYPE("powernv8", pnv_machine_power8_class_init),
> +    DEFINE_PNV_MACHINE_TYPE("powernv9", pnv_machine_power9_class_init),
>      {
>          .name          = TYPE_PNV_MACHINE,
>          .parent        = TYPE_MACHINE,
> +        .abstract       = true,
>          .instance_size = sizeof(PnvMachineState),
>          .instance_init = pnv_machine_instance_init,
>          .class_init    = pnv_machine_class_init,

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [Qemu-devel] [PATCH v3 02/18] tests/boot-serial-test: add support for all the PowerNV machines
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 02/18] tests/boot-serial-test: add support for all the PowerNV machines Cédric Le Goater
@ 2019-08-05 12:30   ` David Gibson
  0 siblings, 0 replies; 26+ messages in thread
From: David Gibson @ 2019-08-05 12:30 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, Greg Kurz, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 1210 bytes --]

On Wed, Jul 31, 2019 at 04:12:17PM +0200, Cédric Le Goater wrote:
> Use the machine names specifiying the CPU type, POWER8 and POWER9.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Applied to ppc-for-4.2, thanks.

> ---
>  tests/boot-serial-test.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/tests/boot-serial-test.c b/tests/boot-serial-test.c
> index 24852d4c7d0b..a54d007298f7 100644
> --- a/tests/boot-serial-test.c
> +++ b/tests/boot-serial-test.c
> @@ -103,7 +103,8 @@ static testdef_t tests[] = {
>      { "ppc64", "pseries",
>        "-machine cap-cfpc=broken,cap-sbbc=broken,cap-ibs=broken",
>        "Open Firmware" },
> -    { "ppc64", "powernv", "-cpu POWER8", "OPAL" },
> +    { "ppc64", "powernv8", "", "OPAL" },
> +    { "ppc64", "powernv9", "", "OPAL" },
>      { "ppc64", "sam460ex", "-device e1000", "8086  100e" },
>      { "i386", "isapc", "-cpu qemu32 -device sga", "SGABIOS" },
>      { "i386", "pc", "-device sga", "SGABIOS" },

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [Qemu-devel] [PATCH v3 16/18] ppc/pnv: Extend XivePresenter with a get_block_id() handler
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 16/18] ppc/pnv: Extend XivePresenter with a get_block_id() handler Cédric Le Goater
@ 2019-09-02  8:49   ` Cédric Le Goater
  0 siblings, 0 replies; 26+ messages in thread
From: Cédric Le Goater @ 2019-09-02  8:49 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, Greg Kurz, qemu-devel

Hello David,

On 31/07/2019 16:12, Cédric Le Goater wrote:
> When doing CAM line compares, fetch the block id from the interrupt
> controller which can have set the PC_TCTXT_CHIPID field.

I don't know if you had time to review the rest of this patchset. 

I would prefer to move the get_block_id() in XiveRouter, we could get
rid of the 'block_id' field in the XiveEndSource.

Thanks,

C.


> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
>  include/hw/ppc/xive.h | 1 +
>  hw/intc/pnv_xive.c    | 6 ++++++
>  hw/intc/spapr_xive.c  | 6 ++++++
>  hw/intc/xive.c        | 8 +++++---
>  4 files changed, 18 insertions(+), 3 deletions(-)
> 
> diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
> index e16c3b63fc44..d68fb6eea46e 100644
> --- a/include/hw/ppc/xive.h
> +++ b/include/hw/ppc/xive.h
> @@ -391,6 +391,7 @@ typedef struct XivePresenterClass {
>                       uint8_t nvt_blk, uint32_t nvt_idx,
>                       bool cam_ignore, uint8_t priority,
>                       uint32_t logic_serv, XiveTCTXMatch *match);
> +    uint8_t (*get_block_id)(XivePresenter *xptr);
>  } XivePresenterClass;
>  
>  int xive_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx,
> diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
> index 6b7078aa4fde..8e3ba23788f7 100644
> --- a/hw/intc/pnv_xive.c
> +++ b/hw/intc/pnv_xive.c
> @@ -460,6 +460,11 @@ static int pnv_xive_match_nvt(XivePresenter *xptr, uint8_t format,
>      return count;
>  }
>  
> +static uint8_t pnv_xive_get_block_id(XivePresenter *xptr)
> +{
> +    return pnv_xive_block_id(PNV_XIVE(xptr));
> +}
> +
>  /*
>   * The TIMA MMIO space is shared among the chips and to identify the
>   * chip from which the access is being done, we extract the chip id
> @@ -1918,6 +1923,7 @@ static void pnv_xive_class_init(ObjectClass *klass, void *data)
>  
>      xnc->notify = pnv_xive_notify;
>      xpc->match_nvt  = pnv_xive_match_nvt;
> +    xpc->get_block_id = pnv_xive_get_block_id;
>  };
>  
>  static const TypeInfo pnv_xive_info = {
> diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
> index 4abb099d341c..26fc815d3931 100644
> --- a/hw/intc/spapr_xive.c
> +++ b/hw/intc/spapr_xive.c
> @@ -479,6 +479,11 @@ static int spapr_xive_match_nvt(XivePresenter *xptr, uint8_t format,
>      return count;
>  }
>  
> +static uint8_t spapr_xive_get_block_id(XivePresenter *xrtr)
> +{
> +    return SPAPR_XIVE_BLOCK_ID;
> +}
> +
>  static const VMStateDescription vmstate_spapr_xive_end = {
>      .name = TYPE_SPAPR_XIVE "/end",
>      .version_id = 1,
> @@ -570,6 +575,7 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data)
>      xrc->write_nvt = spapr_xive_write_nvt;
>  
>      xpc->match_nvt  = spapr_xive_match_nvt;
> +    xpc->get_block_id = spapr_xive_get_block_id;
>  }
>  
>  static const TypeInfo spapr_xive_info = {
> diff --git a/hw/intc/xive.c b/hw/intc/xive.c
> index 9b02ce423d66..e79439f6b940 100644
> --- a/hw/intc/xive.c
> +++ b/hw/intc/xive.c
> @@ -1305,12 +1305,14 @@ int xive_router_write_nvt(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx,
>   *
>   *   chip << 19 | 0000000 0 0001 thread (7Bit)
>   */
> -static uint32_t xive_tctx_hw_cam_line(XiveTCTX *tctx)
> +static uint32_t xive_tctx_hw_cam_line(XivePresenter *xptr, XiveTCTX *tctx)
>  {
>      CPUPPCState *env = &POWERPC_CPU(tctx->cs)->env;
>      uint32_t pir = env->spr_cb[SPR_PIR].default_value;
> +    XivePresenterClass *xpc = XIVE_PRESENTER_GET_CLASS(xptr);
> +    uint8_t blk = xpc->get_block_id(xptr);
>  
> -    return xive_nvt_cam_line((pir >> 8) & 0xf, 1 << 7 | (pir & 0x7f));
> +    return xive_nvt_cam_line(blk, 1 << 7 | (pir & 0x7f));
>  }
>  
>  /*
> @@ -1347,7 +1349,7 @@ int xive_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx,
>  
>          /* PHYS ring */
>          if ((be32_to_cpu(qw3w2) & TM_QW3W2_VT) &&
> -            cam == xive_tctx_hw_cam_line(tctx)) {
> +            cam == xive_tctx_hw_cam_line(xptr, tctx)) {
>              return TM_QW3_HV_PHYS;
>          }
>  
> 



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

* Re: [Qemu-devel] [PATCH v3 00/18] ppc/pnv: add XIVE support for KVM guests
  2019-07-31 14:12 [Qemu-devel] [PATCH v3 00/18] ppc/pnv: add XIVE support for KVM guests Cédric Le Goater
                   ` (17 preceding siblings ...)
  2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 18/18] ppc/xive: Introduce a xive_os_cam_decode() helper Cédric Le Goater
@ 2019-09-17 11:54 ` Cédric Le Goater
  2019-09-18  5:44   ` David Gibson
  18 siblings, 1 reply; 26+ messages in thread
From: Cédric Le Goater @ 2019-09-17 11:54 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, Greg Kurz, qemu-devel

On 31/07/2019 16:12, Cédric Le Goater wrote:
> Hello,
> 
> The QEMU PowerNV machine emulates a baremetal OpenPOWER system and
> acts as an hypervisor (L0). Supporting emulation of KVM to run guests
> (L1) requires a few more extensions, among which guest support for the
> XIVE interrupt controller on POWER9 processor.
> 
> The following changes add new per-CPU PowerNV machines and extend the
> XIVE models with the new XiveFabric and XivePresenter interfaces to
> provide support for XIVE escalations and interrupt resend. This
> mechanism is used by XIVE to notify the hypervisor that a vCPU is not
> dispatched on a HW thread. Tested on a QEMU PowerNV machine and a
> simple QEMU pseries guest doing network on a local bridge.
> 
> The XIVE interrupt controller offers a way to increase the XIVE
> resources per chip by configuring multiple XIVE blocks on a chip. This
> is not currently supported by the model. However, some configurations,
> such as OPAL/skiboot, use one block-per-chip configuration with some
> optimizations. One of them is to override the hardwired chip ID by the
> block id in the PowerBUS operations and for CAM line compares. This
> patchset improves the support for this setup. Tested with 4 chips.

David,

Do you want me to resend this patchset ? or you just didn't have time
to look at it ?  

Patch 16 has changed a little since. The get_block_id() handler has 
moved to the XiveRouterClass.


Thanks,

Thanks,

C.


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

* Re: [Qemu-devel] [PATCH v3 00/18] ppc/pnv: add XIVE support for KVM guests
  2019-09-17 11:54 ` [Qemu-devel] [PATCH v3 00/18] ppc/pnv: add XIVE support for KVM guests Cédric Le Goater
@ 2019-09-18  5:44   ` David Gibson
  2019-09-18  8:53     ` Cédric Le Goater
  0 siblings, 1 reply; 26+ messages in thread
From: David Gibson @ 2019-09-18  5:44 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, Greg Kurz, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 2173 bytes --]

On Tue, Sep 17, 2019 at 01:54:24PM +0200, Cédric Le Goater wrote:
> On 31/07/2019 16:12, Cédric Le Goater wrote:
> > Hello,
> > 
> > The QEMU PowerNV machine emulates a baremetal OpenPOWER system and
> > acts as an hypervisor (L0). Supporting emulation of KVM to run guests
> > (L1) requires a few more extensions, among which guest support for the
> > XIVE interrupt controller on POWER9 processor.
> > 
> > The following changes add new per-CPU PowerNV machines and extend the
> > XIVE models with the new XiveFabric and XivePresenter interfaces to
> > provide support for XIVE escalations and interrupt resend. This
> > mechanism is used by XIVE to notify the hypervisor that a vCPU is not
> > dispatched on a HW thread. Tested on a QEMU PowerNV machine and a
> > simple QEMU pseries guest doing network on a local bridge.
> > 
> > The XIVE interrupt controller offers a way to increase the XIVE
> > resources per chip by configuring multiple XIVE blocks on a chip. This
> > is not currently supported by the model. However, some configurations,
> > such as OPAL/skiboot, use one block-per-chip configuration with some
> > optimizations. One of them is to override the hardwired chip ID by the
> > block id in the PowerBUS operations and for CAM line compares. This
> > patchset improves the support for this setup. Tested with 4 chips.
> 
> David,
> 
> Do you want me to resend this patchset ? or you just didn't have time
> to look at it ?  

Mostly, I just haven't had time.  I'm also finding the patches pretty
difficult to read and review.  I don't think that's an indication
they're bad, just that what they're doing is necessarily complex, but
it's still made it hard to tackle them.

> Patch 16 has changed a little since. The get_block_id() handler has 
> moved to the XiveRouterClass.

You, might as well repost, so I'm looking at the latest stuff.  I
can't promise I'll be able to look at the new set terribly soon
though.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [Qemu-devel] [PATCH v3 00/18] ppc/pnv: add XIVE support for KVM guests
  2019-09-18  5:44   ` David Gibson
@ 2019-09-18  8:53     ` Cédric Le Goater
  0 siblings, 0 replies; 26+ messages in thread
From: Cédric Le Goater @ 2019-09-18  8:53 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, Greg Kurz, qemu-devel

On 18/09/2019 07:44, David Gibson wrote:
> On Tue, Sep 17, 2019 at 01:54:24PM +0200, Cédric Le Goater wrote:
>> On 31/07/2019 16:12, Cédric Le Goater wrote:
>>> Hello,
>>>
>>> The QEMU PowerNV machine emulates a baremetal OpenPOWER system and
>>> acts as an hypervisor (L0). Supporting emulation of KVM to run guests
>>> (L1) requires a few more extensions, among which guest support for the
>>> XIVE interrupt controller on POWER9 processor.
>>>
>>> The following changes add new per-CPU PowerNV machines and extend the
>>> XIVE models with the new XiveFabric and XivePresenter interfaces to
>>> provide support for XIVE escalations and interrupt resend. This
>>> mechanism is used by XIVE to notify the hypervisor that a vCPU is not
>>> dispatched on a HW thread. Tested on a QEMU PowerNV machine and a
>>> simple QEMU pseries guest doing network on a local bridge.
>>>
>>> The XIVE interrupt controller offers a way to increase the XIVE
>>> resources per chip by configuring multiple XIVE blocks on a chip. This
>>> is not currently supported by the model. However, some configurations,
>>> such as OPAL/skiboot, use one block-per-chip configuration with some
>>> optimizations. One of them is to override the hardwired chip ID by the
>>> block id in the PowerBUS operations and for CAM line compares. This
>>> patchset improves the support for this setup. Tested with 4 chips.
>>
>> David,
>>
>> Do you want me to resend this patchset ? or you just didn't have time
>> to look at it ?  
> 
> Mostly, I just haven't had time.  I'm also finding the patches pretty
> difficult to read and review.  I don't think that's an indication
> they're bad, just that what they're doing is necessarily complex, but
> it's still made it hard to tackle them.

I will try to split the initial patches on the presenter a little more.


>> Patch 16 has changed a little since. The get_block_id() handler has 
>> moved to the XiveRouterClass.
> 
> You, might as well repost, so I'm looking at the latest stuff.  I
> can't promise I'll be able to look at the new set terribly soon
> though.

ok.

thanks,

C.



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

end of thread, other threads:[~2019-09-18  8:54 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-31 14:12 [Qemu-devel] [PATCH v3 00/18] ppc/pnv: add XIVE support for KVM guests Cédric Le Goater
2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 01/18] ppc/pnv: Introduce PowerNV machines with fixed CPU models Cédric Le Goater
2019-08-05 10:46   ` David Gibson
2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 02/18] tests/boot-serial-test: add support for all the PowerNV machines Cédric Le Goater
2019-08-05 12:30   ` David Gibson
2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 03/18] ppc/xive: Introduce the XiveFabric and XivePresenter interfaces Cédric Le Goater
2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 04/18] ppc/pnv: Implement " Cédric Le Goater
2019-07-31 14:21   ` Cédric Le Goater
2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 05/18] ppc/spapr: " Cédric Le Goater
2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 06/18] ppc/xive: Use " Cédric Le Goater
2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 07/18] ppc/xive: Extend the TIMA operation with a XivePresenter parameter Cédric Le Goater
2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 08/18] ppc/pnv: Clarify how the TIMA is accessed on a multichip system Cédric Le Goater
2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 09/18] ppc/xive: Move the TIMA operations to the controller model Cédric Le Goater
2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 10/18] ppc/xive: Introduce a xive_tctx_ipb_update() helper Cédric Le Goater
2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 11/18] ppc/xive: Synthesize interrupt from the saved IPB in the NVT Cédric Le Goater
2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 12/18] ppc/pnv: Remove pnv_xive_vst_size() routine Cédric Le Goater
2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 13/18] ppc/pnv: Dump the XIVE NVT table Cédric Le Goater
2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 14/18] ppc/pnv: Skip empty slots of " Cédric Le Goater
2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 15/18] ppc/pnv: Introduce a pnv_xive_block_id() helper Cédric Le Goater
2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 16/18] ppc/pnv: Extend XivePresenter with a get_block_id() handler Cédric Le Goater
2019-09-02  8:49   ` Cédric Le Goater
2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 17/18] ppc/pnv: Quiesce some XIVE errors Cédric Le Goater
2019-07-31 14:12 ` [Qemu-devel] [PATCH v3 18/18] ppc/xive: Introduce a xive_os_cam_decode() helper Cédric Le Goater
2019-09-17 11:54 ` [Qemu-devel] [PATCH v3 00/18] ppc/pnv: add XIVE support for KVM guests Cédric Le Goater
2019-09-18  5:44   ` David Gibson
2019-09-18  8:53     ` Cédric Le Goater

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.