All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/33] spapr: IRQ subsystem cleanup
@ 2019-09-27  5:49 David Gibson
  2019-09-27  5:49 ` [PATCH v2 01/33] xics: Minor fixes for XICSFabric interface David Gibson
                   ` (32 more replies)
  0 siblings, 33 replies; 83+ messages in thread
From: David Gibson @ 2019-09-27  5:49 UTC (permalink / raw)
  To: qemu-devel, clg, qemu-ppc
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier, Paolo Bonzini,
	Marc-André Lureau, philmd, David Gibson

This is a substantial rework to clean up the handling of IRQs in
spapr.  It includes some cleanups to both the XICS and XIVE interrupt
controller backends, as well as more to the common spapr irq handling
infrastructure.

Changes since v1:
 * Lots of extra patches
 * Many minor adjustments based on feedback
 * Moved towards return value + Error * style, instead of just Error *
   style

David Gibson (33):
  xics: Minor fixes for XICSFabric interface
  xics: Eliminate 'reject', 'resend' and 'eoi' class hooks
  xics: Rename misleading ics_simple_*() functions
  xics: Eliminate reset hook
  xics: Merge TYPE_ICS_BASE and TYPE_ICS_SIMPLE classes
  xics: Create sPAPR specific ICS subtype
  spapr: Fold spapr_phb_lsi_qirq() into its single caller
  spapr: Replace spapr_vio_qirq() helper with spapr_vio_irq_pulse()
    helper
  spapr: Clarify and fix handling of nr_irqs
  spapr: Eliminate nr_irqs parameter to SpaprIrq::init
  spapr: Fix indexing of XICS irqs
  spapr: Simplify spapr_qirq() handling
  spapr: Eliminate SpaprIrq:get_nodename method
  spapr: Remove unhelpful tracepoints from spapr_irq_free_xics()
  spapr: Handle freeing of multiple irqs in frontend only
  spapr, xics, xive: Better use of assert()s on irq claim/free paths
  xive: Improve irq claim/free path
  spapr: Use less cryptic representation of which irq backends are
    supported
  spapr: Eliminate SpaprIrq::init hook
  spapr, xics, xive: Introduce SpaprInterruptController QOM interface
  spapr, xics, xive: Move cpu_intc_create from SpaprIrq to
    SpaprInterruptController
  spapr, xics, xive: Move irq claim and free from SpaprIrq to
    SpaprInterruptController
  spapr: Formalize notion of active interrupt controller
  spapr, xics, xive: Move set_irq from SpaprIrq to
    SpaprInterruptController
  spapr, xics, xive: Move print_info from SpaprIrq to
    SpaprInterruptController
  spapr, xics, xive: Move dt_populate from SpaprIrq to
    SpaprInterruptController
  spapr, xics, xive: Match signatures for XICS and XIVE KVM connect
    routines
  spapr: Remove SpaprIrq::init_kvm hook
  spapr, xics, xive: Move SpaprIrq::reset hook logic into
    activate/deactivate
  spapr, xics, xive: Move SpaprIrq::post_load hook to backends
  spapr: Remove SpaprIrq::nr_msis
  spapr: Move SpaprIrq::nr_xirqs to SpaprMachineClass
  spapr: Remove last pieces of SpaprIrq

 hw/char/spapr_vty.c         |   3 +-
 hw/intc/spapr_xive.c        | 298 ++++++++-----
 hw/intc/spapr_xive_kvm.c    |  30 +-
 hw/intc/trace-events        |  10 +-
 hw/intc/xics.c              | 210 +++------
 hw/intc/xics_kvm.c          |   9 +-
 hw/intc/xics_spapr.c        | 157 ++++++-
 hw/net/spapr_llan.c         |   3 +-
 hw/ppc/pnv_psi.c            |   6 +-
 hw/ppc/spapr.c              |  58 ++-
 hw/ppc/spapr_caps.c         |  64 +++
 hw/ppc/spapr_cpu_core.c     |   3 +-
 hw/ppc/spapr_hcall.c        |   7 +-
 hw/ppc/spapr_irq.c          | 840 +++++++++++-------------------------
 hw/ppc/spapr_pci.c          |  10 +-
 hw/ppc/spapr_vio.c          |   3 +-
 hw/ppc/trace-events         |   4 -
 include/hw/pci-host/spapr.h |  11 +-
 include/hw/ppc/spapr.h      |  14 +-
 include/hw/ppc/spapr_irq.h  |  88 ++--
 include/hw/ppc/spapr_vio.h  |   5 +-
 include/hw/ppc/spapr_xive.h |   9 +-
 include/hw/ppc/xics.h       |  33 +-
 include/hw/ppc/xics_spapr.h |  11 +-
 include/hw/ppc/xive.h       |   2 +-
 25 files changed, 898 insertions(+), 990 deletions(-)

-- 
2.21.0



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

* [PATCH v2 01/33] xics: Minor fixes for XICSFabric interface
  2019-09-27  5:49 [PATCH v2 00/33] spapr: IRQ subsystem cleanup David Gibson
@ 2019-09-27  5:49 ` David Gibson
  2019-09-27  7:17   ` Greg Kurz
  2019-09-27  5:49 ` [PATCH v2 02/33] xics: Eliminate 'reject', 'resend' and 'eoi' class hooks David Gibson
                   ` (31 subsequent siblings)
  32 siblings, 1 reply; 83+ messages in thread
From: David Gibson @ 2019-09-27  5:49 UTC (permalink / raw)
  To: qemu-devel, clg, qemu-ppc
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier, Paolo Bonzini,
	Marc-André Lureau, philmd, David Gibson

Interface instances should never be directly dereferenced.  So, the common
practice is to make them incomplete types to make sure no-one does that.
XICSFrabric, however, had a dummy type which is less safe.

We were also using OBJECT_CHECK() where we should have been using
INTERFACE_CHECK().

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 include/hw/ppc/xics.h | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index 64a2c8862a..faa33ae943 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -147,13 +147,9 @@ struct ICSIRQState {
     uint8_t flags;
 };
 
-struct XICSFabric {
-    Object parent;
-};
-
 #define TYPE_XICS_FABRIC "xics-fabric"
 #define XICS_FABRIC(obj)                                     \
-    OBJECT_CHECK(XICSFabric, (obj), TYPE_XICS_FABRIC)
+    INTERFACE_CHECK(XICSFabric, (obj), TYPE_XICS_FABRIC)
 #define XICS_FABRIC_CLASS(klass)                                     \
     OBJECT_CLASS_CHECK(XICSFabricClass, (klass), TYPE_XICS_FABRIC)
 #define XICS_FABRIC_GET_CLASS(obj)                                   \
-- 
2.21.0



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

* [PATCH v2 02/33] xics: Eliminate 'reject', 'resend' and 'eoi' class hooks
  2019-09-27  5:49 [PATCH v2 00/33] spapr: IRQ subsystem cleanup David Gibson
  2019-09-27  5:49 ` [PATCH v2 01/33] xics: Minor fixes for XICSFabric interface David Gibson
@ 2019-09-27  5:49 ` David Gibson
  2019-09-27  5:49 ` [PATCH v2 03/33] xics: Rename misleading ics_simple_*() functions David Gibson
                   ` (30 subsequent siblings)
  32 siblings, 0 replies; 83+ messages in thread
From: David Gibson @ 2019-09-27  5:49 UTC (permalink / raw)
  To: qemu-devel, clg, qemu-ppc
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier, Paolo Bonzini,
	Marc-André Lureau, philmd, David Gibson

Currently ics_reject(), ics_resend() and ics_eoi() indirect through
class methods.  But there's only one implementation of each method,
the one in TYPE_ICS_SIMPLE.  TYPE_ICS_BASE has no implementation, but
it's never instantiated, and has no other subtypes.

So clean up by eliminating the method and just having ics_reject(),
ics_resend() and ics_eoi() contain the logic directly.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
---
 hw/intc/trace-events  |  4 ++--
 hw/intc/xics.c        | 54 +++++++++++--------------------------------
 include/hw/ppc/xics.h |  4 ----
 3 files changed, 15 insertions(+), 47 deletions(-)

diff --git a/hw/intc/trace-events b/hw/intc/trace-events
index 719f46b516..fdc716c2cc 100644
--- a/hw/intc/trace-events
+++ b/hw/intc/trace-events
@@ -70,8 +70,8 @@ xics_ics_simple_set_irq_msi(int srcno, int nr) "set_irq_msi: srcno %d [irq 0x%x]
 xics_masked_pending(void) "set_irq_msi: masked pending"
 xics_ics_simple_set_irq_lsi(int srcno, int nr) "set_irq_lsi: srcno %d [irq 0x%x]"
 xics_ics_simple_write_xive(int nr, int srcno, int server, uint8_t priority) "ics_write_xive: irq 0x%x [src %d] server 0x%x prio 0x%x"
-xics_ics_simple_reject(int nr, int srcno) "reject irq 0x%x [src %d]"
-xics_ics_simple_eoi(int nr) "ics_eoi: irq 0x%x"
+xics_ics_reject(int nr, int srcno) "reject irq 0x%x [src %d]"
+xics_ics_eoi(int nr) "ics_eoi: irq 0x%x"
 
 # s390_flic_kvm.c
 flic_create_device(int err) "flic: create device failed %d"
diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index b2fca2975c..93139b0189 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -98,32 +98,8 @@ void ics_pic_print_info(ICSState *ics, Monitor *mon)
 #define XISR(icp)   (((icp)->xirr) & XISR_MASK)
 #define CPPR(icp)   (((icp)->xirr) >> 24)
 
-static void ics_reject(ICSState *ics, uint32_t nr)
-{
-    ICSStateClass *k = ICS_BASE_GET_CLASS(ics);
-
-    if (k->reject) {
-        k->reject(ics, nr);
-    }
-}
-
-void ics_resend(ICSState *ics)
-{
-    ICSStateClass *k = ICS_BASE_GET_CLASS(ics);
-
-    if (k->resend) {
-        k->resend(ics);
-    }
-}
-
-static void ics_eoi(ICSState *ics, int nr)
-{
-    ICSStateClass *k = ICS_BASE_GET_CLASS(ics);
-
-    if (k->eoi) {
-        k->eoi(ics, nr);
-    }
-}
+static void ics_reject(ICSState *ics, uint32_t nr);
+static void ics_eoi(ICSState *ics, uint32_t nr);
 
 static void icp_check_ipi(ICPState *icp)
 {
@@ -427,7 +403,7 @@ Object *icp_create(Object *cpu, const char *type, XICSFabric *xi, Error **errp)
 /*
  * ICS: Source layer
  */
-static void ics_simple_resend_msi(ICSState *ics, int srcno)
+static void ics_resend_msi(ICSState *ics, int srcno)
 {
     ICSIRQState *irq = ics->irqs + srcno;
 
@@ -440,7 +416,7 @@ static void ics_simple_resend_msi(ICSState *ics, int srcno)
     }
 }
 
-static void ics_simple_resend_lsi(ICSState *ics, int srcno)
+static void ics_resend_lsi(ICSState *ics, int srcno)
 {
     ICSIRQState *irq = ics->irqs + srcno;
 
@@ -478,7 +454,7 @@ static void ics_simple_set_irq_lsi(ICSState *ics, int srcno, int val)
     } else {
         irq->status &= ~XICS_STATUS_ASSERTED;
     }
-    ics_simple_resend_lsi(ics, srcno);
+    ics_resend_lsi(ics, srcno);
 }
 
 void ics_simple_set_irq(void *opaque, int srcno, int val)
@@ -512,7 +488,7 @@ static void ics_simple_write_xive_msi(ICSState *ics, int srcno)
 
 static void ics_simple_write_xive_lsi(ICSState *ics, int srcno)
 {
-    ics_simple_resend_lsi(ics, srcno);
+    ics_resend_lsi(ics, srcno);
 }
 
 void ics_simple_write_xive(ICSState *ics, int srcno, int server,
@@ -534,11 +510,11 @@ void ics_simple_write_xive(ICSState *ics, int srcno, int server,
     }
 }
 
-static void ics_simple_reject(ICSState *ics, uint32_t nr)
+static void ics_reject(ICSState *ics, uint32_t nr)
 {
     ICSIRQState *irq = ics->irqs + nr - ics->offset;
 
-    trace_xics_ics_simple_reject(nr, nr - ics->offset);
+    trace_xics_ics_reject(nr, nr - ics->offset);
     if (irq->flags & XICS_FLAGS_IRQ_MSI) {
         irq->status |= XICS_STATUS_REJECTED;
     } else if (irq->flags & XICS_FLAGS_IRQ_LSI) {
@@ -546,26 +522,26 @@ static void ics_simple_reject(ICSState *ics, uint32_t nr)
     }
 }
 
-static void ics_simple_resend(ICSState *ics)
+void ics_resend(ICSState *ics)
 {
     int i;
 
     for (i = 0; i < ics->nr_irqs; i++) {
         /* FIXME: filter by server#? */
         if (ics->irqs[i].flags & XICS_FLAGS_IRQ_LSI) {
-            ics_simple_resend_lsi(ics, i);
+            ics_resend_lsi(ics, i);
         } else {
-            ics_simple_resend_msi(ics, i);
+            ics_resend_msi(ics, i);
         }
     }
 }
 
-static void ics_simple_eoi(ICSState *ics, uint32_t nr)
+static void ics_eoi(ICSState *ics, uint32_t nr)
 {
     int srcno = nr - ics->offset;
     ICSIRQState *irq = ics->irqs + srcno;
 
-    trace_xics_ics_simple_eoi(nr);
+    trace_xics_ics_eoi(nr);
 
     if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI) {
         irq->status &= ~XICS_STATUS_SENT;
@@ -617,10 +593,6 @@ static void ics_simple_class_init(ObjectClass *klass, void *data)
                                     &isc->parent_realize);
     device_class_set_parent_reset(dc, ics_simple_reset,
                                   &isc->parent_reset);
-
-    isc->reject = ics_simple_reject;
-    isc->resend = ics_simple_resend;
-    isc->eoi = ics_simple_eoi;
 }
 
 static const TypeInfo ics_simple_info = {
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index faa33ae943..ecca17695d 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -106,10 +106,6 @@ struct ICSStateClass {
 
     DeviceRealize parent_realize;
     DeviceReset parent_reset;
-
-    void (*reject)(ICSState *s, uint32_t irq);
-    void (*resend)(ICSState *s);
-    void (*eoi)(ICSState *s, uint32_t irq);
 };
 
 struct ICSState {
-- 
2.21.0



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

* [PATCH v2 03/33] xics: Rename misleading ics_simple_*() functions
  2019-09-27  5:49 [PATCH v2 00/33] spapr: IRQ subsystem cleanup David Gibson
  2019-09-27  5:49 ` [PATCH v2 01/33] xics: Minor fixes for XICSFabric interface David Gibson
  2019-09-27  5:49 ` [PATCH v2 02/33] xics: Eliminate 'reject', 'resend' and 'eoi' class hooks David Gibson
@ 2019-09-27  5:49 ` David Gibson
  2019-09-27  5:49 ` [PATCH v2 04/33] xics: Eliminate reset hook David Gibson
                   ` (29 subsequent siblings)
  32 siblings, 0 replies; 83+ messages in thread
From: David Gibson @ 2019-09-27  5:49 UTC (permalink / raw)
  To: qemu-devel, clg, qemu-ppc
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier, Paolo Bonzini,
	Marc-André Lureau, philmd, David Gibson

There are a number of ics_simple_*() functions that aren't actually
specific to TYPE_XICS_SIMPLE at all, and are equally valid on
TYPE_XICS_BASE.  Rename them to ics_*() accordingly.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
---
 hw/intc/trace-events  |  6 +++---
 hw/intc/xics.c        | 29 ++++++++++++++---------------
 hw/intc/xics_spapr.c  | 12 ++++++------
 hw/ppc/pnv_psi.c      |  4 ++--
 hw/ppc/spapr_irq.c    |  2 +-
 include/hw/ppc/xics.h |  6 +++---
 6 files changed, 29 insertions(+), 30 deletions(-)

diff --git a/hw/intc/trace-events b/hw/intc/trace-events
index fdc716c2cc..527c3f76ca 100644
--- a/hw/intc/trace-events
+++ b/hw/intc/trace-events
@@ -66,10 +66,10 @@ xics_icp_accept(uint32_t old_xirr, uint32_t new_xirr) "icp_accept: XIRR 0x%"PRIx
 xics_icp_eoi(int server, uint32_t xirr, uint32_t new_xirr) "icp_eoi: server %d given XIRR 0x%"PRIx32" new XIRR 0x%"PRIx32
 xics_icp_irq(int server, int nr, uint8_t priority) "cpu %d trying to deliver irq 0x%"PRIx32" priority 0x%x"
 xics_icp_raise(uint32_t xirr, uint8_t pending_priority) "raising IRQ new XIRR=0x%x new pending priority=0x%x"
-xics_ics_simple_set_irq_msi(int srcno, int nr) "set_irq_msi: srcno %d [irq 0x%x]"
+xics_ics_set_irq_msi(int srcno, int nr) "set_irq_msi: srcno %d [irq 0x%x]"
 xics_masked_pending(void) "set_irq_msi: masked pending"
-xics_ics_simple_set_irq_lsi(int srcno, int nr) "set_irq_lsi: srcno %d [irq 0x%x]"
-xics_ics_simple_write_xive(int nr, int srcno, int server, uint8_t priority) "ics_write_xive: irq 0x%x [src %d] server 0x%x prio 0x%x"
+xics_ics_set_irq_lsi(int srcno, int nr) "set_irq_lsi: srcno %d [irq 0x%x]"
+xics_ics_write_xive(int nr, int srcno, int server, uint8_t priority) "ics_write_xive: irq 0x%x [src %d] server 0x%x prio 0x%x"
 xics_ics_reject(int nr, int srcno) "reject irq 0x%x [src %d]"
 xics_ics_eoi(int nr) "ics_eoi: irq 0x%x"
 
diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 93139b0189..310dc72b46 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -428,11 +428,11 @@ static void ics_resend_lsi(ICSState *ics, int srcno)
     }
 }
 
-static void ics_simple_set_irq_msi(ICSState *ics, int srcno, int val)
+static void ics_set_irq_msi(ICSState *ics, int srcno, int val)
 {
     ICSIRQState *irq = ics->irqs + srcno;
 
-    trace_xics_ics_simple_set_irq_msi(srcno, srcno + ics->offset);
+    trace_xics_ics_set_irq_msi(srcno, srcno + ics->offset);
 
     if (val) {
         if (irq->priority == 0xff) {
@@ -444,11 +444,11 @@ static void ics_simple_set_irq_msi(ICSState *ics, int srcno, int val)
     }
 }
 
-static void ics_simple_set_irq_lsi(ICSState *ics, int srcno, int val)
+static void ics_set_irq_lsi(ICSState *ics, int srcno, int val)
 {
     ICSIRQState *irq = ics->irqs + srcno;
 
-    trace_xics_ics_simple_set_irq_lsi(srcno, srcno + ics->offset);
+    trace_xics_ics_set_irq_lsi(srcno, srcno + ics->offset);
     if (val) {
         irq->status |= XICS_STATUS_ASSERTED;
     } else {
@@ -457,7 +457,7 @@ static void ics_simple_set_irq_lsi(ICSState *ics, int srcno, int val)
     ics_resend_lsi(ics, srcno);
 }
 
-void ics_simple_set_irq(void *opaque, int srcno, int val)
+void ics_set_irq(void *opaque, int srcno, int val)
 {
     ICSState *ics = (ICSState *)opaque;
 
@@ -467,13 +467,13 @@ void ics_simple_set_irq(void *opaque, int srcno, int val)
     }
 
     if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI) {
-        ics_simple_set_irq_lsi(ics, srcno, val);
+        ics_set_irq_lsi(ics, srcno, val);
     } else {
-        ics_simple_set_irq_msi(ics, srcno, val);
+        ics_set_irq_msi(ics, srcno, val);
     }
 }
 
-static void ics_simple_write_xive_msi(ICSState *ics, int srcno)
+static void ics_write_xive_msi(ICSState *ics, int srcno)
 {
     ICSIRQState *irq = ics->irqs + srcno;
 
@@ -486,13 +486,13 @@ static void ics_simple_write_xive_msi(ICSState *ics, int srcno)
     icp_irq(ics, irq->server, srcno + ics->offset, irq->priority);
 }
 
-static void ics_simple_write_xive_lsi(ICSState *ics, int srcno)
+static void ics_write_xive_lsi(ICSState *ics, int srcno)
 {
     ics_resend_lsi(ics, srcno);
 }
 
-void ics_simple_write_xive(ICSState *ics, int srcno, int server,
-                           uint8_t priority, uint8_t saved_priority)
+void ics_write_xive(ICSState *ics, int srcno, int server,
+                    uint8_t priority, uint8_t saved_priority)
 {
     ICSIRQState *irq = ics->irqs + srcno;
 
@@ -500,13 +500,12 @@ void ics_simple_write_xive(ICSState *ics, int srcno, int server,
     irq->priority = priority;
     irq->saved_priority = saved_priority;
 
-    trace_xics_ics_simple_write_xive(ics->offset + srcno, srcno, server,
-                                     priority);
+    trace_xics_ics_write_xive(ics->offset + srcno, srcno, server, priority);
 
     if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI) {
-        ics_simple_write_xive_lsi(ics, srcno);
+        ics_write_xive_lsi(ics, srcno);
     } else {
-        ics_simple_write_xive_msi(ics, srcno);
+        ics_write_xive_msi(ics, srcno);
     }
 }
 
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 6577be0d92..3e9444813a 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -179,7 +179,7 @@ static void rtas_set_xive(PowerPCCPU *cpu, SpaprMachineState *spapr,
     }
 
     srcno = nr - ics->offset;
-    ics_simple_write_xive(ics, srcno, server, priority, priority);
+    ics_write_xive(ics, srcno, server, priority, priority);
 
     rtas_st(rets, 0, RTAS_OUT_SUCCESS);
 }
@@ -243,8 +243,8 @@ static void rtas_int_off(PowerPCCPU *cpu, SpaprMachineState *spapr,
     }
 
     srcno = nr - ics->offset;
-    ics_simple_write_xive(ics, srcno, ics->irqs[srcno].server, 0xff,
-                          ics->irqs[srcno].priority);
+    ics_write_xive(ics, srcno, ics->irqs[srcno].server, 0xff,
+                   ics->irqs[srcno].priority);
 
     rtas_st(rets, 0, RTAS_OUT_SUCCESS);
 }
@@ -276,9 +276,9 @@ static void rtas_int_on(PowerPCCPU *cpu, SpaprMachineState *spapr,
     }
 
     srcno = nr - ics->offset;
-    ics_simple_write_xive(ics, srcno, ics->irqs[srcno].server,
-                          ics->irqs[srcno].saved_priority,
-                          ics->irqs[srcno].saved_priority);
+    ics_write_xive(ics, srcno, ics->irqs[srcno].server,
+                   ics->irqs[srcno].saved_priority,
+                   ics->irqs[srcno].saved_priority);
 
     rtas_st(rets, 0, RTAS_OUT_SUCCESS);
 }
diff --git a/hw/ppc/pnv_psi.c b/hw/ppc/pnv_psi.c
index 88ba8e7b9b..8ea81e9d8e 100644
--- a/hw/ppc/pnv_psi.c
+++ b/hw/ppc/pnv_psi.c
@@ -311,7 +311,7 @@ static void pnv_psi_set_xivr(PnvPsi *psi, uint32_t reg, uint64_t val)
      * do for now but a more accurate implementation would instead
      * use a fixed server/prio and a remapper of the generated irq.
      */
-    ics_simple_write_xive(ics, src, server, prio, prio);
+    ics_write_xive(ics, src, server, prio, prio);
 }
 
 static uint64_t pnv_psi_reg_read(PnvPsi *psi, uint32_t offset, bool mmio)
@@ -514,7 +514,7 @@ static void pnv_psi_power8_realize(DeviceState *dev, Error **errp)
         ics_set_irq_type(ics, i, true);
     }
 
-    psi->qirqs = qemu_allocate_irqs(ics_simple_set_irq, ics, ics->nr_irqs);
+    psi->qirqs = qemu_allocate_irqs(ics_set_irq, ics, ics->nr_irqs);
 
     /* XSCOM region for PSI registers */
     pnv_xscom_region_init(&psi->xscom_regs, OBJECT(dev), &pnv_psi_xscom_ops,
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index d8f46b6797..ac189c5796 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -210,7 +210,7 @@ static void spapr_irq_set_irq_xics(void *opaque, int srcno, int val)
 {
     SpaprMachineState *spapr = opaque;
 
-    ics_simple_set_irq(spapr->ics, srcno, val);
+    ics_set_irq(spapr->ics, srcno, val);
 }
 
 static void spapr_irq_reset_xics(SpaprMachineState *spapr, Error **errp)
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index ecca17695d..8874bad328 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -167,9 +167,9 @@ uint32_t icp_accept(ICPState *ss);
 uint32_t icp_ipoll(ICPState *ss, uint32_t *mfrr);
 void icp_eoi(ICPState *icp, uint32_t xirr);
 
-void ics_simple_write_xive(ICSState *ics, int nr, int server,
-                           uint8_t priority, uint8_t saved_priority);
-void ics_simple_set_irq(void *opaque, int srcno, int val);
+void ics_write_xive(ICSState *ics, int nr, int server,
+                    uint8_t priority, uint8_t saved_priority);
+void ics_set_irq(void *opaque, int srcno, int val);
 
 static inline bool ics_irq_free(ICSState *ics, uint32_t srcno)
 {
-- 
2.21.0



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

* [PATCH v2 04/33] xics: Eliminate reset hook
  2019-09-27  5:49 [PATCH v2 00/33] spapr: IRQ subsystem cleanup David Gibson
                   ` (2 preceding siblings ...)
  2019-09-27  5:49 ` [PATCH v2 03/33] xics: Rename misleading ics_simple_*() functions David Gibson
@ 2019-09-27  5:49 ` David Gibson
  2019-09-27  7:19   ` Greg Kurz
  2019-09-27  5:50 ` [PATCH v2 05/33] xics: Merge TYPE_ICS_BASE and TYPE_ICS_SIMPLE classes David Gibson
                   ` (28 subsequent siblings)
  32 siblings, 1 reply; 83+ messages in thread
From: David Gibson @ 2019-09-27  5:49 UTC (permalink / raw)
  To: qemu-devel, clg, qemu-ppc
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier, Paolo Bonzini,
	Marc-André Lureau, philmd, David Gibson

Currently TYPE_XICS_BASE and TYPE_XICS_SIMPLE have their own reset methods,
using the standard technique for having the subtype call the supertype's
methods before doing its own thing.

But TYPE_XICS_SIMPLE is the only subtype of TYPE_XICS_BASE ever
instantiated, so there's no point having the split here.  Merge them
together into just an ics_reset() function.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
---
 hw/intc/xics.c        | 57 ++++++++++++++++++-------------------------
 include/hw/ppc/xics.h |  1 -
 2 files changed, 24 insertions(+), 34 deletions(-)

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 310dc72b46..82e6f09259 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -547,11 +547,28 @@ static void ics_eoi(ICSState *ics, uint32_t nr)
     }
 }
 
-static void ics_simple_reset(DeviceState *dev)
+static void ics_reset_irq(ICSIRQState *irq)
 {
-    ICSStateClass *icsc = ICS_BASE_GET_CLASS(dev);
+    irq->priority = 0xff;
+    irq->saved_priority = 0xff;
+}
 
-    icsc->parent_reset(dev);
+static void ics_reset(DeviceState *dev)
+{
+    ICSState *ics = ICS_BASE(dev);
+    int i;
+    uint8_t flags[ics->nr_irqs];
+
+    for (i = 0; i < ics->nr_irqs; i++) {
+        flags[i] = ics->irqs[i].flags;
+    }
+
+    memset(ics->irqs, 0, sizeof(ICSIRQState) * ics->nr_irqs);
+
+    for (i = 0; i < ics->nr_irqs; i++) {
+        ics_reset_irq(ics->irqs + i);
+        ics->irqs[i].flags = flags[i];
+    }
 
     if (kvm_irqchip_in_kernel()) {
         Error *local_err = NULL;
@@ -563,9 +580,9 @@ static void ics_simple_reset(DeviceState *dev)
     }
 }
 
-static void ics_simple_reset_handler(void *dev)
+static void ics_reset_handler(void *dev)
 {
-    ics_simple_reset(dev);
+    ics_reset(dev);
 }
 
 static void ics_simple_realize(DeviceState *dev, Error **errp)
@@ -580,7 +597,7 @@ static void ics_simple_realize(DeviceState *dev, Error **errp)
         return;
     }
 
-    qemu_register_reset(ics_simple_reset_handler, ics);
+    qemu_register_reset(ics_reset_handler, ics);
 }
 
 static void ics_simple_class_init(ObjectClass *klass, void *data)
@@ -590,8 +607,6 @@ static void ics_simple_class_init(ObjectClass *klass, void *data)
 
     device_class_set_parent_realize(dc, ics_simple_realize,
                                     &isc->parent_realize);
-    device_class_set_parent_reset(dc, ics_simple_reset,
-                                  &isc->parent_reset);
 }
 
 static const TypeInfo ics_simple_info = {
@@ -602,30 +617,6 @@ static const TypeInfo ics_simple_info = {
     .class_size = sizeof(ICSStateClass),
 };
 
-static void ics_reset_irq(ICSIRQState *irq)
-{
-    irq->priority = 0xff;
-    irq->saved_priority = 0xff;
-}
-
-static void ics_base_reset(DeviceState *dev)
-{
-    ICSState *ics = ICS_BASE(dev);
-    int i;
-    uint8_t flags[ics->nr_irqs];
-
-    for (i = 0; i < ics->nr_irqs; i++) {
-        flags[i] = ics->irqs[i].flags;
-    }
-
-    memset(ics->irqs, 0, sizeof(ICSIRQState) * ics->nr_irqs);
-
-    for (i = 0; i < ics->nr_irqs; i++) {
-        ics_reset_irq(ics->irqs + i);
-        ics->irqs[i].flags = flags[i];
-    }
-}
-
 static void ics_base_realize(DeviceState *dev, Error **errp)
 {
     ICSState *ics = ICS_BASE(dev);
@@ -726,7 +717,7 @@ static void ics_base_class_init(ObjectClass *klass, void *data)
 
     dc->realize = ics_base_realize;
     dc->props = ics_base_properties;
-    dc->reset = ics_base_reset;
+    dc->reset = ics_reset;
     dc->vmsd = &vmstate_ics_base;
 }
 
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index 8874bad328..7efd49c02c 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -105,7 +105,6 @@ struct ICSStateClass {
     DeviceClass parent_class;
 
     DeviceRealize parent_realize;
-    DeviceReset parent_reset;
 };
 
 struct ICSState {
-- 
2.21.0



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

* [PATCH v2 05/33] xics: Merge TYPE_ICS_BASE and TYPE_ICS_SIMPLE classes
  2019-09-27  5:49 [PATCH v2 00/33] spapr: IRQ subsystem cleanup David Gibson
                   ` (3 preceding siblings ...)
  2019-09-27  5:49 ` [PATCH v2 04/33] xics: Eliminate reset hook David Gibson
@ 2019-09-27  5:50 ` David Gibson
  2019-09-27  5:50 ` [PATCH v2 06/33] xics: Create sPAPR specific ICS subtype David Gibson
                   ` (27 subsequent siblings)
  32 siblings, 0 replies; 83+ messages in thread
From: David Gibson @ 2019-09-27  5:50 UTC (permalink / raw)
  To: qemu-devel, clg, qemu-ppc
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier, Paolo Bonzini,
	Marc-André Lureau, philmd, David Gibson

TYPE_ICS_SIMPLE is the only subtype of TYPE_ICS_BASE that's ever
instantiated.  The existence of different classes is mostly a hang
over from when we (misguidedly) had separate subtypes for the KVM and
non-KVM version of the device.

There could be some call for an abstract base type for ICS variants
that use a different representation of their state (PowerNV PHB3 might
want this).  The current split isn't really in the right place for
that though.  If we need this in future, we can re-implement it more
in line with what we actually need.

So, collapse the two classes together into just TYPE_ICS.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
---
 hw/intc/xics.c        | 86 ++++++++++++++-----------------------------
 hw/ppc/pnv_psi.c      |  2 +-
 hw/ppc/spapr_irq.c    |  4 +-
 include/hw/ppc/xics.h | 16 +++-----
 4 files changed, 36 insertions(+), 72 deletions(-)

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 82e6f09259..dfe7dbd254 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -555,7 +555,7 @@ static void ics_reset_irq(ICSIRQState *irq)
 
 static void ics_reset(DeviceState *dev)
 {
-    ICSState *ics = ICS_BASE(dev);
+    ICSState *ics = ICS(dev);
     int i;
     uint8_t flags[ics->nr_irqs];
 
@@ -573,7 +573,7 @@ static void ics_reset(DeviceState *dev)
     if (kvm_irqchip_in_kernel()) {
         Error *local_err = NULL;
 
-        ics_set_kvm_state(ICS_BASE(dev), &local_err);
+        ics_set_kvm_state(ICS(dev), &local_err);
         if (local_err) {
             error_report_err(local_err);
         }
@@ -585,47 +585,15 @@ static void ics_reset_handler(void *dev)
     ics_reset(dev);
 }
 
-static void ics_simple_realize(DeviceState *dev, Error **errp)
+static void ics_realize(DeviceState *dev, Error **errp)
 {
-    ICSState *ics = ICS_SIMPLE(dev);
-    ICSStateClass *icsc = ICS_BASE_GET_CLASS(ics);
+    ICSState *ics = ICS(dev);
     Error *local_err = NULL;
-
-    icsc->parent_realize(dev, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-
-    qemu_register_reset(ics_reset_handler, ics);
-}
-
-static void ics_simple_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    ICSStateClass *isc = ICS_BASE_CLASS(klass);
-
-    device_class_set_parent_realize(dc, ics_simple_realize,
-                                    &isc->parent_realize);
-}
-
-static const TypeInfo ics_simple_info = {
-    .name = TYPE_ICS_SIMPLE,
-    .parent = TYPE_ICS_BASE,
-    .instance_size = sizeof(ICSState),
-    .class_init = ics_simple_class_init,
-    .class_size = sizeof(ICSStateClass),
-};
-
-static void ics_base_realize(DeviceState *dev, Error **errp)
-{
-    ICSState *ics = ICS_BASE(dev);
     Object *obj;
-    Error *err = NULL;
 
-    obj = object_property_get_link(OBJECT(dev), ICS_PROP_XICS, &err);
+    obj = object_property_get_link(OBJECT(dev), ICS_PROP_XICS, &local_err);
     if (!obj) {
-        error_propagate_prepend(errp, err,
+        error_propagate_prepend(errp, local_err,
                                 "required link '" ICS_PROP_XICS
                                 "' not found: ");
         return;
@@ -637,16 +605,18 @@ static void ics_base_realize(DeviceState *dev, Error **errp)
         return;
     }
     ics->irqs = g_malloc0(ics->nr_irqs * sizeof(ICSIRQState));
+
+    qemu_register_reset(ics_reset_handler, ics);
 }
 
-static void ics_base_instance_init(Object *obj)
+static void ics_instance_init(Object *obj)
 {
-    ICSState *ics = ICS_BASE(obj);
+    ICSState *ics = ICS(obj);
 
     ics->offset = XICS_IRQ_BASE;
 }
 
-static int ics_base_pre_save(void *opaque)
+static int ics_pre_save(void *opaque)
 {
     ICSState *ics = opaque;
 
@@ -657,7 +627,7 @@ static int ics_base_pre_save(void *opaque)
     return 0;
 }
 
-static int ics_base_post_load(void *opaque, int version_id)
+static int ics_post_load(void *opaque, int version_id)
 {
     ICSState *ics = opaque;
 
@@ -675,7 +645,7 @@ static int ics_base_post_load(void *opaque, int version_id)
     return 0;
 }
 
-static const VMStateDescription vmstate_ics_base_irq = {
+static const VMStateDescription vmstate_ics_irq = {
     .name = "ics/irq",
     .version_id = 2,
     .minimum_version_id = 1,
@@ -689,45 +659,44 @@ static const VMStateDescription vmstate_ics_base_irq = {
     },
 };
 
-static const VMStateDescription vmstate_ics_base = {
+static const VMStateDescription vmstate_ics = {
     .name = "ics",
     .version_id = 1,
     .minimum_version_id = 1,
-    .pre_save = ics_base_pre_save,
-    .post_load = ics_base_post_load,
+    .pre_save = ics_pre_save,
+    .post_load = ics_post_load,
     .fields = (VMStateField[]) {
         /* Sanity check */
         VMSTATE_UINT32_EQUAL(nr_irqs, ICSState, NULL),
 
         VMSTATE_STRUCT_VARRAY_POINTER_UINT32(irqs, ICSState, nr_irqs,
-                                             vmstate_ics_base_irq,
+                                             vmstate_ics_irq,
                                              ICSIRQState),
         VMSTATE_END_OF_LIST()
     },
 };
 
-static Property ics_base_properties[] = {
+static Property ics_properties[] = {
     DEFINE_PROP_UINT32("nr-irqs", ICSState, nr_irqs, 0),
     DEFINE_PROP_END_OF_LIST(),
 };
 
-static void ics_base_class_init(ObjectClass *klass, void *data)
+static void ics_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
 
-    dc->realize = ics_base_realize;
-    dc->props = ics_base_properties;
+    dc->realize = ics_realize;
+    dc->props = ics_properties;
     dc->reset = ics_reset;
-    dc->vmsd = &vmstate_ics_base;
+    dc->vmsd = &vmstate_ics;
 }
 
-static const TypeInfo ics_base_info = {
-    .name = TYPE_ICS_BASE,
+static const TypeInfo ics_info = {
+    .name = TYPE_ICS,
     .parent = TYPE_DEVICE,
-    .abstract = true,
     .instance_size = sizeof(ICSState),
-    .instance_init = ics_base_instance_init,
-    .class_init = ics_base_class_init,
+    .instance_init = ics_instance_init,
+    .class_init = ics_class_init,
     .class_size = sizeof(ICSStateClass),
 };
 
@@ -767,8 +736,7 @@ void ics_set_irq_type(ICSState *ics, int srcno, bool lsi)
 
 static void xics_register_types(void)
 {
-    type_register_static(&ics_simple_info);
-    type_register_static(&ics_base_info);
+    type_register_static(&ics_info);
     type_register_static(&icp_info);
     type_register_static(&xics_fabric_info);
 }
diff --git a/hw/ppc/pnv_psi.c b/hw/ppc/pnv_psi.c
index 8ea81e9d8e..a997f16bb4 100644
--- a/hw/ppc/pnv_psi.c
+++ b/hw/ppc/pnv_psi.c
@@ -469,7 +469,7 @@ static void pnv_psi_power8_instance_init(Object *obj)
     Pnv8Psi *psi8 = PNV8_PSI(obj);
 
     object_initialize_child(obj, "ics-psi",  &psi8->ics, sizeof(psi8->ics),
-                            TYPE_ICS_SIMPLE, &error_abort, NULL);
+                            TYPE_ICS, &error_abort, NULL);
 }
 
 static const uint8_t irq_to_xivr[] = {
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index ac189c5796..6c45d2a3c0 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -98,7 +98,7 @@ static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_irqs,
     Object *obj;
     Error *local_err = NULL;
 
-    obj = object_new(TYPE_ICS_SIMPLE);
+    obj = object_new(TYPE_ICS);
     object_property_add_child(OBJECT(spapr), "ics", obj, &error_abort);
     object_property_add_const_link(obj, ICS_PROP_XICS, OBJECT(spapr),
                                    &error_fatal);
@@ -109,7 +109,7 @@ static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_irqs,
         return;
     }
 
-    spapr->ics = ICS_BASE(obj);
+    spapr->ics = ICS(obj);
 
     xics_spapr_init(spapr);
 }
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index 7efd49c02c..1e6a9300eb 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -89,17 +89,13 @@ struct PnvICPState {
     uint32_t links[3];
 };
 
-#define TYPE_ICS_BASE "ics-base"
-#define ICS_BASE(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_BASE)
+#define TYPE_ICS "ics"
+#define ICS(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS)
 
-/* Retain ics for sPAPR for migration from existing sPAPR guests */
-#define TYPE_ICS_SIMPLE "ics"
-#define ICS_SIMPLE(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SIMPLE)
-
-#define ICS_BASE_CLASS(klass) \
-     OBJECT_CLASS_CHECK(ICSStateClass, (klass), TYPE_ICS_BASE)
-#define ICS_BASE_GET_CLASS(obj) \
-     OBJECT_GET_CLASS(ICSStateClass, (obj), TYPE_ICS_BASE)
+#define ICS_CLASS(klass) \
+     OBJECT_CLASS_CHECK(ICSStateClass, (klass), TYPE_ICS)
+#define ICS_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(ICSStateClass, (obj), TYPE_ICS)
 
 struct ICSStateClass {
     DeviceClass parent_class;
-- 
2.21.0



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

* [PATCH v2 06/33] xics: Create sPAPR specific ICS subtype
  2019-09-27  5:49 [PATCH v2 00/33] spapr: IRQ subsystem cleanup David Gibson
                   ` (4 preceding siblings ...)
  2019-09-27  5:50 ` [PATCH v2 05/33] xics: Merge TYPE_ICS_BASE and TYPE_ICS_SIMPLE classes David Gibson
@ 2019-09-27  5:50 ` David Gibson
  2019-09-27  7:22   ` Greg Kurz
  2019-09-27  5:50 ` [PATCH v2 07/33] spapr: Fold spapr_phb_lsi_qirq() into its single caller David Gibson
                   ` (26 subsequent siblings)
  32 siblings, 1 reply; 83+ messages in thread
From: David Gibson @ 2019-09-27  5:50 UTC (permalink / raw)
  To: qemu-devel, clg, qemu-ppc
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier, Paolo Bonzini,
	Marc-André Lureau, philmd, David Gibson

We create a subtype of TYPE_ICS specifically for sPAPR.  For now all this
does is move the setup of the PAPR specific hcalls and RTAS calls to
the realize() function for this, rather than requiring the PAPR code to
explicitly call xics_spapr_init().  In future it will have some more
function.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
---
 hw/intc/xics_spapr.c        | 34 +++++++++++++++++++++++++++++++++-
 hw/ppc/spapr_irq.c          |  6 ++----
 include/hw/ppc/xics_spapr.h |  4 +++-
 3 files changed, 38 insertions(+), 6 deletions(-)

diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 3e9444813a..e6dd004587 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -283,8 +283,18 @@ static void rtas_int_on(PowerPCCPU *cpu, SpaprMachineState *spapr,
     rtas_st(rets, 0, RTAS_OUT_SUCCESS);
 }
 
-void xics_spapr_init(SpaprMachineState *spapr)
+static void ics_spapr_realize(DeviceState *dev, Error **errp)
 {
+    ICSState *ics = ICS_SPAPR(dev);
+    ICSStateClass *icsc = ICS_GET_CLASS(ics);
+    Error *local_err = NULL;
+
+    icsc->parent_realize(dev, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+
     spapr_rtas_register(RTAS_IBM_SET_XIVE, "ibm,set-xive", rtas_set_xive);
     spapr_rtas_register(RTAS_IBM_GET_XIVE, "ibm,get-xive", rtas_get_xive);
     spapr_rtas_register(RTAS_IBM_INT_OFF, "ibm,int-off", rtas_int_off);
@@ -319,3 +329,25 @@ void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
     _FDT(fdt_setprop_cell(fdt, node, "linux,phandle", phandle));
     _FDT(fdt_setprop_cell(fdt, node, "phandle", phandle));
 }
+
+static void ics_spapr_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    ICSStateClass *isc = ICS_CLASS(klass);
+
+    device_class_set_parent_realize(dc, ics_spapr_realize,
+                                    &isc->parent_realize);
+}
+
+static const TypeInfo ics_spapr_info = {
+    .name = TYPE_ICS_SPAPR,
+    .parent = TYPE_ICS,
+    .class_init = ics_spapr_class_init,
+};
+
+static void xics_spapr_register_types(void)
+{
+    type_register_static(&ics_spapr_info);
+}
+
+type_init(xics_spapr_register_types)
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 6c45d2a3c0..8c26fa2d1e 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -98,7 +98,7 @@ static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_irqs,
     Object *obj;
     Error *local_err = NULL;
 
-    obj = object_new(TYPE_ICS);
+    obj = object_new(TYPE_ICS_SPAPR);
     object_property_add_child(OBJECT(spapr), "ics", obj, &error_abort);
     object_property_add_const_link(obj, ICS_PROP_XICS, OBJECT(spapr),
                                    &error_fatal);
@@ -109,9 +109,7 @@ static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_irqs,
         return;
     }
 
-    spapr->ics = ICS(obj);
-
-    xics_spapr_init(spapr);
+    spapr->ics = ICS_SPAPR(obj);
 }
 
 static int spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h
index 5dabc9a138..691a6d00f7 100644
--- a/include/hw/ppc/xics_spapr.h
+++ b/include/hw/ppc/xics_spapr.h
@@ -31,11 +31,13 @@
 
 #define XICS_NODENAME "interrupt-controller"
 
+#define TYPE_ICS_SPAPR "ics-spapr"
+#define ICS_SPAPR(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SPAPR)
+
 void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
                    uint32_t phandle);
 int xics_kvm_connect(SpaprMachineState *spapr, Error **errp);
 void xics_kvm_disconnect(SpaprMachineState *spapr, Error **errp);
 bool xics_kvm_has_broken_disconnect(SpaprMachineState *spapr);
-void xics_spapr_init(SpaprMachineState *spapr);
 
 #endif /* XICS_SPAPR_H */
-- 
2.21.0



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

* [PATCH v2 07/33] spapr: Fold spapr_phb_lsi_qirq() into its single caller
  2019-09-27  5:49 [PATCH v2 00/33] spapr: IRQ subsystem cleanup David Gibson
                   ` (5 preceding siblings ...)
  2019-09-27  5:50 ` [PATCH v2 06/33] xics: Create sPAPR specific ICS subtype David Gibson
@ 2019-09-27  5:50 ` David Gibson
  2019-09-27  5:50 ` [PATCH v2 08/33] spapr: Replace spapr_vio_qirq() helper with spapr_vio_irq_pulse() helper David Gibson
                   ` (25 subsequent siblings)
  32 siblings, 0 replies; 83+ messages in thread
From: David Gibson @ 2019-09-27  5:50 UTC (permalink / raw)
  To: qemu-devel, clg, qemu-ppc
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier, Paolo Bonzini,
	Marc-André Lureau, philmd, David Gibson

No point having a two-line helper that's used exactly once, and not likely
to be used anywhere else in future.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
---
 hw/ppc/spapr_pci.c          | 3 ++-
 include/hw/pci-host/spapr.h | 7 -------
 2 files changed, 2 insertions(+), 8 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 7b71ad7c74..6934d506a7 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -721,9 +721,10 @@ static void pci_spapr_set_irq(void *opaque, int irq_num, int level)
      * corresponding qemu_irq.
      */
     SpaprPhbState *phb = opaque;
+    SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
 
     trace_spapr_pci_lsi_set(phb->dtbusname, irq_num, phb->lsi_table[irq_num].irq);
-    qemu_set_irq(spapr_phb_lsi_qirq(phb, irq_num), level);
+    qemu_set_irq(spapr_qirq(spapr, phb->lsi_table[irq_num].irq), level);
 }
 
 static PCIINTxRoute spapr_route_intx_pin_to_irq(void *opaque, int pin)
diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h
index abd87605b2..23506f05d9 100644
--- a/include/hw/pci-host/spapr.h
+++ b/include/hw/pci-host/spapr.h
@@ -128,13 +128,6 @@ struct SpaprPhbState {
 #define SPAPR_PCI_NV2ATSD_WIN_SIZE   (NVGPU_MAX_NUM * NVGPU_MAX_LINKS * \
                                       64 * KiB)
 
-static inline qemu_irq spapr_phb_lsi_qirq(struct SpaprPhbState *phb, int pin)
-{
-    SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
-
-    return spapr_qirq(spapr, phb->lsi_table[pin].irq);
-}
-
 int spapr_dt_phb(SpaprPhbState *phb, uint32_t intc_phandle, void *fdt,
                  uint32_t nr_msis, int *node_offset);
 
-- 
2.21.0



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

* [PATCH v2 08/33] spapr: Replace spapr_vio_qirq() helper with spapr_vio_irq_pulse() helper
  2019-09-27  5:49 [PATCH v2 00/33] spapr: IRQ subsystem cleanup David Gibson
                   ` (6 preceding siblings ...)
  2019-09-27  5:50 ` [PATCH v2 07/33] spapr: Fold spapr_phb_lsi_qirq() into its single caller David Gibson
@ 2019-09-27  5:50 ` David Gibson
  2019-09-27  5:50 ` [PATCH v2 09/33] spapr: Clarify and fix handling of nr_irqs David Gibson
                   ` (24 subsequent siblings)
  32 siblings, 0 replies; 83+ messages in thread
From: David Gibson @ 2019-09-27  5:50 UTC (permalink / raw)
  To: qemu-devel, clg, qemu-ppc
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier, Paolo Bonzini,
	Marc-André Lureau, philmd, David Gibson

Every caller of spapr_vio_qirq() immediately calls qemu_irq_pulse() with
the result, so we might as well just fold that into the helper.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
---
 hw/char/spapr_vty.c        | 3 +--
 hw/net/spapr_llan.c        | 3 +--
 hw/ppc/spapr_vio.c         | 3 +--
 include/hw/ppc/spapr_vio.h | 5 +++--
 4 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/hw/char/spapr_vty.c b/hw/char/spapr_vty.c
index 087c93e4fa..8f4d9fe472 100644
--- a/hw/char/spapr_vty.c
+++ b/hw/char/spapr_vty.c
@@ -5,7 +5,6 @@
 #include "cpu.h"
 #include "migration/vmstate.h"
 #include "chardev/char-fe.h"
-#include "hw/irq.h"
 #include "hw/ppc/spapr.h"
 #include "hw/ppc/spapr_vio.h"
 #include "hw/qdev-properties.h"
@@ -37,7 +36,7 @@ static void vty_receive(void *opaque, const uint8_t *buf, int size)
 
     if ((dev->in == dev->out) && size) {
         /* toggle line to simulate edge interrupt */
-        qemu_irq_pulse(spapr_vio_qirq(&dev->sdev));
+        spapr_vio_irq_pulse(&dev->sdev);
     }
     for (i = 0; i < size; i++) {
         if (dev->in - dev->out >= VTERM_BUFSIZE) {
diff --git a/hw/net/spapr_llan.c b/hw/net/spapr_llan.c
index 701e6e1514..3d96884d66 100644
--- a/hw/net/spapr_llan.c
+++ b/hw/net/spapr_llan.c
@@ -27,7 +27,6 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include "hw/irq.h"
 #include "qemu/log.h"
 #include "qemu/module.h"
 #include "net/net.h"
@@ -267,7 +266,7 @@ static ssize_t spapr_vlan_receive(NetClientState *nc, const uint8_t *buf,
     }
 
     if (sdev->signal_state & 1) {
-        qemu_irq_pulse(spapr_vio_qirq(sdev));
+        spapr_vio_irq_pulse(sdev);
     }
 
     return size;
diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c
index 0803649658..554de9930d 100644
--- a/hw/ppc/spapr_vio.c
+++ b/hw/ppc/spapr_vio.c
@@ -23,7 +23,6 @@
 #include "qemu/error-report.h"
 #include "qapi/error.h"
 #include "qapi/visitor.h"
-#include "hw/irq.h"
 #include "qemu/log.h"
 #include "hw/loader.h"
 #include "elf.h"
@@ -294,7 +293,7 @@ int spapr_vio_send_crq(SpaprVioDevice *dev, uint8_t *crq)
     dev->crq.qnext = (dev->crq.qnext + 16) % dev->crq.qsize;
 
     if (dev->signal_state & 1) {
-        qemu_irq_pulse(spapr_vio_qirq(dev));
+        spapr_vio_irq_pulse(dev);
     }
 
     return 0;
diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h
index 875be28cdd..72762ed16b 100644
--- a/include/hw/ppc/spapr_vio.h
+++ b/include/hw/ppc/spapr_vio.h
@@ -24,6 +24,7 @@
 
 #include "hw/ppc/spapr.h"
 #include "sysemu/dma.h"
+#include "hw/irq.h"
 
 #define TYPE_VIO_SPAPR_DEVICE "vio-spapr-device"
 #define VIO_SPAPR_DEVICE(obj) \
@@ -84,11 +85,11 @@ extern SpaprVioDevice *spapr_vio_find_by_reg(SpaprVioBus *bus, uint32_t reg);
 void spapr_dt_vdevice(SpaprVioBus *bus, void *fdt);
 extern gchar *spapr_vio_stdout_path(SpaprVioBus *bus);
 
-static inline qemu_irq spapr_vio_qirq(SpaprVioDevice *dev)
+static inline void spapr_vio_irq_pulse(SpaprVioDevice *dev)
 {
     SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
 
-    return spapr_qirq(spapr, dev->irq);
+    qemu_irq_pulse(spapr_qirq(spapr, dev->irq));
 }
 
 static inline bool spapr_vio_dma_valid(SpaprVioDevice *dev, uint64_t taddr,
-- 
2.21.0



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

* [PATCH v2 09/33] spapr: Clarify and fix handling of nr_irqs
  2019-09-27  5:49 [PATCH v2 00/33] spapr: IRQ subsystem cleanup David Gibson
                   ` (7 preceding siblings ...)
  2019-09-27  5:50 ` [PATCH v2 08/33] spapr: Replace spapr_vio_qirq() helper with spapr_vio_irq_pulse() helper David Gibson
@ 2019-09-27  5:50 ` David Gibson
  2019-09-27  7:53   ` Greg Kurz
  2019-09-27  5:50 ` [PATCH v2 10/33] spapr: Eliminate nr_irqs parameter to SpaprIrq::init David Gibson
                   ` (23 subsequent siblings)
  32 siblings, 1 reply; 83+ messages in thread
From: David Gibson @ 2019-09-27  5:50 UTC (permalink / raw)
  To: qemu-devel, clg, qemu-ppc
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier, Paolo Bonzini,
	Marc-André Lureau, philmd, David Gibson

Both the XICS and XIVE interrupt backends have a "nr-irqs" property, but
it means slightly different things.  For XICS (or, strictly, the ICS) it
indicates the number of "real" external IRQs.  Those start at XICS_IRQ_BASE
(0x1000) and don't include the special IPI vector.  For XIVE, however, it
includes the whole IRQ space, including XIVE's many IPI vectors.

The spapr code currently doesn't handle this sensibly, with the
nr_irqs value in SpaprIrq having different meanings depending on the
backend.  We fix this by renaming nr_irqs to nr_xirqs and making it
always indicate just the number of external irqs, adjusting the value
we pass to XIVE accordingly.  We also move to using common constants
in most of the irq configurations, to make it clearer that the IRQ
space looks the same to the guest (and emulated devices), even if the
backend is different.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr_irq.c         | 53 ++++++++++++++------------------------
 include/hw/ppc/spapr_irq.h | 19 +++++++++-----
 2 files changed, 31 insertions(+), 41 deletions(-)

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 8c26fa2d1e..3207b6bd01 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -92,7 +92,7 @@ static void spapr_irq_init_kvm(SpaprMachineState *spapr,
  * XICS IRQ backend.
  */
 
-static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_irqs,
+static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_xirqs,
                                 Error **errp)
 {
     Object *obj;
@@ -102,7 +102,7 @@ static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_irqs,
     object_property_add_child(OBJECT(spapr), "ics", obj, &error_abort);
     object_property_add_const_link(obj, ICS_PROP_XICS, OBJECT(spapr),
                                    &error_fatal);
-    object_property_set_int(obj, nr_irqs, "nr-irqs",  &error_fatal);
+    object_property_set_int(obj, nr_xirqs, "nr-irqs",  &error_fatal);
     object_property_set_bool(obj, true, "realized", &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
@@ -234,13 +234,9 @@ static void spapr_irq_init_kvm_xics(SpaprMachineState *spapr, Error **errp)
     }
 }
 
-#define SPAPR_IRQ_XICS_NR_IRQS     0x1000
-#define SPAPR_IRQ_XICS_NR_MSIS     \
-    (XICS_IRQ_BASE + SPAPR_IRQ_XICS_NR_IRQS - SPAPR_IRQ_MSI)
-
 SpaprIrq spapr_irq_xics = {
-    .nr_irqs     = SPAPR_IRQ_XICS_NR_IRQS,
-    .nr_msis     = SPAPR_IRQ_XICS_NR_MSIS,
+    .nr_xirqs    = SPAPR_NR_XIRQS,
+    .nr_msis     = SPAPR_NR_MSIS,
     .ov5         = SPAPR_OV5_XIVE_LEGACY,
 
     .init        = spapr_irq_init_xics,
@@ -260,7 +256,7 @@ SpaprIrq spapr_irq_xics = {
 /*
  * XIVE IRQ backend.
  */
-static void spapr_irq_init_xive(SpaprMachineState *spapr, int nr_irqs,
+static void spapr_irq_init_xive(SpaprMachineState *spapr, int nr_xirqs,
                                 Error **errp)
 {
     uint32_t nr_servers = spapr_max_server_number(spapr);
@@ -268,7 +264,7 @@ static void spapr_irq_init_xive(SpaprMachineState *spapr, int nr_irqs,
     int i;
 
     dev = qdev_create(NULL, TYPE_SPAPR_XIVE);
-    qdev_prop_set_uint32(dev, "nr-irqs", nr_irqs);
+    qdev_prop_set_uint32(dev, "nr-irqs", nr_xirqs + SPAPR_XIRQ_BASE);
     /*
      * 8 XIVE END structures per CPU. One for each available priority
      */
@@ -308,7 +304,7 @@ static qemu_irq spapr_qirq_xive(SpaprMachineState *spapr, int irq)
 {
     SpaprXive *xive = spapr->xive;
 
-    if (irq >= xive->nr_irqs) {
+    if ((irq < SPAPR_XIRQ_BASE) || (irq >= xive->nr_irqs)) {
         return NULL;
     }
 
@@ -404,17 +400,9 @@ static void spapr_irq_init_kvm_xive(SpaprMachineState *spapr, Error **errp)
     }
 }
 
-/*
- * XIVE uses the full IRQ number space. Set it to 8K to be compatible
- * with XICS.
- */
-
-#define SPAPR_IRQ_XIVE_NR_IRQS     0x2000
-#define SPAPR_IRQ_XIVE_NR_MSIS     (SPAPR_IRQ_XIVE_NR_IRQS - SPAPR_IRQ_MSI)
-
 SpaprIrq spapr_irq_xive = {
-    .nr_irqs     = SPAPR_IRQ_XIVE_NR_IRQS,
-    .nr_msis     = SPAPR_IRQ_XIVE_NR_MSIS,
+    .nr_xirqs    = SPAPR_NR_XIRQS,
+    .nr_msis     = SPAPR_NR_MSIS,
     .ov5         = SPAPR_OV5_XIVE_EXPLOIT,
 
     .init        = spapr_irq_init_xive,
@@ -450,18 +438,18 @@ static SpaprIrq *spapr_irq_current(SpaprMachineState *spapr)
         &spapr_irq_xive : &spapr_irq_xics;
 }
 
-static void spapr_irq_init_dual(SpaprMachineState *spapr, int nr_irqs,
+static void spapr_irq_init_dual(SpaprMachineState *spapr, int nr_xirqs,
                                 Error **errp)
 {
     Error *local_err = NULL;
 
-    spapr_irq_xics.init(spapr, spapr_irq_xics.nr_irqs, &local_err);
+    spapr_irq_xics.init(spapr, spapr_irq_xics.nr_xirqs, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
         return;
     }
 
-    spapr_irq_xive.init(spapr, spapr_irq_xive.nr_irqs, &local_err);
+    spapr_irq_xive.init(spapr, spapr_irq_xive.nr_xirqs, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
         return;
@@ -586,12 +574,9 @@ static const char *spapr_irq_get_nodename_dual(SpaprMachineState *spapr)
 /*
  * Define values in sync with the XIVE and XICS backend
  */
-#define SPAPR_IRQ_DUAL_NR_IRQS     0x2000
-#define SPAPR_IRQ_DUAL_NR_MSIS     (SPAPR_IRQ_DUAL_NR_IRQS - SPAPR_IRQ_MSI)
-
 SpaprIrq spapr_irq_dual = {
-    .nr_irqs     = SPAPR_IRQ_DUAL_NR_IRQS,
-    .nr_msis     = SPAPR_IRQ_DUAL_NR_MSIS,
+    .nr_xirqs    = SPAPR_NR_XIRQS,
+    .nr_msis     = SPAPR_NR_MSIS,
     .ov5         = SPAPR_OV5_XIVE_BOTH,
 
     .init        = spapr_irq_init_dual,
@@ -693,10 +678,10 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
         spapr_irq_msi_init(spapr, spapr->irq->nr_msis);
     }
 
-    spapr->irq->init(spapr, spapr->irq->nr_irqs, errp);
+    spapr->irq->init(spapr, spapr->irq->nr_xirqs, errp);
 
     spapr->qirqs = qemu_allocate_irqs(spapr->irq->set_irq, spapr,
-                                      spapr->irq->nr_irqs);
+                                      spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
 }
 
 int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
@@ -804,11 +789,11 @@ int spapr_irq_find(SpaprMachineState *spapr, int num, bool align, Error **errp)
     return first + ics->offset;
 }
 
-#define SPAPR_IRQ_XICS_LEGACY_NR_IRQS     0x400
+#define SPAPR_IRQ_XICS_LEGACY_NR_XIRQS     0x400
 
 SpaprIrq spapr_irq_xics_legacy = {
-    .nr_irqs     = SPAPR_IRQ_XICS_LEGACY_NR_IRQS,
-    .nr_msis     = SPAPR_IRQ_XICS_LEGACY_NR_IRQS,
+    .nr_xirqs    = SPAPR_IRQ_XICS_LEGACY_NR_XIRQS,
+    .nr_msis     = SPAPR_IRQ_XICS_LEGACY_NR_XIRQS,
     .ov5         = SPAPR_OV5_XIVE_LEGACY,
 
     .init        = spapr_irq_init_xics,
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index 5db305165c..a8f9a2ab11 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -16,13 +16,18 @@
  * IRQ range offsets per device type
  */
 #define SPAPR_IRQ_IPI        0x0
-#define SPAPR_IRQ_EPOW       0x1000  /* XICS_IRQ_BASE offset */
-#define SPAPR_IRQ_HOTPLUG    0x1001
-#define SPAPR_IRQ_VIO        0x1100  /* 256 VIO devices */
-#define SPAPR_IRQ_PCI_LSI    0x1200  /* 32+ PHBs devices */
 
-#define SPAPR_IRQ_MSI        0x1300  /* Offset of the dynamic range covered
-                                      * by the bitmap allocator */
+#define SPAPR_XIRQ_BASE      XICS_IRQ_BASE /* 0x1000 */
+#define SPAPR_IRQ_EPOW       (SPAPR_XIRQ_BASE + 0x0000)
+#define SPAPR_IRQ_HOTPLUG    (SPAPR_XIRQ_BASE + 0x0001)
+#define SPAPR_IRQ_VIO        (SPAPR_XIRQ_BASE + 0x0100)  /* 256 VIO devices */
+#define SPAPR_IRQ_PCI_LSI    (SPAPR_XIRQ_BASE + 0x0200)  /* 32+ PHBs devices */
+
+/* Offset of the dynamic range covered by the bitmap allocator */
+#define SPAPR_IRQ_MSI        (SPAPR_XIRQ_BASE + 0x0300)
+
+#define SPAPR_NR_XIRQS       0x1000
+#define SPAPR_NR_MSIS        (SPAPR_XIRQ_BASE + SPAPR_NR_XIRQS - SPAPR_IRQ_MSI)
 
 typedef struct SpaprMachineState SpaprMachineState;
 
@@ -32,7 +37,7 @@ int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align,
 void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, uint32_t num);
 
 typedef struct SpaprIrq {
-    uint32_t    nr_irqs;
+    uint32_t    nr_xirqs;
     uint32_t    nr_msis;
     uint8_t     ov5;
 
-- 
2.21.0



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

* [PATCH v2 10/33] spapr: Eliminate nr_irqs parameter to SpaprIrq::init
  2019-09-27  5:49 [PATCH v2 00/33] spapr: IRQ subsystem cleanup David Gibson
                   ` (8 preceding siblings ...)
  2019-09-27  5:50 ` [PATCH v2 09/33] spapr: Clarify and fix handling of nr_irqs David Gibson
@ 2019-09-27  5:50 ` David Gibson
  2019-09-27  7:57   ` Greg Kurz
  2019-09-27  5:50 ` [PATCH v2 11/33] spapr: Fix indexing of XICS irqs David Gibson
                   ` (22 subsequent siblings)
  32 siblings, 1 reply; 83+ messages in thread
From: David Gibson @ 2019-09-27  5:50 UTC (permalink / raw)
  To: qemu-devel, clg, qemu-ppc
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier, Paolo Bonzini,
	Marc-André Lureau, philmd, David Gibson

The only reason this parameter was needed was to work around the
inconsistent meaning of nr_irqs between xics and xive.  Now that we've
fixed that, we can consistently use the number directly in the SpaprIrq
configuration.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
---
 hw/ppc/spapr_irq.c         | 21 ++++++++++-----------
 include/hw/ppc/spapr_irq.h |  2 +-
 2 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 3207b6bd01..cded3a0154 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -92,8 +92,7 @@ static void spapr_irq_init_kvm(SpaprMachineState *spapr,
  * XICS IRQ backend.
  */
 
-static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_xirqs,
-                                Error **errp)
+static void spapr_irq_init_xics(SpaprMachineState *spapr, Error **errp)
 {
     Object *obj;
     Error *local_err = NULL;
@@ -102,7 +101,8 @@ static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_xirqs,
     object_property_add_child(OBJECT(spapr), "ics", obj, &error_abort);
     object_property_add_const_link(obj, ICS_PROP_XICS, OBJECT(spapr),
                                    &error_fatal);
-    object_property_set_int(obj, nr_xirqs, "nr-irqs",  &error_fatal);
+    object_property_set_int(obj, spapr->irq->nr_xirqs,
+                            "nr-irqs",  &error_fatal);
     object_property_set_bool(obj, true, "realized", &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
@@ -256,15 +256,15 @@ SpaprIrq spapr_irq_xics = {
 /*
  * XIVE IRQ backend.
  */
-static void spapr_irq_init_xive(SpaprMachineState *spapr, int nr_xirqs,
-                                Error **errp)
+static void spapr_irq_init_xive(SpaprMachineState *spapr, Error **errp)
 {
     uint32_t nr_servers = spapr_max_server_number(spapr);
     DeviceState *dev;
     int i;
 
     dev = qdev_create(NULL, TYPE_SPAPR_XIVE);
-    qdev_prop_set_uint32(dev, "nr-irqs", nr_xirqs + SPAPR_XIRQ_BASE);
+    qdev_prop_set_uint32(dev, "nr-irqs",
+                         spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
     /*
      * 8 XIVE END structures per CPU. One for each available priority
      */
@@ -438,18 +438,17 @@ static SpaprIrq *spapr_irq_current(SpaprMachineState *spapr)
         &spapr_irq_xive : &spapr_irq_xics;
 }
 
-static void spapr_irq_init_dual(SpaprMachineState *spapr, int nr_xirqs,
-                                Error **errp)
+static void spapr_irq_init_dual(SpaprMachineState *spapr, Error **errp)
 {
     Error *local_err = NULL;
 
-    spapr_irq_xics.init(spapr, spapr_irq_xics.nr_xirqs, &local_err);
+    spapr_irq_xics.init(spapr, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
         return;
     }
 
-    spapr_irq_xive.init(spapr, spapr_irq_xive.nr_xirqs, &local_err);
+    spapr_irq_xive.init(spapr, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
         return;
@@ -678,7 +677,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
         spapr_irq_msi_init(spapr, spapr->irq->nr_msis);
     }
 
-    spapr->irq->init(spapr, spapr->irq->nr_xirqs, errp);
+    spapr->irq->init(spapr, errp);
 
     spapr->qirqs = qemu_allocate_irqs(spapr->irq->set_irq, spapr,
                                       spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index a8f9a2ab11..7e26288fcd 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -41,7 +41,7 @@ typedef struct SpaprIrq {
     uint32_t    nr_msis;
     uint8_t     ov5;
 
-    void (*init)(SpaprMachineState *spapr, int nr_irqs, Error **errp);
+    void (*init)(SpaprMachineState *spapr, Error **errp);
     int (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
     void (*free)(SpaprMachineState *spapr, int irq, int num);
     qemu_irq (*qirq)(SpaprMachineState *spapr, int irq);
-- 
2.21.0



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

* [PATCH v2 11/33] spapr: Fix indexing of XICS irqs
  2019-09-27  5:49 [PATCH v2 00/33] spapr: IRQ subsystem cleanup David Gibson
                   ` (9 preceding siblings ...)
  2019-09-27  5:50 ` [PATCH v2 10/33] spapr: Eliminate nr_irqs parameter to SpaprIrq::init David Gibson
@ 2019-09-27  5:50 ` David Gibson
  2019-09-27  5:50 ` [PATCH v2 12/33] spapr: Simplify spapr_qirq() handling David Gibson
                   ` (21 subsequent siblings)
  32 siblings, 0 replies; 83+ messages in thread
From: David Gibson @ 2019-09-27  5:50 UTC (permalink / raw)
  To: qemu-devel, clg, qemu-ppc
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier, Paolo Bonzini,
	Marc-André Lureau, philmd, David Gibson

spapr global irq numbers are different from the source numbers on the ICS
when using XICS - they're offset by XICS_IRQ_BASE (0x1000).  But
spapr_irq_set_irq_xics() was passing through the global irq number to
the ICS code unmodified.

We only got away with this because of a counteracting bug - we were
incorrectly adjusting the qemu_irq we returned for a requested global irq
number.

That approach mostly worked but is very confusing, incorrectly relies on
the way the qemu_irq array is allocated, and undermines the intention of
having the global array of qemu_irqs for spapr have a consistent meaning
regardless of irq backend.

So, fix both set_irq and qemu_irq indexing.  We rename some parameters at
the same time to make it clear that they are referring to spapr global
irq numbers.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
---
 hw/ppc/spapr_irq.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index cded3a0154..8f79aa829f 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -153,10 +153,9 @@ static void spapr_irq_free_xics(SpaprMachineState *spapr, int irq, int num)
 static qemu_irq spapr_qirq_xics(SpaprMachineState *spapr, int irq)
 {
     ICSState *ics = spapr->ics;
-    uint32_t srcno = irq - ics->offset;
 
     if (ics_valid_irq(ics, irq)) {
-        return spapr->qirqs[srcno];
+        return spapr->qirqs[irq];
     }
 
     return NULL;
@@ -204,9 +203,10 @@ static int spapr_irq_post_load_xics(SpaprMachineState *spapr, int version_id)
     return 0;
 }
 
-static void spapr_irq_set_irq_xics(void *opaque, int srcno, int val)
+static void spapr_irq_set_irq_xics(void *opaque, int irq, int val)
 {
     SpaprMachineState *spapr = opaque;
+    uint32_t srcno = irq - spapr->ics->offset;
 
     ics_set_irq(spapr->ics, srcno, val);
 }
@@ -377,14 +377,14 @@ static void spapr_irq_reset_xive(SpaprMachineState *spapr, Error **errp)
     spapr_xive_mmio_set_enabled(spapr->xive, true);
 }
 
-static void spapr_irq_set_irq_xive(void *opaque, int srcno, int val)
+static void spapr_irq_set_irq_xive(void *opaque, int irq, int val)
 {
     SpaprMachineState *spapr = opaque;
 
     if (kvm_irqchip_in_kernel()) {
-        kvmppc_xive_source_set_irq(&spapr->xive->source, srcno, val);
+        kvmppc_xive_source_set_irq(&spapr->xive->source, irq, val);
     } else {
-        xive_source_set_irq(&spapr->xive->source, srcno, val);
+        xive_source_set_irq(&spapr->xive->source, irq, val);
     }
 }
 
@@ -558,11 +558,11 @@ static void spapr_irq_reset_dual(SpaprMachineState *spapr, Error **errp)
     spapr_irq_current(spapr)->reset(spapr, errp);
 }
 
-static void spapr_irq_set_irq_dual(void *opaque, int srcno, int val)
+static void spapr_irq_set_irq_dual(void *opaque, int irq, int val)
 {
     SpaprMachineState *spapr = opaque;
 
-    spapr_irq_current(spapr)->set_irq(spapr, srcno, val);
+    spapr_irq_current(spapr)->set_irq(spapr, irq, val);
 }
 
 static const char *spapr_irq_get_nodename_dual(SpaprMachineState *spapr)
-- 
2.21.0



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

* [PATCH v2 12/33] spapr: Simplify spapr_qirq() handling
  2019-09-27  5:49 [PATCH v2 00/33] spapr: IRQ subsystem cleanup David Gibson
                   ` (10 preceding siblings ...)
  2019-09-27  5:50 ` [PATCH v2 11/33] spapr: Fix indexing of XICS irqs David Gibson
@ 2019-09-27  5:50 ` David Gibson
  2019-09-27  5:50 ` [PATCH v2 13/33] spapr: Eliminate SpaprIrq:get_nodename method David Gibson
                   ` (20 subsequent siblings)
  32 siblings, 0 replies; 83+ messages in thread
From: David Gibson @ 2019-09-27  5:50 UTC (permalink / raw)
  To: qemu-devel, clg, qemu-ppc
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier, Paolo Bonzini,
	Marc-André Lureau, philmd, David Gibson

Currently spapr_qirq(), whic is used to find the qemu_irq for an spapr
global irq number, redirects through the SpaprIrq::qirq method.  But
the array of qemu_irqs is allocated in the PAPR layer, not the
backends, and so the method implementations all return the same thing,
just differing in the preliminary checks they make.

So, we can remove the method, and just implement spapr_qirq() directly,
including all the relevant checks in one place.  We change all those
checks into assert()s as well, since a failure here indicates an error in
the calling code.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
---
 hw/ppc/spapr_irq.c         | 54 ++++++++++++++------------------------
 include/hw/ppc/spapr_irq.h |  1 -
 2 files changed, 19 insertions(+), 36 deletions(-)

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 8f79aa829f..8f179076c6 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -150,17 +150,6 @@ static void spapr_irq_free_xics(SpaprMachineState *spapr, int irq, int num)
     }
 }
 
-static qemu_irq spapr_qirq_xics(SpaprMachineState *spapr, int irq)
-{
-    ICSState *ics = spapr->ics;
-
-    if (ics_valid_irq(ics, irq)) {
-        return spapr->qirqs[irq];
-    }
-
-    return NULL;
-}
-
 static void spapr_irq_print_info_xics(SpaprMachineState *spapr, Monitor *mon)
 {
     CPUState *cs;
@@ -242,7 +231,6 @@ SpaprIrq spapr_irq_xics = {
     .init        = spapr_irq_init_xics,
     .claim       = spapr_irq_claim_xics,
     .free        = spapr_irq_free_xics,
-    .qirq        = spapr_qirq_xics,
     .print_info  = spapr_irq_print_info_xics,
     .dt_populate = spapr_dt_xics,
     .cpu_intc_create = spapr_irq_cpu_intc_create_xics,
@@ -300,20 +288,6 @@ static void spapr_irq_free_xive(SpaprMachineState *spapr, int irq, int num)
     }
 }
 
-static qemu_irq spapr_qirq_xive(SpaprMachineState *spapr, int irq)
-{
-    SpaprXive *xive = spapr->xive;
-
-    if ((irq < SPAPR_XIRQ_BASE) || (irq >= xive->nr_irqs)) {
-        return NULL;
-    }
-
-    /* The sPAPR machine/device should have claimed the IRQ before */
-    assert(xive_eas_is_valid(&xive->eat[irq]));
-
-    return spapr->qirqs[irq];
-}
-
 static void spapr_irq_print_info_xive(SpaprMachineState *spapr,
                                       Monitor *mon)
 {
@@ -408,7 +382,6 @@ SpaprIrq spapr_irq_xive = {
     .init        = spapr_irq_init_xive,
     .claim       = spapr_irq_claim_xive,
     .free        = spapr_irq_free_xive,
-    .qirq        = spapr_qirq_xive,
     .print_info  = spapr_irq_print_info_xive,
     .dt_populate = spapr_dt_xive,
     .cpu_intc_create = spapr_irq_cpu_intc_create_xive,
@@ -482,11 +455,6 @@ static void spapr_irq_free_dual(SpaprMachineState *spapr, int irq, int num)
     spapr_irq_xive.free(spapr, irq, num);
 }
 
-static qemu_irq spapr_qirq_dual(SpaprMachineState *spapr, int irq)
-{
-    return spapr_irq_current(spapr)->qirq(spapr, irq);
-}
-
 static void spapr_irq_print_info_dual(SpaprMachineState *spapr, Monitor *mon)
 {
     spapr_irq_current(spapr)->print_info(spapr, mon);
@@ -581,7 +549,6 @@ SpaprIrq spapr_irq_dual = {
     .init        = spapr_irq_init_dual,
     .claim       = spapr_irq_claim_dual,
     .free        = spapr_irq_free_dual,
-    .qirq        = spapr_qirq_dual,
     .print_info  = spapr_irq_print_info_dual,
     .dt_populate = spapr_irq_dt_populate_dual,
     .cpu_intc_create = spapr_irq_cpu_intc_create_dual,
@@ -695,7 +662,25 @@ void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
 
 qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq)
 {
-    return spapr->irq->qirq(spapr, irq);
+    /*
+     * This interface is basically for VIO and PHB devices to find the
+     * right qemu_irq to manipulate, so we only allow access to the
+     * external irqs for now.  Currently anything which needs to
+     * access the IPIs most naturally gets there via the guest side
+     * interfaces, we can change this if we need to in future.
+     */
+    assert(irq >= SPAPR_XIRQ_BASE);
+    assert(irq < (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
+
+    if (spapr->ics) {
+        assert(ics_valid_irq(spapr->ics, irq));
+    }
+    if (spapr->xive) {
+        assert(irq < spapr->xive->nr_irqs);
+        assert(xive_eas_is_valid(&spapr->xive->eat[irq]));
+    }
+
+    return spapr->qirqs[irq];
 }
 
 int spapr_irq_post_load(SpaprMachineState *spapr, int version_id)
@@ -798,7 +783,6 @@ SpaprIrq spapr_irq_xics_legacy = {
     .init        = spapr_irq_init_xics,
     .claim       = spapr_irq_claim_xics,
     .free        = spapr_irq_free_xics,
-    .qirq        = spapr_qirq_xics,
     .print_info  = spapr_irq_print_info_xics,
     .dt_populate = spapr_dt_xics,
     .cpu_intc_create = spapr_irq_cpu_intc_create_xics,
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index 7e26288fcd..a4e790ef60 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -44,7 +44,6 @@ typedef struct SpaprIrq {
     void (*init)(SpaprMachineState *spapr, Error **errp);
     int (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
     void (*free)(SpaprMachineState *spapr, int irq, int num);
-    qemu_irq (*qirq)(SpaprMachineState *spapr, int irq);
     void (*print_info)(SpaprMachineState *spapr, Monitor *mon);
     void (*dt_populate)(SpaprMachineState *spapr, uint32_t nr_servers,
                         void *fdt, uint32_t phandle);
-- 
2.21.0



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

* [PATCH v2 13/33] spapr: Eliminate SpaprIrq:get_nodename method
  2019-09-27  5:49 [PATCH v2 00/33] spapr: IRQ subsystem cleanup David Gibson
                   ` (11 preceding siblings ...)
  2019-09-27  5:50 ` [PATCH v2 12/33] spapr: Simplify spapr_qirq() handling David Gibson
@ 2019-09-27  5:50 ` David Gibson
  2019-09-27  5:50 ` [PATCH v2 14/33] spapr: Remove unhelpful tracepoints from spapr_irq_free_xics() David Gibson
                   ` (19 subsequent siblings)
  32 siblings, 0 replies; 83+ messages in thread
From: David Gibson @ 2019-09-27  5:50 UTC (permalink / raw)
  To: qemu-devel, clg, qemu-ppc
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier, Paolo Bonzini,
	Marc-André Lureau, philmd, David Gibson

This method is used to determine the name of the irq backend's node in the
device tree, so that we can find its phandle (after SLOF may have modified
it from the phandle we initially gave it).

But, in the two cases the only difference between the node name is the
presence of a unit address.  Searching for a node name without considering
unit address is standard practice for the device tree, and
fdt_subnode_offset() will do exactly that, making this method unecessary.

While we're there, remove the XICS_NODENAME define.  The name
"interrupt-controller" is required by PAPR (and IEEE1275), and a bunch of
places assume it already.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Greg Kurz <groug@kaod.org>
---
 hw/intc/xics_spapr.c        |  2 +-
 hw/ppc/spapr_irq.c          | 25 +++----------------------
 include/hw/ppc/spapr_irq.h  |  1 -
 include/hw/ppc/xics_spapr.h |  2 --
 4 files changed, 4 insertions(+), 26 deletions(-)

diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index e6dd004587..6e5eb24b3c 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -316,7 +316,7 @@ void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
     };
     int node;
 
-    _FDT(node = fdt_add_subnode(fdt, 0, XICS_NODENAME));
+    _FDT(node = fdt_add_subnode(fdt, 0, "interrupt-controller"));
 
     _FDT(fdt_setprop_string(fdt, node, "device_type",
                             "PowerPC-External-Interrupt-Presentation"));
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 8f179076c6..ec2229d2d1 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -211,11 +211,6 @@ static void spapr_irq_reset_xics(SpaprMachineState *spapr, Error **errp)
     }
 }
 
-static const char *spapr_irq_get_nodename_xics(SpaprMachineState *spapr)
-{
-    return XICS_NODENAME;
-}
-
 static void spapr_irq_init_kvm_xics(SpaprMachineState *spapr, Error **errp)
 {
     if (kvm_enabled()) {
@@ -237,7 +232,6 @@ SpaprIrq spapr_irq_xics = {
     .post_load   = spapr_irq_post_load_xics,
     .reset       = spapr_irq_reset_xics,
     .set_irq     = spapr_irq_set_irq_xics,
-    .get_nodename = spapr_irq_get_nodename_xics,
     .init_kvm    = spapr_irq_init_kvm_xics,
 };
 
@@ -362,11 +356,6 @@ static void spapr_irq_set_irq_xive(void *opaque, int irq, int val)
     }
 }
 
-static const char *spapr_irq_get_nodename_xive(SpaprMachineState *spapr)
-{
-    return spapr->xive->nodename;
-}
-
 static void spapr_irq_init_kvm_xive(SpaprMachineState *spapr, Error **errp)
 {
     if (kvm_enabled()) {
@@ -388,7 +377,6 @@ SpaprIrq spapr_irq_xive = {
     .post_load   = spapr_irq_post_load_xive,
     .reset       = spapr_irq_reset_xive,
     .set_irq     = spapr_irq_set_irq_xive,
-    .get_nodename = spapr_irq_get_nodename_xive,
     .init_kvm    = spapr_irq_init_kvm_xive,
 };
 
@@ -533,11 +521,6 @@ static void spapr_irq_set_irq_dual(void *opaque, int irq, int val)
     spapr_irq_current(spapr)->set_irq(spapr, irq, val);
 }
 
-static const char *spapr_irq_get_nodename_dual(SpaprMachineState *spapr)
-{
-    return spapr_irq_current(spapr)->get_nodename(spapr);
-}
-
 /*
  * Define values in sync with the XIVE and XICS backend
  */
@@ -555,7 +538,6 @@ SpaprIrq spapr_irq_dual = {
     .post_load   = spapr_irq_post_load_dual,
     .reset       = spapr_irq_reset_dual,
     .set_irq     = spapr_irq_set_irq_dual,
-    .get_nodename = spapr_irq_get_nodename_dual,
     .init_kvm    = NULL, /* should not be used */
 };
 
@@ -699,13 +681,13 @@ void spapr_irq_reset(SpaprMachineState *spapr, Error **errp)
 
 int spapr_irq_get_phandle(SpaprMachineState *spapr, void *fdt, Error **errp)
 {
-    const char *nodename = spapr->irq->get_nodename(spapr);
+    const char *nodename = "interrupt-controller";
     int offset, phandle;
 
     offset = fdt_subnode_offset(fdt, 0, nodename);
     if (offset < 0) {
-        error_setg(errp, "Can't find node \"%s\": %s", nodename,
-                   fdt_strerror(offset));
+        error_setg(errp, "Can't find node \"%s\": %s",
+                   nodename, fdt_strerror(offset));
         return -1;
     }
 
@@ -789,6 +771,5 @@ SpaprIrq spapr_irq_xics_legacy = {
     .post_load   = spapr_irq_post_load_xics,
     .reset       = spapr_irq_reset_xics,
     .set_irq     = spapr_irq_set_irq_xics,
-    .get_nodename = spapr_irq_get_nodename_xics,
     .init_kvm    = spapr_irq_init_kvm_xics,
 };
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index a4e790ef60..9b60378e28 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -52,7 +52,6 @@ typedef struct SpaprIrq {
     int (*post_load)(SpaprMachineState *spapr, int version_id);
     void (*reset)(SpaprMachineState *spapr, Error **errp);
     void (*set_irq)(void *opaque, int srcno, int val);
-    const char *(*get_nodename)(SpaprMachineState *spapr);
     void (*init_kvm)(SpaprMachineState *spapr, Error **errp);
 } SpaprIrq;
 
diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h
index 691a6d00f7..0b35e85c26 100644
--- a/include/hw/ppc/xics_spapr.h
+++ b/include/hw/ppc/xics_spapr.h
@@ -29,8 +29,6 @@
 
 #include "hw/ppc/spapr.h"
 
-#define XICS_NODENAME "interrupt-controller"
-
 #define TYPE_ICS_SPAPR "ics-spapr"
 #define ICS_SPAPR(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SPAPR)
 
-- 
2.21.0



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

* [PATCH v2 14/33] spapr: Remove unhelpful tracepoints from spapr_irq_free_xics()
  2019-09-27  5:49 [PATCH v2 00/33] spapr: IRQ subsystem cleanup David Gibson
                   ` (12 preceding siblings ...)
  2019-09-27  5:50 ` [PATCH v2 13/33] spapr: Eliminate SpaprIrq:get_nodename method David Gibson
@ 2019-09-27  5:50 ` David Gibson
  2019-09-27  5:50 ` [PATCH v2 15/33] spapr: Handle freeing of multiple irqs in frontend only David Gibson
                   ` (18 subsequent siblings)
  32 siblings, 0 replies; 83+ messages in thread
From: David Gibson @ 2019-09-27  5:50 UTC (permalink / raw)
  To: qemu-devel, clg, qemu-ppc
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier, Paolo Bonzini,
	Marc-André Lureau, philmd, David Gibson

These traces contain some useless information (the always-0 source#) and
have no equivalents for XIVE mode.  For now just remove them, and we can
put back something more sensible if and when we need it.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
---
 hw/ppc/spapr_irq.c  | 4 ----
 hw/ppc/trace-events | 4 ----
 2 files changed, 8 deletions(-)

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index ec2229d2d1..9919910a86 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -140,11 +140,7 @@ static void spapr_irq_free_xics(SpaprMachineState *spapr, int irq, int num)
     int i;
 
     if (ics_valid_irq(ics, irq)) {
-        trace_spapr_irq_free(0, irq, num);
         for (i = srcno; i < srcno + num; ++i) {
-            if (ics_irq_free(ics, i)) {
-                trace_spapr_irq_free_warn(0, i);
-            }
             memset(&ics->irqs[i], 0, sizeof(ICSIRQState));
         }
     }
diff --git a/hw/ppc/trace-events b/hw/ppc/trace-events
index 96dad767a1..9ea620f23c 100644
--- a/hw/ppc/trace-events
+++ b/hw/ppc/trace-events
@@ -13,10 +13,6 @@ spapr_pci_msi_retry(unsigned config_addr, unsigned req_num, unsigned max_irqs) "
 spapr_cas_failed(unsigned long n) "DT diff buffer is too small: %ld bytes"
 spapr_cas_continue(unsigned long n) "Copy changes to the guest: %ld bytes"
 
-# spapr_irq.c
-spapr_irq_free(int src, int irq, int num) "Source#%d, first irq %d, %d irqs"
-spapr_irq_free_warn(int src, int irq) "Source#%d, irq %d is already free"
-
 # spapr_hcall.c
 spapr_cas_pvr(uint32_t cur_pvr, bool explicit_match, uint32_t new_pvr) "current=0x%x, explicit_match=%u, new=0x%x"
 spapr_h_resize_hpt_prepare(uint64_t flags, uint64_t shift) "flags=0x%"PRIx64", shift=%"PRIu64
-- 
2.21.0



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

* [PATCH v2 15/33] spapr: Handle freeing of multiple irqs in frontend only
  2019-09-27  5:49 [PATCH v2 00/33] spapr: IRQ subsystem cleanup David Gibson
                   ` (13 preceding siblings ...)
  2019-09-27  5:50 ` [PATCH v2 14/33] spapr: Remove unhelpful tracepoints from spapr_irq_free_xics() David Gibson
@ 2019-09-27  5:50 ` David Gibson
  2019-09-27  5:50 ` [PATCH v2 16/33] spapr, xics, xive: Better use of assert()s on irq claim/free paths David Gibson
                   ` (17 subsequent siblings)
  32 siblings, 0 replies; 83+ messages in thread
From: David Gibson @ 2019-09-27  5:50 UTC (permalink / raw)
  To: qemu-devel, clg, qemu-ppc
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier, Paolo Bonzini,
	Marc-André Lureau, philmd, David Gibson

spapr_irq_free() can be used to free multiple irqs at once. That's useful
for its callers, but there's no need to make the individual backend hooks
handle this.  We can loop across the irqs in spapr_irq_free() itself and
have the hooks just do one at time.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
---
 hw/ppc/spapr_irq.c         | 27 ++++++++++++---------------
 include/hw/ppc/spapr_irq.h |  2 +-
 2 files changed, 13 insertions(+), 16 deletions(-)

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 9919910a86..37c51c96ae 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -133,16 +133,13 @@ static int spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
     return 0;
 }
 
-static void spapr_irq_free_xics(SpaprMachineState *spapr, int irq, int num)
+static void spapr_irq_free_xics(SpaprMachineState *spapr, int irq)
 {
     ICSState *ics = spapr->ics;
     uint32_t srcno = irq - ics->offset;
-    int i;
 
     if (ics_valid_irq(ics, irq)) {
-        for (i = srcno; i < srcno + num; ++i) {
-            memset(&ics->irqs[i], 0, sizeof(ICSIRQState));
-        }
+        memset(&ics->irqs[srcno], 0, sizeof(ICSIRQState));
     }
 }
 
@@ -269,13 +266,9 @@ static int spapr_irq_claim_xive(SpaprMachineState *spapr, int irq, bool lsi,
     return 0;
 }
 
-static void spapr_irq_free_xive(SpaprMachineState *spapr, int irq, int num)
+static void spapr_irq_free_xive(SpaprMachineState *spapr, int irq)
 {
-    int i;
-
-    for (i = irq; i < irq + num; ++i) {
-        spapr_xive_irq_free(spapr->xive, i);
-    }
+    spapr_xive_irq_free(spapr->xive, irq);
 }
 
 static void spapr_irq_print_info_xive(SpaprMachineState *spapr,
@@ -433,10 +426,10 @@ static int spapr_irq_claim_dual(SpaprMachineState *spapr, int irq, bool lsi,
     return ret;
 }
 
-static void spapr_irq_free_dual(SpaprMachineState *spapr, int irq, int num)
+static void spapr_irq_free_dual(SpaprMachineState *spapr, int irq)
 {
-    spapr_irq_xics.free(spapr, irq, num);
-    spapr_irq_xive.free(spapr, irq, num);
+    spapr_irq_xics.free(spapr, irq);
+    spapr_irq_xive.free(spapr, irq);
 }
 
 static void spapr_irq_print_info_dual(SpaprMachineState *spapr, Monitor *mon)
@@ -635,7 +628,11 @@ int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
 
 void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
 {
-    spapr->irq->free(spapr, irq, num);
+    int i;
+
+    for (i = irq; i < (irq + num); i++) {
+        spapr->irq->free(spapr, irq);
+    }
 }
 
 qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq)
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index 9b60378e28..ed88b4599a 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -43,7 +43,7 @@ typedef struct SpaprIrq {
 
     void (*init)(SpaprMachineState *spapr, Error **errp);
     int (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
-    void (*free)(SpaprMachineState *spapr, int irq, int num);
+    void (*free)(SpaprMachineState *spapr, int irq);
     void (*print_info)(SpaprMachineState *spapr, Monitor *mon);
     void (*dt_populate)(SpaprMachineState *spapr, uint32_t nr_servers,
                         void *fdt, uint32_t phandle);
-- 
2.21.0



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

* [PATCH v2 16/33] spapr, xics, xive: Better use of assert()s on irq claim/free paths
  2019-09-27  5:49 [PATCH v2 00/33] spapr: IRQ subsystem cleanup David Gibson
                   ` (14 preceding siblings ...)
  2019-09-27  5:50 ` [PATCH v2 15/33] spapr: Handle freeing of multiple irqs in frontend only David Gibson
@ 2019-09-27  5:50 ` David Gibson
  2019-09-27  5:50 ` [PATCH v2 17/33] xive: Improve irq claim/free path David Gibson
                   ` (16 subsequent siblings)
  32 siblings, 0 replies; 83+ messages in thread
From: David Gibson @ 2019-09-27  5:50 UTC (permalink / raw)
  To: qemu-devel, clg, qemu-ppc
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier, Paolo Bonzini,
	Marc-André Lureau, philmd, David Gibson

The irq claim and free paths for both XICS and XIVE check for some
validity conditions.  Some of these represent genuine runtime failures,
however others - particularly checking that the basic irq number is in a
sane range - could only fail in the case of bugs in the callin code.
Therefore use assert()s instead of runtime failures for those.

In addition the non backend-specific part of the claim/free paths should
only be used for PAPR external irqs, that is in the range SPAPR_XIRQ_BASE
to the maximum irq number.  Put assert()s for that into the top level
dispatchers as well.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
---
 hw/intc/spapr_xive.c |  8 ++------
 hw/ppc/spapr_irq.c   | 18 ++++++++++--------
 2 files changed, 12 insertions(+), 14 deletions(-)

diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index c1c97192a7..47b5ec0b56 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -532,9 +532,7 @@ bool spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi)
 {
     XiveSource *xsrc = &xive->source;
 
-    if (lisn >= xive->nr_irqs) {
-        return false;
-    }
+    assert(lisn < xive->nr_irqs);
 
     /*
      * Set default values when allocating an IRQ number
@@ -559,9 +557,7 @@ bool spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi)
 
 bool spapr_xive_irq_free(SpaprXive *xive, uint32_t lisn)
 {
-    if (lisn >= xive->nr_irqs) {
-        return false;
-    }
+    assert(lisn < xive->nr_irqs);
 
     xive->eat[lisn].w &= cpu_to_be64(~EAS_VALID);
     return true;
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 37c51c96ae..da9e80b24e 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -118,11 +118,7 @@ static int spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
     ICSState *ics = spapr->ics;
 
     assert(ics);
-
-    if (!ics_valid_irq(ics, irq)) {
-        error_setg(errp, "IRQ %d is invalid", irq);
-        return -1;
-    }
+    assert(ics_valid_irq(ics, irq));
 
     if (!ics_irq_free(ics, irq - ics->offset)) {
         error_setg(errp, "IRQ %d is not free", irq);
@@ -138,9 +134,9 @@ static void spapr_irq_free_xics(SpaprMachineState *spapr, int irq)
     ICSState *ics = spapr->ics;
     uint32_t srcno = irq - ics->offset;
 
-    if (ics_valid_irq(ics, irq)) {
-        memset(&ics->irqs[srcno], 0, sizeof(ICSIRQState));
-    }
+    assert(ics_valid_irq(ics, irq));
+
+    memset(&ics->irqs[srcno], 0, sizeof(ICSIRQState));
 }
 
 static void spapr_irq_print_info_xics(SpaprMachineState *spapr, Monitor *mon)
@@ -623,6 +619,9 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
 
 int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
 {
+    assert(irq >= SPAPR_XIRQ_BASE);
+    assert(irq < (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
+
     return spapr->irq->claim(spapr, irq, lsi, errp);
 }
 
@@ -630,6 +629,9 @@ void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
 {
     int i;
 
+    assert(irq >= SPAPR_XIRQ_BASE);
+    assert((irq + num) <= (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
+
     for (i = irq; i < (irq + num); i++) {
         spapr->irq->free(spapr, irq);
     }
-- 
2.21.0



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

* [PATCH v2 17/33] xive: Improve irq claim/free path
  2019-09-27  5:49 [PATCH v2 00/33] spapr: IRQ subsystem cleanup David Gibson
                   ` (15 preceding siblings ...)
  2019-09-27  5:50 ` [PATCH v2 16/33] spapr, xics, xive: Better use of assert()s on irq claim/free paths David Gibson
@ 2019-09-27  5:50 ` David Gibson
  2019-09-27  8:40   ` Greg Kurz
  2019-09-27  5:50 ` [PATCH v2 18/33] spapr: Use less cryptic representation of which irq backends are supported David Gibson
                   ` (15 subsequent siblings)
  32 siblings, 1 reply; 83+ messages in thread
From: David Gibson @ 2019-09-27  5:50 UTC (permalink / raw)
  To: qemu-devel, clg, qemu-ppc
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier, Paolo Bonzini,
	Marc-André Lureau, philmd, David Gibson

spapr_xive_irq_claim() returns a bool to indicate if it succeeded.
But most of the callers and one callee use int return values and/or an
Error * with more information instead.  In any case, ints are a more
common idiom for success/failure states than bools (one never knows
what sense they'll be in).

So instead change to an int return value to indicate presence of error
+ an Error * to describe the details through that call chain.

It also didn't actually check if the irq was already claimed, which is
one of the primary purposes of the claim path, so do that.

spapr_xive_irq_free() also returned a bool... which no callers checked
and was always true, so just drop it.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
---
 hw/intc/spapr_xive.c        | 20 +++++++++-----------
 hw/intc/spapr_xive_kvm.c    |  8 ++++----
 hw/ppc/spapr_irq.c          | 14 ++++++++------
 include/hw/ppc/spapr_xive.h |  4 ++--
 include/hw/ppc/xive.h       |  2 +-
 5 files changed, 24 insertions(+), 24 deletions(-)

diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index 47b5ec0b56..04879abf2e 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -528,12 +528,17 @@ static void spapr_xive_register_types(void)
 
 type_init(spapr_xive_register_types)
 
-bool spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi)
+int spapr_xive_irq_claim(SpaprXive *xive, int lisn, bool lsi, Error **errp)
 {
     XiveSource *xsrc = &xive->source;
 
     assert(lisn < xive->nr_irqs);
 
+    if (xive_eas_is_valid(&xive->eat[lisn])) {
+        error_setg(errp, "IRQ %d is not free", lisn);
+        return -EBUSY;
+    }
+
     /*
      * Set default values when allocating an IRQ number
      */
@@ -543,24 +548,17 @@ bool spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi)
     }
 
     if (kvm_irqchip_in_kernel()) {
-        Error *local_err = NULL;
-
-        kvmppc_xive_source_reset_one(xsrc, lisn, &local_err);
-        if (local_err) {
-            error_report_err(local_err);
-            return false;
-        }
+        return kvmppc_xive_source_reset_one(xsrc, lisn, errp);
     }
 
-    return true;
+    return 0;
 }
 
-bool spapr_xive_irq_free(SpaprXive *xive, uint32_t lisn)
+void spapr_xive_irq_free(SpaprXive *xive, int lisn)
 {
     assert(lisn < xive->nr_irqs);
 
     xive->eat[lisn].w &= cpu_to_be64(~EAS_VALID);
-    return true;
 }
 
 /*
diff --git a/hw/intc/spapr_xive_kvm.c b/hw/intc/spapr_xive_kvm.c
index 2006f96aec..51b334b676 100644
--- a/hw/intc/spapr_xive_kvm.c
+++ b/hw/intc/spapr_xive_kvm.c
@@ -232,14 +232,14 @@ void kvmppc_xive_sync_source(SpaprXive *xive, uint32_t lisn, Error **errp)
  * only need to inform the KVM XIVE device about their type: LSI or
  * MSI.
  */
-void kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **errp)
+int kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **errp)
 {
     SpaprXive *xive = SPAPR_XIVE(xsrc->xive);
     uint64_t state = 0;
 
     /* The KVM XIVE device is not in use */
     if (xive->fd == -1) {
-        return;
+        return -ENODEV;
     }
 
     if (xive_source_irq_is_lsi(xsrc, srcno)) {
@@ -249,8 +249,8 @@ void kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **errp)
         }
     }
 
-    kvm_device_access(xive->fd, KVM_DEV_XIVE_GRP_SOURCE, srcno, &state,
-                      true, errp);
+    return kvm_device_access(xive->fd, KVM_DEV_XIVE_GRP_SOURCE, srcno, &state,
+                             true, errp);
 }
 
 static void kvmppc_xive_source_reset(XiveSource *xsrc, Error **errp)
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index da9e80b24e..4951329959 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -246,7 +246,13 @@ static void spapr_irq_init_xive(SpaprMachineState *spapr, Error **errp)
 
     /* Enable the CPU IPIs */
     for (i = 0; i < nr_servers; ++i) {
-        spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i, false);
+        Error *local_err = NULL;
+
+        spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i, false, &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            return;
+        }
     }
 
     spapr_xive_hcall_init(spapr);
@@ -255,11 +261,7 @@ static void spapr_irq_init_xive(SpaprMachineState *spapr, Error **errp)
 static int spapr_irq_claim_xive(SpaprMachineState *spapr, int irq, bool lsi,
                                 Error **errp)
 {
-    if (!spapr_xive_irq_claim(spapr->xive, irq, lsi)) {
-        error_setg(errp, "IRQ %d is invalid", irq);
-        return -1;
-    }
-    return 0;
+    return spapr_xive_irq_claim(spapr->xive, irq, lsi, errp);
 }
 
 static void spapr_irq_free_xive(SpaprMachineState *spapr, int irq)
diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h
index bfd40f01d8..0df20a6590 100644
--- a/include/hw/ppc/spapr_xive.h
+++ b/include/hw/ppc/spapr_xive.h
@@ -54,8 +54,8 @@ typedef struct SpaprXive {
  */
 #define SPAPR_XIVE_BLOCK_ID 0x0
 
-bool spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi);
-bool spapr_xive_irq_free(SpaprXive *xive, uint32_t lisn);
+int spapr_xive_irq_claim(SpaprXive *xive, int lisn, bool lsi, Error **errp);
+void spapr_xive_irq_free(SpaprXive *xive, int lisn);
 void spapr_xive_pic_print_info(SpaprXive *xive, Monitor *mon);
 int spapr_xive_post_load(SpaprXive *xive, int version_id);
 
diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
index 6d38755f84..fd3319bd32 100644
--- a/include/hw/ppc/xive.h
+++ b/include/hw/ppc/xive.h
@@ -425,7 +425,7 @@ static inline uint32_t xive_nvt_cam_line(uint8_t nvt_blk, uint32_t nvt_idx)
  * KVM XIVE device helpers
  */
 
-void kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **errp);
+int kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **errp);
 void kvmppc_xive_source_set_irq(void *opaque, int srcno, int val);
 void kvmppc_xive_cpu_connect(XiveTCTX *tctx, Error **errp);
 void kvmppc_xive_cpu_synchronize_state(XiveTCTX *tctx, Error **errp);
-- 
2.21.0



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

* [PATCH v2 18/33] spapr: Use less cryptic representation of which irq backends are supported
  2019-09-27  5:49 [PATCH v2 00/33] spapr: IRQ subsystem cleanup David Gibson
                   ` (16 preceding siblings ...)
  2019-09-27  5:50 ` [PATCH v2 17/33] xive: Improve irq claim/free path David Gibson
@ 2019-09-27  5:50 ` David Gibson
  2019-09-27  5:50 ` [PATCH v2 19/33] spapr: Eliminate SpaprIrq::init hook David Gibson
                   ` (14 subsequent siblings)
  32 siblings, 0 replies; 83+ messages in thread
From: David Gibson @ 2019-09-27  5:50 UTC (permalink / raw)
  To: qemu-devel, clg, qemu-ppc
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier, Paolo Bonzini,
	Marc-André Lureau, philmd, David Gibson

SpaprIrq::ov5 stores the value for a particular byte in PAPR option vector
5 which indicates whether XICS, XIVE or both interrupt controllers are
available.  As usual for PAPR, the encoding is kind of overly complicated
and confusing (though to be fair there are some backwards compat things it
has to handle).

But to make our internal code clearer, have SpaprIrq encode more directly
which backends are available as two booleans, and derive the OV5 value from
that at the point we need it.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
---
 hw/ppc/spapr.c             | 15 ++++++++++++---
 hw/ppc/spapr_hcall.c       |  6 +++---
 hw/ppc/spapr_irq.c         | 12 ++++++++----
 include/hw/ppc/spapr_irq.h |  3 ++-
 4 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 3742a8cf06..795f6ab505 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1136,19 +1136,28 @@ static void spapr_dt_ov5_platform_support(SpaprMachineState *spapr, void *fdt,
     PowerPCCPU *first_ppc_cpu = POWERPC_CPU(first_cpu);
 
     char val[2 * 4] = {
-        23, spapr->irq->ov5, /* Xive mode. */
+        23, 0x00, /* XICS / XIVE mode */
         24, 0x00, /* Hash/Radix, filled in below. */
         25, 0x00, /* Hash options: Segment Tables == no, GTSE == no. */
         26, 0x40, /* Radix options: GTSE == yes. */
     };
 
+    if (spapr->irq->xics && spapr->irq->xive) {
+        val[1] = SPAPR_OV5_XIVE_BOTH;
+    } else if (spapr->irq->xive) {
+        val[1] = SPAPR_OV5_XIVE_EXPLOIT;
+    } else {
+        assert(spapr->irq->xics);
+        val[1] = SPAPR_OV5_XIVE_LEGACY;
+    }
+
     if (!ppc_check_compat(first_ppc_cpu, CPU_POWERPC_LOGICAL_3_00, 0,
                           first_ppc_cpu->compat_pvr)) {
         /*
          * If we're in a pre POWER9 compat mode then the guest should
          * do hash and use the legacy interrupt mode
          */
-        val[1] = 0x00; /* XICS */
+        val[1] = SPAPR_OV5_XIVE_LEGACY; /* XICS */
         val[3] = 0x00; /* Hash */
     } else if (kvm_enabled()) {
         if (kvmppc_has_cap_mmu_radix() && kvmppc_has_cap_mmu_hash_v3()) {
@@ -2837,7 +2846,7 @@ static void spapr_machine_init(MachineState *machine)
     spapr_ovec_set(spapr->ov5, OV5_DRMEM_V2);
 
     /* advertise XIVE on POWER9 machines */
-    if (spapr->irq->ov5 & (SPAPR_OV5_XIVE_EXPLOIT | SPAPR_OV5_XIVE_BOTH)) {
+    if (spapr->irq->xive) {
         spapr_ovec_set(spapr->ov5, OV5_XIVE_EXPLOIT);
     }
 
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 3d3a67149a..140f05c1c6 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -1784,13 +1784,13 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
      * terminate the boot.
      */
     if (guest_xive) {
-        if (spapr->irq->ov5 == SPAPR_OV5_XIVE_LEGACY) {
+        if (!spapr->irq->xive) {
             error_report(
 "Guest requested unavailable interrupt mode (XIVE), try the ic-mode=xive or ic-mode=dual machine property");
             exit(EXIT_FAILURE);
         }
     } else {
-        if (spapr->irq->ov5 == SPAPR_OV5_XIVE_EXPLOIT) {
+        if (!spapr->irq->xics) {
             error_report(
 "Guest requested unavailable interrupt mode (XICS), either don't set the ic-mode machine property or try ic-mode=xics or ic-mode=dual");
             exit(EXIT_FAILURE);
@@ -1804,7 +1804,7 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
      */
     if (!spapr->cas_reboot) {
         spapr->cas_reboot = spapr_ovec_test(ov5_updates, OV5_XIVE_EXPLOIT)
-            && spapr->irq->ov5 & SPAPR_OV5_XIVE_BOTH;
+            && spapr->irq->xics && spapr->irq->xive;
     }
 
     spapr_ovec_cleanup(ov5_updates);
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 4951329959..0aec5b0f0e 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -210,7 +210,8 @@ static void spapr_irq_init_kvm_xics(SpaprMachineState *spapr, Error **errp)
 SpaprIrq spapr_irq_xics = {
     .nr_xirqs    = SPAPR_NR_XIRQS,
     .nr_msis     = SPAPR_NR_MSIS,
-    .ov5         = SPAPR_OV5_XIVE_LEGACY,
+    .xics        = true,
+    .xive        = false,
 
     .init        = spapr_irq_init_xics,
     .claim       = spapr_irq_claim_xics,
@@ -353,7 +354,8 @@ static void spapr_irq_init_kvm_xive(SpaprMachineState *spapr, Error **errp)
 SpaprIrq spapr_irq_xive = {
     .nr_xirqs    = SPAPR_NR_XIRQS,
     .nr_msis     = SPAPR_NR_MSIS,
-    .ov5         = SPAPR_OV5_XIVE_EXPLOIT,
+    .xics        = false,
+    .xive        = true,
 
     .init        = spapr_irq_init_xive,
     .claim       = spapr_irq_claim_xive,
@@ -514,7 +516,8 @@ static void spapr_irq_set_irq_dual(void *opaque, int irq, int val)
 SpaprIrq spapr_irq_dual = {
     .nr_xirqs    = SPAPR_NR_XIRQS,
     .nr_msis     = SPAPR_NR_MSIS,
-    .ov5         = SPAPR_OV5_XIVE_BOTH,
+    .xics        = true,
+    .xive        = true,
 
     .init        = spapr_irq_init_dual,
     .claim       = spapr_irq_claim_dual,
@@ -757,7 +760,8 @@ int spapr_irq_find(SpaprMachineState *spapr, int num, bool align, Error **errp)
 SpaprIrq spapr_irq_xics_legacy = {
     .nr_xirqs    = SPAPR_IRQ_XICS_LEGACY_NR_XIRQS,
     .nr_msis     = SPAPR_IRQ_XICS_LEGACY_NR_XIRQS,
-    .ov5         = SPAPR_OV5_XIVE_LEGACY,
+    .xics        = true,
+    .xive        = false,
 
     .init        = spapr_irq_init_xics,
     .claim       = spapr_irq_claim_xics,
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index ed88b4599a..d3f3b85eb9 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -39,7 +39,8 @@ void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, uint32_t num);
 typedef struct SpaprIrq {
     uint32_t    nr_xirqs;
     uint32_t    nr_msis;
-    uint8_t     ov5;
+    bool        xics;
+    bool        xive;
 
     void (*init)(SpaprMachineState *spapr, Error **errp);
     int (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
-- 
2.21.0



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

* [PATCH v2 19/33] spapr: Eliminate SpaprIrq::init hook
  2019-09-27  5:49 [PATCH v2 00/33] spapr: IRQ subsystem cleanup David Gibson
                   ` (17 preceding siblings ...)
  2019-09-27  5:50 ` [PATCH v2 18/33] spapr: Use less cryptic representation of which irq backends are supported David Gibson
@ 2019-09-27  5:50 ` David Gibson
  2019-09-27  5:50 ` [PATCH v2 20/33] spapr, xics, xive: Introduce SpaprInterruptController QOM interface David Gibson
                   ` (13 subsequent siblings)
  32 siblings, 0 replies; 83+ messages in thread
From: David Gibson @ 2019-09-27  5:50 UTC (permalink / raw)
  To: qemu-devel, clg, qemu-ppc
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier, Paolo Bonzini,
	Marc-André Lureau, philmd, David Gibson

This method is used to set up the interrupt backends for the current
configuration.  However, this means some confusing redirection between
the "dual" mode init and the init hooks for xics only and xive only modes.

Since we now have simple flags indicating whether XICS and/or XIVE are
supported, it's easier to just open code each initialization directly in
spapr_irq_init().  This will also make some future cleanups simpler.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
---
 hw/ppc/spapr_irq.c          | 137 +++++++++++++++++-------------------
 include/hw/ppc/spapr_irq.h  |   1 -
 include/hw/ppc/xics_spapr.h |   1 +
 3 files changed, 64 insertions(+), 75 deletions(-)

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 0aec5b0f0e..5e448b1fd4 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -92,26 +92,6 @@ static void spapr_irq_init_kvm(SpaprMachineState *spapr,
  * XICS IRQ backend.
  */
 
-static void spapr_irq_init_xics(SpaprMachineState *spapr, Error **errp)
-{
-    Object *obj;
-    Error *local_err = NULL;
-
-    obj = object_new(TYPE_ICS_SPAPR);
-    object_property_add_child(OBJECT(spapr), "ics", obj, &error_abort);
-    object_property_add_const_link(obj, ICS_PROP_XICS, OBJECT(spapr),
-                                   &error_fatal);
-    object_property_set_int(obj, spapr->irq->nr_xirqs,
-                            "nr-irqs",  &error_fatal);
-    object_property_set_bool(obj, true, "realized", &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-
-    spapr->ics = ICS_SPAPR(obj);
-}
-
 static int spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
                                 Error **errp)
 {
@@ -213,7 +193,6 @@ SpaprIrq spapr_irq_xics = {
     .xics        = true,
     .xive        = false,
 
-    .init        = spapr_irq_init_xics,
     .claim       = spapr_irq_claim_xics,
     .free        = spapr_irq_free_xics,
     .print_info  = spapr_irq_print_info_xics,
@@ -228,36 +207,6 @@ SpaprIrq spapr_irq_xics = {
 /*
  * XIVE IRQ backend.
  */
-static void spapr_irq_init_xive(SpaprMachineState *spapr, Error **errp)
-{
-    uint32_t nr_servers = spapr_max_server_number(spapr);
-    DeviceState *dev;
-    int i;
-
-    dev = qdev_create(NULL, TYPE_SPAPR_XIVE);
-    qdev_prop_set_uint32(dev, "nr-irqs",
-                         spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
-    /*
-     * 8 XIVE END structures per CPU. One for each available priority
-     */
-    qdev_prop_set_uint32(dev, "nr-ends", nr_servers << 3);
-    qdev_init_nofail(dev);
-
-    spapr->xive = SPAPR_XIVE(dev);
-
-    /* Enable the CPU IPIs */
-    for (i = 0; i < nr_servers; ++i) {
-        Error *local_err = NULL;
-
-        spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i, false, &local_err);
-        if (local_err) {
-            error_propagate(errp, local_err);
-            return;
-        }
-    }
-
-    spapr_xive_hcall_init(spapr);
-}
 
 static int spapr_irq_claim_xive(SpaprMachineState *spapr, int irq, bool lsi,
                                 Error **errp)
@@ -357,7 +306,6 @@ SpaprIrq spapr_irq_xive = {
     .xics        = false,
     .xive        = true,
 
-    .init        = spapr_irq_init_xive,
     .claim       = spapr_irq_claim_xive,
     .free        = spapr_irq_free_xive,
     .print_info  = spapr_irq_print_info_xive,
@@ -388,23 +336,6 @@ static SpaprIrq *spapr_irq_current(SpaprMachineState *spapr)
         &spapr_irq_xive : &spapr_irq_xics;
 }
 
-static void spapr_irq_init_dual(SpaprMachineState *spapr, Error **errp)
-{
-    Error *local_err = NULL;
-
-    spapr_irq_xics.init(spapr, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-
-    spapr_irq_xive.init(spapr, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-}
-
 static int spapr_irq_claim_dual(SpaprMachineState *spapr, int irq, bool lsi,
                                 Error **errp)
 {
@@ -519,7 +450,6 @@ SpaprIrq spapr_irq_dual = {
     .xics        = true,
     .xive        = true,
 
-    .init        = spapr_irq_init_dual,
     .claim       = spapr_irq_claim_dual,
     .free        = spapr_irq_free_dual,
     .print_info  = spapr_irq_print_info_dual,
@@ -607,8 +537,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
 
     spapr_irq_check(spapr, &local_err);
     if (local_err) {
-        error_propagate(errp, local_err);
-        return;
+        goto out;
     }
 
     /* Initialize the MSI IRQ allocator. */
@@ -616,10 +545,71 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
         spapr_irq_msi_init(spapr, spapr->irq->nr_msis);
     }
 
-    spapr->irq->init(spapr, errp);
+    if (spapr->irq->xics) {
+        Object *obj;
+
+        obj = object_new(TYPE_ICS_SPAPR);
+        object_property_add_child(OBJECT(spapr), "ics", obj, &local_err);
+        if (local_err) {
+            goto out;
+        }
+
+        object_property_add_const_link(obj, ICS_PROP_XICS, OBJECT(spapr),
+                                       &local_err);
+        if (local_err) {
+            goto out;
+        }
+
+        object_property_set_int(obj, spapr->irq->nr_xirqs, "nr-irqs",
+                                &local_err);
+        if (local_err) {
+            goto out;
+        }
+
+        object_property_set_bool(obj, true, "realized", &local_err);
+        if (local_err) {
+            goto out;
+        }
+
+        spapr->ics = ICS_SPAPR(obj);
+    }
+
+    if (spapr->irq->xive) {
+        uint32_t nr_servers = spapr_max_server_number(spapr);
+        DeviceState *dev;
+        int i;
+
+        dev = qdev_create(NULL, TYPE_SPAPR_XIVE);
+        qdev_prop_set_uint32(dev, "nr-irqs",
+                             spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
+        /*
+         * 8 XIVE END structures per CPU. One for each available
+         * priority
+         */
+        qdev_prop_set_uint32(dev, "nr-ends", nr_servers << 3);
+        qdev_init_nofail(dev);
+
+        spapr->xive = SPAPR_XIVE(dev);
+
+        /* Enable the CPU IPIs */
+        for (i = 0; i < nr_servers; ++i) {
+            Error *local_err = NULL;
+
+            spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i,
+                                 false, &local_err);
+            if (local_err) {
+                goto out;
+            }
+        }
+
+        spapr_xive_hcall_init(spapr);
+    }
 
     spapr->qirqs = qemu_allocate_irqs(spapr->irq->set_irq, spapr,
                                       spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
+
+out:
+    error_propagate(errp, local_err);
 }
 
 int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
@@ -763,7 +753,6 @@ SpaprIrq spapr_irq_xics_legacy = {
     .xics        = true,
     .xive        = false,
 
-    .init        = spapr_irq_init_xics,
     .claim       = spapr_irq_claim_xics,
     .free        = spapr_irq_free_xics,
     .print_info  = spapr_irq_print_info_xics,
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index d3f3b85eb9..69a37f608e 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -42,7 +42,6 @@ typedef struct SpaprIrq {
     bool        xics;
     bool        xive;
 
-    void (*init)(SpaprMachineState *spapr, Error **errp);
     int (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
     void (*free)(SpaprMachineState *spapr, int irq);
     void (*print_info)(SpaprMachineState *spapr, Monitor *mon);
diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h
index 0b35e85c26..0a32a86e3e 100644
--- a/include/hw/ppc/xics_spapr.h
+++ b/include/hw/ppc/xics_spapr.h
@@ -32,6 +32,7 @@
 #define TYPE_ICS_SPAPR "ics-spapr"
 #define ICS_SPAPR(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SPAPR)
 
+void ics_spapr_create(SpaprMachineState *spapr, int nr_xirqs, Error **errp);
 void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
                    uint32_t phandle);
 int xics_kvm_connect(SpaprMachineState *spapr, Error **errp);
-- 
2.21.0



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

* [PATCH v2 20/33] spapr, xics, xive: Introduce SpaprInterruptController QOM interface
  2019-09-27  5:49 [PATCH v2 00/33] spapr: IRQ subsystem cleanup David Gibson
                   ` (18 preceding siblings ...)
  2019-09-27  5:50 ` [PATCH v2 19/33] spapr: Eliminate SpaprIrq::init hook David Gibson
@ 2019-09-27  5:50 ` David Gibson
  2019-09-27  9:52   ` Greg Kurz
  2019-09-30  5:24   ` Cédric Le Goater
  2019-09-27  5:50 ` [PATCH v2 21/33] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController David Gibson
                   ` (12 subsequent siblings)
  32 siblings, 2 replies; 83+ messages in thread
From: David Gibson @ 2019-09-27  5:50 UTC (permalink / raw)
  To: qemu-devel, clg, qemu-ppc
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier, Paolo Bonzini,
	Marc-André Lureau, philmd, David Gibson

The SpaprIrq structure is used to represent ths spapr machine's irq
backend.  Except that it kind of conflates two concepts: one is the
backend proper - a specific interrupt controller that we might or
might not be using, the other is the irq configuration which covers
the layout of irq space and which interrupt controllers are allowed.

This leads to some pretty confusing code paths for the "dual"
configuration where its hooks redirect to other SpaprIrq structures
depending on the currently active irq controller.

To clean this up, we start by introducing a new
SpaprInterruptController QOM interface to represent strictly an
interrupt controller backend, not counting anything configuration
related.  We implement this interface in the XICs and XIVE interrupt
controllers, and in future we'll move relevant methods from SpaprIrq
into it.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/spapr_xive.c       |  4 ++++
 hw/intc/xics_spapr.c       |  4 ++++
 hw/ppc/spapr_irq.c         | 13 +++++++++++++
 include/hw/ppc/spapr_irq.h | 14 ++++++++++++++
 4 files changed, 35 insertions(+)

diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index 04879abf2e..b67e9c3245 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -519,6 +519,10 @@ static const TypeInfo spapr_xive_info = {
     .instance_init = spapr_xive_instance_init,
     .instance_size = sizeof(SpaprXive),
     .class_init = spapr_xive_class_init,
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_SPAPR_INTC },
+        { }
+    },
 };
 
 static void spapr_xive_register_types(void)
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 6e5eb24b3c..4874e6be55 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -343,6 +343,10 @@ static const TypeInfo ics_spapr_info = {
     .name = TYPE_ICS_SPAPR,
     .parent = TYPE_ICS,
     .class_init = ics_spapr_class_init,
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_SPAPR_INTC },
+        { }
+    },
 };
 
 static void xics_spapr_register_types(void)
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 5e448b1fd4..0603c82fe8 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -23,6 +23,12 @@
 
 #include "trace.h"
 
+static const TypeInfo spapr_intc_info = {
+    .name = TYPE_SPAPR_INTC,
+    .parent = TYPE_INTERFACE,
+    .class_size = sizeof(SpaprInterruptControllerClass),
+};
+
 void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis)
 {
     spapr->irq_map_nr = nr_msis;
@@ -763,3 +769,10 @@ SpaprIrq spapr_irq_xics_legacy = {
     .set_irq     = spapr_irq_set_irq_xics,
     .init_kvm    = spapr_irq_init_kvm_xics,
 };
+
+static void spapr_irq_register_types(void)
+{
+    type_register_static(&spapr_intc_info);
+}
+
+type_init(spapr_irq_register_types)
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index 69a37f608e..b9398e0be3 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -31,6 +31,20 @@
 
 typedef struct SpaprMachineState SpaprMachineState;
 
+typedef struct SpaprInterruptController SpaprInterruptController;
+
+#define TYPE_SPAPR_INTC "spapr-interrupt-controller"
+#define SPAPR_INTC(obj)                                     \
+    INTERFACE_CHECK(SpaprInterruptController, (obj), TYPE_SPAPR_INTC)
+#define SPAPR_INTC_CLASS(klass)                                     \
+    OBJECT_CLASS_CHECK(SpaprInterruptControllerClass, (klass), TYPE_SPAPR_INTC)
+#define SPAPR_INTC_GET_CLASS(obj)                                   \
+    OBJECT_GET_CLASS(SpaprInterruptControllerClass, (obj), TYPE_SPAPR_INTC)
+
+typedef struct SpaprInterruptControllerClass {
+    InterfaceClass parent;
+} SpaprInterruptControllerClass;
+
 void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis);
 int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align,
                         Error **errp);
-- 
2.21.0



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

* [PATCH v2 21/33] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController
  2019-09-27  5:49 [PATCH v2 00/33] spapr: IRQ subsystem cleanup David Gibson
                   ` (19 preceding siblings ...)
  2019-09-27  5:50 ` [PATCH v2 20/33] spapr, xics, xive: Introduce SpaprInterruptController QOM interface David Gibson
@ 2019-09-27  5:50 ` David Gibson
  2019-09-27 10:16   ` Greg Kurz
  2019-09-30  5:30   ` Cédric Le Goater
  2019-09-27  5:50 ` [PATCH v2 22/33] spapr, xics, xive: Move irq claim and free " David Gibson
                   ` (11 subsequent siblings)
  32 siblings, 2 replies; 83+ messages in thread
From: David Gibson @ 2019-09-27  5:50 UTC (permalink / raw)
  To: qemu-devel, clg, qemu-ppc
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier, Paolo Bonzini,
	Marc-André Lureau, philmd, David Gibson

This method essentially represents code which belongs to the interrupt
controller, but needs to be called on all possible intcs, rather than
just the currently active one.  The "dual" version therefore calls
into the xics and xive versions confusingly.

Handle this more directly, by making it instead a method on the intc
backend, and always calling it on every backend that exists.

While we're there, streamline the error reporting a bit.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/spapr_xive.c       | 25 ++++++++++++
 hw/intc/xics_spapr.c       | 18 +++++++++
 hw/ppc/spapr_cpu_core.c    |  3 +-
 hw/ppc/spapr_irq.c         | 81 +++++++++++---------------------------
 include/hw/ppc/spapr_irq.h | 16 +++++++-
 5 files changed, 82 insertions(+), 61 deletions(-)

diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index b67e9c3245..9338daba3d 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -495,10 +495,33 @@ static Property spapr_xive_properties[] = {
     DEFINE_PROP_END_OF_LIST(),
 };
 
+static int spapr_xive_cpu_intc_create(SpaprInterruptController *intc,
+                                      PowerPCCPU *cpu, Error **errp)
+{
+    SpaprXive *xive = SPAPR_XIVE(intc);
+    Object *obj;
+    SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
+
+    obj = xive_tctx_create(OBJECT(cpu), XIVE_ROUTER(xive), errp);
+    if (!obj) {
+        return -1;
+    }
+
+    spapr_cpu->tctx = XIVE_TCTX(obj);
+
+    /*
+     * (TCG) Early setting the OS CAM line for hotplugged CPUs as they
+     * don't beneficiate from the reset of the XIVE IRQ backend
+     */
+    spapr_xive_set_tctx_os_cam(spapr_cpu->tctx);
+    return 0;
+}
+
 static void spapr_xive_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
     XiveRouterClass *xrc = XIVE_ROUTER_CLASS(klass);
+    SpaprInterruptControllerClass *sicc = SPAPR_INTC_CLASS(klass);
 
     dc->desc    = "sPAPR XIVE Interrupt Controller";
     dc->props   = spapr_xive_properties;
@@ -511,6 +534,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;
+
+    sicc->cpu_intc_create = spapr_xive_cpu_intc_create;
 }
 
 static const TypeInfo spapr_xive_info = {
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 4874e6be55..946311b858 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -330,13 +330,31 @@ void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
     _FDT(fdt_setprop_cell(fdt, node, "phandle", phandle));
 }
 
+static int xics_spapr_cpu_intc_create(SpaprInterruptController *intc,
+                                       PowerPCCPU *cpu, Error **errp)
+{
+    ICSState *ics = ICS_SPAPR(intc);
+    Object *obj;
+    SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
+
+    obj = icp_create(OBJECT(cpu), TYPE_ICP, ics->xics, errp);
+    if (!obj) {
+        return -1;
+    }
+
+    spapr_cpu->icp = ICP(obj);
+    return 0;
+}
+
 static void ics_spapr_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
     ICSStateClass *isc = ICS_CLASS(klass);
+    SpaprInterruptControllerClass *sicc = SPAPR_INTC_CLASS(klass);
 
     device_class_set_parent_realize(dc, ics_spapr_realize,
                                     &isc->parent_realize);
+    sicc->cpu_intc_create = xics_spapr_cpu_intc_create;
 }
 
 static const TypeInfo ics_spapr_info = {
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index 1d93de8161..3e4302c7d5 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -237,8 +237,7 @@ static void spapr_realize_vcpu(PowerPCCPU *cpu, SpaprMachineState *spapr,
     qemu_register_reset(spapr_cpu_reset, cpu);
     spapr_cpu_reset(cpu);
 
-    spapr->irq->cpu_intc_create(spapr, cpu, &local_err);
-    if (local_err) {
+    if (spapr_irq_cpu_intc_create(spapr, cpu, &local_err) < 0) {
         goto error_unregister;
     }
 
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 0603c82fe8..a855dfe4e9 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -138,23 +138,6 @@ static void spapr_irq_print_info_xics(SpaprMachineState *spapr, Monitor *mon)
     ics_pic_print_info(spapr->ics, mon);
 }
 
-static void spapr_irq_cpu_intc_create_xics(SpaprMachineState *spapr,
-                                           PowerPCCPU *cpu, Error **errp)
-{
-    Error *local_err = NULL;
-    Object *obj;
-    SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
-
-    obj = icp_create(OBJECT(cpu), TYPE_ICP, XICS_FABRIC(spapr),
-                     &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-
-    spapr_cpu->icp = ICP(obj);
-}
-
 static int spapr_irq_post_load_xics(SpaprMachineState *spapr, int version_id)
 {
     if (!kvm_irqchip_in_kernel()) {
@@ -203,7 +186,6 @@ SpaprIrq spapr_irq_xics = {
     .free        = spapr_irq_free_xics,
     .print_info  = spapr_irq_print_info_xics,
     .dt_populate = spapr_dt_xics,
-    .cpu_intc_create = spapr_irq_cpu_intc_create_xics,
     .post_load   = spapr_irq_post_load_xics,
     .reset       = spapr_irq_reset_xics,
     .set_irq     = spapr_irq_set_irq_xics,
@@ -239,28 +221,6 @@ static void spapr_irq_print_info_xive(SpaprMachineState *spapr,
     spapr_xive_pic_print_info(spapr->xive, mon);
 }
 
-static void spapr_irq_cpu_intc_create_xive(SpaprMachineState *spapr,
-                                           PowerPCCPU *cpu, Error **errp)
-{
-    Error *local_err = NULL;
-    Object *obj;
-    SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
-
-    obj = xive_tctx_create(OBJECT(cpu), XIVE_ROUTER(spapr->xive), &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-
-    spapr_cpu->tctx = XIVE_TCTX(obj);
-
-    /*
-     * (TCG) Early setting the OS CAM line for hotplugged CPUs as they
-     * don't beneficiate from the reset of the XIVE IRQ backend
-     */
-    spapr_xive_set_tctx_os_cam(spapr_cpu->tctx);
-}
-
 static int spapr_irq_post_load_xive(SpaprMachineState *spapr, int version_id)
 {
     return spapr_xive_post_load(spapr->xive, version_id);
@@ -316,7 +276,6 @@ SpaprIrq spapr_irq_xive = {
     .free        = spapr_irq_free_xive,
     .print_info  = spapr_irq_print_info_xive,
     .dt_populate = spapr_dt_xive,
-    .cpu_intc_create = spapr_irq_cpu_intc_create_xive,
     .post_load   = spapr_irq_post_load_xive,
     .reset       = spapr_irq_reset_xive,
     .set_irq     = spapr_irq_set_irq_xive,
@@ -381,20 +340,6 @@ static void spapr_irq_dt_populate_dual(SpaprMachineState *spapr,
     spapr_irq_current(spapr)->dt_populate(spapr, nr_servers, fdt, phandle);
 }
 
-static void spapr_irq_cpu_intc_create_dual(SpaprMachineState *spapr,
-                                           PowerPCCPU *cpu, Error **errp)
-{
-    Error *local_err = NULL;
-
-    spapr_irq_xive.cpu_intc_create(spapr, cpu, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-
-    spapr_irq_xics.cpu_intc_create(spapr, cpu, errp);
-}
-
 static int spapr_irq_post_load_dual(SpaprMachineState *spapr, int version_id)
 {
     /*
@@ -460,7 +405,6 @@ SpaprIrq spapr_irq_dual = {
     .free        = spapr_irq_free_dual,
     .print_info  = spapr_irq_print_info_dual,
     .dt_populate = spapr_irq_dt_populate_dual,
-    .cpu_intc_create = spapr_irq_cpu_intc_create_dual,
     .post_load   = spapr_irq_post_load_dual,
     .reset       = spapr_irq_reset_dual,
     .set_irq     = spapr_irq_set_irq_dual,
@@ -525,6 +469,30 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
 /*
  * sPAPR IRQ frontend routines for devices
  */
+int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
+                              PowerPCCPU *cpu, Error **errp)
+{
+    if (spapr->xive) {
+        SpaprInterruptController *intc = SPAPR_INTC(spapr->xive);
+        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
+
+        if (sicc->cpu_intc_create(intc, cpu, errp) < 0) {
+            return -1;
+        }
+    }
+
+    if (spapr->ics) {
+        SpaprInterruptController *intc = SPAPR_INTC(spapr->ics);
+        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
+
+        if (sicc->cpu_intc_create(intc, cpu, errp) < 0) {
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
 void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
 {
     MachineState *machine = MACHINE(spapr);
@@ -763,7 +731,6 @@ SpaprIrq spapr_irq_xics_legacy = {
     .free        = spapr_irq_free_xics,
     .print_info  = spapr_irq_print_info_xics,
     .dt_populate = spapr_dt_xics,
-    .cpu_intc_create = spapr_irq_cpu_intc_create_xics,
     .post_load   = spapr_irq_post_load_xics,
     .reset       = spapr_irq_reset_xics,
     .set_irq     = spapr_irq_set_irq_xics,
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index b9398e0be3..30d660ff1e 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -43,8 +43,22 @@ typedef struct SpaprInterruptController SpaprInterruptController;
 
 typedef struct SpaprInterruptControllerClass {
     InterfaceClass parent;
+
+    /*
+     * These methods will typically be called on all intcs, active and
+     * inactive
+     */
+    int (*cpu_intc_create)(SpaprInterruptController *intc,
+                            PowerPCCPU *cpu, Error **errp);
 } SpaprInterruptControllerClass;
 
+void spapr_irq_print_info(SpaprMachineState *spapr, Monitor *mon);
+void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers,
+                  void *fdt, uint32_t phandle);
+int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
+                              PowerPCCPU *cpu, Error **errp);
+
+
 void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis);
 int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align,
                         Error **errp);
@@ -61,8 +75,6 @@ typedef struct SpaprIrq {
     void (*print_info)(SpaprMachineState *spapr, Monitor *mon);
     void (*dt_populate)(SpaprMachineState *spapr, uint32_t nr_servers,
                         void *fdt, uint32_t phandle);
-    void (*cpu_intc_create)(SpaprMachineState *spapr, PowerPCCPU *cpu,
-                            Error **errp);
     int (*post_load)(SpaprMachineState *spapr, int version_id);
     void (*reset)(SpaprMachineState *spapr, Error **errp);
     void (*set_irq)(void *opaque, int srcno, int val);
-- 
2.21.0



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

* [PATCH v2 22/33] spapr, xics, xive: Move irq claim and free from SpaprIrq to SpaprInterruptController
  2019-09-27  5:49 [PATCH v2 00/33] spapr: IRQ subsystem cleanup David Gibson
                   ` (20 preceding siblings ...)
  2019-09-27  5:50 ` [PATCH v2 21/33] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController David Gibson
@ 2019-09-27  5:50 ` David Gibson
  2019-09-27 12:16   ` Greg Kurz
  2019-09-30  5:33   ` Cédric Le Goater
  2019-09-27  5:50 ` [PATCH v2 23/33] spapr: Formalize notion of active interrupt controller David Gibson
                   ` (10 subsequent siblings)
  32 siblings, 2 replies; 83+ messages in thread
From: David Gibson @ 2019-09-27  5:50 UTC (permalink / raw)
  To: qemu-devel, clg, qemu-ppc
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier, Paolo Bonzini,
	Marc-André Lureau, philmd, David Gibson

These methods, like cpu_intc_create, really belong to the interrupt
controller, but need to be called on all possible intcs.

Like cpu_intc_create, therefore, make them methods on the intc and
always call it for all existing intcs.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/spapr_xive.c        |  71 +++++++++++-----------
 hw/intc/xics_spapr.c        |  29 +++++++++
 hw/ppc/spapr_irq.c          | 114 ++++++++++++------------------------
 include/hw/ppc/spapr_irq.h  |   5 +-
 include/hw/ppc/spapr_xive.h |   2 -
 5 files changed, 107 insertions(+), 114 deletions(-)

diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index 9338daba3d..ff1a175b44 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -487,6 +487,42 @@ static const VMStateDescription vmstate_spapr_xive = {
     },
 };
 
+static int spapr_xive_claim_irq(SpaprInterruptController *intc, int lisn,
+                                bool lsi, Error **errp)
+{
+    SpaprXive *xive = SPAPR_XIVE(intc);
+    XiveSource *xsrc = &xive->source;
+
+    assert(lisn < xive->nr_irqs);
+
+    if (xive_eas_is_valid(&xive->eat[lisn])) {
+        error_setg(errp, "IRQ %d is not free", lisn);
+        return -EBUSY;
+    }
+
+    /*
+     * Set default values when allocating an IRQ number
+     */
+    xive->eat[lisn].w |= cpu_to_be64(EAS_VALID | EAS_MASKED);
+    if (lsi) {
+        xive_source_irq_set_lsi(xsrc, lisn);
+    }
+
+    if (kvm_irqchip_in_kernel()) {
+        return kvmppc_xive_source_reset_one(xsrc, lisn, errp);
+    }
+
+    return 0;
+}
+
+static void spapr_xive_free_irq(SpaprInterruptController *intc, int lisn)
+{
+    SpaprXive *xive = SPAPR_XIVE(intc);
+    assert(lisn < xive->nr_irqs);
+
+    xive->eat[lisn].w &= cpu_to_be64(~EAS_VALID);
+}
+
 static Property spapr_xive_properties[] = {
     DEFINE_PROP_UINT32("nr-irqs", SpaprXive, nr_irqs, 0),
     DEFINE_PROP_UINT32("nr-ends", SpaprXive, nr_ends, 0),
@@ -536,6 +572,8 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data)
     xrc->get_tctx = spapr_xive_get_tctx;
 
     sicc->cpu_intc_create = spapr_xive_cpu_intc_create;
+    sicc->claim_irq = spapr_xive_claim_irq;
+    sicc->free_irq = spapr_xive_free_irq;
 }
 
 static const TypeInfo spapr_xive_info = {
@@ -557,39 +595,6 @@ static void spapr_xive_register_types(void)
 
 type_init(spapr_xive_register_types)
 
-int spapr_xive_irq_claim(SpaprXive *xive, int lisn, bool lsi, Error **errp)
-{
-    XiveSource *xsrc = &xive->source;
-
-    assert(lisn < xive->nr_irqs);
-
-    if (xive_eas_is_valid(&xive->eat[lisn])) {
-        error_setg(errp, "IRQ %d is not free", lisn);
-        return -EBUSY;
-    }
-
-    /*
-     * Set default values when allocating an IRQ number
-     */
-    xive->eat[lisn].w |= cpu_to_be64(EAS_VALID | EAS_MASKED);
-    if (lsi) {
-        xive_source_irq_set_lsi(xsrc, lisn);
-    }
-
-    if (kvm_irqchip_in_kernel()) {
-        return kvmppc_xive_source_reset_one(xsrc, lisn, errp);
-    }
-
-    return 0;
-}
-
-void spapr_xive_irq_free(SpaprXive *xive, int lisn)
-{
-    assert(lisn < xive->nr_irqs);
-
-    xive->eat[lisn].w &= cpu_to_be64(~EAS_VALID);
-}
-
 /*
  * XIVE hcalls
  *
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 946311b858..224fe1efcd 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -346,6 +346,33 @@ static int xics_spapr_cpu_intc_create(SpaprInterruptController *intc,
     return 0;
 }
 
+static int xics_spapr_claim_irq(SpaprInterruptController *intc, int irq,
+                                bool lsi, Error **errp)
+{
+    ICSState *ics = ICS_SPAPR(intc);
+
+    assert(ics);
+    assert(ics_valid_irq(ics, irq));
+
+    if (!ics_irq_free(ics, irq - ics->offset)) {
+        error_setg(errp, "IRQ %d is not free", irq);
+        return -EBUSY;
+    }
+
+    ics_set_irq_type(ics, irq - ics->offset, lsi);
+    return 0;
+}
+
+static void xics_spapr_free_irq(SpaprInterruptController *intc, int irq)
+{
+    ICSState *ics = ICS_SPAPR(intc);
+    uint32_t srcno = irq - ics->offset;
+
+    assert(ics_valid_irq(ics, irq));
+
+    memset(&ics->irqs[srcno], 0, sizeof(ICSIRQState));
+}
+
 static void ics_spapr_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -355,6 +382,8 @@ static void ics_spapr_class_init(ObjectClass *klass, void *data)
     device_class_set_parent_realize(dc, ics_spapr_realize,
                                     &isc->parent_realize);
     sicc->cpu_intc_create = xics_spapr_cpu_intc_create;
+    sicc->claim_irq = xics_spapr_claim_irq;
+    sicc->free_irq = xics_spapr_free_irq;
 }
 
 static const TypeInfo ics_spapr_info = {
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index a855dfe4e9..ea44378d8c 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -98,33 +98,6 @@ static void spapr_irq_init_kvm(SpaprMachineState *spapr,
  * XICS IRQ backend.
  */
 
-static int spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
-                                Error **errp)
-{
-    ICSState *ics = spapr->ics;
-
-    assert(ics);
-    assert(ics_valid_irq(ics, irq));
-
-    if (!ics_irq_free(ics, irq - ics->offset)) {
-        error_setg(errp, "IRQ %d is not free", irq);
-        return -1;
-    }
-
-    ics_set_irq_type(ics, irq - ics->offset, lsi);
-    return 0;
-}
-
-static void spapr_irq_free_xics(SpaprMachineState *spapr, int irq)
-{
-    ICSState *ics = spapr->ics;
-    uint32_t srcno = irq - ics->offset;
-
-    assert(ics_valid_irq(ics, irq));
-
-    memset(&ics->irqs[srcno], 0, sizeof(ICSIRQState));
-}
-
 static void spapr_irq_print_info_xics(SpaprMachineState *spapr, Monitor *mon)
 {
     CPUState *cs;
@@ -182,8 +155,6 @@ SpaprIrq spapr_irq_xics = {
     .xics        = true,
     .xive        = false,
 
-    .claim       = spapr_irq_claim_xics,
-    .free        = spapr_irq_free_xics,
     .print_info  = spapr_irq_print_info_xics,
     .dt_populate = spapr_dt_xics,
     .post_load   = spapr_irq_post_load_xics,
@@ -196,17 +167,6 @@ SpaprIrq spapr_irq_xics = {
  * XIVE IRQ backend.
  */
 
-static int spapr_irq_claim_xive(SpaprMachineState *spapr, int irq, bool lsi,
-                                Error **errp)
-{
-    return spapr_xive_irq_claim(spapr->xive, irq, lsi, errp);
-}
-
-static void spapr_irq_free_xive(SpaprMachineState *spapr, int irq)
-{
-    spapr_xive_irq_free(spapr->xive, irq);
-}
-
 static void spapr_irq_print_info_xive(SpaprMachineState *spapr,
                                       Monitor *mon)
 {
@@ -272,8 +232,6 @@ SpaprIrq spapr_irq_xive = {
     .xics        = false,
     .xive        = true,
 
-    .claim       = spapr_irq_claim_xive,
-    .free        = spapr_irq_free_xive,
     .print_info  = spapr_irq_print_info_xive,
     .dt_populate = spapr_dt_xive,
     .post_load   = spapr_irq_post_load_xive,
@@ -301,33 +259,6 @@ static SpaprIrq *spapr_irq_current(SpaprMachineState *spapr)
         &spapr_irq_xive : &spapr_irq_xics;
 }
 
-static int spapr_irq_claim_dual(SpaprMachineState *spapr, int irq, bool lsi,
-                                Error **errp)
-{
-    Error *local_err = NULL;
-    int ret;
-
-    ret = spapr_irq_xics.claim(spapr, irq, lsi, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return ret;
-    }
-
-    ret = spapr_irq_xive.claim(spapr, irq, lsi, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return ret;
-    }
-
-    return ret;
-}
-
-static void spapr_irq_free_dual(SpaprMachineState *spapr, int irq)
-{
-    spapr_irq_xics.free(spapr, irq);
-    spapr_irq_xive.free(spapr, irq);
-}
-
 static void spapr_irq_print_info_dual(SpaprMachineState *spapr, Monitor *mon)
 {
     spapr_irq_current(spapr)->print_info(spapr, mon);
@@ -401,8 +332,6 @@ SpaprIrq spapr_irq_dual = {
     .xics        = true,
     .xive        = true,
 
-    .claim       = spapr_irq_claim_dual,
-    .free        = spapr_irq_free_dual,
     .print_info  = spapr_irq_print_info_dual,
     .dt_populate = spapr_irq_dt_populate_dual,
     .post_load   = spapr_irq_post_load_dual,
@@ -567,10 +496,12 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
 
         /* Enable the CPU IPIs */
         for (i = 0; i < nr_servers; ++i) {
+            SpaprInterruptControllerClass *sicc
+                = SPAPR_INTC_GET_CLASS(spapr->xive);
             Error *local_err = NULL;
 
-            spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i,
-                                 false, &local_err);
+            sicc->claim_irq(SPAPR_INTC(spapr->xive), SPAPR_IRQ_IPI + i,
+                            false, &local_err);
             if (local_err) {
                 goto out;
             }
@@ -588,10 +519,30 @@ out:
 
 int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
 {
+    int rc;
+
     assert(irq >= SPAPR_XIRQ_BASE);
     assert(irq < (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
 
-    return spapr->irq->claim(spapr, irq, lsi, errp);
+    if (spapr->xive) {
+        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(spapr->xive);
+
+        rc = sicc->claim_irq(SPAPR_INTC(spapr->xive), irq, lsi, errp);
+        if (rc < 0) {
+            return rc;
+        }
+    }
+
+    if (spapr->ics) {
+        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(spapr->ics);
+
+        rc = sicc->claim_irq(SPAPR_INTC(spapr->ics), irq, lsi, errp);
+        if (rc < 0) {
+            return rc;
+        }
+    }
+
+    return 0;
 }
 
 void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
@@ -602,7 +553,18 @@ void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
     assert((irq + num) <= (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
 
     for (i = irq; i < (irq + num); i++) {
-        spapr->irq->free(spapr, irq);
+        if (spapr->xive) {
+            SpaprInterruptController *intc = SPAPR_INTC(spapr->xive);
+            SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
+
+            sicc->free_irq(intc, irq);
+        }
+        if (spapr->ics) {
+            SpaprInterruptController *intc = SPAPR_INTC(spapr->ics);
+            SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
+
+            sicc->free_irq(intc, irq);
+        }
     }
 }
 
@@ -727,8 +689,6 @@ SpaprIrq spapr_irq_xics_legacy = {
     .xics        = true,
     .xive        = false,
 
-    .claim       = spapr_irq_claim_xics,
-    .free        = spapr_irq_free_xics,
     .print_info  = spapr_irq_print_info_xics,
     .dt_populate = spapr_dt_xics,
     .post_load   = spapr_irq_post_load_xics,
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index 30d660ff1e..616086f9bb 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -50,6 +50,9 @@ typedef struct SpaprInterruptControllerClass {
      */
     int (*cpu_intc_create)(SpaprInterruptController *intc,
                             PowerPCCPU *cpu, Error **errp);
+    int (*claim_irq)(SpaprInterruptController *intc, int irq, bool lsi,
+                     Error **errp);
+    void (*free_irq)(SpaprInterruptController *intc, int irq);
 } SpaprInterruptControllerClass;
 
 void spapr_irq_print_info(SpaprMachineState *spapr, Monitor *mon);
@@ -70,8 +73,6 @@ typedef struct SpaprIrq {
     bool        xics;
     bool        xive;
 
-    int (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
-    void (*free)(SpaprMachineState *spapr, int irq);
     void (*print_info)(SpaprMachineState *spapr, Monitor *mon);
     void (*dt_populate)(SpaprMachineState *spapr, uint32_t nr_servers,
                         void *fdt, uint32_t phandle);
diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h
index 0df20a6590..8f875673f5 100644
--- a/include/hw/ppc/spapr_xive.h
+++ b/include/hw/ppc/spapr_xive.h
@@ -54,8 +54,6 @@ typedef struct SpaprXive {
  */
 #define SPAPR_XIVE_BLOCK_ID 0x0
 
-int spapr_xive_irq_claim(SpaprXive *xive, int lisn, bool lsi, Error **errp);
-void spapr_xive_irq_free(SpaprXive *xive, int lisn);
 void spapr_xive_pic_print_info(SpaprXive *xive, Monitor *mon);
 int spapr_xive_post_load(SpaprXive *xive, int version_id);
 
-- 
2.21.0



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

* [PATCH v2 23/33] spapr: Formalize notion of active interrupt controller
  2019-09-27  5:49 [PATCH v2 00/33] spapr: IRQ subsystem cleanup David Gibson
                   ` (21 preceding siblings ...)
  2019-09-27  5:50 ` [PATCH v2 22/33] spapr, xics, xive: Move irq claim and free " David Gibson
@ 2019-09-27  5:50 ` David Gibson
  2019-09-27 14:16   ` Greg Kurz
  2019-09-30  5:39   ` Cédric Le Goater
  2019-09-27  5:50 ` [PATCH v2 24/33] spapr, xics, xive: Move set_irq from SpaprIrq to SpaprInterruptController David Gibson
                   ` (9 subsequent siblings)
  32 siblings, 2 replies; 83+ messages in thread
From: David Gibson @ 2019-09-27  5:50 UTC (permalink / raw)
  To: qemu-devel, clg, qemu-ppc
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier, Paolo Bonzini,
	Marc-André Lureau, philmd, David Gibson

spapr now has the mechanism of constructing both XICS and XIVE instances of
the SpaprInterruptController interface.  However, only one of the interrupt
controllers will actually be active at any given time, depending on feature
negotiation with the guest.  This is handled in the current code via
spapr_irq_current() which checks the OV5 vector from feature negotiation to
determine the current backend.

Determining the active controller at the point we need it like this
can be pretty confusing, because it makes it very non obvious at what
points the active controller can change.  This can make it difficult
to reason about the code and where a change of active controller could
appear in sequence with other events.

Make this mechanism more explicit by adding an 'active_intc' pointer
and an explicit spapr_irq_update_active_intc() function to update it
from the CAS state.  We also add hooks on the intc backend which will
get called when it is activated or deactivated.

For now we just introduce the switch and hooks, later patches will
actually start using them.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr_irq.c         | 51 ++++++++++++++++++++++++++++++++++++++
 include/hw/ppc/spapr.h     |  5 ++--
 include/hw/ppc/spapr_irq.h |  5 ++++
 3 files changed, 59 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index ea44378d8c..dfa875b7cd 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -593,6 +593,7 @@ qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq)
 
 int spapr_irq_post_load(SpaprMachineState *spapr, int version_id)
 {
+    spapr_irq_update_active_intc(spapr);
     return spapr->irq->post_load(spapr, version_id);
 }
 
@@ -600,6 +601,8 @@ void spapr_irq_reset(SpaprMachineState *spapr, Error **errp)
 {
     assert(!spapr->irq_map || bitmap_empty(spapr->irq_map, spapr->irq_map_nr));
 
+    spapr_irq_update_active_intc(spapr);
+
     if (spapr->irq->reset) {
         spapr->irq->reset(spapr, errp);
     }
@@ -626,6 +629,54 @@ int spapr_irq_get_phandle(SpaprMachineState *spapr, void *fdt, Error **errp)
     return phandle;
 }
 
+static void set_active_intc(SpaprMachineState *spapr,
+                            SpaprInterruptController *new_intc)
+{
+    SpaprInterruptControllerClass *sicc;
+
+    assert(new_intc);
+
+    if (new_intc == spapr->active_intc) {
+        /* Nothing to do */
+        return;
+    }
+
+    if (spapr->active_intc) {
+        sicc = SPAPR_INTC_GET_CLASS(spapr->active_intc);
+        if (sicc->deactivate) {
+            sicc->deactivate(spapr->active_intc);
+        }
+    }
+
+    sicc = SPAPR_INTC_GET_CLASS(new_intc);
+    if (sicc->activate) {
+        sicc->activate(new_intc, &error_fatal);
+    }
+
+    spapr->active_intc = new_intc;
+}
+
+void spapr_irq_update_active_intc(SpaprMachineState *spapr)
+{
+    SpaprInterruptController *new_intc;
+
+    if (!spapr->ics) {
+        /*
+         * XXX before we run CAS, ov5_cas is initialized empty, which
+         * indicates XICS, even if we have ic-mode=xive.  TODO: clean
+         * up the CAS path so that we have a clearer way of handling
+         * this.
+         */
+        new_intc = SPAPR_INTC(spapr->xive);
+    } else if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
+        new_intc = SPAPR_INTC(spapr->xive);
+    } else {
+        new_intc = SPAPR_INTC(spapr->ics);
+    }
+
+    set_active_intc(spapr, new_intc);
+}
+
 /*
  * XICS legacy routines - to deprecate one day
  */
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index cbd1a4c9f3..763da757f0 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -143,7 +143,6 @@ struct SpaprMachineState {
     struct SpaprVioBus *vio_bus;
     QLIST_HEAD(, SpaprPhbState) phbs;
     struct SpaprNvram *nvram;
-    ICSState *ics;
     SpaprRtcState rtc;
 
     SpaprResizeHpt resize_hpt;
@@ -195,9 +194,11 @@ struct SpaprMachineState {
 
     int32_t irq_map_nr;
     unsigned long *irq_map;
-    SpaprXive  *xive;
     SpaprIrq *irq;
     qemu_irq *qirqs;
+    SpaprInterruptController *active_intc;
+    ICSState *ics;
+    SpaprXive *xive;
 
     bool cmd_line_caps[SPAPR_CAP_NUM];
     SpaprCapabilities def, eff, mig;
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index 616086f9bb..3102d152b2 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -44,6 +44,9 @@ typedef struct SpaprInterruptController SpaprInterruptController;
 typedef struct SpaprInterruptControllerClass {
     InterfaceClass parent;
 
+    void (*activate)(SpaprInterruptController *intc, Error **errp);
+    void (*deactivate)(SpaprInterruptController *intc);
+
     /*
      * These methods will typically be called on all intcs, active and
      * inactive
@@ -55,6 +58,8 @@ typedef struct SpaprInterruptControllerClass {
     void (*free_irq)(SpaprInterruptController *intc, int irq);
 } SpaprInterruptControllerClass;
 
+void spapr_irq_update_active_intc(SpaprMachineState *spapr);
+
 void spapr_irq_print_info(SpaprMachineState *spapr, Monitor *mon);
 void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers,
                   void *fdt, uint32_t phandle);
-- 
2.21.0



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

* [PATCH v2 24/33] spapr, xics, xive: Move set_irq from SpaprIrq to SpaprInterruptController
  2019-09-27  5:49 [PATCH v2 00/33] spapr: IRQ subsystem cleanup David Gibson
                   ` (22 preceding siblings ...)
  2019-09-27  5:50 ` [PATCH v2 23/33] spapr: Formalize notion of active interrupt controller David Gibson
@ 2019-09-27  5:50 ` David Gibson
  2019-09-27 14:27   ` Greg Kurz
  2019-09-30  5:48   ` Cédric Le Goater
  2019-09-27  5:50 ` [PATCH v2 25/33] spapr, xics, xive: Move print_info " David Gibson
                   ` (8 subsequent siblings)
  32 siblings, 2 replies; 83+ messages in thread
From: David Gibson @ 2019-09-27  5:50 UTC (permalink / raw)
  To: qemu-devel, clg, qemu-ppc
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier, Paolo Bonzini,
	Marc-André Lureau, philmd, David Gibson

This method depends only on the active irq controller.  Now that we've
formalized the notion of active controller we can dispatch directly through
that, rather than dispatching via SpaprIrq with the dual version having
to do a second conditional dispatch.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/spapr_xive.c       | 12 +++++++++++
 hw/intc/xics_spapr.c       |  9 +++++++++
 hw/ppc/spapr_irq.c         | 41 ++++++++++----------------------------
 include/hw/ppc/spapr_irq.h |  4 +++-
 4 files changed, 34 insertions(+), 32 deletions(-)

diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index ff1a175b44..52d5e71793 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -553,6 +553,17 @@ static int spapr_xive_cpu_intc_create(SpaprInterruptController *intc,
     return 0;
 }
 
+static void spapr_xive_set_irq(SpaprInterruptController *intc, int irq, int val)
+{
+    SpaprXive *xive = SPAPR_XIVE(intc);
+
+    if (kvm_irqchip_in_kernel()) {
+        kvmppc_xive_source_set_irq(&xive->source, irq, val);
+    } else {
+        xive_source_set_irq(&xive->source, irq, val);
+    }
+}
+
 static void spapr_xive_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -574,6 +585,7 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data)
     sicc->cpu_intc_create = spapr_xive_cpu_intc_create;
     sicc->claim_irq = spapr_xive_claim_irq;
     sicc->free_irq = spapr_xive_free_irq;
+    sicc->set_irq = spapr_xive_set_irq;
 }
 
 static const TypeInfo spapr_xive_info = {
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 224fe1efcd..02372697f6 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -373,6 +373,14 @@ static void xics_spapr_free_irq(SpaprInterruptController *intc, int irq)
     memset(&ics->irqs[srcno], 0, sizeof(ICSIRQState));
 }
 
+static void xics_spapr_set_irq(SpaprInterruptController *intc, int irq, int val)
+{
+    ICSState *ics = ICS_SPAPR(intc);
+    uint32_t srcno = irq - ics->offset;
+
+    ics_set_irq(ics, srcno, val);
+}
+
 static void ics_spapr_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -384,6 +392,7 @@ static void ics_spapr_class_init(ObjectClass *klass, void *data)
     sicc->cpu_intc_create = xics_spapr_cpu_intc_create;
     sicc->claim_irq = xics_spapr_claim_irq;
     sicc->free_irq = xics_spapr_free_irq;
+    sicc->set_irq = xics_spapr_set_irq;
 }
 
 static const TypeInfo ics_spapr_info = {
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index dfa875b7cd..4922062908 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -123,14 +123,6 @@ static int spapr_irq_post_load_xics(SpaprMachineState *spapr, int version_id)
     return 0;
 }
 
-static void spapr_irq_set_irq_xics(void *opaque, int irq, int val)
-{
-    SpaprMachineState *spapr = opaque;
-    uint32_t srcno = irq - spapr->ics->offset;
-
-    ics_set_irq(spapr->ics, srcno, val);
-}
-
 static void spapr_irq_reset_xics(SpaprMachineState *spapr, Error **errp)
 {
     Error *local_err = NULL;
@@ -159,7 +151,6 @@ SpaprIrq spapr_irq_xics = {
     .dt_populate = spapr_dt_xics,
     .post_load   = spapr_irq_post_load_xics,
     .reset       = spapr_irq_reset_xics,
-    .set_irq     = spapr_irq_set_irq_xics,
     .init_kvm    = spapr_irq_init_kvm_xics,
 };
 
@@ -208,17 +199,6 @@ static void spapr_irq_reset_xive(SpaprMachineState *spapr, Error **errp)
     spapr_xive_mmio_set_enabled(spapr->xive, true);
 }
 
-static void spapr_irq_set_irq_xive(void *opaque, int irq, int val)
-{
-    SpaprMachineState *spapr = opaque;
-
-    if (kvm_irqchip_in_kernel()) {
-        kvmppc_xive_source_set_irq(&spapr->xive->source, irq, val);
-    } else {
-        xive_source_set_irq(&spapr->xive->source, irq, val);
-    }
-}
-
 static void spapr_irq_init_kvm_xive(SpaprMachineState *spapr, Error **errp)
 {
     if (kvm_enabled()) {
@@ -236,7 +216,6 @@ SpaprIrq spapr_irq_xive = {
     .dt_populate = spapr_dt_xive,
     .post_load   = spapr_irq_post_load_xive,
     .reset       = spapr_irq_reset_xive,
-    .set_irq     = spapr_irq_set_irq_xive,
     .init_kvm    = spapr_irq_init_kvm_xive,
 };
 
@@ -316,13 +295,6 @@ static void spapr_irq_reset_dual(SpaprMachineState *spapr, Error **errp)
     spapr_irq_current(spapr)->reset(spapr, errp);
 }
 
-static void spapr_irq_set_irq_dual(void *opaque, int irq, int val)
-{
-    SpaprMachineState *spapr = opaque;
-
-    spapr_irq_current(spapr)->set_irq(spapr, irq, val);
-}
-
 /*
  * Define values in sync with the XIVE and XICS backend
  */
@@ -336,7 +308,6 @@ SpaprIrq spapr_irq_dual = {
     .dt_populate = spapr_irq_dt_populate_dual,
     .post_load   = spapr_irq_post_load_dual,
     .reset       = spapr_irq_reset_dual,
-    .set_irq     = spapr_irq_set_irq_dual,
     .init_kvm    = NULL, /* should not be used */
 };
 
@@ -422,6 +393,15 @@ int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
     return 0;
 }
 
+static void spapr_set_irq(void *opaque, int irq, int level)
+{
+    SpaprMachineState *spapr = SPAPR_MACHINE(opaque);
+    SpaprInterruptControllerClass *sicc
+        = SPAPR_INTC_GET_CLASS(spapr->active_intc);
+
+    sicc->set_irq(spapr->active_intc, irq, level);
+}
+
 void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
 {
     MachineState *machine = MACHINE(spapr);
@@ -510,7 +490,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
         spapr_xive_hcall_init(spapr);
     }
 
-    spapr->qirqs = qemu_allocate_irqs(spapr->irq->set_irq, spapr,
+    spapr->qirqs = qemu_allocate_irqs(spapr_set_irq, spapr,
                                       spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
 
 out:
@@ -744,7 +724,6 @@ SpaprIrq spapr_irq_xics_legacy = {
     .dt_populate = spapr_dt_xics,
     .post_load   = spapr_irq_post_load_xics,
     .reset       = spapr_irq_reset_xics,
-    .set_irq     = spapr_irq_set_irq_xics,
     .init_kvm    = spapr_irq_init_kvm_xics,
 };
 
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index 3102d152b2..8286a9aa63 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -56,6 +56,9 @@ typedef struct SpaprInterruptControllerClass {
     int (*claim_irq)(SpaprInterruptController *intc, int irq, bool lsi,
                      Error **errp);
     void (*free_irq)(SpaprInterruptController *intc, int irq);
+
+    /* These methods should only be called on the active intc */
+    void (*set_irq)(SpaprInterruptController *intc, int irq, int val);
 } SpaprInterruptControllerClass;
 
 void spapr_irq_update_active_intc(SpaprMachineState *spapr);
@@ -83,7 +86,6 @@ typedef struct SpaprIrq {
                         void *fdt, uint32_t phandle);
     int (*post_load)(SpaprMachineState *spapr, int version_id);
     void (*reset)(SpaprMachineState *spapr, Error **errp);
-    void (*set_irq)(void *opaque, int srcno, int val);
     void (*init_kvm)(SpaprMachineState *spapr, Error **errp);
 } SpaprIrq;
 
-- 
2.21.0



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

* [PATCH v2 25/33] spapr, xics, xive: Move print_info from SpaprIrq to SpaprInterruptController
  2019-09-27  5:49 [PATCH v2 00/33] spapr: IRQ subsystem cleanup David Gibson
                   ` (23 preceding siblings ...)
  2019-09-27  5:50 ` [PATCH v2 24/33] spapr, xics, xive: Move set_irq from SpaprIrq to SpaprInterruptController David Gibson
@ 2019-09-27  5:50 ` David Gibson
  2019-09-27 14:31   ` Greg Kurz
  2019-09-27  5:50 ` [PATCH v2 26/33] spapr, xics, xive: Move dt_populate " David Gibson
                   ` (7 subsequent siblings)
  32 siblings, 1 reply; 83+ messages in thread
From: David Gibson @ 2019-09-27  5:50 UTC (permalink / raw)
  To: qemu-devel, clg, qemu-ppc
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier, Paolo Bonzini,
	Marc-André Lureau, philmd, David Gibson

This method depends only on the active irq controller.  Now that we've
formalized the notion of active controller we can dispatch directly
through that, rather than dispatching via SpaprIrq with the dual
version having to do a second conditional dispatch.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/spapr_xive.c       | 15 +++++++++++++
 hw/intc/xics_spapr.c       | 15 +++++++++++++
 hw/ppc/spapr.c             |  2 +-
 hw/ppc/spapr_irq.c         | 44 +++++++-------------------------------
 include/hw/ppc/spapr_irq.h |  2 +-
 5 files changed, 40 insertions(+), 38 deletions(-)

diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index 52d5e71793..700ec5c9c1 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -564,6 +564,20 @@ static void spapr_xive_set_irq(SpaprInterruptController *intc, int irq, int val)
     }
 }
 
+static void spapr_xive_print_info(SpaprInterruptController *intc, Monitor *mon)
+{
+    SpaprXive *xive = SPAPR_XIVE(intc);
+    CPUState *cs;
+
+    CPU_FOREACH(cs) {
+        PowerPCCPU *cpu = POWERPC_CPU(cs);
+
+        xive_tctx_pic_print_info(spapr_cpu_state(cpu)->tctx, mon);
+    }
+
+    spapr_xive_pic_print_info(xive, mon);
+}
+
 static void spapr_xive_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -586,6 +600,7 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data)
     sicc->claim_irq = spapr_xive_claim_irq;
     sicc->free_irq = spapr_xive_free_irq;
     sicc->set_irq = spapr_xive_set_irq;
+    sicc->print_info = spapr_xive_print_info;
 }
 
 static const TypeInfo spapr_xive_info = {
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 02372697f6..415defe394 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -381,6 +381,20 @@ static void xics_spapr_set_irq(SpaprInterruptController *intc, int irq, int val)
     ics_set_irq(ics, srcno, val);
 }
 
+static void xics_spapr_print_info(SpaprInterruptController *intc, Monitor *mon)
+{
+    ICSState *ics = ICS_SPAPR(intc);
+    CPUState *cs;
+
+    CPU_FOREACH(cs) {
+        PowerPCCPU *cpu = POWERPC_CPU(cs);
+
+        icp_pic_print_info(spapr_cpu_state(cpu)->icp, mon);
+    }
+
+    ics_pic_print_info(ics, mon);
+}
+
 static void ics_spapr_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -393,6 +407,7 @@ static void ics_spapr_class_init(ObjectClass *klass, void *data)
     sicc->claim_irq = xics_spapr_claim_irq;
     sicc->free_irq = xics_spapr_free_irq;
     sicc->set_irq = xics_spapr_set_irq;
+    sicc->print_info = xics_spapr_print_info;
 }
 
 static const TypeInfo ics_spapr_info = {
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 795f6ab505..7e04746db1 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -4341,7 +4341,7 @@ static void spapr_pic_print_info(InterruptStatsProvider *obj,
 {
     SpaprMachineState *spapr = SPAPR_MACHINE(obj);
 
-    spapr->irq->print_info(spapr, mon);
+    spapr_irq_print_info(spapr, mon);
     monitor_printf(mon, "irqchip: %s\n",
                    kvm_irqchip_in_kernel() ? "in-kernel" : "emulated");
 }
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 4922062908..be20bbf3cf 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -98,19 +98,6 @@ static void spapr_irq_init_kvm(SpaprMachineState *spapr,
  * XICS IRQ backend.
  */
 
-static void spapr_irq_print_info_xics(SpaprMachineState *spapr, Monitor *mon)
-{
-    CPUState *cs;
-
-    CPU_FOREACH(cs) {
-        PowerPCCPU *cpu = POWERPC_CPU(cs);
-
-        icp_pic_print_info(spapr_cpu_state(cpu)->icp, mon);
-    }
-
-    ics_pic_print_info(spapr->ics, mon);
-}
-
 static int spapr_irq_post_load_xics(SpaprMachineState *spapr, int version_id)
 {
     if (!kvm_irqchip_in_kernel()) {
@@ -147,7 +134,6 @@ SpaprIrq spapr_irq_xics = {
     .xics        = true,
     .xive        = false,
 
-    .print_info  = spapr_irq_print_info_xics,
     .dt_populate = spapr_dt_xics,
     .post_load   = spapr_irq_post_load_xics,
     .reset       = spapr_irq_reset_xics,
@@ -158,20 +144,6 @@ SpaprIrq spapr_irq_xics = {
  * XIVE IRQ backend.
  */
 
-static void spapr_irq_print_info_xive(SpaprMachineState *spapr,
-                                      Monitor *mon)
-{
-    CPUState *cs;
-
-    CPU_FOREACH(cs) {
-        PowerPCCPU *cpu = POWERPC_CPU(cs);
-
-        xive_tctx_pic_print_info(spapr_cpu_state(cpu)->tctx, mon);
-    }
-
-    spapr_xive_pic_print_info(spapr->xive, mon);
-}
-
 static int spapr_irq_post_load_xive(SpaprMachineState *spapr, int version_id)
 {
     return spapr_xive_post_load(spapr->xive, version_id);
@@ -212,7 +184,6 @@ SpaprIrq spapr_irq_xive = {
     .xics        = false,
     .xive        = true,
 
-    .print_info  = spapr_irq_print_info_xive,
     .dt_populate = spapr_dt_xive,
     .post_load   = spapr_irq_post_load_xive,
     .reset       = spapr_irq_reset_xive,
@@ -238,11 +209,6 @@ static SpaprIrq *spapr_irq_current(SpaprMachineState *spapr)
         &spapr_irq_xive : &spapr_irq_xics;
 }
 
-static void spapr_irq_print_info_dual(SpaprMachineState *spapr, Monitor *mon)
-{
-    spapr_irq_current(spapr)->print_info(spapr, mon);
-}
-
 static void spapr_irq_dt_populate_dual(SpaprMachineState *spapr,
                                        uint32_t nr_servers, void *fdt,
                                        uint32_t phandle)
@@ -304,7 +270,6 @@ SpaprIrq spapr_irq_dual = {
     .xics        = true,
     .xive        = true,
 
-    .print_info  = spapr_irq_print_info_dual,
     .dt_populate = spapr_irq_dt_populate_dual,
     .post_load   = spapr_irq_post_load_dual,
     .reset       = spapr_irq_reset_dual,
@@ -402,6 +367,14 @@ static void spapr_set_irq(void *opaque, int irq, int level)
     sicc->set_irq(spapr->active_intc, irq, level);
 }
 
+void spapr_irq_print_info(SpaprMachineState *spapr, Monitor *mon)
+{
+    SpaprInterruptControllerClass *sicc
+        = SPAPR_INTC_GET_CLASS(spapr->active_intc);
+
+    sicc->print_info(spapr->active_intc, mon);
+}
+
 void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
 {
     MachineState *machine = MACHINE(spapr);
@@ -720,7 +693,6 @@ SpaprIrq spapr_irq_xics_legacy = {
     .xics        = true,
     .xive        = false,
 
-    .print_info  = spapr_irq_print_info_xics,
     .dt_populate = spapr_dt_xics,
     .post_load   = spapr_irq_post_load_xics,
     .reset       = spapr_irq_reset_xics,
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index 8286a9aa63..2ade580992 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -59,6 +59,7 @@ typedef struct SpaprInterruptControllerClass {
 
     /* These methods should only be called on the active intc */
     void (*set_irq)(SpaprInterruptController *intc, int irq, int val);
+    void (*print_info)(SpaprInterruptController *intc, Monitor *mon);
 } SpaprInterruptControllerClass;
 
 void spapr_irq_update_active_intc(SpaprMachineState *spapr);
@@ -81,7 +82,6 @@ typedef struct SpaprIrq {
     bool        xics;
     bool        xive;
 
-    void (*print_info)(SpaprMachineState *spapr, Monitor *mon);
     void (*dt_populate)(SpaprMachineState *spapr, uint32_t nr_servers,
                         void *fdt, uint32_t phandle);
     int (*post_load)(SpaprMachineState *spapr, int version_id);
-- 
2.21.0



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

* [PATCH v2 26/33] spapr, xics, xive: Move dt_populate from SpaprIrq to SpaprInterruptController
  2019-09-27  5:49 [PATCH v2 00/33] spapr: IRQ subsystem cleanup David Gibson
                   ` (24 preceding siblings ...)
  2019-09-27  5:50 ` [PATCH v2 25/33] spapr, xics, xive: Move print_info " David Gibson
@ 2019-09-27  5:50 ` David Gibson
  2019-09-27 14:38   ` Greg Kurz
  2019-09-30  5:51   ` Cédric Le Goater
  2019-09-27  5:50 ` [PATCH v2 27/33] spapr, xics, xive: Match signatures for XICS and XIVE KVM connect routines David Gibson
                   ` (6 subsequent siblings)
  32 siblings, 2 replies; 83+ messages in thread
From: David Gibson @ 2019-09-27  5:50 UTC (permalink / raw)
  To: qemu-devel, clg, qemu-ppc
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier, Paolo Bonzini,
	Marc-André Lureau, philmd, David Gibson

This method depends only on the active irq controller.  Now that we've
formalized the notion of active controller we can dispatch directly
through that, rather than dispatching via SpaprIrq with the dual
version having to do a second conditional dispatch.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/spapr_xive.c        | 125 ++++++++++++++++++------------------
 hw/intc/xics_spapr.c        |   5 +-
 hw/ppc/spapr.c              |   3 +-
 hw/ppc/spapr_irq.c          |  20 +++---
 include/hw/ppc/spapr_irq.h  |   5 +-
 include/hw/ppc/spapr_xive.h |   2 -
 include/hw/ppc/xics_spapr.h |   2 -
 7 files changed, 78 insertions(+), 84 deletions(-)

diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index 700ec5c9c1..37ffb74ca5 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -578,6 +578,68 @@ static void spapr_xive_print_info(SpaprInterruptController *intc, Monitor *mon)
     spapr_xive_pic_print_info(xive, mon);
 }
 
+static void spapr_xive_dt(SpaprInterruptController *intc, uint32_t nr_servers,
+                          void *fdt, uint32_t phandle)
+{
+    SpaprXive *xive = SPAPR_XIVE(intc);
+    int node;
+    uint64_t timas[2 * 2];
+    /* Interrupt number ranges for the IPIs */
+    uint32_t lisn_ranges[] = {
+        cpu_to_be32(0),
+        cpu_to_be32(nr_servers),
+    };
+    /*
+     * EQ size - the sizes of pages supported by the system 4K, 64K,
+     * 2M, 16M. We only advertise 64K for the moment.
+     */
+    uint32_t eq_sizes[] = {
+        cpu_to_be32(16), /* 64K */
+    };
+    /*
+     * The following array is in sync with the reserved priorities
+     * defined by the 'spapr_xive_priority_is_reserved' routine.
+     */
+    uint32_t plat_res_int_priorities[] = {
+        cpu_to_be32(7),    /* start */
+        cpu_to_be32(0xf8), /* count */
+    };
+
+    /* Thread Interrupt Management Area : User (ring 3) and OS (ring 2) */
+    timas[0] = cpu_to_be64(xive->tm_base +
+                           XIVE_TM_USER_PAGE * (1ull << TM_SHIFT));
+    timas[1] = cpu_to_be64(1ull << TM_SHIFT);
+    timas[2] = cpu_to_be64(xive->tm_base +
+                           XIVE_TM_OS_PAGE * (1ull << TM_SHIFT));
+    timas[3] = cpu_to_be64(1ull << TM_SHIFT);
+
+    _FDT(node = fdt_add_subnode(fdt, 0, xive->nodename));
+
+    _FDT(fdt_setprop_string(fdt, node, "device_type", "power-ivpe"));
+    _FDT(fdt_setprop(fdt, node, "reg", timas, sizeof(timas)));
+
+    _FDT(fdt_setprop_string(fdt, node, "compatible", "ibm,power-ivpe"));
+    _FDT(fdt_setprop(fdt, node, "ibm,xive-eq-sizes", eq_sizes,
+                     sizeof(eq_sizes)));
+    _FDT(fdt_setprop(fdt, node, "ibm,xive-lisn-ranges", lisn_ranges,
+                     sizeof(lisn_ranges)));
+
+    /* For Linux to link the LSIs to the interrupt controller. */
+    _FDT(fdt_setprop(fdt, node, "interrupt-controller", NULL, 0));
+    _FDT(fdt_setprop_cell(fdt, node, "#interrupt-cells", 2));
+
+    /* For SLOF */
+    _FDT(fdt_setprop_cell(fdt, node, "linux,phandle", phandle));
+    _FDT(fdt_setprop_cell(fdt, node, "phandle", phandle));
+
+    /*
+     * The "ibm,plat-res-int-priorities" property defines the priority
+     * ranges reserved by the hypervisor
+     */
+    _FDT(fdt_setprop(fdt, 0, "ibm,plat-res-int-priorities",
+                     plat_res_int_priorities, sizeof(plat_res_int_priorities)));
+}
+
 static void spapr_xive_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -601,6 +663,7 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data)
     sicc->free_irq = spapr_xive_free_irq;
     sicc->set_irq = spapr_xive_set_irq;
     sicc->print_info = spapr_xive_print_info;
+    sicc->dt = spapr_xive_dt;
 }
 
 static const TypeInfo spapr_xive_info = {
@@ -1601,65 +1664,3 @@ void spapr_xive_hcall_init(SpaprMachineState *spapr)
     spapr_register_hypercall(H_INT_SYNC, h_int_sync);
     spapr_register_hypercall(H_INT_RESET, h_int_reset);
 }
-
-void spapr_dt_xive(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
-                   uint32_t phandle)
-{
-    SpaprXive *xive = spapr->xive;
-    int node;
-    uint64_t timas[2 * 2];
-    /* Interrupt number ranges for the IPIs */
-    uint32_t lisn_ranges[] = {
-        cpu_to_be32(0),
-        cpu_to_be32(nr_servers),
-    };
-    /*
-     * EQ size - the sizes of pages supported by the system 4K, 64K,
-     * 2M, 16M. We only advertise 64K for the moment.
-     */
-    uint32_t eq_sizes[] = {
-        cpu_to_be32(16), /* 64K */
-    };
-    /*
-     * The following array is in sync with the reserved priorities
-     * defined by the 'spapr_xive_priority_is_reserved' routine.
-     */
-    uint32_t plat_res_int_priorities[] = {
-        cpu_to_be32(7),    /* start */
-        cpu_to_be32(0xf8), /* count */
-    };
-
-    /* Thread Interrupt Management Area : User (ring 3) and OS (ring 2) */
-    timas[0] = cpu_to_be64(xive->tm_base +
-                           XIVE_TM_USER_PAGE * (1ull << TM_SHIFT));
-    timas[1] = cpu_to_be64(1ull << TM_SHIFT);
-    timas[2] = cpu_to_be64(xive->tm_base +
-                           XIVE_TM_OS_PAGE * (1ull << TM_SHIFT));
-    timas[3] = cpu_to_be64(1ull << TM_SHIFT);
-
-    _FDT(node = fdt_add_subnode(fdt, 0, xive->nodename));
-
-    _FDT(fdt_setprop_string(fdt, node, "device_type", "power-ivpe"));
-    _FDT(fdt_setprop(fdt, node, "reg", timas, sizeof(timas)));
-
-    _FDT(fdt_setprop_string(fdt, node, "compatible", "ibm,power-ivpe"));
-    _FDT(fdt_setprop(fdt, node, "ibm,xive-eq-sizes", eq_sizes,
-                     sizeof(eq_sizes)));
-    _FDT(fdt_setprop(fdt, node, "ibm,xive-lisn-ranges", lisn_ranges,
-                     sizeof(lisn_ranges)));
-
-    /* For Linux to link the LSIs to the interrupt controller. */
-    _FDT(fdt_setprop(fdt, node, "interrupt-controller", NULL, 0));
-    _FDT(fdt_setprop_cell(fdt, node, "#interrupt-cells", 2));
-
-    /* For SLOF */
-    _FDT(fdt_setprop_cell(fdt, node, "linux,phandle", phandle));
-    _FDT(fdt_setprop_cell(fdt, node, "phandle", phandle));
-
-    /*
-     * The "ibm,plat-res-int-priorities" property defines the priority
-     * ranges reserved by the hypervisor
-     */
-    _FDT(fdt_setprop(fdt, 0, "ibm,plat-res-int-priorities",
-                     plat_res_int_priorities, sizeof(plat_res_int_priorities)));
-}
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 415defe394..4eabafc7e1 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -308,8 +308,8 @@ static void ics_spapr_realize(DeviceState *dev, Error **errp)
     spapr_register_hypercall(H_IPOLL, h_ipoll);
 }
 
-void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
-                   uint32_t phandle)
+static void xics_spapr_dt(SpaprInterruptController *intc, uint32_t nr_servers,
+                          void *fdt, uint32_t phandle)
 {
     uint32_t interrupt_server_ranges_prop[] = {
         0, cpu_to_be32(nr_servers),
@@ -408,6 +408,7 @@ static void ics_spapr_class_init(ObjectClass *klass, void *data)
     sicc->free_irq = xics_spapr_free_irq;
     sicc->set_irq = xics_spapr_set_irq;
     sicc->print_info = xics_spapr_print_info;
+    sicc->dt = xics_spapr_dt;
 }
 
 static const TypeInfo ics_spapr_info = {
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 7e04746db1..f55d227cd3 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1325,8 +1325,7 @@ static void *spapr_build_fdt(SpaprMachineState *spapr)
     _FDT(fdt_setprop_cell(fdt, 0, "#size-cells", 2));
 
     /* /interrupt controller */
-    spapr->irq->dt_populate(spapr, spapr_max_server_number(spapr), fdt,
-                          PHANDLE_INTC);
+    spapr_irq_dt(spapr, spapr_max_server_number(spapr), fdt, PHANDLE_INTC);
 
     ret = spapr_populate_memory(spapr, fdt);
     if (ret < 0) {
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index be20bbf3cf..79cbe8064e 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -134,7 +134,6 @@ SpaprIrq spapr_irq_xics = {
     .xics        = true,
     .xive        = false,
 
-    .dt_populate = spapr_dt_xics,
     .post_load   = spapr_irq_post_load_xics,
     .reset       = spapr_irq_reset_xics,
     .init_kvm    = spapr_irq_init_kvm_xics,
@@ -184,7 +183,6 @@ SpaprIrq spapr_irq_xive = {
     .xics        = false,
     .xive        = true,
 
-    .dt_populate = spapr_dt_xive,
     .post_load   = spapr_irq_post_load_xive,
     .reset       = spapr_irq_reset_xive,
     .init_kvm    = spapr_irq_init_kvm_xive,
@@ -209,13 +207,6 @@ static SpaprIrq *spapr_irq_current(SpaprMachineState *spapr)
         &spapr_irq_xive : &spapr_irq_xics;
 }
 
-static void spapr_irq_dt_populate_dual(SpaprMachineState *spapr,
-                                       uint32_t nr_servers, void *fdt,
-                                       uint32_t phandle)
-{
-    spapr_irq_current(spapr)->dt_populate(spapr, nr_servers, fdt, phandle);
-}
-
 static int spapr_irq_post_load_dual(SpaprMachineState *spapr, int version_id)
 {
     /*
@@ -270,7 +261,6 @@ SpaprIrq spapr_irq_dual = {
     .xics        = true,
     .xive        = true,
 
-    .dt_populate = spapr_irq_dt_populate_dual,
     .post_load   = spapr_irq_post_load_dual,
     .reset       = spapr_irq_reset_dual,
     .init_kvm    = NULL, /* should not be used */
@@ -375,6 +365,15 @@ void spapr_irq_print_info(SpaprMachineState *spapr, Monitor *mon)
     sicc->print_info(spapr->active_intc, mon);
 }
 
+void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers,
+                  void *fdt, uint32_t phandle)
+{
+    SpaprInterruptControllerClass *sicc
+        = SPAPR_INTC_GET_CLASS(spapr->active_intc);
+
+    sicc->dt(spapr->active_intc, nr_servers, fdt, phandle);
+}
+
 void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
 {
     MachineState *machine = MACHINE(spapr);
@@ -693,7 +692,6 @@ SpaprIrq spapr_irq_xics_legacy = {
     .xics        = true,
     .xive        = false,
 
-    .dt_populate = spapr_dt_xics,
     .post_load   = spapr_irq_post_load_xics,
     .reset       = spapr_irq_reset_xics,
     .init_kvm    = spapr_irq_init_kvm_xics,
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index 2ade580992..c82724fc2b 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -60,6 +60,8 @@ typedef struct SpaprInterruptControllerClass {
     /* These methods should only be called on the active intc */
     void (*set_irq)(SpaprInterruptController *intc, int irq, int val);
     void (*print_info)(SpaprInterruptController *intc, Monitor *mon);
+    void (*dt)(SpaprInterruptController *intc, uint32_t nr_servers,
+               void *fdt, uint32_t phandle);
 } SpaprInterruptControllerClass;
 
 void spapr_irq_update_active_intc(SpaprMachineState *spapr);
@@ -70,7 +72,6 @@ void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers,
 int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
                               PowerPCCPU *cpu, Error **errp);
 
-
 void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis);
 int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align,
                         Error **errp);
@@ -82,8 +83,6 @@ typedef struct SpaprIrq {
     bool        xics;
     bool        xive;
 
-    void (*dt_populate)(SpaprMachineState *spapr, uint32_t nr_servers,
-                        void *fdt, uint32_t phandle);
     int (*post_load)(SpaprMachineState *spapr, int version_id);
     void (*reset)(SpaprMachineState *spapr, Error **errp);
     void (*init_kvm)(SpaprMachineState *spapr, Error **errp);
diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h
index 8f875673f5..ebe156eb30 100644
--- a/include/hw/ppc/spapr_xive.h
+++ b/include/hw/ppc/spapr_xive.h
@@ -58,8 +58,6 @@ void spapr_xive_pic_print_info(SpaprXive *xive, Monitor *mon);
 int spapr_xive_post_load(SpaprXive *xive, int version_id);
 
 void spapr_xive_hcall_init(SpaprMachineState *spapr);
-void spapr_dt_xive(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
-                   uint32_t phandle);
 void spapr_xive_set_tctx_os_cam(XiveTCTX *tctx);
 void spapr_xive_mmio_set_enabled(SpaprXive *xive, bool enable);
 void spapr_xive_map_mmio(SpaprXive *xive);
diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h
index 0a32a86e3e..9c9044db65 100644
--- a/include/hw/ppc/xics_spapr.h
+++ b/include/hw/ppc/xics_spapr.h
@@ -33,8 +33,6 @@
 #define ICS_SPAPR(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SPAPR)
 
 void ics_spapr_create(SpaprMachineState *spapr, int nr_xirqs, Error **errp);
-void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
-                   uint32_t phandle);
 int xics_kvm_connect(SpaprMachineState *spapr, Error **errp);
 void xics_kvm_disconnect(SpaprMachineState *spapr, Error **errp);
 bool xics_kvm_has_broken_disconnect(SpaprMachineState *spapr);
-- 
2.21.0



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

* [PATCH v2 27/33] spapr, xics, xive: Match signatures for XICS and XIVE KVM connect routines
  2019-09-27  5:49 [PATCH v2 00/33] spapr: IRQ subsystem cleanup David Gibson
                   ` (25 preceding siblings ...)
  2019-09-27  5:50 ` [PATCH v2 26/33] spapr, xics, xive: Move dt_populate " David Gibson
@ 2019-09-27  5:50 ` David Gibson
  2019-09-27 14:49   ` Greg Kurz
  2019-09-30  5:52   ` Cédric Le Goater
  2019-09-27  5:50 ` [PATCH v2 28/33] spapr: Remove SpaprIrq::init_kvm hook David Gibson
                   ` (5 subsequent siblings)
  32 siblings, 2 replies; 83+ messages in thread
From: David Gibson @ 2019-09-27  5:50 UTC (permalink / raw)
  To: qemu-devel, clg, qemu-ppc
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier, Paolo Bonzini,
	Marc-André Lureau, philmd, David Gibson

Both XICS and XIVE have routines to connect and disconnect KVM with similar
but not identical signatures.  This adjusts them to match exactly, which
will be useful for further cleanups later.

While we're at it, remove error reporting from the disconnect path.  In the
XICS case this wasn't used at all.  In the XIVE case the only error case
was if the KVM device was set up, but KVM didn't have the capability to do
so which is pretty obviously impossible.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/spapr_xive_kvm.c    | 22 ++++++++++------------
 hw/intc/xics_kvm.c          |  9 +++++----
 hw/ppc/spapr_irq.c          | 22 +++++-----------------
 include/hw/ppc/spapr_xive.h |  4 ++--
 include/hw/ppc/xics_spapr.h |  4 ++--
 5 files changed, 24 insertions(+), 37 deletions(-)

diff --git a/hw/intc/spapr_xive_kvm.c b/hw/intc/spapr_xive_kvm.c
index 51b334b676..08012ac7cd 100644
--- a/hw/intc/spapr_xive_kvm.c
+++ b/hw/intc/spapr_xive_kvm.c
@@ -740,8 +740,9 @@ static void *kvmppc_xive_mmap(SpaprXive *xive, int pgoff, size_t len,
  * All the XIVE memory regions are now backed by mappings from the KVM
  * XIVE device.
  */
-void kvmppc_xive_connect(SpaprXive *xive, Error **errp)
+int kvmppc_xive_connect(SpaprInterruptController *intc, Error **errp)
 {
+    SpaprXive *xive = SPAPR_XIVE(intc);
     XiveSource *xsrc = &xive->source;
     Error *local_err = NULL;
     size_t esb_len = (1ull << xsrc->esb_shift) * xsrc->nr_irqs;
@@ -753,19 +754,19 @@ void kvmppc_xive_connect(SpaprXive *xive, Error **errp)
      * rebooting under the XIVE-only interrupt mode.
      */
     if (xive->fd != -1) {
-        return;
+        return 0;
     }
 
     if (!kvmppc_has_cap_xive()) {
         error_setg(errp, "IRQ_XIVE capability must be present for KVM");
-        return;
+        return -1;
     }
 
     /* First, create the KVM XIVE device */
     xive->fd = kvm_create_device(kvm_state, KVM_DEV_TYPE_XIVE, false);
     if (xive->fd < 0) {
         error_setg_errno(errp, -xive->fd, "XIVE: error creating KVM device");
-        return;
+        return -1;
     }
 
     /*
@@ -821,15 +822,17 @@ void kvmppc_xive_connect(SpaprXive *xive, Error **errp)
     kvm_kernel_irqchip = true;
     kvm_msi_via_irqfd_allowed = true;
     kvm_gsi_direct_mapping = true;
-    return;
+    return 0;
 
 fail:
     error_propagate(errp, local_err);
-    kvmppc_xive_disconnect(xive, NULL);
+    kvmppc_xive_disconnect(intc);
+    return -1;
 }
 
-void kvmppc_xive_disconnect(SpaprXive *xive, Error **errp)
+void kvmppc_xive_disconnect(SpaprInterruptController *intc)
 {
+    SpaprXive *xive = SPAPR_XIVE(intc);
     XiveSource *xsrc;
     size_t esb_len;
 
@@ -838,11 +841,6 @@ void kvmppc_xive_disconnect(SpaprXive *xive, Error **errp)
         return;
     }
 
-    if (!kvmppc_has_cap_xive()) {
-        error_setg(errp, "IRQ_XIVE capability must be present for KVM");
-        return;
-    }
-
     /* Clear the KVM mapping */
     xsrc = &xive->source;
     esb_len = (1ull << xsrc->esb_shift) * xsrc->nr_irqs;
diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index ba90d6dc96..954c424b36 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -342,8 +342,9 @@ void ics_kvm_set_irq(ICSState *ics, int srcno, int val)
     }
 }
 
-int xics_kvm_connect(SpaprMachineState *spapr, Error **errp)
+int xics_kvm_connect(SpaprInterruptController *intc, Error **errp)
 {
+    ICSState *ics = ICS_SPAPR(intc);
     int rc;
     CPUState *cs;
     Error *local_err = NULL;
@@ -413,7 +414,7 @@ int xics_kvm_connect(SpaprMachineState *spapr, Error **errp)
     }
 
     /* Update the KVM sources */
-    ics_set_kvm_state(spapr->ics, &local_err);
+    ics_set_kvm_state(ics, &local_err);
     if (local_err) {
         goto fail;
     }
@@ -431,11 +432,11 @@ int xics_kvm_connect(SpaprMachineState *spapr, Error **errp)
 
 fail:
     error_propagate(errp, local_err);
-    xics_kvm_disconnect(spapr, NULL);
+    xics_kvm_disconnect(intc);
     return -1;
 }
 
-void xics_kvm_disconnect(SpaprMachineState *spapr, Error **errp)
+void xics_kvm_disconnect(SpaprInterruptController *intc)
 {
     /*
      * Only on P9 using the XICS-on XIVE KVM device:
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 79cbe8064e..561bdbc4de 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -124,7 +124,7 @@ static void spapr_irq_reset_xics(SpaprMachineState *spapr, Error **errp)
 static void spapr_irq_init_kvm_xics(SpaprMachineState *spapr, Error **errp)
 {
     if (kvm_enabled()) {
-        xics_kvm_connect(spapr, errp);
+        xics_kvm_connect(SPAPR_INTC(spapr->ics), errp);
     }
 }
 
@@ -173,7 +173,7 @@ static void spapr_irq_reset_xive(SpaprMachineState *spapr, Error **errp)
 static void spapr_irq_init_kvm_xive(SpaprMachineState *spapr, Error **errp)
 {
     if (kvm_enabled()) {
-        kvmppc_xive_connect(spapr->xive, errp);
+        kvmppc_xive_connect(SPAPR_INTC(spapr->xive), errp);
     }
 }
 
@@ -215,7 +215,7 @@ static int spapr_irq_post_load_dual(SpaprMachineState *spapr, int version_id)
      */
     if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
         if (kvm_irqchip_in_kernel()) {
-            xics_kvm_disconnect(spapr, &error_fatal);
+            xics_kvm_disconnect(SPAPR_INTC(spapr->ics));
         }
         spapr_irq_xive.reset(spapr, &error_fatal);
     }
@@ -225,8 +225,6 @@ static int spapr_irq_post_load_dual(SpaprMachineState *spapr, int version_id)
 
 static void spapr_irq_reset_dual(SpaprMachineState *spapr, Error **errp)
 {
-    Error *local_err = NULL;
-
     /*
      * Deactivate the XIVE MMIOs. The XIVE backend will reenable them
      * if selected.
@@ -235,18 +233,8 @@ static void spapr_irq_reset_dual(SpaprMachineState *spapr, Error **errp)
 
     /* Destroy all KVM devices */
     if (kvm_irqchip_in_kernel()) {
-        xics_kvm_disconnect(spapr, &local_err);
-        if (local_err) {
-            error_propagate(errp, local_err);
-            error_prepend(errp, "KVM XICS disconnect failed: ");
-            return;
-        }
-        kvmppc_xive_disconnect(spapr->xive, &local_err);
-        if (local_err) {
-            error_propagate(errp, local_err);
-            error_prepend(errp, "KVM XIVE disconnect failed: ");
-            return;
-        }
+        xics_kvm_disconnect(SPAPR_INTC(spapr->ics));
+        kvmppc_xive_disconnect(SPAPR_INTC(spapr->xive));
     }
 
     spapr_irq_current(spapr)->reset(spapr, errp);
diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h
index ebe156eb30..64972754f9 100644
--- a/include/hw/ppc/spapr_xive.h
+++ b/include/hw/ppc/spapr_xive.h
@@ -68,8 +68,8 @@ int spapr_xive_end_to_target(uint8_t end_blk, uint32_t end_idx,
 /*
  * KVM XIVE device helpers
  */
-void kvmppc_xive_connect(SpaprXive *xive, Error **errp);
-void kvmppc_xive_disconnect(SpaprXive *xive, Error **errp);
+int kvmppc_xive_connect(SpaprInterruptController *intc, Error **errp);
+void kvmppc_xive_disconnect(SpaprInterruptController *intc);
 void kvmppc_xive_reset(SpaprXive *xive, Error **errp);
 void kvmppc_xive_set_source_config(SpaprXive *xive, uint32_t lisn, XiveEAS *eas,
                                    Error **errp);
diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h
index 9c9044db65..445beeffef 100644
--- a/include/hw/ppc/xics_spapr.h
+++ b/include/hw/ppc/xics_spapr.h
@@ -33,8 +33,8 @@
 #define ICS_SPAPR(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SPAPR)
 
 void ics_spapr_create(SpaprMachineState *spapr, int nr_xirqs, Error **errp);
-int xics_kvm_connect(SpaprMachineState *spapr, Error **errp);
-void xics_kvm_disconnect(SpaprMachineState *spapr, Error **errp);
+int xics_kvm_connect(SpaprInterruptController *intc, Error **errp);
+void xics_kvm_disconnect(SpaprInterruptController *intc);
 bool xics_kvm_has_broken_disconnect(SpaprMachineState *spapr);
 
 #endif /* XICS_SPAPR_H */
-- 
2.21.0



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

* [PATCH v2 28/33] spapr: Remove SpaprIrq::init_kvm hook
  2019-09-27  5:49 [PATCH v2 00/33] spapr: IRQ subsystem cleanup David Gibson
                   ` (26 preceding siblings ...)
  2019-09-27  5:50 ` [PATCH v2 27/33] spapr, xics, xive: Match signatures for XICS and XIVE KVM connect routines David Gibson
@ 2019-09-27  5:50 ` David Gibson
  2019-09-27 15:04   ` Greg Kurz
  2019-09-30  5:55   ` Cédric Le Goater
  2019-09-27  5:50 ` [PATCH v2 29/33] spapr, xics, xive: Move SpaprIrq::reset hook logic into activate/deactivate David Gibson
                   ` (4 subsequent siblings)
  32 siblings, 2 replies; 83+ messages in thread
From: David Gibson @ 2019-09-27  5:50 UTC (permalink / raw)
  To: qemu-devel, clg, qemu-ppc
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier, Paolo Bonzini,
	Marc-André Lureau, philmd, David Gibson

This hook is a bit odd.  The only caller is spapr_irq_init_kvm(), but
it explicitly takes an SpaprIrq *, so it's never really called through the
current SpaprIrq.  Essentially this is just a way of passing through a
function pointer so that spapr_irq_init_kvm() can handle some
configuration and error handling logic without duplicating it between the
xics and xive reset paths.

So, make it just take that function pointer.  Because of earlier reworks
to the KVM connect/disconnect code in the xics and xive backends we can
also eliminate some wrapper functions and streamline error handling a bit.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr_irq.c         | 74 +++++++++++++-------------------------
 include/hw/ppc/spapr_irq.h |  1 -
 2 files changed, 25 insertions(+), 50 deletions(-)

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 561bdbc4de..c6abebc4ef 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -65,33 +65,35 @@ void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, uint32_t num)
     bitmap_clear(spapr->irq_map, irq - SPAPR_IRQ_MSI, num);
 }
 
-static void spapr_irq_init_kvm(SpaprMachineState *spapr,
-                                  SpaprIrq *irq, Error **errp)
+static int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController *, Error **),
+                              SpaprInterruptController *intc,
+                              Error **errp)
 {
-    MachineState *machine = MACHINE(spapr);
+    MachineState *machine = MACHINE(qdev_get_machine());
     Error *local_err = NULL;
 
     if (kvm_enabled() && machine_kernel_irqchip_allowed(machine)) {
-        irq->init_kvm(spapr, &local_err);
-        if (local_err && machine_kernel_irqchip_required(machine)) {
-            error_prepend(&local_err,
-                          "kernel_irqchip requested but unavailable: ");
-            error_propagate(errp, local_err);
-            return;
-        }
+        if (fn(intc, &local_err) < 0) {
+            if (machine_kernel_irqchip_required(machine)) {
+                error_prepend(&local_err,
+                              "kernel_irqchip requested but unavailable: ");
+                error_propagate(errp, local_err);
+                return -1;
+            }
 
-        if (!local_err) {
-            return;
+            /*
+             * We failed to initialize the KVM device, fallback to
+             * emulated mode
+             */
+            error_prepend(&local_err,
+                          "kernel_irqchip allowed but unavailable: ");
+            error_append_hint(&local_err,
+                              "Falling back to kernel-irqchip=off\n");
+            warn_report_err(local_err);
         }
-
-        /*
-         * We failed to initialize the KVM device, fallback to
-         * emulated mode
-         */
-        error_prepend(&local_err, "kernel_irqchip allowed but unavailable: ");
-        error_append_hint(&local_err, "Falling back to kernel-irqchip=off\n");
-        warn_report_err(local_err);
     }
+
+    return 0;
 }
 
 /*
@@ -112,20 +114,7 @@ static int spapr_irq_post_load_xics(SpaprMachineState *spapr, int version_id)
 
 static void spapr_irq_reset_xics(SpaprMachineState *spapr, Error **errp)
 {
-    Error *local_err = NULL;
-
-    spapr_irq_init_kvm(spapr, &spapr_irq_xics, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-}
-
-static void spapr_irq_init_kvm_xics(SpaprMachineState *spapr, Error **errp)
-{
-    if (kvm_enabled()) {
-        xics_kvm_connect(SPAPR_INTC(spapr->ics), errp);
-    }
+    spapr_irq_init_kvm(xics_kvm_connect, SPAPR_INTC(spapr->ics), errp);
 }
 
 SpaprIrq spapr_irq_xics = {
@@ -136,7 +125,6 @@ SpaprIrq spapr_irq_xics = {
 
     .post_load   = spapr_irq_post_load_xics,
     .reset       = spapr_irq_reset_xics,
-    .init_kvm    = spapr_irq_init_kvm_xics,
 };
 
 /*
@@ -151,7 +139,6 @@ static int spapr_irq_post_load_xive(SpaprMachineState *spapr, int version_id)
 static void spapr_irq_reset_xive(SpaprMachineState *spapr, Error **errp)
 {
     CPUState *cs;
-    Error *local_err = NULL;
 
     CPU_FOREACH(cs) {
         PowerPCCPU *cpu = POWERPC_CPU(cs);
@@ -160,9 +147,8 @@ static void spapr_irq_reset_xive(SpaprMachineState *spapr, Error **errp)
         spapr_xive_set_tctx_os_cam(spapr_cpu_state(cpu)->tctx);
     }
 
-    spapr_irq_init_kvm(spapr, &spapr_irq_xive, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
+    if (spapr_irq_init_kvm(kvmppc_xive_connect,
+                           SPAPR_INTC(spapr->xive), errp) < 0) {
         return;
     }
 
@@ -170,13 +156,6 @@ static void spapr_irq_reset_xive(SpaprMachineState *spapr, Error **errp)
     spapr_xive_mmio_set_enabled(spapr->xive, true);
 }
 
-static void spapr_irq_init_kvm_xive(SpaprMachineState *spapr, Error **errp)
-{
-    if (kvm_enabled()) {
-        kvmppc_xive_connect(SPAPR_INTC(spapr->xive), errp);
-    }
-}
-
 SpaprIrq spapr_irq_xive = {
     .nr_xirqs    = SPAPR_NR_XIRQS,
     .nr_msis     = SPAPR_NR_MSIS,
@@ -185,7 +164,6 @@ SpaprIrq spapr_irq_xive = {
 
     .post_load   = spapr_irq_post_load_xive,
     .reset       = spapr_irq_reset_xive,
-    .init_kvm    = spapr_irq_init_kvm_xive,
 };
 
 /*
@@ -251,7 +229,6 @@ SpaprIrq spapr_irq_dual = {
 
     .post_load   = spapr_irq_post_load_dual,
     .reset       = spapr_irq_reset_dual,
-    .init_kvm    = NULL, /* should not be used */
 };
 
 
@@ -682,7 +659,6 @@ SpaprIrq spapr_irq_xics_legacy = {
 
     .post_load   = spapr_irq_post_load_xics,
     .reset       = spapr_irq_reset_xics,
-    .init_kvm    = spapr_irq_init_kvm_xics,
 };
 
 static void spapr_irq_register_types(void)
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index c82724fc2b..c947f40571 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -85,7 +85,6 @@ typedef struct SpaprIrq {
 
     int (*post_load)(SpaprMachineState *spapr, int version_id);
     void (*reset)(SpaprMachineState *spapr, Error **errp);
-    void (*init_kvm)(SpaprMachineState *spapr, Error **errp);
 } SpaprIrq;
 
 extern SpaprIrq spapr_irq_xics;
-- 
2.21.0



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

* [PATCH v2 29/33] spapr, xics, xive: Move SpaprIrq::reset hook logic into activate/deactivate
  2019-09-27  5:49 [PATCH v2 00/33] spapr: IRQ subsystem cleanup David Gibson
                   ` (27 preceding siblings ...)
  2019-09-27  5:50 ` [PATCH v2 28/33] spapr: Remove SpaprIrq::init_kvm hook David Gibson
@ 2019-09-27  5:50 ` David Gibson
  2019-09-30  6:11   ` Cédric Le Goater
  2019-09-27  5:50 ` [PATCH v2 30/33] spapr, xics, xive: Move SpaprIrq::post_load hook to backends David Gibson
                   ` (3 subsequent siblings)
  32 siblings, 1 reply; 83+ messages in thread
From: David Gibson @ 2019-09-27  5:50 UTC (permalink / raw)
  To: qemu-devel, clg, qemu-ppc
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier, Paolo Bonzini,
	Marc-André Lureau, philmd, David Gibson

It turns out that all the logic in the SpaprIrq::reset hooks (and some in
the SpaprIrq::post_load hooks) isn't really related to resetting the irq
backend (that's handled by the backends' own reset routines).  Rather its
about getting the backend ready to be the active interrupt controller or
stopping being the active interrupt controller - reset (and post_load) is
just the only time that changes at present.

To make this flow clearer, move the logic into the explicit backend
activate and deactivate hooks.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/spapr_xive.c       | 35 ++++++++++++++++++++
 hw/intc/xics_spapr.c       | 16 +++++++++
 hw/ppc/spapr_irq.c         | 67 ++------------------------------------
 include/hw/ppc/spapr_irq.h |  4 ++-
 4 files changed, 57 insertions(+), 65 deletions(-)

diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index 37ffb74ca5..e8b946982c 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -640,6 +640,39 @@ static void spapr_xive_dt(SpaprInterruptController *intc, uint32_t nr_servers,
                      plat_res_int_priorities, sizeof(plat_res_int_priorities)));
 }
 
+static void spapr_xive_activate(SpaprInterruptController *intc, Error **errp)
+{
+    SpaprXive *xive = SPAPR_XIVE(intc);
+    CPUState *cs;
+
+    CPU_FOREACH(cs) {
+        PowerPCCPU *cpu = POWERPC_CPU(cs);
+
+        /* (TCG) Set the OS CAM line of the thread interrupt context. */
+        spapr_xive_set_tctx_os_cam(spapr_cpu_state(cpu)->tctx);
+    }
+
+    if (kvm_enabled()) {
+        if (spapr_irq_init_kvm(kvmppc_xive_connect, intc, errp) < 0) {
+            return;
+        }
+    }
+
+    /* Activate the XIVE MMIOs */
+    spapr_xive_mmio_set_enabled(xive, true);
+}
+
+static void spapr_xive_deactivate(SpaprInterruptController *intc)
+{
+    SpaprXive *xive = SPAPR_XIVE(intc);
+
+    spapr_xive_mmio_set_enabled(xive, false);
+
+    if (kvm_irqchip_in_kernel()) {
+        kvmppc_xive_disconnect(intc);
+    }
+}
+
 static void spapr_xive_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -658,6 +691,8 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data)
     xrc->write_nvt = spapr_xive_write_nvt;
     xrc->get_tctx = spapr_xive_get_tctx;
 
+    sicc->activate = spapr_xive_activate;
+    sicc->deactivate = spapr_xive_deactivate;
     sicc->cpu_intc_create = spapr_xive_cpu_intc_create;
     sicc->claim_irq = spapr_xive_claim_irq;
     sicc->free_irq = spapr_xive_free_irq;
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 4eabafc7e1..8abbc799ba 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -395,6 +395,20 @@ static void xics_spapr_print_info(SpaprInterruptController *intc, Monitor *mon)
     ics_pic_print_info(ics, mon);
 }
 
+static void xics_spapr_activate(SpaprInterruptController *intc, Error **errp)
+{
+    if (kvm_enabled()) {
+        spapr_irq_init_kvm(xics_kvm_connect, intc, errp);
+    }
+}
+
+static void xics_spapr_deactivate(SpaprInterruptController *intc)
+{
+    if (kvm_irqchip_in_kernel()) {
+        xics_kvm_disconnect(intc);
+    }
+}
+
 static void ics_spapr_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -403,6 +417,8 @@ static void ics_spapr_class_init(ObjectClass *klass, void *data)
 
     device_class_set_parent_realize(dc, ics_spapr_realize,
                                     &isc->parent_realize);
+    sicc->activate = xics_spapr_activate;
+    sicc->deactivate = xics_spapr_deactivate;
     sicc->cpu_intc_create = xics_spapr_cpu_intc_create;
     sicc->claim_irq = xics_spapr_claim_irq;
     sicc->free_irq = xics_spapr_free_irq;
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index c6abebc4ef..2fd9dd0ec2 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -65,9 +65,9 @@ void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, uint32_t num)
     bitmap_clear(spapr->irq_map, irq - SPAPR_IRQ_MSI, num);
 }
 
-static int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController *, Error **),
-                              SpaprInterruptController *intc,
-                              Error **errp)
+int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController *, Error **),
+                       SpaprInterruptController *intc,
+                       Error **errp)
 {
     MachineState *machine = MACHINE(qdev_get_machine());
     Error *local_err = NULL;
@@ -112,11 +112,6 @@ static int spapr_irq_post_load_xics(SpaprMachineState *spapr, int version_id)
     return 0;
 }
 
-static void spapr_irq_reset_xics(SpaprMachineState *spapr, Error **errp)
-{
-    spapr_irq_init_kvm(xics_kvm_connect, SPAPR_INTC(spapr->ics), errp);
-}
-
 SpaprIrq spapr_irq_xics = {
     .nr_xirqs    = SPAPR_NR_XIRQS,
     .nr_msis     = SPAPR_NR_MSIS,
@@ -124,7 +119,6 @@ SpaprIrq spapr_irq_xics = {
     .xive        = false,
 
     .post_load   = spapr_irq_post_load_xics,
-    .reset       = spapr_irq_reset_xics,
 };
 
 /*
@@ -136,26 +130,6 @@ static int spapr_irq_post_load_xive(SpaprMachineState *spapr, int version_id)
     return spapr_xive_post_load(spapr->xive, version_id);
 }
 
-static void spapr_irq_reset_xive(SpaprMachineState *spapr, Error **errp)
-{
-    CPUState *cs;
-
-    CPU_FOREACH(cs) {
-        PowerPCCPU *cpu = POWERPC_CPU(cs);
-
-        /* (TCG) Set the OS CAM line of the thread interrupt context. */
-        spapr_xive_set_tctx_os_cam(spapr_cpu_state(cpu)->tctx);
-    }
-
-    if (spapr_irq_init_kvm(kvmppc_xive_connect,
-                           SPAPR_INTC(spapr->xive), errp) < 0) {
-        return;
-    }
-
-    /* Activate the XIVE MMIOs */
-    spapr_xive_mmio_set_enabled(spapr->xive, true);
-}
-
 SpaprIrq spapr_irq_xive = {
     .nr_xirqs    = SPAPR_NR_XIRQS,
     .nr_msis     = SPAPR_NR_MSIS,
@@ -163,7 +137,6 @@ SpaprIrq spapr_irq_xive = {
     .xive        = true,
 
     .post_load   = spapr_irq_post_load_xive,
-    .reset       = spapr_irq_reset_xive,
 };
 
 /*
@@ -187,37 +160,9 @@ static SpaprIrq *spapr_irq_current(SpaprMachineState *spapr)
 
 static int spapr_irq_post_load_dual(SpaprMachineState *spapr, int version_id)
 {
-    /*
-     * Force a reset of the XIVE backend after migration. The machine
-     * defaults to XICS at startup.
-     */
-    if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
-        if (kvm_irqchip_in_kernel()) {
-            xics_kvm_disconnect(SPAPR_INTC(spapr->ics));
-        }
-        spapr_irq_xive.reset(spapr, &error_fatal);
-    }
-
     return spapr_irq_current(spapr)->post_load(spapr, version_id);
 }
 
-static void spapr_irq_reset_dual(SpaprMachineState *spapr, Error **errp)
-{
-    /*
-     * Deactivate the XIVE MMIOs. The XIVE backend will reenable them
-     * if selected.
-     */
-    spapr_xive_mmio_set_enabled(spapr->xive, false);
-
-    /* Destroy all KVM devices */
-    if (kvm_irqchip_in_kernel()) {
-        xics_kvm_disconnect(SPAPR_INTC(spapr->ics));
-        kvmppc_xive_disconnect(SPAPR_INTC(spapr->xive));
-    }
-
-    spapr_irq_current(spapr)->reset(spapr, errp);
-}
-
 /*
  * Define values in sync with the XIVE and XICS backend
  */
@@ -228,7 +173,6 @@ SpaprIrq spapr_irq_dual = {
     .xive        = true,
 
     .post_load   = spapr_irq_post_load_dual,
-    .reset       = spapr_irq_reset_dual,
 };
 
 
@@ -519,10 +463,6 @@ void spapr_irq_reset(SpaprMachineState *spapr, Error **errp)
     assert(!spapr->irq_map || bitmap_empty(spapr->irq_map, spapr->irq_map_nr));
 
     spapr_irq_update_active_intc(spapr);
-
-    if (spapr->irq->reset) {
-        spapr->irq->reset(spapr, errp);
-    }
 }
 
 int spapr_irq_get_phandle(SpaprMachineState *spapr, void *fdt, Error **errp)
@@ -658,7 +598,6 @@ SpaprIrq spapr_irq_xics_legacy = {
     .xive        = false,
 
     .post_load   = spapr_irq_post_load_xics,
-    .reset       = spapr_irq_reset_xics,
 };
 
 static void spapr_irq_register_types(void)
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index c947f40571..28044d7479 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -84,7 +84,6 @@ typedef struct SpaprIrq {
     bool        xive;
 
     int (*post_load)(SpaprMachineState *spapr, int version_id);
-    void (*reset)(SpaprMachineState *spapr, Error **errp);
 } SpaprIrq;
 
 extern SpaprIrq spapr_irq_xics;
@@ -99,6 +98,9 @@ qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq);
 int spapr_irq_post_load(SpaprMachineState *spapr, int version_id);
 void spapr_irq_reset(SpaprMachineState *spapr, Error **errp);
 int spapr_irq_get_phandle(SpaprMachineState *spapr, void *fdt, Error **errp);
+int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController *, Error **),
+                       SpaprInterruptController *intc,
+                       Error **errp);
 
 /*
  * XICS legacy routines
-- 
2.21.0



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

* [PATCH v2 30/33] spapr, xics, xive: Move SpaprIrq::post_load hook to backends
  2019-09-27  5:49 [PATCH v2 00/33] spapr: IRQ subsystem cleanup David Gibson
                   ` (28 preceding siblings ...)
  2019-09-27  5:50 ` [PATCH v2 29/33] spapr, xics, xive: Move SpaprIrq::reset hook logic into activate/deactivate David Gibson
@ 2019-09-27  5:50 ` David Gibson
  2019-09-27  5:50 ` [PATCH v2 31/33] spapr: Remove SpaprIrq::nr_msis David Gibson
                   ` (2 subsequent siblings)
  32 siblings, 0 replies; 83+ messages in thread
From: David Gibson @ 2019-09-27  5:50 UTC (permalink / raw)
  To: qemu-devel, clg, qemu-ppc
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier, Paolo Bonzini,
	Marc-André Lureau, philmd, David Gibson

The remaining logic in the post_load hook really belongs to the interrupt
controller backends, and just needs to be called on the active controller
(after the active controller is set to the right thing based on the
incoming migration in the generic spapr_irq_post_load() logic).

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/spapr_xive.c        |  5 +++--
 hw/intc/xics_spapr.c        | 13 +++++++++++
 hw/ppc/spapr_irq.c          | 45 ++++---------------------------------
 include/hw/ppc/spapr_irq.h  |  3 +--
 include/hw/ppc/spapr_xive.h |  1 -
 5 files changed, 21 insertions(+), 46 deletions(-)

diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index e8b946982c..ab68e6eaf6 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -462,10 +462,10 @@ static int vmstate_spapr_xive_pre_save(void *opaque)
  * Called by the sPAPR IRQ backend 'post_load' method at the machine
  * level.
  */
-int spapr_xive_post_load(SpaprXive *xive, int version_id)
+static int spapr_xive_post_load(SpaprInterruptController *intc, int version_id)
 {
     if (kvm_irqchip_in_kernel()) {
-        return kvmppc_xive_post_load(xive, version_id);
+        return kvmppc_xive_post_load(SPAPR_XIVE(intc), version_id);
     }
 
     return 0;
@@ -699,6 +699,7 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data)
     sicc->set_irq = spapr_xive_set_irq;
     sicc->print_info = spapr_xive_print_info;
     sicc->dt = spapr_xive_dt;
+    sicc->post_load = spapr_xive_post_load;
 }
 
 static const TypeInfo spapr_xive_info = {
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 8abbc799ba..9590eedc3d 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -395,6 +395,18 @@ static void xics_spapr_print_info(SpaprInterruptController *intc, Monitor *mon)
     ics_pic_print_info(ics, mon);
 }
 
+static int xics_spapr_post_load(SpaprInterruptController *intc, int version_id)
+{
+    if (!kvm_irqchip_in_kernel()) {
+        CPUState *cs;
+        CPU_FOREACH(cs) {
+            PowerPCCPU *cpu = POWERPC_CPU(cs);
+            icp_resend(spapr_cpu_state(cpu)->icp);
+        }
+    }
+    return 0;
+}
+
 static void xics_spapr_activate(SpaprInterruptController *intc, Error **errp)
 {
     if (kvm_enabled()) {
@@ -425,6 +437,7 @@ static void ics_spapr_class_init(ObjectClass *klass, void *data)
     sicc->set_irq = xics_spapr_set_irq;
     sicc->print_info = xics_spapr_print_info;
     sicc->dt = xics_spapr_dt;
+    sicc->post_load = xics_spapr_post_load;
 }
 
 static const TypeInfo ics_spapr_info = {
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 2fd9dd0ec2..040384b0fe 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -100,43 +100,22 @@ int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController *, Error **),
  * XICS IRQ backend.
  */
 
-static int spapr_irq_post_load_xics(SpaprMachineState *spapr, int version_id)
-{
-    if (!kvm_irqchip_in_kernel()) {
-        CPUState *cs;
-        CPU_FOREACH(cs) {
-            PowerPCCPU *cpu = POWERPC_CPU(cs);
-            icp_resend(spapr_cpu_state(cpu)->icp);
-        }
-    }
-    return 0;
-}
-
 SpaprIrq spapr_irq_xics = {
     .nr_xirqs    = SPAPR_NR_XIRQS,
     .nr_msis     = SPAPR_NR_MSIS,
     .xics        = true,
     .xive        = false,
-
-    .post_load   = spapr_irq_post_load_xics,
 };
 
 /*
  * XIVE IRQ backend.
  */
 
-static int spapr_irq_post_load_xive(SpaprMachineState *spapr, int version_id)
-{
-    return spapr_xive_post_load(spapr->xive, version_id);
-}
-
 SpaprIrq spapr_irq_xive = {
     .nr_xirqs    = SPAPR_NR_XIRQS,
     .nr_msis     = SPAPR_NR_MSIS,
     .xics        = false,
     .xive        = true,
-
-    .post_load   = spapr_irq_post_load_xive,
 };
 
 /*
@@ -148,21 +127,6 @@ SpaprIrq spapr_irq_xive = {
  * activated after an extra machine reset.
  */
 
-/*
- * Returns the sPAPR IRQ backend negotiated by CAS. XICS is the
- * default.
- */
-static SpaprIrq *spapr_irq_current(SpaprMachineState *spapr)
-{
-    return spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT) ?
-        &spapr_irq_xive : &spapr_irq_xics;
-}
-
-static int spapr_irq_post_load_dual(SpaprMachineState *spapr, int version_id)
-{
-    return spapr_irq_current(spapr)->post_load(spapr, version_id);
-}
-
 /*
  * Define values in sync with the XIVE and XICS backend
  */
@@ -171,8 +135,6 @@ SpaprIrq spapr_irq_dual = {
     .nr_msis     = SPAPR_NR_MSIS,
     .xics        = true,
     .xive        = true,
-
-    .post_load   = spapr_irq_post_load_dual,
 };
 
 
@@ -454,8 +416,11 @@ qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq)
 
 int spapr_irq_post_load(SpaprMachineState *spapr, int version_id)
 {
+    SpaprInterruptControllerClass *sicc;
+
     spapr_irq_update_active_intc(spapr);
-    return spapr->irq->post_load(spapr, version_id);
+    sicc = SPAPR_INTC_GET_CLASS(spapr->active_intc);
+    return sicc->post_load(spapr->active_intc, version_id);
 }
 
 void spapr_irq_reset(SpaprMachineState *spapr, Error **errp)
@@ -596,8 +561,6 @@ SpaprIrq spapr_irq_xics_legacy = {
     .nr_msis     = SPAPR_IRQ_XICS_LEGACY_NR_XIRQS,
     .xics        = true,
     .xive        = false,
-
-    .post_load   = spapr_irq_post_load_xics,
 };
 
 static void spapr_irq_register_types(void)
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index 28044d7479..bc379b0761 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -62,6 +62,7 @@ typedef struct SpaprInterruptControllerClass {
     void (*print_info)(SpaprInterruptController *intc, Monitor *mon);
     void (*dt)(SpaprInterruptController *intc, uint32_t nr_servers,
                void *fdt, uint32_t phandle);
+    int (*post_load)(SpaprInterruptController *intc, int version_id);
 } SpaprInterruptControllerClass;
 
 void spapr_irq_update_active_intc(SpaprMachineState *spapr);
@@ -82,8 +83,6 @@ typedef struct SpaprIrq {
     uint32_t    nr_msis;
     bool        xics;
     bool        xive;
-
-    int (*post_load)(SpaprMachineState *spapr, int version_id);
 } SpaprIrq;
 
 extern SpaprIrq spapr_irq_xics;
diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h
index 64972754f9..d84bd5c229 100644
--- a/include/hw/ppc/spapr_xive.h
+++ b/include/hw/ppc/spapr_xive.h
@@ -55,7 +55,6 @@ typedef struct SpaprXive {
 #define SPAPR_XIVE_BLOCK_ID 0x0
 
 void spapr_xive_pic_print_info(SpaprXive *xive, Monitor *mon);
-int spapr_xive_post_load(SpaprXive *xive, int version_id);
 
 void spapr_xive_hcall_init(SpaprMachineState *spapr);
 void spapr_xive_set_tctx_os_cam(XiveTCTX *tctx);
-- 
2.21.0



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

* [PATCH v2 31/33] spapr: Remove SpaprIrq::nr_msis
  2019-09-27  5:49 [PATCH v2 00/33] spapr: IRQ subsystem cleanup David Gibson
                   ` (29 preceding siblings ...)
  2019-09-27  5:50 ` [PATCH v2 30/33] spapr, xics, xive: Move SpaprIrq::post_load hook to backends David Gibson
@ 2019-09-27  5:50 ` David Gibson
  2019-09-27 15:17   ` Greg Kurz
  2019-09-27  5:50 ` [PATCH v2 32/33] spapr: Move SpaprIrq::nr_xirqs to SpaprMachineClass David Gibson
  2019-09-27  5:50 ` [PATCH v2 33/33] spapr: Remove last pieces of SpaprIrq David Gibson
  32 siblings, 1 reply; 83+ messages in thread
From: David Gibson @ 2019-09-27  5:50 UTC (permalink / raw)
  To: qemu-devel, clg, qemu-ppc
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier, Paolo Bonzini,
	Marc-André Lureau, philmd, David Gibson

The nr_msis value we use here has to line up with whether we're using
legacy or modern irq allocation.  Therefore it's safer to derive it based
on legacy_irq_allocation rather than having SpaprIrq contain a canned
value.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr.c              |  5 ++---
 hw/ppc/spapr_irq.c          | 26 +++++++++++++++++---------
 hw/ppc/spapr_pci.c          |  7 ++++---
 include/hw/pci-host/spapr.h |  4 ++--
 include/hw/ppc/spapr_irq.h  |  5 +----
 5 files changed, 26 insertions(+), 21 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index f55d227cd3..34b693beba 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1345,7 +1345,7 @@ static void *spapr_build_fdt(SpaprMachineState *spapr)
     }
 
     QLIST_FOREACH(phb, &spapr->phbs, list) {
-        ret = spapr_dt_phb(phb, PHANDLE_INTC, fdt, spapr->irq->nr_msis, NULL);
+        ret = spapr_dt_phb(spapr, phb, PHANDLE_INTC, fdt, NULL);
         if (ret < 0) {
             error_report("couldn't setup PCI devices in fdt");
             exit(1);
@@ -3980,8 +3980,7 @@ int spapr_phb_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr,
         return -1;
     }
 
-    if (spapr_dt_phb(sphb, intc_phandle, fdt, spapr->irq->nr_msis,
-                     fdt_start_offset)) {
+    if (spapr_dt_phb(spapr, sphb, intc_phandle, fdt, fdt_start_offset)) {
         error_setg(errp, "unable to create FDT node for PHB %d", sphb->index);
         return -1;
     }
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 040384b0fe..799755c811 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -29,9 +29,14 @@ static const TypeInfo spapr_intc_info = {
     .class_size = sizeof(SpaprInterruptControllerClass),
 };
 
-void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis)
+static void spapr_irq_msi_init(SpaprMachineState *spapr)
 {
-    spapr->irq_map_nr = nr_msis;
+    if (SPAPR_MACHINE_GET_CLASS(spapr)->legacy_irq_allocation) {
+        /* Legacy mode doesn't use this allocater */
+        return;
+    }
+
+    spapr->irq_map_nr = spapr_irq_nr_msis(spapr);
     spapr->irq_map = bitmap_new(spapr->irq_map_nr);
 }
 
@@ -102,7 +107,6 @@ int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController *, Error **),
 
 SpaprIrq spapr_irq_xics = {
     .nr_xirqs    = SPAPR_NR_XIRQS,
-    .nr_msis     = SPAPR_NR_MSIS,
     .xics        = true,
     .xive        = false,
 };
@@ -113,7 +117,6 @@ SpaprIrq spapr_irq_xics = {
 
 SpaprIrq spapr_irq_xive = {
     .nr_xirqs    = SPAPR_NR_XIRQS,
-    .nr_msis     = SPAPR_NR_MSIS,
     .xics        = false,
     .xive        = true,
 };
@@ -132,7 +135,6 @@ SpaprIrq spapr_irq_xive = {
  */
 SpaprIrq spapr_irq_dual = {
     .nr_xirqs    = SPAPR_NR_XIRQS,
-    .nr_msis     = SPAPR_NR_MSIS,
     .xics        = true,
     .xive        = true,
 };
@@ -245,6 +247,15 @@ void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers,
     sicc->dt(spapr->active_intc, nr_servers, fdt, phandle);
 }
 
+uint32_t spapr_irq_nr_msis(SpaprMachineState *spapr)
+{
+    if (SPAPR_MACHINE_GET_CLASS(spapr)->legacy_irq_allocation) {
+        return spapr->irq->nr_xirqs;
+    } else {
+        return SPAPR_XIRQ_BASE + spapr->irq->nr_xirqs - SPAPR_IRQ_MSI;
+    }
+}
+
 void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
 {
     MachineState *machine = MACHINE(spapr);
@@ -267,9 +278,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
     }
 
     /* Initialize the MSI IRQ allocator. */
-    if (!SPAPR_MACHINE_GET_CLASS(spapr)->legacy_irq_allocation) {
-        spapr_irq_msi_init(spapr, spapr->irq->nr_msis);
-    }
+    spapr_irq_msi_init(spapr);
 
     if (spapr->irq->xics) {
         Object *obj;
@@ -558,7 +567,6 @@ int spapr_irq_find(SpaprMachineState *spapr, int num, bool align, Error **errp)
 
 SpaprIrq spapr_irq_xics_legacy = {
     .nr_xirqs    = SPAPR_IRQ_XICS_LEGACY_NR_XIRQS,
-    .nr_msis     = SPAPR_IRQ_XICS_LEGACY_NR_XIRQS,
     .xics        = true,
     .xive        = false,
 };
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 6934d506a7..8ed06e5964 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -2305,8 +2305,8 @@ static void spapr_phb_pci_enumerate(SpaprPhbState *phb)
 
 }
 
-int spapr_dt_phb(SpaprPhbState *phb, uint32_t intc_phandle, void *fdt,
-                 uint32_t nr_msis, int *node_offset)
+int spapr_dt_phb(SpaprMachineState *spapr, SpaprPhbState *phb,
+                 uint32_t intc_phandle, void *fdt, int *node_offset)
 {
     int bus_off, i, j, ret;
     uint32_t bus_range[] = { cpu_to_be32(0), cpu_to_be32(0xff) };
@@ -2371,7 +2371,8 @@ int spapr_dt_phb(SpaprPhbState *phb, uint32_t intc_phandle, void *fdt,
     _FDT(fdt_setprop(fdt, bus_off, "ranges", &ranges, sizeof_ranges));
     _FDT(fdt_setprop(fdt, bus_off, "reg", &bus_reg, sizeof(bus_reg)));
     _FDT(fdt_setprop_cell(fdt, bus_off, "ibm,pci-config-space-type", 0x1));
-    _FDT(fdt_setprop_cell(fdt, bus_off, "ibm,pe-total-#msi", nr_msis));
+    _FDT(fdt_setprop_cell(fdt, bus_off, "ibm,pe-total-#msi",
+                          spapr_irq_nr_msis(spapr)));
 
     /* Dynamic DMA window */
     if (phb->ddw_enabled) {
diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h
index 23506f05d9..8877ff51fb 100644
--- a/include/hw/pci-host/spapr.h
+++ b/include/hw/pci-host/spapr.h
@@ -128,8 +128,8 @@ struct SpaprPhbState {
 #define SPAPR_PCI_NV2ATSD_WIN_SIZE   (NVGPU_MAX_NUM * NVGPU_MAX_LINKS * \
                                       64 * KiB)
 
-int spapr_dt_phb(SpaprPhbState *phb, uint32_t intc_phandle, void *fdt,
-                 uint32_t nr_msis, int *node_offset);
+int spapr_dt_phb(SpaprMachineState *spapr, SpaprPhbState *phb,
+                 uint32_t intc_phandle, void *fdt, int *node_offset);
 
 void spapr_pci_rtas_init(void);
 
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index bc379b0761..308bfcefd1 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -27,7 +27,6 @@
 #define SPAPR_IRQ_MSI        (SPAPR_XIRQ_BASE + 0x0300)
 
 #define SPAPR_NR_XIRQS       0x1000
-#define SPAPR_NR_MSIS        (SPAPR_XIRQ_BASE + SPAPR_NR_XIRQS - SPAPR_IRQ_MSI)
 
 typedef struct SpaprMachineState SpaprMachineState;
 
@@ -72,15 +71,13 @@ void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers,
                   void *fdt, uint32_t phandle);
 int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
                               PowerPCCPU *cpu, Error **errp);
-
-void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis);
+uint32_t spapr_irq_nr_msis(SpaprMachineState *spapr);
 int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align,
                         Error **errp);
 void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, uint32_t num);
 
 typedef struct SpaprIrq {
     uint32_t    nr_xirqs;
-    uint32_t    nr_msis;
     bool        xics;
     bool        xive;
 } SpaprIrq;
-- 
2.21.0



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

* [PATCH v2 32/33] spapr: Move SpaprIrq::nr_xirqs to SpaprMachineClass
  2019-09-27  5:49 [PATCH v2 00/33] spapr: IRQ subsystem cleanup David Gibson
                   ` (30 preceding siblings ...)
  2019-09-27  5:50 ` [PATCH v2 31/33] spapr: Remove SpaprIrq::nr_msis David Gibson
@ 2019-09-27  5:50 ` David Gibson
  2019-09-27 15:22   ` Greg Kurz
  2019-09-27  5:50 ` [PATCH v2 33/33] spapr: Remove last pieces of SpaprIrq David Gibson
  32 siblings, 1 reply; 83+ messages in thread
From: David Gibson @ 2019-09-27  5:50 UTC (permalink / raw)
  To: qemu-devel, clg, qemu-ppc
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier, Paolo Bonzini,
	Marc-André Lureau, philmd, David Gibson

For the benefit of peripheral device allocation, the number of available
irqs really wants to be the same on a given machine type version,
regardless of what irq backends we are using.  That's the case now, but
only because we make sure the different SpaprIrq instances have the same
value except for the special legacy one.

Since this really only depends on machine type version, move the value to
SpaprMachineClass instead of SpaprIrq.  This also puts the code to set it
to the lower value on old machine types right next to setting
legacy_irq_allocation, which needs to go hand in hand.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr.c             |  2 ++
 hw/ppc/spapr_irq.c         | 33 ++++++++++++++++-----------------
 include/hw/ppc/spapr.h     |  1 +
 include/hw/ppc/spapr_irq.h |  1 -
 4 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 34b693beba..7113249c89 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -4513,6 +4513,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
     smc->irq = &spapr_irq_dual;
     smc->dr_phb_enabled = true;
     smc->linux_pci_probe = true;
+    smc->nr_xirqs = SPAPR_NR_XIRQS;
 }
 
 static const TypeInfo spapr_machine_info = {
@@ -4648,6 +4649,7 @@ static void spapr_machine_3_0_class_options(MachineClass *mc)
     compat_props_add(mc->compat_props, hw_compat_3_0, hw_compat_3_0_len);
 
     smc->legacy_irq_allocation = true;
+    smc->nr_xirqs = 0x400;
     smc->irq = &spapr_irq_xics_legacy;
 }
 
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 799755c811..f76f30f54b 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -106,7 +106,6 @@ int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController *, Error **),
  */
 
 SpaprIrq spapr_irq_xics = {
-    .nr_xirqs    = SPAPR_NR_XIRQS,
     .xics        = true,
     .xive        = false,
 };
@@ -116,7 +115,6 @@ SpaprIrq spapr_irq_xics = {
  */
 
 SpaprIrq spapr_irq_xive = {
-    .nr_xirqs    = SPAPR_NR_XIRQS,
     .xics        = false,
     .xive        = true,
 };
@@ -134,7 +132,6 @@ SpaprIrq spapr_irq_xive = {
  * Define values in sync with the XIVE and XICS backend
  */
 SpaprIrq spapr_irq_dual = {
-    .nr_xirqs    = SPAPR_NR_XIRQS,
     .xics        = true,
     .xive        = true,
 };
@@ -249,16 +246,19 @@ void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers,
 
 uint32_t spapr_irq_nr_msis(SpaprMachineState *spapr)
 {
-    if (SPAPR_MACHINE_GET_CLASS(spapr)->legacy_irq_allocation) {
-        return spapr->irq->nr_xirqs;
+    SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
+
+    if (smc->legacy_irq_allocation) {
+        return smc->nr_xirqs;
     } else {
-        return SPAPR_XIRQ_BASE + spapr->irq->nr_xirqs - SPAPR_IRQ_MSI;
+        return SPAPR_XIRQ_BASE + smc->nr_xirqs - SPAPR_IRQ_MSI;
     }
 }
 
 void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
 {
     MachineState *machine = MACHINE(spapr);
+    SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
     Error *local_err = NULL;
 
     if (machine_kernel_irqchip_split(machine)) {
@@ -295,8 +295,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
             goto out;
         }
 
-        object_property_set_int(obj, spapr->irq->nr_xirqs, "nr-irqs",
-                                &local_err);
+        object_property_set_int(obj, smc->nr_xirqs, "nr-irqs", &local_err);
         if (local_err) {
             goto out;
         }
@@ -315,8 +314,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
         int i;
 
         dev = qdev_create(NULL, TYPE_SPAPR_XIVE);
-        qdev_prop_set_uint32(dev, "nr-irqs",
-                             spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
+        qdev_prop_set_uint32(dev, "nr-irqs", smc->nr_xirqs + SPAPR_XIRQ_BASE);
         /*
          * 8 XIVE END structures per CPU. One for each available
          * priority
@@ -343,7 +341,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
     }
 
     spapr->qirqs = qemu_allocate_irqs(spapr_set_irq, spapr,
-                                      spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
+                                      smc->nr_xirqs + SPAPR_XIRQ_BASE);
 
 out:
     error_propagate(errp, local_err);
@@ -351,10 +349,11 @@ out:
 
 int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
 {
+    SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
     int rc;
 
     assert(irq >= SPAPR_XIRQ_BASE);
-    assert(irq < (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
+    assert(irq < (smc->nr_xirqs + SPAPR_XIRQ_BASE));
 
     if (spapr->xive) {
         SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(spapr->xive);
@@ -379,10 +378,11 @@ int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
 
 void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
 {
+    SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
     int i;
 
     assert(irq >= SPAPR_XIRQ_BASE);
-    assert((irq + num) <= (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
+    assert((irq + num) <= (smc->nr_xirqs + SPAPR_XIRQ_BASE));
 
     for (i = irq; i < (irq + num); i++) {
         if (spapr->xive) {
@@ -402,6 +402,8 @@ void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
 
 qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq)
 {
+    SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
+
     /*
      * This interface is basically for VIO and PHB devices to find the
      * right qemu_irq to manipulate, so we only allow access to the
@@ -410,7 +412,7 @@ qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq)
      * interfaces, we can change this if we need to in future.
      */
     assert(irq >= SPAPR_XIRQ_BASE);
-    assert(irq < (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
+    assert(irq < (smc->nr_xirqs + SPAPR_XIRQ_BASE));
 
     if (spapr->ics) {
         assert(ics_valid_irq(spapr->ics, irq));
@@ -563,10 +565,7 @@ int spapr_irq_find(SpaprMachineState *spapr, int num, bool align, Error **errp)
     return first + ics->offset;
 }
 
-#define SPAPR_IRQ_XICS_LEGACY_NR_XIRQS     0x400
-
 SpaprIrq spapr_irq_xics_legacy = {
-    .nr_xirqs    = SPAPR_IRQ_XICS_LEGACY_NR_XIRQS,
     .xics        = true,
     .xive        = false,
 };
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 763da757f0..623e8e3f93 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -119,6 +119,7 @@ struct SpaprMachineClass {
     bool use_ohci_by_default;  /* use USB-OHCI instead of XHCI */
     bool pre_2_10_has_unused_icps;
     bool legacy_irq_allocation;
+    uint32_t nr_xirqs;
     bool broken_host_serial_model; /* present real host info to the guest */
     bool pre_4_1_migration; /* don't migrate hpt-max-page-size */
     bool linux_pci_probe;
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index 308bfcefd1..73d8beda39 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -77,7 +77,6 @@ int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align,
 void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, uint32_t num);
 
 typedef struct SpaprIrq {
-    uint32_t    nr_xirqs;
     bool        xics;
     bool        xive;
 } SpaprIrq;
-- 
2.21.0



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

* [PATCH v2 33/33] spapr: Remove last pieces of SpaprIrq
  2019-09-27  5:49 [PATCH v2 00/33] spapr: IRQ subsystem cleanup David Gibson
                   ` (31 preceding siblings ...)
  2019-09-27  5:50 ` [PATCH v2 32/33] spapr: Move SpaprIrq::nr_xirqs to SpaprMachineClass David Gibson
@ 2019-09-27  5:50 ` David Gibson
  32 siblings, 0 replies; 83+ messages in thread
From: David Gibson @ 2019-09-27  5:50 UTC (permalink / raw)
  To: qemu-devel, clg, qemu-ppc
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier, Paolo Bonzini,
	Marc-André Lureau, philmd, David Gibson

The only thing remaining in this structure are the flags to allow either
XICS or XIVE to be present.  These actually make more sense as spapr
capabilities - that way they can take advantage of the existing
infrastructure to sanity check capability states across migration and so
forth.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr.c             | 39 ++++++++++--------
 hw/ppc/spapr_caps.c        | 64 +++++++++++++++++++++++++++++
 hw/ppc/spapr_hcall.c       |  7 ++--
 hw/ppc/spapr_irq.c         | 84 ++------------------------------------
 include/hw/ppc/spapr.h     |  8 ++--
 include/hw/ppc/spapr_irq.h | 10 -----
 6 files changed, 100 insertions(+), 112 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 7113249c89..3b73c5b493 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1142,12 +1142,13 @@ static void spapr_dt_ov5_platform_support(SpaprMachineState *spapr, void *fdt,
         26, 0x40, /* Radix options: GTSE == yes. */
     };
 
-    if (spapr->irq->xics && spapr->irq->xive) {
+    if (spapr_get_cap(spapr, SPAPR_CAP_XICS)
+        && spapr_get_cap(spapr, SPAPR_CAP_XIVE)) {
         val[1] = SPAPR_OV5_XIVE_BOTH;
-    } else if (spapr->irq->xive) {
+    } else if (spapr_get_cap(spapr, SPAPR_CAP_XIVE)) {
         val[1] = SPAPR_OV5_XIVE_EXPLOIT;
     } else {
-        assert(spapr->irq->xics);
+        assert(spapr_get_cap(spapr, SPAPR_CAP_XICS));
         val[1] = SPAPR_OV5_XIVE_LEGACY;
     }
 
@@ -2845,7 +2846,7 @@ static void spapr_machine_init(MachineState *machine)
     spapr_ovec_set(spapr->ov5, OV5_DRMEM_V2);
 
     /* advertise XIVE on POWER9 machines */
-    if (spapr->irq->xive) {
+    if (spapr_get_cap(spapr, SPAPR_CAP_XIVE)) {
         spapr_ovec_set(spapr->ov5, OV5_XIVE_EXPLOIT);
     }
 
@@ -3312,14 +3313,18 @@ static void spapr_set_vsmt(Object *obj, Visitor *v, const char *name,
 static char *spapr_get_ic_mode(Object *obj, Error **errp)
 {
     SpaprMachineState *spapr = SPAPR_MACHINE(obj);
+    SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
 
-    if (spapr->irq == &spapr_irq_xics_legacy) {
+    if (smc->legacy_irq_allocation) {
         return g_strdup("legacy");
-    } else if (spapr->irq == &spapr_irq_xics) {
+    } else if (spapr_get_cap(spapr, SPAPR_CAP_XICS)
+               && !spapr_get_cap(spapr, SPAPR_CAP_XIVE)) {
         return g_strdup("xics");
-    } else if (spapr->irq == &spapr_irq_xive) {
+    } else if (!spapr_get_cap(spapr, SPAPR_CAP_XICS)
+               && spapr_get_cap(spapr, SPAPR_CAP_XIVE)) {
         return g_strdup("xive");
-    } else if (spapr->irq == &spapr_irq_dual) {
+    } else if (spapr_get_cap(spapr, SPAPR_CAP_XICS)
+               && spapr_get_cap(spapr, SPAPR_CAP_XIVE)) {
         return g_strdup("dual");
     }
     g_assert_not_reached();
@@ -3336,11 +3341,15 @@ static void spapr_set_ic_mode(Object *obj, const char *value, Error **errp)
 
     /* The legacy IRQ backend can not be set */
     if (strcmp(value, "xics") == 0) {
-        spapr->irq = &spapr_irq_xics;
+        fprintf(stderr, "Setting ic-mode=xics\n");
+        object_property_set_bool(obj, true, "cap-xics", errp);
+        object_property_set_bool(obj, false, "cap-xive", errp);
     } else if (strcmp(value, "xive") == 0) {
-        spapr->irq = &spapr_irq_xive;
+        object_property_set_bool(obj, false, "cap-xics", errp);
+        object_property_set_bool(obj, true, "cap-xive", errp);
     } else if (strcmp(value, "dual") == 0) {
-        spapr->irq = &spapr_irq_dual;
+        object_property_set_bool(obj, true, "cap-xics", errp);
+        object_property_set_bool(obj, true, "cap-xive", errp);
     } else {
         error_setg(errp, "Bad value for \"ic-mode\" property");
     }
@@ -3379,7 +3388,6 @@ static void spapr_set_host_serial(Object *obj, const char *value, Error **errp)
 static void spapr_instance_init(Object *obj)
 {
     SpaprMachineState *spapr = SPAPR_MACHINE(obj);
-    SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
 
     spapr->htab_fd = -1;
     spapr->use_hotplug_event_source = true;
@@ -3415,7 +3423,6 @@ static void spapr_instance_init(Object *obj)
                              spapr_get_msix_emulation, NULL, NULL);
 
     /* The machine class defines the default interrupt controller mode */
-    spapr->irq = smc->irq;
     object_property_add_str(obj, "ic-mode", spapr_get_ic_mode,
                             spapr_set_ic_mode, NULL);
     object_property_set_description(obj, "ic-mode",
@@ -4509,8 +4516,9 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
     smc->default_caps.caps[SPAPR_CAP_NESTED_KVM_HV] = SPAPR_CAP_OFF;
     smc->default_caps.caps[SPAPR_CAP_LARGE_DECREMENTER] = SPAPR_CAP_ON;
     smc->default_caps.caps[SPAPR_CAP_CCF_ASSIST] = SPAPR_CAP_OFF;
+    smc->default_caps.caps[SPAPR_CAP_XICS] = SPAPR_CAP_ON;
+    smc->default_caps.caps[SPAPR_CAP_XIVE] = SPAPR_CAP_ON;
     spapr_caps_add_properties(smc, &error_abort);
-    smc->irq = &spapr_irq_dual;
     smc->dr_phb_enabled = true;
     smc->linux_pci_probe = true;
     smc->nr_xirqs = SPAPR_NR_XIRQS;
@@ -4609,7 +4617,7 @@ static void spapr_machine_4_0_class_options(MachineClass *mc)
     spapr_machine_4_1_class_options(mc);
     compat_props_add(mc->compat_props, hw_compat_4_0, hw_compat_4_0_len);
     smc->phb_placement = phb_placement_4_0;
-    smc->irq = &spapr_irq_xics;
+    smc->default_caps.caps[SPAPR_CAP_XIVE] = SPAPR_CAP_OFF;
     smc->pre_4_1_migration = true;
 }
 
@@ -4650,7 +4658,6 @@ static void spapr_machine_3_0_class_options(MachineClass *mc)
 
     smc->legacy_irq_allocation = true;
     smc->nr_xirqs = 0x400;
-    smc->irq = &spapr_irq_xics_legacy;
 }
 
 DEFINE_SPAPR_MACHINE(3_0, "3.0", false);
diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
index 481dfd2a27..e06fd386f6 100644
--- a/hw/ppc/spapr_caps.c
+++ b/hw/ppc/spapr_caps.c
@@ -496,6 +496,42 @@ static void cap_ccf_assist_apply(SpaprMachineState *spapr, uint8_t val,
     }
 }
 
+static void cap_xics_apply(SpaprMachineState *spapr, uint8_t val, Error **errp)
+{
+    SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
+
+    if (!val) {
+        if (!spapr_get_cap(spapr, SPAPR_CAP_XIVE)) {
+            error_setg(errp,
+"No interrupt controllers enabled, try cap-xics=on or cap-xive=on");
+            return;
+        }
+
+        if (smc->legacy_irq_allocation) {
+            error_setg(errp, "This machine version requires XICS support");
+            return;
+        }
+    }
+}
+
+static void cap_xive_apply(SpaprMachineState *spapr, uint8_t val, Error **errp)
+{
+    SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
+    PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
+
+    if (val) {
+        if (smc->legacy_irq_allocation) {
+            error_setg(errp, "This machine version cannot support XIVE");
+            return;
+        }
+        if (!ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_3_00, 0,
+                              spapr->max_compat_pvr)) {
+            error_setg(errp, "XIVE requires POWER9 CPU");
+            return;
+        }
+    }
+}
+
 SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
     [SPAPR_CAP_HTM] = {
         .name = "htm",
@@ -595,6 +631,24 @@ SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
         .type = "bool",
         .apply = cap_ccf_assist_apply,
     },
+    [SPAPR_CAP_XICS] = {
+        .name = "xics",
+        .description = "Allow XICS interrupt controller",
+        .index = SPAPR_CAP_XICS,
+        .get = spapr_cap_get_bool,
+        .set = spapr_cap_set_bool,
+        .type = "bool",
+        .apply = cap_xics_apply,
+    },
+    [SPAPR_CAP_XIVE] = {
+        .name = "xive",
+        .description = "Allow XIVE interrupt controller",
+        .index = SPAPR_CAP_XIVE,
+        .get = spapr_cap_get_bool,
+        .set = spapr_cap_set_bool,
+        .type = "bool",
+        .apply = cap_xive_apply,
+    },
 };
 
 static SpaprCapabilities default_caps_with_cpu(SpaprMachineState *spapr,
@@ -641,6 +695,14 @@ static SpaprCapabilities default_caps_with_cpu(SpaprMachineState *spapr,
         caps.caps[SPAPR_CAP_HPT_MAXPAGESIZE] = mps;
     }
 
+    /*
+     * POWER8 machines don't have XIVE
+     */
+    if (!ppc_type_check_compat(cputype, CPU_POWERPC_LOGICAL_3_00,
+                               0, spapr->max_compat_pvr)) {
+        caps.caps[SPAPR_CAP_XIVE] = SPAPR_CAP_OFF;
+    }
+
     return caps;
 }
 
@@ -734,6 +796,8 @@ SPAPR_CAP_MIG_STATE(hpt_maxpagesize, SPAPR_CAP_HPT_MAXPAGESIZE);
 SPAPR_CAP_MIG_STATE(nested_kvm_hv, SPAPR_CAP_NESTED_KVM_HV);
 SPAPR_CAP_MIG_STATE(large_decr, SPAPR_CAP_LARGE_DECREMENTER);
 SPAPR_CAP_MIG_STATE(ccf_assist, SPAPR_CAP_CCF_ASSIST);
+SPAPR_CAP_MIG_STATE(xics, SPAPR_CAP_XICS);
+SPAPR_CAP_MIG_STATE(xive, SPAPR_CAP_XIVE);
 
 void spapr_caps_init(SpaprMachineState *spapr)
 {
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 140f05c1c6..cb4c6edf63 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -1784,13 +1784,13 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
      * terminate the boot.
      */
     if (guest_xive) {
-        if (!spapr->irq->xive) {
+        if (!spapr_get_cap(spapr, SPAPR_CAP_XIVE)) {
             error_report(
 "Guest requested unavailable interrupt mode (XIVE), try the ic-mode=xive or ic-mode=dual machine property");
             exit(EXIT_FAILURE);
         }
     } else {
-        if (!spapr->irq->xics) {
+        if (!spapr_get_cap(spapr, SPAPR_CAP_XICS)) {
             error_report(
 "Guest requested unavailable interrupt mode (XICS), either don't set the ic-mode machine property or try ic-mode=xics or ic-mode=dual");
             exit(EXIT_FAILURE);
@@ -1804,7 +1804,8 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
      */
     if (!spapr->cas_reboot) {
         spapr->cas_reboot = spapr_ovec_test(ov5_updates, OV5_XIVE_EXPLOIT)
-            && spapr->irq->xics && spapr->irq->xive;
+            && spapr_get_cap(spapr, SPAPR_CAP_XICS)
+            && spapr_get_cap(spapr, SPAPR_CAP_XIVE);
     }
 
     spapr_ovec_cleanup(ov5_updates);
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index f76f30f54b..d5a4fedf19 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -101,90 +101,19 @@ int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController *, Error **),
     return 0;
 }
 
-/*
- * XICS IRQ backend.
- */
-
-SpaprIrq spapr_irq_xics = {
-    .xics        = true,
-    .xive        = false,
-};
-
-/*
- * XIVE IRQ backend.
- */
-
-SpaprIrq spapr_irq_xive = {
-    .xics        = false,
-    .xive        = true,
-};
-
-/*
- * Dual XIVE and XICS IRQ backend.
- *
- * Both interrupt mode, XIVE and XICS, objects are created but the
- * machine starts in legacy interrupt mode (XICS). It can be changed
- * by the CAS negotiation process and, in that case, the new mode is
- * activated after an extra machine reset.
- */
-
-/*
- * Define values in sync with the XIVE and XICS backend
- */
-SpaprIrq spapr_irq_dual = {
-    .xics        = true,
-    .xive        = true,
-};
-
-
 static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
 {
     MachineState *machine = MACHINE(spapr);
 
-    /*
-     * Sanity checks on non-P9 machines. On these, XIVE is not
-     * advertised, see spapr_dt_ov5_platform_support()
-     */
-    if (!ppc_type_check_compat(machine->cpu_type, CPU_POWERPC_LOGICAL_3_00,
-                               0, spapr->max_compat_pvr)) {
-        /*
-         * If the 'dual' interrupt mode is selected, force XICS as CAS
-         * negotiation is useless.
-         */
-        if (spapr->irq == &spapr_irq_dual) {
-            spapr->irq = &spapr_irq_xics;
-            return;
-        }
-
-        /*
-         * Non-P9 machines using only XIVE is a bogus setup. We have two
-         * scenarios to take into account because of the compat mode:
-         *
-         * 1. POWER7/8 machines should fail to init later on when creating
-         *    the XIVE interrupt presenters because a POWER9 exception
-         *    model is required.
-
-         * 2. POWER9 machines using the POWER8 compat mode won't fail and
-         *    will let the OS boot with a partial XIVE setup : DT
-         *    properties but no hcalls.
-         *
-         * To cover both and not confuse the OS, add an early failure in
-         * QEMU.
-         */
-        if (spapr->irq == &spapr_irq_xive) {
-            error_setg(errp, "XIVE-only machines require a POWER9 CPU");
-            return;
-        }
-    }
-
     /*
      * On a POWER9 host, some older KVM XICS devices cannot be destroyed and
      * re-created. Detect that early to avoid QEMU to exit later when the
      * guest reboots.
      */
     if (kvm_enabled() &&
-        spapr->irq == &spapr_irq_dual &&
         machine_kernel_irqchip_required(machine) &&
+        spapr_get_cap(spapr, SPAPR_CAP_XICS) &&
+        spapr_get_cap(spapr, SPAPR_CAP_XIVE) &&
         xics_kvm_has_broken_disconnect(spapr)) {
         error_setg(errp, "KVM is too old to support ic-mode=dual,kernel-irqchip=on");
         return;
@@ -280,7 +209,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
     /* Initialize the MSI IRQ allocator. */
     spapr_irq_msi_init(spapr);
 
-    if (spapr->irq->xics) {
+    if (spapr_get_cap(spapr, SPAPR_CAP_XICS)) {
         Object *obj;
 
         obj = object_new(TYPE_ICS_SPAPR);
@@ -308,7 +237,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
         spapr->ics = ICS_SPAPR(obj);
     }
 
-    if (spapr->irq->xive) {
+    if (spapr_get_cap(spapr, SPAPR_CAP_XIVE)) {
         uint32_t nr_servers = spapr_max_server_number(spapr);
         DeviceState *dev;
         int i;
@@ -565,11 +494,6 @@ int spapr_irq_find(SpaprMachineState *spapr, int num, bool align, Error **errp)
     return first + ics->offset;
 }
 
-SpaprIrq spapr_irq_xics_legacy = {
-    .xics        = true,
-    .xive        = false,
-};
-
 static void spapr_irq_register_types(void)
 {
     type_register_static(&spapr_intc_info);
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 623e8e3f93..bae5d1ccb3 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -79,8 +79,12 @@ typedef enum {
 #define SPAPR_CAP_LARGE_DECREMENTER     0x08
 /* Count Cache Flush Assist HW Instruction */
 #define SPAPR_CAP_CCF_ASSIST            0x09
+/* XICS interrupt controller */
+#define SPAPR_CAP_XICS                  0x0a
+/* XIVE interrupt controller */
+#define SPAPR_CAP_XIVE                  0x0b
 /* Num Caps */
-#define SPAPR_CAP_NUM                   (SPAPR_CAP_CCF_ASSIST + 1)
+#define SPAPR_CAP_NUM                   (SPAPR_CAP_XIVE + 1)
 
 /*
  * Capability Values
@@ -131,7 +135,6 @@ struct SpaprMachineClass {
                           hwaddr *nv2atsd, Error **errp);
     SpaprResizeHpt resize_hpt_default;
     SpaprCapabilities default_caps;
-    SpaprIrq *irq;
 };
 
 /**
@@ -195,7 +198,6 @@ struct SpaprMachineState {
 
     int32_t irq_map_nr;
     unsigned long *irq_map;
-    SpaprIrq *irq;
     qemu_irq *qirqs;
     SpaprInterruptController *active_intc;
     ICSState *ics;
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index 73d8beda39..3533896425 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -76,16 +76,6 @@ int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align,
                         Error **errp);
 void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, uint32_t num);
 
-typedef struct SpaprIrq {
-    bool        xics;
-    bool        xive;
-} SpaprIrq;
-
-extern SpaprIrq spapr_irq_xics;
-extern SpaprIrq spapr_irq_xics_legacy;
-extern SpaprIrq spapr_irq_xive;
-extern SpaprIrq spapr_irq_dual;
-
 void spapr_irq_init(SpaprMachineState *spapr, Error **errp);
 int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
 void spapr_irq_free(SpaprMachineState *spapr, int irq, int num);
-- 
2.21.0



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

* Re: [PATCH v2 01/33] xics: Minor fixes for XICSFabric interface
  2019-09-27  5:49 ` [PATCH v2 01/33] xics: Minor fixes for XICSFabric interface David Gibson
@ 2019-09-27  7:17   ` Greg Kurz
  0 siblings, 0 replies; 83+ messages in thread
From: Greg Kurz @ 2019-09-27  7:17 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

On Fri, 27 Sep 2019 15:49:56 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> Interface instances should never be directly dereferenced.  So, the common
> practice is to make them incomplete types to make sure no-one does that.
> XICSFrabric, however, had a dummy type which is less safe.
> 
> We were also using OBJECT_CHECK() where we should have been using
> INTERFACE_CHECK().
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---

Reviewed-by: Greg Kurz <groug@kaod.org>

>  include/hw/ppc/xics.h | 6 +-----
>  1 file changed, 1 insertion(+), 5 deletions(-)
> 
> diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
> index 64a2c8862a..faa33ae943 100644
> --- a/include/hw/ppc/xics.h
> +++ b/include/hw/ppc/xics.h
> @@ -147,13 +147,9 @@ struct ICSIRQState {
>      uint8_t flags;
>  };
>  
> -struct XICSFabric {
> -    Object parent;
> -};
> -
>  #define TYPE_XICS_FABRIC "xics-fabric"
>  #define XICS_FABRIC(obj)                                     \
> -    OBJECT_CHECK(XICSFabric, (obj), TYPE_XICS_FABRIC)
> +    INTERFACE_CHECK(XICSFabric, (obj), TYPE_XICS_FABRIC)
>  #define XICS_FABRIC_CLASS(klass)                                     \
>      OBJECT_CLASS_CHECK(XICSFabricClass, (klass), TYPE_XICS_FABRIC)
>  #define XICS_FABRIC_GET_CLASS(obj)                                   \



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

* Re: [PATCH v2 04/33] xics: Eliminate reset hook
  2019-09-27  5:49 ` [PATCH v2 04/33] xics: Eliminate reset hook David Gibson
@ 2019-09-27  7:19   ` Greg Kurz
  0 siblings, 0 replies; 83+ messages in thread
From: Greg Kurz @ 2019-09-27  7:19 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

On Fri, 27 Sep 2019 15:49:59 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> Currently TYPE_XICS_BASE and TYPE_XICS_SIMPLE have their own reset methods,
> using the standard technique for having the subtype call the supertype's
> methods before doing its own thing.
> 
> But TYPE_XICS_SIMPLE is the only subtype of TYPE_XICS_BASE ever
> instantiated, so there's no point having the split here.  Merge them
> together into just an ics_reset() function.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> Reviewed-by: Cédric Le Goater <clg@kaod.org>
> ---

Reviewed-by: Greg Kurz <groug@kaod.org>

>  hw/intc/xics.c        | 57 ++++++++++++++++++-------------------------
>  include/hw/ppc/xics.h |  1 -
>  2 files changed, 24 insertions(+), 34 deletions(-)
> 
> diff --git a/hw/intc/xics.c b/hw/intc/xics.c
> index 310dc72b46..82e6f09259 100644
> --- a/hw/intc/xics.c
> +++ b/hw/intc/xics.c
> @@ -547,11 +547,28 @@ static void ics_eoi(ICSState *ics, uint32_t nr)
>      }
>  }
>  
> -static void ics_simple_reset(DeviceState *dev)
> +static void ics_reset_irq(ICSIRQState *irq)
>  {
> -    ICSStateClass *icsc = ICS_BASE_GET_CLASS(dev);
> +    irq->priority = 0xff;
> +    irq->saved_priority = 0xff;
> +}
>  
> -    icsc->parent_reset(dev);
> +static void ics_reset(DeviceState *dev)
> +{
> +    ICSState *ics = ICS_BASE(dev);
> +    int i;
> +    uint8_t flags[ics->nr_irqs];
> +
> +    for (i = 0; i < ics->nr_irqs; i++) {
> +        flags[i] = ics->irqs[i].flags;
> +    }
> +
> +    memset(ics->irqs, 0, sizeof(ICSIRQState) * ics->nr_irqs);
> +
> +    for (i = 0; i < ics->nr_irqs; i++) {
> +        ics_reset_irq(ics->irqs + i);
> +        ics->irqs[i].flags = flags[i];
> +    }
>  
>      if (kvm_irqchip_in_kernel()) {
>          Error *local_err = NULL;
> @@ -563,9 +580,9 @@ static void ics_simple_reset(DeviceState *dev)
>      }
>  }
>  
> -static void ics_simple_reset_handler(void *dev)
> +static void ics_reset_handler(void *dev)
>  {
> -    ics_simple_reset(dev);
> +    ics_reset(dev);
>  }
>  
>  static void ics_simple_realize(DeviceState *dev, Error **errp)
> @@ -580,7 +597,7 @@ static void ics_simple_realize(DeviceState *dev, Error **errp)
>          return;
>      }
>  
> -    qemu_register_reset(ics_simple_reset_handler, ics);
> +    qemu_register_reset(ics_reset_handler, ics);
>  }
>  
>  static void ics_simple_class_init(ObjectClass *klass, void *data)
> @@ -590,8 +607,6 @@ static void ics_simple_class_init(ObjectClass *klass, void *data)
>  
>      device_class_set_parent_realize(dc, ics_simple_realize,
>                                      &isc->parent_realize);
> -    device_class_set_parent_reset(dc, ics_simple_reset,
> -                                  &isc->parent_reset);
>  }
>  
>  static const TypeInfo ics_simple_info = {
> @@ -602,30 +617,6 @@ static const TypeInfo ics_simple_info = {
>      .class_size = sizeof(ICSStateClass),
>  };
>  
> -static void ics_reset_irq(ICSIRQState *irq)
> -{
> -    irq->priority = 0xff;
> -    irq->saved_priority = 0xff;
> -}
> -
> -static void ics_base_reset(DeviceState *dev)
> -{
> -    ICSState *ics = ICS_BASE(dev);
> -    int i;
> -    uint8_t flags[ics->nr_irqs];
> -
> -    for (i = 0; i < ics->nr_irqs; i++) {
> -        flags[i] = ics->irqs[i].flags;
> -    }
> -
> -    memset(ics->irqs, 0, sizeof(ICSIRQState) * ics->nr_irqs);
> -
> -    for (i = 0; i < ics->nr_irqs; i++) {
> -        ics_reset_irq(ics->irqs + i);
> -        ics->irqs[i].flags = flags[i];
> -    }
> -}
> -
>  static void ics_base_realize(DeviceState *dev, Error **errp)
>  {
>      ICSState *ics = ICS_BASE(dev);
> @@ -726,7 +717,7 @@ static void ics_base_class_init(ObjectClass *klass, void *data)
>  
>      dc->realize = ics_base_realize;
>      dc->props = ics_base_properties;
> -    dc->reset = ics_base_reset;
> +    dc->reset = ics_reset;
>      dc->vmsd = &vmstate_ics_base;
>  }
>  
> diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
> index 8874bad328..7efd49c02c 100644
> --- a/include/hw/ppc/xics.h
> +++ b/include/hw/ppc/xics.h
> @@ -105,7 +105,6 @@ struct ICSStateClass {
>      DeviceClass parent_class;
>  
>      DeviceRealize parent_realize;
> -    DeviceReset parent_reset;
>  };
>  
>  struct ICSState {



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

* Re: [PATCH v2 06/33] xics: Create sPAPR specific ICS subtype
  2019-09-27  5:50 ` [PATCH v2 06/33] xics: Create sPAPR specific ICS subtype David Gibson
@ 2019-09-27  7:22   ` Greg Kurz
  0 siblings, 0 replies; 83+ messages in thread
From: Greg Kurz @ 2019-09-27  7:22 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

On Fri, 27 Sep 2019 15:50:01 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> We create a subtype of TYPE_ICS specifically for sPAPR.  For now all this
> does is move the setup of the PAPR specific hcalls and RTAS calls to
> the realize() function for this, rather than requiring the PAPR code to
> explicitly call xics_spapr_init().  In future it will have some more
> function.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> Reviewed-by: Cédric Le Goater <clg@kaod.org>
> ---

Reviewed-by: Greg Kurz <groug@kaod.org>

>  hw/intc/xics_spapr.c        | 34 +++++++++++++++++++++++++++++++++-
>  hw/ppc/spapr_irq.c          |  6 ++----
>  include/hw/ppc/xics_spapr.h |  4 +++-
>  3 files changed, 38 insertions(+), 6 deletions(-)
> 
> diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
> index 3e9444813a..e6dd004587 100644
> --- a/hw/intc/xics_spapr.c
> +++ b/hw/intc/xics_spapr.c
> @@ -283,8 +283,18 @@ static void rtas_int_on(PowerPCCPU *cpu, SpaprMachineState *spapr,
>      rtas_st(rets, 0, RTAS_OUT_SUCCESS);
>  }
>  
> -void xics_spapr_init(SpaprMachineState *spapr)
> +static void ics_spapr_realize(DeviceState *dev, Error **errp)
>  {
> +    ICSState *ics = ICS_SPAPR(dev);
> +    ICSStateClass *icsc = ICS_GET_CLASS(ics);
> +    Error *local_err = NULL;
> +
> +    icsc->parent_realize(dev, &local_err);
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +        return;
> +    }
> +
>      spapr_rtas_register(RTAS_IBM_SET_XIVE, "ibm,set-xive", rtas_set_xive);
>      spapr_rtas_register(RTAS_IBM_GET_XIVE, "ibm,get-xive", rtas_get_xive);
>      spapr_rtas_register(RTAS_IBM_INT_OFF, "ibm,int-off", rtas_int_off);
> @@ -319,3 +329,25 @@ void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
>      _FDT(fdt_setprop_cell(fdt, node, "linux,phandle", phandle));
>      _FDT(fdt_setprop_cell(fdt, node, "phandle", phandle));
>  }
> +
> +static void ics_spapr_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +    ICSStateClass *isc = ICS_CLASS(klass);
> +
> +    device_class_set_parent_realize(dc, ics_spapr_realize,
> +                                    &isc->parent_realize);
> +}
> +
> +static const TypeInfo ics_spapr_info = {
> +    .name = TYPE_ICS_SPAPR,
> +    .parent = TYPE_ICS,
> +    .class_init = ics_spapr_class_init,
> +};
> +
> +static void xics_spapr_register_types(void)
> +{
> +    type_register_static(&ics_spapr_info);
> +}
> +
> +type_init(xics_spapr_register_types)
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index 6c45d2a3c0..8c26fa2d1e 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -98,7 +98,7 @@ static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_irqs,
>      Object *obj;
>      Error *local_err = NULL;
>  
> -    obj = object_new(TYPE_ICS);
> +    obj = object_new(TYPE_ICS_SPAPR);
>      object_property_add_child(OBJECT(spapr), "ics", obj, &error_abort);
>      object_property_add_const_link(obj, ICS_PROP_XICS, OBJECT(spapr),
>                                     &error_fatal);
> @@ -109,9 +109,7 @@ static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_irqs,
>          return;
>      }
>  
> -    spapr->ics = ICS(obj);
> -
> -    xics_spapr_init(spapr);
> +    spapr->ics = ICS_SPAPR(obj);
>  }
>  
>  static int spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
> diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h
> index 5dabc9a138..691a6d00f7 100644
> --- a/include/hw/ppc/xics_spapr.h
> +++ b/include/hw/ppc/xics_spapr.h
> @@ -31,11 +31,13 @@
>  
>  #define XICS_NODENAME "interrupt-controller"
>  
> +#define TYPE_ICS_SPAPR "ics-spapr"
> +#define ICS_SPAPR(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SPAPR)
> +
>  void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
>                     uint32_t phandle);
>  int xics_kvm_connect(SpaprMachineState *spapr, Error **errp);
>  void xics_kvm_disconnect(SpaprMachineState *spapr, Error **errp);
>  bool xics_kvm_has_broken_disconnect(SpaprMachineState *spapr);
> -void xics_spapr_init(SpaprMachineState *spapr);
>  
>  #endif /* XICS_SPAPR_H */



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

* Re: [PATCH v2 09/33] spapr: Clarify and fix handling of nr_irqs
  2019-09-27  5:50 ` [PATCH v2 09/33] spapr: Clarify and fix handling of nr_irqs David Gibson
@ 2019-09-27  7:53   ` Greg Kurz
  2019-09-27  7:58     ` David Gibson
  0 siblings, 1 reply; 83+ messages in thread
From: Greg Kurz @ 2019-09-27  7:53 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

On Fri, 27 Sep 2019 15:50:04 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> Both the XICS and XIVE interrupt backends have a "nr-irqs" property, but
> it means slightly different things.  For XICS (or, strictly, the ICS) it
> indicates the number of "real" external IRQs.  Those start at XICS_IRQ_BASE
> (0x1000) and don't include the special IPI vector.  For XIVE, however, it
> includes the whole IRQ space, including XIVE's many IPI vectors.
> 
> The spapr code currently doesn't handle this sensibly, with the
> nr_irqs value in SpaprIrq having different meanings depending on the
> backend.  We fix this by renaming nr_irqs to nr_xirqs and making it
> always indicate just the number of external irqs, adjusting the value
> we pass to XIVE accordingly.  We also move to using common constants
> in most of the irq configurations, to make it clearer that the IRQ
> space looks the same to the guest (and emulated devices), even if the
> backend is different.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---

Cedric and I have already given an R-b for this one.

Reviewed-by: Greg Kurz <groug@kaod.org>

>  hw/ppc/spapr_irq.c         | 53 ++++++++++++++------------------------
>  include/hw/ppc/spapr_irq.h | 19 +++++++++-----
>  2 files changed, 31 insertions(+), 41 deletions(-)
> 
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index 8c26fa2d1e..3207b6bd01 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -92,7 +92,7 @@ static void spapr_irq_init_kvm(SpaprMachineState *spapr,
>   * XICS IRQ backend.
>   */
>  
> -static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_irqs,
> +static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_xirqs,
>                                  Error **errp)
>  {
>      Object *obj;
> @@ -102,7 +102,7 @@ static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_irqs,
>      object_property_add_child(OBJECT(spapr), "ics", obj, &error_abort);
>      object_property_add_const_link(obj, ICS_PROP_XICS, OBJECT(spapr),
>                                     &error_fatal);
> -    object_property_set_int(obj, nr_irqs, "nr-irqs",  &error_fatal);
> +    object_property_set_int(obj, nr_xirqs, "nr-irqs",  &error_fatal);
>      object_property_set_bool(obj, true, "realized", &local_err);
>      if (local_err) {
>          error_propagate(errp, local_err);
> @@ -234,13 +234,9 @@ static void spapr_irq_init_kvm_xics(SpaprMachineState *spapr, Error **errp)
>      }
>  }
>  
> -#define SPAPR_IRQ_XICS_NR_IRQS     0x1000
> -#define SPAPR_IRQ_XICS_NR_MSIS     \
> -    (XICS_IRQ_BASE + SPAPR_IRQ_XICS_NR_IRQS - SPAPR_IRQ_MSI)
> -
>  SpaprIrq spapr_irq_xics = {
> -    .nr_irqs     = SPAPR_IRQ_XICS_NR_IRQS,
> -    .nr_msis     = SPAPR_IRQ_XICS_NR_MSIS,
> +    .nr_xirqs    = SPAPR_NR_XIRQS,
> +    .nr_msis     = SPAPR_NR_MSIS,
>      .ov5         = SPAPR_OV5_XIVE_LEGACY,
>  
>      .init        = spapr_irq_init_xics,
> @@ -260,7 +256,7 @@ SpaprIrq spapr_irq_xics = {
>  /*
>   * XIVE IRQ backend.
>   */
> -static void spapr_irq_init_xive(SpaprMachineState *spapr, int nr_irqs,
> +static void spapr_irq_init_xive(SpaprMachineState *spapr, int nr_xirqs,
>                                  Error **errp)
>  {
>      uint32_t nr_servers = spapr_max_server_number(spapr);
> @@ -268,7 +264,7 @@ static void spapr_irq_init_xive(SpaprMachineState *spapr, int nr_irqs,
>      int i;
>  
>      dev = qdev_create(NULL, TYPE_SPAPR_XIVE);
> -    qdev_prop_set_uint32(dev, "nr-irqs", nr_irqs);
> +    qdev_prop_set_uint32(dev, "nr-irqs", nr_xirqs + SPAPR_XIRQ_BASE);
>      /*
>       * 8 XIVE END structures per CPU. One for each available priority
>       */
> @@ -308,7 +304,7 @@ static qemu_irq spapr_qirq_xive(SpaprMachineState *spapr, int irq)
>  {
>      SpaprXive *xive = spapr->xive;
>  
> -    if (irq >= xive->nr_irqs) {
> +    if ((irq < SPAPR_XIRQ_BASE) || (irq >= xive->nr_irqs)) {
>          return NULL;
>      }
>  
> @@ -404,17 +400,9 @@ static void spapr_irq_init_kvm_xive(SpaprMachineState *spapr, Error **errp)
>      }
>  }
>  
> -/*
> - * XIVE uses the full IRQ number space. Set it to 8K to be compatible
> - * with XICS.
> - */
> -
> -#define SPAPR_IRQ_XIVE_NR_IRQS     0x2000
> -#define SPAPR_IRQ_XIVE_NR_MSIS     (SPAPR_IRQ_XIVE_NR_IRQS - SPAPR_IRQ_MSI)
> -
>  SpaprIrq spapr_irq_xive = {
> -    .nr_irqs     = SPAPR_IRQ_XIVE_NR_IRQS,
> -    .nr_msis     = SPAPR_IRQ_XIVE_NR_MSIS,
> +    .nr_xirqs    = SPAPR_NR_XIRQS,
> +    .nr_msis     = SPAPR_NR_MSIS,
>      .ov5         = SPAPR_OV5_XIVE_EXPLOIT,
>  
>      .init        = spapr_irq_init_xive,
> @@ -450,18 +438,18 @@ static SpaprIrq *spapr_irq_current(SpaprMachineState *spapr)
>          &spapr_irq_xive : &spapr_irq_xics;
>  }
>  
> -static void spapr_irq_init_dual(SpaprMachineState *spapr, int nr_irqs,
> +static void spapr_irq_init_dual(SpaprMachineState *spapr, int nr_xirqs,
>                                  Error **errp)
>  {
>      Error *local_err = NULL;
>  
> -    spapr_irq_xics.init(spapr, spapr_irq_xics.nr_irqs, &local_err);
> +    spapr_irq_xics.init(spapr, spapr_irq_xics.nr_xirqs, &local_err);
>      if (local_err) {
>          error_propagate(errp, local_err);
>          return;
>      }
>  
> -    spapr_irq_xive.init(spapr, spapr_irq_xive.nr_irqs, &local_err);
> +    spapr_irq_xive.init(spapr, spapr_irq_xive.nr_xirqs, &local_err);
>      if (local_err) {
>          error_propagate(errp, local_err);
>          return;
> @@ -586,12 +574,9 @@ static const char *spapr_irq_get_nodename_dual(SpaprMachineState *spapr)
>  /*
>   * Define values in sync with the XIVE and XICS backend
>   */
> -#define SPAPR_IRQ_DUAL_NR_IRQS     0x2000
> -#define SPAPR_IRQ_DUAL_NR_MSIS     (SPAPR_IRQ_DUAL_NR_IRQS - SPAPR_IRQ_MSI)
> -
>  SpaprIrq spapr_irq_dual = {
> -    .nr_irqs     = SPAPR_IRQ_DUAL_NR_IRQS,
> -    .nr_msis     = SPAPR_IRQ_DUAL_NR_MSIS,
> +    .nr_xirqs    = SPAPR_NR_XIRQS,
> +    .nr_msis     = SPAPR_NR_MSIS,
>      .ov5         = SPAPR_OV5_XIVE_BOTH,
>  
>      .init        = spapr_irq_init_dual,
> @@ -693,10 +678,10 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>          spapr_irq_msi_init(spapr, spapr->irq->nr_msis);
>      }
>  
> -    spapr->irq->init(spapr, spapr->irq->nr_irqs, errp);
> +    spapr->irq->init(spapr, spapr->irq->nr_xirqs, errp);
>  
>      spapr->qirqs = qemu_allocate_irqs(spapr->irq->set_irq, spapr,
> -                                      spapr->irq->nr_irqs);
> +                                      spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
>  }
>  
>  int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
> @@ -804,11 +789,11 @@ int spapr_irq_find(SpaprMachineState *spapr, int num, bool align, Error **errp)
>      return first + ics->offset;
>  }
>  
> -#define SPAPR_IRQ_XICS_LEGACY_NR_IRQS     0x400
> +#define SPAPR_IRQ_XICS_LEGACY_NR_XIRQS     0x400
>  
>  SpaprIrq spapr_irq_xics_legacy = {
> -    .nr_irqs     = SPAPR_IRQ_XICS_LEGACY_NR_IRQS,
> -    .nr_msis     = SPAPR_IRQ_XICS_LEGACY_NR_IRQS,
> +    .nr_xirqs    = SPAPR_IRQ_XICS_LEGACY_NR_XIRQS,
> +    .nr_msis     = SPAPR_IRQ_XICS_LEGACY_NR_XIRQS,
>      .ov5         = SPAPR_OV5_XIVE_LEGACY,
>  
>      .init        = spapr_irq_init_xics,
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index 5db305165c..a8f9a2ab11 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -16,13 +16,18 @@
>   * IRQ range offsets per device type
>   */
>  #define SPAPR_IRQ_IPI        0x0
> -#define SPAPR_IRQ_EPOW       0x1000  /* XICS_IRQ_BASE offset */
> -#define SPAPR_IRQ_HOTPLUG    0x1001
> -#define SPAPR_IRQ_VIO        0x1100  /* 256 VIO devices */
> -#define SPAPR_IRQ_PCI_LSI    0x1200  /* 32+ PHBs devices */
>  
> -#define SPAPR_IRQ_MSI        0x1300  /* Offset of the dynamic range covered
> -                                      * by the bitmap allocator */
> +#define SPAPR_XIRQ_BASE      XICS_IRQ_BASE /* 0x1000 */
> +#define SPAPR_IRQ_EPOW       (SPAPR_XIRQ_BASE + 0x0000)
> +#define SPAPR_IRQ_HOTPLUG    (SPAPR_XIRQ_BASE + 0x0001)
> +#define SPAPR_IRQ_VIO        (SPAPR_XIRQ_BASE + 0x0100)  /* 256 VIO devices */
> +#define SPAPR_IRQ_PCI_LSI    (SPAPR_XIRQ_BASE + 0x0200)  /* 32+ PHBs devices */
> +
> +/* Offset of the dynamic range covered by the bitmap allocator */
> +#define SPAPR_IRQ_MSI        (SPAPR_XIRQ_BASE + 0x0300)
> +
> +#define SPAPR_NR_XIRQS       0x1000
> +#define SPAPR_NR_MSIS        (SPAPR_XIRQ_BASE + SPAPR_NR_XIRQS - SPAPR_IRQ_MSI)
>  
>  typedef struct SpaprMachineState SpaprMachineState;
>  
> @@ -32,7 +37,7 @@ int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align,
>  void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, uint32_t num);
>  
>  typedef struct SpaprIrq {
> -    uint32_t    nr_irqs;
> +    uint32_t    nr_xirqs;
>      uint32_t    nr_msis;
>      uint8_t     ov5;
>  



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

* Re: [PATCH v2 10/33] spapr: Eliminate nr_irqs parameter to SpaprIrq::init
  2019-09-27  5:50 ` [PATCH v2 10/33] spapr: Eliminate nr_irqs parameter to SpaprIrq::init David Gibson
@ 2019-09-27  7:57   ` Greg Kurz
  0 siblings, 0 replies; 83+ messages in thread
From: Greg Kurz @ 2019-09-27  7:57 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

On Fri, 27 Sep 2019 15:50:05 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> The only reason this parameter was needed was to work around the
> inconsistent meaning of nr_irqs between xics and xive.  Now that we've
> fixed that, we can consistently use the number directly in the SpaprIrq
> configuration.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> Reviewed-by: Cédric Le Goater <clg@kaod.org>
> ---

Again ;)

Reviewed-by: Greg Kurz <groug@kaod.org>

>  hw/ppc/spapr_irq.c         | 21 ++++++++++-----------
>  include/hw/ppc/spapr_irq.h |  2 +-
>  2 files changed, 11 insertions(+), 12 deletions(-)
> 
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index 3207b6bd01..cded3a0154 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -92,8 +92,7 @@ static void spapr_irq_init_kvm(SpaprMachineState *spapr,
>   * XICS IRQ backend.
>   */
>  
> -static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_xirqs,
> -                                Error **errp)
> +static void spapr_irq_init_xics(SpaprMachineState *spapr, Error **errp)
>  {
>      Object *obj;
>      Error *local_err = NULL;
> @@ -102,7 +101,8 @@ static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_xirqs,
>      object_property_add_child(OBJECT(spapr), "ics", obj, &error_abort);
>      object_property_add_const_link(obj, ICS_PROP_XICS, OBJECT(spapr),
>                                     &error_fatal);
> -    object_property_set_int(obj, nr_xirqs, "nr-irqs",  &error_fatal);
> +    object_property_set_int(obj, spapr->irq->nr_xirqs,
> +                            "nr-irqs",  &error_fatal);
>      object_property_set_bool(obj, true, "realized", &local_err);
>      if (local_err) {
>          error_propagate(errp, local_err);
> @@ -256,15 +256,15 @@ SpaprIrq spapr_irq_xics = {
>  /*
>   * XIVE IRQ backend.
>   */
> -static void spapr_irq_init_xive(SpaprMachineState *spapr, int nr_xirqs,
> -                                Error **errp)
> +static void spapr_irq_init_xive(SpaprMachineState *spapr, Error **errp)
>  {
>      uint32_t nr_servers = spapr_max_server_number(spapr);
>      DeviceState *dev;
>      int i;
>  
>      dev = qdev_create(NULL, TYPE_SPAPR_XIVE);
> -    qdev_prop_set_uint32(dev, "nr-irqs", nr_xirqs + SPAPR_XIRQ_BASE);
> +    qdev_prop_set_uint32(dev, "nr-irqs",
> +                         spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
>      /*
>       * 8 XIVE END structures per CPU. One for each available priority
>       */
> @@ -438,18 +438,17 @@ static SpaprIrq *spapr_irq_current(SpaprMachineState *spapr)
>          &spapr_irq_xive : &spapr_irq_xics;
>  }
>  
> -static void spapr_irq_init_dual(SpaprMachineState *spapr, int nr_xirqs,
> -                                Error **errp)
> +static void spapr_irq_init_dual(SpaprMachineState *spapr, Error **errp)
>  {
>      Error *local_err = NULL;
>  
> -    spapr_irq_xics.init(spapr, spapr_irq_xics.nr_xirqs, &local_err);
> +    spapr_irq_xics.init(spapr, &local_err);
>      if (local_err) {
>          error_propagate(errp, local_err);
>          return;
>      }
>  
> -    spapr_irq_xive.init(spapr, spapr_irq_xive.nr_xirqs, &local_err);
> +    spapr_irq_xive.init(spapr, &local_err);
>      if (local_err) {
>          error_propagate(errp, local_err);
>          return;
> @@ -678,7 +677,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>          spapr_irq_msi_init(spapr, spapr->irq->nr_msis);
>      }
>  
> -    spapr->irq->init(spapr, spapr->irq->nr_xirqs, errp);
> +    spapr->irq->init(spapr, errp);
>  
>      spapr->qirqs = qemu_allocate_irqs(spapr->irq->set_irq, spapr,
>                                        spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index a8f9a2ab11..7e26288fcd 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -41,7 +41,7 @@ typedef struct SpaprIrq {
>      uint32_t    nr_msis;
>      uint8_t     ov5;
>  
> -    void (*init)(SpaprMachineState *spapr, int nr_irqs, Error **errp);
> +    void (*init)(SpaprMachineState *spapr, Error **errp);
>      int (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
>      void (*free)(SpaprMachineState *spapr, int irq, int num);
>      qemu_irq (*qirq)(SpaprMachineState *spapr, int irq);



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

* Re: [PATCH v2 09/33] spapr: Clarify and fix handling of nr_irqs
  2019-09-27  7:53   ` Greg Kurz
@ 2019-09-27  7:58     ` David Gibson
  0 siblings, 0 replies; 83+ messages in thread
From: David Gibson @ 2019-09-27  7:58 UTC (permalink / raw)
  To: Greg Kurz
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

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

On Fri, Sep 27, 2019 at 09:53:59AM +0200, Greg Kurz wrote:
65;5603;1c> On Fri, 27 Sep 2019 15:50:04 +1000
> David Gibson <david@gibson.dropbear.id.au> wrote:
> 
> > Both the XICS and XIVE interrupt backends have a "nr-irqs" property, but
> > it means slightly different things.  For XICS (or, strictly, the ICS) it
> > indicates the number of "real" external IRQs.  Those start at XICS_IRQ_BASE
> > (0x1000) and don't include the special IPI vector.  For XIVE, however, it
> > includes the whole IRQ space, including XIVE's many IPI vectors.
> > 
> > The spapr code currently doesn't handle this sensibly, with the
> > nr_irqs value in SpaprIrq having different meanings depending on the
> > backend.  We fix this by renaming nr_irqs to nr_xirqs and making it
> > always indicate just the number of external irqs, adjusting the value
> > we pass to XIVE accordingly.  We also move to using common constants
> > in most of the irq configurations, to make it clearer that the IRQ
> > space looks the same to the guest (and emulated devices), even if the
> > backend is different.
> > 
> > Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> > ---
> 
> Cedric and I have already given an R-b for this one.

Oh, yeah, not sure how I dropped that one.

> Reviewed-by: Greg Kurz <groug@kaod.org>
> 
> >  hw/ppc/spapr_irq.c         | 53 ++++++++++++++------------------------
> >  include/hw/ppc/spapr_irq.h | 19 +++++++++-----
> >  2 files changed, 31 insertions(+), 41 deletions(-)
> > 
> > diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> > index 8c26fa2d1e..3207b6bd01 100644
> > --- a/hw/ppc/spapr_irq.c
> > +++ b/hw/ppc/spapr_irq.c
> > @@ -92,7 +92,7 @@ static void spapr_irq_init_kvm(SpaprMachineState *spapr,
> >   * XICS IRQ backend.
> >   */
> >  
> > -static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_irqs,
> > +static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_xirqs,
> >                                  Error **errp)
> >  {
> >      Object *obj;
> > @@ -102,7 +102,7 @@ static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_irqs,
> >      object_property_add_child(OBJECT(spapr), "ics", obj, &error_abort);
> >      object_property_add_const_link(obj, ICS_PROP_XICS, OBJECT(spapr),
> >                                     &error_fatal);
> > -    object_property_set_int(obj, nr_irqs, "nr-irqs",  &error_fatal);
> > +    object_property_set_int(obj, nr_xirqs, "nr-irqs",  &error_fatal);
> >      object_property_set_bool(obj, true, "realized", &local_err);
> >      if (local_err) {
> >          error_propagate(errp, local_err);
> > @@ -234,13 +234,9 @@ static void spapr_irq_init_kvm_xics(SpaprMachineState *spapr, Error **errp)
> >      }
> >  }
> >  
> > -#define SPAPR_IRQ_XICS_NR_IRQS     0x1000
> > -#define SPAPR_IRQ_XICS_NR_MSIS     \
> > -    (XICS_IRQ_BASE + SPAPR_IRQ_XICS_NR_IRQS - SPAPR_IRQ_MSI)
> > -
> >  SpaprIrq spapr_irq_xics = {
> > -    .nr_irqs     = SPAPR_IRQ_XICS_NR_IRQS,
> > -    .nr_msis     = SPAPR_IRQ_XICS_NR_MSIS,
> > +    .nr_xirqs    = SPAPR_NR_XIRQS,
> > +    .nr_msis     = SPAPR_NR_MSIS,
> >      .ov5         = SPAPR_OV5_XIVE_LEGACY,
> >  
> >      .init        = spapr_irq_init_xics,
> > @@ -260,7 +256,7 @@ SpaprIrq spapr_irq_xics = {
> >  /*
> >   * XIVE IRQ backend.
> >   */
> > -static void spapr_irq_init_xive(SpaprMachineState *spapr, int nr_irqs,
> > +static void spapr_irq_init_xive(SpaprMachineState *spapr, int nr_xirqs,
> >                                  Error **errp)
> >  {
> >      uint32_t nr_servers = spapr_max_server_number(spapr);
> > @@ -268,7 +264,7 @@ static void spapr_irq_init_xive(SpaprMachineState *spapr, int nr_irqs,
> >      int i;
> >  
> >      dev = qdev_create(NULL, TYPE_SPAPR_XIVE);
> > -    qdev_prop_set_uint32(dev, "nr-irqs", nr_irqs);
> > +    qdev_prop_set_uint32(dev, "nr-irqs", nr_xirqs + SPAPR_XIRQ_BASE);
> >      /*
> >       * 8 XIVE END structures per CPU. One for each available priority
> >       */
> > @@ -308,7 +304,7 @@ static qemu_irq spapr_qirq_xive(SpaprMachineState *spapr, int irq)
> >  {
> >      SpaprXive *xive = spapr->xive;
> >  
> > -    if (irq >= xive->nr_irqs) {
> > +    if ((irq < SPAPR_XIRQ_BASE) || (irq >= xive->nr_irqs)) {
> >          return NULL;
> >      }
> >  
> > @@ -404,17 +400,9 @@ static void spapr_irq_init_kvm_xive(SpaprMachineState *spapr, Error **errp)
> >      }
> >  }
> >  
> > -/*
> > - * XIVE uses the full IRQ number space. Set it to 8K to be compatible
> > - * with XICS.
> > - */
> > -
> > -#define SPAPR_IRQ_XIVE_NR_IRQS     0x2000
> > -#define SPAPR_IRQ_XIVE_NR_MSIS     (SPAPR_IRQ_XIVE_NR_IRQS - SPAPR_IRQ_MSI)
> > -
> >  SpaprIrq spapr_irq_xive = {
> > -    .nr_irqs     = SPAPR_IRQ_XIVE_NR_IRQS,
> > -    .nr_msis     = SPAPR_IRQ_XIVE_NR_MSIS,
> > +    .nr_xirqs    = SPAPR_NR_XIRQS,
> > +    .nr_msis     = SPAPR_NR_MSIS,
> >      .ov5         = SPAPR_OV5_XIVE_EXPLOIT,
> >  
> >      .init        = spapr_irq_init_xive,
> > @@ -450,18 +438,18 @@ static SpaprIrq *spapr_irq_current(SpaprMachineState *spapr)
> >          &spapr_irq_xive : &spapr_irq_xics;
> >  }
> >  
> > -static void spapr_irq_init_dual(SpaprMachineState *spapr, int nr_irqs,
> > +static void spapr_irq_init_dual(SpaprMachineState *spapr, int nr_xirqs,
> >                                  Error **errp)
> >  {
> >      Error *local_err = NULL;
> >  
> > -    spapr_irq_xics.init(spapr, spapr_irq_xics.nr_irqs, &local_err);
> > +    spapr_irq_xics.init(spapr, spapr_irq_xics.nr_xirqs, &local_err);
> >      if (local_err) {
> >          error_propagate(errp, local_err);
> >          return;
> >      }
> >  
> > -    spapr_irq_xive.init(spapr, spapr_irq_xive.nr_irqs, &local_err);
> > +    spapr_irq_xive.init(spapr, spapr_irq_xive.nr_xirqs, &local_err);
> >      if (local_err) {
> >          error_propagate(errp, local_err);
> >          return;
> > @@ -586,12 +574,9 @@ static const char *spapr_irq_get_nodename_dual(SpaprMachineState *spapr)
> >  /*
> >   * Define values in sync with the XIVE and XICS backend
> >   */
> > -#define SPAPR_IRQ_DUAL_NR_IRQS     0x2000
> > -#define SPAPR_IRQ_DUAL_NR_MSIS     (SPAPR_IRQ_DUAL_NR_IRQS - SPAPR_IRQ_MSI)
> > -
> >  SpaprIrq spapr_irq_dual = {
> > -    .nr_irqs     = SPAPR_IRQ_DUAL_NR_IRQS,
> > -    .nr_msis     = SPAPR_IRQ_DUAL_NR_MSIS,
> > +    .nr_xirqs    = SPAPR_NR_XIRQS,
> > +    .nr_msis     = SPAPR_NR_MSIS,
> >      .ov5         = SPAPR_OV5_XIVE_BOTH,
> >  
> >      .init        = spapr_irq_init_dual,
> > @@ -693,10 +678,10 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
> >          spapr_irq_msi_init(spapr, spapr->irq->nr_msis);
> >      }
> >  
> > -    spapr->irq->init(spapr, spapr->irq->nr_irqs, errp);
> > +    spapr->irq->init(spapr, spapr->irq->nr_xirqs, errp);
> >  
> >      spapr->qirqs = qemu_allocate_irqs(spapr->irq->set_irq, spapr,
> > -                                      spapr->irq->nr_irqs);
> > +                                      spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
> >  }
> >  
> >  int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
> > @@ -804,11 +789,11 @@ int spapr_irq_find(SpaprMachineState *spapr, int num, bool align, Error **errp)
> >      return first + ics->offset;
> >  }
> >  
> > -#define SPAPR_IRQ_XICS_LEGACY_NR_IRQS     0x400
> > +#define SPAPR_IRQ_XICS_LEGACY_NR_XIRQS     0x400
> >  
> >  SpaprIrq spapr_irq_xics_legacy = {
> > -    .nr_irqs     = SPAPR_IRQ_XICS_LEGACY_NR_IRQS,
> > -    .nr_msis     = SPAPR_IRQ_XICS_LEGACY_NR_IRQS,
> > +    .nr_xirqs    = SPAPR_IRQ_XICS_LEGACY_NR_XIRQS,
> > +    .nr_msis     = SPAPR_IRQ_XICS_LEGACY_NR_XIRQS,
> >      .ov5         = SPAPR_OV5_XIVE_LEGACY,
> >  
> >      .init        = spapr_irq_init_xics,
> > diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> > index 5db305165c..a8f9a2ab11 100644
> > --- a/include/hw/ppc/spapr_irq.h
> > +++ b/include/hw/ppc/spapr_irq.h
> > @@ -16,13 +16,18 @@
> >   * IRQ range offsets per device type
> >   */
> >  #define SPAPR_IRQ_IPI        0x0
> > -#define SPAPR_IRQ_EPOW       0x1000  /* XICS_IRQ_BASE offset */
> > -#define SPAPR_IRQ_HOTPLUG    0x1001
> > -#define SPAPR_IRQ_VIO        0x1100  /* 256 VIO devices */
> > -#define SPAPR_IRQ_PCI_LSI    0x1200  /* 32+ PHBs devices */
> >  
> > -#define SPAPR_IRQ_MSI        0x1300  /* Offset of the dynamic range covered
> > -                                      * by the bitmap allocator */
> > +#define SPAPR_XIRQ_BASE      XICS_IRQ_BASE /* 0x1000 */
> > +#define SPAPR_IRQ_EPOW       (SPAPR_XIRQ_BASE + 0x0000)
> > +#define SPAPR_IRQ_HOTPLUG    (SPAPR_XIRQ_BASE + 0x0001)
> > +#define SPAPR_IRQ_VIO        (SPAPR_XIRQ_BASE + 0x0100)  /* 256 VIO devices */
> > +#define SPAPR_IRQ_PCI_LSI    (SPAPR_XIRQ_BASE + 0x0200)  /* 32+ PHBs devices */
> > +
> > +/* Offset of the dynamic range covered by the bitmap allocator */
> > +#define SPAPR_IRQ_MSI        (SPAPR_XIRQ_BASE + 0x0300)
> > +
> > +#define SPAPR_NR_XIRQS       0x1000
> > +#define SPAPR_NR_MSIS        (SPAPR_XIRQ_BASE + SPAPR_NR_XIRQS - SPAPR_IRQ_MSI)
> >  
> >  typedef struct SpaprMachineState SpaprMachineState;
> >  
> > @@ -32,7 +37,7 @@ int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align,
> >  void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, uint32_t num);
> >  
> >  typedef struct SpaprIrq {
> > -    uint32_t    nr_irqs;
> > +    uint32_t    nr_xirqs;
> >      uint32_t    nr_msis;
> >      uint8_t     ov5;
> >  
> 

-- 
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] 83+ messages in thread

* Re: [PATCH v2 17/33] xive: Improve irq claim/free path
  2019-09-27  5:50 ` [PATCH v2 17/33] xive: Improve irq claim/free path David Gibson
@ 2019-09-27  8:40   ` Greg Kurz
  2019-09-30  1:39     ` David Gibson
  0 siblings, 1 reply; 83+ messages in thread
From: Greg Kurz @ 2019-09-27  8:40 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

On Fri, 27 Sep 2019 15:50:12 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> spapr_xive_irq_claim() returns a bool to indicate if it succeeded.
> But most of the callers and one callee use int return values and/or an
> Error * with more information instead.  In any case, ints are a more
> common idiom for success/failure states than bools (one never knows
> what sense they'll be in).
> 
> So instead change to an int return value to indicate presence of error
> + an Error * to describe the details through that call chain.
> 
> It also didn't actually check if the irq was already claimed, which is
> one of the primary purposes of the claim path, so do that.
> 
> spapr_xive_irq_free() also returned a bool... which no callers checked
> and was always true, so just drop it.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> Reviewed-by: Cédric Le Goater <clg@kaod.org>
> ---
>  hw/intc/spapr_xive.c        | 20 +++++++++-----------
>  hw/intc/spapr_xive_kvm.c    |  8 ++++----
>  hw/ppc/spapr_irq.c          | 14 ++++++++------
>  include/hw/ppc/spapr_xive.h |  4 ++--
>  include/hw/ppc/xive.h       |  2 +-
>  5 files changed, 24 insertions(+), 24 deletions(-)
> 
> diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
> index 47b5ec0b56..04879abf2e 100644
> --- a/hw/intc/spapr_xive.c
> +++ b/hw/intc/spapr_xive.c
> @@ -528,12 +528,17 @@ static void spapr_xive_register_types(void)
>  
>  type_init(spapr_xive_register_types)
>  
> -bool spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi)
> +int spapr_xive_irq_claim(SpaprXive *xive, int lisn, bool lsi, Error **errp)
>  {
>      XiveSource *xsrc = &xive->source;
>  
>      assert(lisn < xive->nr_irqs);
>  
> +    if (xive_eas_is_valid(&xive->eat[lisn])) {
> +        error_setg(errp, "IRQ %d is not free", lisn);
> +        return -EBUSY;
> +    }
> +
>      /*
>       * Set default values when allocating an IRQ number
>       */
> @@ -543,24 +548,17 @@ bool spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi)
>      }
>  
>      if (kvm_irqchip_in_kernel()) {
> -        Error *local_err = NULL;
> -
> -        kvmppc_xive_source_reset_one(xsrc, lisn, &local_err);
> -        if (local_err) {
> -            error_report_err(local_err);
> -            return false;
> -        }
> +        return kvmppc_xive_source_reset_one(xsrc, lisn, errp);
>      }
>  
> -    return true;
> +    return 0;
>  }
>  
> -bool spapr_xive_irq_free(SpaprXive *xive, uint32_t lisn)
> +void spapr_xive_irq_free(SpaprXive *xive, int lisn)
>  {
>      assert(lisn < xive->nr_irqs);
>  
>      xive->eat[lisn].w &= cpu_to_be64(~EAS_VALID);
> -    return true;
>  }
>  
>  /*
> diff --git a/hw/intc/spapr_xive_kvm.c b/hw/intc/spapr_xive_kvm.c
> index 2006f96aec..51b334b676 100644
> --- a/hw/intc/spapr_xive_kvm.c
> +++ b/hw/intc/spapr_xive_kvm.c
> @@ -232,14 +232,14 @@ void kvmppc_xive_sync_source(SpaprXive *xive, uint32_t lisn, Error **errp)
>   * only need to inform the KVM XIVE device about their type: LSI or
>   * MSI.
>   */
> -void kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **errp)
> +int kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **errp)
>  {
>      SpaprXive *xive = SPAPR_XIVE(xsrc->xive);
>      uint64_t state = 0;
>  
>      /* The KVM XIVE device is not in use */
>      if (xive->fd == -1) {
> -        return;
> +        return -ENODEV;
>      }
>  
>      if (xive_source_irq_is_lsi(xsrc, srcno)) {
> @@ -249,8 +249,8 @@ void kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **errp)
>          }
>      }
>  
> -    kvm_device_access(xive->fd, KVM_DEV_XIVE_GRP_SOURCE, srcno, &state,
> -                      true, errp);
> +    return kvm_device_access(xive->fd, KVM_DEV_XIVE_GRP_SOURCE, srcno, &state,
> +                             true, errp);
>  }
>  
>  static void kvmppc_xive_source_reset(XiveSource *xsrc, Error **errp)
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index da9e80b24e..4951329959 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -246,7 +246,13 @@ static void spapr_irq_init_xive(SpaprMachineState *spapr, Error **errp)
>  
>      /* Enable the CPU IPIs */
>      for (i = 0; i < nr_servers; ++i) {
> -        spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i, false);
> +        Error *local_err = NULL;
> +
> +        spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i, false, &local_err);
> +        if (local_err) {
> +            error_propagate(errp, local_err);
> +            return;
> +        }

Quoting the changelog

> So instead change to an int return value to indicate presence of error
> + an Error * to describe the details through that call chain.

Shouldn't this rather be:

        if (spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i, false, errp)) {
            return;
        }

?

With or without that fixed,

Reviewed-by: Greg Kurz <groug@kaod.org>

>      }
>  
>      spapr_xive_hcall_init(spapr);
> @@ -255,11 +261,7 @@ static void spapr_irq_init_xive(SpaprMachineState *spapr, Error **errp)
>  static int spapr_irq_claim_xive(SpaprMachineState *spapr, int irq, bool lsi,
>                                  Error **errp)
>  {
> -    if (!spapr_xive_irq_claim(spapr->xive, irq, lsi)) {
> -        error_setg(errp, "IRQ %d is invalid", irq);
> -        return -1;
> -    }
> -    return 0;
> +    return spapr_xive_irq_claim(spapr->xive, irq, lsi, errp);
>  }
>  
>  static void spapr_irq_free_xive(SpaprMachineState *spapr, int irq)
> diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h
> index bfd40f01d8..0df20a6590 100644
> --- a/include/hw/ppc/spapr_xive.h
> +++ b/include/hw/ppc/spapr_xive.h
> @@ -54,8 +54,8 @@ typedef struct SpaprXive {
>   */
>  #define SPAPR_XIVE_BLOCK_ID 0x0
>  
> -bool spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi);
> -bool spapr_xive_irq_free(SpaprXive *xive, uint32_t lisn);
> +int spapr_xive_irq_claim(SpaprXive *xive, int lisn, bool lsi, Error **errp);
> +void spapr_xive_irq_free(SpaprXive *xive, int lisn);
>  void spapr_xive_pic_print_info(SpaprXive *xive, Monitor *mon);
>  int spapr_xive_post_load(SpaprXive *xive, int version_id);
>  
> diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
> index 6d38755f84..fd3319bd32 100644
> --- a/include/hw/ppc/xive.h
> +++ b/include/hw/ppc/xive.h
> @@ -425,7 +425,7 @@ static inline uint32_t xive_nvt_cam_line(uint8_t nvt_blk, uint32_t nvt_idx)
>   * KVM XIVE device helpers
>   */
>  
> -void kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **errp);
> +int kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **errp);
>  void kvmppc_xive_source_set_irq(void *opaque, int srcno, int val);
>  void kvmppc_xive_cpu_connect(XiveTCTX *tctx, Error **errp);
>  void kvmppc_xive_cpu_synchronize_state(XiveTCTX *tctx, Error **errp);



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

* Re: [PATCH v2 20/33] spapr, xics, xive: Introduce SpaprInterruptController QOM interface
  2019-09-27  5:50 ` [PATCH v2 20/33] spapr, xics, xive: Introduce SpaprInterruptController QOM interface David Gibson
@ 2019-09-27  9:52   ` Greg Kurz
  2019-09-30  5:24   ` Cédric Le Goater
  1 sibling, 0 replies; 83+ messages in thread
From: Greg Kurz @ 2019-09-27  9:52 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

On Fri, 27 Sep 2019 15:50:15 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> The SpaprIrq structure is used to represent ths spapr machine's irq
> backend.  Except that it kind of conflates two concepts: one is the
> backend proper - a specific interrupt controller that we might or
> might not be using, the other is the irq configuration which covers
> the layout of irq space and which interrupt controllers are allowed.
> 
> This leads to some pretty confusing code paths for the "dual"
> configuration where its hooks redirect to other SpaprIrq structures
> depending on the currently active irq controller.
> 
> To clean this up, we start by introducing a new
> SpaprInterruptController QOM interface to represent strictly an
> interrupt controller backend, not counting anything configuration
> related.  We implement this interface in the XICs and XIVE interrupt
> controllers, and in future we'll move relevant methods from SpaprIrq
> into it.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---

Reviewed-by: Greg Kurz <groug@kaod.org>

>  hw/intc/spapr_xive.c       |  4 ++++
>  hw/intc/xics_spapr.c       |  4 ++++
>  hw/ppc/spapr_irq.c         | 13 +++++++++++++
>  include/hw/ppc/spapr_irq.h | 14 ++++++++++++++
>  4 files changed, 35 insertions(+)
> 
> diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
> index 04879abf2e..b67e9c3245 100644
> --- a/hw/intc/spapr_xive.c
> +++ b/hw/intc/spapr_xive.c
> @@ -519,6 +519,10 @@ static const TypeInfo spapr_xive_info = {
>      .instance_init = spapr_xive_instance_init,
>      .instance_size = sizeof(SpaprXive),
>      .class_init = spapr_xive_class_init,
> +    .interfaces = (InterfaceInfo[]) {
> +        { TYPE_SPAPR_INTC },
> +        { }
> +    },
>  };
>  
>  static void spapr_xive_register_types(void)
> diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
> index 6e5eb24b3c..4874e6be55 100644
> --- a/hw/intc/xics_spapr.c
> +++ b/hw/intc/xics_spapr.c
> @@ -343,6 +343,10 @@ static const TypeInfo ics_spapr_info = {
>      .name = TYPE_ICS_SPAPR,
>      .parent = TYPE_ICS,
>      .class_init = ics_spapr_class_init,
> +    .interfaces = (InterfaceInfo[]) {
> +        { TYPE_SPAPR_INTC },
> +        { }
> +    },
>  };
>  
>  static void xics_spapr_register_types(void)
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index 5e448b1fd4..0603c82fe8 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -23,6 +23,12 @@
>  
>  #include "trace.h"
>  
> +static const TypeInfo spapr_intc_info = {
> +    .name = TYPE_SPAPR_INTC,
> +    .parent = TYPE_INTERFACE,
> +    .class_size = sizeof(SpaprInterruptControllerClass),
> +};
> +
>  void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis)
>  {
>      spapr->irq_map_nr = nr_msis;
> @@ -763,3 +769,10 @@ SpaprIrq spapr_irq_xics_legacy = {
>      .set_irq     = spapr_irq_set_irq_xics,
>      .init_kvm    = spapr_irq_init_kvm_xics,
>  };
> +
> +static void spapr_irq_register_types(void)
> +{
> +    type_register_static(&spapr_intc_info);
> +}
> +
> +type_init(spapr_irq_register_types)
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index 69a37f608e..b9398e0be3 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -31,6 +31,20 @@
>  
>  typedef struct SpaprMachineState SpaprMachineState;
>  
> +typedef struct SpaprInterruptController SpaprInterruptController;
> +
> +#define TYPE_SPAPR_INTC "spapr-interrupt-controller"
> +#define SPAPR_INTC(obj)                                     \
> +    INTERFACE_CHECK(SpaprInterruptController, (obj), TYPE_SPAPR_INTC)
> +#define SPAPR_INTC_CLASS(klass)                                     \
> +    OBJECT_CLASS_CHECK(SpaprInterruptControllerClass, (klass), TYPE_SPAPR_INTC)
> +#define SPAPR_INTC_GET_CLASS(obj)                                   \
> +    OBJECT_GET_CLASS(SpaprInterruptControllerClass, (obj), TYPE_SPAPR_INTC)
> +
> +typedef struct SpaprInterruptControllerClass {
> +    InterfaceClass parent;
> +} SpaprInterruptControllerClass;
> +
>  void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis);
>  int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align,
>                          Error **errp);



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

* Re: [PATCH v2 21/33] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController
  2019-09-27  5:50 ` [PATCH v2 21/33] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController David Gibson
@ 2019-09-27 10:16   ` Greg Kurz
  2019-09-30  1:49     ` David Gibson
  2019-09-30  2:37     ` David Gibson
  2019-09-30  5:30   ` Cédric Le Goater
  1 sibling, 2 replies; 83+ messages in thread
From: Greg Kurz @ 2019-09-27 10:16 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

On Fri, 27 Sep 2019 15:50:16 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> This method essentially represents code which belongs to the interrupt
> controller, but needs to be called on all possible intcs, rather than
> just the currently active one.  The "dual" version therefore calls
> into the xics and xive versions confusingly.
> 
> Handle this more directly, by making it instead a method on the intc
> backend, and always calling it on every backend that exists.
> 
> While we're there, streamline the error reporting a bit.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---
>  hw/intc/spapr_xive.c       | 25 ++++++++++++
>  hw/intc/xics_spapr.c       | 18 +++++++++
>  hw/ppc/spapr_cpu_core.c    |  3 +-
>  hw/ppc/spapr_irq.c         | 81 +++++++++++---------------------------
>  include/hw/ppc/spapr_irq.h | 16 +++++++-
>  5 files changed, 82 insertions(+), 61 deletions(-)
> 
> diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
> index b67e9c3245..9338daba3d 100644
> --- a/hw/intc/spapr_xive.c
> +++ b/hw/intc/spapr_xive.c
> @@ -495,10 +495,33 @@ static Property spapr_xive_properties[] = {
>      DEFINE_PROP_END_OF_LIST(),
>  };
>  
> +static int spapr_xive_cpu_intc_create(SpaprInterruptController *intc,
> +                                      PowerPCCPU *cpu, Error **errp)
> +{
> +    SpaprXive *xive = SPAPR_XIVE(intc);
> +    Object *obj;
> +    SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
> +
> +    obj = xive_tctx_create(OBJECT(cpu), XIVE_ROUTER(xive), errp);
> +    if (!obj) {
> +        return -1;
> +    }
> +
> +    spapr_cpu->tctx = XIVE_TCTX(obj);
> +
> +    /*
> +     * (TCG) Early setting the OS CAM line for hotplugged CPUs as they
> +     * don't beneficiate from the reset of the XIVE IRQ backend
> +     */
> +    spapr_xive_set_tctx_os_cam(spapr_cpu->tctx);
> +    return 0;
> +}
> +
>  static void spapr_xive_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
>      XiveRouterClass *xrc = XIVE_ROUTER_CLASS(klass);
> +    SpaprInterruptControllerClass *sicc = SPAPR_INTC_CLASS(klass);
>  
>      dc->desc    = "sPAPR XIVE Interrupt Controller";
>      dc->props   = spapr_xive_properties;
> @@ -511,6 +534,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;
> +
> +    sicc->cpu_intc_create = spapr_xive_cpu_intc_create;
>  }
>  
>  static const TypeInfo spapr_xive_info = {
> diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
> index 4874e6be55..946311b858 100644
> --- a/hw/intc/xics_spapr.c
> +++ b/hw/intc/xics_spapr.c
> @@ -330,13 +330,31 @@ void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
>      _FDT(fdt_setprop_cell(fdt, node, "phandle", phandle));
>  }
>  
> +static int xics_spapr_cpu_intc_create(SpaprInterruptController *intc,
> +                                       PowerPCCPU *cpu, Error **errp)
> +{
> +    ICSState *ics = ICS_SPAPR(intc);
> +    Object *obj;
> +    SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
> +
> +    obj = icp_create(OBJECT(cpu), TYPE_ICP, ics->xics, errp);
> +    if (!obj) {
> +        return -1;
> +    }
> +
> +    spapr_cpu->icp = ICP(obj);
> +    return 0;
> +}
> +
>  static void ics_spapr_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
>      ICSStateClass *isc = ICS_CLASS(klass);
> +    SpaprInterruptControllerClass *sicc = SPAPR_INTC_CLASS(klass);
>  
>      device_class_set_parent_realize(dc, ics_spapr_realize,
>                                      &isc->parent_realize);
> +    sicc->cpu_intc_create = xics_spapr_cpu_intc_create;
>  }
>  
>  static const TypeInfo ics_spapr_info = {
> diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
> index 1d93de8161..3e4302c7d5 100644
> --- a/hw/ppc/spapr_cpu_core.c
> +++ b/hw/ppc/spapr_cpu_core.c
> @@ -237,8 +237,7 @@ static void spapr_realize_vcpu(PowerPCCPU *cpu, SpaprMachineState *spapr,
>      qemu_register_reset(spapr_cpu_reset, cpu);
>      spapr_cpu_reset(cpu);
>  
> -    spapr->irq->cpu_intc_create(spapr, cpu, &local_err);
> -    if (local_err) {
> +    if (spapr_irq_cpu_intc_create(spapr, cpu, &local_err) < 0) {
>          goto error_unregister;
>      }
>  
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index 0603c82fe8..a855dfe4e9 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -138,23 +138,6 @@ static void spapr_irq_print_info_xics(SpaprMachineState *spapr, Monitor *mon)
>      ics_pic_print_info(spapr->ics, mon);
>  }
>  
> -static void spapr_irq_cpu_intc_create_xics(SpaprMachineState *spapr,
> -                                           PowerPCCPU *cpu, Error **errp)
> -{
> -    Error *local_err = NULL;
> -    Object *obj;
> -    SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
> -
> -    obj = icp_create(OBJECT(cpu), TYPE_ICP, XICS_FABRIC(spapr),
> -                     &local_err);
> -    if (local_err) {
> -        error_propagate(errp, local_err);
> -        return;
> -    }
> -
> -    spapr_cpu->icp = ICP(obj);
> -}
> -
>  static int spapr_irq_post_load_xics(SpaprMachineState *spapr, int version_id)
>  {
>      if (!kvm_irqchip_in_kernel()) {
> @@ -203,7 +186,6 @@ SpaprIrq spapr_irq_xics = {
>      .free        = spapr_irq_free_xics,
>      .print_info  = spapr_irq_print_info_xics,
>      .dt_populate = spapr_dt_xics,
> -    .cpu_intc_create = spapr_irq_cpu_intc_create_xics,
>      .post_load   = spapr_irq_post_load_xics,
>      .reset       = spapr_irq_reset_xics,
>      .set_irq     = spapr_irq_set_irq_xics,
> @@ -239,28 +221,6 @@ static void spapr_irq_print_info_xive(SpaprMachineState *spapr,
>      spapr_xive_pic_print_info(spapr->xive, mon);
>  }
>  
> -static void spapr_irq_cpu_intc_create_xive(SpaprMachineState *spapr,
> -                                           PowerPCCPU *cpu, Error **errp)
> -{
> -    Error *local_err = NULL;
> -    Object *obj;
> -    SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
> -
> -    obj = xive_tctx_create(OBJECT(cpu), XIVE_ROUTER(spapr->xive), &local_err);
> -    if (local_err) {
> -        error_propagate(errp, local_err);
> -        return;
> -    }
> -
> -    spapr_cpu->tctx = XIVE_TCTX(obj);
> -
> -    /*
> -     * (TCG) Early setting the OS CAM line for hotplugged CPUs as they
> -     * don't beneficiate from the reset of the XIVE IRQ backend
> -     */
> -    spapr_xive_set_tctx_os_cam(spapr_cpu->tctx);
> -}
> -
>  static int spapr_irq_post_load_xive(SpaprMachineState *spapr, int version_id)
>  {
>      return spapr_xive_post_load(spapr->xive, version_id);
> @@ -316,7 +276,6 @@ SpaprIrq spapr_irq_xive = {
>      .free        = spapr_irq_free_xive,
>      .print_info  = spapr_irq_print_info_xive,
>      .dt_populate = spapr_dt_xive,
> -    .cpu_intc_create = spapr_irq_cpu_intc_create_xive,
>      .post_load   = spapr_irq_post_load_xive,
>      .reset       = spapr_irq_reset_xive,
>      .set_irq     = spapr_irq_set_irq_xive,
> @@ -381,20 +340,6 @@ static void spapr_irq_dt_populate_dual(SpaprMachineState *spapr,
>      spapr_irq_current(spapr)->dt_populate(spapr, nr_servers, fdt, phandle);
>  }
>  
> -static void spapr_irq_cpu_intc_create_dual(SpaprMachineState *spapr,
> -                                           PowerPCCPU *cpu, Error **errp)
> -{
> -    Error *local_err = NULL;
> -
> -    spapr_irq_xive.cpu_intc_create(spapr, cpu, &local_err);
> -    if (local_err) {
> -        error_propagate(errp, local_err);
> -        return;
> -    }
> -
> -    spapr_irq_xics.cpu_intc_create(spapr, cpu, errp);
> -}
> -
>  static int spapr_irq_post_load_dual(SpaprMachineState *spapr, int version_id)
>  {
>      /*
> @@ -460,7 +405,6 @@ SpaprIrq spapr_irq_dual = {
>      .free        = spapr_irq_free_dual,
>      .print_info  = spapr_irq_print_info_dual,
>      .dt_populate = spapr_irq_dt_populate_dual,
> -    .cpu_intc_create = spapr_irq_cpu_intc_create_dual,
>      .post_load   = spapr_irq_post_load_dual,
>      .reset       = spapr_irq_reset_dual,
>      .set_irq     = spapr_irq_set_irq_dual,
> @@ -525,6 +469,30 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
>  /*
>   * sPAPR IRQ frontend routines for devices
>   */
> +int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
> +                              PowerPCCPU *cpu, Error **errp)
> +{
> +    if (spapr->xive) {
> +        SpaprInterruptController *intc = SPAPR_INTC(spapr->xive);
> +        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
> +
> +        if (sicc->cpu_intc_create(intc, cpu, errp) < 0) {
> +            return -1;
> +        }
> +    }
> +
> +    if (spapr->ics) {
> +        SpaprInterruptController *intc = SPAPR_INTC(spapr->ics);
> +        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
> +
> +        if (sicc->cpu_intc_create(intc, cpu, errp) < 0) {
> +            return -1;
> +        }
> +    }
> +

Instead of these hooks, what about open-coding spapr_xive_cpu_intc_create()
and xics_spapr_cpu_intc_create() directly here, like you already did for the
ICS and the XIVE objects in spapr_irq_init() ?

> +    return 0;
> +}
> +
>  void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>  {
>      MachineState *machine = MACHINE(spapr);
> @@ -763,7 +731,6 @@ SpaprIrq spapr_irq_xics_legacy = {
>      .free        = spapr_irq_free_xics,
>      .print_info  = spapr_irq_print_info_xics,
>      .dt_populate = spapr_dt_xics,
> -    .cpu_intc_create = spapr_irq_cpu_intc_create_xics,
>      .post_load   = spapr_irq_post_load_xics,
>      .reset       = spapr_irq_reset_xics,
>      .set_irq     = spapr_irq_set_irq_xics,
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index b9398e0be3..30d660ff1e 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -43,8 +43,22 @@ typedef struct SpaprInterruptController SpaprInterruptController;
>  
>  typedef struct SpaprInterruptControllerClass {
>      InterfaceClass parent;
> +
> +    /*
> +     * These methods will typically be called on all intcs, active and
> +     * inactive
> +     */
> +    int (*cpu_intc_create)(SpaprInterruptController *intc,
> +                            PowerPCCPU *cpu, Error **errp);
>  } SpaprInterruptControllerClass;
>  
> +void spapr_irq_print_info(SpaprMachineState *spapr, Monitor *mon);
> +void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers,
> +                  void *fdt, uint32_t phandle);

These two ^^ seem to belong to later patches.

> +int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
> +                              PowerPCCPU *cpu, Error **errp);
> +
> +
>  void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis);
>  int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align,
>                          Error **errp);
> @@ -61,8 +75,6 @@ typedef struct SpaprIrq {
>      void (*print_info)(SpaprMachineState *spapr, Monitor *mon);
>      void (*dt_populate)(SpaprMachineState *spapr, uint32_t nr_servers,
>                          void *fdt, uint32_t phandle);
> -    void (*cpu_intc_create)(SpaprMachineState *spapr, PowerPCCPU *cpu,
> -                            Error **errp);
>      int (*post_load)(SpaprMachineState *spapr, int version_id);
>      void (*reset)(SpaprMachineState *spapr, Error **errp);
>      void (*set_irq)(void *opaque, int srcno, int val);



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

* Re: [PATCH v2 22/33] spapr, xics, xive: Move irq claim and free from SpaprIrq to SpaprInterruptController
  2019-09-27  5:50 ` [PATCH v2 22/33] spapr, xics, xive: Move irq claim and free " David Gibson
@ 2019-09-27 12:16   ` Greg Kurz
  2019-09-30  2:39     ` David Gibson
  2019-09-30  5:33   ` Cédric Le Goater
  1 sibling, 1 reply; 83+ messages in thread
From: Greg Kurz @ 2019-09-27 12:16 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

On Fri, 27 Sep 2019 15:50:17 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> These methods, like cpu_intc_create, really belong to the interrupt
> controller, but need to be called on all possible intcs.
> 
> Like cpu_intc_create, therefore, make them methods on the intc and
> always call it for all existing intcs.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---
>  hw/intc/spapr_xive.c        |  71 +++++++++++-----------
>  hw/intc/xics_spapr.c        |  29 +++++++++
>  hw/ppc/spapr_irq.c          | 114 ++++++++++++------------------------
>  include/hw/ppc/spapr_irq.h  |   5 +-
>  include/hw/ppc/spapr_xive.h |   2 -
>  5 files changed, 107 insertions(+), 114 deletions(-)
> 
> diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
> index 9338daba3d..ff1a175b44 100644
> --- a/hw/intc/spapr_xive.c
> +++ b/hw/intc/spapr_xive.c
> @@ -487,6 +487,42 @@ static const VMStateDescription vmstate_spapr_xive = {
>      },
>  };
>  
> +static int spapr_xive_claim_irq(SpaprInterruptController *intc, int lisn,
> +                                bool lsi, Error **errp)
> +{
> +    SpaprXive *xive = SPAPR_XIVE(intc);
> +    XiveSource *xsrc = &xive->source;
> +
> +    assert(lisn < xive->nr_irqs);
> +
> +    if (xive_eas_is_valid(&xive->eat[lisn])) {
> +        error_setg(errp, "IRQ %d is not free", lisn);
> +        return -EBUSY;
> +    }
> +
> +    /*
> +     * Set default values when allocating an IRQ number
> +     */
> +    xive->eat[lisn].w |= cpu_to_be64(EAS_VALID | EAS_MASKED);
> +    if (lsi) {
> +        xive_source_irq_set_lsi(xsrc, lisn);
> +    }
> +
> +    if (kvm_irqchip_in_kernel()) {
> +        return kvmppc_xive_source_reset_one(xsrc, lisn, errp);
> +    }
> +
> +    return 0;
> +}
> +
> +static void spapr_xive_free_irq(SpaprInterruptController *intc, int lisn)
> +{
> +    SpaprXive *xive = SPAPR_XIVE(intc);
> +    assert(lisn < xive->nr_irqs);
> +
> +    xive->eat[lisn].w &= cpu_to_be64(~EAS_VALID);
> +}
> +
>  static Property spapr_xive_properties[] = {
>      DEFINE_PROP_UINT32("nr-irqs", SpaprXive, nr_irqs, 0),
>      DEFINE_PROP_UINT32("nr-ends", SpaprXive, nr_ends, 0),
> @@ -536,6 +572,8 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data)
>      xrc->get_tctx = spapr_xive_get_tctx;
>  
>      sicc->cpu_intc_create = spapr_xive_cpu_intc_create;
> +    sicc->claim_irq = spapr_xive_claim_irq;
> +    sicc->free_irq = spapr_xive_free_irq;
>  }
>  
>  static const TypeInfo spapr_xive_info = {
> @@ -557,39 +595,6 @@ static void spapr_xive_register_types(void)
>  
>  type_init(spapr_xive_register_types)
>  
> -int spapr_xive_irq_claim(SpaprXive *xive, int lisn, bool lsi, Error **errp)
> -{
> -    XiveSource *xsrc = &xive->source;
> -
> -    assert(lisn < xive->nr_irqs);
> -
> -    if (xive_eas_is_valid(&xive->eat[lisn])) {
> -        error_setg(errp, "IRQ %d is not free", lisn);
> -        return -EBUSY;
> -    }
> -
> -    /*
> -     * Set default values when allocating an IRQ number
> -     */
> -    xive->eat[lisn].w |= cpu_to_be64(EAS_VALID | EAS_MASKED);
> -    if (lsi) {
> -        xive_source_irq_set_lsi(xsrc, lisn);
> -    }
> -
> -    if (kvm_irqchip_in_kernel()) {
> -        return kvmppc_xive_source_reset_one(xsrc, lisn, errp);
> -    }
> -
> -    return 0;
> -}
> -
> -void spapr_xive_irq_free(SpaprXive *xive, int lisn)
> -{
> -    assert(lisn < xive->nr_irqs);
> -
> -    xive->eat[lisn].w &= cpu_to_be64(~EAS_VALID);
> -}
> -
>  /*
>   * XIVE hcalls
>   *
> diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
> index 946311b858..224fe1efcd 100644
> --- a/hw/intc/xics_spapr.c
> +++ b/hw/intc/xics_spapr.c
> @@ -346,6 +346,33 @@ static int xics_spapr_cpu_intc_create(SpaprInterruptController *intc,
>      return 0;
>  }
>  
> +static int xics_spapr_claim_irq(SpaprInterruptController *intc, int irq,
> +                                bool lsi, Error **errp)
> +{
> +    ICSState *ics = ICS_SPAPR(intc);
> +
> +    assert(ics);
> +    assert(ics_valid_irq(ics, irq));
> +
> +    if (!ics_irq_free(ics, irq - ics->offset)) {
> +        error_setg(errp, "IRQ %d is not free", irq);
> +        return -EBUSY;
> +    }
> +
> +    ics_set_irq_type(ics, irq - ics->offset, lsi);
> +    return 0;
> +}
> +
> +static void xics_spapr_free_irq(SpaprInterruptController *intc, int irq)
> +{
> +    ICSState *ics = ICS_SPAPR(intc);
> +    uint32_t srcno = irq - ics->offset;
> +
> +    assert(ics_valid_irq(ics, irq));
> +
> +    memset(&ics->irqs[srcno], 0, sizeof(ICSIRQState));
> +}
> +
>  static void ics_spapr_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
> @@ -355,6 +382,8 @@ static void ics_spapr_class_init(ObjectClass *klass, void *data)
>      device_class_set_parent_realize(dc, ics_spapr_realize,
>                                      &isc->parent_realize);
>      sicc->cpu_intc_create = xics_spapr_cpu_intc_create;
> +    sicc->claim_irq = xics_spapr_claim_irq;
> +    sicc->free_irq = xics_spapr_free_irq;
>  }
>  
>  static const TypeInfo ics_spapr_info = {
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index a855dfe4e9..ea44378d8c 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -98,33 +98,6 @@ static void spapr_irq_init_kvm(SpaprMachineState *spapr,
>   * XICS IRQ backend.
>   */
>  
> -static int spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
> -                                Error **errp)
> -{
> -    ICSState *ics = spapr->ics;
> -
> -    assert(ics);
> -    assert(ics_valid_irq(ics, irq));
> -
> -    if (!ics_irq_free(ics, irq - ics->offset)) {
> -        error_setg(errp, "IRQ %d is not free", irq);
> -        return -1;
> -    }
> -
> -    ics_set_irq_type(ics, irq - ics->offset, lsi);
> -    return 0;
> -}
> -
> -static void spapr_irq_free_xics(SpaprMachineState *spapr, int irq)
> -{
> -    ICSState *ics = spapr->ics;
> -    uint32_t srcno = irq - ics->offset;
> -
> -    assert(ics_valid_irq(ics, irq));
> -
> -    memset(&ics->irqs[srcno], 0, sizeof(ICSIRQState));
> -}
> -
>  static void spapr_irq_print_info_xics(SpaprMachineState *spapr, Monitor *mon)
>  {
>      CPUState *cs;
> @@ -182,8 +155,6 @@ SpaprIrq spapr_irq_xics = {
>      .xics        = true,
>      .xive        = false,
>  
> -    .claim       = spapr_irq_claim_xics,
> -    .free        = spapr_irq_free_xics,
>      .print_info  = spapr_irq_print_info_xics,
>      .dt_populate = spapr_dt_xics,
>      .post_load   = spapr_irq_post_load_xics,
> @@ -196,17 +167,6 @@ SpaprIrq spapr_irq_xics = {
>   * XIVE IRQ backend.
>   */
>  
> -static int spapr_irq_claim_xive(SpaprMachineState *spapr, int irq, bool lsi,
> -                                Error **errp)
> -{
> -    return spapr_xive_irq_claim(spapr->xive, irq, lsi, errp);
> -}
> -
> -static void spapr_irq_free_xive(SpaprMachineState *spapr, int irq)
> -{
> -    spapr_xive_irq_free(spapr->xive, irq);
> -}
> -
>  static void spapr_irq_print_info_xive(SpaprMachineState *spapr,
>                                        Monitor *mon)
>  {
> @@ -272,8 +232,6 @@ SpaprIrq spapr_irq_xive = {
>      .xics        = false,
>      .xive        = true,
>  
> -    .claim       = spapr_irq_claim_xive,
> -    .free        = spapr_irq_free_xive,
>      .print_info  = spapr_irq_print_info_xive,
>      .dt_populate = spapr_dt_xive,
>      .post_load   = spapr_irq_post_load_xive,
> @@ -301,33 +259,6 @@ static SpaprIrq *spapr_irq_current(SpaprMachineState *spapr)
>          &spapr_irq_xive : &spapr_irq_xics;
>  }
>  
> -static int spapr_irq_claim_dual(SpaprMachineState *spapr, int irq, bool lsi,
> -                                Error **errp)
> -{
> -    Error *local_err = NULL;
> -    int ret;
> -
> -    ret = spapr_irq_xics.claim(spapr, irq, lsi, &local_err);
> -    if (local_err) {
> -        error_propagate(errp, local_err);
> -        return ret;
> -    }
> -
> -    ret = spapr_irq_xive.claim(spapr, irq, lsi, &local_err);
> -    if (local_err) {
> -        error_propagate(errp, local_err);
> -        return ret;
> -    }
> -
> -    return ret;
> -}
> -
> -static void spapr_irq_free_dual(SpaprMachineState *spapr, int irq)
> -{
> -    spapr_irq_xics.free(spapr, irq);
> -    spapr_irq_xive.free(spapr, irq);
> -}
> -
>  static void spapr_irq_print_info_dual(SpaprMachineState *spapr, Monitor *mon)
>  {
>      spapr_irq_current(spapr)->print_info(spapr, mon);
> @@ -401,8 +332,6 @@ SpaprIrq spapr_irq_dual = {
>      .xics        = true,
>      .xive        = true,
>  
> -    .claim       = spapr_irq_claim_dual,
> -    .free        = spapr_irq_free_dual,
>      .print_info  = spapr_irq_print_info_dual,
>      .dt_populate = spapr_irq_dt_populate_dual,
>      .post_load   = spapr_irq_post_load_dual,
> @@ -567,10 +496,12 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>  
>          /* Enable the CPU IPIs */
>          for (i = 0; i < nr_servers; ++i) {
> +            SpaprInterruptControllerClass *sicc
> +                = SPAPR_INTC_GET_CLASS(spapr->xive);
>              Error *local_err = NULL;
>  
> -            spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i,
> -                                 false, &local_err);
> +            sicc->claim_irq(SPAPR_INTC(spapr->xive), SPAPR_IRQ_IPI + i,
> +                            false, &local_err);
>              if (local_err) {
>                  goto out;
>              }
> @@ -588,10 +519,30 @@ out:
>  
>  int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
>  {
> +    int rc;
> +
>      assert(irq >= SPAPR_XIRQ_BASE);
>      assert(irq < (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
>  
> -    return spapr->irq->claim(spapr, irq, lsi, errp);
> +    if (spapr->xive) {
> +        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(spapr->xive);
> +
> +        rc = sicc->claim_irq(SPAPR_INTC(spapr->xive), irq, lsi, errp);
> +        if (rc < 0) {
> +            return rc;
> +        }
> +    }
> +
> +    if (spapr->ics) {
> +        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(spapr->ics);
> +
> +        rc = sicc->claim_irq(SPAPR_INTC(spapr->ics), irq, lsi, errp);
> +        if (rc < 0) {
> +            return rc;
> +        }
> +    }
> +

We don't really need an indirection here since we explicitly check
spapr->xive and spapr->ics. Calling directly spapr_xive_claim_irq() and
xics_spapr_claim_irq() would allow to avoid the method boiler plate and
be more explicit IMHO.

> +    return 0;
>  }
>  
>  void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
> @@ -602,7 +553,18 @@ void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
>      assert((irq + num) <= (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
>  
>      for (i = irq; i < (irq + num); i++) {
> -        spapr->irq->free(spapr, irq);
> +        if (spapr->xive) {
> +            SpaprInterruptController *intc = SPAPR_INTC(spapr->xive);
> +            SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
> +
> +            sicc->free_irq(intc, irq);
> +        }
> +        if (spapr->ics) {
> +            SpaprInterruptController *intc = SPAPR_INTC(spapr->ics);
> +            SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
> +
> +            sicc->free_irq(intc, irq);
> +        }

Same here.

>      }
>  }
>  
> @@ -727,8 +689,6 @@ SpaprIrq spapr_irq_xics_legacy = {
>      .xics        = true,
>      .xive        = false,
>  
> -    .claim       = spapr_irq_claim_xics,
> -    .free        = spapr_irq_free_xics,
>      .print_info  = spapr_irq_print_info_xics,
>      .dt_populate = spapr_dt_xics,
>      .post_load   = spapr_irq_post_load_xics,
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index 30d660ff1e..616086f9bb 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -50,6 +50,9 @@ typedef struct SpaprInterruptControllerClass {
>       */
>      int (*cpu_intc_create)(SpaprInterruptController *intc,
>                              PowerPCCPU *cpu, Error **errp);
> +    int (*claim_irq)(SpaprInterruptController *intc, int irq, bool lsi,
> +                     Error **errp);
> +    void (*free_irq)(SpaprInterruptController *intc, int irq);
>  } SpaprInterruptControllerClass;
>  
>  void spapr_irq_print_info(SpaprMachineState *spapr, Monitor *mon);
> @@ -70,8 +73,6 @@ typedef struct SpaprIrq {
>      bool        xics;
>      bool        xive;
>  
> -    int (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
> -    void (*free)(SpaprMachineState *spapr, int irq);
>      void (*print_info)(SpaprMachineState *spapr, Monitor *mon);
>      void (*dt_populate)(SpaprMachineState *spapr, uint32_t nr_servers,
>                          void *fdt, uint32_t phandle);
> diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h
> index 0df20a6590..8f875673f5 100644
> --- a/include/hw/ppc/spapr_xive.h
> +++ b/include/hw/ppc/spapr_xive.h
> @@ -54,8 +54,6 @@ typedef struct SpaprXive {
>   */
>  #define SPAPR_XIVE_BLOCK_ID 0x0
>  
> -int spapr_xive_irq_claim(SpaprXive *xive, int lisn, bool lsi, Error **errp);
> -void spapr_xive_irq_free(SpaprXive *xive, int lisn);
>  void spapr_xive_pic_print_info(SpaprXive *xive, Monitor *mon);
>  int spapr_xive_post_load(SpaprXive *xive, int version_id);
>  



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

* Re: [PATCH v2 23/33] spapr: Formalize notion of active interrupt controller
  2019-09-27  5:50 ` [PATCH v2 23/33] spapr: Formalize notion of active interrupt controller David Gibson
@ 2019-09-27 14:16   ` Greg Kurz
  2019-09-30  5:39   ` Cédric Le Goater
  1 sibling, 0 replies; 83+ messages in thread
From: Greg Kurz @ 2019-09-27 14:16 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

On Fri, 27 Sep 2019 15:50:18 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> spapr now has the mechanism of constructing both XICS and XIVE instances of
> the SpaprInterruptController interface.  However, only one of the interrupt
> controllers will actually be active at any given time, depending on feature
> negotiation with the guest.  This is handled in the current code via
> spapr_irq_current() which checks the OV5 vector from feature negotiation to
> determine the current backend.
> 
> Determining the active controller at the point we need it like this
> can be pretty confusing, because it makes it very non obvious at what
> points the active controller can change.  This can make it difficult
> to reason about the code and where a change of active controller could
> appear in sequence with other events.
> 
> Make this mechanism more explicit by adding an 'active_intc' pointer
> and an explicit spapr_irq_update_active_intc() function to update it
> from the CAS state.  We also add hooks on the intc backend which will
> get called when it is activated or deactivated.
> 
> For now we just introduce the switch and hooks, later patches will
> actually start using them.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---

Reviewed-by: Greg Kurz <groug@kaod.org>

>  hw/ppc/spapr_irq.c         | 51 ++++++++++++++++++++++++++++++++++++++
>  include/hw/ppc/spapr.h     |  5 ++--
>  include/hw/ppc/spapr_irq.h |  5 ++++
>  3 files changed, 59 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index ea44378d8c..dfa875b7cd 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -593,6 +593,7 @@ qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq)
>  
>  int spapr_irq_post_load(SpaprMachineState *spapr, int version_id)
>  {
> +    spapr_irq_update_active_intc(spapr);
>      return spapr->irq->post_load(spapr, version_id);
>  }
>  
> @@ -600,6 +601,8 @@ void spapr_irq_reset(SpaprMachineState *spapr, Error **errp)
>  {
>      assert(!spapr->irq_map || bitmap_empty(spapr->irq_map, spapr->irq_map_nr));
>  
> +    spapr_irq_update_active_intc(spapr);
> +
>      if (spapr->irq->reset) {
>          spapr->irq->reset(spapr, errp);
>      }
> @@ -626,6 +629,54 @@ int spapr_irq_get_phandle(SpaprMachineState *spapr, void *fdt, Error **errp)
>      return phandle;
>  }
>  
> +static void set_active_intc(SpaprMachineState *spapr,
> +                            SpaprInterruptController *new_intc)
> +{
> +    SpaprInterruptControllerClass *sicc;
> +
> +    assert(new_intc);
> +
> +    if (new_intc == spapr->active_intc) {
> +        /* Nothing to do */
> +        return;
> +    }
> +
> +    if (spapr->active_intc) {
> +        sicc = SPAPR_INTC_GET_CLASS(spapr->active_intc);
> +        if (sicc->deactivate) {
> +            sicc->deactivate(spapr->active_intc);
> +        }
> +    }
> +
> +    sicc = SPAPR_INTC_GET_CLASS(new_intc);
> +    if (sicc->activate) {
> +        sicc->activate(new_intc, &error_fatal);
> +    }
> +
> +    spapr->active_intc = new_intc;
> +}
> +
> +void spapr_irq_update_active_intc(SpaprMachineState *spapr)
> +{
> +    SpaprInterruptController *new_intc;
> +
> +    if (!spapr->ics) {
> +        /*
> +         * XXX before we run CAS, ov5_cas is initialized empty, which
> +         * indicates XICS, even if we have ic-mode=xive.  TODO: clean
> +         * up the CAS path so that we have a clearer way of handling
> +         * this.
> +         */
> +        new_intc = SPAPR_INTC(spapr->xive);
> +    } else if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
> +        new_intc = SPAPR_INTC(spapr->xive);
> +    } else {
> +        new_intc = SPAPR_INTC(spapr->ics);
> +    }
> +
> +    set_active_intc(spapr, new_intc);
> +}
> +
>  /*
>   * XICS legacy routines - to deprecate one day
>   */
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index cbd1a4c9f3..763da757f0 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -143,7 +143,6 @@ struct SpaprMachineState {
>      struct SpaprVioBus *vio_bus;
>      QLIST_HEAD(, SpaprPhbState) phbs;
>      struct SpaprNvram *nvram;
> -    ICSState *ics;
>      SpaprRtcState rtc;
>  
>      SpaprResizeHpt resize_hpt;
> @@ -195,9 +194,11 @@ struct SpaprMachineState {
>  
>      int32_t irq_map_nr;
>      unsigned long *irq_map;
> -    SpaprXive  *xive;
>      SpaprIrq *irq;
>      qemu_irq *qirqs;
> +    SpaprInterruptController *active_intc;
> +    ICSState *ics;
> +    SpaprXive *xive;
>  
>      bool cmd_line_caps[SPAPR_CAP_NUM];
>      SpaprCapabilities def, eff, mig;
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index 616086f9bb..3102d152b2 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -44,6 +44,9 @@ typedef struct SpaprInterruptController SpaprInterruptController;
>  typedef struct SpaprInterruptControllerClass {
>      InterfaceClass parent;
>  
> +    void (*activate)(SpaprInterruptController *intc, Error **errp);
> +    void (*deactivate)(SpaprInterruptController *intc);
> +
>      /*
>       * These methods will typically be called on all intcs, active and
>       * inactive
> @@ -55,6 +58,8 @@ typedef struct SpaprInterruptControllerClass {
>      void (*free_irq)(SpaprInterruptController *intc, int irq);
>  } SpaprInterruptControllerClass;
>  
> +void spapr_irq_update_active_intc(SpaprMachineState *spapr);
> +
>  void spapr_irq_print_info(SpaprMachineState *spapr, Monitor *mon);
>  void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers,
>                    void *fdt, uint32_t phandle);



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

* Re: [PATCH v2 24/33] spapr, xics, xive: Move set_irq from SpaprIrq to SpaprInterruptController
  2019-09-27  5:50 ` [PATCH v2 24/33] spapr, xics, xive: Move set_irq from SpaprIrq to SpaprInterruptController David Gibson
@ 2019-09-27 14:27   ` Greg Kurz
  2019-09-30  2:41     ` David Gibson
  2019-09-30  5:48   ` Cédric Le Goater
  1 sibling, 1 reply; 83+ messages in thread
From: Greg Kurz @ 2019-09-27 14:27 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

On Fri, 27 Sep 2019 15:50:19 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> This method depends only on the active irq controller.  Now that we've
> formalized the notion of active controller we can dispatch directly through
> that, rather than dispatching via SpaprIrq with the dual version having
> to do a second conditional dispatch.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---
>  hw/intc/spapr_xive.c       | 12 +++++++++++
>  hw/intc/xics_spapr.c       |  9 +++++++++
>  hw/ppc/spapr_irq.c         | 41 ++++++++++----------------------------
>  include/hw/ppc/spapr_irq.h |  4 +++-
>  4 files changed, 34 insertions(+), 32 deletions(-)
> 
> diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
> index ff1a175b44..52d5e71793 100644
> --- a/hw/intc/spapr_xive.c
> +++ b/hw/intc/spapr_xive.c
> @@ -553,6 +553,17 @@ static int spapr_xive_cpu_intc_create(SpaprInterruptController *intc,
>      return 0;
>  }
>  
> +static void spapr_xive_set_irq(SpaprInterruptController *intc, int irq, int val)
> +{
> +    SpaprXive *xive = SPAPR_XIVE(intc);
> +
> +    if (kvm_irqchip_in_kernel()) {
> +        kvmppc_xive_source_set_irq(&xive->source, irq, val);
> +    } else {
> +        xive_source_set_irq(&xive->source, irq, val);
> +    }
> +}
> +
>  static void spapr_xive_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
> @@ -574,6 +585,7 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data)
>      sicc->cpu_intc_create = spapr_xive_cpu_intc_create;
>      sicc->claim_irq = spapr_xive_claim_irq;
>      sicc->free_irq = spapr_xive_free_irq;
> +    sicc->set_irq = spapr_xive_set_irq;
>  }
>  
>  static const TypeInfo spapr_xive_info = {
> diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
> index 224fe1efcd..02372697f6 100644
> --- a/hw/intc/xics_spapr.c
> +++ b/hw/intc/xics_spapr.c
> @@ -373,6 +373,14 @@ static void xics_spapr_free_irq(SpaprInterruptController *intc, int irq)
>      memset(&ics->irqs[srcno], 0, sizeof(ICSIRQState));
>  }
>  
> +static void xics_spapr_set_irq(SpaprInterruptController *intc, int irq, int val)
> +{
> +    ICSState *ics = ICS_SPAPR(intc);
> +    uint32_t srcno = irq - ics->offset;
> +
> +    ics_set_irq(ics, srcno, val);

And we have:

void ics_set_irq(void *opaque, int srcno, int val)
{
    ICSState *ics = (ICSState *)opaque;

    if (kvm_irqchip_in_kernel()) {
        ics_kvm_set_irq(ics, srcno, val);
        return;
    }

    if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI) {
        ics_set_irq_lsi(ics, srcno, val);
    } else {
        ics_set_irq_msi(ics, srcno, val);
    }
}

The kvm_irqchip_in_kernel() block would fit better in xics_spapr_set_irq(),
like it is already the case for XIVE. Maybe do it now while here ?

Anyway,

Reviewed-by: Greg Kurz <groug@kaod.org>

> +}
> +
>  static void ics_spapr_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
> @@ -384,6 +392,7 @@ static void ics_spapr_class_init(ObjectClass *klass, void *data)
>      sicc->cpu_intc_create = xics_spapr_cpu_intc_create;
>      sicc->claim_irq = xics_spapr_claim_irq;
>      sicc->free_irq = xics_spapr_free_irq;
> +    sicc->set_irq = xics_spapr_set_irq;
>  }
>  
>  static const TypeInfo ics_spapr_info = {
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index dfa875b7cd..4922062908 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -123,14 +123,6 @@ static int spapr_irq_post_load_xics(SpaprMachineState *spapr, int version_id)
>      return 0;
>  }
>  
> -static void spapr_irq_set_irq_xics(void *opaque, int irq, int val)
> -{
> -    SpaprMachineState *spapr = opaque;
> -    uint32_t srcno = irq - spapr->ics->offset;
> -
> -    ics_set_irq(spapr->ics, srcno, val);
> -}
> -
>  static void spapr_irq_reset_xics(SpaprMachineState *spapr, Error **errp)
>  {
>      Error *local_err = NULL;
> @@ -159,7 +151,6 @@ SpaprIrq spapr_irq_xics = {
>      .dt_populate = spapr_dt_xics,
>      .post_load   = spapr_irq_post_load_xics,
>      .reset       = spapr_irq_reset_xics,
> -    .set_irq     = spapr_irq_set_irq_xics,
>      .init_kvm    = spapr_irq_init_kvm_xics,
>  };
>  
> @@ -208,17 +199,6 @@ static void spapr_irq_reset_xive(SpaprMachineState *spapr, Error **errp)
>      spapr_xive_mmio_set_enabled(spapr->xive, true);
>  }
>  
> -static void spapr_irq_set_irq_xive(void *opaque, int irq, int val)
> -{
> -    SpaprMachineState *spapr = opaque;
> -
> -    if (kvm_irqchip_in_kernel()) {
> -        kvmppc_xive_source_set_irq(&spapr->xive->source, irq, val);
> -    } else {
> -        xive_source_set_irq(&spapr->xive->source, irq, val);
> -    }
> -}
> -
>  static void spapr_irq_init_kvm_xive(SpaprMachineState *spapr, Error **errp)
>  {
>      if (kvm_enabled()) {
> @@ -236,7 +216,6 @@ SpaprIrq spapr_irq_xive = {
>      .dt_populate = spapr_dt_xive,
>      .post_load   = spapr_irq_post_load_xive,
>      .reset       = spapr_irq_reset_xive,
> -    .set_irq     = spapr_irq_set_irq_xive,
>      .init_kvm    = spapr_irq_init_kvm_xive,
>  };
>  
> @@ -316,13 +295,6 @@ static void spapr_irq_reset_dual(SpaprMachineState *spapr, Error **errp)
>      spapr_irq_current(spapr)->reset(spapr, errp);
>  }
>  
> -static void spapr_irq_set_irq_dual(void *opaque, int irq, int val)
> -{
> -    SpaprMachineState *spapr = opaque;
> -
> -    spapr_irq_current(spapr)->set_irq(spapr, irq, val);
> -}
> -
>  /*
>   * Define values in sync with the XIVE and XICS backend
>   */
> @@ -336,7 +308,6 @@ SpaprIrq spapr_irq_dual = {
>      .dt_populate = spapr_irq_dt_populate_dual,
>      .post_load   = spapr_irq_post_load_dual,
>      .reset       = spapr_irq_reset_dual,
> -    .set_irq     = spapr_irq_set_irq_dual,
>      .init_kvm    = NULL, /* should not be used */
>  };
>  
> @@ -422,6 +393,15 @@ int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
>      return 0;
>  }
>  
> +static void spapr_set_irq(void *opaque, int irq, int level)
> +{
> +    SpaprMachineState *spapr = SPAPR_MACHINE(opaque);
> +    SpaprInterruptControllerClass *sicc
> +        = SPAPR_INTC_GET_CLASS(spapr->active_intc);
> +
> +    sicc->set_irq(spapr->active_intc, irq, level);
> +}
> +
>  void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>  {
>      MachineState *machine = MACHINE(spapr);
> @@ -510,7 +490,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>          spapr_xive_hcall_init(spapr);
>      }
>  
> -    spapr->qirqs = qemu_allocate_irqs(spapr->irq->set_irq, spapr,
> +    spapr->qirqs = qemu_allocate_irqs(spapr_set_irq, spapr,
>                                        spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
>  
>  out:
> @@ -744,7 +724,6 @@ SpaprIrq spapr_irq_xics_legacy = {
>      .dt_populate = spapr_dt_xics,
>      .post_load   = spapr_irq_post_load_xics,
>      .reset       = spapr_irq_reset_xics,
> -    .set_irq     = spapr_irq_set_irq_xics,
>      .init_kvm    = spapr_irq_init_kvm_xics,
>  };
>  
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index 3102d152b2..8286a9aa63 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -56,6 +56,9 @@ typedef struct SpaprInterruptControllerClass {
>      int (*claim_irq)(SpaprInterruptController *intc, int irq, bool lsi,
>                       Error **errp);
>      void (*free_irq)(SpaprInterruptController *intc, int irq);
> +
> +    /* These methods should only be called on the active intc */
> +    void (*set_irq)(SpaprInterruptController *intc, int irq, int val);
>  } SpaprInterruptControllerClass;
>  
>  void spapr_irq_update_active_intc(SpaprMachineState *spapr);
> @@ -83,7 +86,6 @@ typedef struct SpaprIrq {
>                          void *fdt, uint32_t phandle);
>      int (*post_load)(SpaprMachineState *spapr, int version_id);
>      void (*reset)(SpaprMachineState *spapr, Error **errp);
> -    void (*set_irq)(void *opaque, int srcno, int val);
>      void (*init_kvm)(SpaprMachineState *spapr, Error **errp);
>  } SpaprIrq;
>  



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

* Re: [PATCH v2 25/33] spapr, xics, xive: Move print_info from SpaprIrq to SpaprInterruptController
  2019-09-27  5:50 ` [PATCH v2 25/33] spapr, xics, xive: Move print_info " David Gibson
@ 2019-09-27 14:31   ` Greg Kurz
  0 siblings, 0 replies; 83+ messages in thread
From: Greg Kurz @ 2019-09-27 14:31 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

On Fri, 27 Sep 2019 15:50:20 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> This method depends only on the active irq controller.  Now that we've
> formalized the notion of active controller we can dispatch directly
> through that, rather than dispatching via SpaprIrq with the dual
> version having to do a second conditional dispatch.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---

Reviewed-by: Greg Kurz <groug@kaod.org>

>  hw/intc/spapr_xive.c       | 15 +++++++++++++
>  hw/intc/xics_spapr.c       | 15 +++++++++++++
>  hw/ppc/spapr.c             |  2 +-
>  hw/ppc/spapr_irq.c         | 44 +++++++-------------------------------
>  include/hw/ppc/spapr_irq.h |  2 +-
>  5 files changed, 40 insertions(+), 38 deletions(-)
> 
> diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
> index 52d5e71793..700ec5c9c1 100644
> --- a/hw/intc/spapr_xive.c
> +++ b/hw/intc/spapr_xive.c
> @@ -564,6 +564,20 @@ static void spapr_xive_set_irq(SpaprInterruptController *intc, int irq, int val)
>      }
>  }
>  
> +static void spapr_xive_print_info(SpaprInterruptController *intc, Monitor *mon)
> +{
> +    SpaprXive *xive = SPAPR_XIVE(intc);
> +    CPUState *cs;
> +
> +    CPU_FOREACH(cs) {
> +        PowerPCCPU *cpu = POWERPC_CPU(cs);
> +
> +        xive_tctx_pic_print_info(spapr_cpu_state(cpu)->tctx, mon);
> +    }
> +
> +    spapr_xive_pic_print_info(xive, mon);
> +}
> +
>  static void spapr_xive_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
> @@ -586,6 +600,7 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data)
>      sicc->claim_irq = spapr_xive_claim_irq;
>      sicc->free_irq = spapr_xive_free_irq;
>      sicc->set_irq = spapr_xive_set_irq;
> +    sicc->print_info = spapr_xive_print_info;
>  }
>  
>  static const TypeInfo spapr_xive_info = {
> diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
> index 02372697f6..415defe394 100644
> --- a/hw/intc/xics_spapr.c
> +++ b/hw/intc/xics_spapr.c
> @@ -381,6 +381,20 @@ static void xics_spapr_set_irq(SpaprInterruptController *intc, int irq, int val)
>      ics_set_irq(ics, srcno, val);
>  }
>  
> +static void xics_spapr_print_info(SpaprInterruptController *intc, Monitor *mon)
> +{
> +    ICSState *ics = ICS_SPAPR(intc);
> +    CPUState *cs;
> +
> +    CPU_FOREACH(cs) {
> +        PowerPCCPU *cpu = POWERPC_CPU(cs);
> +
> +        icp_pic_print_info(spapr_cpu_state(cpu)->icp, mon);
> +    }
> +
> +    ics_pic_print_info(ics, mon);
> +}
> +
>  static void ics_spapr_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
> @@ -393,6 +407,7 @@ static void ics_spapr_class_init(ObjectClass *klass, void *data)
>      sicc->claim_irq = xics_spapr_claim_irq;
>      sicc->free_irq = xics_spapr_free_irq;
>      sicc->set_irq = xics_spapr_set_irq;
> +    sicc->print_info = xics_spapr_print_info;
>  }
>  
>  static const TypeInfo ics_spapr_info = {
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 795f6ab505..7e04746db1 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -4341,7 +4341,7 @@ static void spapr_pic_print_info(InterruptStatsProvider *obj,
>  {
>      SpaprMachineState *spapr = SPAPR_MACHINE(obj);
>  
> -    spapr->irq->print_info(spapr, mon);
> +    spapr_irq_print_info(spapr, mon);
>      monitor_printf(mon, "irqchip: %s\n",
>                     kvm_irqchip_in_kernel() ? "in-kernel" : "emulated");
>  }
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index 4922062908..be20bbf3cf 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -98,19 +98,6 @@ static void spapr_irq_init_kvm(SpaprMachineState *spapr,
>   * XICS IRQ backend.
>   */
>  
> -static void spapr_irq_print_info_xics(SpaprMachineState *spapr, Monitor *mon)
> -{
> -    CPUState *cs;
> -
> -    CPU_FOREACH(cs) {
> -        PowerPCCPU *cpu = POWERPC_CPU(cs);
> -
> -        icp_pic_print_info(spapr_cpu_state(cpu)->icp, mon);
> -    }
> -
> -    ics_pic_print_info(spapr->ics, mon);
> -}
> -
>  static int spapr_irq_post_load_xics(SpaprMachineState *spapr, int version_id)
>  {
>      if (!kvm_irqchip_in_kernel()) {
> @@ -147,7 +134,6 @@ SpaprIrq spapr_irq_xics = {
>      .xics        = true,
>      .xive        = false,
>  
> -    .print_info  = spapr_irq_print_info_xics,
>      .dt_populate = spapr_dt_xics,
>      .post_load   = spapr_irq_post_load_xics,
>      .reset       = spapr_irq_reset_xics,
> @@ -158,20 +144,6 @@ SpaprIrq spapr_irq_xics = {
>   * XIVE IRQ backend.
>   */
>  
> -static void spapr_irq_print_info_xive(SpaprMachineState *spapr,
> -                                      Monitor *mon)
> -{
> -    CPUState *cs;
> -
> -    CPU_FOREACH(cs) {
> -        PowerPCCPU *cpu = POWERPC_CPU(cs);
> -
> -        xive_tctx_pic_print_info(spapr_cpu_state(cpu)->tctx, mon);
> -    }
> -
> -    spapr_xive_pic_print_info(spapr->xive, mon);
> -}
> -
>  static int spapr_irq_post_load_xive(SpaprMachineState *spapr, int version_id)
>  {
>      return spapr_xive_post_load(spapr->xive, version_id);
> @@ -212,7 +184,6 @@ SpaprIrq spapr_irq_xive = {
>      .xics        = false,
>      .xive        = true,
>  
> -    .print_info  = spapr_irq_print_info_xive,
>      .dt_populate = spapr_dt_xive,
>      .post_load   = spapr_irq_post_load_xive,
>      .reset       = spapr_irq_reset_xive,
> @@ -238,11 +209,6 @@ static SpaprIrq *spapr_irq_current(SpaprMachineState *spapr)
>          &spapr_irq_xive : &spapr_irq_xics;
>  }
>  
> -static void spapr_irq_print_info_dual(SpaprMachineState *spapr, Monitor *mon)
> -{
> -    spapr_irq_current(spapr)->print_info(spapr, mon);
> -}
> -
>  static void spapr_irq_dt_populate_dual(SpaprMachineState *spapr,
>                                         uint32_t nr_servers, void *fdt,
>                                         uint32_t phandle)
> @@ -304,7 +270,6 @@ SpaprIrq spapr_irq_dual = {
>      .xics        = true,
>      .xive        = true,
>  
> -    .print_info  = spapr_irq_print_info_dual,
>      .dt_populate = spapr_irq_dt_populate_dual,
>      .post_load   = spapr_irq_post_load_dual,
>      .reset       = spapr_irq_reset_dual,
> @@ -402,6 +367,14 @@ static void spapr_set_irq(void *opaque, int irq, int level)
>      sicc->set_irq(spapr->active_intc, irq, level);
>  }
>  
> +void spapr_irq_print_info(SpaprMachineState *spapr, Monitor *mon)
> +{
> +    SpaprInterruptControllerClass *sicc
> +        = SPAPR_INTC_GET_CLASS(spapr->active_intc);
> +
> +    sicc->print_info(spapr->active_intc, mon);
> +}
> +
>  void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>  {
>      MachineState *machine = MACHINE(spapr);
> @@ -720,7 +693,6 @@ SpaprIrq spapr_irq_xics_legacy = {
>      .xics        = true,
>      .xive        = false,
>  
> -    .print_info  = spapr_irq_print_info_xics,
>      .dt_populate = spapr_dt_xics,
>      .post_load   = spapr_irq_post_load_xics,
>      .reset       = spapr_irq_reset_xics,
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index 8286a9aa63..2ade580992 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -59,6 +59,7 @@ typedef struct SpaprInterruptControllerClass {
>  
>      /* These methods should only be called on the active intc */
>      void (*set_irq)(SpaprInterruptController *intc, int irq, int val);
> +    void (*print_info)(SpaprInterruptController *intc, Monitor *mon);
>  } SpaprInterruptControllerClass;
>  
>  void spapr_irq_update_active_intc(SpaprMachineState *spapr);
> @@ -81,7 +82,6 @@ typedef struct SpaprIrq {
>      bool        xics;
>      bool        xive;
>  
> -    void (*print_info)(SpaprMachineState *spapr, Monitor *mon);
>      void (*dt_populate)(SpaprMachineState *spapr, uint32_t nr_servers,
>                          void *fdt, uint32_t phandle);
>      int (*post_load)(SpaprMachineState *spapr, int version_id);



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

* Re: [PATCH v2 26/33] spapr, xics, xive: Move dt_populate from SpaprIrq to SpaprInterruptController
  2019-09-27  5:50 ` [PATCH v2 26/33] spapr, xics, xive: Move dt_populate " David Gibson
@ 2019-09-27 14:38   ` Greg Kurz
  2019-09-30  5:51   ` Cédric Le Goater
  1 sibling, 0 replies; 83+ messages in thread
From: Greg Kurz @ 2019-09-27 14:38 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

On Fri, 27 Sep 2019 15:50:21 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> This method depends only on the active irq controller.  Now that we've
> formalized the notion of active controller we can dispatch directly
> through that, rather than dispatching via SpaprIrq with the dual
> version having to do a second conditional dispatch.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---

Reviewed-by: Greg Kurz <groug@kaod.org>

>  hw/intc/spapr_xive.c        | 125 ++++++++++++++++++------------------
>  hw/intc/xics_spapr.c        |   5 +-
>  hw/ppc/spapr.c              |   3 +-
>  hw/ppc/spapr_irq.c          |  20 +++---
>  include/hw/ppc/spapr_irq.h  |   5 +-
>  include/hw/ppc/spapr_xive.h |   2 -
>  include/hw/ppc/xics_spapr.h |   2 -
>  7 files changed, 78 insertions(+), 84 deletions(-)
> 
> diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
> index 700ec5c9c1..37ffb74ca5 100644
> --- a/hw/intc/spapr_xive.c
> +++ b/hw/intc/spapr_xive.c
> @@ -578,6 +578,68 @@ static void spapr_xive_print_info(SpaprInterruptController *intc, Monitor *mon)
>      spapr_xive_pic_print_info(xive, mon);
>  }
>  
> +static void spapr_xive_dt(SpaprInterruptController *intc, uint32_t nr_servers,
> +                          void *fdt, uint32_t phandle)
> +{
> +    SpaprXive *xive = SPAPR_XIVE(intc);
> +    int node;
> +    uint64_t timas[2 * 2];
> +    /* Interrupt number ranges for the IPIs */
> +    uint32_t lisn_ranges[] = {
> +        cpu_to_be32(0),
> +        cpu_to_be32(nr_servers),
> +    };
> +    /*
> +     * EQ size - the sizes of pages supported by the system 4K, 64K,
> +     * 2M, 16M. We only advertise 64K for the moment.
> +     */
> +    uint32_t eq_sizes[] = {
> +        cpu_to_be32(16), /* 64K */
> +    };
> +    /*
> +     * The following array is in sync with the reserved priorities
> +     * defined by the 'spapr_xive_priority_is_reserved' routine.
> +     */
> +    uint32_t plat_res_int_priorities[] = {
> +        cpu_to_be32(7),    /* start */
> +        cpu_to_be32(0xf8), /* count */
> +    };
> +
> +    /* Thread Interrupt Management Area : User (ring 3) and OS (ring 2) */
> +    timas[0] = cpu_to_be64(xive->tm_base +
> +                           XIVE_TM_USER_PAGE * (1ull << TM_SHIFT));
> +    timas[1] = cpu_to_be64(1ull << TM_SHIFT);
> +    timas[2] = cpu_to_be64(xive->tm_base +
> +                           XIVE_TM_OS_PAGE * (1ull << TM_SHIFT));
> +    timas[3] = cpu_to_be64(1ull << TM_SHIFT);
> +
> +    _FDT(node = fdt_add_subnode(fdt, 0, xive->nodename));
> +
> +    _FDT(fdt_setprop_string(fdt, node, "device_type", "power-ivpe"));
> +    _FDT(fdt_setprop(fdt, node, "reg", timas, sizeof(timas)));
> +
> +    _FDT(fdt_setprop_string(fdt, node, "compatible", "ibm,power-ivpe"));
> +    _FDT(fdt_setprop(fdt, node, "ibm,xive-eq-sizes", eq_sizes,
> +                     sizeof(eq_sizes)));
> +    _FDT(fdt_setprop(fdt, node, "ibm,xive-lisn-ranges", lisn_ranges,
> +                     sizeof(lisn_ranges)));
> +
> +    /* For Linux to link the LSIs to the interrupt controller. */
> +    _FDT(fdt_setprop(fdt, node, "interrupt-controller", NULL, 0));
> +    _FDT(fdt_setprop_cell(fdt, node, "#interrupt-cells", 2));
> +
> +    /* For SLOF */
> +    _FDT(fdt_setprop_cell(fdt, node, "linux,phandle", phandle));
> +    _FDT(fdt_setprop_cell(fdt, node, "phandle", phandle));
> +
> +    /*
> +     * The "ibm,plat-res-int-priorities" property defines the priority
> +     * ranges reserved by the hypervisor
> +     */
> +    _FDT(fdt_setprop(fdt, 0, "ibm,plat-res-int-priorities",
> +                     plat_res_int_priorities, sizeof(plat_res_int_priorities)));
> +}
> +
>  static void spapr_xive_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
> @@ -601,6 +663,7 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data)
>      sicc->free_irq = spapr_xive_free_irq;
>      sicc->set_irq = spapr_xive_set_irq;
>      sicc->print_info = spapr_xive_print_info;
> +    sicc->dt = spapr_xive_dt;
>  }
>  
>  static const TypeInfo spapr_xive_info = {
> @@ -1601,65 +1664,3 @@ void spapr_xive_hcall_init(SpaprMachineState *spapr)
>      spapr_register_hypercall(H_INT_SYNC, h_int_sync);
>      spapr_register_hypercall(H_INT_RESET, h_int_reset);
>  }
> -
> -void spapr_dt_xive(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
> -                   uint32_t phandle)
> -{
> -    SpaprXive *xive = spapr->xive;
> -    int node;
> -    uint64_t timas[2 * 2];
> -    /* Interrupt number ranges for the IPIs */
> -    uint32_t lisn_ranges[] = {
> -        cpu_to_be32(0),
> -        cpu_to_be32(nr_servers),
> -    };
> -    /*
> -     * EQ size - the sizes of pages supported by the system 4K, 64K,
> -     * 2M, 16M. We only advertise 64K for the moment.
> -     */
> -    uint32_t eq_sizes[] = {
> -        cpu_to_be32(16), /* 64K */
> -    };
> -    /*
> -     * The following array is in sync with the reserved priorities
> -     * defined by the 'spapr_xive_priority_is_reserved' routine.
> -     */
> -    uint32_t plat_res_int_priorities[] = {
> -        cpu_to_be32(7),    /* start */
> -        cpu_to_be32(0xf8), /* count */
> -    };
> -
> -    /* Thread Interrupt Management Area : User (ring 3) and OS (ring 2) */
> -    timas[0] = cpu_to_be64(xive->tm_base +
> -                           XIVE_TM_USER_PAGE * (1ull << TM_SHIFT));
> -    timas[1] = cpu_to_be64(1ull << TM_SHIFT);
> -    timas[2] = cpu_to_be64(xive->tm_base +
> -                           XIVE_TM_OS_PAGE * (1ull << TM_SHIFT));
> -    timas[3] = cpu_to_be64(1ull << TM_SHIFT);
> -
> -    _FDT(node = fdt_add_subnode(fdt, 0, xive->nodename));
> -
> -    _FDT(fdt_setprop_string(fdt, node, "device_type", "power-ivpe"));
> -    _FDT(fdt_setprop(fdt, node, "reg", timas, sizeof(timas)));
> -
> -    _FDT(fdt_setprop_string(fdt, node, "compatible", "ibm,power-ivpe"));
> -    _FDT(fdt_setprop(fdt, node, "ibm,xive-eq-sizes", eq_sizes,
> -                     sizeof(eq_sizes)));
> -    _FDT(fdt_setprop(fdt, node, "ibm,xive-lisn-ranges", lisn_ranges,
> -                     sizeof(lisn_ranges)));
> -
> -    /* For Linux to link the LSIs to the interrupt controller. */
> -    _FDT(fdt_setprop(fdt, node, "interrupt-controller", NULL, 0));
> -    _FDT(fdt_setprop_cell(fdt, node, "#interrupt-cells", 2));
> -
> -    /* For SLOF */
> -    _FDT(fdt_setprop_cell(fdt, node, "linux,phandle", phandle));
> -    _FDT(fdt_setprop_cell(fdt, node, "phandle", phandle));
> -
> -    /*
> -     * The "ibm,plat-res-int-priorities" property defines the priority
> -     * ranges reserved by the hypervisor
> -     */
> -    _FDT(fdt_setprop(fdt, 0, "ibm,plat-res-int-priorities",
> -                     plat_res_int_priorities, sizeof(plat_res_int_priorities)));
> -}
> diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
> index 415defe394..4eabafc7e1 100644
> --- a/hw/intc/xics_spapr.c
> +++ b/hw/intc/xics_spapr.c
> @@ -308,8 +308,8 @@ static void ics_spapr_realize(DeviceState *dev, Error **errp)
>      spapr_register_hypercall(H_IPOLL, h_ipoll);
>  }
>  
> -void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
> -                   uint32_t phandle)
> +static void xics_spapr_dt(SpaprInterruptController *intc, uint32_t nr_servers,
> +                          void *fdt, uint32_t phandle)
>  {
>      uint32_t interrupt_server_ranges_prop[] = {
>          0, cpu_to_be32(nr_servers),
> @@ -408,6 +408,7 @@ static void ics_spapr_class_init(ObjectClass *klass, void *data)
>      sicc->free_irq = xics_spapr_free_irq;
>      sicc->set_irq = xics_spapr_set_irq;
>      sicc->print_info = xics_spapr_print_info;
> +    sicc->dt = xics_spapr_dt;
>  }
>  
>  static const TypeInfo ics_spapr_info = {
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 7e04746db1..f55d227cd3 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -1325,8 +1325,7 @@ static void *spapr_build_fdt(SpaprMachineState *spapr)
>      _FDT(fdt_setprop_cell(fdt, 0, "#size-cells", 2));
>  
>      /* /interrupt controller */
> -    spapr->irq->dt_populate(spapr, spapr_max_server_number(spapr), fdt,
> -                          PHANDLE_INTC);
> +    spapr_irq_dt(spapr, spapr_max_server_number(spapr), fdt, PHANDLE_INTC);
>  
>      ret = spapr_populate_memory(spapr, fdt);
>      if (ret < 0) {
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index be20bbf3cf..79cbe8064e 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -134,7 +134,6 @@ SpaprIrq spapr_irq_xics = {
>      .xics        = true,
>      .xive        = false,
>  
> -    .dt_populate = spapr_dt_xics,
>      .post_load   = spapr_irq_post_load_xics,
>      .reset       = spapr_irq_reset_xics,
>      .init_kvm    = spapr_irq_init_kvm_xics,
> @@ -184,7 +183,6 @@ SpaprIrq spapr_irq_xive = {
>      .xics        = false,
>      .xive        = true,
>  
> -    .dt_populate = spapr_dt_xive,
>      .post_load   = spapr_irq_post_load_xive,
>      .reset       = spapr_irq_reset_xive,
>      .init_kvm    = spapr_irq_init_kvm_xive,
> @@ -209,13 +207,6 @@ static SpaprIrq *spapr_irq_current(SpaprMachineState *spapr)
>          &spapr_irq_xive : &spapr_irq_xics;
>  }
>  
> -static void spapr_irq_dt_populate_dual(SpaprMachineState *spapr,
> -                                       uint32_t nr_servers, void *fdt,
> -                                       uint32_t phandle)
> -{
> -    spapr_irq_current(spapr)->dt_populate(spapr, nr_servers, fdt, phandle);
> -}
> -
>  static int spapr_irq_post_load_dual(SpaprMachineState *spapr, int version_id)
>  {
>      /*
> @@ -270,7 +261,6 @@ SpaprIrq spapr_irq_dual = {
>      .xics        = true,
>      .xive        = true,
>  
> -    .dt_populate = spapr_irq_dt_populate_dual,
>      .post_load   = spapr_irq_post_load_dual,
>      .reset       = spapr_irq_reset_dual,
>      .init_kvm    = NULL, /* should not be used */
> @@ -375,6 +365,15 @@ void spapr_irq_print_info(SpaprMachineState *spapr, Monitor *mon)
>      sicc->print_info(spapr->active_intc, mon);
>  }
>  
> +void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers,
> +                  void *fdt, uint32_t phandle)
> +{
> +    SpaprInterruptControllerClass *sicc
> +        = SPAPR_INTC_GET_CLASS(spapr->active_intc);
> +
> +    sicc->dt(spapr->active_intc, nr_servers, fdt, phandle);
> +}
> +
>  void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>  {
>      MachineState *machine = MACHINE(spapr);
> @@ -693,7 +692,6 @@ SpaprIrq spapr_irq_xics_legacy = {
>      .xics        = true,
>      .xive        = false,
>  
> -    .dt_populate = spapr_dt_xics,
>      .post_load   = spapr_irq_post_load_xics,
>      .reset       = spapr_irq_reset_xics,
>      .init_kvm    = spapr_irq_init_kvm_xics,
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index 2ade580992..c82724fc2b 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -60,6 +60,8 @@ typedef struct SpaprInterruptControllerClass {
>      /* These methods should only be called on the active intc */
>      void (*set_irq)(SpaprInterruptController *intc, int irq, int val);
>      void (*print_info)(SpaprInterruptController *intc, Monitor *mon);
> +    void (*dt)(SpaprInterruptController *intc, uint32_t nr_servers,
> +               void *fdt, uint32_t phandle);
>  } SpaprInterruptControllerClass;
>  
>  void spapr_irq_update_active_intc(SpaprMachineState *spapr);
> @@ -70,7 +72,6 @@ void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers,
>  int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
>                                PowerPCCPU *cpu, Error **errp);
>  
> -
>  void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis);
>  int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align,
>                          Error **errp);
> @@ -82,8 +83,6 @@ typedef struct SpaprIrq {
>      bool        xics;
>      bool        xive;
>  
> -    void (*dt_populate)(SpaprMachineState *spapr, uint32_t nr_servers,
> -                        void *fdt, uint32_t phandle);
>      int (*post_load)(SpaprMachineState *spapr, int version_id);
>      void (*reset)(SpaprMachineState *spapr, Error **errp);
>      void (*init_kvm)(SpaprMachineState *spapr, Error **errp);
> diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h
> index 8f875673f5..ebe156eb30 100644
> --- a/include/hw/ppc/spapr_xive.h
> +++ b/include/hw/ppc/spapr_xive.h
> @@ -58,8 +58,6 @@ void spapr_xive_pic_print_info(SpaprXive *xive, Monitor *mon);
>  int spapr_xive_post_load(SpaprXive *xive, int version_id);
>  
>  void spapr_xive_hcall_init(SpaprMachineState *spapr);
> -void spapr_dt_xive(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
> -                   uint32_t phandle);
>  void spapr_xive_set_tctx_os_cam(XiveTCTX *tctx);
>  void spapr_xive_mmio_set_enabled(SpaprXive *xive, bool enable);
>  void spapr_xive_map_mmio(SpaprXive *xive);
> diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h
> index 0a32a86e3e..9c9044db65 100644
> --- a/include/hw/ppc/xics_spapr.h
> +++ b/include/hw/ppc/xics_spapr.h
> @@ -33,8 +33,6 @@
>  #define ICS_SPAPR(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SPAPR)
>  
>  void ics_spapr_create(SpaprMachineState *spapr, int nr_xirqs, Error **errp);
> -void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
> -                   uint32_t phandle);
>  int xics_kvm_connect(SpaprMachineState *spapr, Error **errp);
>  void xics_kvm_disconnect(SpaprMachineState *spapr, Error **errp);
>  bool xics_kvm_has_broken_disconnect(SpaprMachineState *spapr);



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

* Re: [PATCH v2 27/33] spapr, xics, xive: Match signatures for XICS and XIVE KVM connect routines
  2019-09-27  5:50 ` [PATCH v2 27/33] spapr, xics, xive: Match signatures for XICS and XIVE KVM connect routines David Gibson
@ 2019-09-27 14:49   ` Greg Kurz
  2019-09-30  5:52   ` Cédric Le Goater
  1 sibling, 0 replies; 83+ messages in thread
From: Greg Kurz @ 2019-09-27 14:49 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

On Fri, 27 Sep 2019 15:50:22 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> Both XICS and XIVE have routines to connect and disconnect KVM with similar
> but not identical signatures.  This adjusts them to match exactly, which

Maybe mention this includes a return value to be able to streamline error
reporting.

> will be useful for further cleanups later.
> 
> While we're at it, remove error reporting from the disconnect path.  In the
> XICS case this wasn't used at all.  In the XIVE case the only error case
> was if the KVM device was set up, but KVM didn't have the capability to do
> so which is pretty obviously impossible.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---

Reviewed-by: Greg Kurz <groug@kaod.org>

>  hw/intc/spapr_xive_kvm.c    | 22 ++++++++++------------
>  hw/intc/xics_kvm.c          |  9 +++++----
>  hw/ppc/spapr_irq.c          | 22 +++++-----------------
>  include/hw/ppc/spapr_xive.h |  4 ++--
>  include/hw/ppc/xics_spapr.h |  4 ++--
>  5 files changed, 24 insertions(+), 37 deletions(-)
> 
> diff --git a/hw/intc/spapr_xive_kvm.c b/hw/intc/spapr_xive_kvm.c
> index 51b334b676..08012ac7cd 100644
> --- a/hw/intc/spapr_xive_kvm.c
> +++ b/hw/intc/spapr_xive_kvm.c
> @@ -740,8 +740,9 @@ static void *kvmppc_xive_mmap(SpaprXive *xive, int pgoff, size_t len,
>   * All the XIVE memory regions are now backed by mappings from the KVM
>   * XIVE device.
>   */
> -void kvmppc_xive_connect(SpaprXive *xive, Error **errp)
> +int kvmppc_xive_connect(SpaprInterruptController *intc, Error **errp)
>  {
> +    SpaprXive *xive = SPAPR_XIVE(intc);
>      XiveSource *xsrc = &xive->source;
>      Error *local_err = NULL;
>      size_t esb_len = (1ull << xsrc->esb_shift) * xsrc->nr_irqs;
> @@ -753,19 +754,19 @@ void kvmppc_xive_connect(SpaprXive *xive, Error **errp)
>       * rebooting under the XIVE-only interrupt mode.
>       */
>      if (xive->fd != -1) {
> -        return;
> +        return 0;
>      }
>  
>      if (!kvmppc_has_cap_xive()) {
>          error_setg(errp, "IRQ_XIVE capability must be present for KVM");
> -        return;
> +        return -1;
>      }
>  
>      /* First, create the KVM XIVE device */
>      xive->fd = kvm_create_device(kvm_state, KVM_DEV_TYPE_XIVE, false);
>      if (xive->fd < 0) {
>          error_setg_errno(errp, -xive->fd, "XIVE: error creating KVM device");
> -        return;
> +        return -1;
>      }
>  
>      /*
> @@ -821,15 +822,17 @@ void kvmppc_xive_connect(SpaprXive *xive, Error **errp)
>      kvm_kernel_irqchip = true;
>      kvm_msi_via_irqfd_allowed = true;
>      kvm_gsi_direct_mapping = true;
> -    return;
> +    return 0;
>  
>  fail:
>      error_propagate(errp, local_err);
> -    kvmppc_xive_disconnect(xive, NULL);
> +    kvmppc_xive_disconnect(intc);
> +    return -1;
>  }
>  
> -void kvmppc_xive_disconnect(SpaprXive *xive, Error **errp)
> +void kvmppc_xive_disconnect(SpaprInterruptController *intc)
>  {
> +    SpaprXive *xive = SPAPR_XIVE(intc);
>      XiveSource *xsrc;
>      size_t esb_len;
>  
> @@ -838,11 +841,6 @@ void kvmppc_xive_disconnect(SpaprXive *xive, Error **errp)
>          return;
>      }
>  
> -    if (!kvmppc_has_cap_xive()) {
> -        error_setg(errp, "IRQ_XIVE capability must be present for KVM");
> -        return;
> -    }
> -
>      /* Clear the KVM mapping */
>      xsrc = &xive->source;
>      esb_len = (1ull << xsrc->esb_shift) * xsrc->nr_irqs;
> diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
> index ba90d6dc96..954c424b36 100644
> --- a/hw/intc/xics_kvm.c
> +++ b/hw/intc/xics_kvm.c
> @@ -342,8 +342,9 @@ void ics_kvm_set_irq(ICSState *ics, int srcno, int val)
>      }
>  }
>  
> -int xics_kvm_connect(SpaprMachineState *spapr, Error **errp)
> +int xics_kvm_connect(SpaprInterruptController *intc, Error **errp)
>  {
> +    ICSState *ics = ICS_SPAPR(intc);
>      int rc;
>      CPUState *cs;
>      Error *local_err = NULL;
> @@ -413,7 +414,7 @@ int xics_kvm_connect(SpaprMachineState *spapr, Error **errp)
>      }
>  
>      /* Update the KVM sources */
> -    ics_set_kvm_state(spapr->ics, &local_err);
> +    ics_set_kvm_state(ics, &local_err);
>      if (local_err) {
>          goto fail;
>      }
> @@ -431,11 +432,11 @@ int xics_kvm_connect(SpaprMachineState *spapr, Error **errp)
>  
>  fail:
>      error_propagate(errp, local_err);
> -    xics_kvm_disconnect(spapr, NULL);
> +    xics_kvm_disconnect(intc);
>      return -1;
>  }
>  
> -void xics_kvm_disconnect(SpaprMachineState *spapr, Error **errp)
> +void xics_kvm_disconnect(SpaprInterruptController *intc)
>  {
>      /*
>       * Only on P9 using the XICS-on XIVE KVM device:
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index 79cbe8064e..561bdbc4de 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -124,7 +124,7 @@ static void spapr_irq_reset_xics(SpaprMachineState *spapr, Error **errp)
>  static void spapr_irq_init_kvm_xics(SpaprMachineState *spapr, Error **errp)
>  {
>      if (kvm_enabled()) {
> -        xics_kvm_connect(spapr, errp);
> +        xics_kvm_connect(SPAPR_INTC(spapr->ics), errp);
>      }
>  }
>  
> @@ -173,7 +173,7 @@ static void spapr_irq_reset_xive(SpaprMachineState *spapr, Error **errp)
>  static void spapr_irq_init_kvm_xive(SpaprMachineState *spapr, Error **errp)
>  {
>      if (kvm_enabled()) {
> -        kvmppc_xive_connect(spapr->xive, errp);
> +        kvmppc_xive_connect(SPAPR_INTC(spapr->xive), errp);
>      }
>  }
>  
> @@ -215,7 +215,7 @@ static int spapr_irq_post_load_dual(SpaprMachineState *spapr, int version_id)
>       */
>      if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
>          if (kvm_irqchip_in_kernel()) {
> -            xics_kvm_disconnect(spapr, &error_fatal);
> +            xics_kvm_disconnect(SPAPR_INTC(spapr->ics));
>          }
>          spapr_irq_xive.reset(spapr, &error_fatal);
>      }
> @@ -225,8 +225,6 @@ static int spapr_irq_post_load_dual(SpaprMachineState *spapr, int version_id)
>  
>  static void spapr_irq_reset_dual(SpaprMachineState *spapr, Error **errp)
>  {
> -    Error *local_err = NULL;
> -
>      /*
>       * Deactivate the XIVE MMIOs. The XIVE backend will reenable them
>       * if selected.
> @@ -235,18 +233,8 @@ static void spapr_irq_reset_dual(SpaprMachineState *spapr, Error **errp)
>  
>      /* Destroy all KVM devices */
>      if (kvm_irqchip_in_kernel()) {
> -        xics_kvm_disconnect(spapr, &local_err);
> -        if (local_err) {
> -            error_propagate(errp, local_err);
> -            error_prepend(errp, "KVM XICS disconnect failed: ");
> -            return;
> -        }
> -        kvmppc_xive_disconnect(spapr->xive, &local_err);
> -        if (local_err) {
> -            error_propagate(errp, local_err);
> -            error_prepend(errp, "KVM XIVE disconnect failed: ");
> -            return;
> -        }
> +        xics_kvm_disconnect(SPAPR_INTC(spapr->ics));
> +        kvmppc_xive_disconnect(SPAPR_INTC(spapr->xive));
>      }
>  
>      spapr_irq_current(spapr)->reset(spapr, errp);
> diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h
> index ebe156eb30..64972754f9 100644
> --- a/include/hw/ppc/spapr_xive.h
> +++ b/include/hw/ppc/spapr_xive.h
> @@ -68,8 +68,8 @@ int spapr_xive_end_to_target(uint8_t end_blk, uint32_t end_idx,
>  /*
>   * KVM XIVE device helpers
>   */
> -void kvmppc_xive_connect(SpaprXive *xive, Error **errp);
> -void kvmppc_xive_disconnect(SpaprXive *xive, Error **errp);
> +int kvmppc_xive_connect(SpaprInterruptController *intc, Error **errp);
> +void kvmppc_xive_disconnect(SpaprInterruptController *intc);
>  void kvmppc_xive_reset(SpaprXive *xive, Error **errp);
>  void kvmppc_xive_set_source_config(SpaprXive *xive, uint32_t lisn, XiveEAS *eas,
>                                     Error **errp);
> diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h
> index 9c9044db65..445beeffef 100644
> --- a/include/hw/ppc/xics_spapr.h
> +++ b/include/hw/ppc/xics_spapr.h
> @@ -33,8 +33,8 @@
>  #define ICS_SPAPR(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SPAPR)
>  
>  void ics_spapr_create(SpaprMachineState *spapr, int nr_xirqs, Error **errp);
> -int xics_kvm_connect(SpaprMachineState *spapr, Error **errp);
> -void xics_kvm_disconnect(SpaprMachineState *spapr, Error **errp);
> +int xics_kvm_connect(SpaprInterruptController *intc, Error **errp);
> +void xics_kvm_disconnect(SpaprInterruptController *intc);
>  bool xics_kvm_has_broken_disconnect(SpaprMachineState *spapr);
>  
>  #endif /* XICS_SPAPR_H */



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

* Re: [PATCH v2 28/33] spapr: Remove SpaprIrq::init_kvm hook
  2019-09-27  5:50 ` [PATCH v2 28/33] spapr: Remove SpaprIrq::init_kvm hook David Gibson
@ 2019-09-27 15:04   ` Greg Kurz
  2019-09-30  5:55   ` Cédric Le Goater
  1 sibling, 0 replies; 83+ messages in thread
From: Greg Kurz @ 2019-09-27 15:04 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

On Fri, 27 Sep 2019 15:50:23 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> This hook is a bit odd.  The only caller is spapr_irq_init_kvm(), but
> it explicitly takes an SpaprIrq *, so it's never really called through the
> current SpaprIrq.  Essentially this is just a way of passing through a
> function pointer so that spapr_irq_init_kvm() can handle some
> configuration and error handling logic without duplicating it between the
> xics and xive reset paths.
> 
> So, make it just take that function pointer.  Because of earlier reworks
> to the KVM connect/disconnect code in the xics and xive backends we can
> also eliminate some wrapper functions and streamline error handling a bit.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---

Reviewed-by: Greg Kurz <groug@kaod.org>

>  hw/ppc/spapr_irq.c         | 74 +++++++++++++-------------------------
>  include/hw/ppc/spapr_irq.h |  1 -
>  2 files changed, 25 insertions(+), 50 deletions(-)
> 
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index 561bdbc4de..c6abebc4ef 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -65,33 +65,35 @@ void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, uint32_t num)
>      bitmap_clear(spapr->irq_map, irq - SPAPR_IRQ_MSI, num);
>  }
>  
> -static void spapr_irq_init_kvm(SpaprMachineState *spapr,
> -                                  SpaprIrq *irq, Error **errp)
> +static int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController *, Error **),
> +                              SpaprInterruptController *intc,
> +                              Error **errp)
>  {
> -    MachineState *machine = MACHINE(spapr);
> +    MachineState *machine = MACHINE(qdev_get_machine());
>      Error *local_err = NULL;
>  
>      if (kvm_enabled() && machine_kernel_irqchip_allowed(machine)) {
> -        irq->init_kvm(spapr, &local_err);
> -        if (local_err && machine_kernel_irqchip_required(machine)) {
> -            error_prepend(&local_err,
> -                          "kernel_irqchip requested but unavailable: ");
> -            error_propagate(errp, local_err);
> -            return;
> -        }
> +        if (fn(intc, &local_err) < 0) {
> +            if (machine_kernel_irqchip_required(machine)) {
> +                error_prepend(&local_err,
> +                              "kernel_irqchip requested but unavailable: ");
> +                error_propagate(errp, local_err);
> +                return -1;
> +            }
>  
> -        if (!local_err) {
> -            return;
> +            /*
> +             * We failed to initialize the KVM device, fallback to
> +             * emulated mode
> +             */
> +            error_prepend(&local_err,
> +                          "kernel_irqchip allowed but unavailable: ");
> +            error_append_hint(&local_err,
> +                              "Falling back to kernel-irqchip=off\n");
> +            warn_report_err(local_err);
>          }
> -
> -        /*
> -         * We failed to initialize the KVM device, fallback to
> -         * emulated mode
> -         */
> -        error_prepend(&local_err, "kernel_irqchip allowed but unavailable: ");
> -        error_append_hint(&local_err, "Falling back to kernel-irqchip=off\n");
> -        warn_report_err(local_err);
>      }
> +
> +    return 0;
>  }
>  
>  /*
> @@ -112,20 +114,7 @@ static int spapr_irq_post_load_xics(SpaprMachineState *spapr, int version_id)
>  
>  static void spapr_irq_reset_xics(SpaprMachineState *spapr, Error **errp)
>  {
> -    Error *local_err = NULL;
> -
> -    spapr_irq_init_kvm(spapr, &spapr_irq_xics, &local_err);
> -    if (local_err) {
> -        error_propagate(errp, local_err);
> -        return;
> -    }
> -}
> -
> -static void spapr_irq_init_kvm_xics(SpaprMachineState *spapr, Error **errp)
> -{
> -    if (kvm_enabled()) {
> -        xics_kvm_connect(SPAPR_INTC(spapr->ics), errp);
> -    }
> +    spapr_irq_init_kvm(xics_kvm_connect, SPAPR_INTC(spapr->ics), errp);
>  }
>  
>  SpaprIrq spapr_irq_xics = {
> @@ -136,7 +125,6 @@ SpaprIrq spapr_irq_xics = {
>  
>      .post_load   = spapr_irq_post_load_xics,
>      .reset       = spapr_irq_reset_xics,
> -    .init_kvm    = spapr_irq_init_kvm_xics,
>  };
>  
>  /*
> @@ -151,7 +139,6 @@ static int spapr_irq_post_load_xive(SpaprMachineState *spapr, int version_id)
>  static void spapr_irq_reset_xive(SpaprMachineState *spapr, Error **errp)
>  {
>      CPUState *cs;
> -    Error *local_err = NULL;
>  
>      CPU_FOREACH(cs) {
>          PowerPCCPU *cpu = POWERPC_CPU(cs);
> @@ -160,9 +147,8 @@ static void spapr_irq_reset_xive(SpaprMachineState *spapr, Error **errp)
>          spapr_xive_set_tctx_os_cam(spapr_cpu_state(cpu)->tctx);
>      }
>  
> -    spapr_irq_init_kvm(spapr, &spapr_irq_xive, &local_err);
> -    if (local_err) {
> -        error_propagate(errp, local_err);
> +    if (spapr_irq_init_kvm(kvmppc_xive_connect,
> +                           SPAPR_INTC(spapr->xive), errp) < 0) {
>          return;
>      }
>  
> @@ -170,13 +156,6 @@ static void spapr_irq_reset_xive(SpaprMachineState *spapr, Error **errp)
>      spapr_xive_mmio_set_enabled(spapr->xive, true);
>  }
>  
> -static void spapr_irq_init_kvm_xive(SpaprMachineState *spapr, Error **errp)
> -{
> -    if (kvm_enabled()) {
> -        kvmppc_xive_connect(SPAPR_INTC(spapr->xive), errp);
> -    }
> -}
> -
>  SpaprIrq spapr_irq_xive = {
>      .nr_xirqs    = SPAPR_NR_XIRQS,
>      .nr_msis     = SPAPR_NR_MSIS,
> @@ -185,7 +164,6 @@ SpaprIrq spapr_irq_xive = {
>  
>      .post_load   = spapr_irq_post_load_xive,
>      .reset       = spapr_irq_reset_xive,
> -    .init_kvm    = spapr_irq_init_kvm_xive,
>  };
>  
>  /*
> @@ -251,7 +229,6 @@ SpaprIrq spapr_irq_dual = {
>  
>      .post_load   = spapr_irq_post_load_dual,
>      .reset       = spapr_irq_reset_dual,
> -    .init_kvm    = NULL, /* should not be used */
>  };
>  
>  
> @@ -682,7 +659,6 @@ SpaprIrq spapr_irq_xics_legacy = {
>  
>      .post_load   = spapr_irq_post_load_xics,
>      .reset       = spapr_irq_reset_xics,
> -    .init_kvm    = spapr_irq_init_kvm_xics,
>  };
>  
>  static void spapr_irq_register_types(void)
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index c82724fc2b..c947f40571 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -85,7 +85,6 @@ typedef struct SpaprIrq {
>  
>      int (*post_load)(SpaprMachineState *spapr, int version_id);
>      void (*reset)(SpaprMachineState *spapr, Error **errp);
> -    void (*init_kvm)(SpaprMachineState *spapr, Error **errp);
>  } SpaprIrq;
>  
>  extern SpaprIrq spapr_irq_xics;



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

* Re: [PATCH v2 31/33] spapr: Remove SpaprIrq::nr_msis
  2019-09-27  5:50 ` [PATCH v2 31/33] spapr: Remove SpaprIrq::nr_msis David Gibson
@ 2019-09-27 15:17   ` Greg Kurz
  0 siblings, 0 replies; 83+ messages in thread
From: Greg Kurz @ 2019-09-27 15:17 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

On Fri, 27 Sep 2019 15:50:26 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> The nr_msis value we use here has to line up with whether we're using
> legacy or modern irq allocation.  Therefore it's safer to derive it based
> on legacy_irq_allocation rather than having SpaprIrq contain a canned
> value.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---

Reviewed-by: Greg Kurz <groug@kaod.org>

>  hw/ppc/spapr.c              |  5 ++---
>  hw/ppc/spapr_irq.c          | 26 +++++++++++++++++---------
>  hw/ppc/spapr_pci.c          |  7 ++++---
>  include/hw/pci-host/spapr.h |  4 ++--
>  include/hw/ppc/spapr_irq.h  |  5 +----
>  5 files changed, 26 insertions(+), 21 deletions(-)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index f55d227cd3..34b693beba 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -1345,7 +1345,7 @@ static void *spapr_build_fdt(SpaprMachineState *spapr)
>      }
>  
>      QLIST_FOREACH(phb, &spapr->phbs, list) {
> -        ret = spapr_dt_phb(phb, PHANDLE_INTC, fdt, spapr->irq->nr_msis, NULL);
> +        ret = spapr_dt_phb(spapr, phb, PHANDLE_INTC, fdt, NULL);
>          if (ret < 0) {
>              error_report("couldn't setup PCI devices in fdt");
>              exit(1);
> @@ -3980,8 +3980,7 @@ int spapr_phb_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr,
>          return -1;
>      }
>  
> -    if (spapr_dt_phb(sphb, intc_phandle, fdt, spapr->irq->nr_msis,
> -                     fdt_start_offset)) {
> +    if (spapr_dt_phb(spapr, sphb, intc_phandle, fdt, fdt_start_offset)) {
>          error_setg(errp, "unable to create FDT node for PHB %d", sphb->index);
>          return -1;
>      }
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index 040384b0fe..799755c811 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -29,9 +29,14 @@ static const TypeInfo spapr_intc_info = {
>      .class_size = sizeof(SpaprInterruptControllerClass),
>  };
>  
> -void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis)
> +static void spapr_irq_msi_init(SpaprMachineState *spapr)
>  {
> -    spapr->irq_map_nr = nr_msis;
> +    if (SPAPR_MACHINE_GET_CLASS(spapr)->legacy_irq_allocation) {
> +        /* Legacy mode doesn't use this allocater */
> +        return;
> +    }
> +
> +    spapr->irq_map_nr = spapr_irq_nr_msis(spapr);
>      spapr->irq_map = bitmap_new(spapr->irq_map_nr);
>  }
>  
> @@ -102,7 +107,6 @@ int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController *, Error **),
>  
>  SpaprIrq spapr_irq_xics = {
>      .nr_xirqs    = SPAPR_NR_XIRQS,
> -    .nr_msis     = SPAPR_NR_MSIS,
>      .xics        = true,
>      .xive        = false,
>  };
> @@ -113,7 +117,6 @@ SpaprIrq spapr_irq_xics = {
>  
>  SpaprIrq spapr_irq_xive = {
>      .nr_xirqs    = SPAPR_NR_XIRQS,
> -    .nr_msis     = SPAPR_NR_MSIS,
>      .xics        = false,
>      .xive        = true,
>  };
> @@ -132,7 +135,6 @@ SpaprIrq spapr_irq_xive = {
>   */
>  SpaprIrq spapr_irq_dual = {
>      .nr_xirqs    = SPAPR_NR_XIRQS,
> -    .nr_msis     = SPAPR_NR_MSIS,
>      .xics        = true,
>      .xive        = true,
>  };
> @@ -245,6 +247,15 @@ void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers,
>      sicc->dt(spapr->active_intc, nr_servers, fdt, phandle);
>  }
>  
> +uint32_t spapr_irq_nr_msis(SpaprMachineState *spapr)
> +{
> +    if (SPAPR_MACHINE_GET_CLASS(spapr)->legacy_irq_allocation) {
> +        return spapr->irq->nr_xirqs;
> +    } else {
> +        return SPAPR_XIRQ_BASE + spapr->irq->nr_xirqs - SPAPR_IRQ_MSI;
> +    }
> +}
> +
>  void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>  {
>      MachineState *machine = MACHINE(spapr);
> @@ -267,9 +278,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>      }
>  
>      /* Initialize the MSI IRQ allocator. */
> -    if (!SPAPR_MACHINE_GET_CLASS(spapr)->legacy_irq_allocation) {
> -        spapr_irq_msi_init(spapr, spapr->irq->nr_msis);
> -    }
> +    spapr_irq_msi_init(spapr);
>  
>      if (spapr->irq->xics) {
>          Object *obj;
> @@ -558,7 +567,6 @@ int spapr_irq_find(SpaprMachineState *spapr, int num, bool align, Error **errp)
>  
>  SpaprIrq spapr_irq_xics_legacy = {
>      .nr_xirqs    = SPAPR_IRQ_XICS_LEGACY_NR_XIRQS,
> -    .nr_msis     = SPAPR_IRQ_XICS_LEGACY_NR_XIRQS,
>      .xics        = true,
>      .xive        = false,
>  };
> diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
> index 6934d506a7..8ed06e5964 100644
> --- a/hw/ppc/spapr_pci.c
> +++ b/hw/ppc/spapr_pci.c
> @@ -2305,8 +2305,8 @@ static void spapr_phb_pci_enumerate(SpaprPhbState *phb)
>  
>  }
>  
> -int spapr_dt_phb(SpaprPhbState *phb, uint32_t intc_phandle, void *fdt,
> -                 uint32_t nr_msis, int *node_offset)
> +int spapr_dt_phb(SpaprMachineState *spapr, SpaprPhbState *phb,
> +                 uint32_t intc_phandle, void *fdt, int *node_offset)
>  {
>      int bus_off, i, j, ret;
>      uint32_t bus_range[] = { cpu_to_be32(0), cpu_to_be32(0xff) };
> @@ -2371,7 +2371,8 @@ int spapr_dt_phb(SpaprPhbState *phb, uint32_t intc_phandle, void *fdt,
>      _FDT(fdt_setprop(fdt, bus_off, "ranges", &ranges, sizeof_ranges));
>      _FDT(fdt_setprop(fdt, bus_off, "reg", &bus_reg, sizeof(bus_reg)));
>      _FDT(fdt_setprop_cell(fdt, bus_off, "ibm,pci-config-space-type", 0x1));
> -    _FDT(fdt_setprop_cell(fdt, bus_off, "ibm,pe-total-#msi", nr_msis));
> +    _FDT(fdt_setprop_cell(fdt, bus_off, "ibm,pe-total-#msi",
> +                          spapr_irq_nr_msis(spapr)));
>  
>      /* Dynamic DMA window */
>      if (phb->ddw_enabled) {
> diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h
> index 23506f05d9..8877ff51fb 100644
> --- a/include/hw/pci-host/spapr.h
> +++ b/include/hw/pci-host/spapr.h
> @@ -128,8 +128,8 @@ struct SpaprPhbState {
>  #define SPAPR_PCI_NV2ATSD_WIN_SIZE   (NVGPU_MAX_NUM * NVGPU_MAX_LINKS * \
>                                        64 * KiB)
>  
> -int spapr_dt_phb(SpaprPhbState *phb, uint32_t intc_phandle, void *fdt,
> -                 uint32_t nr_msis, int *node_offset);
> +int spapr_dt_phb(SpaprMachineState *spapr, SpaprPhbState *phb,
> +                 uint32_t intc_phandle, void *fdt, int *node_offset);
>  
>  void spapr_pci_rtas_init(void);
>  
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index bc379b0761..308bfcefd1 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -27,7 +27,6 @@
>  #define SPAPR_IRQ_MSI        (SPAPR_XIRQ_BASE + 0x0300)
>  
>  #define SPAPR_NR_XIRQS       0x1000
> -#define SPAPR_NR_MSIS        (SPAPR_XIRQ_BASE + SPAPR_NR_XIRQS - SPAPR_IRQ_MSI)
>  
>  typedef struct SpaprMachineState SpaprMachineState;
>  
> @@ -72,15 +71,13 @@ void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers,
>                    void *fdt, uint32_t phandle);
>  int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
>                                PowerPCCPU *cpu, Error **errp);
> -
> -void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis);
> +uint32_t spapr_irq_nr_msis(SpaprMachineState *spapr);
>  int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align,
>                          Error **errp);
>  void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, uint32_t num);
>  
>  typedef struct SpaprIrq {
>      uint32_t    nr_xirqs;
> -    uint32_t    nr_msis;
>      bool        xics;
>      bool        xive;
>  } SpaprIrq;



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

* Re: [PATCH v2 32/33] spapr: Move SpaprIrq::nr_xirqs to SpaprMachineClass
  2019-09-27  5:50 ` [PATCH v2 32/33] spapr: Move SpaprIrq::nr_xirqs to SpaprMachineClass David Gibson
@ 2019-09-27 15:22   ` Greg Kurz
  2019-09-30  2:44     ` David Gibson
  0 siblings, 1 reply; 83+ messages in thread
From: Greg Kurz @ 2019-09-27 15:22 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

On Fri, 27 Sep 2019 15:50:27 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> For the benefit of peripheral device allocation, the number of available
> irqs really wants to be the same on a given machine type version,
> regardless of what irq backends we are using.  That's the case now, but
> only because we make sure the different SpaprIrq instances have the same
> value except for the special legacy one.
> 
> Since this really only depends on machine type version, move the value to
> SpaprMachineClass instead of SpaprIrq.  This also puts the code to set it
> to the lower value on old machine types right next to setting
> legacy_irq_allocation, which needs to go hand in hand.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---
>  hw/ppc/spapr.c             |  2 ++
>  hw/ppc/spapr_irq.c         | 33 ++++++++++++++++-----------------
>  include/hw/ppc/spapr.h     |  1 +
>  include/hw/ppc/spapr_irq.h |  1 -
>  4 files changed, 19 insertions(+), 18 deletions(-)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 34b693beba..7113249c89 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -4513,6 +4513,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
>      smc->irq = &spapr_irq_dual;
>      smc->dr_phb_enabled = true;
>      smc->linux_pci_probe = true;
> +    smc->nr_xirqs = SPAPR_NR_XIRQS;

This is the last user of SPAPR_NR_XIRQS.

$ git grep SPAPR_NR_XIRQS
hw/ppc/spapr.c:    smc->nr_xirqs = SPAPR_NR_XIRQS;
include/hw/ppc/spapr_irq.h:#define SPAPR_NR_XIRQS       0x1000

Maybe open-code it here, like you already do for SPAPR_IRQ_XICS_LEGACY_NR_XIRQS
below.

With or without that fixed.

Reviewed-by: Greg Kurz <groug@kaod.org>

>  }
>  
>  static const TypeInfo spapr_machine_info = {
> @@ -4648,6 +4649,7 @@ static void spapr_machine_3_0_class_options(MachineClass *mc)
>      compat_props_add(mc->compat_props, hw_compat_3_0, hw_compat_3_0_len);
>  
>      smc->legacy_irq_allocation = true;
> +    smc->nr_xirqs = 0x400;
>      smc->irq = &spapr_irq_xics_legacy;
>  }
>  
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index 799755c811..f76f30f54b 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -106,7 +106,6 @@ int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController *, Error **),
>   */
>  
>  SpaprIrq spapr_irq_xics = {
> -    .nr_xirqs    = SPAPR_NR_XIRQS,
>      .xics        = true,
>      .xive        = false,
>  };
> @@ -116,7 +115,6 @@ SpaprIrq spapr_irq_xics = {
>   */
>  
>  SpaprIrq spapr_irq_xive = {
> -    .nr_xirqs    = SPAPR_NR_XIRQS,
>      .xics        = false,
>      .xive        = true,
>  };
> @@ -134,7 +132,6 @@ SpaprIrq spapr_irq_xive = {
>   * Define values in sync with the XIVE and XICS backend
>   */
>  SpaprIrq spapr_irq_dual = {
> -    .nr_xirqs    = SPAPR_NR_XIRQS,
>      .xics        = true,
>      .xive        = true,
>  };
> @@ -249,16 +246,19 @@ void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers,
>  
>  uint32_t spapr_irq_nr_msis(SpaprMachineState *spapr)
>  {
> -    if (SPAPR_MACHINE_GET_CLASS(spapr)->legacy_irq_allocation) {
> -        return spapr->irq->nr_xirqs;
> +    SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
> +
> +    if (smc->legacy_irq_allocation) {
> +        return smc->nr_xirqs;
>      } else {
> -        return SPAPR_XIRQ_BASE + spapr->irq->nr_xirqs - SPAPR_IRQ_MSI;
> +        return SPAPR_XIRQ_BASE + smc->nr_xirqs - SPAPR_IRQ_MSI;
>      }
>  }
>  
>  void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>  {
>      MachineState *machine = MACHINE(spapr);
> +    SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
>      Error *local_err = NULL;
>  
>      if (machine_kernel_irqchip_split(machine)) {
> @@ -295,8 +295,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>              goto out;
>          }
>  
> -        object_property_set_int(obj, spapr->irq->nr_xirqs, "nr-irqs",
> -                                &local_err);
> +        object_property_set_int(obj, smc->nr_xirqs, "nr-irqs", &local_err);
>          if (local_err) {
>              goto out;
>          }
> @@ -315,8 +314,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>          int i;
>  
>          dev = qdev_create(NULL, TYPE_SPAPR_XIVE);
> -        qdev_prop_set_uint32(dev, "nr-irqs",
> -                             spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
> +        qdev_prop_set_uint32(dev, "nr-irqs", smc->nr_xirqs + SPAPR_XIRQ_BASE);
>          /*
>           * 8 XIVE END structures per CPU. One for each available
>           * priority
> @@ -343,7 +341,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>      }
>  
>      spapr->qirqs = qemu_allocate_irqs(spapr_set_irq, spapr,
> -                                      spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
> +                                      smc->nr_xirqs + SPAPR_XIRQ_BASE);
>  
>  out:
>      error_propagate(errp, local_err);
> @@ -351,10 +349,11 @@ out:
>  
>  int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
>  {
> +    SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
>      int rc;
>  
>      assert(irq >= SPAPR_XIRQ_BASE);
> -    assert(irq < (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
> +    assert(irq < (smc->nr_xirqs + SPAPR_XIRQ_BASE));
>  
>      if (spapr->xive) {
>          SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(spapr->xive);
> @@ -379,10 +378,11 @@ int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
>  
>  void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
>  {
> +    SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
>      int i;
>  
>      assert(irq >= SPAPR_XIRQ_BASE);
> -    assert((irq + num) <= (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
> +    assert((irq + num) <= (smc->nr_xirqs + SPAPR_XIRQ_BASE));
>  
>      for (i = irq; i < (irq + num); i++) {
>          if (spapr->xive) {
> @@ -402,6 +402,8 @@ void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
>  
>  qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq)
>  {
> +    SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
> +
>      /*
>       * This interface is basically for VIO and PHB devices to find the
>       * right qemu_irq to manipulate, so we only allow access to the
> @@ -410,7 +412,7 @@ qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq)
>       * interfaces, we can change this if we need to in future.
>       */
>      assert(irq >= SPAPR_XIRQ_BASE);
> -    assert(irq < (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
> +    assert(irq < (smc->nr_xirqs + SPAPR_XIRQ_BASE));
>  
>      if (spapr->ics) {
>          assert(ics_valid_irq(spapr->ics, irq));
> @@ -563,10 +565,7 @@ int spapr_irq_find(SpaprMachineState *spapr, int num, bool align, Error **errp)
>      return first + ics->offset;
>  }
>  
> -#define SPAPR_IRQ_XICS_LEGACY_NR_XIRQS     0x400
> -
>  SpaprIrq spapr_irq_xics_legacy = {
> -    .nr_xirqs    = SPAPR_IRQ_XICS_LEGACY_NR_XIRQS,
>      .xics        = true,
>      .xive        = false,
>  };
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index 763da757f0..623e8e3f93 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -119,6 +119,7 @@ struct SpaprMachineClass {
>      bool use_ohci_by_default;  /* use USB-OHCI instead of XHCI */
>      bool pre_2_10_has_unused_icps;
>      bool legacy_irq_allocation;
> +    uint32_t nr_xirqs;
>      bool broken_host_serial_model; /* present real host info to the guest */
>      bool pre_4_1_migration; /* don't migrate hpt-max-page-size */
>      bool linux_pci_probe;
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index 308bfcefd1..73d8beda39 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -77,7 +77,6 @@ int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align,
>  void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, uint32_t num);
>  
>  typedef struct SpaprIrq {
> -    uint32_t    nr_xirqs;
>      bool        xics;
>      bool        xive;
>  } SpaprIrq;



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

* Re: [PATCH v2 17/33] xive: Improve irq claim/free path
  2019-09-27  8:40   ` Greg Kurz
@ 2019-09-30  1:39     ` David Gibson
  0 siblings, 0 replies; 83+ messages in thread
From: David Gibson @ 2019-09-30  1:39 UTC (permalink / raw)
  To: Greg Kurz
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

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

On Fri, Sep 27, 2019 at 10:40:14AM +0200, Greg Kurz wrote:
> On Fri, 27 Sep 2019 15:50:12 +1000
> David Gibson <david@gibson.dropbear.id.au> wrote:
> 
> > spapr_xive_irq_claim() returns a bool to indicate if it succeeded.
> > But most of the callers and one callee use int return values and/or an
> > Error * with more information instead.  In any case, ints are a more
> > common idiom for success/failure states than bools (one never knows
> > what sense they'll be in).
> > 
> > So instead change to an int return value to indicate presence of error
> > + an Error * to describe the details through that call chain.
> > 
> > It also didn't actually check if the irq was already claimed, which is
> > one of the primary purposes of the claim path, so do that.
> > 
> > spapr_xive_irq_free() also returned a bool... which no callers checked
> > and was always true, so just drop it.
> > 
> > Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> > Reviewed-by: Cédric Le Goater <clg@kaod.org>
> > ---
> >  hw/intc/spapr_xive.c        | 20 +++++++++-----------
> >  hw/intc/spapr_xive_kvm.c    |  8 ++++----
> >  hw/ppc/spapr_irq.c          | 14 ++++++++------
> >  include/hw/ppc/spapr_xive.h |  4 ++--
> >  include/hw/ppc/xive.h       |  2 +-
> >  5 files changed, 24 insertions(+), 24 deletions(-)
> > 
> > diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
> > index 47b5ec0b56..04879abf2e 100644
> > --- a/hw/intc/spapr_xive.c
> > +++ b/hw/intc/spapr_xive.c
> > @@ -528,12 +528,17 @@ static void spapr_xive_register_types(void)
> >  
> >  type_init(spapr_xive_register_types)
> >  
> > -bool spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi)
> > +int spapr_xive_irq_claim(SpaprXive *xive, int lisn, bool lsi, Error **errp)
> >  {
> >      XiveSource *xsrc = &xive->source;
> >  
> >      assert(lisn < xive->nr_irqs);
> >  
> > +    if (xive_eas_is_valid(&xive->eat[lisn])) {
> > +        error_setg(errp, "IRQ %d is not free", lisn);
> > +        return -EBUSY;
> > +    }
> > +
> >      /*
> >       * Set default values when allocating an IRQ number
> >       */
> > @@ -543,24 +548,17 @@ bool spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi)
> >      }
> >  
> >      if (kvm_irqchip_in_kernel()) {
> > -        Error *local_err = NULL;
> > -
> > -        kvmppc_xive_source_reset_one(xsrc, lisn, &local_err);
> > -        if (local_err) {
> > -            error_report_err(local_err);
> > -            return false;
> > -        }
> > +        return kvmppc_xive_source_reset_one(xsrc, lisn, errp);
> >      }
> >  
> > -    return true;
> > +    return 0;
> >  }
> >  
> > -bool spapr_xive_irq_free(SpaprXive *xive, uint32_t lisn)
> > +void spapr_xive_irq_free(SpaprXive *xive, int lisn)
> >  {
> >      assert(lisn < xive->nr_irqs);
> >  
> >      xive->eat[lisn].w &= cpu_to_be64(~EAS_VALID);
> > -    return true;
> >  }
> >  
> >  /*
> > diff --git a/hw/intc/spapr_xive_kvm.c b/hw/intc/spapr_xive_kvm.c
> > index 2006f96aec..51b334b676 100644
> > --- a/hw/intc/spapr_xive_kvm.c
> > +++ b/hw/intc/spapr_xive_kvm.c
> > @@ -232,14 +232,14 @@ void kvmppc_xive_sync_source(SpaprXive *xive, uint32_t lisn, Error **errp)
> >   * only need to inform the KVM XIVE device about their type: LSI or
> >   * MSI.
> >   */
> > -void kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **errp)
> > +int kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **errp)
> >  {
> >      SpaprXive *xive = SPAPR_XIVE(xsrc->xive);
> >      uint64_t state = 0;
> >  
> >      /* The KVM XIVE device is not in use */
> >      if (xive->fd == -1) {
> > -        return;
> > +        return -ENODEV;
> >      }
> >  
> >      if (xive_source_irq_is_lsi(xsrc, srcno)) {
> > @@ -249,8 +249,8 @@ void kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **errp)
> >          }
> >      }
> >  
> > -    kvm_device_access(xive->fd, KVM_DEV_XIVE_GRP_SOURCE, srcno, &state,
> > -                      true, errp);
> > +    return kvm_device_access(xive->fd, KVM_DEV_XIVE_GRP_SOURCE, srcno, &state,
> > +                             true, errp);
> >  }
> >  
> >  static void kvmppc_xive_source_reset(XiveSource *xsrc, Error **errp)
> > diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> > index da9e80b24e..4951329959 100644
> > --- a/hw/ppc/spapr_irq.c
> > +++ b/hw/ppc/spapr_irq.c
> > @@ -246,7 +246,13 @@ static void spapr_irq_init_xive(SpaprMachineState *spapr, Error **errp)
> >  
> >      /* Enable the CPU IPIs */
> >      for (i = 0; i < nr_servers; ++i) {
> > -        spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i, false);
> > +        Error *local_err = NULL;
> > +
> > +        spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i, false, &local_err);
> > +        if (local_err) {
> > +            error_propagate(errp, local_err);
> > +            return;
> > +        }
> 
> Quoting the changelog
> 
> > So instead change to an int return value to indicate presence of error
> > + an Error * to describe the details through that call chain.
> 
> Shouldn't this rather be:
> 
>         if (spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i, false, errp)) {
>             return;
>         }
> 
> ?

Yes, yes it should.  Fixed now.

> 
> With or without that fixed,
> 
> Reviewed-by: Greg Kurz <groug@kaod.org>
> 
> >      }
> >  
> >      spapr_xive_hcall_init(spapr);
> > @@ -255,11 +261,7 @@ static void spapr_irq_init_xive(SpaprMachineState *spapr, Error **errp)
> >  static int spapr_irq_claim_xive(SpaprMachineState *spapr, int irq, bool lsi,
> >                                  Error **errp)
> >  {
> > -    if (!spapr_xive_irq_claim(spapr->xive, irq, lsi)) {
> > -        error_setg(errp, "IRQ %d is invalid", irq);
> > -        return -1;
> > -    }
> > -    return 0;
> > +    return spapr_xive_irq_claim(spapr->xive, irq, lsi, errp);
> >  }
> >  
> >  static void spapr_irq_free_xive(SpaprMachineState *spapr, int irq)
> > diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h
> > index bfd40f01d8..0df20a6590 100644
> > --- a/include/hw/ppc/spapr_xive.h
> > +++ b/include/hw/ppc/spapr_xive.h
> > @@ -54,8 +54,8 @@ typedef struct SpaprXive {
> >   */
> >  #define SPAPR_XIVE_BLOCK_ID 0x0
> >  
> > -bool spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi);
> > -bool spapr_xive_irq_free(SpaprXive *xive, uint32_t lisn);
> > +int spapr_xive_irq_claim(SpaprXive *xive, int lisn, bool lsi, Error **errp);
> > +void spapr_xive_irq_free(SpaprXive *xive, int lisn);
> >  void spapr_xive_pic_print_info(SpaprXive *xive, Monitor *mon);
> >  int spapr_xive_post_load(SpaprXive *xive, int version_id);
> >  
> > diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
> > index 6d38755f84..fd3319bd32 100644
> > --- a/include/hw/ppc/xive.h
> > +++ b/include/hw/ppc/xive.h
> > @@ -425,7 +425,7 @@ static inline uint32_t xive_nvt_cam_line(uint8_t nvt_blk, uint32_t nvt_idx)
> >   * KVM XIVE device helpers
> >   */
> >  
> > -void kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **errp);
> > +int kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **errp);
> >  void kvmppc_xive_source_set_irq(void *opaque, int srcno, int val);
> >  void kvmppc_xive_cpu_connect(XiveTCTX *tctx, Error **errp);
> >  void kvmppc_xive_cpu_synchronize_state(XiveTCTX *tctx, Error **errp);
> 

-- 
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] 83+ messages in thread

* Re: [PATCH v2 21/33] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController
  2019-09-27 10:16   ` Greg Kurz
@ 2019-09-30  1:49     ` David Gibson
  2019-09-30  5:28       ` Cédric Le Goater
  2019-09-30  2:37     ` David Gibson
  1 sibling, 1 reply; 83+ messages in thread
From: David Gibson @ 2019-09-30  1:49 UTC (permalink / raw)
  To: Greg Kurz
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

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

On Fri, Sep 27, 2019 at 12:16:49PM +0200, Greg Kurz wrote:
> On Fri, 27 Sep 2019 15:50:16 +1000
> David Gibson <david@gibson.dropbear.id.au> wrote:
> 
> > This method essentially represents code which belongs to the interrupt
> > controller, but needs to be called on all possible intcs, rather than
> > just the currently active one.  The "dual" version therefore calls
> > into the xics and xive versions confusingly.
> > 
> > Handle this more directly, by making it instead a method on the intc
> > backend, and always calling it on every backend that exists.
> > 
> > While we're there, streamline the error reporting a bit.
> > 
> > Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
[snip]
> > @@ -525,6 +469,30 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
> >  /*
> >   * sPAPR IRQ frontend routines for devices
> >   */
> > +int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
> > +                              PowerPCCPU *cpu, Error **errp)
> > +{
> > +    if (spapr->xive) {
> > +        SpaprInterruptController *intc = SPAPR_INTC(spapr->xive);
> > +        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
> > +
> > +        if (sicc->cpu_intc_create(intc, cpu, errp) < 0) {
> > +            return -1;
> > +        }
> > +    }
> > +
> > +    if (spapr->ics) {
> > +        SpaprInterruptController *intc = SPAPR_INTC(spapr->ics);
> > +        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
> > +
> > +        if (sicc->cpu_intc_create(intc, cpu, errp) < 0) {
> > +            return -1;
> > +        }
> > +    }
> > +
> 
> Instead of these hooks, what about open-coding spapr_xive_cpu_intc_create()
> and xics_spapr_cpu_intc_create() directly here, like you already did for the
> ICS and the XIVE objects in spapr_irq_init() ?

I'd prefer not to.  The idea is I want to treat this as basically:

	foreach_possible_intc(intc)
		intc::cpu_intc_create(...)

If I find time I might indeed replace the explicit ics and xive
pointers with just an array of SpaprInterruptController *.

init is fundamentally different though, because it needs to *create*
that list (implicit or explicit) of possible intcs, so it can't be
based on an existing one.

> 
> > +    return 0;
> > +}
> > +
> >  void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
> >  {
> >      MachineState *machine = MACHINE(spapr);
> > @@ -763,7 +731,6 @@ SpaprIrq spapr_irq_xics_legacy = {
> >      .free        = spapr_irq_free_xics,
> >      .print_info  = spapr_irq_print_info_xics,
> >      .dt_populate = spapr_dt_xics,
> > -    .cpu_intc_create = spapr_irq_cpu_intc_create_xics,
> >      .post_load   = spapr_irq_post_load_xics,
> >      .reset       = spapr_irq_reset_xics,
> >      .set_irq     = spapr_irq_set_irq_xics,
> > diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> > index b9398e0be3..30d660ff1e 100644
> > --- a/include/hw/ppc/spapr_irq.h
> > +++ b/include/hw/ppc/spapr_irq.h
> > @@ -43,8 +43,22 @@ typedef struct SpaprInterruptController SpaprInterruptController;
> >  
> >  typedef struct SpaprInterruptControllerClass {
> >      InterfaceClass parent;
> > +
> > +    /*
> > +     * These methods will typically be called on all intcs, active and
> > +     * inactive
> > +     */
> > +    int (*cpu_intc_create)(SpaprInterruptController *intc,
> > +                            PowerPCCPU *cpu, Error **errp);
> >  } SpaprInterruptControllerClass;
> >  
> > +void spapr_irq_print_info(SpaprMachineState *spapr, Monitor *mon);
> > +void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers,
> > +                  void *fdt, uint32_t phandle);
> 
> These two ^^ seem to belong to later patches.
> 
> > +int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
> > +                              PowerPCCPU *cpu, Error **errp);
> > +
> > +
> >  void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis);
> >  int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align,
> >                          Error **errp);
> > @@ -61,8 +75,6 @@ typedef struct SpaprIrq {
> >      void (*print_info)(SpaprMachineState *spapr, Monitor *mon);
> >      void (*dt_populate)(SpaprMachineState *spapr, uint32_t nr_servers,
> >                          void *fdt, uint32_t phandle);
> > -    void (*cpu_intc_create)(SpaprMachineState *spapr, PowerPCCPU *cpu,
> > -                            Error **errp);
> >      int (*post_load)(SpaprMachineState *spapr, int version_id);
> >      void (*reset)(SpaprMachineState *spapr, Error **errp);
> >      void (*set_irq)(void *opaque, int srcno, int val);
> 

-- 
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] 83+ messages in thread

* Re: [PATCH v2 21/33] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController
  2019-09-27 10:16   ` Greg Kurz
  2019-09-30  1:49     ` David Gibson
@ 2019-09-30  2:37     ` David Gibson
  1 sibling, 0 replies; 83+ messages in thread
From: David Gibson @ 2019-09-30  2:37 UTC (permalink / raw)
  To: Greg Kurz
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

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

On Fri, Sep 27, 2019 at 12:16:49PM +0200, Greg Kurz wrote:
> On Fri, 27 Sep 2019 15:50:16 +1000
> David Gibson <david@gibson.dropbear.id.au> wrote:
> 
> > This method essentially represents code which belongs to the interrupt
> > controller, but needs to be called on all possible intcs, rather than
> > just the currently active one.  The "dual" version therefore calls
> > into the xics and xive versions confusingly.
> > 
> > Handle this more directly, by making it instead a method on the intc
> > backend, and always calling it on every backend that exists.
> > 
> > While we're there, streamline the error reporting a bit.
> > 
> > Signed-off-by: David Gibson <david@gibson.dropbear.id.au>

[snip]
> > +void spapr_irq_print_info(SpaprMachineState *spapr, Monitor *mon);
> > +void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers,
> > +                  void *fdt, uint32_t phandle);
> 
> These two ^^ seem to belong to later patches.

Oops, yes.  I've moved those to where they belong.

> 
> > +int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
> > +                              PowerPCCPU *cpu, Error **errp);
> > +
> > +
> >  void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis);
> >  int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align,
> >                          Error **errp);
> > @@ -61,8 +75,6 @@ typedef struct SpaprIrq {
> >      void (*print_info)(SpaprMachineState *spapr, Monitor *mon);
> >      void (*dt_populate)(SpaprMachineState *spapr, uint32_t nr_servers,
> >                          void *fdt, uint32_t phandle);
> > -    void (*cpu_intc_create)(SpaprMachineState *spapr, PowerPCCPU *cpu,
> > -                            Error **errp);
> >      int (*post_load)(SpaprMachineState *spapr, int version_id);
> >      void (*reset)(SpaprMachineState *spapr, Error **errp);
> >      void (*set_irq)(void *opaque, int srcno, int val);
> 

-- 
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] 83+ messages in thread

* Re: [PATCH v2 22/33] spapr, xics, xive: Move irq claim and free from SpaprIrq to SpaprInterruptController
  2019-09-27 12:16   ` Greg Kurz
@ 2019-09-30  2:39     ` David Gibson
  2019-09-30  5:36       ` Cédric Le Goater
  0 siblings, 1 reply; 83+ messages in thread
From: David Gibson @ 2019-09-30  2:39 UTC (permalink / raw)
  To: Greg Kurz
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

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

On Fri, Sep 27, 2019 at 02:16:12PM +0200, Greg Kurz wrote:
> On Fri, 27 Sep 2019 15:50:17 +1000
> David Gibson <david@gibson.dropbear.id.au> wrote:
> 
> > These methods, like cpu_intc_create, really belong to the interrupt
> > controller, but need to be called on all possible intcs.
> > 
> > Like cpu_intc_create, therefore, make them methods on the intc and
> > always call it for all existing intcs.
> > 
> > Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> > ---
> >  hw/intc/spapr_xive.c        |  71 +++++++++++-----------
> >  hw/intc/xics_spapr.c        |  29 +++++++++
> >  hw/ppc/spapr_irq.c          | 114 ++++++++++++------------------------
> >  include/hw/ppc/spapr_irq.h  |   5 +-
> >  include/hw/ppc/spapr_xive.h |   2 -
> >  5 files changed, 107 insertions(+), 114 deletions(-)
> > 
> > diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
> > index 9338daba3d..ff1a175b44 100644
> > --- a/hw/intc/spapr_xive.c
> > +++ b/hw/intc/spapr_xive.c
> > @@ -487,6 +487,42 @@ static const VMStateDescription vmstate_spapr_xive = {
> >      },
> >  };
> >  
> > +static int spapr_xive_claim_irq(SpaprInterruptController *intc, int lisn,
> > +                                bool lsi, Error **errp)
> > +{
> > +    SpaprXive *xive = SPAPR_XIVE(intc);
> > +    XiveSource *xsrc = &xive->source;
> > +
> > +    assert(lisn < xive->nr_irqs);
> > +
> > +    if (xive_eas_is_valid(&xive->eat[lisn])) {
> > +        error_setg(errp, "IRQ %d is not free", lisn);
> > +        return -EBUSY;
> > +    }
> > +
> > +    /*
> > +     * Set default values when allocating an IRQ number
> > +     */
> > +    xive->eat[lisn].w |= cpu_to_be64(EAS_VALID | EAS_MASKED);
> > +    if (lsi) {
> > +        xive_source_irq_set_lsi(xsrc, lisn);
> > +    }
> > +
> > +    if (kvm_irqchip_in_kernel()) {
> > +        return kvmppc_xive_source_reset_one(xsrc, lisn, errp);
> > +    }
> > +
> > +    return 0;
> > +}
> > +
> > +static void spapr_xive_free_irq(SpaprInterruptController *intc, int lisn)
> > +{
> > +    SpaprXive *xive = SPAPR_XIVE(intc);
> > +    assert(lisn < xive->nr_irqs);
> > +
> > +    xive->eat[lisn].w &= cpu_to_be64(~EAS_VALID);
> > +}
> > +
> >  static Property spapr_xive_properties[] = {
> >      DEFINE_PROP_UINT32("nr-irqs", SpaprXive, nr_irqs, 0),
> >      DEFINE_PROP_UINT32("nr-ends", SpaprXive, nr_ends, 0),
> > @@ -536,6 +572,8 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data)
> >      xrc->get_tctx = spapr_xive_get_tctx;
> >  
> >      sicc->cpu_intc_create = spapr_xive_cpu_intc_create;
> > +    sicc->claim_irq = spapr_xive_claim_irq;
> > +    sicc->free_irq = spapr_xive_free_irq;
> >  }
> >  
> >  static const TypeInfo spapr_xive_info = {
> > @@ -557,39 +595,6 @@ static void spapr_xive_register_types(void)
> >  
> >  type_init(spapr_xive_register_types)
> >  
> > -int spapr_xive_irq_claim(SpaprXive *xive, int lisn, bool lsi, Error **errp)
> > -{
> > -    XiveSource *xsrc = &xive->source;
> > -
> > -    assert(lisn < xive->nr_irqs);
> > -
> > -    if (xive_eas_is_valid(&xive->eat[lisn])) {
> > -        error_setg(errp, "IRQ %d is not free", lisn);
> > -        return -EBUSY;
> > -    }
> > -
> > -    /*
> > -     * Set default values when allocating an IRQ number
> > -     */
> > -    xive->eat[lisn].w |= cpu_to_be64(EAS_VALID | EAS_MASKED);
> > -    if (lsi) {
> > -        xive_source_irq_set_lsi(xsrc, lisn);
> > -    }
> > -
> > -    if (kvm_irqchip_in_kernel()) {
> > -        return kvmppc_xive_source_reset_one(xsrc, lisn, errp);
> > -    }
> > -
> > -    return 0;
> > -}
> > -
> > -void spapr_xive_irq_free(SpaprXive *xive, int lisn)
> > -{
> > -    assert(lisn < xive->nr_irqs);
> > -
> > -    xive->eat[lisn].w &= cpu_to_be64(~EAS_VALID);
> > -}
> > -
> >  /*
> >   * XIVE hcalls
> >   *
> > diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
> > index 946311b858..224fe1efcd 100644
> > --- a/hw/intc/xics_spapr.c
> > +++ b/hw/intc/xics_spapr.c
> > @@ -346,6 +346,33 @@ static int xics_spapr_cpu_intc_create(SpaprInterruptController *intc,
> >      return 0;
> >  }
> >  
> > +static int xics_spapr_claim_irq(SpaprInterruptController *intc, int irq,
> > +                                bool lsi, Error **errp)
> > +{
> > +    ICSState *ics = ICS_SPAPR(intc);
> > +
> > +    assert(ics);
> > +    assert(ics_valid_irq(ics, irq));
> > +
> > +    if (!ics_irq_free(ics, irq - ics->offset)) {
> > +        error_setg(errp, "IRQ %d is not free", irq);
> > +        return -EBUSY;
> > +    }
> > +
> > +    ics_set_irq_type(ics, irq - ics->offset, lsi);
> > +    return 0;
> > +}
> > +
> > +static void xics_spapr_free_irq(SpaprInterruptController *intc, int irq)
> > +{
> > +    ICSState *ics = ICS_SPAPR(intc);
> > +    uint32_t srcno = irq - ics->offset;
> > +
> > +    assert(ics_valid_irq(ics, irq));
> > +
> > +    memset(&ics->irqs[srcno], 0, sizeof(ICSIRQState));
> > +}
> > +
> >  static void ics_spapr_class_init(ObjectClass *klass, void *data)
> >  {
> >      DeviceClass *dc = DEVICE_CLASS(klass);
> > @@ -355,6 +382,8 @@ static void ics_spapr_class_init(ObjectClass *klass, void *data)
> >      device_class_set_parent_realize(dc, ics_spapr_realize,
> >                                      &isc->parent_realize);
> >      sicc->cpu_intc_create = xics_spapr_cpu_intc_create;
> > +    sicc->claim_irq = xics_spapr_claim_irq;
> > +    sicc->free_irq = xics_spapr_free_irq;
> >  }
> >  
> >  static const TypeInfo ics_spapr_info = {
> > diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> > index a855dfe4e9..ea44378d8c 100644
> > --- a/hw/ppc/spapr_irq.c
> > +++ b/hw/ppc/spapr_irq.c
> > @@ -98,33 +98,6 @@ static void spapr_irq_init_kvm(SpaprMachineState *spapr,
> >   * XICS IRQ backend.
> >   */
> >  
> > -static int spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
> > -                                Error **errp)
> > -{
> > -    ICSState *ics = spapr->ics;
> > -
> > -    assert(ics);
> > -    assert(ics_valid_irq(ics, irq));
> > -
> > -    if (!ics_irq_free(ics, irq - ics->offset)) {
> > -        error_setg(errp, "IRQ %d is not free", irq);
> > -        return -1;
> > -    }
> > -
> > -    ics_set_irq_type(ics, irq - ics->offset, lsi);
> > -    return 0;
> > -}
> > -
> > -static void spapr_irq_free_xics(SpaprMachineState *spapr, int irq)
> > -{
> > -    ICSState *ics = spapr->ics;
> > -    uint32_t srcno = irq - ics->offset;
> > -
> > -    assert(ics_valid_irq(ics, irq));
> > -
> > -    memset(&ics->irqs[srcno], 0, sizeof(ICSIRQState));
> > -}
> > -
> >  static void spapr_irq_print_info_xics(SpaprMachineState *spapr, Monitor *mon)
> >  {
> >      CPUState *cs;
> > @@ -182,8 +155,6 @@ SpaprIrq spapr_irq_xics = {
> >      .xics        = true,
> >      .xive        = false,
> >  
> > -    .claim       = spapr_irq_claim_xics,
> > -    .free        = spapr_irq_free_xics,
> >      .print_info  = spapr_irq_print_info_xics,
> >      .dt_populate = spapr_dt_xics,
> >      .post_load   = spapr_irq_post_load_xics,
> > @@ -196,17 +167,6 @@ SpaprIrq spapr_irq_xics = {
> >   * XIVE IRQ backend.
> >   */
> >  
> > -static int spapr_irq_claim_xive(SpaprMachineState *spapr, int irq, bool lsi,
> > -                                Error **errp)
> > -{
> > -    return spapr_xive_irq_claim(spapr->xive, irq, lsi, errp);
> > -}
> > -
> > -static void spapr_irq_free_xive(SpaprMachineState *spapr, int irq)
> > -{
> > -    spapr_xive_irq_free(spapr->xive, irq);
> > -}
> > -
> >  static void spapr_irq_print_info_xive(SpaprMachineState *spapr,
> >                                        Monitor *mon)
> >  {
> > @@ -272,8 +232,6 @@ SpaprIrq spapr_irq_xive = {
> >      .xics        = false,
> >      .xive        = true,
> >  
> > -    .claim       = spapr_irq_claim_xive,
> > -    .free        = spapr_irq_free_xive,
> >      .print_info  = spapr_irq_print_info_xive,
> >      .dt_populate = spapr_dt_xive,
> >      .post_load   = spapr_irq_post_load_xive,
> > @@ -301,33 +259,6 @@ static SpaprIrq *spapr_irq_current(SpaprMachineState *spapr)
> >          &spapr_irq_xive : &spapr_irq_xics;
> >  }
> >  
> > -static int spapr_irq_claim_dual(SpaprMachineState *spapr, int irq, bool lsi,
> > -                                Error **errp)
> > -{
> > -    Error *local_err = NULL;
> > -    int ret;
> > -
> > -    ret = spapr_irq_xics.claim(spapr, irq, lsi, &local_err);
> > -    if (local_err) {
> > -        error_propagate(errp, local_err);
> > -        return ret;
> > -    }
> > -
> > -    ret = spapr_irq_xive.claim(spapr, irq, lsi, &local_err);
> > -    if (local_err) {
> > -        error_propagate(errp, local_err);
> > -        return ret;
> > -    }
> > -
> > -    return ret;
> > -}
> > -
> > -static void spapr_irq_free_dual(SpaprMachineState *spapr, int irq)
> > -{
> > -    spapr_irq_xics.free(spapr, irq);
> > -    spapr_irq_xive.free(spapr, irq);
> > -}
> > -
> >  static void spapr_irq_print_info_dual(SpaprMachineState *spapr, Monitor *mon)
> >  {
> >      spapr_irq_current(spapr)->print_info(spapr, mon);
> > @@ -401,8 +332,6 @@ SpaprIrq spapr_irq_dual = {
> >      .xics        = true,
> >      .xive        = true,
> >  
> > -    .claim       = spapr_irq_claim_dual,
> > -    .free        = spapr_irq_free_dual,
> >      .print_info  = spapr_irq_print_info_dual,
> >      .dt_populate = spapr_irq_dt_populate_dual,
> >      .post_load   = spapr_irq_post_load_dual,
> > @@ -567,10 +496,12 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
> >  
> >          /* Enable the CPU IPIs */
> >          for (i = 0; i < nr_servers; ++i) {
> > +            SpaprInterruptControllerClass *sicc
> > +                = SPAPR_INTC_GET_CLASS(spapr->xive);
> >              Error *local_err = NULL;
> >  
> > -            spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i,
> > -                                 false, &local_err);
> > +            sicc->claim_irq(SPAPR_INTC(spapr->xive), SPAPR_IRQ_IPI + i,
> > +                            false, &local_err);
> >              if (local_err) {
> >                  goto out;
> >              }
> > @@ -588,10 +519,30 @@ out:
> >  
> >  int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
> >  {
> > +    int rc;
> > +
> >      assert(irq >= SPAPR_XIRQ_BASE);
> >      assert(irq < (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
> >  
> > -    return spapr->irq->claim(spapr, irq, lsi, errp);
> > +    if (spapr->xive) {
> > +        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(spapr->xive);
> > +
> > +        rc = sicc->claim_irq(SPAPR_INTC(spapr->xive), irq, lsi, errp);
> > +        if (rc < 0) {
> > +            return rc;
> > +        }
> > +    }
> > +
> > +    if (spapr->ics) {
> > +        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(spapr->ics);
> > +
> > +        rc = sicc->claim_irq(SPAPR_INTC(spapr->ics), irq, lsi, errp);
> > +        if (rc < 0) {
> > +            return rc;
> > +        }
> > +    }
> > +
> 
> We don't really need an indirection here since we explicitly check
> spapr->xive and spapr->ics. Calling directly spapr_xive_claim_irq() and
> xics_spapr_claim_irq() would allow to avoid the method boiler plate and
> be more explicit IMHO.
> 
> > +    return 0;
> >  }
> >  
> >  void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
> > @@ -602,7 +553,18 @@ void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
> >      assert((irq + num) <= (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
> >  
> >      for (i = irq; i < (irq + num); i++) {
> > -        spapr->irq->free(spapr, irq);
> > +        if (spapr->xive) {
> > +            SpaprInterruptController *intc = SPAPR_INTC(spapr->xive);
> > +            SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
> > +
> > +            sicc->free_irq(intc, irq);
> > +        }
> > +        if (spapr->ics) {
> > +            SpaprInterruptController *intc = SPAPR_INTC(spapr->ics);
> > +            SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
> > +
> > +            sicc->free_irq(intc, irq);
> > +        }
> 
> Same here.

As with cpu_intc_create(), I'd prefer to keep both of these as is, but
I'll look at replacing spapr->ics and spapr->xive with something like
spapr->all_intcs[].

> 
> >      }
> >  }
> >  
> > @@ -727,8 +689,6 @@ SpaprIrq spapr_irq_xics_legacy = {
> >      .xics        = true,
> >      .xive        = false,
> >  
> > -    .claim       = spapr_irq_claim_xics,
> > -    .free        = spapr_irq_free_xics,
> >      .print_info  = spapr_irq_print_info_xics,
> >      .dt_populate = spapr_dt_xics,
> >      .post_load   = spapr_irq_post_load_xics,
> > diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> > index 30d660ff1e..616086f9bb 100644
> > --- a/include/hw/ppc/spapr_irq.h
> > +++ b/include/hw/ppc/spapr_irq.h
> > @@ -50,6 +50,9 @@ typedef struct SpaprInterruptControllerClass {
> >       */
> >      int (*cpu_intc_create)(SpaprInterruptController *intc,
> >                              PowerPCCPU *cpu, Error **errp);
> > +    int (*claim_irq)(SpaprInterruptController *intc, int irq, bool lsi,
> > +                     Error **errp);
> > +    void (*free_irq)(SpaprInterruptController *intc, int irq);
> >  } SpaprInterruptControllerClass;
> >  
> >  void spapr_irq_print_info(SpaprMachineState *spapr, Monitor *mon);
> > @@ -70,8 +73,6 @@ typedef struct SpaprIrq {
> >      bool        xics;
> >      bool        xive;
> >  
> > -    int (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
> > -    void (*free)(SpaprMachineState *spapr, int irq);
> >      void (*print_info)(SpaprMachineState *spapr, Monitor *mon);
> >      void (*dt_populate)(SpaprMachineState *spapr, uint32_t nr_servers,
> >                          void *fdt, uint32_t phandle);
> > diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h
> > index 0df20a6590..8f875673f5 100644
> > --- a/include/hw/ppc/spapr_xive.h
> > +++ b/include/hw/ppc/spapr_xive.h
> > @@ -54,8 +54,6 @@ typedef struct SpaprXive {
> >   */
> >  #define SPAPR_XIVE_BLOCK_ID 0x0
> >  
> > -int spapr_xive_irq_claim(SpaprXive *xive, int lisn, bool lsi, Error **errp);
> > -void spapr_xive_irq_free(SpaprXive *xive, int lisn);
> >  void spapr_xive_pic_print_info(SpaprXive *xive, Monitor *mon);
> >  int spapr_xive_post_load(SpaprXive *xive, int version_id);
> >  
> 

-- 
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] 83+ messages in thread

* Re: [PATCH v2 24/33] spapr, xics, xive: Move set_irq from SpaprIrq to SpaprInterruptController
  2019-09-27 14:27   ` Greg Kurz
@ 2019-09-30  2:41     ` David Gibson
  2019-09-30  7:22       ` Greg Kurz
  0 siblings, 1 reply; 83+ messages in thread
From: David Gibson @ 2019-09-30  2:41 UTC (permalink / raw)
  To: Greg Kurz
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

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

On Fri, Sep 27, 2019 at 04:27:12PM +0200, Greg Kurz wrote:
> On Fri, 27 Sep 2019 15:50:19 +1000
> David Gibson <david@gibson.dropbear.id.au> wrote:
> 
> > This method depends only on the active irq controller.  Now that we've
> > formalized the notion of active controller we can dispatch directly through
> > that, rather than dispatching via SpaprIrq with the dual version having
> > to do a second conditional dispatch.
> > 
> > Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> > ---
> >  hw/intc/spapr_xive.c       | 12 +++++++++++
> >  hw/intc/xics_spapr.c       |  9 +++++++++
> >  hw/ppc/spapr_irq.c         | 41 ++++++++++----------------------------
> >  include/hw/ppc/spapr_irq.h |  4 +++-
> >  4 files changed, 34 insertions(+), 32 deletions(-)
> > 
> > diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
> > index ff1a175b44..52d5e71793 100644
> > --- a/hw/intc/spapr_xive.c
> > +++ b/hw/intc/spapr_xive.c
> > @@ -553,6 +553,17 @@ static int spapr_xive_cpu_intc_create(SpaprInterruptController *intc,
> >      return 0;
> >  }
> >  
> > +static void spapr_xive_set_irq(SpaprInterruptController *intc, int irq, int val)
> > +{
> > +    SpaprXive *xive = SPAPR_XIVE(intc);
> > +
> > +    if (kvm_irqchip_in_kernel()) {
> > +        kvmppc_xive_source_set_irq(&xive->source, irq, val);
> > +    } else {
> > +        xive_source_set_irq(&xive->source, irq, val);
> > +    }
> > +}
> > +
> >  static void spapr_xive_class_init(ObjectClass *klass, void *data)
> >  {
> >      DeviceClass *dc = DEVICE_CLASS(klass);
> > @@ -574,6 +585,7 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data)
> >      sicc->cpu_intc_create = spapr_xive_cpu_intc_create;
> >      sicc->claim_irq = spapr_xive_claim_irq;
> >      sicc->free_irq = spapr_xive_free_irq;
> > +    sicc->set_irq = spapr_xive_set_irq;
> >  }
> >  
> >  static const TypeInfo spapr_xive_info = {
> > diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
> > index 224fe1efcd..02372697f6 100644
> > --- a/hw/intc/xics_spapr.c
> > +++ b/hw/intc/xics_spapr.c
> > @@ -373,6 +373,14 @@ static void xics_spapr_free_irq(SpaprInterruptController *intc, int irq)
> >      memset(&ics->irqs[srcno], 0, sizeof(ICSIRQState));
> >  }
> >  
> > +static void xics_spapr_set_irq(SpaprInterruptController *intc, int irq, int val)
> > +{
> > +    ICSState *ics = ICS_SPAPR(intc);
> > +    uint32_t srcno = irq - ics->offset;
> > +
> > +    ics_set_irq(ics, srcno, val);
> 
> And we have:
> 
> void ics_set_irq(void *opaque, int srcno, int val)
> {
>     ICSState *ics = (ICSState *)opaque;
> 
>     if (kvm_irqchip_in_kernel()) {
>         ics_kvm_set_irq(ics, srcno, val);
>         return;
>     }
> 
>     if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI) {
>         ics_set_irq_lsi(ics, srcno, val);
>     } else {
>         ics_set_irq_msi(ics, srcno, val);
>     }
> }
> 
> The kvm_irqchip_in_kernel() block would fit better in xics_spapr_set_irq(),
> like it is already the case for XIVE.

Hmm.. I don't really see why you say that.

> Maybe do it now while here ?
> 
> Anyway,
> 
> Reviewed-by: Greg Kurz <groug@kaod.org>
> 
> > +}
> > +
> >  static void ics_spapr_class_init(ObjectClass *klass, void *data)
> >  {
> >      DeviceClass *dc = DEVICE_CLASS(klass);
> > @@ -384,6 +392,7 @@ static void ics_spapr_class_init(ObjectClass *klass, void *data)
> >      sicc->cpu_intc_create = xics_spapr_cpu_intc_create;
> >      sicc->claim_irq = xics_spapr_claim_irq;
> >      sicc->free_irq = xics_spapr_free_irq;
> > +    sicc->set_irq = xics_spapr_set_irq;
> >  }
> >  
> >  static const TypeInfo ics_spapr_info = {
> > diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> > index dfa875b7cd..4922062908 100644
> > --- a/hw/ppc/spapr_irq.c
> > +++ b/hw/ppc/spapr_irq.c
> > @@ -123,14 +123,6 @@ static int spapr_irq_post_load_xics(SpaprMachineState *spapr, int version_id)
> >      return 0;
> >  }
> >  
> > -static void spapr_irq_set_irq_xics(void *opaque, int irq, int val)
> > -{
> > -    SpaprMachineState *spapr = opaque;
> > -    uint32_t srcno = irq - spapr->ics->offset;
> > -
> > -    ics_set_irq(spapr->ics, srcno, val);
> > -}
> > -
> >  static void spapr_irq_reset_xics(SpaprMachineState *spapr, Error **errp)
> >  {
> >      Error *local_err = NULL;
> > @@ -159,7 +151,6 @@ SpaprIrq spapr_irq_xics = {
> >      .dt_populate = spapr_dt_xics,
> >      .post_load   = spapr_irq_post_load_xics,
> >      .reset       = spapr_irq_reset_xics,
> > -    .set_irq     = spapr_irq_set_irq_xics,
> >      .init_kvm    = spapr_irq_init_kvm_xics,
> >  };
> >  
> > @@ -208,17 +199,6 @@ static void spapr_irq_reset_xive(SpaprMachineState *spapr, Error **errp)
> >      spapr_xive_mmio_set_enabled(spapr->xive, true);
> >  }
> >  
> > -static void spapr_irq_set_irq_xive(void *opaque, int irq, int val)
> > -{
> > -    SpaprMachineState *spapr = opaque;
> > -
> > -    if (kvm_irqchip_in_kernel()) {
> > -        kvmppc_xive_source_set_irq(&spapr->xive->source, irq, val);
> > -    } else {
> > -        xive_source_set_irq(&spapr->xive->source, irq, val);
> > -    }
> > -}
> > -
> >  static void spapr_irq_init_kvm_xive(SpaprMachineState *spapr, Error **errp)
> >  {
> >      if (kvm_enabled()) {
> > @@ -236,7 +216,6 @@ SpaprIrq spapr_irq_xive = {
> >      .dt_populate = spapr_dt_xive,
> >      .post_load   = spapr_irq_post_load_xive,
> >      .reset       = spapr_irq_reset_xive,
> > -    .set_irq     = spapr_irq_set_irq_xive,
> >      .init_kvm    = spapr_irq_init_kvm_xive,
> >  };
> >  
> > @@ -316,13 +295,6 @@ static void spapr_irq_reset_dual(SpaprMachineState *spapr, Error **errp)
> >      spapr_irq_current(spapr)->reset(spapr, errp);
> >  }
> >  
> > -static void spapr_irq_set_irq_dual(void *opaque, int irq, int val)
> > -{
> > -    SpaprMachineState *spapr = opaque;
> > -
> > -    spapr_irq_current(spapr)->set_irq(spapr, irq, val);
> > -}
> > -
> >  /*
> >   * Define values in sync with the XIVE and XICS backend
> >   */
> > @@ -336,7 +308,6 @@ SpaprIrq spapr_irq_dual = {
> >      .dt_populate = spapr_irq_dt_populate_dual,
> >      .post_load   = spapr_irq_post_load_dual,
> >      .reset       = spapr_irq_reset_dual,
> > -    .set_irq     = spapr_irq_set_irq_dual,
> >      .init_kvm    = NULL, /* should not be used */
> >  };
> >  
> > @@ -422,6 +393,15 @@ int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
> >      return 0;
> >  }
> >  
> > +static void spapr_set_irq(void *opaque, int irq, int level)
> > +{
> > +    SpaprMachineState *spapr = SPAPR_MACHINE(opaque);
> > +    SpaprInterruptControllerClass *sicc
> > +        = SPAPR_INTC_GET_CLASS(spapr->active_intc);
> > +
> > +    sicc->set_irq(spapr->active_intc, irq, level);
> > +}
> > +
> >  void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
> >  {
> >      MachineState *machine = MACHINE(spapr);
> > @@ -510,7 +490,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
> >          spapr_xive_hcall_init(spapr);
> >      }
> >  
> > -    spapr->qirqs = qemu_allocate_irqs(spapr->irq->set_irq, spapr,
> > +    spapr->qirqs = qemu_allocate_irqs(spapr_set_irq, spapr,
> >                                        spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
> >  
> >  out:
> > @@ -744,7 +724,6 @@ SpaprIrq spapr_irq_xics_legacy = {
> >      .dt_populate = spapr_dt_xics,
> >      .post_load   = spapr_irq_post_load_xics,
> >      .reset       = spapr_irq_reset_xics,
> > -    .set_irq     = spapr_irq_set_irq_xics,
> >      .init_kvm    = spapr_irq_init_kvm_xics,
> >  };
> >  
> > diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> > index 3102d152b2..8286a9aa63 100644
> > --- a/include/hw/ppc/spapr_irq.h
> > +++ b/include/hw/ppc/spapr_irq.h
> > @@ -56,6 +56,9 @@ typedef struct SpaprInterruptControllerClass {
> >      int (*claim_irq)(SpaprInterruptController *intc, int irq, bool lsi,
> >                       Error **errp);
> >      void (*free_irq)(SpaprInterruptController *intc, int irq);
> > +
> > +    /* These methods should only be called on the active intc */
> > +    void (*set_irq)(SpaprInterruptController *intc, int irq, int val);
> >  } SpaprInterruptControllerClass;
> >  
> >  void spapr_irq_update_active_intc(SpaprMachineState *spapr);
> > @@ -83,7 +86,6 @@ typedef struct SpaprIrq {
> >                          void *fdt, uint32_t phandle);
> >      int (*post_load)(SpaprMachineState *spapr, int version_id);
> >      void (*reset)(SpaprMachineState *spapr, Error **errp);
> > -    void (*set_irq)(void *opaque, int srcno, int val);
> >      void (*init_kvm)(SpaprMachineState *spapr, Error **errp);
> >  } SpaprIrq;
> >  
> 

-- 
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] 83+ messages in thread

* Re: [PATCH v2 32/33] spapr: Move SpaprIrq::nr_xirqs to SpaprMachineClass
  2019-09-27 15:22   ` Greg Kurz
@ 2019-09-30  2:44     ` David Gibson
  0 siblings, 0 replies; 83+ messages in thread
From: David Gibson @ 2019-09-30  2:44 UTC (permalink / raw)
  To: Greg Kurz
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

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

On Fri, Sep 27, 2019 at 05:22:16PM +0200, Greg Kurz wrote:
> On Fri, 27 Sep 2019 15:50:27 +1000
> David Gibson <david@gibson.dropbear.id.au> wrote:
> 
> > For the benefit of peripheral device allocation, the number of available
> > irqs really wants to be the same on a given machine type version,
> > regardless of what irq backends we are using.  That's the case now, but
> > only because we make sure the different SpaprIrq instances have the same
> > value except for the special legacy one.
> > 
> > Since this really only depends on machine type version, move the value to
> > SpaprMachineClass instead of SpaprIrq.  This also puts the code to set it
> > to the lower value on old machine types right next to setting
> > legacy_irq_allocation, which needs to go hand in hand.
> > 
> > Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> > ---
> >  hw/ppc/spapr.c             |  2 ++
> >  hw/ppc/spapr_irq.c         | 33 ++++++++++++++++-----------------
> >  include/hw/ppc/spapr.h     |  1 +
> >  include/hw/ppc/spapr_irq.h |  1 -
> >  4 files changed, 19 insertions(+), 18 deletions(-)
> > 
> > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> > index 34b693beba..7113249c89 100644
> > --- a/hw/ppc/spapr.c
> > +++ b/hw/ppc/spapr.c
> > @@ -4513,6 +4513,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
> >      smc->irq = &spapr_irq_dual;
> >      smc->dr_phb_enabled = true;
> >      smc->linux_pci_probe = true;
> > +    smc->nr_xirqs = SPAPR_NR_XIRQS;
> 
> This is the last user of SPAPR_NR_XIRQS.
> 
> $ git grep SPAPR_NR_XIRQS
> hw/ppc/spapr.c:    smc->nr_xirqs = SPAPR_NR_XIRQS;
> include/hw/ppc/spapr_irq.h:#define SPAPR_NR_XIRQS       0x1000
> 
> Maybe open-code it here, like you already do for SPAPR_IRQ_XICS_LEGACY_NR_XIRQS
> below.

I thought about it.  I kind of prefer having the #define, though I'm
not really sure that's a rational choice.

> 
> With or without that fixed.
> 
> Reviewed-by: Greg Kurz <groug@kaod.org>
> 
> >  }
> >  
> >  static const TypeInfo spapr_machine_info = {
> > @@ -4648,6 +4649,7 @@ static void spapr_machine_3_0_class_options(MachineClass *mc)
> >      compat_props_add(mc->compat_props, hw_compat_3_0, hw_compat_3_0_len);
> >  
> >      smc->legacy_irq_allocation = true;
> > +    smc->nr_xirqs = 0x400;
> >      smc->irq = &spapr_irq_xics_legacy;
> >  }
> >  
> > diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> > index 799755c811..f76f30f54b 100644
> > --- a/hw/ppc/spapr_irq.c
> > +++ b/hw/ppc/spapr_irq.c
> > @@ -106,7 +106,6 @@ int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController *, Error **),
> >   */
> >  
> >  SpaprIrq spapr_irq_xics = {
> > -    .nr_xirqs    = SPAPR_NR_XIRQS,
> >      .xics        = true,
> >      .xive        = false,
> >  };
> > @@ -116,7 +115,6 @@ SpaprIrq spapr_irq_xics = {
> >   */
> >  
> >  SpaprIrq spapr_irq_xive = {
> > -    .nr_xirqs    = SPAPR_NR_XIRQS,
> >      .xics        = false,
> >      .xive        = true,
> >  };
> > @@ -134,7 +132,6 @@ SpaprIrq spapr_irq_xive = {
> >   * Define values in sync with the XIVE and XICS backend
> >   */
> >  SpaprIrq spapr_irq_dual = {
> > -    .nr_xirqs    = SPAPR_NR_XIRQS,
> >      .xics        = true,
> >      .xive        = true,
> >  };
> > @@ -249,16 +246,19 @@ void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers,
> >  
> >  uint32_t spapr_irq_nr_msis(SpaprMachineState *spapr)
> >  {
> > -    if (SPAPR_MACHINE_GET_CLASS(spapr)->legacy_irq_allocation) {
> > -        return spapr->irq->nr_xirqs;
> > +    SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
> > +
> > +    if (smc->legacy_irq_allocation) {
> > +        return smc->nr_xirqs;
> >      } else {
> > -        return SPAPR_XIRQ_BASE + spapr->irq->nr_xirqs - SPAPR_IRQ_MSI;
> > +        return SPAPR_XIRQ_BASE + smc->nr_xirqs - SPAPR_IRQ_MSI;
> >      }
> >  }
> >  
> >  void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
> >  {
> >      MachineState *machine = MACHINE(spapr);
> > +    SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
> >      Error *local_err = NULL;
> >  
> >      if (machine_kernel_irqchip_split(machine)) {
> > @@ -295,8 +295,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
> >              goto out;
> >          }
> >  
> > -        object_property_set_int(obj, spapr->irq->nr_xirqs, "nr-irqs",
> > -                                &local_err);
> > +        object_property_set_int(obj, smc->nr_xirqs, "nr-irqs", &local_err);
> >          if (local_err) {
> >              goto out;
> >          }
> > @@ -315,8 +314,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
> >          int i;
> >  
> >          dev = qdev_create(NULL, TYPE_SPAPR_XIVE);
> > -        qdev_prop_set_uint32(dev, "nr-irqs",
> > -                             spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
> > +        qdev_prop_set_uint32(dev, "nr-irqs", smc->nr_xirqs + SPAPR_XIRQ_BASE);
> >          /*
> >           * 8 XIVE END structures per CPU. One for each available
> >           * priority
> > @@ -343,7 +341,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
> >      }
> >  
> >      spapr->qirqs = qemu_allocate_irqs(spapr_set_irq, spapr,
> > -                                      spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
> > +                                      smc->nr_xirqs + SPAPR_XIRQ_BASE);
> >  
> >  out:
> >      error_propagate(errp, local_err);
> > @@ -351,10 +349,11 @@ out:
> >  
> >  int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
> >  {
> > +    SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
> >      int rc;
> >  
> >      assert(irq >= SPAPR_XIRQ_BASE);
> > -    assert(irq < (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
> > +    assert(irq < (smc->nr_xirqs + SPAPR_XIRQ_BASE));
> >  
> >      if (spapr->xive) {
> >          SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(spapr->xive);
> > @@ -379,10 +378,11 @@ int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
> >  
> >  void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
> >  {
> > +    SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
> >      int i;
> >  
> >      assert(irq >= SPAPR_XIRQ_BASE);
> > -    assert((irq + num) <= (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
> > +    assert((irq + num) <= (smc->nr_xirqs + SPAPR_XIRQ_BASE));
> >  
> >      for (i = irq; i < (irq + num); i++) {
> >          if (spapr->xive) {
> > @@ -402,6 +402,8 @@ void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
> >  
> >  qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq)
> >  {
> > +    SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
> > +
> >      /*
> >       * This interface is basically for VIO and PHB devices to find the
> >       * right qemu_irq to manipulate, so we only allow access to the
> > @@ -410,7 +412,7 @@ qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq)
> >       * interfaces, we can change this if we need to in future.
> >       */
> >      assert(irq >= SPAPR_XIRQ_BASE);
> > -    assert(irq < (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
> > +    assert(irq < (smc->nr_xirqs + SPAPR_XIRQ_BASE));
> >  
> >      if (spapr->ics) {
> >          assert(ics_valid_irq(spapr->ics, irq));
> > @@ -563,10 +565,7 @@ int spapr_irq_find(SpaprMachineState *spapr, int num, bool align, Error **errp)
> >      return first + ics->offset;
> >  }
> >  
> > -#define SPAPR_IRQ_XICS_LEGACY_NR_XIRQS     0x400
> > -
> >  SpaprIrq spapr_irq_xics_legacy = {
> > -    .nr_xirqs    = SPAPR_IRQ_XICS_LEGACY_NR_XIRQS,
> >      .xics        = true,
> >      .xive        = false,
> >  };
> > diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> > index 763da757f0..623e8e3f93 100644
> > --- a/include/hw/ppc/spapr.h
> > +++ b/include/hw/ppc/spapr.h
> > @@ -119,6 +119,7 @@ struct SpaprMachineClass {
> >      bool use_ohci_by_default;  /* use USB-OHCI instead of XHCI */
> >      bool pre_2_10_has_unused_icps;
> >      bool legacy_irq_allocation;
> > +    uint32_t nr_xirqs;
> >      bool broken_host_serial_model; /* present real host info to the guest */
> >      bool pre_4_1_migration; /* don't migrate hpt-max-page-size */
> >      bool linux_pci_probe;
> > diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> > index 308bfcefd1..73d8beda39 100644
> > --- a/include/hw/ppc/spapr_irq.h
> > +++ b/include/hw/ppc/spapr_irq.h
> > @@ -77,7 +77,6 @@ int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align,
> >  void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, uint32_t num);
> >  
> >  typedef struct SpaprIrq {
> > -    uint32_t    nr_xirqs;
> >      bool        xics;
> >      bool        xive;
> >  } SpaprIrq;
> 

-- 
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] 83+ messages in thread

* Re: [PATCH v2 20/33] spapr, xics, xive: Introduce SpaprInterruptController QOM interface
  2019-09-27  5:50 ` [PATCH v2 20/33] spapr, xics, xive: Introduce SpaprInterruptController QOM interface David Gibson
  2019-09-27  9:52   ` Greg Kurz
@ 2019-09-30  5:24   ` Cédric Le Goater
  1 sibling, 0 replies; 83+ messages in thread
From: Cédric Le Goater @ 2019-09-30  5:24 UTC (permalink / raw)
  To: David Gibson, qemu-devel, qemu-ppc
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, Paolo Bonzini,
	Marc-André Lureau, philmd

On 27/09/2019 07:50, David Gibson wrote:
> The SpaprIrq structure is used to represent ths spapr machine's irq
> backend.  Except that it kind of conflates two concepts: one is the
> backend proper - a specific interrupt controller that we might or
> might not be using, the other is the irq configuration which covers
> the layout of irq space and which interrupt controllers are allowed.
> 
> This leads to some pretty confusing code paths for the "dual"
> configuration where its hooks redirect to other SpaprIrq structures
> depending on the currently active irq controller.
> 
> To clean this up, we start by introducing a new
> SpaprInterruptController QOM interface to represent strictly an
> interrupt controller backend, not counting anything configuration
> related.  We implement this interface in the XICs and XIVE interrupt
> controllers, and in future we'll move relevant methods from SpaprIrq
> into it.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>

Reviewed-by: Cédric Le Goater <clg@kaod.org>

> ---
>  hw/intc/spapr_xive.c       |  4 ++++
>  hw/intc/xics_spapr.c       |  4 ++++
>  hw/ppc/spapr_irq.c         | 13 +++++++++++++
>  include/hw/ppc/spapr_irq.h | 14 ++++++++++++++
>  4 files changed, 35 insertions(+)
> 
> diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
> index 04879abf2e..b67e9c3245 100644
> --- a/hw/intc/spapr_xive.c
> +++ b/hw/intc/spapr_xive.c
> @@ -519,6 +519,10 @@ static const TypeInfo spapr_xive_info = {
>      .instance_init = spapr_xive_instance_init,
>      .instance_size = sizeof(SpaprXive),
>      .class_init = spapr_xive_class_init,
> +    .interfaces = (InterfaceInfo[]) {
> +        { TYPE_SPAPR_INTC },
> +        { }
> +    },
>  };
>  
>  static void spapr_xive_register_types(void)
> diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
> index 6e5eb24b3c..4874e6be55 100644
> --- a/hw/intc/xics_spapr.c
> +++ b/hw/intc/xics_spapr.c
> @@ -343,6 +343,10 @@ static const TypeInfo ics_spapr_info = {
>      .name = TYPE_ICS_SPAPR,
>      .parent = TYPE_ICS,
>      .class_init = ics_spapr_class_init,
> +    .interfaces = (InterfaceInfo[]) {
> +        { TYPE_SPAPR_INTC },
> +        { }
> +    },
>  };
>  
>  static void xics_spapr_register_types(void)
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index 5e448b1fd4..0603c82fe8 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -23,6 +23,12 @@
>  
>  #include "trace.h"
>  
> +static const TypeInfo spapr_intc_info = {
> +    .name = TYPE_SPAPR_INTC,
> +    .parent = TYPE_INTERFACE,
> +    .class_size = sizeof(SpaprInterruptControllerClass),
> +};
> +
>  void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis)
>  {
>      spapr->irq_map_nr = nr_msis;
> @@ -763,3 +769,10 @@ SpaprIrq spapr_irq_xics_legacy = {
>      .set_irq     = spapr_irq_set_irq_xics,
>      .init_kvm    = spapr_irq_init_kvm_xics,
>  };
> +
> +static void spapr_irq_register_types(void)
> +{
> +    type_register_static(&spapr_intc_info);
> +}
> +
> +type_init(spapr_irq_register_types)
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index 69a37f608e..b9398e0be3 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -31,6 +31,20 @@
>  
>  typedef struct SpaprMachineState SpaprMachineState;
>  
> +typedef struct SpaprInterruptController SpaprInterruptController;
> +
> +#define TYPE_SPAPR_INTC "spapr-interrupt-controller"
> +#define SPAPR_INTC(obj)                                     \
> +    INTERFACE_CHECK(SpaprInterruptController, (obj), TYPE_SPAPR_INTC)
> +#define SPAPR_INTC_CLASS(klass)                                     \
> +    OBJECT_CLASS_CHECK(SpaprInterruptControllerClass, (klass), TYPE_SPAPR_INTC)
> +#define SPAPR_INTC_GET_CLASS(obj)                                   \
> +    OBJECT_GET_CLASS(SpaprInterruptControllerClass, (obj), TYPE_SPAPR_INTC)
> +
> +typedef struct SpaprInterruptControllerClass {
> +    InterfaceClass parent;
> +} SpaprInterruptControllerClass;
> +
>  void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis);
>  int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align,
>                          Error **errp);
> 



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

* Re: [PATCH v2 21/33] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController
  2019-09-30  1:49     ` David Gibson
@ 2019-09-30  5:28       ` Cédric Le Goater
  2019-09-30  6:14         ` David Gibson
  0 siblings, 1 reply; 83+ messages in thread
From: Cédric Le Goater @ 2019-09-30  5:28 UTC (permalink / raw)
  To: David Gibson, Greg Kurz
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	Marc-André Lureau, Paolo Bonzini, philmd

On 30/09/2019 03:49, David Gibson wrote:
> On Fri, Sep 27, 2019 at 12:16:49PM +0200, Greg Kurz wrote:
>> On Fri, 27 Sep 2019 15:50:16 +1000
>> David Gibson <david@gibson.dropbear.id.au> wrote:
>>
>>> This method essentially represents code which belongs to the interrupt
>>> controller, but needs to be called on all possible intcs, rather than
>>> just the currently active one.  The "dual" version therefore calls
>>> into the xics and xive versions confusingly.
>>>
>>> Handle this more directly, by making it instead a method on the intc
>>> backend, and always calling it on every backend that exists.
>>>
>>> While we're there, streamline the error reporting a bit.
>>>
>>> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> [snip]
>>> @@ -525,6 +469,30 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
>>>  /*
>>>   * sPAPR IRQ frontend routines for devices
>>>   */
>>> +int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
>>> +                              PowerPCCPU *cpu, Error **errp)
>>> +{
>>> +    if (spapr->xive) {
>>> +        SpaprInterruptController *intc = SPAPR_INTC(spapr->xive);
>>> +        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
>>> +
>>> +        if (sicc->cpu_intc_create(intc, cpu, errp) < 0) {
>>> +            return -1;
>>> +        }
>>> +    }
>>> +
>>> +    if (spapr->ics) {
>>> +        SpaprInterruptController *intc = SPAPR_INTC(spapr->ics);
>>> +        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
>>> +
>>> +        if (sicc->cpu_intc_create(intc, cpu, errp) < 0) {
>>> +            return -1;
>>> +        }
>>> +    }
>>> +
>>
>> Instead of these hooks, what about open-coding spapr_xive_cpu_intc_create()
>> and xics_spapr_cpu_intc_create() directly here, like you already did for the
>> ICS and the XIVE objects in spapr_irq_init() ?
> 
> I'd prefer not to.  The idea is I want to treat this as basically:
> 
> 	foreach_possible_intc(intc)
> 		intc::cpu_intc_create(...)
> 
> If I find time I might indeed replace the explicit ics and xive
> pointers with just an array of SpaprInterruptController *.

Or you could use object_child_foreach() and check for the type. If we had
a helper object_child_foreach_type(), we could use it elsewhere.

 
> init is fundamentally different though, because it needs to *create*
> that list (implicit or explicit) of possible intcs, so it can't be
> based on an existing one.
> 
>>
>>> +    return 0;
>>> +}
>>> +
>>>  void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>>>  {
>>>      MachineState *machine = MACHINE(spapr);
>>> @@ -763,7 +731,6 @@ SpaprIrq spapr_irq_xics_legacy = {
>>>      .free        = spapr_irq_free_xics,
>>>      .print_info  = spapr_irq_print_info_xics,
>>>      .dt_populate = spapr_dt_xics,
>>> -    .cpu_intc_create = spapr_irq_cpu_intc_create_xics,
>>>      .post_load   = spapr_irq_post_load_xics,
>>>      .reset       = spapr_irq_reset_xics,
>>>      .set_irq     = spapr_irq_set_irq_xics,
>>> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
>>> index b9398e0be3..30d660ff1e 100644
>>> --- a/include/hw/ppc/spapr_irq.h
>>> +++ b/include/hw/ppc/spapr_irq.h
>>> @@ -43,8 +43,22 @@ typedef struct SpaprInterruptController SpaprInterruptController;
>>>  
>>>  typedef struct SpaprInterruptControllerClass {
>>>      InterfaceClass parent;
>>> +
>>> +    /*
>>> +     * These methods will typically be called on all intcs, active and
>>> +     * inactive
>>> +     */
>>> +    int (*cpu_intc_create)(SpaprInterruptController *intc,
>>> +                            PowerPCCPU *cpu, Error **errp);
>>>  } SpaprInterruptControllerClass;
>>>  
>>> +void spapr_irq_print_info(SpaprMachineState *spapr, Monitor *mon);
>>> +void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers,
>>> +                  void *fdt, uint32_t phandle);
>>
>> These two ^^ seem to belong to later patches.
>>
>>> +int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
>>> +                              PowerPCCPU *cpu, Error **errp);
>>> +
>>> +
>>>  void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis);
>>>  int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align,
>>>                          Error **errp);
>>> @@ -61,8 +75,6 @@ typedef struct SpaprIrq {
>>>      void (*print_info)(SpaprMachineState *spapr, Monitor *mon);
>>>      void (*dt_populate)(SpaprMachineState *spapr, uint32_t nr_servers,
>>>                          void *fdt, uint32_t phandle);
>>> -    void (*cpu_intc_create)(SpaprMachineState *spapr, PowerPCCPU *cpu,
>>> -                            Error **errp);
>>>      int (*post_load)(SpaprMachineState *spapr, int version_id);
>>>      void (*reset)(SpaprMachineState *spapr, Error **errp);
>>>      void (*set_irq)(void *opaque, int srcno, int val);
>>
> 



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

* Re: [PATCH v2 21/33] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController
  2019-09-27  5:50 ` [PATCH v2 21/33] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController David Gibson
  2019-09-27 10:16   ` Greg Kurz
@ 2019-09-30  5:30   ` Cédric Le Goater
  1 sibling, 0 replies; 83+ messages in thread
From: Cédric Le Goater @ 2019-09-30  5:30 UTC (permalink / raw)
  To: David Gibson, qemu-devel, qemu-ppc
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, Paolo Bonzini,
	Marc-André Lureau, philmd

On 27/09/2019 07:50, David Gibson wrote:
> This method essentially represents code which belongs to the interrupt
> controller, but needs to be called on all possible intcs, rather than
> just the currently active one.  The "dual" version therefore calls
> into the xics and xive versions confusingly.
> 
> Handle this more directly, by making it instead a method on the intc
> backend, and always calling it on every backend that exists.
> 
> While we're there, streamline the error reporting a bit.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>

With the function declarations removed from spapr_irq.h,

Reviewed-by: Cédric Le Goater <clg@kaod.org>

> ---
>  hw/intc/spapr_xive.c       | 25 ++++++++++++
>  hw/intc/xics_spapr.c       | 18 +++++++++
>  hw/ppc/spapr_cpu_core.c    |  3 +-
>  hw/ppc/spapr_irq.c         | 81 +++++++++++---------------------------
>  include/hw/ppc/spapr_irq.h | 16 +++++++-
>  5 files changed, 82 insertions(+), 61 deletions(-)
> 
> diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
> index b67e9c3245..9338daba3d 100644
> --- a/hw/intc/spapr_xive.c
> +++ b/hw/intc/spapr_xive.c
> @@ -495,10 +495,33 @@ static Property spapr_xive_properties[] = {
>      DEFINE_PROP_END_OF_LIST(),
>  };
>  
> +static int spapr_xive_cpu_intc_create(SpaprInterruptController *intc,
> +                                      PowerPCCPU *cpu, Error **errp)
> +{
> +    SpaprXive *xive = SPAPR_XIVE(intc);
> +    Object *obj;
> +    SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
> +
> +    obj = xive_tctx_create(OBJECT(cpu), XIVE_ROUTER(xive), errp);
> +    if (!obj) {
> +        return -1;
> +    }
> +
> +    spapr_cpu->tctx = XIVE_TCTX(obj);
> +
> +    /*
> +     * (TCG) Early setting the OS CAM line for hotplugged CPUs as they
> +     * don't beneficiate from the reset of the XIVE IRQ backend
> +     */
> +    spapr_xive_set_tctx_os_cam(spapr_cpu->tctx);
> +    return 0;
> +}
> +
>  static void spapr_xive_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
>      XiveRouterClass *xrc = XIVE_ROUTER_CLASS(klass);
> +    SpaprInterruptControllerClass *sicc = SPAPR_INTC_CLASS(klass);
>  
>      dc->desc    = "sPAPR XIVE Interrupt Controller";
>      dc->props   = spapr_xive_properties;
> @@ -511,6 +534,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;
> +
> +    sicc->cpu_intc_create = spapr_xive_cpu_intc_create;
>  }
>  
>  static const TypeInfo spapr_xive_info = {
> diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
> index 4874e6be55..946311b858 100644
> --- a/hw/intc/xics_spapr.c
> +++ b/hw/intc/xics_spapr.c
> @@ -330,13 +330,31 @@ void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
>      _FDT(fdt_setprop_cell(fdt, node, "phandle", phandle));
>  }
>  
> +static int xics_spapr_cpu_intc_create(SpaprInterruptController *intc,
> +                                       PowerPCCPU *cpu, Error **errp)
> +{
> +    ICSState *ics = ICS_SPAPR(intc);
> +    Object *obj;
> +    SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
> +
> +    obj = icp_create(OBJECT(cpu), TYPE_ICP, ics->xics, errp);
> +    if (!obj) {
> +        return -1;
> +    }
> +
> +    spapr_cpu->icp = ICP(obj);
> +    return 0;
> +}
> +
>  static void ics_spapr_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
>      ICSStateClass *isc = ICS_CLASS(klass);
> +    SpaprInterruptControllerClass *sicc = SPAPR_INTC_CLASS(klass);
>  
>      device_class_set_parent_realize(dc, ics_spapr_realize,
>                                      &isc->parent_realize);
> +    sicc->cpu_intc_create = xics_spapr_cpu_intc_create;
>  }
>  
>  static const TypeInfo ics_spapr_info = {
> diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
> index 1d93de8161..3e4302c7d5 100644
> --- a/hw/ppc/spapr_cpu_core.c
> +++ b/hw/ppc/spapr_cpu_core.c
> @@ -237,8 +237,7 @@ static void spapr_realize_vcpu(PowerPCCPU *cpu, SpaprMachineState *spapr,
>      qemu_register_reset(spapr_cpu_reset, cpu);
>      spapr_cpu_reset(cpu);
>  
> -    spapr->irq->cpu_intc_create(spapr, cpu, &local_err);
> -    if (local_err) {
> +    if (spapr_irq_cpu_intc_create(spapr, cpu, &local_err) < 0) {
>          goto error_unregister;
>      }
>  
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index 0603c82fe8..a855dfe4e9 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -138,23 +138,6 @@ static void spapr_irq_print_info_xics(SpaprMachineState *spapr, Monitor *mon)
>      ics_pic_print_info(spapr->ics, mon);
>  }
>  
> -static void spapr_irq_cpu_intc_create_xics(SpaprMachineState *spapr,
> -                                           PowerPCCPU *cpu, Error **errp)
> -{
> -    Error *local_err = NULL;
> -    Object *obj;
> -    SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
> -
> -    obj = icp_create(OBJECT(cpu), TYPE_ICP, XICS_FABRIC(spapr),
> -                     &local_err);
> -    if (local_err) {
> -        error_propagate(errp, local_err);
> -        return;
> -    }
> -
> -    spapr_cpu->icp = ICP(obj);
> -}
> -
>  static int spapr_irq_post_load_xics(SpaprMachineState *spapr, int version_id)
>  {
>      if (!kvm_irqchip_in_kernel()) {
> @@ -203,7 +186,6 @@ SpaprIrq spapr_irq_xics = {
>      .free        = spapr_irq_free_xics,
>      .print_info  = spapr_irq_print_info_xics,
>      .dt_populate = spapr_dt_xics,
> -    .cpu_intc_create = spapr_irq_cpu_intc_create_xics,
>      .post_load   = spapr_irq_post_load_xics,
>      .reset       = spapr_irq_reset_xics,
>      .set_irq     = spapr_irq_set_irq_xics,
> @@ -239,28 +221,6 @@ static void spapr_irq_print_info_xive(SpaprMachineState *spapr,
>      spapr_xive_pic_print_info(spapr->xive, mon);
>  }
>  
> -static void spapr_irq_cpu_intc_create_xive(SpaprMachineState *spapr,
> -                                           PowerPCCPU *cpu, Error **errp)
> -{
> -    Error *local_err = NULL;
> -    Object *obj;
> -    SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
> -
> -    obj = xive_tctx_create(OBJECT(cpu), XIVE_ROUTER(spapr->xive), &local_err);
> -    if (local_err) {
> -        error_propagate(errp, local_err);
> -        return;
> -    }
> -
> -    spapr_cpu->tctx = XIVE_TCTX(obj);
> -
> -    /*
> -     * (TCG) Early setting the OS CAM line for hotplugged CPUs as they
> -     * don't beneficiate from the reset of the XIVE IRQ backend
> -     */
> -    spapr_xive_set_tctx_os_cam(spapr_cpu->tctx);
> -}
> -
>  static int spapr_irq_post_load_xive(SpaprMachineState *spapr, int version_id)
>  {
>      return spapr_xive_post_load(spapr->xive, version_id);
> @@ -316,7 +276,6 @@ SpaprIrq spapr_irq_xive = {
>      .free        = spapr_irq_free_xive,
>      .print_info  = spapr_irq_print_info_xive,
>      .dt_populate = spapr_dt_xive,
> -    .cpu_intc_create = spapr_irq_cpu_intc_create_xive,
>      .post_load   = spapr_irq_post_load_xive,
>      .reset       = spapr_irq_reset_xive,
>      .set_irq     = spapr_irq_set_irq_xive,
> @@ -381,20 +340,6 @@ static void spapr_irq_dt_populate_dual(SpaprMachineState *spapr,
>      spapr_irq_current(spapr)->dt_populate(spapr, nr_servers, fdt, phandle);
>  }
>  
> -static void spapr_irq_cpu_intc_create_dual(SpaprMachineState *spapr,
> -                                           PowerPCCPU *cpu, Error **errp)
> -{
> -    Error *local_err = NULL;
> -
> -    spapr_irq_xive.cpu_intc_create(spapr, cpu, &local_err);
> -    if (local_err) {
> -        error_propagate(errp, local_err);
> -        return;
> -    }
> -
> -    spapr_irq_xics.cpu_intc_create(spapr, cpu, errp);
> -}
> -
>  static int spapr_irq_post_load_dual(SpaprMachineState *spapr, int version_id)
>  {
>      /*
> @@ -460,7 +405,6 @@ SpaprIrq spapr_irq_dual = {
>      .free        = spapr_irq_free_dual,
>      .print_info  = spapr_irq_print_info_dual,
>      .dt_populate = spapr_irq_dt_populate_dual,
> -    .cpu_intc_create = spapr_irq_cpu_intc_create_dual,
>      .post_load   = spapr_irq_post_load_dual,
>      .reset       = spapr_irq_reset_dual,
>      .set_irq     = spapr_irq_set_irq_dual,
> @@ -525,6 +469,30 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
>  /*
>   * sPAPR IRQ frontend routines for devices
>   */
> +int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
> +                              PowerPCCPU *cpu, Error **errp)
> +{
> +    if (spapr->xive) {
> +        SpaprInterruptController *intc = SPAPR_INTC(spapr->xive);
> +        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
> +
> +        if (sicc->cpu_intc_create(intc, cpu, errp) < 0) {
> +            return -1;
> +        }
> +    }
> +
> +    if (spapr->ics) {
> +        SpaprInterruptController *intc = SPAPR_INTC(spapr->ics);
> +        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
> +
> +        if (sicc->cpu_intc_create(intc, cpu, errp) < 0) {
> +            return -1;
> +        }
> +    }
> +
> +    return 0;
> +}
> +
>  void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>  {
>      MachineState *machine = MACHINE(spapr);
> @@ -763,7 +731,6 @@ SpaprIrq spapr_irq_xics_legacy = {
>      .free        = spapr_irq_free_xics,
>      .print_info  = spapr_irq_print_info_xics,
>      .dt_populate = spapr_dt_xics,
> -    .cpu_intc_create = spapr_irq_cpu_intc_create_xics,
>      .post_load   = spapr_irq_post_load_xics,
>      .reset       = spapr_irq_reset_xics,
>      .set_irq     = spapr_irq_set_irq_xics,
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index b9398e0be3..30d660ff1e 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -43,8 +43,22 @@ typedef struct SpaprInterruptController SpaprInterruptController;
>  
>  typedef struct SpaprInterruptControllerClass {
>      InterfaceClass parent;
> +
> +    /*
> +     * These methods will typically be called on all intcs, active and
> +     * inactive
> +     */
> +    int (*cpu_intc_create)(SpaprInterruptController *intc,
> +                            PowerPCCPU *cpu, Error **errp);
>  } SpaprInterruptControllerClass;
>  
> +void spapr_irq_print_info(SpaprMachineState *spapr, Monitor *mon);
> +void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers,
> +                  void *fdt, uint32_t phandle);
> +int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
> +                              PowerPCCPU *cpu, Error **errp);
> +
> +
>  void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis);
>  int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align,
>                          Error **errp);
> @@ -61,8 +75,6 @@ typedef struct SpaprIrq {
>      void (*print_info)(SpaprMachineState *spapr, Monitor *mon);
>      void (*dt_populate)(SpaprMachineState *spapr, uint32_t nr_servers,
>                          void *fdt, uint32_t phandle);
> -    void (*cpu_intc_create)(SpaprMachineState *spapr, PowerPCCPU *cpu,
> -                            Error **errp);
>      int (*post_load)(SpaprMachineState *spapr, int version_id);
>      void (*reset)(SpaprMachineState *spapr, Error **errp);
>      void (*set_irq)(void *opaque, int srcno, int val);
> 



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

* Re: [PATCH v2 22/33] spapr, xics, xive: Move irq claim and free from SpaprIrq to SpaprInterruptController
  2019-09-27  5:50 ` [PATCH v2 22/33] spapr, xics, xive: Move irq claim and free " David Gibson
  2019-09-27 12:16   ` Greg Kurz
@ 2019-09-30  5:33   ` Cédric Le Goater
  1 sibling, 0 replies; 83+ messages in thread
From: Cédric Le Goater @ 2019-09-30  5:33 UTC (permalink / raw)
  To: David Gibson, qemu-devel, qemu-ppc
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, Paolo Bonzini,
	Marc-André Lureau, philmd

On 27/09/2019 07:50, David Gibson wrote:
> These methods, like cpu_intc_create, really belong to the interrupt
> controller, but need to be called on all possible intcs.
> 
> Like cpu_intc_create, therefore, make them methods on the intc and
> always call it for all existing intcs.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---
>  hw/intc/spapr_xive.c        |  71 +++++++++++-----------
>  hw/intc/xics_spapr.c        |  29 +++++++++
>  hw/ppc/spapr_irq.c          | 114 ++++++++++++------------------------
>  include/hw/ppc/spapr_irq.h  |   5 +-
>  include/hw/ppc/spapr_xive.h |   2 -
>  5 files changed, 107 insertions(+), 114 deletions(-)
> 
> diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
> index 9338daba3d..ff1a175b44 100644
> --- a/hw/intc/spapr_xive.c
> +++ b/hw/intc/spapr_xive.c
> @@ -487,6 +487,42 @@ static const VMStateDescription vmstate_spapr_xive = {
>      },
>  };
>  
> +static int spapr_xive_claim_irq(SpaprInterruptController *intc, int lisn,
> +                                bool lsi, Error **errp)
> +{
> +    SpaprXive *xive = SPAPR_XIVE(intc);
> +    XiveSource *xsrc = &xive->source;
> +
> +    assert(lisn < xive->nr_irqs);
> +
> +    if (xive_eas_is_valid(&xive->eat[lisn])) {
> +        error_setg(errp, "IRQ %d is not free", lisn);
> +        return -EBUSY;
> +    }
> +
> +    /*
> +     * Set default values when allocating an IRQ number
> +     */
> +    xive->eat[lisn].w |= cpu_to_be64(EAS_VALID | EAS_MASKED);
> +    if (lsi) {
> +        xive_source_irq_set_lsi(xsrc, lisn);
> +    }
> +
> +    if (kvm_irqchip_in_kernel()) {
> +        return kvmppc_xive_source_reset_one(xsrc, lisn, errp);
> +    }
> +
> +    return 0;
> +}
> +
> +static void spapr_xive_free_irq(SpaprInterruptController *intc, int lisn)
> +{
> +    SpaprXive *xive = SPAPR_XIVE(intc);
> +    assert(lisn < xive->nr_irqs);
> +
> +    xive->eat[lisn].w &= cpu_to_be64(~EAS_VALID);
> +}
> +
>  static Property spapr_xive_properties[] = {
>      DEFINE_PROP_UINT32("nr-irqs", SpaprXive, nr_irqs, 0),
>      DEFINE_PROP_UINT32("nr-ends", SpaprXive, nr_ends, 0),
> @@ -536,6 +572,8 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data)
>      xrc->get_tctx = spapr_xive_get_tctx;
>  
>      sicc->cpu_intc_create = spapr_xive_cpu_intc_create;
> +    sicc->claim_irq = spapr_xive_claim_irq;
> +    sicc->free_irq = spapr_xive_free_irq;
>  }
>  
>  static const TypeInfo spapr_xive_info = {
> @@ -557,39 +595,6 @@ static void spapr_xive_register_types(void)
>  
>  type_init(spapr_xive_register_types)
>  
> -int spapr_xive_irq_claim(SpaprXive *xive, int lisn, bool lsi, Error **errp)
> -{
> -    XiveSource *xsrc = &xive->source;
> -
> -    assert(lisn < xive->nr_irqs);
> -
> -    if (xive_eas_is_valid(&xive->eat[lisn])) {
> -        error_setg(errp, "IRQ %d is not free", lisn);
> -        return -EBUSY;
> -    }
> -
> -    /*
> -     * Set default values when allocating an IRQ number
> -     */
> -    xive->eat[lisn].w |= cpu_to_be64(EAS_VALID | EAS_MASKED);
> -    if (lsi) {
> -        xive_source_irq_set_lsi(xsrc, lisn);
> -    }
> -
> -    if (kvm_irqchip_in_kernel()) {
> -        return kvmppc_xive_source_reset_one(xsrc, lisn, errp);
> -    }
> -
> -    return 0;
> -}
> -
> -void spapr_xive_irq_free(SpaprXive *xive, int lisn)
> -{
> -    assert(lisn < xive->nr_irqs);
> -
> -    xive->eat[lisn].w &= cpu_to_be64(~EAS_VALID);
> -}
> -
>  /*
>   * XIVE hcalls
>   *
> diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
> index 946311b858..224fe1efcd 100644
> --- a/hw/intc/xics_spapr.c
> +++ b/hw/intc/xics_spapr.c
> @@ -346,6 +346,33 @@ static int xics_spapr_cpu_intc_create(SpaprInterruptController *intc,
>      return 0;
>  }
>  
> +static int xics_spapr_claim_irq(SpaprInterruptController *intc, int irq,
> +                                bool lsi, Error **errp)
> +{
> +    ICSState *ics = ICS_SPAPR(intc);
> +
> +    assert(ics);
> +    assert(ics_valid_irq(ics, irq));
> +
> +    if (!ics_irq_free(ics, irq - ics->offset)) {
> +        error_setg(errp, "IRQ %d is not free", irq);
> +        return -EBUSY;
> +    }
> +
> +    ics_set_irq_type(ics, irq - ics->offset, lsi);
> +    return 0;
> +}
> +
> +static void xics_spapr_free_irq(SpaprInterruptController *intc, int irq)
> +{
> +    ICSState *ics = ICS_SPAPR(intc);
> +    uint32_t srcno = irq - ics->offset;
> +
> +    assert(ics_valid_irq(ics, irq));
> +
> +    memset(&ics->irqs[srcno], 0, sizeof(ICSIRQState));
> +}
> +
>  static void ics_spapr_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
> @@ -355,6 +382,8 @@ static void ics_spapr_class_init(ObjectClass *klass, void *data)
>      device_class_set_parent_realize(dc, ics_spapr_realize,
>                                      &isc->parent_realize);
>      sicc->cpu_intc_create = xics_spapr_cpu_intc_create;
> +    sicc->claim_irq = xics_spapr_claim_irq;
> +    sicc->free_irq = xics_spapr_free_irq;
>  }
>  
>  static const TypeInfo ics_spapr_info = {
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index a855dfe4e9..ea44378d8c 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -98,33 +98,6 @@ static void spapr_irq_init_kvm(SpaprMachineState *spapr,
>   * XICS IRQ backend.
>   */
>  
> -static int spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
> -                                Error **errp)
> -{
> -    ICSState *ics = spapr->ics;
> -
> -    assert(ics);
> -    assert(ics_valid_irq(ics, irq));
> -
> -    if (!ics_irq_free(ics, irq - ics->offset)) {
> -        error_setg(errp, "IRQ %d is not free", irq);
> -        return -1;
> -    }
> -
> -    ics_set_irq_type(ics, irq - ics->offset, lsi);
> -    return 0;
> -}
> -
> -static void spapr_irq_free_xics(SpaprMachineState *spapr, int irq)
> -{
> -    ICSState *ics = spapr->ics;
> -    uint32_t srcno = irq - ics->offset;
> -
> -    assert(ics_valid_irq(ics, irq));
> -
> -    memset(&ics->irqs[srcno], 0, sizeof(ICSIRQState));
> -}
> -
>  static void spapr_irq_print_info_xics(SpaprMachineState *spapr, Monitor *mon)
>  {
>      CPUState *cs;
> @@ -182,8 +155,6 @@ SpaprIrq spapr_irq_xics = {
>      .xics        = true,
>      .xive        = false,
>  
> -    .claim       = spapr_irq_claim_xics,
> -    .free        = spapr_irq_free_xics,
>      .print_info  = spapr_irq_print_info_xics,
>      .dt_populate = spapr_dt_xics,
>      .post_load   = spapr_irq_post_load_xics,
> @@ -196,17 +167,6 @@ SpaprIrq spapr_irq_xics = {
>   * XIVE IRQ backend.
>   */
>  
> -static int spapr_irq_claim_xive(SpaprMachineState *spapr, int irq, bool lsi,
> -                                Error **errp)
> -{
> -    return spapr_xive_irq_claim(spapr->xive, irq, lsi, errp);
> -}
> -
> -static void spapr_irq_free_xive(SpaprMachineState *spapr, int irq)
> -{
> -    spapr_xive_irq_free(spapr->xive, irq);
> -}
> -
>  static void spapr_irq_print_info_xive(SpaprMachineState *spapr,
>                                        Monitor *mon)
>  {
> @@ -272,8 +232,6 @@ SpaprIrq spapr_irq_xive = {
>      .xics        = false,
>      .xive        = true,
>  
> -    .claim       = spapr_irq_claim_xive,
> -    .free        = spapr_irq_free_xive,
>      .print_info  = spapr_irq_print_info_xive,
>      .dt_populate = spapr_dt_xive,
>      .post_load   = spapr_irq_post_load_xive,
> @@ -301,33 +259,6 @@ static SpaprIrq *spapr_irq_current(SpaprMachineState *spapr)
>          &spapr_irq_xive : &spapr_irq_xics;
>  }
>  
> -static int spapr_irq_claim_dual(SpaprMachineState *spapr, int irq, bool lsi,
> -                                Error **errp)
> -{
> -    Error *local_err = NULL;
> -    int ret;
> -
> -    ret = spapr_irq_xics.claim(spapr, irq, lsi, &local_err);
> -    if (local_err) {
> -        error_propagate(errp, local_err);
> -        return ret;
> -    }
> -
> -    ret = spapr_irq_xive.claim(spapr, irq, lsi, &local_err);
> -    if (local_err) {
> -        error_propagate(errp, local_err);
> -        return ret;
> -    }
> -
> -    return ret;
> -}
> -
> -static void spapr_irq_free_dual(SpaprMachineState *spapr, int irq)
> -{
> -    spapr_irq_xics.free(spapr, irq);
> -    spapr_irq_xive.free(spapr, irq);
> -}
> -
>  static void spapr_irq_print_info_dual(SpaprMachineState *spapr, Monitor *mon)
>  {
>      spapr_irq_current(spapr)->print_info(spapr, mon);
> @@ -401,8 +332,6 @@ SpaprIrq spapr_irq_dual = {
>      .xics        = true,
>      .xive        = true,
>  
> -    .claim       = spapr_irq_claim_dual,
> -    .free        = spapr_irq_free_dual,
>      .print_info  = spapr_irq_print_info_dual,
>      .dt_populate = spapr_irq_dt_populate_dual,
>      .post_load   = spapr_irq_post_load_dual,
> @@ -567,10 +496,12 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>  
>          /* Enable the CPU IPIs */
>          for (i = 0; i < nr_servers; ++i) {
> +            SpaprInterruptControllerClass *sicc
> +                = SPAPR_INTC_GET_CLASS(spapr->xive);
>              Error *local_err = NULL;
>  
> -            spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i,
> -                                 false, &local_err);
> +            sicc->claim_irq(SPAPR_INTC(spapr->xive), SPAPR_IRQ_IPI + i,
> +                            false, &local_err);
>              if (local_err) {
>                  goto out;
>              }
> @@ -588,10 +519,30 @@ out:
>  
>  int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
>  {
> +    int rc;
> +
>      assert(irq >= SPAPR_XIRQ_BASE);
>      assert(irq < (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
>  
> -    return spapr->irq->claim(spapr, irq, lsi, errp);
> +    if (spapr->xive) {
> +        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(spapr->xive);
> +
> +        rc = sicc->claim_irq(SPAPR_INTC(spapr->xive), irq, lsi, errp);
> +        if (rc < 0) {
> +            return rc;
> +        }
> +    }
> +
> +    if (spapr->ics) {
> +        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(spapr->ics);
> +
> +        rc = sicc->claim_irq(SPAPR_INTC(spapr->ics), irq, lsi, errp);
> +        if (rc < 0) {
> +            return rc;
> +        }
> +    }
> +
> +    return 0;
>  }
>  
>  void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
> @@ -602,7 +553,18 @@ void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
>      assert((irq + num) <= (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
>  
>      for (i = irq; i < (irq + num); i++) {
> -        spapr->irq->free(spapr, irq);
> +        if (spapr->xive) {
> +            SpaprInterruptController *intc = SPAPR_INTC(spapr->xive);
> +            SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
> +
> +            sicc->free_irq(intc, irq);
> +        }
> +        if (spapr->ics) {
> +            SpaprInterruptController *intc = SPAPR_INTC(spapr->ics);
> +            SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
> +
> +            sicc->free_irq(intc, irq);
> +        }
>      }
>  }


I think we need to introduce a object_child_foreach_type() helper first. 
It would simplify the above calls.


> @@ -727,8 +689,6 @@ SpaprIrq spapr_irq_xics_legacy = {
>      .xics        = true,
>      .xive        = false,
>  
> -    .claim       = spapr_irq_claim_xics,
> -    .free        = spapr_irq_free_xics,
>      .print_info  = spapr_irq_print_info_xics,
>      .dt_populate = spapr_dt_xics,
>      .post_load   = spapr_irq_post_load_xics,
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index 30d660ff1e..616086f9bb 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -50,6 +50,9 @@ typedef struct SpaprInterruptControllerClass {
>       */
>      int (*cpu_intc_create)(SpaprInterruptController *intc,
>                              PowerPCCPU *cpu, Error **errp);
> +    int (*claim_irq)(SpaprInterruptController *intc, int irq, bool lsi,
> +                     Error **errp);
> +    void (*free_irq)(SpaprInterruptController *intc, int irq);
>  } SpaprInterruptControllerClass;
>  
>  void spapr_irq_print_info(SpaprMachineState *spapr, Monitor *mon);
> @@ -70,8 +73,6 @@ typedef struct SpaprIrq {
>      bool        xics;
>      bool        xive;
>  
> -    int (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
> -    void (*free)(SpaprMachineState *spapr, int irq);
>      void (*print_info)(SpaprMachineState *spapr, Monitor *mon);
>      void (*dt_populate)(SpaprMachineState *spapr, uint32_t nr_servers,
>                          void *fdt, uint32_t phandle);
> diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h
> index 0df20a6590..8f875673f5 100644
> --- a/include/hw/ppc/spapr_xive.h
> +++ b/include/hw/ppc/spapr_xive.h
> @@ -54,8 +54,6 @@ typedef struct SpaprXive {
>   */
>  #define SPAPR_XIVE_BLOCK_ID 0x0
>  
> -int spapr_xive_irq_claim(SpaprXive *xive, int lisn, bool lsi, Error **errp);
> -void spapr_xive_irq_free(SpaprXive *xive, int lisn);
>  void spapr_xive_pic_print_info(SpaprXive *xive, Monitor *mon);
>  int spapr_xive_post_load(SpaprXive *xive, int version_id);
>  
> 



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

* Re: [PATCH v2 22/33] spapr, xics, xive: Move irq claim and free from SpaprIrq to SpaprInterruptController
  2019-09-30  2:39     ` David Gibson
@ 2019-09-30  5:36       ` Cédric Le Goater
  0 siblings, 0 replies; 83+ messages in thread
From: Cédric Le Goater @ 2019-09-30  5:36 UTC (permalink / raw)
  To: David Gibson, Greg Kurz
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	Marc-André Lureau, Paolo Bonzini, philmd

On 30/09/2019 04:39, David Gibson wrote:
> On Fri, Sep 27, 2019 at 02:16:12PM +0200, Greg Kurz wrote:
>> On Fri, 27 Sep 2019 15:50:17 +1000
>> David Gibson <david@gibson.dropbear.id.au> wrote:
>>
>>> These methods, like cpu_intc_create, really belong to the interrupt
>>> controller, but need to be called on all possible intcs.
>>>
>>> Like cpu_intc_create, therefore, make them methods on the intc and
>>> always call it for all existing intcs.
>>>
>>> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
>>> ---
>>>  hw/intc/spapr_xive.c        |  71 +++++++++++-----------
>>>  hw/intc/xics_spapr.c        |  29 +++++++++
>>>  hw/ppc/spapr_irq.c          | 114 ++++++++++++------------------------
>>>  include/hw/ppc/spapr_irq.h  |   5 +-
>>>  include/hw/ppc/spapr_xive.h |   2 -
>>>  5 files changed, 107 insertions(+), 114 deletions(-)
>>>
>>> diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
>>> index 9338daba3d..ff1a175b44 100644
>>> --- a/hw/intc/spapr_xive.c
>>> +++ b/hw/intc/spapr_xive.c
>>> @@ -487,6 +487,42 @@ static const VMStateDescription vmstate_spapr_xive = {
>>>      },
>>>  };
>>>  
>>> +static int spapr_xive_claim_irq(SpaprInterruptController *intc, int lisn,
>>> +                                bool lsi, Error **errp)
>>> +{
>>> +    SpaprXive *xive = SPAPR_XIVE(intc);
>>> +    XiveSource *xsrc = &xive->source;
>>> +
>>> +    assert(lisn < xive->nr_irqs);
>>> +
>>> +    if (xive_eas_is_valid(&xive->eat[lisn])) {
>>> +        error_setg(errp, "IRQ %d is not free", lisn);
>>> +        return -EBUSY;
>>> +    }
>>> +
>>> +    /*
>>> +     * Set default values when allocating an IRQ number
>>> +     */
>>> +    xive->eat[lisn].w |= cpu_to_be64(EAS_VALID | EAS_MASKED);
>>> +    if (lsi) {
>>> +        xive_source_irq_set_lsi(xsrc, lisn);
>>> +    }
>>> +
>>> +    if (kvm_irqchip_in_kernel()) {
>>> +        return kvmppc_xive_source_reset_one(xsrc, lisn, errp);
>>> +    }
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +static void spapr_xive_free_irq(SpaprInterruptController *intc, int lisn)
>>> +{
>>> +    SpaprXive *xive = SPAPR_XIVE(intc);
>>> +    assert(lisn < xive->nr_irqs);
>>> +
>>> +    xive->eat[lisn].w &= cpu_to_be64(~EAS_VALID);
>>> +}
>>> +
>>>  static Property spapr_xive_properties[] = {
>>>      DEFINE_PROP_UINT32("nr-irqs", SpaprXive, nr_irqs, 0),
>>>      DEFINE_PROP_UINT32("nr-ends", SpaprXive, nr_ends, 0),
>>> @@ -536,6 +572,8 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data)
>>>      xrc->get_tctx = spapr_xive_get_tctx;
>>>  
>>>      sicc->cpu_intc_create = spapr_xive_cpu_intc_create;
>>> +    sicc->claim_irq = spapr_xive_claim_irq;
>>> +    sicc->free_irq = spapr_xive_free_irq;
>>>  }
>>>  
>>>  static const TypeInfo spapr_xive_info = {
>>> @@ -557,39 +595,6 @@ static void spapr_xive_register_types(void)
>>>  
>>>  type_init(spapr_xive_register_types)
>>>  
>>> -int spapr_xive_irq_claim(SpaprXive *xive, int lisn, bool lsi, Error **errp)
>>> -{
>>> -    XiveSource *xsrc = &xive->source;
>>> -
>>> -    assert(lisn < xive->nr_irqs);
>>> -
>>> -    if (xive_eas_is_valid(&xive->eat[lisn])) {
>>> -        error_setg(errp, "IRQ %d is not free", lisn);
>>> -        return -EBUSY;
>>> -    }
>>> -
>>> -    /*
>>> -     * Set default values when allocating an IRQ number
>>> -     */
>>> -    xive->eat[lisn].w |= cpu_to_be64(EAS_VALID | EAS_MASKED);
>>> -    if (lsi) {
>>> -        xive_source_irq_set_lsi(xsrc, lisn);
>>> -    }
>>> -
>>> -    if (kvm_irqchip_in_kernel()) {
>>> -        return kvmppc_xive_source_reset_one(xsrc, lisn, errp);
>>> -    }
>>> -
>>> -    return 0;
>>> -}
>>> -
>>> -void spapr_xive_irq_free(SpaprXive *xive, int lisn)
>>> -{
>>> -    assert(lisn < xive->nr_irqs);
>>> -
>>> -    xive->eat[lisn].w &= cpu_to_be64(~EAS_VALID);
>>> -}
>>> -
>>>  /*
>>>   * XIVE hcalls
>>>   *
>>> diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
>>> index 946311b858..224fe1efcd 100644
>>> --- a/hw/intc/xics_spapr.c
>>> +++ b/hw/intc/xics_spapr.c
>>> @@ -346,6 +346,33 @@ static int xics_spapr_cpu_intc_create(SpaprInterruptController *intc,
>>>      return 0;
>>>  }
>>>  
>>> +static int xics_spapr_claim_irq(SpaprInterruptController *intc, int irq,
>>> +                                bool lsi, Error **errp)
>>> +{
>>> +    ICSState *ics = ICS_SPAPR(intc);
>>> +
>>> +    assert(ics);
>>> +    assert(ics_valid_irq(ics, irq));
>>> +
>>> +    if (!ics_irq_free(ics, irq - ics->offset)) {
>>> +        error_setg(errp, "IRQ %d is not free", irq);
>>> +        return -EBUSY;
>>> +    }
>>> +
>>> +    ics_set_irq_type(ics, irq - ics->offset, lsi);
>>> +    return 0;
>>> +}
>>> +
>>> +static void xics_spapr_free_irq(SpaprInterruptController *intc, int irq)
>>> +{
>>> +    ICSState *ics = ICS_SPAPR(intc);
>>> +    uint32_t srcno = irq - ics->offset;
>>> +
>>> +    assert(ics_valid_irq(ics, irq));
>>> +
>>> +    memset(&ics->irqs[srcno], 0, sizeof(ICSIRQState));
>>> +}
>>> +
>>>  static void ics_spapr_class_init(ObjectClass *klass, void *data)
>>>  {
>>>      DeviceClass *dc = DEVICE_CLASS(klass);
>>> @@ -355,6 +382,8 @@ static void ics_spapr_class_init(ObjectClass *klass, void *data)
>>>      device_class_set_parent_realize(dc, ics_spapr_realize,
>>>                                      &isc->parent_realize);
>>>      sicc->cpu_intc_create = xics_spapr_cpu_intc_create;
>>> +    sicc->claim_irq = xics_spapr_claim_irq;
>>> +    sicc->free_irq = xics_spapr_free_irq;
>>>  }
>>>  
>>>  static const TypeInfo ics_spapr_info = {
>>> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
>>> index a855dfe4e9..ea44378d8c 100644
>>> --- a/hw/ppc/spapr_irq.c
>>> +++ b/hw/ppc/spapr_irq.c
>>> @@ -98,33 +98,6 @@ static void spapr_irq_init_kvm(SpaprMachineState *spapr,
>>>   * XICS IRQ backend.
>>>   */
>>>  
>>> -static int spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
>>> -                                Error **errp)
>>> -{
>>> -    ICSState *ics = spapr->ics;
>>> -
>>> -    assert(ics);
>>> -    assert(ics_valid_irq(ics, irq));
>>> -
>>> -    if (!ics_irq_free(ics, irq - ics->offset)) {
>>> -        error_setg(errp, "IRQ %d is not free", irq);
>>> -        return -1;
>>> -    }
>>> -
>>> -    ics_set_irq_type(ics, irq - ics->offset, lsi);
>>> -    return 0;
>>> -}
>>> -
>>> -static void spapr_irq_free_xics(SpaprMachineState *spapr, int irq)
>>> -{
>>> -    ICSState *ics = spapr->ics;
>>> -    uint32_t srcno = irq - ics->offset;
>>> -
>>> -    assert(ics_valid_irq(ics, irq));
>>> -
>>> -    memset(&ics->irqs[srcno], 0, sizeof(ICSIRQState));
>>> -}
>>> -
>>>  static void spapr_irq_print_info_xics(SpaprMachineState *spapr, Monitor *mon)
>>>  {
>>>      CPUState *cs;
>>> @@ -182,8 +155,6 @@ SpaprIrq spapr_irq_xics = {
>>>      .xics        = true,
>>>      .xive        = false,
>>>  
>>> -    .claim       = spapr_irq_claim_xics,
>>> -    .free        = spapr_irq_free_xics,
>>>      .print_info  = spapr_irq_print_info_xics,
>>>      .dt_populate = spapr_dt_xics,
>>>      .post_load   = spapr_irq_post_load_xics,
>>> @@ -196,17 +167,6 @@ SpaprIrq spapr_irq_xics = {
>>>   * XIVE IRQ backend.
>>>   */
>>>  
>>> -static int spapr_irq_claim_xive(SpaprMachineState *spapr, int irq, bool lsi,
>>> -                                Error **errp)
>>> -{
>>> -    return spapr_xive_irq_claim(spapr->xive, irq, lsi, errp);
>>> -}
>>> -
>>> -static void spapr_irq_free_xive(SpaprMachineState *spapr, int irq)
>>> -{
>>> -    spapr_xive_irq_free(spapr->xive, irq);
>>> -}
>>> -
>>>  static void spapr_irq_print_info_xive(SpaprMachineState *spapr,
>>>                                        Monitor *mon)
>>>  {
>>> @@ -272,8 +232,6 @@ SpaprIrq spapr_irq_xive = {
>>>      .xics        = false,
>>>      .xive        = true,
>>>  
>>> -    .claim       = spapr_irq_claim_xive,
>>> -    .free        = spapr_irq_free_xive,
>>>      .print_info  = spapr_irq_print_info_xive,
>>>      .dt_populate = spapr_dt_xive,
>>>      .post_load   = spapr_irq_post_load_xive,
>>> @@ -301,33 +259,6 @@ static SpaprIrq *spapr_irq_current(SpaprMachineState *spapr)
>>>          &spapr_irq_xive : &spapr_irq_xics;
>>>  }
>>>  
>>> -static int spapr_irq_claim_dual(SpaprMachineState *spapr, int irq, bool lsi,
>>> -                                Error **errp)
>>> -{
>>> -    Error *local_err = NULL;
>>> -    int ret;
>>> -
>>> -    ret = spapr_irq_xics.claim(spapr, irq, lsi, &local_err);
>>> -    if (local_err) {
>>> -        error_propagate(errp, local_err);
>>> -        return ret;
>>> -    }
>>> -
>>> -    ret = spapr_irq_xive.claim(spapr, irq, lsi, &local_err);
>>> -    if (local_err) {
>>> -        error_propagate(errp, local_err);
>>> -        return ret;
>>> -    }
>>> -
>>> -    return ret;
>>> -}
>>> -
>>> -static void spapr_irq_free_dual(SpaprMachineState *spapr, int irq)
>>> -{
>>> -    spapr_irq_xics.free(spapr, irq);
>>> -    spapr_irq_xive.free(spapr, irq);
>>> -}
>>> -
>>>  static void spapr_irq_print_info_dual(SpaprMachineState *spapr, Monitor *mon)
>>>  {
>>>      spapr_irq_current(spapr)->print_info(spapr, mon);
>>> @@ -401,8 +332,6 @@ SpaprIrq spapr_irq_dual = {
>>>      .xics        = true,
>>>      .xive        = true,
>>>  
>>> -    .claim       = spapr_irq_claim_dual,
>>> -    .free        = spapr_irq_free_dual,
>>>      .print_info  = spapr_irq_print_info_dual,
>>>      .dt_populate = spapr_irq_dt_populate_dual,
>>>      .post_load   = spapr_irq_post_load_dual,
>>> @@ -567,10 +496,12 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>>>  
>>>          /* Enable the CPU IPIs */
>>>          for (i = 0; i < nr_servers; ++i) {
>>> +            SpaprInterruptControllerClass *sicc
>>> +                = SPAPR_INTC_GET_CLASS(spapr->xive);
>>>              Error *local_err = NULL;
>>>  
>>> -            spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i,
>>> -                                 false, &local_err);
>>> +            sicc->claim_irq(SPAPR_INTC(spapr->xive), SPAPR_IRQ_IPI + i,
>>> +                            false, &local_err);
>>>              if (local_err) {
>>>                  goto out;
>>>              }
>>> @@ -588,10 +519,30 @@ out:
>>>  
>>>  int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
>>>  {
>>> +    int rc;
>>> +
>>>      assert(irq >= SPAPR_XIRQ_BASE);
>>>      assert(irq < (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
>>>  
>>> -    return spapr->irq->claim(spapr, irq, lsi, errp);
>>> +    if (spapr->xive) {
>>> +        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(spapr->xive);
>>> +
>>> +        rc = sicc->claim_irq(SPAPR_INTC(spapr->xive), irq, lsi, errp);
>>> +        if (rc < 0) {
>>> +            return rc;
>>> +        }
>>> +    }
>>> +
>>> +    if (spapr->ics) {
>>> +        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(spapr->ics);
>>> +
>>> +        rc = sicc->claim_irq(SPAPR_INTC(spapr->ics), irq, lsi, errp);
>>> +        if (rc < 0) {
>>> +            return rc;
>>> +        }
>>> +    }
>>> +
>>
>> We don't really need an indirection here since we explicitly check
>> spapr->xive and spapr->ics. Calling directly spapr_xive_claim_irq() and
>> xics_spapr_claim_irq() would allow to avoid the method boiler plate and
>> be more explicit IMHO.
>>
>>> +    return 0;
>>>  }
>>>  
>>>  void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
>>> @@ -602,7 +553,18 @@ void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
>>>      assert((irq + num) <= (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
>>>  
>>>      for (i = irq; i < (irq + num); i++) {
>>> -        spapr->irq->free(spapr, irq);
>>> +        if (spapr->xive) {
>>> +            SpaprInterruptController *intc = SPAPR_INTC(spapr->xive);
>>> +            SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
>>> +
>>> +            sicc->free_irq(intc, irq);
>>> +        }
>>> +        if (spapr->ics) {
>>> +            SpaprInterruptController *intc = SPAPR_INTC(spapr->ics);
>>> +            SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
>>> +
>>> +            sicc->free_irq(intc, irq);
>>> +        }
>>
>> Same here.
> 
> As with cpu_intc_create(), I'd prefer to keep both of these as is, but
> I'll look at replacing spapr->ics and spapr->xive with something like
> spapr->all_intcs[].

I would keep the pointers, because we probably need them in some place, 
and use an object_child_foreach instead. 

> 
>>
>>>      }
>>>  }
>>>  
>>> @@ -727,8 +689,6 @@ SpaprIrq spapr_irq_xics_legacy = {
>>>      .xics        = true,
>>>      .xive        = false,
>>>  
>>> -    .claim       = spapr_irq_claim_xics,
>>> -    .free        = spapr_irq_free_xics,
>>>      .print_info  = spapr_irq_print_info_xics,
>>>      .dt_populate = spapr_dt_xics,
>>>      .post_load   = spapr_irq_post_load_xics,
>>> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
>>> index 30d660ff1e..616086f9bb 100644
>>> --- a/include/hw/ppc/spapr_irq.h
>>> +++ b/include/hw/ppc/spapr_irq.h
>>> @@ -50,6 +50,9 @@ typedef struct SpaprInterruptControllerClass {
>>>       */
>>>      int (*cpu_intc_create)(SpaprInterruptController *intc,
>>>                              PowerPCCPU *cpu, Error **errp);
>>> +    int (*claim_irq)(SpaprInterruptController *intc, int irq, bool lsi,
>>> +                     Error **errp);
>>> +    void (*free_irq)(SpaprInterruptController *intc, int irq);
>>>  } SpaprInterruptControllerClass;
>>>  
>>>  void spapr_irq_print_info(SpaprMachineState *spapr, Monitor *mon);
>>> @@ -70,8 +73,6 @@ typedef struct SpaprIrq {
>>>      bool        xics;
>>>      bool        xive;
>>>  
>>> -    int (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
>>> -    void (*free)(SpaprMachineState *spapr, int irq);
>>>      void (*print_info)(SpaprMachineState *spapr, Monitor *mon);
>>>      void (*dt_populate)(SpaprMachineState *spapr, uint32_t nr_servers,
>>>                          void *fdt, uint32_t phandle);
>>> diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h
>>> index 0df20a6590..8f875673f5 100644
>>> --- a/include/hw/ppc/spapr_xive.h
>>> +++ b/include/hw/ppc/spapr_xive.h
>>> @@ -54,8 +54,6 @@ typedef struct SpaprXive {
>>>   */
>>>  #define SPAPR_XIVE_BLOCK_ID 0x0
>>>  
>>> -int spapr_xive_irq_claim(SpaprXive *xive, int lisn, bool lsi, Error **errp);
>>> -void spapr_xive_irq_free(SpaprXive *xive, int lisn);
>>>  void spapr_xive_pic_print_info(SpaprXive *xive, Monitor *mon);
>>>  int spapr_xive_post_load(SpaprXive *xive, int version_id);
>>>  
>>
> 



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

* Re: [PATCH v2 23/33] spapr: Formalize notion of active interrupt controller
  2019-09-27  5:50 ` [PATCH v2 23/33] spapr: Formalize notion of active interrupt controller David Gibson
  2019-09-27 14:16   ` Greg Kurz
@ 2019-09-30  5:39   ` Cédric Le Goater
  1 sibling, 0 replies; 83+ messages in thread
From: Cédric Le Goater @ 2019-09-30  5:39 UTC (permalink / raw)
  To: David Gibson, qemu-devel, qemu-ppc
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, Paolo Bonzini,
	Marc-André Lureau, philmd

On 27/09/2019 07:50, David Gibson wrote:
> spapr now has the mechanism of constructing both XICS and XIVE instances of
> the SpaprInterruptController interface.  However, only one of the interrupt
> controllers will actually be active at any given time, depending on feature
> negotiation with the guest.  This is handled in the current code via
> spapr_irq_current() which checks the OV5 vector from feature negotiation to
> determine the current backend.
> 
> Determining the active controller at the point we need it like this
> can be pretty confusing, because it makes it very non obvious at what
> points the active controller can change.  This can make it difficult
> to reason about the code and where a change of active controller could
> appear in sequence with other events.
> 
> Make this mechanism more explicit by adding an 'active_intc' pointer
> and an explicit spapr_irq_update_active_intc() function to update it
> from the CAS state.  We also add hooks on the intc backend which will
> get called when it is activated or deactivated.

I don't see the exact benefit of extra pointers and routines as we can 
calculate the exact same state from other pointers. 

> For now we just introduce the switch and hooks, later patches will
> actually start using them.

OK. 

> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---
>  hw/ppc/spapr_irq.c         | 51 ++++++++++++++++++++++++++++++++++++++
>  include/hw/ppc/spapr.h     |  5 ++--
>  include/hw/ppc/spapr_irq.h |  5 ++++
>  3 files changed, 59 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index ea44378d8c..dfa875b7cd 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -593,6 +593,7 @@ qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq)
>  
>  int spapr_irq_post_load(SpaprMachineState *spapr, int version_id)
>  {
> +    spapr_irq_update_active_intc(spapr);
>      return spapr->irq->post_load(spapr, version_id);
>  }
>  
> @@ -600,6 +601,8 @@ void spapr_irq_reset(SpaprMachineState *spapr, Error **errp)
>  {
>      assert(!spapr->irq_map || bitmap_empty(spapr->irq_map, spapr->irq_map_nr));
>  
> +    spapr_irq_update_active_intc(spapr);
> +
>      if (spapr->irq->reset) {
>          spapr->irq->reset(spapr, errp);
>      }
> @@ -626,6 +629,54 @@ int spapr_irq_get_phandle(SpaprMachineState *spapr, void *fdt, Error **errp)
>      return phandle;
>  }
>  
> +static void set_active_intc(SpaprMachineState *spapr,
> +                            SpaprInterruptController *new_intc)
> +{
> +    SpaprInterruptControllerClass *sicc;
> +
> +    assert(new_intc);
> +
> +    if (new_intc == spapr->active_intc) {
> +        /* Nothing to do */
> +        return;
> +    }
> +
> +    if (spapr->active_intc) {
> +        sicc = SPAPR_INTC_GET_CLASS(spapr->active_intc);
> +        if (sicc->deactivate) {
> +            sicc->deactivate(spapr->active_intc);
> +        }
> +    }
> +
> +    sicc = SPAPR_INTC_GET_CLASS(new_intc);
> +    if (sicc->activate) {
> +        sicc->activate(new_intc, &error_fatal);
> +    }
> +
> +    spapr->active_intc = new_intc;
> +}
> +
> +void spapr_irq_update_active_intc(SpaprMachineState *spapr)
> +{
> +    SpaprInterruptController *new_intc;
> +
> +    if (!spapr->ics) {
> +        /*
> +         * XXX before we run CAS, ov5_cas is initialized empty, which
> +         * indicates XICS, even if we have ic-mode=xive.  TODO: clean
> +         * up the CAS path so that we have a clearer way of handling
> +         * this.
> +         */
> +        new_intc = SPAPR_INTC(spapr->xive);
> +    } else if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
> +        new_intc = SPAPR_INTC(spapr->xive);
> +    } else {
> +        new_intc = SPAPR_INTC(spapr->ics);
> +    }
> +
> +    set_active_intc(spapr, new_intc);
> +}
> +
>  /*
>   * XICS legacy routines - to deprecate one day
>   */
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index cbd1a4c9f3..763da757f0 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -143,7 +143,6 @@ struct SpaprMachineState {
>      struct SpaprVioBus *vio_bus;
>      QLIST_HEAD(, SpaprPhbState) phbs;
>      struct SpaprNvram *nvram;
> -    ICSState *ics;
>      SpaprRtcState rtc;
>  
>      SpaprResizeHpt resize_hpt;
> @@ -195,9 +194,11 @@ struct SpaprMachineState {
>  
>      int32_t irq_map_nr;
>      unsigned long *irq_map;
> -    SpaprXive  *xive;
>      SpaprIrq *irq;
>      qemu_irq *qirqs;
> +    SpaprInterruptController *active_intc;
> +    ICSState *ics;
> +    SpaprXive *xive;
>  
>      bool cmd_line_caps[SPAPR_CAP_NUM];
>      SpaprCapabilities def, eff, mig;
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index 616086f9bb..3102d152b2 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -44,6 +44,9 @@ typedef struct SpaprInterruptController SpaprInterruptController;
>  typedef struct SpaprInterruptControllerClass {
>      InterfaceClass parent;
>  
> +    void (*activate)(SpaprInterruptController *intc, Error **errp);
> +    void (*deactivate)(SpaprInterruptController *intc);
> +
>      /*
>       * These methods will typically be called on all intcs, active and
>       * inactive
> @@ -55,6 +58,8 @@ typedef struct SpaprInterruptControllerClass {
>      void (*free_irq)(SpaprInterruptController *intc, int irq);
>  } SpaprInterruptControllerClass;
>  
> +void spapr_irq_update_active_intc(SpaprMachineState *spapr);
> +
>  void spapr_irq_print_info(SpaprMachineState *spapr, Monitor *mon);
>  void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers,
>                    void *fdt, uint32_t phandle);
> 



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

* Re: [PATCH v2 24/33] spapr, xics, xive: Move set_irq from SpaprIrq to SpaprInterruptController
  2019-09-27  5:50 ` [PATCH v2 24/33] spapr, xics, xive: Move set_irq from SpaprIrq to SpaprInterruptController David Gibson
  2019-09-27 14:27   ` Greg Kurz
@ 2019-09-30  5:48   ` Cédric Le Goater
  1 sibling, 0 replies; 83+ messages in thread
From: Cédric Le Goater @ 2019-09-30  5:48 UTC (permalink / raw)
  To: David Gibson, qemu-devel, qemu-ppc
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, Paolo Bonzini,
	Marc-André Lureau, philmd

On 27/09/2019 07:50, David Gibson wrote:
> This method depends only on the active irq controller.  Now that we've
> formalized the notion of active controller we can dispatch directly through
> that, rather than dispatching via SpaprIrq with the dual version having
> to do a second conditional dispatch.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---
>  hw/intc/spapr_xive.c       | 12 +++++++++++
>  hw/intc/xics_spapr.c       |  9 +++++++++
>  hw/ppc/spapr_irq.c         | 41 ++++++++++----------------------------
>  include/hw/ppc/spapr_irq.h |  4 +++-
>  4 files changed, 34 insertions(+), 32 deletions(-)
> 
> diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
> index ff1a175b44..52d5e71793 100644
> --- a/hw/intc/spapr_xive.c
> +++ b/hw/intc/spapr_xive.c
> @@ -553,6 +553,17 @@ static int spapr_xive_cpu_intc_create(SpaprInterruptController *intc,
>      return 0;
>  }
>  
> +static void spapr_xive_set_irq(SpaprInterruptController *intc, int irq, int val)
> +{
> +    SpaprXive *xive = SPAPR_XIVE(intc);
> +
> +    if (kvm_irqchip_in_kernel()) {
> +        kvmppc_xive_source_set_irq(&xive->source, irq, val);
> +    } else {
> +        xive_source_set_irq(&xive->source, irq, val);
> +    }
> +}
>  static void spapr_xive_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
> @@ -574,6 +585,7 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data)
>      sicc->cpu_intc_create = spapr_xive_cpu_intc_create;
>      sicc->claim_irq = spapr_xive_claim_irq;
>      sicc->free_irq = spapr_xive_free_irq;
> +    sicc->set_irq = spapr_xive_set_irq;
>  }
>  
>  static const TypeInfo spapr_xive_info = {
> diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
> index 224fe1efcd..02372697f6 100644
> --- a/hw/intc/xics_spapr.c
> +++ b/hw/intc/xics_spapr.c
> @@ -373,6 +373,14 @@ static void xics_spapr_free_irq(SpaprInterruptController *intc, int irq)
>      memset(&ics->irqs[srcno], 0, sizeof(ICSIRQState));
>  }
>  
> +static void xics_spapr_set_irq(SpaprInterruptController *intc, int irq, int val)
> +{
> +    ICSState *ics = ICS_SPAPR(intc);
> +    uint32_t srcno = irq - ics->offset;
> +
> +    ics_set_irq(ics, srcno, val);
> +}
> +
>  static void ics_spapr_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
> @@ -384,6 +392,7 @@ static void ics_spapr_class_init(ObjectClass *klass, void *data)
>      sicc->cpu_intc_create = xics_spapr_cpu_intc_create;
>      sicc->claim_irq = xics_spapr_claim_irq;
>      sicc->free_irq = xics_spapr_free_irq;
> +    sicc->set_irq = xics_spapr_set_irq;
>  }
>  
>  static const TypeInfo ics_spapr_info = {
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index dfa875b7cd..4922062908 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -123,14 +123,6 @@ static int spapr_irq_post_load_xics(SpaprMachineState *spapr, int version_id)
>      return 0;
>  }
>  
> -static void spapr_irq_set_irq_xics(void *opaque, int irq, int val)
> -{
> -    SpaprMachineState *spapr = opaque;
> -    uint32_t srcno = irq - spapr->ics->offset;
> -
> -    ics_set_irq(spapr->ics, srcno, val);
> -}
> -
>  static void spapr_irq_reset_xics(SpaprMachineState *spapr, Error **errp)
>  {
>      Error *local_err = NULL;
> @@ -159,7 +151,6 @@ SpaprIrq spapr_irq_xics = {
>      .dt_populate = spapr_dt_xics,
>      .post_load   = spapr_irq_post_load_xics,
>      .reset       = spapr_irq_reset_xics,
> -    .set_irq     = spapr_irq_set_irq_xics,
>      .init_kvm    = spapr_irq_init_kvm_xics,
>  };
>  
> @@ -208,17 +199,6 @@ static void spapr_irq_reset_xive(SpaprMachineState *spapr, Error **errp)
>      spapr_xive_mmio_set_enabled(spapr->xive, true);
>  }
>  
> -static void spapr_irq_set_irq_xive(void *opaque, int irq, int val)
> -{
> -    SpaprMachineState *spapr = opaque;
> -
> -    if (kvm_irqchip_in_kernel()) {
> -        kvmppc_xive_source_set_irq(&spapr->xive->source, irq, val);
> -    } else {
> -        xive_source_set_irq(&spapr->xive->source, irq, val);
> -    }
> -}
> -
>  static void spapr_irq_init_kvm_xive(SpaprMachineState *spapr, Error **errp)
>  {
>      if (kvm_enabled()) {
> @@ -236,7 +216,6 @@ SpaprIrq spapr_irq_xive = {
>      .dt_populate = spapr_dt_xive,
>      .post_load   = spapr_irq_post_load_xive,
>      .reset       = spapr_irq_reset_xive,
> -    .set_irq     = spapr_irq_set_irq_xive,
>      .init_kvm    = spapr_irq_init_kvm_xive,
>  };
>  
> @@ -316,13 +295,6 @@ static void spapr_irq_reset_dual(SpaprMachineState *spapr, Error **errp)
>      spapr_irq_current(spapr)->reset(spapr, errp);
>  }
>  
> -static void spapr_irq_set_irq_dual(void *opaque, int irq, int val)
> -{
> -    SpaprMachineState *spapr = opaque;
> -
> -    spapr_irq_current(spapr)->set_irq(spapr, irq, val);
> -}
> -
>  /*
>   * Define values in sync with the XIVE and XICS backend
>   */
> @@ -336,7 +308,6 @@ SpaprIrq spapr_irq_dual = {
>      .dt_populate = spapr_irq_dt_populate_dual,
>      .post_load   = spapr_irq_post_load_dual,
>      .reset       = spapr_irq_reset_dual,
> -    .set_irq     = spapr_irq_set_irq_dual,
>      .init_kvm    = NULL, /* should not be used */
>  };

Above changes are all fine. I am still dubious for the 'active_intc'.

C.


> @@ -422,6 +393,15 @@ int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
>      return 0;
>  }
>  
> +static void spapr_set_irq(void *opaque, int irq, int level)
> +{
> +    SpaprMachineState *spapr = SPAPR_MACHINE(opaque);
> +    SpaprInterruptControllerClass *sicc
> +        = SPAPR_INTC_GET_CLASS(spapr->active_intc);
> +
> +    sicc->set_irq(spapr->active_intc, irq, level);
> +}
> +
>  void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>  {
>      MachineState *machine = MACHINE(spapr);
> @@ -510,7 +490,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>          spapr_xive_hcall_init(spapr);
>      }
>  
> -    spapr->qirqs = qemu_allocate_irqs(spapr->irq->set_irq, spapr,
> +    spapr->qirqs = qemu_allocate_irqs(spapr_set_irq, spapr,
>                                        spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
>  
>  out:
> @@ -744,7 +724,6 @@ SpaprIrq spapr_irq_xics_legacy = {
>      .dt_populate = spapr_dt_xics,
>      .post_load   = spapr_irq_post_load_xics,
>      .reset       = spapr_irq_reset_xics,
> -    .set_irq     = spapr_irq_set_irq_xics,
>      .init_kvm    = spapr_irq_init_kvm_xics,
>  };
>  
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index 3102d152b2..8286a9aa63 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -56,6 +56,9 @@ typedef struct SpaprInterruptControllerClass {
>      int (*claim_irq)(SpaprInterruptController *intc, int irq, bool lsi,
>                       Error **errp);
>      void (*free_irq)(SpaprInterruptController *intc, int irq);
> +
> +    /* These methods should only be called on the active intc */
> +    void (*set_irq)(SpaprInterruptController *intc, int irq, int val);
>  } SpaprInterruptControllerClass;
>  
>  void spapr_irq_update_active_intc(SpaprMachineState *spapr);
> @@ -83,7 +86,6 @@ typedef struct SpaprIrq {
>                          void *fdt, uint32_t phandle);
>      int (*post_load)(SpaprMachineState *spapr, int version_id);
>      void (*reset)(SpaprMachineState *spapr, Error **errp);
> -    void (*set_irq)(void *opaque, int srcno, int val);
>      void (*init_kvm)(SpaprMachineState *spapr, Error **errp);
>  } SpaprIrq;
>  
> 



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

* Re: [PATCH v2 26/33] spapr, xics, xive: Move dt_populate from SpaprIrq to SpaprInterruptController
  2019-09-27  5:50 ` [PATCH v2 26/33] spapr, xics, xive: Move dt_populate " David Gibson
  2019-09-27 14:38   ` Greg Kurz
@ 2019-09-30  5:51   ` Cédric Le Goater
  1 sibling, 0 replies; 83+ messages in thread
From: Cédric Le Goater @ 2019-09-30  5:51 UTC (permalink / raw)
  To: David Gibson, qemu-devel, qemu-ppc
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, Paolo Bonzini,
	Marc-André Lureau, philmd

On 27/09/2019 07:50, David Gibson wrote:
> This method depends only on the active irq controller.  Now that we've
> formalized the notion of active controller we can dispatch directly
> through that, rather than dispatching via SpaprIrq with the dual
> version having to do a second conditional dispatch.

You are moving code from one interface to another and using 
a precalculated 'field' instead of spapr_irq_current(spapr).

I don't see the benefits yet.

C.

> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---
>  hw/intc/spapr_xive.c        | 125 ++++++++++++++++++------------------
>  hw/intc/xics_spapr.c        |   5 +-
>  hw/ppc/spapr.c              |   3 +-
>  hw/ppc/spapr_irq.c          |  20 +++---
>  include/hw/ppc/spapr_irq.h  |   5 +-
>  include/hw/ppc/spapr_xive.h |   2 -
>  include/hw/ppc/xics_spapr.h |   2 -
>  7 files changed, 78 insertions(+), 84 deletions(-)
> 
> diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
> index 700ec5c9c1..37ffb74ca5 100644
> --- a/hw/intc/spapr_xive.c
> +++ b/hw/intc/spapr_xive.c
> @@ -578,6 +578,68 @@ static void spapr_xive_print_info(SpaprInterruptController *intc, Monitor *mon)
>      spapr_xive_pic_print_info(xive, mon);
>  }
>  
> +static void spapr_xive_dt(SpaprInterruptController *intc, uint32_t nr_servers,
> +                          void *fdt, uint32_t phandle)
> +{
> +    SpaprXive *xive = SPAPR_XIVE(intc);
> +    int node;
> +    uint64_t timas[2 * 2];
> +    /* Interrupt number ranges for the IPIs */
> +    uint32_t lisn_ranges[] = {
> +        cpu_to_be32(0),
> +        cpu_to_be32(nr_servers),
> +    };
> +    /*
> +     * EQ size - the sizes of pages supported by the system 4K, 64K,
> +     * 2M, 16M. We only advertise 64K for the moment.
> +     */
> +    uint32_t eq_sizes[] = {
> +        cpu_to_be32(16), /* 64K */
> +    };
> +    /*
> +     * The following array is in sync with the reserved priorities
> +     * defined by the 'spapr_xive_priority_is_reserved' routine.
> +     */
> +    uint32_t plat_res_int_priorities[] = {
> +        cpu_to_be32(7),    /* start */
> +        cpu_to_be32(0xf8), /* count */
> +    };
> +
> +    /* Thread Interrupt Management Area : User (ring 3) and OS (ring 2) */
> +    timas[0] = cpu_to_be64(xive->tm_base +
> +                           XIVE_TM_USER_PAGE * (1ull << TM_SHIFT));
> +    timas[1] = cpu_to_be64(1ull << TM_SHIFT);
> +    timas[2] = cpu_to_be64(xive->tm_base +
> +                           XIVE_TM_OS_PAGE * (1ull << TM_SHIFT));
> +    timas[3] = cpu_to_be64(1ull << TM_SHIFT);
> +
> +    _FDT(node = fdt_add_subnode(fdt, 0, xive->nodename));
> +
> +    _FDT(fdt_setprop_string(fdt, node, "device_type", "power-ivpe"));
> +    _FDT(fdt_setprop(fdt, node, "reg", timas, sizeof(timas)));
> +
> +    _FDT(fdt_setprop_string(fdt, node, "compatible", "ibm,power-ivpe"));
> +    _FDT(fdt_setprop(fdt, node, "ibm,xive-eq-sizes", eq_sizes,
> +                     sizeof(eq_sizes)));
> +    _FDT(fdt_setprop(fdt, node, "ibm,xive-lisn-ranges", lisn_ranges,
> +                     sizeof(lisn_ranges)));
> +
> +    /* For Linux to link the LSIs to the interrupt controller. */
> +    _FDT(fdt_setprop(fdt, node, "interrupt-controller", NULL, 0));
> +    _FDT(fdt_setprop_cell(fdt, node, "#interrupt-cells", 2));
> +
> +    /* For SLOF */
> +    _FDT(fdt_setprop_cell(fdt, node, "linux,phandle", phandle));
> +    _FDT(fdt_setprop_cell(fdt, node, "phandle", phandle));
> +
> +    /*
> +     * The "ibm,plat-res-int-priorities" property defines the priority
> +     * ranges reserved by the hypervisor
> +     */
> +    _FDT(fdt_setprop(fdt, 0, "ibm,plat-res-int-priorities",
> +                     plat_res_int_priorities, sizeof(plat_res_int_priorities)));
> +}
> +
>  static void spapr_xive_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
> @@ -601,6 +663,7 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data)
>      sicc->free_irq = spapr_xive_free_irq;
>      sicc->set_irq = spapr_xive_set_irq;
>      sicc->print_info = spapr_xive_print_info;
> +    sicc->dt = spapr_xive_dt;
>  }
>  
>  static const TypeInfo spapr_xive_info = {
> @@ -1601,65 +1664,3 @@ void spapr_xive_hcall_init(SpaprMachineState *spapr)
>      spapr_register_hypercall(H_INT_SYNC, h_int_sync);
>      spapr_register_hypercall(H_INT_RESET, h_int_reset);
>  }
> -
> -void spapr_dt_xive(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
> -                   uint32_t phandle)
> -{
> -    SpaprXive *xive = spapr->xive;
> -    int node;
> -    uint64_t timas[2 * 2];
> -    /* Interrupt number ranges for the IPIs */
> -    uint32_t lisn_ranges[] = {
> -        cpu_to_be32(0),
> -        cpu_to_be32(nr_servers),
> -    };
> -    /*
> -     * EQ size - the sizes of pages supported by the system 4K, 64K,
> -     * 2M, 16M. We only advertise 64K for the moment.
> -     */
> -    uint32_t eq_sizes[] = {
> -        cpu_to_be32(16), /* 64K */
> -    };
> -    /*
> -     * The following array is in sync with the reserved priorities
> -     * defined by the 'spapr_xive_priority_is_reserved' routine.
> -     */
> -    uint32_t plat_res_int_priorities[] = {
> -        cpu_to_be32(7),    /* start */
> -        cpu_to_be32(0xf8), /* count */
> -    };
> -
> -    /* Thread Interrupt Management Area : User (ring 3) and OS (ring 2) */
> -    timas[0] = cpu_to_be64(xive->tm_base +
> -                           XIVE_TM_USER_PAGE * (1ull << TM_SHIFT));
> -    timas[1] = cpu_to_be64(1ull << TM_SHIFT);
> -    timas[2] = cpu_to_be64(xive->tm_base +
> -                           XIVE_TM_OS_PAGE * (1ull << TM_SHIFT));
> -    timas[3] = cpu_to_be64(1ull << TM_SHIFT);
> -
> -    _FDT(node = fdt_add_subnode(fdt, 0, xive->nodename));
> -
> -    _FDT(fdt_setprop_string(fdt, node, "device_type", "power-ivpe"));
> -    _FDT(fdt_setprop(fdt, node, "reg", timas, sizeof(timas)));
> -
> -    _FDT(fdt_setprop_string(fdt, node, "compatible", "ibm,power-ivpe"));
> -    _FDT(fdt_setprop(fdt, node, "ibm,xive-eq-sizes", eq_sizes,
> -                     sizeof(eq_sizes)));
> -    _FDT(fdt_setprop(fdt, node, "ibm,xive-lisn-ranges", lisn_ranges,
> -                     sizeof(lisn_ranges)));
> -
> -    /* For Linux to link the LSIs to the interrupt controller. */
> -    _FDT(fdt_setprop(fdt, node, "interrupt-controller", NULL, 0));
> -    _FDT(fdt_setprop_cell(fdt, node, "#interrupt-cells", 2));
> -
> -    /* For SLOF */
> -    _FDT(fdt_setprop_cell(fdt, node, "linux,phandle", phandle));
> -    _FDT(fdt_setprop_cell(fdt, node, "phandle", phandle));
> -
> -    /*
> -     * The "ibm,plat-res-int-priorities" property defines the priority
> -     * ranges reserved by the hypervisor
> -     */
> -    _FDT(fdt_setprop(fdt, 0, "ibm,plat-res-int-priorities",
> -                     plat_res_int_priorities, sizeof(plat_res_int_priorities)));
> -}
> diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
> index 415defe394..4eabafc7e1 100644
> --- a/hw/intc/xics_spapr.c
> +++ b/hw/intc/xics_spapr.c
> @@ -308,8 +308,8 @@ static void ics_spapr_realize(DeviceState *dev, Error **errp)
>      spapr_register_hypercall(H_IPOLL, h_ipoll);
>  }
>  
> -void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
> -                   uint32_t phandle)
> +static void xics_spapr_dt(SpaprInterruptController *intc, uint32_t nr_servers,
> +                          void *fdt, uint32_t phandle)
>  {
>      uint32_t interrupt_server_ranges_prop[] = {
>          0, cpu_to_be32(nr_servers),
> @@ -408,6 +408,7 @@ static void ics_spapr_class_init(ObjectClass *klass, void *data)
>      sicc->free_irq = xics_spapr_free_irq;
>      sicc->set_irq = xics_spapr_set_irq;
>      sicc->print_info = xics_spapr_print_info;
> +    sicc->dt = xics_spapr_dt;
>  }
>  
>  static const TypeInfo ics_spapr_info = {
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 7e04746db1..f55d227cd3 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -1325,8 +1325,7 @@ static void *spapr_build_fdt(SpaprMachineState *spapr)
>      _FDT(fdt_setprop_cell(fdt, 0, "#size-cells", 2));
>  
>      /* /interrupt controller */
> -    spapr->irq->dt_populate(spapr, spapr_max_server_number(spapr), fdt,
> -                          PHANDLE_INTC);
> +    spapr_irq_dt(spapr, spapr_max_server_number(spapr), fdt, PHANDLE_INTC);
>  
>      ret = spapr_populate_memory(spapr, fdt);
>      if (ret < 0) {
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index be20bbf3cf..79cbe8064e 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -134,7 +134,6 @@ SpaprIrq spapr_irq_xics = {
>      .xics        = true,
>      .xive        = false,
>  
> -    .dt_populate = spapr_dt_xics,
>      .post_load   = spapr_irq_post_load_xics,
>      .reset       = spapr_irq_reset_xics,
>      .init_kvm    = spapr_irq_init_kvm_xics,
> @@ -184,7 +183,6 @@ SpaprIrq spapr_irq_xive = {
>      .xics        = false,
>      .xive        = true,
>  
> -    .dt_populate = spapr_dt_xive,
>      .post_load   = spapr_irq_post_load_xive,
>      .reset       = spapr_irq_reset_xive,
>      .init_kvm    = spapr_irq_init_kvm_xive,
> @@ -209,13 +207,6 @@ static SpaprIrq *spapr_irq_current(SpaprMachineState *spapr)
>          &spapr_irq_xive : &spapr_irq_xics;
>  }
>  
> -static void spapr_irq_dt_populate_dual(SpaprMachineState *spapr,
> -                                       uint32_t nr_servers, void *fdt,
> -                                       uint32_t phandle)
> -{
> -    spapr_irq_current(spapr)->dt_populate(spapr, nr_servers, fdt, phandle);
> -}
> -
>  static int spapr_irq_post_load_dual(SpaprMachineState *spapr, int version_id)
>  {
>      /*
> @@ -270,7 +261,6 @@ SpaprIrq spapr_irq_dual = {
>      .xics        = true,
>      .xive        = true,
>  
> -    .dt_populate = spapr_irq_dt_populate_dual,
>      .post_load   = spapr_irq_post_load_dual,
>      .reset       = spapr_irq_reset_dual,
>      .init_kvm    = NULL, /* should not be used */
> @@ -375,6 +365,15 @@ void spapr_irq_print_info(SpaprMachineState *spapr, Monitor *mon)
>      sicc->print_info(spapr->active_intc, mon);
>  }
>  
> +void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers,
> +                  void *fdt, uint32_t phandle)
> +{
> +    SpaprInterruptControllerClass *sicc
> +        = SPAPR_INTC_GET_CLASS(spapr->active_intc);
> +
> +    sicc->dt(spapr->active_intc, nr_servers, fdt, phandle);
> +}
> +
>  void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>  {
>      MachineState *machine = MACHINE(spapr);
> @@ -693,7 +692,6 @@ SpaprIrq spapr_irq_xics_legacy = {
>      .xics        = true,
>      .xive        = false,
>  
> -    .dt_populate = spapr_dt_xics,
>      .post_load   = spapr_irq_post_load_xics,
>      .reset       = spapr_irq_reset_xics,
>      .init_kvm    = spapr_irq_init_kvm_xics,
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index 2ade580992..c82724fc2b 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -60,6 +60,8 @@ typedef struct SpaprInterruptControllerClass {
>      /* These methods should only be called on the active intc */
>      void (*set_irq)(SpaprInterruptController *intc, int irq, int val);
>      void (*print_info)(SpaprInterruptController *intc, Monitor *mon);
> +    void (*dt)(SpaprInterruptController *intc, uint32_t nr_servers,
> +               void *fdt, uint32_t phandle);
>  } SpaprInterruptControllerClass;
>  
>  void spapr_irq_update_active_intc(SpaprMachineState *spapr);
> @@ -70,7 +72,6 @@ void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers,
>  int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
>                                PowerPCCPU *cpu, Error **errp);
>  
> -
>  void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis);
>  int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align,
>                          Error **errp);
> @@ -82,8 +83,6 @@ typedef struct SpaprIrq {
>      bool        xics;
>      bool        xive;
>  
> -    void (*dt_populate)(SpaprMachineState *spapr, uint32_t nr_servers,
> -                        void *fdt, uint32_t phandle);
>      int (*post_load)(SpaprMachineState *spapr, int version_id);
>      void (*reset)(SpaprMachineState *spapr, Error **errp);
>      void (*init_kvm)(SpaprMachineState *spapr, Error **errp);
> diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h
> index 8f875673f5..ebe156eb30 100644
> --- a/include/hw/ppc/spapr_xive.h
> +++ b/include/hw/ppc/spapr_xive.h
> @@ -58,8 +58,6 @@ void spapr_xive_pic_print_info(SpaprXive *xive, Monitor *mon);
>  int spapr_xive_post_load(SpaprXive *xive, int version_id);
>  
>  void spapr_xive_hcall_init(SpaprMachineState *spapr);
> -void spapr_dt_xive(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
> -                   uint32_t phandle);
>  void spapr_xive_set_tctx_os_cam(XiveTCTX *tctx);
>  void spapr_xive_mmio_set_enabled(SpaprXive *xive, bool enable);
>  void spapr_xive_map_mmio(SpaprXive *xive);
> diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h
> index 0a32a86e3e..9c9044db65 100644
> --- a/include/hw/ppc/xics_spapr.h
> +++ b/include/hw/ppc/xics_spapr.h
> @@ -33,8 +33,6 @@
>  #define ICS_SPAPR(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SPAPR)
>  
>  void ics_spapr_create(SpaprMachineState *spapr, int nr_xirqs, Error **errp);
> -void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
> -                   uint32_t phandle);
>  int xics_kvm_connect(SpaprMachineState *spapr, Error **errp);
>  void xics_kvm_disconnect(SpaprMachineState *spapr, Error **errp);
>  bool xics_kvm_has_broken_disconnect(SpaprMachineState *spapr);
> 



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

* Re: [PATCH v2 27/33] spapr, xics, xive: Match signatures for XICS and XIVE KVM connect routines
  2019-09-27  5:50 ` [PATCH v2 27/33] spapr, xics, xive: Match signatures for XICS and XIVE KVM connect routines David Gibson
  2019-09-27 14:49   ` Greg Kurz
@ 2019-09-30  5:52   ` Cédric Le Goater
  1 sibling, 0 replies; 83+ messages in thread
From: Cédric Le Goater @ 2019-09-30  5:52 UTC (permalink / raw)
  To: David Gibson, qemu-devel, qemu-ppc
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, Paolo Bonzini,
	Marc-André Lureau, philmd

On 27/09/2019 07:50, David Gibson wrote:
> Both XICS and XIVE have routines to connect and disconnect KVM with similar
> but not identical signatures.  This adjusts them to match exactly, which
> will be useful for further cleanups later.
> 
> While we're at it, remove error reporting from the disconnect path.  In the
> XICS case this wasn't used at all.  In the XIVE case the only error case
> was if the KVM device was set up, but KVM didn't have the capability to do
> so which is pretty obviously impossible.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>

Reviewed-by: Cédric Le Goater <clg@kaod.org>

> ---
>  hw/intc/spapr_xive_kvm.c    | 22 ++++++++++------------
>  hw/intc/xics_kvm.c          |  9 +++++----
>  hw/ppc/spapr_irq.c          | 22 +++++-----------------
>  include/hw/ppc/spapr_xive.h |  4 ++--
>  include/hw/ppc/xics_spapr.h |  4 ++--
>  5 files changed, 24 insertions(+), 37 deletions(-)
> 
> diff --git a/hw/intc/spapr_xive_kvm.c b/hw/intc/spapr_xive_kvm.c
> index 51b334b676..08012ac7cd 100644
> --- a/hw/intc/spapr_xive_kvm.c
> +++ b/hw/intc/spapr_xive_kvm.c
> @@ -740,8 +740,9 @@ static void *kvmppc_xive_mmap(SpaprXive *xive, int pgoff, size_t len,
>   * All the XIVE memory regions are now backed by mappings from the KVM
>   * XIVE device.
>   */
> -void kvmppc_xive_connect(SpaprXive *xive, Error **errp)
> +int kvmppc_xive_connect(SpaprInterruptController *intc, Error **errp)
>  {
> +    SpaprXive *xive = SPAPR_XIVE(intc);
>      XiveSource *xsrc = &xive->source;
>      Error *local_err = NULL;
>      size_t esb_len = (1ull << xsrc->esb_shift) * xsrc->nr_irqs;
> @@ -753,19 +754,19 @@ void kvmppc_xive_connect(SpaprXive *xive, Error **errp)
>       * rebooting under the XIVE-only interrupt mode.
>       */
>      if (xive->fd != -1) {
> -        return;
> +        return 0;
>      }
>  
>      if (!kvmppc_has_cap_xive()) {
>          error_setg(errp, "IRQ_XIVE capability must be present for KVM");
> -        return;
> +        return -1;
>      }
>  
>      /* First, create the KVM XIVE device */
>      xive->fd = kvm_create_device(kvm_state, KVM_DEV_TYPE_XIVE, false);
>      if (xive->fd < 0) {
>          error_setg_errno(errp, -xive->fd, "XIVE: error creating KVM device");
> -        return;
> +        return -1;
>      }
>  
>      /*
> @@ -821,15 +822,17 @@ void kvmppc_xive_connect(SpaprXive *xive, Error **errp)
>      kvm_kernel_irqchip = true;
>      kvm_msi_via_irqfd_allowed = true;
>      kvm_gsi_direct_mapping = true;
> -    return;
> +    return 0;
>  
>  fail:
>      error_propagate(errp, local_err);
> -    kvmppc_xive_disconnect(xive, NULL);
> +    kvmppc_xive_disconnect(intc);
> +    return -1;
>  }
>  
> -void kvmppc_xive_disconnect(SpaprXive *xive, Error **errp)
> +void kvmppc_xive_disconnect(SpaprInterruptController *intc)
>  {
> +    SpaprXive *xive = SPAPR_XIVE(intc);
>      XiveSource *xsrc;
>      size_t esb_len;
>  
> @@ -838,11 +841,6 @@ void kvmppc_xive_disconnect(SpaprXive *xive, Error **errp)
>          return;
>      }
>  
> -    if (!kvmppc_has_cap_xive()) {
> -        error_setg(errp, "IRQ_XIVE capability must be present for KVM");
> -        return;
> -    }
> -
>      /* Clear the KVM mapping */
>      xsrc = &xive->source;
>      esb_len = (1ull << xsrc->esb_shift) * xsrc->nr_irqs;
> diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
> index ba90d6dc96..954c424b36 100644
> --- a/hw/intc/xics_kvm.c
> +++ b/hw/intc/xics_kvm.c
> @@ -342,8 +342,9 @@ void ics_kvm_set_irq(ICSState *ics, int srcno, int val)
>      }
>  }
>  
> -int xics_kvm_connect(SpaprMachineState *spapr, Error **errp)
> +int xics_kvm_connect(SpaprInterruptController *intc, Error **errp)
>  {
> +    ICSState *ics = ICS_SPAPR(intc);
>      int rc;
>      CPUState *cs;
>      Error *local_err = NULL;
> @@ -413,7 +414,7 @@ int xics_kvm_connect(SpaprMachineState *spapr, Error **errp)
>      }
>  
>      /* Update the KVM sources */
> -    ics_set_kvm_state(spapr->ics, &local_err);
> +    ics_set_kvm_state(ics, &local_err);
>      if (local_err) {
>          goto fail;
>      }
> @@ -431,11 +432,11 @@ int xics_kvm_connect(SpaprMachineState *spapr, Error **errp)
>  
>  fail:
>      error_propagate(errp, local_err);
> -    xics_kvm_disconnect(spapr, NULL);
> +    xics_kvm_disconnect(intc);
>      return -1;
>  }
>  
> -void xics_kvm_disconnect(SpaprMachineState *spapr, Error **errp)
> +void xics_kvm_disconnect(SpaprInterruptController *intc)
>  {
>      /*
>       * Only on P9 using the XICS-on XIVE KVM device:
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index 79cbe8064e..561bdbc4de 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -124,7 +124,7 @@ static void spapr_irq_reset_xics(SpaprMachineState *spapr, Error **errp)
>  static void spapr_irq_init_kvm_xics(SpaprMachineState *spapr, Error **errp)
>  {
>      if (kvm_enabled()) {
> -        xics_kvm_connect(spapr, errp);
> +        xics_kvm_connect(SPAPR_INTC(spapr->ics), errp);
>      }
>  }
>  
> @@ -173,7 +173,7 @@ static void spapr_irq_reset_xive(SpaprMachineState *spapr, Error **errp)
>  static void spapr_irq_init_kvm_xive(SpaprMachineState *spapr, Error **errp)
>  {
>      if (kvm_enabled()) {
> -        kvmppc_xive_connect(spapr->xive, errp);
> +        kvmppc_xive_connect(SPAPR_INTC(spapr->xive), errp);
>      }
>  }
>  
> @@ -215,7 +215,7 @@ static int spapr_irq_post_load_dual(SpaprMachineState *spapr, int version_id)
>       */
>      if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
>          if (kvm_irqchip_in_kernel()) {
> -            xics_kvm_disconnect(spapr, &error_fatal);
> +            xics_kvm_disconnect(SPAPR_INTC(spapr->ics));
>          }
>          spapr_irq_xive.reset(spapr, &error_fatal);
>      }
> @@ -225,8 +225,6 @@ static int spapr_irq_post_load_dual(SpaprMachineState *spapr, int version_id)
>  
>  static void spapr_irq_reset_dual(SpaprMachineState *spapr, Error **errp)
>  {
> -    Error *local_err = NULL;
> -
>      /*
>       * Deactivate the XIVE MMIOs. The XIVE backend will reenable them
>       * if selected.
> @@ -235,18 +233,8 @@ static void spapr_irq_reset_dual(SpaprMachineState *spapr, Error **errp)
>  
>      /* Destroy all KVM devices */
>      if (kvm_irqchip_in_kernel()) {
> -        xics_kvm_disconnect(spapr, &local_err);
> -        if (local_err) {
> -            error_propagate(errp, local_err);
> -            error_prepend(errp, "KVM XICS disconnect failed: ");
> -            return;
> -        }
> -        kvmppc_xive_disconnect(spapr->xive, &local_err);
> -        if (local_err) {
> -            error_propagate(errp, local_err);
> -            error_prepend(errp, "KVM XIVE disconnect failed: ");
> -            return;
> -        }
> +        xics_kvm_disconnect(SPAPR_INTC(spapr->ics));
> +        kvmppc_xive_disconnect(SPAPR_INTC(spapr->xive));
>      }
>  
>      spapr_irq_current(spapr)->reset(spapr, errp);
> diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h
> index ebe156eb30..64972754f9 100644
> --- a/include/hw/ppc/spapr_xive.h
> +++ b/include/hw/ppc/spapr_xive.h
> @@ -68,8 +68,8 @@ int spapr_xive_end_to_target(uint8_t end_blk, uint32_t end_idx,
>  /*
>   * KVM XIVE device helpers
>   */
> -void kvmppc_xive_connect(SpaprXive *xive, Error **errp);
> -void kvmppc_xive_disconnect(SpaprXive *xive, Error **errp);
> +int kvmppc_xive_connect(SpaprInterruptController *intc, Error **errp);
> +void kvmppc_xive_disconnect(SpaprInterruptController *intc);
>  void kvmppc_xive_reset(SpaprXive *xive, Error **errp);
>  void kvmppc_xive_set_source_config(SpaprXive *xive, uint32_t lisn, XiveEAS *eas,
>                                     Error **errp);
> diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h
> index 9c9044db65..445beeffef 100644
> --- a/include/hw/ppc/xics_spapr.h
> +++ b/include/hw/ppc/xics_spapr.h
> @@ -33,8 +33,8 @@
>  #define ICS_SPAPR(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SPAPR)
>  
>  void ics_spapr_create(SpaprMachineState *spapr, int nr_xirqs, Error **errp);
> -int xics_kvm_connect(SpaprMachineState *spapr, Error **errp);
> -void xics_kvm_disconnect(SpaprMachineState *spapr, Error **errp);
> +int xics_kvm_connect(SpaprInterruptController *intc, Error **errp);
> +void xics_kvm_disconnect(SpaprInterruptController *intc);
>  bool xics_kvm_has_broken_disconnect(SpaprMachineState *spapr);
>  
>  #endif /* XICS_SPAPR_H */
> 



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

* Re: [PATCH v2 28/33] spapr: Remove SpaprIrq::init_kvm hook
  2019-09-27  5:50 ` [PATCH v2 28/33] spapr: Remove SpaprIrq::init_kvm hook David Gibson
  2019-09-27 15:04   ` Greg Kurz
@ 2019-09-30  5:55   ` Cédric Le Goater
  1 sibling, 0 replies; 83+ messages in thread
From: Cédric Le Goater @ 2019-09-30  5:55 UTC (permalink / raw)
  To: David Gibson, qemu-devel, qemu-ppc
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, Paolo Bonzini,
	Marc-André Lureau, philmd

On 27/09/2019 07:50, David Gibson wrote:
> This hook is a bit odd.  The only caller is spapr_irq_init_kvm(), but
> it explicitly takes an SpaprIrq *, so it's never really called through the
> current SpaprIrq.  Essentially this is just a way of passing through a
> function pointer so that spapr_irq_init_kvm() can handle some
> configuration and error handling logic without duplicating it between the
> xics and xive reset paths.

yes. There were a few iteration before reaching that state. 
 
> So, make it just take that function pointer.  Because of earlier reworks
> to the KVM connect/disconnect code in the xics and xive backends we can
> also eliminate some wrapper functions and streamline error handling a bit.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>

Reviewed-by: Cédric Le Goater <clg@kaod.org>

> ---
>  hw/ppc/spapr_irq.c         | 74 +++++++++++++-------------------------
>  include/hw/ppc/spapr_irq.h |  1 -
>  2 files changed, 25 insertions(+), 50 deletions(-)
> 
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index 561bdbc4de..c6abebc4ef 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -65,33 +65,35 @@ void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, uint32_t num)
>      bitmap_clear(spapr->irq_map, irq - SPAPR_IRQ_MSI, num);
>  }
>  
> -static void spapr_irq_init_kvm(SpaprMachineState *spapr,
> -                                  SpaprIrq *irq, Error **errp)
> +static int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController *, Error **),
> +                              SpaprInterruptController *intc,
> +                              Error **errp)
>  {
> -    MachineState *machine = MACHINE(spapr);
> +    MachineState *machine = MACHINE(qdev_get_machine());
>      Error *local_err = NULL;
>  
>      if (kvm_enabled() && machine_kernel_irqchip_allowed(machine)) {
> -        irq->init_kvm(spapr, &local_err);
> -        if (local_err && machine_kernel_irqchip_required(machine)) {
> -            error_prepend(&local_err,
> -                          "kernel_irqchip requested but unavailable: ");
> -            error_propagate(errp, local_err);
> -            return;
> -        }
> +        if (fn(intc, &local_err) < 0) {
> +            if (machine_kernel_irqchip_required(machine)) {
> +                error_prepend(&local_err,
> +                              "kernel_irqchip requested but unavailable: ");
> +                error_propagate(errp, local_err);
> +                return -1;
> +            }
>  
> -        if (!local_err) {
> -            return;
> +            /*
> +             * We failed to initialize the KVM device, fallback to
> +             * emulated mode
> +             */
> +            error_prepend(&local_err,
> +                          "kernel_irqchip allowed but unavailable: ");
> +            error_append_hint(&local_err,
> +                              "Falling back to kernel-irqchip=off\n");
> +            warn_report_err(local_err);
>          }
> -
> -        /*
> -         * We failed to initialize the KVM device, fallback to
> -         * emulated mode
> -         */
> -        error_prepend(&local_err, "kernel_irqchip allowed but unavailable: ");
> -        error_append_hint(&local_err, "Falling back to kernel-irqchip=off\n");
> -        warn_report_err(local_err);
>      }
> +
> +    return 0;
>  }
>  
>  /*
> @@ -112,20 +114,7 @@ static int spapr_irq_post_load_xics(SpaprMachineState *spapr, int version_id)
>  
>  static void spapr_irq_reset_xics(SpaprMachineState *spapr, Error **errp)
>  {
> -    Error *local_err = NULL;
> -
> -    spapr_irq_init_kvm(spapr, &spapr_irq_xics, &local_err);
> -    if (local_err) {
> -        error_propagate(errp, local_err);
> -        return;
> -    }
> -}
> -
> -static void spapr_irq_init_kvm_xics(SpaprMachineState *spapr, Error **errp)
> -{
> -    if (kvm_enabled()) {
> -        xics_kvm_connect(SPAPR_INTC(spapr->ics), errp);
> -    }
> +    spapr_irq_init_kvm(xics_kvm_connect, SPAPR_INTC(spapr->ics), errp);
>  }
>  
>  SpaprIrq spapr_irq_xics = {
> @@ -136,7 +125,6 @@ SpaprIrq spapr_irq_xics = {
>  
>      .post_load   = spapr_irq_post_load_xics,
>      .reset       = spapr_irq_reset_xics,
> -    .init_kvm    = spapr_irq_init_kvm_xics,
>  };
>  
>  /*
> @@ -151,7 +139,6 @@ static int spapr_irq_post_load_xive(SpaprMachineState *spapr, int version_id)
>  static void spapr_irq_reset_xive(SpaprMachineState *spapr, Error **errp)
>  {
>      CPUState *cs;
> -    Error *local_err = NULL;
>  
>      CPU_FOREACH(cs) {
>          PowerPCCPU *cpu = POWERPC_CPU(cs);
> @@ -160,9 +147,8 @@ static void spapr_irq_reset_xive(SpaprMachineState *spapr, Error **errp)
>          spapr_xive_set_tctx_os_cam(spapr_cpu_state(cpu)->tctx);
>      }
>  
> -    spapr_irq_init_kvm(spapr, &spapr_irq_xive, &local_err);
> -    if (local_err) {
> -        error_propagate(errp, local_err);
> +    if (spapr_irq_init_kvm(kvmppc_xive_connect,
> +                           SPAPR_INTC(spapr->xive), errp) < 0) {
>          return;
>      }
>  
> @@ -170,13 +156,6 @@ static void spapr_irq_reset_xive(SpaprMachineState *spapr, Error **errp)
>      spapr_xive_mmio_set_enabled(spapr->xive, true);
>  }
>  
> -static void spapr_irq_init_kvm_xive(SpaprMachineState *spapr, Error **errp)
> -{
> -    if (kvm_enabled()) {
> -        kvmppc_xive_connect(SPAPR_INTC(spapr->xive), errp);
> -    }
> -}
> -
>  SpaprIrq spapr_irq_xive = {
>      .nr_xirqs    = SPAPR_NR_XIRQS,
>      .nr_msis     = SPAPR_NR_MSIS,
> @@ -185,7 +164,6 @@ SpaprIrq spapr_irq_xive = {
>  
>      .post_load   = spapr_irq_post_load_xive,
>      .reset       = spapr_irq_reset_xive,
> -    .init_kvm    = spapr_irq_init_kvm_xive,
>  };
>  
>  /*
> @@ -251,7 +229,6 @@ SpaprIrq spapr_irq_dual = {
>  
>      .post_load   = spapr_irq_post_load_dual,
>      .reset       = spapr_irq_reset_dual,
> -    .init_kvm    = NULL, /* should not be used */
>  };
>  
>  
> @@ -682,7 +659,6 @@ SpaprIrq spapr_irq_xics_legacy = {
>  
>      .post_load   = spapr_irq_post_load_xics,
>      .reset       = spapr_irq_reset_xics,
> -    .init_kvm    = spapr_irq_init_kvm_xics,
>  };
>  
>  static void spapr_irq_register_types(void)
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index c82724fc2b..c947f40571 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -85,7 +85,6 @@ typedef struct SpaprIrq {
>  
>      int (*post_load)(SpaprMachineState *spapr, int version_id);
>      void (*reset)(SpaprMachineState *spapr, Error **errp);
> -    void (*init_kvm)(SpaprMachineState *spapr, Error **errp);
>  } SpaprIrq;
>  
>  extern SpaprIrq spapr_irq_xics;
> 



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

* Re: [PATCH v2 29/33] spapr, xics, xive: Move SpaprIrq::reset hook logic into activate/deactivate
  2019-09-27  5:50 ` [PATCH v2 29/33] spapr, xics, xive: Move SpaprIrq::reset hook logic into activate/deactivate David Gibson
@ 2019-09-30  6:11   ` Cédric Le Goater
  2019-09-30  8:25     ` David Gibson
  0 siblings, 1 reply; 83+ messages in thread
From: Cédric Le Goater @ 2019-09-30  6:11 UTC (permalink / raw)
  To: David Gibson, qemu-devel, qemu-ppc
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, Paolo Bonzini,
	Marc-André Lureau, philmd

On 27/09/2019 07:50, David Gibson wrote:
> It turns out that all the logic in the SpaprIrq::reset hooks (and some in
> the SpaprIrq::post_load hooks) isn't really related to resetting the irq
> backend (that's handled by the backends' own reset routines).  Rather its
> about getting the backend ready to be the active interrupt controller or
> stopping being the active interrupt controller - reset (and post_load) is
> just the only time that changes at present.

This is a 'critical' part which impacts all the migration cases: 

ic-mode=xics,xive,dual + kernel_irqchip=on/off + TCG
 
> To make this flow clearer, move the logic into the explicit backend
> activate and deactivate hooks.

I don't see where the hooks are called ? 

> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---
>  hw/intc/spapr_xive.c       | 35 ++++++++++++++++++++
>  hw/intc/xics_spapr.c       | 16 +++++++++
>  hw/ppc/spapr_irq.c         | 67 ++------------------------------------
>  include/hw/ppc/spapr_irq.h |  4 ++-
>  4 files changed, 57 insertions(+), 65 deletions(-)
> 
> diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
> index 37ffb74ca5..e8b946982c 100644
> --- a/hw/intc/spapr_xive.c
> +++ b/hw/intc/spapr_xive.c
> @@ -640,6 +640,39 @@ static void spapr_xive_dt(SpaprInterruptController *intc, uint32_t nr_servers,
>                       plat_res_int_priorities, sizeof(plat_res_int_priorities)));
>  }
>  
> +static void spapr_xive_activate(SpaprInterruptController *intc, Error **errp)
> +{
> +    SpaprXive *xive = SPAPR_XIVE(intc);
> +    CPUState *cs;
> +
> +    CPU_FOREACH(cs) {
> +        PowerPCCPU *cpu = POWERPC_CPU(cs);
> +
> +        /* (TCG) Set the OS CAM line of the thread interrupt context. */
> +        spapr_xive_set_tctx_os_cam(spapr_cpu_state(cpu)->tctx);
> +    }

Setting the thread interrupt registers is only needed in TCG, so it could
be below a else.

> +    if (kvm_enabled()) {
> +        if (spapr_irq_init_kvm(kvmppc_xive_connect, intc, errp) < 0) {
> +            return;
> +        }
> +    }
> +
> +    /* Activate the XIVE MMIOs */
> +    spapr_xive_mmio_set_enabled(xive, true);
> +}
> +
> +static void spapr_xive_deactivate(SpaprInterruptController *intc)
> +{
> +    SpaprXive *xive = SPAPR_XIVE(intc);
> +
> +    spapr_xive_mmio_set_enabled(xive, false);
> +
> +    if (kvm_irqchip_in_kernel()) {
> +        kvmppc_xive_disconnect(intc);
> +    }
> +}
> +
>  static void spapr_xive_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
> @@ -658,6 +691,8 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data)
>      xrc->write_nvt = spapr_xive_write_nvt;
>      xrc->get_tctx = spapr_xive_get_tctx;
>  
> +    sicc->activate = spapr_xive_activate;
> +    sicc->deactivate = spapr_xive_deactivate;
>      sicc->cpu_intc_create = spapr_xive_cpu_intc_create;
>      sicc->claim_irq = spapr_xive_claim_irq;
>      sicc->free_irq = spapr_xive_free_irq;
> diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
> index 4eabafc7e1..8abbc799ba 100644
> --- a/hw/intc/xics_spapr.c
> +++ b/hw/intc/xics_spapr.c
> @@ -395,6 +395,20 @@ static void xics_spapr_print_info(SpaprInterruptController *intc, Monitor *mon)
>      ics_pic_print_info(ics, mon);
>  }
>  
> +static void xics_spapr_activate(SpaprInterruptController *intc, Error **errp)
> +{
> +    if (kvm_enabled()) {
> +        spapr_irq_init_kvm(xics_kvm_connect, intc, errp);
> +    }
> +}
> +
> +static void xics_spapr_deactivate(SpaprInterruptController *intc)
> +{
> +    if (kvm_irqchip_in_kernel()) {
> +        xics_kvm_disconnect(intc);
> +    }
> +}
> +
>  static void ics_spapr_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
> @@ -403,6 +417,8 @@ static void ics_spapr_class_init(ObjectClass *klass, void *data)
>  
>      device_class_set_parent_realize(dc, ics_spapr_realize,
>                                      &isc->parent_realize);
> +    sicc->activate = xics_spapr_activate;
> +    sicc->deactivate = xics_spapr_deactivate;
>      sicc->cpu_intc_create = xics_spapr_cpu_intc_create;
>      sicc->claim_irq = xics_spapr_claim_irq;
>      sicc->free_irq = xics_spapr_free_irq;
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index c6abebc4ef..2fd9dd0ec2 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -65,9 +65,9 @@ void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, uint32_t num)
>      bitmap_clear(spapr->irq_map, irq - SPAPR_IRQ_MSI, num);
>  }
>  
> -static int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController *, Error **),
> -                              SpaprInterruptController *intc,
> -                              Error **errp)
> +int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController *, Error **),
> +                       SpaprInterruptController *intc,
> +                       Error **errp)
>  {
>      MachineState *machine = MACHINE(qdev_get_machine());
>      Error *local_err = NULL;
> @@ -112,11 +112,6 @@ static int spapr_irq_post_load_xics(SpaprMachineState *spapr, int version_id)
>      return 0;
>  }
>  
> -static void spapr_irq_reset_xics(SpaprMachineState *spapr, Error **errp)
> -{
> -    spapr_irq_init_kvm(xics_kvm_connect, SPAPR_INTC(spapr->ics), errp);
> -}
> -
>  SpaprIrq spapr_irq_xics = {
>      .nr_xirqs    = SPAPR_NR_XIRQS,
>      .nr_msis     = SPAPR_NR_MSIS,
> @@ -124,7 +119,6 @@ SpaprIrq spapr_irq_xics = {
>      .xive        = false,
>  
>      .post_load   = spapr_irq_post_load_xics,
> -    .reset       = spapr_irq_reset_xics,
>  };
>  
>  /*
> @@ -136,26 +130,6 @@ static int spapr_irq_post_load_xive(SpaprMachineState *spapr, int version_id)
>      return spapr_xive_post_load(spapr->xive, version_id);
>  }
>  
> -static void spapr_irq_reset_xive(SpaprMachineState *spapr, Error **errp)
> -{
> -    CPUState *cs;
> -
> -    CPU_FOREACH(cs) {
> -        PowerPCCPU *cpu = POWERPC_CPU(cs);
> -
> -        /* (TCG) Set the OS CAM line of the thread interrupt context. */
> -        spapr_xive_set_tctx_os_cam(spapr_cpu_state(cpu)->tctx);
> -    }
> -
> -    if (spapr_irq_init_kvm(kvmppc_xive_connect,
> -                           SPAPR_INTC(spapr->xive), errp) < 0) {
> -        return;
> -    }
> -
> -    /* Activate the XIVE MMIOs */
> -    spapr_xive_mmio_set_enabled(spapr->xive, true);
> -}
> -
>  SpaprIrq spapr_irq_xive = {
>      .nr_xirqs    = SPAPR_NR_XIRQS,
>      .nr_msis     = SPAPR_NR_MSIS,
> @@ -163,7 +137,6 @@ SpaprIrq spapr_irq_xive = {
>      .xive        = true,
>  
>      .post_load   = spapr_irq_post_load_xive,
> -    .reset       = spapr_irq_reset_xive,
>  };
>  
>  /*
> @@ -187,37 +160,9 @@ static SpaprIrq *spapr_irq_current(SpaprMachineState *spapr)
>  
>  static int spapr_irq_post_load_dual(SpaprMachineState *spapr, int version_id)
>  {
> -    /*
> -     * Force a reset of the XIVE backend after migration. The machine
> -     * defaults to XICS at startup.
> -     */
> -    if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
> -        if (kvm_irqchip_in_kernel()) {
> -            xics_kvm_disconnect(SPAPR_INTC(spapr->ics));
> -        }
> -        spapr_irq_xive.reset(spapr, &error_fatal);
> -    }
> -
>      return spapr_irq_current(spapr)->post_load(spapr, version_id);
>  }
>  
> -static void spapr_irq_reset_dual(SpaprMachineState *spapr, Error **errp)
> -{
> -    /*
> -     * Deactivate the XIVE MMIOs. The XIVE backend will reenable them
> -     * if selected.
> -     */
> -    spapr_xive_mmio_set_enabled(spapr->xive, false);
> -
> -    /* Destroy all KVM devices */
> -    if (kvm_irqchip_in_kernel()) {
> -        xics_kvm_disconnect(SPAPR_INTC(spapr->ics));
> -        kvmppc_xive_disconnect(SPAPR_INTC(spapr->xive));
> -    }
> -
> -    spapr_irq_current(spapr)->reset(spapr, errp);
> -}
> -
>  /*
>   * Define values in sync with the XIVE and XICS backend
>   */
> @@ -228,7 +173,6 @@ SpaprIrq spapr_irq_dual = {
>      .xive        = true,
>  
>      .post_load   = spapr_irq_post_load_dual,
> -    .reset       = spapr_irq_reset_dual,
>  };
>  
>  
> @@ -519,10 +463,6 @@ void spapr_irq_reset(SpaprMachineState *spapr, Error **errp)
>      assert(!spapr->irq_map || bitmap_empty(spapr->irq_map, spapr->irq_map_nr));
>  
>      spapr_irq_update_active_intc(spapr);
> -
> -    if (spapr->irq->reset) {
> -        spapr->irq->reset(spapr, errp);
> -    }
>  }
>  
>  int spapr_irq_get_phandle(SpaprMachineState *spapr, void *fdt, Error **errp)
> @@ -658,7 +598,6 @@ SpaprIrq spapr_irq_xics_legacy = {
>      .xive        = false,
>  
>      .post_load   = spapr_irq_post_load_xics,
> -    .reset       = spapr_irq_reset_xics,
>  };
>  
>  static void spapr_irq_register_types(void)
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index c947f40571..28044d7479 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -84,7 +84,6 @@ typedef struct SpaprIrq {
>      bool        xive;
>  
>      int (*post_load)(SpaprMachineState *spapr, int version_id);
> -    void (*reset)(SpaprMachineState *spapr, Error **errp);
>  } SpaprIrq;
>  
>  extern SpaprIrq spapr_irq_xics;
> @@ -99,6 +98,9 @@ qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq);
>  int spapr_irq_post_load(SpaprMachineState *spapr, int version_id);
>  void spapr_irq_reset(SpaprMachineState *spapr, Error **errp);
>  int spapr_irq_get_phandle(SpaprMachineState *spapr, void *fdt, Error **errp);
> +int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController *, Error **),
> +                       SpaprInterruptController *intc,
> +                       Error **errp);
>  
>  /*
>   * XICS legacy routines
> 



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

* Re: [PATCH v2 21/33] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController
  2019-09-30  5:28       ` Cédric Le Goater
@ 2019-09-30  6:14         ` David Gibson
  2019-09-30 10:13           ` Cédric Le Goater
  0 siblings, 1 reply; 83+ messages in thread
From: David Gibson @ 2019-09-30  6:14 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Jason Wang, Riku Voipio, Greg Kurz, qemu-devel, qemu-ppc,
	Marc-André Lureau, Paolo Bonzini, philmd, Laurent Vivier

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

On Mon, Sep 30, 2019 at 07:28:45AM +0200, Cédric Le Goater wrote:
> On 30/09/2019 03:49, David Gibson wrote:
> > On Fri, Sep 27, 2019 at 12:16:49PM +0200, Greg Kurz wrote:
> >> On Fri, 27 Sep 2019 15:50:16 +1000
> >> David Gibson <david@gibson.dropbear.id.au> wrote:
> >>
> >>> This method essentially represents code which belongs to the interrupt
> >>> controller, but needs to be called on all possible intcs, rather than
> >>> just the currently active one.  The "dual" version therefore calls
> >>> into the xics and xive versions confusingly.
> >>>
> >>> Handle this more directly, by making it instead a method on the intc
> >>> backend, and always calling it on every backend that exists.
> >>>
> >>> While we're there, streamline the error reporting a bit.
> >>>
> >>> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> > [snip]
> >>> @@ -525,6 +469,30 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
> >>>  /*
> >>>   * sPAPR IRQ frontend routines for devices
> >>>   */
> >>> +int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
> >>> +                              PowerPCCPU *cpu, Error **errp)
> >>> +{
> >>> +    if (spapr->xive) {
> >>> +        SpaprInterruptController *intc = SPAPR_INTC(spapr->xive);
> >>> +        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
> >>> +
> >>> +        if (sicc->cpu_intc_create(intc, cpu, errp) < 0) {
> >>> +            return -1;
> >>> +        }
> >>> +    }
> >>> +
> >>> +    if (spapr->ics) {
> >>> +        SpaprInterruptController *intc = SPAPR_INTC(spapr->ics);
> >>> +        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
> >>> +
> >>> +        if (sicc->cpu_intc_create(intc, cpu, errp) < 0) {
> >>> +            return -1;
> >>> +        }
> >>> +    }
> >>> +
> >>
> >> Instead of these hooks, what about open-coding spapr_xive_cpu_intc_create()
> >> and xics_spapr_cpu_intc_create() directly here, like you already did for the
> >> ICS and the XIVE objects in spapr_irq_init() ?
> > 
> > I'd prefer not to.  The idea is I want to treat this as basically:
> > 
> > 	foreach_possible_intc(intc)
> > 		intc::cpu_intc_create(...)
> > 
> > If I find time I might indeed replace the explicit ics and xive
> > pointers with just an array of SpaprInterruptController *.
> 
> Or you could use object_child_foreach() and check for the type. If we had
> a helper object_child_foreach_type(), we could use it elsewhere.

I thought about that, but I don't think it quite works.  The
complication is that the xics device is made explicitly a child of the
machine, but the xive device has mmio, so it's a SusBusDevice sitting
on the root bus instead.

-- 
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] 83+ messages in thread

* Re: [PATCH v2 24/33] spapr, xics, xive: Move set_irq from SpaprIrq to SpaprInterruptController
  2019-09-30  2:41     ` David Gibson
@ 2019-09-30  7:22       ` Greg Kurz
  2019-09-30  8:28         ` David Gibson
  0 siblings, 1 reply; 83+ messages in thread
From: Greg Kurz @ 2019-09-30  7:22 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

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

On Mon, 30 Sep 2019 12:41:39 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> On Fri, Sep 27, 2019 at 04:27:12PM +0200, Greg Kurz wrote:
> > On Fri, 27 Sep 2019 15:50:19 +1000
> > David Gibson <david@gibson.dropbear.id.au> wrote:
> > 
> > > This method depends only on the active irq controller.  Now that we've
> > > formalized the notion of active controller we can dispatch directly through
> > > that, rather than dispatching via SpaprIrq with the dual version having
> > > to do a second conditional dispatch.
> > > 
> > > Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> > > ---
> > >  hw/intc/spapr_xive.c       | 12 +++++++++++
> > >  hw/intc/xics_spapr.c       |  9 +++++++++
> > >  hw/ppc/spapr_irq.c         | 41 ++++++++++----------------------------
> > >  include/hw/ppc/spapr_irq.h |  4 +++-
> > >  4 files changed, 34 insertions(+), 32 deletions(-)
> > > 
> > > diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
> > > index ff1a175b44..52d5e71793 100644
> > > --- a/hw/intc/spapr_xive.c
> > > +++ b/hw/intc/spapr_xive.c
> > > @@ -553,6 +553,17 @@ static int spapr_xive_cpu_intc_create(SpaprInterruptController *intc,
> > >      return 0;
> > >  }
> > >  
> > > +static void spapr_xive_set_irq(SpaprInterruptController *intc, int irq, int val)
> > > +{
> > > +    SpaprXive *xive = SPAPR_XIVE(intc);
> > > +
> > > +    if (kvm_irqchip_in_kernel()) {
> > > +        kvmppc_xive_source_set_irq(&xive->source, irq, val);
> > > +    } else {
> > > +        xive_source_set_irq(&xive->source, irq, val);
> > > +    }
> > > +}
> > > +
> > >  static void spapr_xive_class_init(ObjectClass *klass, void *data)
> > >  {
> > >      DeviceClass *dc = DEVICE_CLASS(klass);
> > > @@ -574,6 +585,7 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data)
> > >      sicc->cpu_intc_create = spapr_xive_cpu_intc_create;
> > >      sicc->claim_irq = spapr_xive_claim_irq;
> > >      sicc->free_irq = spapr_xive_free_irq;
> > > +    sicc->set_irq = spapr_xive_set_irq;
> > >  }
> > >  
> > >  static const TypeInfo spapr_xive_info = {
> > > diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
> > > index 224fe1efcd..02372697f6 100644
> > > --- a/hw/intc/xics_spapr.c
> > > +++ b/hw/intc/xics_spapr.c
> > > @@ -373,6 +373,14 @@ static void xics_spapr_free_irq(SpaprInterruptController *intc, int irq)
> > >      memset(&ics->irqs[srcno], 0, sizeof(ICSIRQState));
> > >  }
> > >  
> > > +static void xics_spapr_set_irq(SpaprInterruptController *intc, int irq, int val)
> > > +{
> > > +    ICSState *ics = ICS_SPAPR(intc);
> > > +    uint32_t srcno = irq - ics->offset;
> > > +
> > > +    ics_set_irq(ics, srcno, val);
> > 
> > And we have:
> > 
> > void ics_set_irq(void *opaque, int srcno, int val)
> > {
> >     ICSState *ics = (ICSState *)opaque;
> > 
> >     if (kvm_irqchip_in_kernel()) {
> >         ics_kvm_set_irq(ics, srcno, val);
> >         return;
> >     }
> > 
> >     if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI) {
> >         ics_set_irq_lsi(ics, srcno, val);
> >     } else {
> >         ics_set_irq_msi(ics, srcno, val);
> >     }
> > }
> > 
> > The kvm_irqchip_in_kernel() block would fit better in xics_spapr_set_irq(),
> > like it is already the case for XIVE.
> 
> Hmm.. I don't really see why you say that.
> 

I mean this:

static void xics_spapr_set_irq(SpaprInterruptController *intc, int irq, int val)
{
    IcsSpapr *icss = ICS_SPAPR(intc);
    ICSState *ics = &icss->parent;
    uint32_t srcno = irq - ics->offset;

    if (kvm_irqchip_in_kernel()) {
        ics_kvm_set_irq(ics, srcno, val);
    } else {
        ics_set_irq(ics, srcno, val);
    }
}

It is very similar to spapr_xive_set_irq() and looks nicer to me.

> > Maybe do it now while here ?
> > 
> > Anyway,
> > 
> > Reviewed-by: Greg Kurz <groug@kaod.org>
> > 
> > > +}
> > > +
> > >  static void ics_spapr_class_init(ObjectClass *klass, void *data)
> > >  {
> > >      DeviceClass *dc = DEVICE_CLASS(klass);
> > > @@ -384,6 +392,7 @@ static void ics_spapr_class_init(ObjectClass *klass, void *data)
> > >      sicc->cpu_intc_create = xics_spapr_cpu_intc_create;
> > >      sicc->claim_irq = xics_spapr_claim_irq;
> > >      sicc->free_irq = xics_spapr_free_irq;
> > > +    sicc->set_irq = xics_spapr_set_irq;
> > >  }
> > >  
> > >  static const TypeInfo ics_spapr_info = {
> > > diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> > > index dfa875b7cd..4922062908 100644
> > > --- a/hw/ppc/spapr_irq.c
> > > +++ b/hw/ppc/spapr_irq.c
> > > @@ -123,14 +123,6 @@ static int spapr_irq_post_load_xics(SpaprMachineState *spapr, int version_id)
> > >      return 0;
> > >  }
> > >  
> > > -static void spapr_irq_set_irq_xics(void *opaque, int irq, int val)
> > > -{
> > > -    SpaprMachineState *spapr = opaque;
> > > -    uint32_t srcno = irq - spapr->ics->offset;
> > > -
> > > -    ics_set_irq(spapr->ics, srcno, val);
> > > -}
> > > -
> > >  static void spapr_irq_reset_xics(SpaprMachineState *spapr, Error **errp)
> > >  {
> > >      Error *local_err = NULL;
> > > @@ -159,7 +151,6 @@ SpaprIrq spapr_irq_xics = {
> > >      .dt_populate = spapr_dt_xics,
> > >      .post_load   = spapr_irq_post_load_xics,
> > >      .reset       = spapr_irq_reset_xics,
> > > -    .set_irq     = spapr_irq_set_irq_xics,
> > >      .init_kvm    = spapr_irq_init_kvm_xics,
> > >  };
> > >  
> > > @@ -208,17 +199,6 @@ static void spapr_irq_reset_xive(SpaprMachineState *spapr, Error **errp)
> > >      spapr_xive_mmio_set_enabled(spapr->xive, true);
> > >  }
> > >  
> > > -static void spapr_irq_set_irq_xive(void *opaque, int irq, int val)
> > > -{
> > > -    SpaprMachineState *spapr = opaque;
> > > -
> > > -    if (kvm_irqchip_in_kernel()) {
> > > -        kvmppc_xive_source_set_irq(&spapr->xive->source, irq, val);
> > > -    } else {
> > > -        xive_source_set_irq(&spapr->xive->source, irq, val);
> > > -    }
> > > -}
> > > -
> > >  static void spapr_irq_init_kvm_xive(SpaprMachineState *spapr, Error **errp)
> > >  {
> > >      if (kvm_enabled()) {
> > > @@ -236,7 +216,6 @@ SpaprIrq spapr_irq_xive = {
> > >      .dt_populate = spapr_dt_xive,
> > >      .post_load   = spapr_irq_post_load_xive,
> > >      .reset       = spapr_irq_reset_xive,
> > > -    .set_irq     = spapr_irq_set_irq_xive,
> > >      .init_kvm    = spapr_irq_init_kvm_xive,
> > >  };
> > >  
> > > @@ -316,13 +295,6 @@ static void spapr_irq_reset_dual(SpaprMachineState *spapr, Error **errp)
> > >      spapr_irq_current(spapr)->reset(spapr, errp);
> > >  }
> > >  
> > > -static void spapr_irq_set_irq_dual(void *opaque, int irq, int val)
> > > -{
> > > -    SpaprMachineState *spapr = opaque;
> > > -
> > > -    spapr_irq_current(spapr)->set_irq(spapr, irq, val);
> > > -}
> > > -
> > >  /*
> > >   * Define values in sync with the XIVE and XICS backend
> > >   */
> > > @@ -336,7 +308,6 @@ SpaprIrq spapr_irq_dual = {
> > >      .dt_populate = spapr_irq_dt_populate_dual,
> > >      .post_load   = spapr_irq_post_load_dual,
> > >      .reset       = spapr_irq_reset_dual,
> > > -    .set_irq     = spapr_irq_set_irq_dual,
> > >      .init_kvm    = NULL, /* should not be used */
> > >  };
> > >  
> > > @@ -422,6 +393,15 @@ int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
> > >      return 0;
> > >  }
> > >  
> > > +static void spapr_set_irq(void *opaque, int irq, int level)
> > > +{
> > > +    SpaprMachineState *spapr = SPAPR_MACHINE(opaque);
> > > +    SpaprInterruptControllerClass *sicc
> > > +        = SPAPR_INTC_GET_CLASS(spapr->active_intc);
> > > +
> > > +    sicc->set_irq(spapr->active_intc, irq, level);
> > > +}
> > > +
> > >  void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
> > >  {
> > >      MachineState *machine = MACHINE(spapr);
> > > @@ -510,7 +490,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
> > >          spapr_xive_hcall_init(spapr);
> > >      }
> > >  
> > > -    spapr->qirqs = qemu_allocate_irqs(spapr->irq->set_irq, spapr,
> > > +    spapr->qirqs = qemu_allocate_irqs(spapr_set_irq, spapr,
> > >                                        spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
> > >  
> > >  out:
> > > @@ -744,7 +724,6 @@ SpaprIrq spapr_irq_xics_legacy = {
> > >      .dt_populate = spapr_dt_xics,
> > >      .post_load   = spapr_irq_post_load_xics,
> > >      .reset       = spapr_irq_reset_xics,
> > > -    .set_irq     = spapr_irq_set_irq_xics,
> > >      .init_kvm    = spapr_irq_init_kvm_xics,
> > >  };
> > >  
> > > diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> > > index 3102d152b2..8286a9aa63 100644
> > > --- a/include/hw/ppc/spapr_irq.h
> > > +++ b/include/hw/ppc/spapr_irq.h
> > > @@ -56,6 +56,9 @@ typedef struct SpaprInterruptControllerClass {
> > >      int (*claim_irq)(SpaprInterruptController *intc, int irq, bool lsi,
> > >                       Error **errp);
> > >      void (*free_irq)(SpaprInterruptController *intc, int irq);
> > > +
> > > +    /* These methods should only be called on the active intc */
> > > +    void (*set_irq)(SpaprInterruptController *intc, int irq, int val);
> > >  } SpaprInterruptControllerClass;
> > >  
> > >  void spapr_irq_update_active_intc(SpaprMachineState *spapr);
> > > @@ -83,7 +86,6 @@ typedef struct SpaprIrq {
> > >                          void *fdt, uint32_t phandle);
> > >      int (*post_load)(SpaprMachineState *spapr, int version_id);
> > >      void (*reset)(SpaprMachineState *spapr, Error **errp);
> > > -    void (*set_irq)(void *opaque, int srcno, int val);
> > >      void (*init_kvm)(SpaprMachineState *spapr, Error **errp);
> > >  } SpaprIrq;
> > >  
> > 
> 


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

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

* Re: [PATCH v2 29/33] spapr, xics, xive: Move SpaprIrq::reset hook logic into activate/deactivate
  2019-09-30  6:11   ` Cédric Le Goater
@ 2019-09-30  8:25     ` David Gibson
  2019-09-30 19:29       ` Cédric Le Goater
  0 siblings, 1 reply; 83+ messages in thread
From: David Gibson @ 2019-09-30  8:25 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Jason Wang, Riku Voipio, groug, qemu-devel, qemu-ppc,
	Marc-André Lureau, Paolo Bonzini, philmd, Laurent Vivier

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

On Mon, Sep 30, 2019 at 08:11:56AM +0200, Cédric Le Goater wrote:
> On 27/09/2019 07:50, David Gibson wrote:
> > It turns out that all the logic in the SpaprIrq::reset hooks (and some in
> > the SpaprIrq::post_load hooks) isn't really related to resetting the irq
> > backend (that's handled by the backends' own reset routines).  Rather its
> > about getting the backend ready to be the active interrupt controller or
> > stopping being the active interrupt controller - reset (and post_load) is
> > just the only time that changes at present.
> 
> This is a 'critical' part which impacts all the migration cases: 
> 
> ic-mode=xics,xive,dual + kernel_irqchip=on/off + TCG

Yes... and?

> > To make this flow clearer, move the logic into the explicit backend
> > activate and deactivate hooks.
> 
> I don't see where the hooks are called ?

spapr_irq_reset()
  -> spapr_irq_update_active_intc()
    -> set_active_intc()
      -> activate/deactivate hooks

Similarly via spapr_irq_post_load().

I'm hoping to add one at CAS time to avoid the CAS reboot, too.

-- 
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] 83+ messages in thread

* Re: [PATCH v2 24/33] spapr, xics, xive: Move set_irq from SpaprIrq to SpaprInterruptController
  2019-09-30  7:22       ` Greg Kurz
@ 2019-09-30  8:28         ` David Gibson
  0 siblings, 0 replies; 83+ messages in thread
From: David Gibson @ 2019-09-30  8:28 UTC (permalink / raw)
  To: Greg Kurz
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

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

On Mon, Sep 30, 2019 at 09:22:16AM +0200, Greg Kurz wrote:
> On Mon, 30 Sep 2019 12:41:39 +1000
> David Gibson <david@gibson.dropbear.id.au> wrote:
> 
> > On Fri, Sep 27, 2019 at 04:27:12PM +0200, Greg Kurz wrote:
> > > On Fri, 27 Sep 2019 15:50:19 +1000
> > > David Gibson <david@gibson.dropbear.id.au> wrote:
> > > 
> > > > This method depends only on the active irq controller.  Now that we've
> > > > formalized the notion of active controller we can dispatch directly through
> > > > that, rather than dispatching via SpaprIrq with the dual version having
> > > > to do a second conditional dispatch.
> > > > 
> > > > Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> > > > ---
> > > >  hw/intc/spapr_xive.c       | 12 +++++++++++
> > > >  hw/intc/xics_spapr.c       |  9 +++++++++
> > > >  hw/ppc/spapr_irq.c         | 41 ++++++++++----------------------------
> > > >  include/hw/ppc/spapr_irq.h |  4 +++-
> > > >  4 files changed, 34 insertions(+), 32 deletions(-)
> > > > 
> > > > diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
> > > > index ff1a175b44..52d5e71793 100644
> > > > --- a/hw/intc/spapr_xive.c
> > > > +++ b/hw/intc/spapr_xive.c
> > > > @@ -553,6 +553,17 @@ static int spapr_xive_cpu_intc_create(SpaprInterruptController *intc,
> > > >      return 0;
> > > >  }
> > > >  
> > > > +static void spapr_xive_set_irq(SpaprInterruptController *intc, int irq, int val)
> > > > +{
> > > > +    SpaprXive *xive = SPAPR_XIVE(intc);
> > > > +
> > > > +    if (kvm_irqchip_in_kernel()) {
> > > > +        kvmppc_xive_source_set_irq(&xive->source, irq, val);
> > > > +    } else {
> > > > +        xive_source_set_irq(&xive->source, irq, val);
> > > > +    }
> > > > +}
> > > > +
> > > >  static void spapr_xive_class_init(ObjectClass *klass, void *data)
> > > >  {
> > > >      DeviceClass *dc = DEVICE_CLASS(klass);
> > > > @@ -574,6 +585,7 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data)
> > > >      sicc->cpu_intc_create = spapr_xive_cpu_intc_create;
> > > >      sicc->claim_irq = spapr_xive_claim_irq;
> > > >      sicc->free_irq = spapr_xive_free_irq;
> > > > +    sicc->set_irq = spapr_xive_set_irq;
> > > >  }
> > > >  
> > > >  static const TypeInfo spapr_xive_info = {
> > > > diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
> > > > index 224fe1efcd..02372697f6 100644
> > > > --- a/hw/intc/xics_spapr.c
> > > > +++ b/hw/intc/xics_spapr.c
> > > > @@ -373,6 +373,14 @@ static void xics_spapr_free_irq(SpaprInterruptController *intc, int irq)
> > > >      memset(&ics->irqs[srcno], 0, sizeof(ICSIRQState));
> > > >  }
> > > >  
> > > > +static void xics_spapr_set_irq(SpaprInterruptController *intc, int irq, int val)
> > > > +{
> > > > +    ICSState *ics = ICS_SPAPR(intc);
> > > > +    uint32_t srcno = irq - ics->offset;
> > > > +
> > > > +    ics_set_irq(ics, srcno, val);
> > > 
> > > And we have:
> > > 
> > > void ics_set_irq(void *opaque, int srcno, int val)
> > > {
> > >     ICSState *ics = (ICSState *)opaque;
> > > 
> > >     if (kvm_irqchip_in_kernel()) {
> > >         ics_kvm_set_irq(ics, srcno, val);
> > >         return;
> > >     }
> > > 
> > >     if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI) {
> > >         ics_set_irq_lsi(ics, srcno, val);
> > >     } else {
> > >         ics_set_irq_msi(ics, srcno, val);
> > >     }
> > > }
> > > 
> > > The kvm_irqchip_in_kernel() block would fit better in xics_spapr_set_irq(),
> > > like it is already the case for XIVE.
> > 
> > Hmm.. I don't really see why you say that.
> > 
> 
> I mean this:
> 
> static void xics_spapr_set_irq(SpaprInterruptController *intc, int irq, int val)
> {
>     IcsSpapr *icss = ICS_SPAPR(intc);
>     ICSState *ics = &icss->parent;
>     uint32_t srcno = irq - ics->offset;
> 
>     if (kvm_irqchip_in_kernel()) {
>         ics_kvm_set_irq(ics, srcno, val);
>     } else {
>         ics_set_irq(ics, srcno, val);
>     }
> }
> 
> It is very similar to spapr_xive_set_irq() and looks nicer to me.

Eh.. I don't really agree.  Seems to me KVM is essentialy an
implementation detail, so belongs in the ICS proper rather than the
papr specific wrapper.

It's not really obvious where it belongs, because the KVM
implementation only works for the PAPR version of the thing, but the
way we call it doesn't explicitly depend on any PAPR specific
information.

-- 
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] 83+ messages in thread

* Re: [PATCH v2 21/33] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController
  2019-09-30  6:14         ` David Gibson
@ 2019-09-30 10:13           ` Cédric Le Goater
  2019-10-01  2:31             ` David Gibson
  0 siblings, 1 reply; 83+ messages in thread
From: Cédric Le Goater @ 2019-09-30 10:13 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, Greg Kurz, qemu-devel, qemu-ppc,
	Marc-André Lureau, Paolo Bonzini, philmd, Laurent Vivier

On 30/09/2019 08:14, David Gibson wrote:
> On Mon, Sep 30, 2019 at 07:28:45AM +0200, Cédric Le Goater wrote:
>> On 30/09/2019 03:49, David Gibson wrote:
>>> On Fri, Sep 27, 2019 at 12:16:49PM +0200, Greg Kurz wrote:
>>>> On Fri, 27 Sep 2019 15:50:16 +1000
>>>> David Gibson <david@gibson.dropbear.id.au> wrote:
>>>>
>>>>> This method essentially represents code which belongs to the interrupt
>>>>> controller, but needs to be called on all possible intcs, rather than
>>>>> just the currently active one.  The "dual" version therefore calls
>>>>> into the xics and xive versions confusingly.
>>>>>
>>>>> Handle this more directly, by making it instead a method on the intc
>>>>> backend, and always calling it on every backend that exists.
>>>>>
>>>>> While we're there, streamline the error reporting a bit.
>>>>>
>>>>> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
>>> [snip]
>>>>> @@ -525,6 +469,30 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
>>>>>  /*
>>>>>   * sPAPR IRQ frontend routines for devices
>>>>>   */
>>>>> +int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
>>>>> +                              PowerPCCPU *cpu, Error **errp)
>>>>> +{
>>>>> +    if (spapr->xive) {
>>>>> +        SpaprInterruptController *intc = SPAPR_INTC(spapr->xive);
>>>>> +        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
>>>>> +
>>>>> +        if (sicc->cpu_intc_create(intc, cpu, errp) < 0) {
>>>>> +            return -1;
>>>>> +        }
>>>>> +    }
>>>>> +
>>>>> +    if (spapr->ics) {
>>>>> +        SpaprInterruptController *intc = SPAPR_INTC(spapr->ics);
>>>>> +        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
>>>>> +
>>>>> +        if (sicc->cpu_intc_create(intc, cpu, errp) < 0) {
>>>>> +            return -1;
>>>>> +        }
>>>>> +    }
>>>>> +
>>>>
>>>> Instead of these hooks, what about open-coding spapr_xive_cpu_intc_create()
>>>> and xics_spapr_cpu_intc_create() directly here, like you already did for the
>>>> ICS and the XIVE objects in spapr_irq_init() ?
>>>
>>> I'd prefer not to.  The idea is I want to treat this as basically:
>>>
>>> 	foreach_possible_intc(intc)
>>> 		intc::cpu_intc_create(...)
>>>
>>> If I find time I might indeed replace the explicit ics and xive
>>> pointers with just an array of SpaprInterruptController *.
>>
>> Or you could use object_child_foreach() and check for the type. If we had
>> a helper object_child_foreach_type(), we could use it elsewhere.
> 
> I thought about that, but I don't think it quite works.  The
> complication is that the xics device is made explicitly a child of the
> machine, but the xive device has mmio, so it's a SusBusDevice sitting
> on the root bus instead.

PnvXscom works fine with Devices and SysBusDevices.

C. 



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

* Re: [PATCH v2 29/33] spapr, xics, xive: Move SpaprIrq::reset hook logic into activate/deactivate
  2019-09-30  8:25     ` David Gibson
@ 2019-09-30 19:29       ` Cédric Le Goater
  2019-10-01  3:07         ` David Gibson
  0 siblings, 1 reply; 83+ messages in thread
From: Cédric Le Goater @ 2019-09-30 19:29 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, groug, qemu-devel, qemu-ppc,
	Marc-André Lureau, Paolo Bonzini, philmd, Laurent Vivier

On 30/09/2019 10:25, David Gibson wrote:
> On Mon, Sep 30, 2019 at 08:11:56AM +0200, Cédric Le Goater wrote:
>> On 27/09/2019 07:50, David Gibson wrote:
>>> It turns out that all the logic in the SpaprIrq::reset hooks (and some in
>>> the SpaprIrq::post_load hooks) isn't really related to resetting the irq
>>> backend (that's handled by the backends' own reset routines).  Rather its
>>> about getting the backend ready to be the active interrupt controller or
>>> stopping being the active interrupt controller - reset (and post_load) is
>>> just the only time that changes at present.
>>
>> This is a 'critical' part which impacts all the migration cases: 
>>
>> ic-mode=xics,xive,dual + kernel_irqchip=on/off + TCG
> 
> Yes... and?

and it's fragile.  

>>> To make this flow clearer, move the logic into the explicit backend
>>> activate and deactivate hooks.
>>
>> I don't see where the hooks are called ?
> 
> spapr_irq_reset()
>   -> spapr_irq_update_active_intc()
>     -> set_active_intc()
>       -> activate/deactivate hooks
> 
> Similarly via spapr_irq_post_load().
> 
> I'm hoping to add one at CAS time to avoid the CAS reboot, too.

OK. I think the first 22 patches are ready, just some minor comments
if I am correct. Could you merge them ?

C.




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

* Re: [PATCH v2 21/33] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController
  2019-09-30 10:13           ` Cédric Le Goater
@ 2019-10-01  2:31             ` David Gibson
  2019-10-01  5:43               ` Cédric Le Goater
  0 siblings, 1 reply; 83+ messages in thread
From: David Gibson @ 2019-10-01  2:31 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Jason Wang, Riku Voipio, Greg Kurz, qemu-devel, qemu-ppc,
	Marc-André Lureau, Paolo Bonzini, philmd, Laurent Vivier

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

On Mon, Sep 30, 2019 at 12:13:14PM +0200, Cédric Le Goater wrote:
> On 30/09/2019 08:14, David Gibson wrote:
> > On Mon, Sep 30, 2019 at 07:28:45AM +0200, Cédric Le Goater wrote:
> >> On 30/09/2019 03:49, David Gibson wrote:
> >>> On Fri, Sep 27, 2019 at 12:16:49PM +0200, Greg Kurz wrote:
> >>>> On Fri, 27 Sep 2019 15:50:16 +1000
> >>>> David Gibson <david@gibson.dropbear.id.au> wrote:
> >>>>
> >>>>> This method essentially represents code which belongs to the interrupt
> >>>>> controller, but needs to be called on all possible intcs, rather than
> >>>>> just the currently active one.  The "dual" version therefore calls
> >>>>> into the xics and xive versions confusingly.
> >>>>>
> >>>>> Handle this more directly, by making it instead a method on the intc
> >>>>> backend, and always calling it on every backend that exists.
> >>>>>
> >>>>> While we're there, streamline the error reporting a bit.
> >>>>>
> >>>>> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> >>> [snip]
> >>>>> @@ -525,6 +469,30 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
> >>>>>  /*
> >>>>>   * sPAPR IRQ frontend routines for devices
> >>>>>   */
> >>>>> +int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
> >>>>> +                              PowerPCCPU *cpu, Error **errp)
> >>>>> +{
> >>>>> +    if (spapr->xive) {
> >>>>> +        SpaprInterruptController *intc = SPAPR_INTC(spapr->xive);
> >>>>> +        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
> >>>>> +
> >>>>> +        if (sicc->cpu_intc_create(intc, cpu, errp) < 0) {
> >>>>> +            return -1;
> >>>>> +        }
> >>>>> +    }
> >>>>> +
> >>>>> +    if (spapr->ics) {
> >>>>> +        SpaprInterruptController *intc = SPAPR_INTC(spapr->ics);
> >>>>> +        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
> >>>>> +
> >>>>> +        if (sicc->cpu_intc_create(intc, cpu, errp) < 0) {
> >>>>> +            return -1;
> >>>>> +        }
> >>>>> +    }
> >>>>> +
> >>>>
> >>>> Instead of these hooks, what about open-coding spapr_xive_cpu_intc_create()
> >>>> and xics_spapr_cpu_intc_create() directly here, like you already did for the
> >>>> ICS and the XIVE objects in spapr_irq_init() ?
> >>>
> >>> I'd prefer not to.  The idea is I want to treat this as basically:
> >>>
> >>> 	foreach_possible_intc(intc)
> >>> 		intc::cpu_intc_create(...)
> >>>
> >>> If I find time I might indeed replace the explicit ics and xive
> >>> pointers with just an array of SpaprInterruptController *.
> >>
> >> Or you could use object_child_foreach() and check for the type. If we had
> >> a helper object_child_foreach_type(), we could use it elsewhere.
> > 
> > I thought about that, but I don't think it quite works.  The
> > complication is that the xics device is made explicitly a child of the
> > machine, but the xive device has mmio, so it's a SusBusDevice sitting
> > on the root bus instead.
> 
> PnvXscom works fine with Devices and SysBusDevices.

Uh... what's an example of it working with a SysBusDevice?  All the
implementors of PNV_XSCOM_INTERFACE I could find were instantiated
with object_initialize_child() making them explicitly children of the
chip.  The SPAPR_XIVE is instantiated with qdev_create(NULL,
TYPE_SPAPR_XIVE), making it a child of the root bus, not the machine,
I believe.

-- 
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] 83+ messages in thread

* Re: [PATCH v2 29/33] spapr, xics, xive: Move SpaprIrq::reset hook logic into activate/deactivate
  2019-09-30 19:29       ` Cédric Le Goater
@ 2019-10-01  3:07         ` David Gibson
  0 siblings, 0 replies; 83+ messages in thread
From: David Gibson @ 2019-10-01  3:07 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Jason Wang, Riku Voipio, groug, qemu-devel, qemu-ppc,
	Marc-André Lureau, Paolo Bonzini, philmd, Laurent Vivier

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

On Mon, Sep 30, 2019 at 09:29:14PM +0200, Cédric Le Goater wrote:
> On 30/09/2019 10:25, David Gibson wrote:
> > On Mon, Sep 30, 2019 at 08:11:56AM +0200, Cédric Le Goater wrote:
> >> On 27/09/2019 07:50, David Gibson wrote:
> >>> It turns out that all the logic in the SpaprIrq::reset hooks (and some in
> >>> the SpaprIrq::post_load hooks) isn't really related to resetting the irq
> >>> backend (that's handled by the backends' own reset routines).  Rather its
> >>> about getting the backend ready to be the active interrupt controller or
> >>> stopping being the active interrupt controller - reset (and post_load) is
> >>> just the only time that changes at present.
> >>
> >> This is a 'critical' part which impacts all the migration cases: 
> >>
> >> ic-mode=xics,xive,dual + kernel_irqchip=on/off + TCG
> > 
> > Yes... and?
> 
> and it's fragile.

How so?  Explicitly having logic for when an intc becomes active or
inactive, and having a single callsite which does that and updates the
active controller seems less fragile to me.  At least compared to
having the update to the active controller (implicit in changing the
CAS vector) and the logic to get the controllers ready for being
active/inactive in totally different places and relying on the fact
they both only happen at reset for them to travel together.

> 
> >>> To make this flow clearer, move the logic into the explicit backend
> >>> activate and deactivate hooks.
> >>
> >> I don't see where the hooks are called ?
> > 
> > spapr_irq_reset()
> >   -> spapr_irq_update_active_intc()
> >     -> set_active_intc()
> >       -> activate/deactivate hooks
> > 
> > Similarly via spapr_irq_post_load().
> > 
> > I'm hoping to add one at CAS time to avoid the CAS reboot, too.
> 
> OK. I think the first 22 patches are ready, just some minor comments
> if I am correct. Could you merge them ?

I might repost first, because one of the changes Greg suggested to
error handling caused a larger than expected number of ripple on
fixes.

-- 
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] 83+ messages in thread

* Re: [PATCH v2 21/33] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController
  2019-10-01  2:31             ` David Gibson
@ 2019-10-01  5:43               ` Cédric Le Goater
  2019-10-01  6:47                 ` David Gibson
  0 siblings, 1 reply; 83+ messages in thread
From: Cédric Le Goater @ 2019-10-01  5:43 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, Greg Kurz, qemu-devel, qemu-ppc,
	Marc-André Lureau, Paolo Bonzini, philmd, Laurent Vivier

On 01/10/2019 04:31, David Gibson wrote:
> On Mon, Sep 30, 2019 at 12:13:14PM +0200, Cédric Le Goater wrote:
>> On 30/09/2019 08:14, David Gibson wrote:
>>> On Mon, Sep 30, 2019 at 07:28:45AM +0200, Cédric Le Goater wrote:
>>>> On 30/09/2019 03:49, David Gibson wrote:
>>>>> On Fri, Sep 27, 2019 at 12:16:49PM +0200, Greg Kurz wrote:
>>>>>> On Fri, 27 Sep 2019 15:50:16 +1000
>>>>>> David Gibson <david@gibson.dropbear.id.au> wrote:
>>>>>>
>>>>>>> This method essentially represents code which belongs to the interrupt
>>>>>>> controller, but needs to be called on all possible intcs, rather than
>>>>>>> just the currently active one.  The "dual" version therefore calls
>>>>>>> into the xics and xive versions confusingly.
>>>>>>>
>>>>>>> Handle this more directly, by making it instead a method on the intc
>>>>>>> backend, and always calling it on every backend that exists.
>>>>>>>
>>>>>>> While we're there, streamline the error reporting a bit.
>>>>>>>
>>>>>>> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
>>>>> [snip]
>>>>>>> @@ -525,6 +469,30 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
>>>>>>>  /*
>>>>>>>   * sPAPR IRQ frontend routines for devices
>>>>>>>   */
>>>>>>> +int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
>>>>>>> +                              PowerPCCPU *cpu, Error **errp)
>>>>>>> +{
>>>>>>> +    if (spapr->xive) {
>>>>>>> +        SpaprInterruptController *intc = SPAPR_INTC(spapr->xive);
>>>>>>> +        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
>>>>>>> +
>>>>>>> +        if (sicc->cpu_intc_create(intc, cpu, errp) < 0) {
>>>>>>> +            return -1;
>>>>>>> +        }
>>>>>>> +    }
>>>>>>> +
>>>>>>> +    if (spapr->ics) {
>>>>>>> +        SpaprInterruptController *intc = SPAPR_INTC(spapr->ics);
>>>>>>> +        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
>>>>>>> +
>>>>>>> +        if (sicc->cpu_intc_create(intc, cpu, errp) < 0) {
>>>>>>> +            return -1;
>>>>>>> +        }
>>>>>>> +    }
>>>>>>> +
>>>>>>
>>>>>> Instead of these hooks, what about open-coding spapr_xive_cpu_intc_create()
>>>>>> and xics_spapr_cpu_intc_create() directly here, like you already did for the
>>>>>> ICS and the XIVE objects in spapr_irq_init() ?
>>>>>
>>>>> I'd prefer not to.  The idea is I want to treat this as basically:
>>>>>
>>>>> 	foreach_possible_intc(intc)
>>>>> 		intc::cpu_intc_create(...)
>>>>>
>>>>> If I find time I might indeed replace the explicit ics and xive
>>>>> pointers with just an array of SpaprInterruptController *.
>>>>
>>>> Or you could use object_child_foreach() and check for the type. If we had
>>>> a helper object_child_foreach_type(), we could use it elsewhere.
>>>
>>> I thought about that, but I don't think it quite works.  The
>>> complication is that the xics device is made explicitly a child of the
>>> machine, but the xive device has mmio, so it's a SusBusDevice sitting
>>> on the root bus instead.
>>
>> PnvXscom works fine with Devices and SysBusDevices.
> 
> Uh... what's an example of it working with a SysBusDevice?  All the
> implementors of PNV_XSCOM_INTERFACE I could find were instantiated
> with object_initialize_child() making them explicitly children of the
> chip.  The SPAPR_XIVE is instantiated with qdev_create(NULL,
> TYPE_SPAPR_XIVE), making it a child of the root bus, not the machine,
> I believe.

I see. We should reparent the interrupt controller then, Could we rework 
the code to instantiate and realize the XICS and XIVE model objects ? 
We have the handlers spapr_instance_init() and spapr_machine_init(). 

That always has been a problem IMO.


C. 
 




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

* Re: [PATCH v2 21/33] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController
  2019-10-01  5:43               ` Cédric Le Goater
@ 2019-10-01  6:47                 ` David Gibson
  2019-10-01  7:41                   ` Cédric Le Goater
  0 siblings, 1 reply; 83+ messages in thread
From: David Gibson @ 2019-10-01  6:47 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Jason Wang, Riku Voipio, Greg Kurz, qemu-devel, qemu-ppc,
	Marc-André Lureau, Paolo Bonzini, philmd, Laurent Vivier

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

On Tue, Oct 01, 2019 at 07:43:51AM +0200, Cédric Le Goater wrote:
> On 01/10/2019 04:31, David Gibson wrote:
> > On Mon, Sep 30, 2019 at 12:13:14PM +0200, Cédric Le Goater wrote:
> >> On 30/09/2019 08:14, David Gibson wrote:
> >>> On Mon, Sep 30, 2019 at 07:28:45AM +0200, Cédric Le Goater wrote:
> >>>> On 30/09/2019 03:49, David Gibson wrote:
> >>>>> On Fri, Sep 27, 2019 at 12:16:49PM +0200, Greg Kurz wrote:
> >>>>>> On Fri, 27 Sep 2019 15:50:16 +1000
> >>>>>> David Gibson <david@gibson.dropbear.id.au> wrote:
> >>>>>>
> >>>>>>> This method essentially represents code which belongs to the interrupt
> >>>>>>> controller, but needs to be called on all possible intcs, rather than
> >>>>>>> just the currently active one.  The "dual" version therefore calls
> >>>>>>> into the xics and xive versions confusingly.
> >>>>>>>
> >>>>>>> Handle this more directly, by making it instead a method on the intc
> >>>>>>> backend, and always calling it on every backend that exists.
> >>>>>>>
> >>>>>>> While we're there, streamline the error reporting a bit.
> >>>>>>>
> >>>>>>> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> >>>>> [snip]
> >>>>>>> @@ -525,6 +469,30 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
> >>>>>>>  /*
> >>>>>>>   * sPAPR IRQ frontend routines for devices
> >>>>>>>   */
> >>>>>>> +int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
> >>>>>>> +                              PowerPCCPU *cpu, Error **errp)
> >>>>>>> +{
> >>>>>>> +    if (spapr->xive) {
> >>>>>>> +        SpaprInterruptController *intc = SPAPR_INTC(spapr->xive);
> >>>>>>> +        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
> >>>>>>> +
> >>>>>>> +        if (sicc->cpu_intc_create(intc, cpu, errp) < 0) {
> >>>>>>> +            return -1;
> >>>>>>> +        }
> >>>>>>> +    }
> >>>>>>> +
> >>>>>>> +    if (spapr->ics) {
> >>>>>>> +        SpaprInterruptController *intc = SPAPR_INTC(spapr->ics);
> >>>>>>> +        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
> >>>>>>> +
> >>>>>>> +        if (sicc->cpu_intc_create(intc, cpu, errp) < 0) {
> >>>>>>> +            return -1;
> >>>>>>> +        }
> >>>>>>> +    }
> >>>>>>> +
> >>>>>>
> >>>>>> Instead of these hooks, what about open-coding spapr_xive_cpu_intc_create()
> >>>>>> and xics_spapr_cpu_intc_create() directly here, like you already did for the
> >>>>>> ICS and the XIVE objects in spapr_irq_init() ?
> >>>>>
> >>>>> I'd prefer not to.  The idea is I want to treat this as basically:
> >>>>>
> >>>>> 	foreach_possible_intc(intc)
> >>>>> 		intc::cpu_intc_create(...)
> >>>>>
> >>>>> If I find time I might indeed replace the explicit ics and xive
> >>>>> pointers with just an array of SpaprInterruptController *.
> >>>>
> >>>> Or you could use object_child_foreach() and check for the type. If we had
> >>>> a helper object_child_foreach_type(), we could use it elsewhere.
> >>>
> >>> I thought about that, but I don't think it quite works.  The
> >>> complication is that the xics device is made explicitly a child of the
> >>> machine, but the xive device has mmio, so it's a SusBusDevice sitting
> >>> on the root bus instead.
> >>
> >> PnvXscom works fine with Devices and SysBusDevices.
> > 
> > Uh... what's an example of it working with a SysBusDevice?  All the
> > implementors of PNV_XSCOM_INTERFACE I could find were instantiated
> > with object_initialize_child() making them explicitly children of the
> > chip.  The SPAPR_XIVE is instantiated with qdev_create(NULL,
> > TYPE_SPAPR_XIVE), making it a child of the root bus, not the machine,
> > I believe.
> 
> I see. We should reparent the interrupt controller then.

Well, maybe.  It's not obvious to me that that's the right approach
just because of this.


> Could we rework 
> the code to instantiate and realize the XICS and XIVE model objects ? 
> We have the handlers spapr_instance_init() and spapr_machine_init(). 

I'm not really sure what you're suggesting here.

> That always has been a problem IMO.
> 
> 
> C. 
>  
> 
> 

-- 
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] 83+ messages in thread

* Re: [PATCH v2 21/33] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController
  2019-10-01  6:47                 ` David Gibson
@ 2019-10-01  7:41                   ` Cédric Le Goater
  2019-10-01  8:11                     ` David Gibson
  0 siblings, 1 reply; 83+ messages in thread
From: Cédric Le Goater @ 2019-10-01  7:41 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, Greg Kurz, qemu-devel, qemu-ppc,
	Marc-André Lureau, Paolo Bonzini, philmd, Laurent Vivier

On 01/10/2019 08:47, David Gibson wrote:
> On Tue, Oct 01, 2019 at 07:43:51AM +0200, Cédric Le Goater wrote:
>> On 01/10/2019 04:31, David Gibson wrote:
>>> On Mon, Sep 30, 2019 at 12:13:14PM +0200, Cédric Le Goater wrote:
>>>> On 30/09/2019 08:14, David Gibson wrote:
>>>>> On Mon, Sep 30, 2019 at 07:28:45AM +0200, Cédric Le Goater wrote:
>>>>>> On 30/09/2019 03:49, David Gibson wrote:
>>>>>>> On Fri, Sep 27, 2019 at 12:16:49PM +0200, Greg Kurz wrote:
>>>>>>>> On Fri, 27 Sep 2019 15:50:16 +1000
>>>>>>>> David Gibson <david@gibson.dropbear.id.au> wrote:
>>>>>>>>
>>>>>>>>> This method essentially represents code which belongs to the interrupt
>>>>>>>>> controller, but needs to be called on all possible intcs, rather than
>>>>>>>>> just the currently active one.  The "dual" version therefore calls
>>>>>>>>> into the xics and xive versions confusingly.
>>>>>>>>>
>>>>>>>>> Handle this more directly, by making it instead a method on the intc
>>>>>>>>> backend, and always calling it on every backend that exists.
>>>>>>>>>
>>>>>>>>> While we're there, streamline the error reporting a bit.
>>>>>>>>>
>>>>>>>>> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
>>>>>>> [snip]
>>>>>>>>> @@ -525,6 +469,30 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
>>>>>>>>>  /*
>>>>>>>>>   * sPAPR IRQ frontend routines for devices
>>>>>>>>>   */
>>>>>>>>> +int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
>>>>>>>>> +                              PowerPCCPU *cpu, Error **errp)
>>>>>>>>> +{
>>>>>>>>> +    if (spapr->xive) {
>>>>>>>>> +        SpaprInterruptController *intc = SPAPR_INTC(spapr->xive);
>>>>>>>>> +        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
>>>>>>>>> +
>>>>>>>>> +        if (sicc->cpu_intc_create(intc, cpu, errp) < 0) {
>>>>>>>>> +            return -1;
>>>>>>>>> +        }
>>>>>>>>> +    }
>>>>>>>>> +
>>>>>>>>> +    if (spapr->ics) {
>>>>>>>>> +        SpaprInterruptController *intc = SPAPR_INTC(spapr->ics);
>>>>>>>>> +        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
>>>>>>>>> +
>>>>>>>>> +        if (sicc->cpu_intc_create(intc, cpu, errp) < 0) {
>>>>>>>>> +            return -1;
>>>>>>>>> +        }
>>>>>>>>> +    }
>>>>>>>>> +
>>>>>>>>
>>>>>>>> Instead of these hooks, what about open-coding spapr_xive_cpu_intc_create()
>>>>>>>> and xics_spapr_cpu_intc_create() directly here, like you already did for the
>>>>>>>> ICS and the XIVE objects in spapr_irq_init() ?
>>>>>>>
>>>>>>> I'd prefer not to.  The idea is I want to treat this as basically:
>>>>>>>
>>>>>>> 	foreach_possible_intc(intc)
>>>>>>> 		intc::cpu_intc_create(...)
>>>>>>>
>>>>>>> If I find time I might indeed replace the explicit ics and xive
>>>>>>> pointers with just an array of SpaprInterruptController *.
>>>>>>
>>>>>> Or you could use object_child_foreach() and check for the type. If we had
>>>>>> a helper object_child_foreach_type(), we could use it elsewhere.
>>>>>
>>>>> I thought about that, but I don't think it quite works.  The
>>>>> complication is that the xics device is made explicitly a child of the
>>>>> machine, but the xive device has mmio, so it's a SusBusDevice sitting
>>>>> on the root bus instead.
>>>>
>>>> PnvXscom works fine with Devices and SysBusDevices.
>>>
>>> Uh... what's an example of it working with a SysBusDevice?  All the
>>> implementors of PNV_XSCOM_INTERFACE I could find were instantiated
>>> with object_initialize_child() making them explicitly children of the
>>> chip.  The SPAPR_XIVE is instantiated with qdev_create(NULL,
>>> TYPE_SPAPR_XIVE), making it a child of the root bus, not the machine,
>>> I believe.
>>
>> I see. We should reparent the interrupt controller then.
> 
> Well, maybe.  It's not obvious to me that that's the right approach
> just because of this.
> 
> 
>> Could we rework 
>> the code to instantiate and realize the XICS and XIVE model objects ? 
>> We have the handlers spapr_instance_init() and spapr_machine_init(). 
> 
> I'm not really sure what you're suggesting here.

Define the device model objects under the machine and not pointers :

	struct SpaprMachineState {
		...
		ICSState ics;
		SpaprXive  xive;
		...
	};

in spapr_instance_init() :

	object_initialize_child(obj, "ics",  &spapr->ics, sizeof(spapr->ics),
                            TYPE_ICS, &error_abort, NULL);
	object_property_add_const_link(OBJECT(&spapr->ics), "xics", obj,
                                   &error_abort);

	object_initialize_child(obj, "xive",  &spapr->xive, sizeof(spapr->xive),
                            TYPE_SPAPR_XIVE, &error_abort, NULL);


in spapr_machine_init(), call the realize handler depending on the chosen 
'ic-mode'. 


C.


>> That always has been a problem IMO.
>>
>>
>> C. 
>>  
>>
>>
> 



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

* Re: [PATCH v2 21/33] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController
  2019-10-01  7:41                   ` Cédric Le Goater
@ 2019-10-01  8:11                     ` David Gibson
  2019-10-01 11:43                       ` Cédric Le Goater
  0 siblings, 1 reply; 83+ messages in thread
From: David Gibson @ 2019-10-01  8:11 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Jason Wang, Riku Voipio, Greg Kurz, qemu-devel, qemu-ppc,
	Marc-André Lureau, Paolo Bonzini, philmd, Laurent Vivier

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

On Tue, Oct 01, 2019 at 09:41:27AM +0200, Cédric Le Goater wrote:
> On 01/10/2019 08:47, David Gibson wrote:
> > On Tue, Oct 01, 2019 at 07:43:51AM +0200, Cédric Le Goater wrote:
> >> On 01/10/2019 04:31, David Gibson wrote:
> >>> On Mon, Sep 30, 2019 at 12:13:14PM +0200, Cédric Le Goater wrote:
> >>>> On 30/09/2019 08:14, David Gibson wrote:
> >>>>> On Mon, Sep 30, 2019 at 07:28:45AM +0200, Cédric Le Goater wrote:
> >>>>>> On 30/09/2019 03:49, David Gibson wrote:
> >>>>>>> On Fri, Sep 27, 2019 at 12:16:49PM +0200, Greg Kurz wrote:
> >>>>>>>> On Fri, 27 Sep 2019 15:50:16 +1000
> >>>>>>>> David Gibson <david@gibson.dropbear.id.au> wrote:
> >>>>>>>>
> >>>>>>>>> This method essentially represents code which belongs to the interrupt
> >>>>>>>>> controller, but needs to be called on all possible intcs, rather than
> >>>>>>>>> just the currently active one.  The "dual" version therefore calls
> >>>>>>>>> into the xics and xive versions confusingly.
> >>>>>>>>>
> >>>>>>>>> Handle this more directly, by making it instead a method on the intc
> >>>>>>>>> backend, and always calling it on every backend that exists.
> >>>>>>>>>
> >>>>>>>>> While we're there, streamline the error reporting a bit.
> >>>>>>>>>
> >>>>>>>>> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> >>>>>>> [snip]
> >>>>>>>>> @@ -525,6 +469,30 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
> >>>>>>>>>  /*
> >>>>>>>>>   * sPAPR IRQ frontend routines for devices
> >>>>>>>>>   */
> >>>>>>>>> +int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
> >>>>>>>>> +                              PowerPCCPU *cpu, Error **errp)
> >>>>>>>>> +{
> >>>>>>>>> +    if (spapr->xive) {
> >>>>>>>>> +        SpaprInterruptController *intc = SPAPR_INTC(spapr->xive);
> >>>>>>>>> +        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
> >>>>>>>>> +
> >>>>>>>>> +        if (sicc->cpu_intc_create(intc, cpu, errp) < 0) {
> >>>>>>>>> +            return -1;
> >>>>>>>>> +        }
> >>>>>>>>> +    }
> >>>>>>>>> +
> >>>>>>>>> +    if (spapr->ics) {
> >>>>>>>>> +        SpaprInterruptController *intc = SPAPR_INTC(spapr->ics);
> >>>>>>>>> +        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
> >>>>>>>>> +
> >>>>>>>>> +        if (sicc->cpu_intc_create(intc, cpu, errp) < 0) {
> >>>>>>>>> +            return -1;
> >>>>>>>>> +        }
> >>>>>>>>> +    }
> >>>>>>>>> +
> >>>>>>>>
> >>>>>>>> Instead of these hooks, what about open-coding spapr_xive_cpu_intc_create()
> >>>>>>>> and xics_spapr_cpu_intc_create() directly here, like you already did for the
> >>>>>>>> ICS and the XIVE objects in spapr_irq_init() ?
> >>>>>>>
> >>>>>>> I'd prefer not to.  The idea is I want to treat this as basically:
> >>>>>>>
> >>>>>>> 	foreach_possible_intc(intc)
> >>>>>>> 		intc::cpu_intc_create(...)
> >>>>>>>
> >>>>>>> If I find time I might indeed replace the explicit ics and xive
> >>>>>>> pointers with just an array of SpaprInterruptController *.
> >>>>>>
> >>>>>> Or you could use object_child_foreach() and check for the type. If we had
> >>>>>> a helper object_child_foreach_type(), we could use it elsewhere.
> >>>>>
> >>>>> I thought about that, but I don't think it quite works.  The
> >>>>> complication is that the xics device is made explicitly a child of the
> >>>>> machine, but the xive device has mmio, so it's a SusBusDevice sitting
> >>>>> on the root bus instead.
> >>>>
> >>>> PnvXscom works fine with Devices and SysBusDevices.
> >>>
> >>> Uh... what's an example of it working with a SysBusDevice?  All the
> >>> implementors of PNV_XSCOM_INTERFACE I could find were instantiated
> >>> with object_initialize_child() making them explicitly children of the
> >>> chip.  The SPAPR_XIVE is instantiated with qdev_create(NULL,
> >>> TYPE_SPAPR_XIVE), making it a child of the root bus, not the machine,
> >>> I believe.
> >>
> >> I see. We should reparent the interrupt controller then.
> > 
> > Well, maybe.  It's not obvious to me that that's the right approach
> > just because of this.
> > 
> > 
> >> Could we rework 
> >> the code to instantiate and realize the XICS and XIVE model objects ? 
> >> We have the handlers spapr_instance_init() and spapr_machine_init(). 
> > 
> > I'm not really sure what you're suggesting here.
> 
> Define the device model objects under the machine and not pointers :
> 
> 	struct SpaprMachineState {
> 		...
> 		ICSState ics;
> 		SpaprXive  xive;
> 		...
> 	};
> 
> in spapr_instance_init() :
> 
> 	object_initialize_child(obj, "ics",  &spapr->ics, sizeof(spapr->ics),
>                             TYPE_ICS, &error_abort, NULL);
> 	object_property_add_const_link(OBJECT(&spapr->ics), "xics", obj,
>                                    &error_abort);
> 
> 	object_initialize_child(obj, "xive",  &spapr->xive, sizeof(spapr->xive),
>                             TYPE_SPAPR_XIVE, &error_abort, NULL);
> 
> 
> in spapr_machine_init(), call the realize handler depending on the chosen 
> 'ic-mode'.

Hm, yeah, maybe.  I don't love having a whole structure in there
that's unused when ic-mode != dual.

-- 
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] 83+ messages in thread

* Re: [PATCH v2 21/33] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController
  2019-10-01  8:11                     ` David Gibson
@ 2019-10-01 11:43                       ` Cédric Le Goater
  2019-10-02  1:11                         ` David Gibson
  0 siblings, 1 reply; 83+ messages in thread
From: Cédric Le Goater @ 2019-10-01 11:43 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, Greg Kurz, qemu-devel, qemu-ppc,
	Marc-André Lureau, Paolo Bonzini, philmd, Laurent Vivier

On 01/10/2019 10:11, David Gibson wrote:
> On Tue, Oct 01, 2019 at 09:41:27AM +0200, Cédric Le Goater wrote:
>> On 01/10/2019 08:47, David Gibson wrote:
>>> On Tue, Oct 01, 2019 at 07:43:51AM +0200, Cédric Le Goater wrote:
>>>> On 01/10/2019 04:31, David Gibson wrote:
>>>>> On Mon, Sep 30, 2019 at 12:13:14PM +0200, Cédric Le Goater wrote:
>>>>>> On 30/09/2019 08:14, David Gibson wrote:
>>>>>>> On Mon, Sep 30, 2019 at 07:28:45AM +0200, Cédric Le Goater wrote:
>>>>>>>> On 30/09/2019 03:49, David Gibson wrote:
>>>>>>>>> On Fri, Sep 27, 2019 at 12:16:49PM +0200, Greg Kurz wrote:
>>>>>>>>>> On Fri, 27 Sep 2019 15:50:16 +1000
>>>>>>>>>> David Gibson <david@gibson.dropbear.id.au> wrote:
>>>>>>>>>>
>>>>>>>>>>> This method essentially represents code which belongs to the interrupt
>>>>>>>>>>> controller, but needs to be called on all possible intcs, rather than
>>>>>>>>>>> just the currently active one.  The "dual" version therefore calls
>>>>>>>>>>> into the xics and xive versions confusingly.
>>>>>>>>>>>
>>>>>>>>>>> Handle this more directly, by making it instead a method on the intc
>>>>>>>>>>> backend, and always calling it on every backend that exists.
>>>>>>>>>>>
>>>>>>>>>>> While we're there, streamline the error reporting a bit.
>>>>>>>>>>>
>>>>>>>>>>> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
>>>>>>>>> [snip]
>>>>>>>>>>> @@ -525,6 +469,30 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
>>>>>>>>>>>  /*
>>>>>>>>>>>   * sPAPR IRQ frontend routines for devices
>>>>>>>>>>>   */
>>>>>>>>>>> +int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
>>>>>>>>>>> +                              PowerPCCPU *cpu, Error **errp)
>>>>>>>>>>> +{
>>>>>>>>>>> +    if (spapr->xive) {
>>>>>>>>>>> +        SpaprInterruptController *intc = SPAPR_INTC(spapr->xive);
>>>>>>>>>>> +        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
>>>>>>>>>>> +
>>>>>>>>>>> +        if (sicc->cpu_intc_create(intc, cpu, errp) < 0) {
>>>>>>>>>>> +            return -1;
>>>>>>>>>>> +        }
>>>>>>>>>>> +    }
>>>>>>>>>>> +
>>>>>>>>>>> +    if (spapr->ics) {
>>>>>>>>>>> +        SpaprInterruptController *intc = SPAPR_INTC(spapr->ics);
>>>>>>>>>>> +        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
>>>>>>>>>>> +
>>>>>>>>>>> +        if (sicc->cpu_intc_create(intc, cpu, errp) < 0) {
>>>>>>>>>>> +            return -1;
>>>>>>>>>>> +        }
>>>>>>>>>>> +    }
>>>>>>>>>>> +
>>>>>>>>>>
>>>>>>>>>> Instead of these hooks, what about open-coding spapr_xive_cpu_intc_create()
>>>>>>>>>> and xics_spapr_cpu_intc_create() directly here, like you already did for the
>>>>>>>>>> ICS and the XIVE objects in spapr_irq_init() ?
>>>>>>>>>
>>>>>>>>> I'd prefer not to.  The idea is I want to treat this as basically:
>>>>>>>>>
>>>>>>>>> 	foreach_possible_intc(intc)
>>>>>>>>> 		intc::cpu_intc_create(...)
>>>>>>>>>
>>>>>>>>> If I find time I might indeed replace the explicit ics and xive
>>>>>>>>> pointers with just an array of SpaprInterruptController *.
>>>>>>>>
>>>>>>>> Or you could use object_child_foreach() and check for the type. If we had
>>>>>>>> a helper object_child_foreach_type(), we could use it elsewhere.
>>>>>>>
>>>>>>> I thought about that, but I don't think it quite works.  The
>>>>>>> complication is that the xics device is made explicitly a child of the
>>>>>>> machine, but the xive device has mmio, so it's a SusBusDevice sitting
>>>>>>> on the root bus instead.
>>>>>>
>>>>>> PnvXscom works fine with Devices and SysBusDevices.
>>>>>
>>>>> Uh... what's an example of it working with a SysBusDevice?  All the
>>>>> implementors of PNV_XSCOM_INTERFACE I could find were instantiated
>>>>> with object_initialize_child() making them explicitly children of the
>>>>> chip.  The SPAPR_XIVE is instantiated with qdev_create(NULL,
>>>>> TYPE_SPAPR_XIVE), making it a child of the root bus, not the machine,
>>>>> I believe.
>>>>
>>>> I see. We should reparent the interrupt controller then.
>>>
>>> Well, maybe.  It's not obvious to me that that's the right approach
>>> just because of this.
>>>
>>>
>>>> Could we rework 
>>>> the code to instantiate and realize the XICS and XIVE model objects ? 
>>>> We have the handlers spapr_instance_init() and spapr_machine_init(). 
>>>
>>> I'm not really sure what you're suggesting here.
>>
>> Define the device model objects under the machine and not pointers :
>>
>> 	struct SpaprMachineState {
>> 		...
>> 		ICSState ics;
>> 		SpaprXive  xive;
>> 		...
>> 	};
>>
>> in spapr_instance_init() :
>>
>> 	object_initialize_child(obj, "ics",  &spapr->ics, sizeof(spapr->ics),
>>                             TYPE_ICS, &error_abort, NULL);
>> 	object_property_add_const_link(OBJECT(&spapr->ics), "xics", obj,
>>                                    &error_abort);
>>
>> 	object_initialize_child(obj, "xive",  &spapr->xive, sizeof(spapr->xive),
>>                             TYPE_SPAPR_XIVE, &error_abort, NULL);
>>
>>
>> in spapr_machine_init(), call the realize handler depending on the chosen 
>> 'ic-mode'.
> 
> Hm, yeah, maybe.  I don't love having a whole structure in there
> that's unused when ic-mode != dual.
> 

This is the pattern followed in the ARM SoC models. Enough room is 
provisioned for the maximum controllers and depending on the SoC
configuration only some are realized.

C. 
  



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

* Re: [PATCH v2 21/33] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController
  2019-10-01 11:43                       ` Cédric Le Goater
@ 2019-10-02  1:11                         ` David Gibson
  0 siblings, 0 replies; 83+ messages in thread
From: David Gibson @ 2019-10-02  1:11 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Jason Wang, Riku Voipio, Greg Kurz, qemu-devel, qemu-ppc,
	Marc-André Lureau, Paolo Bonzini, philmd, Laurent Vivier

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

On Tue, Oct 01, 2019 at 01:43:12PM +0200, Cédric Le Goater wrote:
> On 01/10/2019 10:11, David Gibson wrote:
> > On Tue, Oct 01, 2019 at 09:41:27AM +0200, Cédric Le Goater wrote:
> >> On 01/10/2019 08:47, David Gibson wrote:
> >>> On Tue, Oct 01, 2019 at 07:43:51AM +0200, Cédric Le Goater wrote:
> >>>> On 01/10/2019 04:31, David Gibson wrote:
> >>>>> On Mon, Sep 30, 2019 at 12:13:14PM +0200, Cédric Le Goater wrote:
> >>>>>> On 30/09/2019 08:14, David Gibson wrote:
> >>>>>>> On Mon, Sep 30, 2019 at 07:28:45AM +0200, Cédric Le Goater wrote:
> >>>>>>>> On 30/09/2019 03:49, David Gibson wrote:
> >>>>>>>>> On Fri, Sep 27, 2019 at 12:16:49PM +0200, Greg Kurz wrote:
> >>>>>>>>>> On Fri, 27 Sep 2019 15:50:16 +1000
> >>>>>>>>>> David Gibson <david@gibson.dropbear.id.au> wrote:
> >>>>>>>>>>
> >>>>>>>>>>> This method essentially represents code which belongs to the interrupt
> >>>>>>>>>>> controller, but needs to be called on all possible intcs, rather than
> >>>>>>>>>>> just the currently active one.  The "dual" version therefore calls
> >>>>>>>>>>> into the xics and xive versions confusingly.
> >>>>>>>>>>>
> >>>>>>>>>>> Handle this more directly, by making it instead a method on the intc
> >>>>>>>>>>> backend, and always calling it on every backend that exists.
> >>>>>>>>>>>
> >>>>>>>>>>> While we're there, streamline the error reporting a bit.
> >>>>>>>>>>>
> >>>>>>>>>>> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> >>>>>>>>> [snip]
> >>>>>>>>>>> @@ -525,6 +469,30 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
> >>>>>>>>>>>  /*
> >>>>>>>>>>>   * sPAPR IRQ frontend routines for devices
> >>>>>>>>>>>   */
> >>>>>>>>>>> +int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
> >>>>>>>>>>> +                              PowerPCCPU *cpu, Error **errp)
> >>>>>>>>>>> +{
> >>>>>>>>>>> +    if (spapr->xive) {
> >>>>>>>>>>> +        SpaprInterruptController *intc = SPAPR_INTC(spapr->xive);
> >>>>>>>>>>> +        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
> >>>>>>>>>>> +
> >>>>>>>>>>> +        if (sicc->cpu_intc_create(intc, cpu, errp) < 0) {
> >>>>>>>>>>> +            return -1;
> >>>>>>>>>>> +        }
> >>>>>>>>>>> +    }
> >>>>>>>>>>> +
> >>>>>>>>>>> +    if (spapr->ics) {
> >>>>>>>>>>> +        SpaprInterruptController *intc = SPAPR_INTC(spapr->ics);
> >>>>>>>>>>> +        SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
> >>>>>>>>>>> +
> >>>>>>>>>>> +        if (sicc->cpu_intc_create(intc, cpu, errp) < 0) {
> >>>>>>>>>>> +            return -1;
> >>>>>>>>>>> +        }
> >>>>>>>>>>> +    }
> >>>>>>>>>>> +
> >>>>>>>>>>
> >>>>>>>>>> Instead of these hooks, what about open-coding spapr_xive_cpu_intc_create()
> >>>>>>>>>> and xics_spapr_cpu_intc_create() directly here, like you already did for the
> >>>>>>>>>> ICS and the XIVE objects in spapr_irq_init() ?
> >>>>>>>>>
> >>>>>>>>> I'd prefer not to.  The idea is I want to treat this as basically:
> >>>>>>>>>
> >>>>>>>>> 	foreach_possible_intc(intc)
> >>>>>>>>> 		intc::cpu_intc_create(...)
> >>>>>>>>>
> >>>>>>>>> If I find time I might indeed replace the explicit ics and xive
> >>>>>>>>> pointers with just an array of SpaprInterruptController *.
> >>>>>>>>
> >>>>>>>> Or you could use object_child_foreach() and check for the type. If we had
> >>>>>>>> a helper object_child_foreach_type(), we could use it elsewhere.
> >>>>>>>
> >>>>>>> I thought about that, but I don't think it quite works.  The
> >>>>>>> complication is that the xics device is made explicitly a child of the
> >>>>>>> machine, but the xive device has mmio, so it's a SusBusDevice sitting
> >>>>>>> on the root bus instead.
> >>>>>>
> >>>>>> PnvXscom works fine with Devices and SysBusDevices.
> >>>>>
> >>>>> Uh... what's an example of it working with a SysBusDevice?  All the
> >>>>> implementors of PNV_XSCOM_INTERFACE I could find were instantiated
> >>>>> with object_initialize_child() making them explicitly children of the
> >>>>> chip.  The SPAPR_XIVE is instantiated with qdev_create(NULL,
> >>>>> TYPE_SPAPR_XIVE), making it a child of the root bus, not the machine,
> >>>>> I believe.
> >>>>
> >>>> I see. We should reparent the interrupt controller then.
> >>>
> >>> Well, maybe.  It's not obvious to me that that's the right approach
> >>> just because of this.
> >>>
> >>>
> >>>> Could we rework 
> >>>> the code to instantiate and realize the XICS and XIVE model objects ? 
> >>>> We have the handlers spapr_instance_init() and spapr_machine_init(). 
> >>>
> >>> I'm not really sure what you're suggesting here.
> >>
> >> Define the device model objects under the machine and not pointers :
> >>
> >> 	struct SpaprMachineState {
> >> 		...
> >> 		ICSState ics;
> >> 		SpaprXive  xive;
> >> 		...
> >> 	};
> >>
> >> in spapr_instance_init() :
> >>
> >> 	object_initialize_child(obj, "ics",  &spapr->ics, sizeof(spapr->ics),
> >>                             TYPE_ICS, &error_abort, NULL);
> >> 	object_property_add_const_link(OBJECT(&spapr->ics), "xics", obj,
> >>                                    &error_abort);
> >>
> >> 	object_initialize_child(obj, "xive",  &spapr->xive, sizeof(spapr->xive),
> >>                             TYPE_SPAPR_XIVE, &error_abort, NULL);
> >>
> >>
> >> in spapr_machine_init(), call the realize handler depending on the chosen 
> >> 'ic-mode'.
> > 
> > Hm, yeah, maybe.  I don't love having a whole structure in there
> > that's unused when ic-mode != dual.
> > 
> 
> This is the pattern followed in the ARM SoC models. Enough room is 
> provisioned for the maximum controllers and depending on the SoC
> configuration only some are realized.

Hm, ok, I guess that makes it a pretty promising approach.  Maybe for
another day though.  In the meantime I've come up with an approach
that's not totally elegant, but it does remove the duplication of the
paths for xics vs. xive, keep the individual pointers in the structure
for now, and isn't *too* verbose.

I've stripped your R-b due to the change, so please have a look in the
next spin.

-- 
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] 83+ messages in thread

end of thread, other threads:[~2019-10-02  2:14 UTC | newest]

Thread overview: 83+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-27  5:49 [PATCH v2 00/33] spapr: IRQ subsystem cleanup David Gibson
2019-09-27  5:49 ` [PATCH v2 01/33] xics: Minor fixes for XICSFabric interface David Gibson
2019-09-27  7:17   ` Greg Kurz
2019-09-27  5:49 ` [PATCH v2 02/33] xics: Eliminate 'reject', 'resend' and 'eoi' class hooks David Gibson
2019-09-27  5:49 ` [PATCH v2 03/33] xics: Rename misleading ics_simple_*() functions David Gibson
2019-09-27  5:49 ` [PATCH v2 04/33] xics: Eliminate reset hook David Gibson
2019-09-27  7:19   ` Greg Kurz
2019-09-27  5:50 ` [PATCH v2 05/33] xics: Merge TYPE_ICS_BASE and TYPE_ICS_SIMPLE classes David Gibson
2019-09-27  5:50 ` [PATCH v2 06/33] xics: Create sPAPR specific ICS subtype David Gibson
2019-09-27  7:22   ` Greg Kurz
2019-09-27  5:50 ` [PATCH v2 07/33] spapr: Fold spapr_phb_lsi_qirq() into its single caller David Gibson
2019-09-27  5:50 ` [PATCH v2 08/33] spapr: Replace spapr_vio_qirq() helper with spapr_vio_irq_pulse() helper David Gibson
2019-09-27  5:50 ` [PATCH v2 09/33] spapr: Clarify and fix handling of nr_irqs David Gibson
2019-09-27  7:53   ` Greg Kurz
2019-09-27  7:58     ` David Gibson
2019-09-27  5:50 ` [PATCH v2 10/33] spapr: Eliminate nr_irqs parameter to SpaprIrq::init David Gibson
2019-09-27  7:57   ` Greg Kurz
2019-09-27  5:50 ` [PATCH v2 11/33] spapr: Fix indexing of XICS irqs David Gibson
2019-09-27  5:50 ` [PATCH v2 12/33] spapr: Simplify spapr_qirq() handling David Gibson
2019-09-27  5:50 ` [PATCH v2 13/33] spapr: Eliminate SpaprIrq:get_nodename method David Gibson
2019-09-27  5:50 ` [PATCH v2 14/33] spapr: Remove unhelpful tracepoints from spapr_irq_free_xics() David Gibson
2019-09-27  5:50 ` [PATCH v2 15/33] spapr: Handle freeing of multiple irqs in frontend only David Gibson
2019-09-27  5:50 ` [PATCH v2 16/33] spapr, xics, xive: Better use of assert()s on irq claim/free paths David Gibson
2019-09-27  5:50 ` [PATCH v2 17/33] xive: Improve irq claim/free path David Gibson
2019-09-27  8:40   ` Greg Kurz
2019-09-30  1:39     ` David Gibson
2019-09-27  5:50 ` [PATCH v2 18/33] spapr: Use less cryptic representation of which irq backends are supported David Gibson
2019-09-27  5:50 ` [PATCH v2 19/33] spapr: Eliminate SpaprIrq::init hook David Gibson
2019-09-27  5:50 ` [PATCH v2 20/33] spapr, xics, xive: Introduce SpaprInterruptController QOM interface David Gibson
2019-09-27  9:52   ` Greg Kurz
2019-09-30  5:24   ` Cédric Le Goater
2019-09-27  5:50 ` [PATCH v2 21/33] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController David Gibson
2019-09-27 10:16   ` Greg Kurz
2019-09-30  1:49     ` David Gibson
2019-09-30  5:28       ` Cédric Le Goater
2019-09-30  6:14         ` David Gibson
2019-09-30 10:13           ` Cédric Le Goater
2019-10-01  2:31             ` David Gibson
2019-10-01  5:43               ` Cédric Le Goater
2019-10-01  6:47                 ` David Gibson
2019-10-01  7:41                   ` Cédric Le Goater
2019-10-01  8:11                     ` David Gibson
2019-10-01 11:43                       ` Cédric Le Goater
2019-10-02  1:11                         ` David Gibson
2019-09-30  2:37     ` David Gibson
2019-09-30  5:30   ` Cédric Le Goater
2019-09-27  5:50 ` [PATCH v2 22/33] spapr, xics, xive: Move irq claim and free " David Gibson
2019-09-27 12:16   ` Greg Kurz
2019-09-30  2:39     ` David Gibson
2019-09-30  5:36       ` Cédric Le Goater
2019-09-30  5:33   ` Cédric Le Goater
2019-09-27  5:50 ` [PATCH v2 23/33] spapr: Formalize notion of active interrupt controller David Gibson
2019-09-27 14:16   ` Greg Kurz
2019-09-30  5:39   ` Cédric Le Goater
2019-09-27  5:50 ` [PATCH v2 24/33] spapr, xics, xive: Move set_irq from SpaprIrq to SpaprInterruptController David Gibson
2019-09-27 14:27   ` Greg Kurz
2019-09-30  2:41     ` David Gibson
2019-09-30  7:22       ` Greg Kurz
2019-09-30  8:28         ` David Gibson
2019-09-30  5:48   ` Cédric Le Goater
2019-09-27  5:50 ` [PATCH v2 25/33] spapr, xics, xive: Move print_info " David Gibson
2019-09-27 14:31   ` Greg Kurz
2019-09-27  5:50 ` [PATCH v2 26/33] spapr, xics, xive: Move dt_populate " David Gibson
2019-09-27 14:38   ` Greg Kurz
2019-09-30  5:51   ` Cédric Le Goater
2019-09-27  5:50 ` [PATCH v2 27/33] spapr, xics, xive: Match signatures for XICS and XIVE KVM connect routines David Gibson
2019-09-27 14:49   ` Greg Kurz
2019-09-30  5:52   ` Cédric Le Goater
2019-09-27  5:50 ` [PATCH v2 28/33] spapr: Remove SpaprIrq::init_kvm hook David Gibson
2019-09-27 15:04   ` Greg Kurz
2019-09-30  5:55   ` Cédric Le Goater
2019-09-27  5:50 ` [PATCH v2 29/33] spapr, xics, xive: Move SpaprIrq::reset hook logic into activate/deactivate David Gibson
2019-09-30  6:11   ` Cédric Le Goater
2019-09-30  8:25     ` David Gibson
2019-09-30 19:29       ` Cédric Le Goater
2019-10-01  3:07         ` David Gibson
2019-09-27  5:50 ` [PATCH v2 30/33] spapr, xics, xive: Move SpaprIrq::post_load hook to backends David Gibson
2019-09-27  5:50 ` [PATCH v2 31/33] spapr: Remove SpaprIrq::nr_msis David Gibson
2019-09-27 15:17   ` Greg Kurz
2019-09-27  5:50 ` [PATCH v2 32/33] spapr: Move SpaprIrq::nr_xirqs to SpaprMachineClass David Gibson
2019-09-27 15:22   ` Greg Kurz
2019-09-30  2:44     ` David Gibson
2019-09-27  5:50 ` [PATCH v2 33/33] spapr: Remove last pieces of SpaprIrq David Gibson

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.