qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 00/34] spapr: IRQ subsystem cleanup
@ 2019-10-02  2:51 David Gibson
  2019-10-02  2:51 ` [PATCH v3 01/34] xics: Minor fixes for XICSFabric interface David Gibson
                   ` (34 more replies)
  0 siblings, 35 replies; 64+ messages in thread
From: David Gibson @ 2019-10-02  2:51 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, 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 v2:
 * Fixed a bug where the "move handling multiple irq frees" to
   frontend patch was actually freeing one irq over and over, rather
   than freeing multiple irqs
 * Fixed some places I missed still using only-Error * style, and flow
   on adjustments
 * New idiom to iterate across all constructed backends for the things
   that need that (cpu_intc_create, claim & freem), rather than
   open-coding a call on the xics, then xive versions.

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 (34):
  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: Add return value to spapr_irq_check()
  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              |  57 ++-
 hw/ppc/spapr_caps.c         |  64 +++
 hw/ppc/spapr_cpu_core.c     |   3 +-
 hw/ppc/spapr_hcall.c        |   7 +-
 hw/ppc/spapr_irq.c          | 847 +++++++++++-------------------------
 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  |  89 ++--
 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 |  10 +-
 include/hw/ppc/xive.h       |   2 +-
 25 files changed, 897 insertions(+), 997 deletions(-)

-- 
2.21.0



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

* [PATCH v3 01/34] xics: Minor fixes for XICSFabric interface
  2019-10-02  2:51 [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
@ 2019-10-02  2:51 ` David Gibson
  2019-10-02  5:51   ` Cédric Le Goater
  2019-10-02  2:51 ` [PATCH v3 02/34] xics: Eliminate 'reject', 'resend' and 'eoi' class hooks David Gibson
                   ` (33 subsequent siblings)
  34 siblings, 1 reply; 64+ messages in thread
From: David Gibson @ 2019-10-02  2:51 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, 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>
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)                                   \
-- 
2.21.0



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

* [PATCH v3 02/34] xics: Eliminate 'reject', 'resend' and 'eoi' class hooks
  2019-10-02  2:51 [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
  2019-10-02  2:51 ` [PATCH v3 01/34] xics: Minor fixes for XICSFabric interface David Gibson
@ 2019-10-02  2:51 ` David Gibson
  2019-10-02  2:51 ` [PATCH v3 03/34] xics: Rename misleading ics_simple_*() functions David Gibson
                   ` (32 subsequent siblings)
  34 siblings, 0 replies; 64+ messages in thread
From: David Gibson @ 2019-10-02  2:51 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, 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] 64+ messages in thread

* [PATCH v3 03/34] xics: Rename misleading ics_simple_*() functions
  2019-10-02  2:51 [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
  2019-10-02  2:51 ` [PATCH v3 01/34] xics: Minor fixes for XICSFabric interface David Gibson
  2019-10-02  2:51 ` [PATCH v3 02/34] xics: Eliminate 'reject', 'resend' and 'eoi' class hooks David Gibson
@ 2019-10-02  2:51 ` David Gibson
  2019-10-02  2:51 ` [PATCH v3 04/34] xics: Eliminate reset hook David Gibson
                   ` (31 subsequent siblings)
  34 siblings, 0 replies; 64+ messages in thread
From: David Gibson @ 2019-10-02  2:51 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, 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] 64+ messages in thread

* [PATCH v3 04/34] xics: Eliminate reset hook
  2019-10-02  2:51 [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
                   ` (2 preceding siblings ...)
  2019-10-02  2:51 ` [PATCH v3 03/34] xics: Rename misleading ics_simple_*() functions David Gibson
@ 2019-10-02  2:51 ` David Gibson
  2019-10-02  2:51 ` [PATCH v3 05/34] xics: Merge TYPE_ICS_BASE and TYPE_ICS_SIMPLE classes David Gibson
                   ` (30 subsequent siblings)
  34 siblings, 0 replies; 64+ messages in thread
From: David Gibson @ 2019-10-02  2:51 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, 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>
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 {
-- 
2.21.0



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

* [PATCH v3 05/34] xics: Merge TYPE_ICS_BASE and TYPE_ICS_SIMPLE classes
  2019-10-02  2:51 [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
                   ` (3 preceding siblings ...)
  2019-10-02  2:51 ` [PATCH v3 04/34] xics: Eliminate reset hook David Gibson
@ 2019-10-02  2:51 ` David Gibson
  2019-10-02  2:51 ` [PATCH v3 06/34] xics: Create sPAPR specific ICS subtype David Gibson
                   ` (29 subsequent siblings)
  34 siblings, 0 replies; 64+ messages in thread
From: David Gibson @ 2019-10-02  2:51 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, 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] 64+ messages in thread

* [PATCH v3 06/34] xics: Create sPAPR specific ICS subtype
  2019-10-02  2:51 [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
                   ` (4 preceding siblings ...)
  2019-10-02  2:51 ` [PATCH v3 05/34] xics: Merge TYPE_ICS_BASE and TYPE_ICS_SIMPLE classes David Gibson
@ 2019-10-02  2:51 ` David Gibson
  2019-10-02  2:51 ` [PATCH v3 07/34] spapr: Fold spapr_phb_lsi_qirq() into its single caller David Gibson
                   ` (28 subsequent siblings)
  34 siblings, 0 replies; 64+ messages in thread
From: David Gibson @ 2019-10-02  2:51 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, 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>
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 */
-- 
2.21.0



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

* [PATCH v3 07/34] spapr: Fold spapr_phb_lsi_qirq() into its single caller
  2019-10-02  2:51 [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
                   ` (5 preceding siblings ...)
  2019-10-02  2:51 ` [PATCH v3 06/34] xics: Create sPAPR specific ICS subtype David Gibson
@ 2019-10-02  2:51 ` David Gibson
  2019-10-02  2:51 ` [PATCH v3 08/34] spapr: Replace spapr_vio_qirq() helper with spapr_vio_irq_pulse() helper David Gibson
                   ` (27 subsequent siblings)
  34 siblings, 0 replies; 64+ messages in thread
From: David Gibson @ 2019-10-02  2:51 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, 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 c1c9634755..01ff41d4c4 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] 64+ messages in thread

* [PATCH v3 08/34] spapr: Replace spapr_vio_qirq() helper with spapr_vio_irq_pulse() helper
  2019-10-02  2:51 [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
                   ` (6 preceding siblings ...)
  2019-10-02  2:51 ` [PATCH v3 07/34] spapr: Fold spapr_phb_lsi_qirq() into its single caller David Gibson
@ 2019-10-02  2:51 ` David Gibson
  2019-10-02  2:51 ` [PATCH v3 09/34] spapr: Clarify and fix handling of nr_irqs David Gibson
                   ` (26 subsequent siblings)
  34 siblings, 0 replies; 64+ messages in thread
From: David Gibson @ 2019-10-02  2:51 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, 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] 64+ messages in thread

* [PATCH v3 09/34] spapr: Clarify and fix handling of nr_irqs
  2019-10-02  2:51 [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
                   ` (7 preceding siblings ...)
  2019-10-02  2:51 ` [PATCH v3 08/34] spapr: Replace spapr_vio_qirq() helper with spapr_vio_irq_pulse() helper David Gibson
@ 2019-10-02  2:51 ` David Gibson
  2019-10-02  5:57   ` Cédric Le Goater
  2019-10-02  2:51 ` [PATCH v3 10/34] spapr: Eliminate nr_irqs parameter to SpaprIrq::init David Gibson
                   ` (25 subsequent siblings)
  34 siblings, 1 reply; 64+ messages in thread
From: David Gibson @ 2019-10-02  2:51 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, 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>
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;
 
-- 
2.21.0



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

* [PATCH v3 10/34] spapr: Eliminate nr_irqs parameter to SpaprIrq::init
  2019-10-02  2:51 [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
                   ` (8 preceding siblings ...)
  2019-10-02  2:51 ` [PATCH v3 09/34] spapr: Clarify and fix handling of nr_irqs David Gibson
@ 2019-10-02  2:51 ` David Gibson
  2019-10-02  2:51 ` [PATCH v3 11/34] spapr: Fix indexing of XICS irqs David Gibson
                   ` (24 subsequent siblings)
  34 siblings, 0 replies; 64+ messages in thread
From: David Gibson @ 2019-10-02  2:51 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, 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>
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);
-- 
2.21.0



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

* [PATCH v3 11/34] spapr: Fix indexing of XICS irqs
  2019-10-02  2:51 [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
                   ` (9 preceding siblings ...)
  2019-10-02  2:51 ` [PATCH v3 10/34] spapr: Eliminate nr_irqs parameter to SpaprIrq::init David Gibson
@ 2019-10-02  2:51 ` David Gibson
  2019-10-02  2:51 ` [PATCH v3 12/34] spapr: Simplify spapr_qirq() handling David Gibson
                   ` (23 subsequent siblings)
  34 siblings, 0 replies; 64+ messages in thread
From: David Gibson @ 2019-10-02  2:51 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, 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] 64+ messages in thread

* [PATCH v3 12/34] spapr: Simplify spapr_qirq() handling
  2019-10-02  2:51 [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
                   ` (10 preceding siblings ...)
  2019-10-02  2:51 ` [PATCH v3 11/34] spapr: Fix indexing of XICS irqs David Gibson
@ 2019-10-02  2:51 ` David Gibson
  2019-10-02  2:51 ` [PATCH v3 13/34] spapr: Eliminate SpaprIrq:get_nodename method David Gibson
                   ` (22 subsequent siblings)
  34 siblings, 0 replies; 64+ messages in thread
From: David Gibson @ 2019-10-02  2:51 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, 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] 64+ messages in thread

* [PATCH v3 13/34] spapr: Eliminate SpaprIrq:get_nodename method
  2019-10-02  2:51 [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
                   ` (11 preceding siblings ...)
  2019-10-02  2:51 ` [PATCH v3 12/34] spapr: Simplify spapr_qirq() handling David Gibson
@ 2019-10-02  2:51 ` David Gibson
  2019-10-02  2:51 ` [PATCH v3 14/34] spapr: Remove unhelpful tracepoints from spapr_irq_free_xics() David Gibson
                   ` (21 subsequent siblings)
  34 siblings, 0 replies; 64+ messages in thread
From: David Gibson @ 2019-10-02  2:51 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, 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] 64+ messages in thread

* [PATCH v3 14/34] spapr: Remove unhelpful tracepoints from spapr_irq_free_xics()
  2019-10-02  2:51 [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
                   ` (12 preceding siblings ...)
  2019-10-02  2:51 ` [PATCH v3 13/34] spapr: Eliminate SpaprIrq:get_nodename method David Gibson
@ 2019-10-02  2:51 ` David Gibson
  2019-10-02  2:51 ` [PATCH v3 15/34] spapr: Handle freeing of multiple irqs in frontend only David Gibson
                   ` (20 subsequent siblings)
  34 siblings, 0 replies; 64+ messages in thread
From: David Gibson @ 2019-10-02  2:51 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, 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] 64+ messages in thread

* [PATCH v3 15/34] spapr: Handle freeing of multiple irqs in frontend only
  2019-10-02  2:51 [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
                   ` (13 preceding siblings ...)
  2019-10-02  2:51 ` [PATCH v3 14/34] spapr: Remove unhelpful tracepoints from spapr_irq_free_xics() David Gibson
@ 2019-10-02  2:51 ` David Gibson
  2019-10-02  5:51   ` Greg Kurz
  2019-10-02  5:55   ` Cédric Le Goater
  2019-10-02  2:51 ` [PATCH v3 16/34] spapr, xics, xive: Better use of assert()s on irq claim/free paths David Gibson
                   ` (19 subsequent siblings)
  34 siblings, 2 replies; 64+ messages in thread
From: David Gibson @ 2019-10-02  2:51 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, 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>
---
 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..d2ac35bbe1 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, i);
+    }
 }
 
 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] 64+ messages in thread

* [PATCH v3 16/34] spapr, xics, xive: Better use of assert()s on irq claim/free paths
  2019-10-02  2:51 [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
                   ` (14 preceding siblings ...)
  2019-10-02  2:51 ` [PATCH v3 15/34] spapr: Handle freeing of multiple irqs in frontend only David Gibson
@ 2019-10-02  2:51 ` David Gibson
  2019-10-02  2:51 ` [PATCH v3 17/34] xive: Improve irq claim/free path David Gibson
                   ` (18 subsequent siblings)
  34 siblings, 0 replies; 64+ messages in thread
From: David Gibson @ 2019-10-02  2:51 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, 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 d2ac35bbe1..025c802e7b 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, i);
     }
-- 
2.21.0



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

* [PATCH v3 17/34] xive: Improve irq claim/free path
  2019-10-02  2:51 [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
                   ` (15 preceding siblings ...)
  2019-10-02  2:51 ` [PATCH v3 16/34] spapr, xics, xive: Better use of assert()s on irq claim/free paths David Gibson
@ 2019-10-02  2:51 ` David Gibson
  2019-10-02  2:51 ` [PATCH v3 18/34] spapr: Use less cryptic representation of which irq backends are supported David Gibson
                   ` (17 subsequent siblings)
  34 siblings, 0 replies; 64+ messages in thread
From: David Gibson @ 2019-10-02  2:51 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, 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>
Reviewed-by: Greg Kurz <groug@kaod.org>
---
 hw/intc/spapr_xive.c        | 20 +++++++++-----------
 hw/intc/spapr_xive_kvm.c    |  8 ++++----
 hw/ppc/spapr_irq.c          | 11 +++++------
 include/hw/ppc/spapr_xive.h |  4 ++--
 include/hw/ppc/xive.h       |  2 +-
 5 files changed, 21 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 025c802e7b..516bf00a35 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -246,7 +246,10 @@ 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);
+        if (spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i,
+                                 false, errp) < 0) {
+            return;
+        }
     }
 
     spapr_xive_hcall_init(spapr);
@@ -255,11 +258,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] 64+ messages in thread

* [PATCH v3 18/34] spapr: Use less cryptic representation of which irq backends are supported
  2019-10-02  2:51 [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
                   ` (16 preceding siblings ...)
  2019-10-02  2:51 ` [PATCH v3 17/34] xive: Improve irq claim/free path David Gibson
@ 2019-10-02  2:51 ` David Gibson
  2019-10-02  2:51 ` [PATCH v3 19/34] spapr: Add return value to spapr_irq_check() David Gibson
                   ` (16 subsequent siblings)
  34 siblings, 0 replies; 64+ messages in thread
From: David Gibson @ 2019-10-02  2:51 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, 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 43920c140d..514a17ae74 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1066,19 +1066,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()) {
@@ -2767,7 +2776,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 516bf00a35..3ac67ba0c7 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,
@@ -350,7 +351,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,
@@ -511,7 +513,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,
@@ -754,7 +757,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] 64+ messages in thread

* [PATCH v3 19/34] spapr: Add return value to spapr_irq_check()
  2019-10-02  2:51 [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
                   ` (17 preceding siblings ...)
  2019-10-02  2:51 ` [PATCH v3 18/34] spapr: Use less cryptic representation of which irq backends are supported David Gibson
@ 2019-10-02  2:51 ` David Gibson
  2019-10-02  5:58   ` Cédric Le Goater
  2019-10-02  6:08   ` Greg Kurz
  2019-10-02  2:51 ` [PATCH v3 20/34] spapr: Eliminate SpaprIrq::init hook David Gibson
                   ` (15 subsequent siblings)
  34 siblings, 2 replies; 64+ messages in thread
From: David Gibson @ 2019-10-02  2:51 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, Paolo Bonzini,
	Marc-André Lureau, philmd, David Gibson

Explicitly return success or failure, rather than just relying on the
Error ** parameter.  This makes handling it less verbose in the caller.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr_irq.c | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 3ac67ba0c7..0413fbd0a3 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -529,7 +529,7 @@ SpaprIrq spapr_irq_dual = {
 };
 
 
-static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
+static int spapr_irq_check(SpaprMachineState *spapr, Error **errp)
 {
     MachineState *machine = MACHINE(spapr);
 
@@ -545,7 +545,7 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
          */
         if (spapr->irq == &spapr_irq_dual) {
             spapr->irq = &spapr_irq_xics;
-            return;
+            return 0;
         }
 
         /*
@@ -565,7 +565,7 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
          */
         if (spapr->irq == &spapr_irq_xive) {
             error_setg(errp, "XIVE-only machines require a POWER9 CPU");
-            return;
+            return -1;
         }
     }
 
@@ -579,8 +579,10 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
         machine_kernel_irqchip_required(machine) &&
         xics_kvm_has_broken_disconnect(spapr)) {
         error_setg(errp, "KVM is too old to support ic-mode=dual,kernel-irqchip=on");
-        return;
+        return -1;
     }
+
+    return 0;
 }
 
 /*
@@ -589,7 +591,6 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
 void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
 {
     MachineState *machine = MACHINE(spapr);
-    Error *local_err = NULL;
 
     if (machine_kernel_irqchip_split(machine)) {
         error_setg(errp, "kernel_irqchip split mode not supported on pseries");
@@ -602,9 +603,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
         return;
     }
 
-    spapr_irq_check(spapr, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
+    if (spapr_irq_check(spapr, errp) < 0) {
         return;
     }
 
-- 
2.21.0



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

* [PATCH v3 20/34] spapr: Eliminate SpaprIrq::init hook
  2019-10-02  2:51 [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
                   ` (18 preceding siblings ...)
  2019-10-02  2:51 ` [PATCH v3 19/34] spapr: Add return value to spapr_irq_check() David Gibson
@ 2019-10-02  2:51 ` David Gibson
  2019-10-02  2:51 ` [PATCH v3 21/34] spapr, xics, xive: Introduce SpaprInterruptController QOM interface David Gibson
                   ` (14 subsequent siblings)
  34 siblings, 0 replies; 64+ messages in thread
From: David Gibson @ 2019-10-02  2:51 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, 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         | 130 +++++++++++++++++--------------------
 include/hw/ppc/spapr_irq.h |   1 -
 2 files changed, 61 insertions(+), 70 deletions(-)

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 0413fbd0a3..457eabe24c 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,33 +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) {
-        if (spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i,
-                                 false, errp) < 0) {
-            return;
-        }
-    }
-
-    spapr_xive_hcall_init(spapr);
-}
 
 static int spapr_irq_claim_xive(SpaprMachineState *spapr, int irq, bool lsi,
                                 Error **errp)
@@ -354,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,
@@ -385,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)
 {
@@ -516,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,
@@ -612,7 +545,67 @@ 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) {
+        Error *local_err = NULL;
+        Object *obj;
+
+        obj = object_new(TYPE_ICS_SPAPR);
+        object_property_add_child(OBJECT(spapr), "ics", obj, &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            return;
+        }
+
+        object_property_add_const_link(obj, ICS_PROP_XICS, OBJECT(spapr),
+                                       &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            return;
+        }
+
+        object_property_set_int(obj, spapr->irq->nr_xirqs, "nr-irqs",
+                                &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            return;
+        }
+
+        object_property_set_bool(obj, true, "realized", &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            return;
+        }
+
+        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) {
+            if (spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i,
+                                     false, errp) < 0) {
+                return;
+            }
+        }
+
+        spapr_xive_hcall_init(spapr);
+    }
 
     spapr->qirqs = qemu_allocate_irqs(spapr->irq->set_irq, spapr,
                                       spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
@@ -759,7 +752,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);
-- 
2.21.0



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

* [PATCH v3 21/34] spapr, xics, xive: Introduce SpaprInterruptController QOM interface
  2019-10-02  2:51 [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
                   ` (19 preceding siblings ...)
  2019-10-02  2:51 ` [PATCH v3 20/34] spapr: Eliminate SpaprIrq::init hook David Gibson
@ 2019-10-02  2:51 ` David Gibson
  2019-10-02  2:51 ` [PATCH v3 22/34] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController David Gibson
                   ` (13 subsequent siblings)
  34 siblings, 0 replies; 64+ messages in thread
From: David Gibson @ 2019-10-02  2:51 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, 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>
Reviewed-by: Greg Kurz <groug@kaod.org>
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 457eabe24c..8791dec1ba 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;
@@ -762,3 +768,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] 64+ messages in thread

* [PATCH v3 22/34] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController
  2019-10-02  2:51 [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
                   ` (20 preceding siblings ...)
  2019-10-02  2:51 ` [PATCH v3 21/34] spapr, xics, xive: Introduce SpaprInterruptController QOM interface David Gibson
@ 2019-10-02  2:51 ` David Gibson
  2019-10-02  6:06   ` Cédric Le Goater
                     ` (2 more replies)
  2019-10-02  2:51 ` [PATCH v3 23/34] spapr, xics, xive: Move irq claim and free " David Gibson
                   ` (12 subsequent siblings)
  34 siblings, 3 replies; 64+ messages in thread
From: David Gibson @ 2019-10-02  2:51 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, 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 | 13 +++++-
 5 files changed, 79 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 8791dec1ba..9cb2fc71ca 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,
@@ -527,6 +471,30 @@ static int spapr_irq_check(SpaprMachineState *spapr, Error **errp)
 /*
  * sPAPR IRQ frontend routines for devices
  */
+#define ALL_INTCS(spapr_) \
+    { SPAPR_INTC((spapr_)->ics), SPAPR_INTC((spapr_)->xive), }
+
+int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
+                              PowerPCCPU *cpu, Error **errp)
+{
+    SpaprInterruptController *intcs[] = ALL_INTCS(spapr);
+    int i;
+    int rc;
+
+    for (i = 0; i < ARRAY_SIZE(intcs); i++) {
+        SpaprInterruptController *intc = intcs[i];
+        if (intc) {
+            SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
+            rc = sicc->cpu_intc_create(intc, cpu, errp);
+            if (rc < 0) {
+                return rc;
+            }
+        }
+    }
+
+    return 0;
+}
+
 void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
 {
     MachineState *machine = MACHINE(spapr);
@@ -762,7 +730,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..5e641e23c1 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -43,8 +43,19 @@ 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;
 
+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 +72,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] 64+ messages in thread

* [PATCH v3 23/34] spapr, xics, xive: Move irq claim and free from SpaprIrq to SpaprInterruptController
  2019-10-02  2:51 [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
                   ` (21 preceding siblings ...)
  2019-10-02  2:51 ` [PATCH v3 22/34] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController David Gibson
@ 2019-10-02  2:51 ` David Gibson
  2019-10-02  6:10   ` Cédric Le Goater
                     ` (2 more replies)
  2019-10-02  2:51 ` [PATCH v3 24/34] spapr: Formalize notion of active interrupt controller David Gibson
                   ` (11 subsequent siblings)
  34 siblings, 3 replies; 64+ messages in thread
From: David Gibson @ 2019-10-02  2:51 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, 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          | 110 +++++++++++-------------------------
 include/hw/ppc/spapr_irq.h  |   5 +-
 include/hw/ppc/spapr_xive.h |   2 -
 5 files changed, 102 insertions(+), 115 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 9cb2fc71ca..83882cfad3 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,
@@ -572,8 +501,11 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
 
         /* Enable the CPU IPIs */
         for (i = 0; i < nr_servers; ++i) {
-            if (spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i,
-                                     false, errp) < 0) {
+            SpaprInterruptControllerClass *sicc
+                = SPAPR_INTC_GET_CLASS(spapr->xive);
+
+            if (sicc->claim_irq(SPAPR_INTC(spapr->xive), SPAPR_IRQ_IPI + i,
+                                false, errp) < 0) {
                 return;
             }
         }
@@ -587,21 +519,45 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
 
 int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
 {
+    SpaprInterruptController *intcs[] = ALL_INTCS(spapr);
+    int i;
+    int rc;
+
     assert(irq >= SPAPR_XIRQ_BASE);
     assert(irq < (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
 
-    return spapr->irq->claim(spapr, irq, lsi, errp);
+    for (i = 0; i < ARRAY_SIZE(intcs); i++) {
+        SpaprInterruptController *intc = intcs[i];
+        if (intc) {
+            SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
+            rc = sicc->claim_irq(intc, irq, lsi, errp);
+            if (rc < 0) {
+                return rc;
+            }
+        }
+    }
+
+    return 0;
 }
 
 void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
 {
-    int i;
+    SpaprInterruptController *intcs[] = ALL_INTCS(spapr);
+    int i, j;
 
     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, i);
+        for (j = 0; j < ARRAY_SIZE(intcs); j++) {
+            SpaprInterruptController *intc = intcs[j];
+
+            if (intc) {
+                SpaprInterruptControllerClass *sicc
+                    = SPAPR_INTC_GET_CLASS(intc);
+                sicc->free_irq(intc, i);
+            }
+        }
     }
 }
 
@@ -726,8 +682,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 5e641e23c1..adfef0fcbe 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;
 
 int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
@@ -67,8 +70,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] 64+ messages in thread

* [PATCH v3 24/34] spapr: Formalize notion of active interrupt controller
  2019-10-02  2:51 [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
                   ` (22 preceding siblings ...)
  2019-10-02  2:51 ` [PATCH v3 23/34] spapr, xics, xive: Move irq claim and free " David Gibson
@ 2019-10-02  2:51 ` David Gibson
  2019-10-02  2:51 ` [PATCH v3 25/34] spapr, xics, xive: Move set_irq from SpaprIrq to SpaprInterruptController David Gibson
                   ` (10 subsequent siblings)
  34 siblings, 0 replies; 64+ messages in thread
From: David Gibson @ 2019-10-02  2:51 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, 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>
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 83882cfad3..249a2688ac 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -586,6 +586,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);
 }
 
@@ -593,6 +594,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);
     }
@@ -619,6 +622,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 adfef0fcbe..18660a29db 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);
+
 int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
                               PowerPCCPU *cpu, Error **errp);
 
-- 
2.21.0



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

* [PATCH v3 25/34] spapr, xics, xive: Move set_irq from SpaprIrq to SpaprInterruptController
  2019-10-02  2:51 [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
                   ` (23 preceding siblings ...)
  2019-10-02  2:51 ` [PATCH v3 24/34] spapr: Formalize notion of active interrupt controller David Gibson
@ 2019-10-02  2:51 ` David Gibson
  2019-10-02  2:52 ` [PATCH v3 26/34] spapr, xics, xive: Move print_info " David Gibson
                   ` (9 subsequent siblings)
  34 siblings, 0 replies; 64+ messages in thread
From: David Gibson @ 2019-10-02  2:51 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, 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>
Reviewed-by: Greg Kurz <groug@kaod.org>
---
 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 249a2688ac..bfccb815ed 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 */
 };
 
@@ -424,6 +395,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);
@@ -513,7 +493,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);
 }
 
@@ -737,7 +717,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 18660a29db..73af1ed27a 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);
@@ -80,7 +83,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] 64+ messages in thread

* [PATCH v3 26/34] spapr, xics, xive: Move print_info from SpaprIrq to SpaprInterruptController
  2019-10-02  2:51 [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
                   ` (24 preceding siblings ...)
  2019-10-02  2:51 ` [PATCH v3 25/34] spapr, xics, xive: Move set_irq from SpaprIrq to SpaprInterruptController David Gibson
@ 2019-10-02  2:52 ` David Gibson
  2019-10-02  2:52 ` [PATCH v3 27/34] spapr, xics, xive: Move dt_populate " David Gibson
                   ` (8 subsequent siblings)
  34 siblings, 0 replies; 64+ messages in thread
From: David Gibson @ 2019-10-02  2:52 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, 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>
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 |  4 ++--
 5 files changed, 41 insertions(+), 39 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 514a17ae74..6c38de5927 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -4271,7 +4271,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 bfccb815ed..a29b527232 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,
@@ -404,6 +369,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);
@@ -713,7 +686,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 73af1ed27a..c5081e81d9 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -59,13 +59,14 @@ 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);
 
 int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
                               PowerPCCPU *cpu, Error **errp);
-
+void spapr_irq_print_info(SpaprMachineState *spapr, Monitor *mon);
 
 void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis);
 int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align,
@@ -78,7 +79,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] 64+ messages in thread

* [PATCH v3 27/34] spapr, xics, xive: Move dt_populate from SpaprIrq to SpaprInterruptController
  2019-10-02  2:51 [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
                   ` (25 preceding siblings ...)
  2019-10-02  2:52 ` [PATCH v3 26/34] spapr, xics, xive: Move print_info " David Gibson
@ 2019-10-02  2:52 ` David Gibson
  2019-10-02  2:52 ` [PATCH v3 28/34] spapr, xics, xive: Match signatures for XICS and XIVE KVM connect routines David Gibson
                   ` (7 subsequent siblings)
  34 siblings, 0 replies; 64+ messages in thread
From: David Gibson @ 2019-10-02  2:52 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, 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>
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  |   6 +-
 include/hw/ppc/spapr_xive.h |   2 -
 include/hw/ppc/xics_spapr.h |   2 -
 7 files changed, 80 insertions(+), 83 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 6c38de5927..e880db5d38 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1255,8 +1255,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 a29b527232..a8005072e6 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 */
@@ -377,6 +367,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);
@@ -686,7 +685,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 c5081e81d9..1be53a01bb 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);
@@ -67,6 +69,8 @@ void spapr_irq_update_active_intc(SpaprMachineState *spapr);
 int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
                               PowerPCCPU *cpu, Error **errp);
 void spapr_irq_print_info(SpaprMachineState *spapr, Monitor *mon);
+void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers,
+                  void *fdt, uint32_t phandle);
 
 void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis);
 int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align,
@@ -79,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 0b35e85c26..8e4fb6adce 100644
--- a/include/hw/ppc/xics_spapr.h
+++ b/include/hw/ppc/xics_spapr.h
@@ -32,8 +32,6 @@
 #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);
-- 
2.21.0



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

* [PATCH v3 28/34] spapr, xics, xive: Match signatures for XICS and XIVE KVM connect routines
  2019-10-02  2:51 [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
                   ` (26 preceding siblings ...)
  2019-10-02  2:52 ` [PATCH v3 27/34] spapr, xics, xive: Move dt_populate " David Gibson
@ 2019-10-02  2:52 ` David Gibson
  2019-10-02  2:52 ` [PATCH v3 29/34] spapr: Remove SpaprIrq::init_kvm hook David Gibson
                   ` (6 subsequent siblings)
  34 siblings, 0 replies; 64+ messages in thread
From: David Gibson @ 2019-10-02  2:52 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, 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 there, we add an explicit return value to the connect path
to streamline error reporting in the callers.  We remove error
reporting 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>
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 a8005072e6..5c8ffb27da 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 8e4fb6adce..28b87038c8 100644
--- a/include/hw/ppc/xics_spapr.h
+++ b/include/hw/ppc/xics_spapr.h
@@ -32,8 +32,8 @@
 #define TYPE_ICS_SPAPR "ics-spapr"
 #define ICS_SPAPR(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SPAPR)
 
-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] 64+ messages in thread

* [PATCH v3 29/34] spapr: Remove SpaprIrq::init_kvm hook
  2019-10-02  2:51 [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
                   ` (27 preceding siblings ...)
  2019-10-02  2:52 ` [PATCH v3 28/34] spapr, xics, xive: Match signatures for XICS and XIVE KVM connect routines David Gibson
@ 2019-10-02  2:52 ` David Gibson
  2019-10-02  2:52 ` [PATCH v3 30/34] spapr, xics, xive: Move SpaprIrq::reset hook logic into activate/deactivate David Gibson
                   ` (5 subsequent siblings)
  34 siblings, 0 replies; 64+ messages in thread
From: David Gibson @ 2019-10-02  2:52 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, 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>
Reviewed-by: Greg Kurz <groug@kaod.org>
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 5c8ffb27da..7cd18e5b15 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 */
 };
 
 
@@ -675,7 +652,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 1be53a01bb..a5fdb963a8 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] 64+ messages in thread

* [PATCH v3 30/34] spapr, xics, xive: Move SpaprIrq::reset hook logic into activate/deactivate
  2019-10-02  2:51 [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
                   ` (28 preceding siblings ...)
  2019-10-02  2:52 ` [PATCH v3 29/34] spapr: Remove SpaprIrq::init_kvm hook David Gibson
@ 2019-10-02  2:52 ` David Gibson
  2019-10-02  9:29   ` Greg Kurz
  2019-10-02  2:52 ` [PATCH v3 31/34] spapr, xics, xive: Move SpaprIrq::post_load hook to backends David Gibson
                   ` (4 subsequent siblings)
  34 siblings, 1 reply; 64+ messages in thread
From: David Gibson @ 2019-10-02  2:52 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, 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 7cd18e5b15..f70b331f44 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,
 };
 
 
@@ -512,10 +456,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)
@@ -651,7 +591,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 a5fdb963a8..1aff1c2eb7 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] 64+ messages in thread

* [PATCH v3 31/34] spapr, xics, xive: Move SpaprIrq::post_load hook to backends
  2019-10-02  2:51 [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
                   ` (29 preceding siblings ...)
  2019-10-02  2:52 ` [PATCH v3 30/34] spapr, xics, xive: Move SpaprIrq::reset hook logic into activate/deactivate David Gibson
@ 2019-10-02  2:52 ` David Gibson
  2019-10-02  9:50   ` Greg Kurz
  2019-10-02  2:52 ` [PATCH v3 32/34] spapr: Remove SpaprIrq::nr_msis David Gibson
                   ` (3 subsequent siblings)
  34 siblings, 1 reply; 64+ messages in thread
From: David Gibson @ 2019-10-02  2:52 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, 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 f70b331f44..f3d18b1dad 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,
 };
 
 
@@ -447,8 +409,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)
@@ -589,8 +554,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 1aff1c2eb7..4c2cd091da 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] 64+ messages in thread

* [PATCH v3 32/34] spapr: Remove SpaprIrq::nr_msis
  2019-10-02  2:51 [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
                   ` (30 preceding siblings ...)
  2019-10-02  2:52 ` [PATCH v3 31/34] spapr, xics, xive: Move SpaprIrq::post_load hook to backends David Gibson
@ 2019-10-02  2:52 ` David Gibson
  2019-10-02  2:52 ` [PATCH v3 33/34] spapr: Move SpaprIrq::nr_xirqs to SpaprMachineClass David Gibson
                   ` (2 subsequent siblings)
  34 siblings, 0 replies; 64+ messages in thread
From: David Gibson @ 2019-10-02  2:52 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, 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>
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  |  4 +---
 5 files changed, 26 insertions(+), 20 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index e880db5d38..153cc54354 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1275,7 +1275,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);
@@ -3910,8 +3910,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 f3d18b1dad..076da31501 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,
 };
@@ -247,6 +249,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) {
         Error *local_err = NULL;
@@ -551,7 +560,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 01ff41d4c4..cc0e7829b6 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -2277,8 +2277,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) };
@@ -2343,7 +2343,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 4c2cd091da..f4742ffbd6 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;
 
@@ -73,14 +72,13 @@ void spapr_irq_print_info(SpaprMachineState *spapr, Monitor *mon);
 void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers,
                   void *fdt, uint32_t phandle);
 
-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] 64+ messages in thread

* [PATCH v3 33/34] spapr: Move SpaprIrq::nr_xirqs to SpaprMachineClass
  2019-10-02  2:51 [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
                   ` (31 preceding siblings ...)
  2019-10-02  2:52 ` [PATCH v3 32/34] spapr: Remove SpaprIrq::nr_msis David Gibson
@ 2019-10-02  2:52 ` David Gibson
  2019-10-02  2:52 ` [PATCH v3 34/34] spapr: Remove last pieces of SpaprIrq David Gibson
  2019-10-03  6:18 ` [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
  34 siblings, 0 replies; 64+ messages in thread
From: David Gibson @ 2019-10-02  2:52 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, 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>
Reviewed-by: Greg Kurz <groug@kaod.org>
---
 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 153cc54354..e1ff03152e 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -4443,6 +4443,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 = {
@@ -4578,6 +4579,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 076da31501..2768f9a765 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,
 };
@@ -251,16 +248,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);
 
     if (machine_kernel_irqchip_split(machine)) {
         error_setg(errp, "kernel_irqchip split mode not supported on pseries");
@@ -298,8 +298,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
             return;
         }
 
-        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) {
             error_propagate(errp, local_err);
             return;
@@ -320,8 +319,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
@@ -346,17 +344,18 @@ 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);
 }
 
 int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
 {
     SpaprInterruptController *intcs[] = ALL_INTCS(spapr);
     int i;
+    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));
 
     for (i = 0; i < ARRAY_SIZE(intcs); i++) {
         SpaprInterruptController *intc = intcs[i];
@@ -376,9 +375,10 @@ void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
 {
     SpaprInterruptController *intcs[] = ALL_INTCS(spapr);
     int i, j;
+    SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
 
     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++) {
         for (j = 0; j < ARRAY_SIZE(intcs); j++) {
@@ -395,6 +395,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
@@ -403,7 +405,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));
@@ -556,10 +558,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 f4742ffbd6..50491cea4f 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -78,7 +78,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] 64+ messages in thread

* [PATCH v3 34/34] spapr: Remove last pieces of SpaprIrq
  2019-10-02  2:51 [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
                   ` (32 preceding siblings ...)
  2019-10-02  2:52 ` [PATCH v3 33/34] spapr: Move SpaprIrq::nr_xirqs to SpaprMachineClass David Gibson
@ 2019-10-02  2:52 ` David Gibson
  2019-10-02 10:20   ` Greg Kurz
  2019-10-03  6:18 ` [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
  34 siblings, 1 reply; 64+ messages in thread
From: David Gibson @ 2019-10-02  2:52 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, 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             | 38 +++++++++--------
 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, 99 insertions(+), 112 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index e1ff03152e..b9ac01d90c 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1072,12 +1072,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;
     }
 
@@ -2775,7 +2776,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);
     }
 
@@ -3242,14 +3243,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();
@@ -3266,11 +3271,14 @@ 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;
+        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");
     }
@@ -3309,7 +3317,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;
@@ -3345,7 +3352,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",
@@ -4439,8 +4445,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;
@@ -4539,7 +4546,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;
 }
 
@@ -4580,7 +4587,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 2768f9a765..473fc8780a 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 int 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 0;
-        }
-
-        /*
-         * 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 -1;
-        }
-    }
-
     /*
      * 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 -1;
@@ -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)) {
         Error *local_err = NULL;
         Object *obj;
 
@@ -313,7 +242,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;
@@ -558,11 +487,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 50491cea4f..4b58134701 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -77,16 +77,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] 64+ messages in thread

* Re: [PATCH v3 15/34] spapr: Handle freeing of multiple irqs in frontend only
  2019-10-02  2:51 ` [PATCH v3 15/34] spapr: Handle freeing of multiple irqs in frontend only David Gibson
@ 2019-10-02  5:51   ` Greg Kurz
  2019-10-02  5:55   ` Cédric Le Goater
  1 sibling, 0 replies; 64+ messages in thread
From: Greg Kurz @ 2019-10-02  5:51 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Paolo Bonzini, Marc-André Lureau, philmd

On Wed,  2 Oct 2019 12:51:49 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> 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>
> ---
>  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..d2ac35bbe1 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, i);

It is indeed a lot better than passing irq :)

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

> +    }
>  }
>  
>  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);



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

* Re: [PATCH v3 01/34] xics: Minor fixes for XICSFabric interface
  2019-10-02  2:51 ` [PATCH v3 01/34] xics: Minor fixes for XICSFabric interface David Gibson
@ 2019-10-02  5:51   ` Cédric Le Goater
  2019-10-02  5:55     ` Cédric Le Goater
  2019-10-02  5:55     ` David Gibson
  0 siblings, 2 replies; 64+ messages in thread
From: Cédric Le Goater @ 2019-10-02  5:51 UTC (permalink / raw)
  To: David Gibson, qemu-ppc, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, Paolo Bonzini,
	Marc-André Lureau, philmd

On 02/10/2019 04:51, David Gibson 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>

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

* Re: [PATCH v3 01/34] xics: Minor fixes for XICSFabric interface
  2019-10-02  5:51   ` Cédric Le Goater
@ 2019-10-02  5:55     ` Cédric Le Goater
  2019-10-02  5:55     ` David Gibson
  1 sibling, 0 replies; 64+ messages in thread
From: Cédric Le Goater @ 2019-10-02  5:55 UTC (permalink / raw)
  To: David Gibson, qemu-ppc, qemu-devel

On 02/10/2019 07:51, Cédric Le Goater wrote:
> On 02/10/2019 04:51, David Gibson 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>
> 
> Reviewed-by: Greg Kurz <groug@kaod.org>

pfff ...

Reviewed-by: Cédric Le Goater <clg@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] 64+ messages in thread

* Re: [PATCH v3 01/34] xics: Minor fixes for XICSFabric interface
  2019-10-02  5:51   ` Cédric Le Goater
  2019-10-02  5:55     ` Cédric Le Goater
@ 2019-10-02  5:55     ` David Gibson
  2019-10-02  6:56       ` Greg Kurz
  1 sibling, 1 reply; 64+ messages in thread
From: David Gibson @ 2019-10-02  5:55 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, qemu-devel, groug,
	qemu-ppc, Paolo Bonzini, Marc-André Lureau, philmd

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

On Wed, Oct 02, 2019 at 07:51:45AM +0200, Cédric Le Goater wrote:
> On 02/10/2019 04:51, David Gibson 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>
> 
> Reviewed-by: Greg Kurz <groug@kaod.org>

Uhhh... you sent me an R-b line for Greg, not yourself...

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

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

* Re: [PATCH v3 15/34] spapr: Handle freeing of multiple irqs in frontend only
  2019-10-02  2:51 ` [PATCH v3 15/34] spapr: Handle freeing of multiple irqs in frontend only David Gibson
  2019-10-02  5:51   ` Greg Kurz
@ 2019-10-02  5:55   ` Cédric Le Goater
  1 sibling, 0 replies; 64+ messages in thread
From: Cédric Le Goater @ 2019-10-02  5:55 UTC (permalink / raw)
  To: David Gibson, qemu-ppc, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, Paolo Bonzini,
	Marc-André Lureau, philmd

On 02/10/2019 04:51, David Gibson wrote:
> 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>
> ---
>  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..d2ac35bbe1 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, i);
> +    }
>  }
>  
>  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);
> 



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

* Re: [PATCH v3 09/34] spapr: Clarify and fix handling of nr_irqs
  2019-10-02  2:51 ` [PATCH v3 09/34] spapr: Clarify and fix handling of nr_irqs David Gibson
@ 2019-10-02  5:57   ` Cédric Le Goater
  0 siblings, 0 replies; 64+ messages in thread
From: Cédric Le Goater @ 2019-10-02  5:57 UTC (permalink / raw)
  To: David Gibson, qemu-ppc, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, Paolo Bonzini,
	Marc-André Lureau, philmd

On 02/10/2019 04:51, David Gibson 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>
> Reviewed-by: Greg Kurz <groug@kaod.org>

Reviewed-by: Cédric Le Goater <clg@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] 64+ messages in thread

* Re: [PATCH v3 19/34] spapr: Add return value to spapr_irq_check()
  2019-10-02  2:51 ` [PATCH v3 19/34] spapr: Add return value to spapr_irq_check() David Gibson
@ 2019-10-02  5:58   ` Cédric Le Goater
  2019-10-02  6:08   ` Greg Kurz
  1 sibling, 0 replies; 64+ messages in thread
From: Cédric Le Goater @ 2019-10-02  5:58 UTC (permalink / raw)
  To: David Gibson, qemu-ppc, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, Paolo Bonzini,
	Marc-André Lureau, philmd

On 02/10/2019 04:51, David Gibson wrote:
> Explicitly return success or failure, rather than just relying on the
> Error ** parameter.  This makes handling it less verbose in the caller.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>


Reviewed-by: Cédric Le Goater <clg@kaod.org>
> ---
>  hw/ppc/spapr_irq.c | 15 +++++++--------
>  1 file changed, 7 insertions(+), 8 deletions(-)
> 
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index 3ac67ba0c7..0413fbd0a3 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -529,7 +529,7 @@ SpaprIrq spapr_irq_dual = {
>  };
>  
>  
> -static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
> +static int spapr_irq_check(SpaprMachineState *spapr, Error **errp)
>  {
>      MachineState *machine = MACHINE(spapr);
>  
> @@ -545,7 +545,7 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
>           */
>          if (spapr->irq == &spapr_irq_dual) {
>              spapr->irq = &spapr_irq_xics;
> -            return;
> +            return 0;
>          }
>  
>          /*
> @@ -565,7 +565,7 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
>           */
>          if (spapr->irq == &spapr_irq_xive) {
>              error_setg(errp, "XIVE-only machines require a POWER9 CPU");
> -            return;
> +            return -1;
>          }
>      }
>  
> @@ -579,8 +579,10 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
>          machine_kernel_irqchip_required(machine) &&
>          xics_kvm_has_broken_disconnect(spapr)) {
>          error_setg(errp, "KVM is too old to support ic-mode=dual,kernel-irqchip=on");
> -        return;
> +        return -1;
>      }
> +
> +    return 0;
>  }
>  
>  /*
> @@ -589,7 +591,6 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
>  void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>  {
>      MachineState *machine = MACHINE(spapr);
> -    Error *local_err = NULL;
>  
>      if (machine_kernel_irqchip_split(machine)) {
>          error_setg(errp, "kernel_irqchip split mode not supported on pseries");
> @@ -602,9 +603,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>          return;
>      }
>  
> -    spapr_irq_check(spapr, &local_err);
> -    if (local_err) {
> -        error_propagate(errp, local_err);
> +    if (spapr_irq_check(spapr, errp) < 0) {
>          return;
>      }
>  
> 



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

* Re: [PATCH v3 22/34] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController
  2019-10-02  2:51 ` [PATCH v3 22/34] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController David Gibson
@ 2019-10-02  6:06   ` Cédric Le Goater
  2019-10-02  6:10     ` David Gibson
  2019-10-02  6:13     ` Cédric Le Goater
  2019-10-02  7:13   ` Greg Kurz
  2019-10-02  9:41   ` Cédric Le Goater
  2 siblings, 2 replies; 64+ messages in thread
From: Cédric Le Goater @ 2019-10-02  6:06 UTC (permalink / raw)
  To: David Gibson, qemu-ppc, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, Paolo Bonzini,
	Marc-André Lureau, philmd

On 02/10/2019 04:51, 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>
> ---
>  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 | 13 +++++-
>  5 files changed, 79 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 8791dec1ba..9cb2fc71ca 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,
> @@ -527,6 +471,30 @@ static int spapr_irq_check(SpaprMachineState *spapr, Error **errp)
>  /*
>   * sPAPR IRQ frontend routines for devices
>   */
> +#define ALL_INTCS(spapr_) \
> +    { SPAPR_INTC((spapr_)->ics), SPAPR_INTC((spapr_)->xive), }

I would have expected this array to be under the machine.

> +int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
> +                              PowerPCCPU *cpu, Error **errp)
> +{
> +    SpaprInterruptController *intcs[] = ALL_INTCS(spapr);
> +    int i;
> +    int rc;
> +
> +    for (i = 0; i < ARRAY_SIZE(intcs); i++) {

but it would have been difficult to use ARRAY_SIZE. OK then.

> +        SpaprInterruptController *intc = intcs[i];
> +        if (intc) {

Is that test needed ? 

> +            SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
> +            rc = sicc->cpu_intc_create(intc, cpu, errp);
> +            if (rc < 0) {
> +                return rc;
> +            }
> +        }
> +    }
> +
> +    return 0;
> +}
> +
>  void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>  {
>      MachineState *machine = MACHINE(spapr);
> @@ -762,7 +730,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..5e641e23c1 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -43,8 +43,19 @@ 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;
>  
> +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 +72,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] 64+ messages in thread

* Re: [PATCH v3 19/34] spapr: Add return value to spapr_irq_check()
  2019-10-02  2:51 ` [PATCH v3 19/34] spapr: Add return value to spapr_irq_check() David Gibson
  2019-10-02  5:58   ` Cédric Le Goater
@ 2019-10-02  6:08   ` Greg Kurz
  1 sibling, 0 replies; 64+ messages in thread
From: Greg Kurz @ 2019-10-02  6:08 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Paolo Bonzini, Marc-André Lureau, philmd

On Wed,  2 Oct 2019 12:51:53 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> Explicitly return success or failure, rather than just relying on the
> Error ** parameter.  This makes handling it less verbose in the caller.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---

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

>  hw/ppc/spapr_irq.c | 15 +++++++--------
>  1 file changed, 7 insertions(+), 8 deletions(-)
> 
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index 3ac67ba0c7..0413fbd0a3 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -529,7 +529,7 @@ SpaprIrq spapr_irq_dual = {
>  };
>  
>  
> -static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
> +static int spapr_irq_check(SpaprMachineState *spapr, Error **errp)
>  {
>      MachineState *machine = MACHINE(spapr);
>  
> @@ -545,7 +545,7 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
>           */
>          if (spapr->irq == &spapr_irq_dual) {
>              spapr->irq = &spapr_irq_xics;
> -            return;
> +            return 0;
>          }
>  
>          /*
> @@ -565,7 +565,7 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
>           */
>          if (spapr->irq == &spapr_irq_xive) {
>              error_setg(errp, "XIVE-only machines require a POWER9 CPU");
> -            return;
> +            return -1;
>          }
>      }
>  
> @@ -579,8 +579,10 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
>          machine_kernel_irqchip_required(machine) &&
>          xics_kvm_has_broken_disconnect(spapr)) {
>          error_setg(errp, "KVM is too old to support ic-mode=dual,kernel-irqchip=on");
> -        return;
> +        return -1;
>      }
> +
> +    return 0;
>  }
>  
>  /*
> @@ -589,7 +591,6 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
>  void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>  {
>      MachineState *machine = MACHINE(spapr);
> -    Error *local_err = NULL;
>  
>      if (machine_kernel_irqchip_split(machine)) {
>          error_setg(errp, "kernel_irqchip split mode not supported on pseries");
> @@ -602,9 +603,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>          return;
>      }
>  
> -    spapr_irq_check(spapr, &local_err);
> -    if (local_err) {
> -        error_propagate(errp, local_err);
> +    if (spapr_irq_check(spapr, errp) < 0) {
>          return;
>      }
>  



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

* Re: [PATCH v3 22/34] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController
  2019-10-02  6:06   ` Cédric Le Goater
@ 2019-10-02  6:10     ` David Gibson
  2019-10-02  6:13     ` Cédric Le Goater
  1 sibling, 0 replies; 64+ messages in thread
From: David Gibson @ 2019-10-02  6:10 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, qemu-devel, groug,
	qemu-ppc, Paolo Bonzini, Marc-André Lureau, philmd

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

On Wed, Oct 02, 2019 at 08:06:59AM +0200, Cédric Le Goater wrote:
> On 02/10/2019 04:51, 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>
> > ---
> >  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 | 13 +++++-
> >  5 files changed, 79 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 8791dec1ba..9cb2fc71ca 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,
> > @@ -527,6 +471,30 @@ static int spapr_irq_check(SpaprMachineState *spapr, Error **errp)
> >  /*
> >   * sPAPR IRQ frontend routines for devices
> >   */
> > +#define ALL_INTCS(spapr_) \
> > +    { SPAPR_INTC((spapr_)->ics), SPAPR_INTC((spapr_)->xive), }
> 
> I would have expected this array to be under the machine.
> 
> > +int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
> > +                              PowerPCCPU *cpu, Error **errp)
> > +{
> > +    SpaprInterruptController *intcs[] = ALL_INTCS(spapr);
> > +    int i;
> > +    int rc;
> > +
> > +    for (i = 0; i < ARRAY_SIZE(intcs); i++) {
> 
> but it would have been difficult to use ARRAY_SIZE. OK then.

Right.  It's kind of a compromise, to keep it as separate (and
differently typed) pointers in the machine for now.

> > +        SpaprInterruptController *intc = intcs[i];
> > +        if (intc) {
> 
> Is that test needed ?

Yes.  The array always has two elements even in xics only or xive only
modes, but in those cases one of the entries is NULL.

> 
> > +            SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
> > +            rc = sicc->cpu_intc_create(intc, cpu, errp);
> > +            if (rc < 0) {
> > +                return rc;
> > +            }
> > +        }
> > +    }
> > +
> > +    return 0;
> > +}
> > +
> >  void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
> >  {
> >      MachineState *machine = MACHINE(spapr);
> > @@ -762,7 +730,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..5e641e23c1 100644
> > --- a/include/hw/ppc/spapr_irq.h
> > +++ b/include/hw/ppc/spapr_irq.h
> > @@ -43,8 +43,19 @@ 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;
> >  
> > +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 +72,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] 64+ messages in thread

* Re: [PATCH v3 23/34] spapr, xics, xive: Move irq claim and free from SpaprIrq to SpaprInterruptController
  2019-10-02  2:51 ` [PATCH v3 23/34] spapr, xics, xive: Move irq claim and free " David Gibson
@ 2019-10-02  6:10   ` Cédric Le Goater
  2019-10-02  6:16     ` David Gibson
  2019-10-02  7:59   ` Greg Kurz
  2019-10-02  9:23   ` Cédric Le Goater
  2 siblings, 1 reply; 64+ messages in thread
From: Cédric Le Goater @ 2019-10-02  6:10 UTC (permalink / raw)
  To: David Gibson, qemu-ppc, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, Paolo Bonzini,
	Marc-André Lureau, philmd

On 02/10/2019 04:51, 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          | 110 +++++++++++-------------------------
>  include/hw/ppc/spapr_irq.h  |   5 +-
>  include/hw/ppc/spapr_xive.h |   2 -
>  5 files changed, 102 insertions(+), 115 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 9cb2fc71ca..83882cfad3 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,
> @@ -572,8 +501,11 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>  
>          /* Enable the CPU IPIs */
>          for (i = 0; i < nr_servers; ++i) {
> -            if (spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i,
> -                                     false, errp) < 0) {
> +            SpaprInterruptControllerClass *sicc
> +                = SPAPR_INTC_GET_CLASS(spapr->xive);
> +
> +            if (sicc->claim_irq(SPAPR_INTC(spapr->xive), SPAPR_IRQ_IPI + i,
> +                                false, errp) < 0) {


This should be called for Xive only. Why is this using the class handler ? 

>                  return;
>              }
>          }
> @@ -587,21 +519,45 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>  
>  int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
>  {
> +    SpaprInterruptController *intcs[] = ALL_INTCS(spapr);
> +    int i;
> +    int rc;
> +
>      assert(irq >= SPAPR_XIRQ_BASE);
>      assert(irq < (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
>  
> -    return spapr->irq->claim(spapr, irq, lsi, errp);
> +    for (i = 0; i < ARRAY_SIZE(intcs); i++) {
> +        SpaprInterruptController *intc = intcs[i];
> +        if (intc) {
> +            SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
> +            rc = sicc->claim_irq(intc, irq, lsi, errp);
> +            if (rc < 0) {
> +                return rc;
> +            }
> +        }
> +    }
> +
> +    return 0;
>  }
>  
>  void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
>  {
> -    int i;
> +    SpaprInterruptController *intcs[] = ALL_INTCS(spapr);
> +    int i, j;
>  
>      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, i);
> +        for (j = 0; j < ARRAY_SIZE(intcs); j++) {
> +            SpaprInterruptController *intc = intcs[j];
> +
> +            if (intc) {
> +                SpaprInterruptControllerClass *sicc
> +                    = SPAPR_INTC_GET_CLASS(intc);
> +                sicc->free_irq(intc, i);
> +            }
> +        }
>      }
>  }
>  
> @@ -726,8 +682,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 5e641e23c1..adfef0fcbe 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;
>  
>  int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
> @@ -67,8 +70,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] 64+ messages in thread

* Re: [PATCH v3 22/34] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController
  2019-10-02  6:06   ` Cédric Le Goater
  2019-10-02  6:10     ` David Gibson
@ 2019-10-02  6:13     ` Cédric Le Goater
  2019-10-02  6:40       ` David Gibson
  1 sibling, 1 reply; 64+ messages in thread
From: Cédric Le Goater @ 2019-10-02  6:13 UTC (permalink / raw)
  To: David Gibson, qemu-ppc, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, Paolo Bonzini,
	Marc-André Lureau, philmd

>> @@ -527,6 +471,30 @@ static int spapr_irq_check(SpaprMachineState *spapr, Error **errp)
>>  /*
>>   * sPAPR IRQ frontend routines for devices
>>   */
>> +#define ALL_INTCS(spapr_) \
>> +    { SPAPR_INTC((spapr_)->ics), SPAPR_INTC((spapr_)->xive), }
> 
> I would have expected this array to be under the machine.
> 
>> +int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
>> +                              PowerPCCPU *cpu, Error **errp)
>> +{
>> +    SpaprInterruptController *intcs[] = ALL_INTCS(spapr);
>> +    int i;
>> +    int rc;
>> +
>> +    for (i = 0; i < ARRAY_SIZE(intcs); i++) {
> 
> but it would have been difficult to use ARRAY_SIZE. OK then.
> 
>> +        SpaprInterruptController *intc = intcs[i];
>> +        if (intc) {
> 
> Is that test needed ? 

I understand now : spapr->ics and spapr->xive can be NULL. 

I think using a list would be better. 

C.






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

* Re: [PATCH v3 23/34] spapr, xics, xive: Move irq claim and free from SpaprIrq to SpaprInterruptController
  2019-10-02  6:10   ` Cédric Le Goater
@ 2019-10-02  6:16     ` David Gibson
  0 siblings, 0 replies; 64+ messages in thread
From: David Gibson @ 2019-10-02  6:16 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, qemu-devel, groug,
	qemu-ppc, Paolo Bonzini, Marc-André Lureau, philmd

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

On Wed, Oct 02, 2019 at 08:10:33AM +0200, Cédric Le Goater wrote:
> On 02/10/2019 04:51, 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          | 110 +++++++++++-------------------------
> >  include/hw/ppc/spapr_irq.h  |   5 +-
> >  include/hw/ppc/spapr_xive.h |   2 -
> >  5 files changed, 102 insertions(+), 115 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 9cb2fc71ca..83882cfad3 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,
> > @@ -572,8 +501,11 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
> >  
> >          /* Enable the CPU IPIs */
> >          for (i = 0; i < nr_servers; ++i) {
> > -            if (spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i,
> > -                                     false, errp) < 0) {
> > +            SpaprInterruptControllerClass *sicc
> > +                = SPAPR_INTC_GET_CLASS(spapr->xive);
> > +
> > +            if (sicc->claim_irq(SPAPR_INTC(spapr->xive), SPAPR_IRQ_IPI + i,
> > +                                false, errp) < 0) {
> 
> 
> This should be called for Xive only. Why is this using the class
> handler ?

Only to avoid adding another exported function to the headers, when
it's already indirectly exposed via the hook.

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

* Re: [PATCH v3 22/34] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController
  2019-10-02  6:13     ` Cédric Le Goater
@ 2019-10-02  6:40       ` David Gibson
  2019-10-02  7:31         ` Cédric Le Goater
  0 siblings, 1 reply; 64+ messages in thread
From: David Gibson @ 2019-10-02  6:40 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, qemu-devel, groug,
	qemu-ppc, Paolo Bonzini, Marc-André Lureau, philmd

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

On Wed, Oct 02, 2019 at 08:13:55AM +0200, Cédric Le Goater wrote:
> >> @@ -527,6 +471,30 @@ static int spapr_irq_check(SpaprMachineState *spapr, Error **errp)
> >>  /*
> >>   * sPAPR IRQ frontend routines for devices
> >>   */
> >> +#define ALL_INTCS(spapr_) \
> >> +    { SPAPR_INTC((spapr_)->ics), SPAPR_INTC((spapr_)->xive), }
> > 
> > I would have expected this array to be under the machine.
> > 
> >> +int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
> >> +                              PowerPCCPU *cpu, Error **errp)
> >> +{
> >> +    SpaprInterruptController *intcs[] = ALL_INTCS(spapr);
> >> +    int i;
> >> +    int rc;
> >> +
> >> +    for (i = 0; i < ARRAY_SIZE(intcs); i++) {
> > 
> > but it would have been difficult to use ARRAY_SIZE. OK then.
> > 
> >> +        SpaprInterruptController *intc = intcs[i];
> >> +        if (intc) {
> > 
> > Is that test needed ? 
> 
> I understand now : spapr->ics and spapr->xive can be NULL. 
> 
> I think using a list would be better.

Uh.. a list in what sense?

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

* Re: [PATCH v3 01/34] xics: Minor fixes for XICSFabric interface
  2019-10-02  5:55     ` David Gibson
@ 2019-10-02  6:56       ` Greg Kurz
  0 siblings, 0 replies; 64+ messages in thread
From: Greg Kurz @ 2019-10-02  6:56 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	Cédric Le Goater, Paolo Bonzini, Marc-André Lureau,
	philmd

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

On Wed, 2 Oct 2019 15:55:51 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> On Wed, Oct 02, 2019 at 07:51:45AM +0200, Cédric Le Goater wrote:
> > On 02/10/2019 04:51, David Gibson 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>
> > 
> > Reviewed-by: Greg Kurz <groug@kaod.org>
> 
> Uhhh... you sent me an R-b line for Greg, not yourself...
> 

Heh it's because people confuse our names so often that we don't
really know where we stand now.

--
Cedric ;-)

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


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

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

* Re: [PATCH v3 22/34] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController
  2019-10-02  2:51 ` [PATCH v3 22/34] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController David Gibson
  2019-10-02  6:06   ` Cédric Le Goater
@ 2019-10-02  7:13   ` Greg Kurz
  2019-10-02  9:41   ` Cédric Le Goater
  2 siblings, 0 replies; 64+ messages in thread
From: Greg Kurz @ 2019-10-02  7:13 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Paolo Bonzini, Marc-André Lureau, philmd

On Wed,  2 Oct 2019 12:51:56 +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>
> ---

Reviewed-by: Greg Kurz <groug@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 | 13 +++++-
>  5 files changed, 79 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 8791dec1ba..9cb2fc71ca 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,
> @@ -527,6 +471,30 @@ static int spapr_irq_check(SpaprMachineState *spapr, Error **errp)
>  /*
>   * sPAPR IRQ frontend routines for devices
>   */
> +#define ALL_INTCS(spapr_) \
> +    { SPAPR_INTC((spapr_)->ics), SPAPR_INTC((spapr_)->xive), }
> +
> +int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
> +                              PowerPCCPU *cpu, Error **errp)
> +{
> +    SpaprInterruptController *intcs[] = ALL_INTCS(spapr);
> +    int i;
> +    int rc;
> +
> +    for (i = 0; i < ARRAY_SIZE(intcs); i++) {
> +        SpaprInterruptController *intc = intcs[i];
> +        if (intc) {
> +            SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
> +            rc = sicc->cpu_intc_create(intc, cpu, errp);
> +            if (rc < 0) {
> +                return rc;
> +            }
> +        }
> +    }
> +
> +    return 0;
> +}
> +
>  void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>  {
>      MachineState *machine = MACHINE(spapr);
> @@ -762,7 +730,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..5e641e23c1 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -43,8 +43,19 @@ 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;
>  
> +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 +72,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] 64+ messages in thread

* Re: [PATCH v3 22/34] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController
  2019-10-02  6:40       ` David Gibson
@ 2019-10-02  7:31         ` Cédric Le Goater
  2019-10-02 22:28           ` David Gibson
  0 siblings, 1 reply; 64+ messages in thread
From: Cédric Le Goater @ 2019-10-02  7:31 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, qemu-devel, groug,
	qemu-ppc, Paolo Bonzini, Marc-André Lureau, philmd

On 02/10/2019 08:40, David Gibson wrote:
> On Wed, Oct 02, 2019 at 08:13:55AM +0200, Cédric Le Goater wrote:
>>>> @@ -527,6 +471,30 @@ static int spapr_irq_check(SpaprMachineState *spapr, Error **errp)
>>>>  /*
>>>>   * sPAPR IRQ frontend routines for devices
>>>>   */
>>>> +#define ALL_INTCS(spapr_) \
>>>> +    { SPAPR_INTC((spapr_)->ics), SPAPR_INTC((spapr_)->xive), }
>>>
>>> I would have expected this array to be under the machine.
>>>
>>>> +int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
>>>> +                              PowerPCCPU *cpu, Error **errp)
>>>> +{
>>>> +    SpaprInterruptController *intcs[] = ALL_INTCS(spapr);
>>>> +    int i;
>>>> +    int rc;
>>>> +
>>>> +    for (i = 0; i < ARRAY_SIZE(intcs); i++) {
>>>
>>> but it would have been difficult to use ARRAY_SIZE. OK then.
>>>
>>>> +        SpaprInterruptController *intc = intcs[i];
>>>> +        if (intc) {
>>>
>>> Is that test needed ? 
>>
>> I understand now : spapr->ics and spapr->xive can be NULL. 
>>
>> I think using a list would be better.
> 
> Uh.. a list in what sense?

an interrupt controller list under the machine. 

when created, an interrupt controller would self register in that list.

C.


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

* Re: [PATCH v3 23/34] spapr, xics, xive: Move irq claim and free from SpaprIrq to SpaprInterruptController
  2019-10-02  2:51 ` [PATCH v3 23/34] spapr, xics, xive: Move irq claim and free " David Gibson
  2019-10-02  6:10   ` Cédric Le Goater
@ 2019-10-02  7:59   ` Greg Kurz
  2019-10-02 22:17     ` David Gibson
  2019-10-02  9:23   ` Cédric Le Goater
  2 siblings, 1 reply; 64+ messages in thread
From: Greg Kurz @ 2019-10-02  7:59 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Paolo Bonzini, Marc-André Lureau, philmd

On Wed,  2 Oct 2019 12:51:57 +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          | 110 +++++++++++-------------------------
>  include/hw/ppc/spapr_irq.h  |   5 +-
>  include/hw/ppc/spapr_xive.h |   2 -
>  5 files changed, 102 insertions(+), 115 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;

I guess it makes more sense to return -EBUSY rather than -1 indeed,
and it doesn't break anything.

> +    }
> +
> +    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 9cb2fc71ca..83882cfad3 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,
> @@ -572,8 +501,11 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>  
>          /* Enable the CPU IPIs */
>          for (i = 0; i < nr_servers; ++i) {
> -            if (spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i,
> -                                     false, errp) < 0) {
> +            SpaprInterruptControllerClass *sicc
> +                = SPAPR_INTC_GET_CLASS(spapr->xive);
> +
> +            if (sicc->claim_irq(SPAPR_INTC(spapr->xive), SPAPR_IRQ_IPI + i,
> +                                false, errp) < 0) {
>                  return;
>              }
>          }
> @@ -587,21 +519,45 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>  
>  int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
>  {
> +    SpaprInterruptController *intcs[] = ALL_INTCS(spapr);
> +    int i;
> +    int rc;
> +
>      assert(irq >= SPAPR_XIRQ_BASE);
>      assert(irq < (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
>  
> -    return spapr->irq->claim(spapr, irq, lsi, errp);
> +    for (i = 0; i < ARRAY_SIZE(intcs); i++) {
> +        SpaprInterruptController *intc = intcs[i];
> +        if (intc) {
> +            SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
> +            rc = sicc->claim_irq(intc, irq, lsi, errp);
> +            if (rc < 0) {
> +                return rc;
> +            }
> +        }
> +    }
> +
> +    return 0;
>  }
>  
>  void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
>  {
> -    int i;
> +    SpaprInterruptController *intcs[] = ALL_INTCS(spapr);
> +    int i, j;
>  
>      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, i);
> +        for (j = 0; j < ARRAY_SIZE(intcs); j++) {
> +            SpaprInterruptController *intc = intcs[j];
> +
> +            if (intc) {
> +                SpaprInterruptControllerClass *sicc
> +                    = SPAPR_INTC_GET_CLASS(intc);
> +                sicc->free_irq(intc, i);
> +            }
> +        }

Yet another intcs[] boiler plate. I'm wondering if this could go
into a macro. Anyway, this could be looked at later. This series
is large enough already :)

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

>      }
>  }
>  
> @@ -726,8 +682,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 5e641e23c1..adfef0fcbe 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;
>  
>  int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
> @@ -67,8 +70,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] 64+ messages in thread

* Re: [PATCH v3 23/34] spapr, xics, xive: Move irq claim and free from SpaprIrq to SpaprInterruptController
  2019-10-02  2:51 ` [PATCH v3 23/34] spapr, xics, xive: Move irq claim and free " David Gibson
  2019-10-02  6:10   ` Cédric Le Goater
  2019-10-02  7:59   ` Greg Kurz
@ 2019-10-02  9:23   ` Cédric Le Goater
  2 siblings, 0 replies; 64+ messages in thread
From: Cédric Le Goater @ 2019-10-02  9:23 UTC (permalink / raw)
  To: David Gibson, qemu-ppc, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, Paolo Bonzini,
	Marc-André Lureau, philmd

On 02/10/2019 04:51, 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>


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

> ---
>  hw/intc/spapr_xive.c        |  71 ++++++++++++-----------
>  hw/intc/xics_spapr.c        |  29 ++++++++++
>  hw/ppc/spapr_irq.c          | 110 +++++++++++-------------------------
>  include/hw/ppc/spapr_irq.h  |   5 +-
>  include/hw/ppc/spapr_xive.h |   2 -
>  5 files changed, 102 insertions(+), 115 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 9cb2fc71ca..83882cfad3 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,
> @@ -572,8 +501,11 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>  
>          /* Enable the CPU IPIs */
>          for (i = 0; i < nr_servers; ++i) {
> -            if (spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i,
> -                                     false, errp) < 0) {
> +            SpaprInterruptControllerClass *sicc
> +                = SPAPR_INTC_GET_CLASS(spapr->xive);
> +
> +            if (sicc->claim_irq(SPAPR_INTC(spapr->xive), SPAPR_IRQ_IPI + i,
> +                                false, errp) < 0) {
>                  return;
>              }
>          }
> @@ -587,21 +519,45 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>  
>  int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
>  {
> +    SpaprInterruptController *intcs[] = ALL_INTCS(spapr);
> +    int i;
> +    int rc;
> +
>      assert(irq >= SPAPR_XIRQ_BASE);
>      assert(irq < (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
>  
> -    return spapr->irq->claim(spapr, irq, lsi, errp);
> +    for (i = 0; i < ARRAY_SIZE(intcs); i++) {
> +        SpaprInterruptController *intc = intcs[i];
> +        if (intc) {
> +            SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
> +            rc = sicc->claim_irq(intc, irq, lsi, errp);
> +            if (rc < 0) {
> +                return rc;
> +            }
> +        }
> +    }
> +
> +    return 0;
>  }
>  
>  void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
>  {
> -    int i;
> +    SpaprInterruptController *intcs[] = ALL_INTCS(spapr);
> +    int i, j;
>  
>      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, i);
> +        for (j = 0; j < ARRAY_SIZE(intcs); j++) {
> +            SpaprInterruptController *intc = intcs[j];
> +
> +            if (intc) {
> +                SpaprInterruptControllerClass *sicc
> +                    = SPAPR_INTC_GET_CLASS(intc);
> +                sicc->free_irq(intc, i);
> +            }
> +        }
>      }
>  }
>  
> @@ -726,8 +682,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 5e641e23c1..adfef0fcbe 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;
>  
>  int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
> @@ -67,8 +70,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] 64+ messages in thread

* Re: [PATCH v3 30/34] spapr, xics, xive: Move SpaprIrq::reset hook logic into activate/deactivate
  2019-10-02  2:52 ` [PATCH v3 30/34] spapr, xics, xive: Move SpaprIrq::reset hook logic into activate/deactivate David Gibson
@ 2019-10-02  9:29   ` Greg Kurz
  2019-10-03  0:22     ` David Gibson
  0 siblings, 1 reply; 64+ messages in thread
From: Greg Kurz @ 2019-10-02  9:29 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Paolo Bonzini, Marc-André Lureau, philmd

On Wed,  2 Oct 2019 12:52:04 +1000
David Gibson <david@gibson.dropbear.id.au> 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.
> 
> 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);
> +    }
> +

I think this ^^ can go...

> +    if (kvm_enabled()) {
> +        if (spapr_irq_init_kvm(kvmppc_xive_connect, intc, errp) < 0) {
> +            return;
> +        }
> +    }
> +

... here. If which case, spapr_irq_init_kvm() could be called from
set_active_intc() instead of being called by each backend if I get
it right. This would avoid the frontend->backend->frontend flow.

> +    /* 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 7cd18e5b15..f70b331f44 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,
>  };
>  
>  
> @@ -512,10 +456,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)
> @@ -651,7 +591,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 a5fdb963a8..1aff1c2eb7 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] 64+ messages in thread

* Re: [PATCH v3 22/34] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController
  2019-10-02  2:51 ` [PATCH v3 22/34] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController David Gibson
  2019-10-02  6:06   ` Cédric Le Goater
  2019-10-02  7:13   ` Greg Kurz
@ 2019-10-02  9:41   ` Cédric Le Goater
  2 siblings, 0 replies; 64+ messages in thread
From: Cédric Le Goater @ 2019-10-02  9:41 UTC (permalink / raw)
  To: David Gibson, qemu-ppc, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, Paolo Bonzini,
	Marc-André Lureau, philmd

On 02/10/2019 04:51, 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>

I am not very fond of the ALL_INTCS() macro but this can be reworked
when P10 is introduced.


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

C. 

> ---
>  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 | 13 +++++-
>  5 files changed, 79 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 8791dec1ba..9cb2fc71ca 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,
> @@ -527,6 +471,30 @@ static int spapr_irq_check(SpaprMachineState *spapr, Error **errp)
>  /*
>   * sPAPR IRQ frontend routines for devices
>   */
> +#define ALL_INTCS(spapr_) \
> +    { SPAPR_INTC((spapr_)->ics), SPAPR_INTC((spapr_)->xive), }
> +
> +int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
> +                              PowerPCCPU *cpu, Error **errp)
> +{
> +    SpaprInterruptController *intcs[] = ALL_INTCS(spapr);
> +    int i;
> +    int rc;
> +
> +    for (i = 0; i < ARRAY_SIZE(intcs); i++) {
> +        SpaprInterruptController *intc = intcs[i];
> +        if (intc) {
> +            SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
> +            rc = sicc->cpu_intc_create(intc, cpu, errp);
> +            if (rc < 0) {
> +                return rc;
> +            }
> +        }
> +    }
> +
> +    return 0;
> +}
> +
>  void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>  {
>      MachineState *machine = MACHINE(spapr);
> @@ -762,7 +730,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..5e641e23c1 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -43,8 +43,19 @@ 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;
>  
> +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 +72,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] 64+ messages in thread

* Re: [PATCH v3 31/34] spapr, xics, xive: Move SpaprIrq::post_load hook to backends
  2019-10-02  2:52 ` [PATCH v3 31/34] spapr, xics, xive: Move SpaprIrq::post_load hook to backends David Gibson
@ 2019-10-02  9:50   ` Greg Kurz
  0 siblings, 0 replies; 64+ messages in thread
From: Greg Kurz @ 2019-10-02  9:50 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Paolo Bonzini, Marc-André Lureau, philmd

On Wed,  2 Oct 2019 12:52:05 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

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

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

>  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 f70b331f44..f3d18b1dad 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,
>  };
>  
>  
> @@ -447,8 +409,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)
> @@ -589,8 +554,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 1aff1c2eb7..4c2cd091da 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);



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

* Re: [PATCH v3 34/34] spapr: Remove last pieces of SpaprIrq
  2019-10-02  2:52 ` [PATCH v3 34/34] spapr: Remove last pieces of SpaprIrq David Gibson
@ 2019-10-02 10:20   ` Greg Kurz
  2019-10-02 22:31     ` David Gibson
  0 siblings, 1 reply; 64+ messages in thread
From: Greg Kurz @ 2019-10-02 10:20 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Paolo Bonzini, Marc-André Lureau, philmd

On Wed,  2 Oct 2019 12:52:08 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

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

This needs some more care. Incoming migration of older existing machine
types breaks:

qemu-system-ppc64: cap-xics higher level (1) in incoming stream than on destination (0)
qemu-system-ppc64: error while loading state for instance 0x0 of device 'spapr'
qemu-system-ppc64: load of migration failed: Invalid argument

>  hw/ppc/spapr.c             | 38 +++++++++--------
>  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, 99 insertions(+), 112 deletions(-)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index e1ff03152e..b9ac01d90c 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -1072,12 +1072,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;
>      }
>  
> @@ -2775,7 +2776,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);
>      }
>  
> @@ -3242,14 +3243,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();
> @@ -3266,11 +3271,14 @@ 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;
> +        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");
>      }
> @@ -3309,7 +3317,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;
> @@ -3345,7 +3352,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",
> @@ -4439,8 +4445,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;
> @@ -4539,7 +4546,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;
>  }
>  
> @@ -4580,7 +4587,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 2768f9a765..473fc8780a 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 int 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 0;
> -        }
> -
> -        /*
> -         * 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 -1;
> -        }
> -    }
> -
>      /*
>       * 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 -1;
> @@ -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)) {
>          Error *local_err = NULL;
>          Object *obj;
>  
> @@ -313,7 +242,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;
> @@ -558,11 +487,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 50491cea4f..4b58134701 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -77,16 +77,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);



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

* Re: [PATCH v3 23/34] spapr, xics, xive: Move irq claim and free from SpaprIrq to SpaprInterruptController
  2019-10-02  7:59   ` Greg Kurz
@ 2019-10-02 22:17     ` David Gibson
  0 siblings, 0 replies; 64+ messages in thread
From: David Gibson @ 2019-10-02 22:17 UTC (permalink / raw)
  To: Greg Kurz
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Paolo Bonzini, Marc-André Lureau, philmd

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

On Wed, Oct 02, 2019 at 09:59:25AM +0200, Greg Kurz wrote:
> On Wed,  2 Oct 2019 12:51:57 +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          | 110 +++++++++++-------------------------
> >  include/hw/ppc/spapr_irq.h  |   5 +-
> >  include/hw/ppc/spapr_xive.h |   2 -
> >  5 files changed, 102 insertions(+), 115 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;
> 
> I guess it makes more sense to return -EBUSY rather than -1 indeed,
> and it doesn't break anything.
> 
> > +    }
> > +
> > +    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 9cb2fc71ca..83882cfad3 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,
> > @@ -572,8 +501,11 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
> >  
> >          /* Enable the CPU IPIs */
> >          for (i = 0; i < nr_servers; ++i) {
> > -            if (spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i,
> > -                                     false, errp) < 0) {
> > +            SpaprInterruptControllerClass *sicc
> > +                = SPAPR_INTC_GET_CLASS(spapr->xive);
> > +
> > +            if (sicc->claim_irq(SPAPR_INTC(spapr->xive), SPAPR_IRQ_IPI + i,
> > +                                false, errp) < 0) {
> >                  return;
> >              }
> >          }
> > @@ -587,21 +519,45 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
> >  
> >  int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
> >  {
> > +    SpaprInterruptController *intcs[] = ALL_INTCS(spapr);
> > +    int i;
> > +    int rc;
> > +
> >      assert(irq >= SPAPR_XIRQ_BASE);
> >      assert(irq < (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
> >  
> > -    return spapr->irq->claim(spapr, irq, lsi, errp);
> > +    for (i = 0; i < ARRAY_SIZE(intcs); i++) {
> > +        SpaprInterruptController *intc = intcs[i];
> > +        if (intc) {
> > +            SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
> > +            rc = sicc->claim_irq(intc, irq, lsi, errp);
> > +            if (rc < 0) {
> > +                return rc;
> > +            }
> > +        }
> > +    }
> > +
> > +    return 0;
> >  }
> >  
> >  void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
> >  {
> > -    int i;
> > +    SpaprInterruptController *intcs[] = ALL_INTCS(spapr);
> > +    int i, j;
> >  
> >      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, i);
> > +        for (j = 0; j < ARRAY_SIZE(intcs); j++) {
> > +            SpaprInterruptController *intc = intcs[j];
> > +
> > +            if (intc) {
> > +                SpaprInterruptControllerClass *sicc
> > +                    = SPAPR_INTC_GET_CLASS(intc);
> > +                sicc->free_irq(intc, i);
> > +            }
> > +        }
> 
> Yet another intcs[] boiler plate. I'm wondering if this could go
> into a macro. Anyway, this could be looked at later. This series
> is large enough already :)

I couldn't think of a way that didn't have really awkward syntax.

> 
> Reviewed-by: Greg Kurz <groug@kaod.org>
> 
> >      }
> >  }
> >  
> > @@ -726,8 +682,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 5e641e23c1..adfef0fcbe 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;
> >  
> >  int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
> > @@ -67,8 +70,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] 64+ messages in thread

* Re: [PATCH v3 22/34] spapr, xics, xive: Move cpu_intc_create from SpaprIrq to SpaprInterruptController
  2019-10-02  7:31         ` Cédric Le Goater
@ 2019-10-02 22:28           ` David Gibson
  0 siblings, 0 replies; 64+ messages in thread
From: David Gibson @ 2019-10-02 22:28 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, qemu-devel, groug,
	qemu-ppc, Paolo Bonzini, Marc-André Lureau, philmd

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

On Wed, Oct 02, 2019 at 09:31:08AM +0200, Cédric Le Goater wrote:
> On 02/10/2019 08:40, David Gibson wrote:
> > On Wed, Oct 02, 2019 at 08:13:55AM +0200, Cédric Le Goater wrote:
> >>>> @@ -527,6 +471,30 @@ static int spapr_irq_check(SpaprMachineState *spapr, Error **errp)
> >>>>  /*
> >>>>   * sPAPR IRQ frontend routines for devices
> >>>>   */
> >>>> +#define ALL_INTCS(spapr_) \
> >>>> +    { SPAPR_INTC((spapr_)->ics), SPAPR_INTC((spapr_)->xive), }
> >>>
> >>> I would have expected this array to be under the machine.
> >>>
> >>>> +int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
> >>>> +                              PowerPCCPU *cpu, Error **errp)
> >>>> +{
> >>>> +    SpaprInterruptController *intcs[] = ALL_INTCS(spapr);
> >>>> +    int i;
> >>>> +    int rc;
> >>>> +
> >>>> +    for (i = 0; i < ARRAY_SIZE(intcs); i++) {
> >>>
> >>> but it would have been difficult to use ARRAY_SIZE. OK then.
> >>>
> >>>> +        SpaprInterruptController *intc = intcs[i];
> >>>> +        if (intc) {
> >>>
> >>> Is that test needed ? 
> >>
> >> I understand now : spapr->ics and spapr->xive can be NULL. 
> >>
> >> I think using a list would be better.
> > 
> > Uh.. a list in what sense?
> 
> an interrupt controller list under the machine.


Well

a) You're the one who suggested not dropping the ics and xive
individual pointers, which would be redundant with such a list.

b) A linked list for 2 entries seems overly complicated.

> 
> when created, an interrupt controller would self register in that list.
> 
> 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] 64+ messages in thread

* Re: [PATCH v3 34/34] spapr: Remove last pieces of SpaprIrq
  2019-10-02 10:20   ` Greg Kurz
@ 2019-10-02 22:31     ` David Gibson
  2019-10-03  5:19       ` David Gibson
  0 siblings, 1 reply; 64+ messages in thread
From: David Gibson @ 2019-10-02 22:31 UTC (permalink / raw)
  To: Greg Kurz
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Paolo Bonzini, Marc-André Lureau, philmd

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

On Wed, Oct 02, 2019 at 12:20:35PM +0200, Greg Kurz wrote:
> On Wed,  2 Oct 2019 12:52:08 +1000
> David Gibson <david@gibson.dropbear.id.au> wrote:
> 
> > 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>
> > ---
> 
> This needs some more care. Incoming migration of older existing machine
> types breaks:
> 
> qemu-system-ppc64: cap-xics higher level (1) in incoming stream than on destination (0)
> qemu-system-ppc64: error while loading state for instance 0x0 of device 'spapr'
> qemu-system-ppc64: load of migration failed: Invalid argument

Ah, right, thanks for testing that.  What machine type exactly was broken?

> 
> >  hw/ppc/spapr.c             | 38 +++++++++--------
> >  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, 99 insertions(+), 112 deletions(-)
> > 
> > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> > index e1ff03152e..b9ac01d90c 100644
> > --- a/hw/ppc/spapr.c
> > +++ b/hw/ppc/spapr.c
> > @@ -1072,12 +1072,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;
> >      }
> >  
> > @@ -2775,7 +2776,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);
> >      }
> >  
> > @@ -3242,14 +3243,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();
> > @@ -3266,11 +3271,14 @@ 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;
> > +        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");
> >      }
> > @@ -3309,7 +3317,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;
> > @@ -3345,7 +3352,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",
> > @@ -4439,8 +4445,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;
> > @@ -4539,7 +4546,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;
> >  }
> >  
> > @@ -4580,7 +4587,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 2768f9a765..473fc8780a 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 int 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 0;
> > -        }
> > -
> > -        /*
> > -         * 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 -1;
> > -        }
> > -    }
> > -
> >      /*
> >       * 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 -1;
> > @@ -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)) {
> >          Error *local_err = NULL;
> >          Object *obj;
> >  
> > @@ -313,7 +242,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;
> > @@ -558,11 +487,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 50491cea4f..4b58134701 100644
> > --- a/include/hw/ppc/spapr_irq.h
> > +++ b/include/hw/ppc/spapr_irq.h
> > @@ -77,16 +77,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);
> 

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

* Re: [PATCH v3 30/34] spapr, xics, xive: Move SpaprIrq::reset hook logic into activate/deactivate
  2019-10-02  9:29   ` Greg Kurz
@ 2019-10-03  0:22     ` David Gibson
  0 siblings, 0 replies; 64+ messages in thread
From: David Gibson @ 2019-10-03  0:22 UTC (permalink / raw)
  To: Greg Kurz
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Paolo Bonzini, Marc-André Lureau, philmd

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

On Wed, Oct 02, 2019 at 11:29:08AM +0200, Greg Kurz wrote:
> On Wed,  2 Oct 2019 12:52:04 +1000
> David Gibson <david@gibson.dropbear.id.au> 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.
> > 
> > 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);
> > +    }
> > +
> 
> I think this ^^ can go...
> 
> > +    if (kvm_enabled()) {
> > +        if (spapr_irq_init_kvm(kvmppc_xive_connect, intc, errp) < 0) {
> > +            return;
> > +        }
> > +    }
> > +
> 
> ... here. If which case, spapr_irq_init_kvm() could be called from
> set_active_intc() instead of being called by each backend if I get
> it right. This would avoid the frontend->backend->frontend flow.

Hm.  I don't love the idea.  KVM setup seems like an internal
implementation detail of the backend, which I'd prefer not to handle
in the frontend.

I'm not really considering spapr_irq_init_kvm() as part of the
frontend proper, but rather a helper function for use in the backend.

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

* Re: [PATCH v3 34/34] spapr: Remove last pieces of SpaprIrq
  2019-10-02 22:31     ` David Gibson
@ 2019-10-03  5:19       ` David Gibson
  0 siblings, 0 replies; 64+ messages in thread
From: David Gibson @ 2019-10-03  5:19 UTC (permalink / raw)
  To: Greg Kurz
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Paolo Bonzini, Marc-André Lureau, philmd

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

On Thu, Oct 03, 2019 at 08:31:11AM +1000, David Gibson wrote:
> On Wed, Oct 02, 2019 at 12:20:35PM +0200, Greg Kurz wrote:
> > On Wed,  2 Oct 2019 12:52:08 +1000
> > David Gibson <david@gibson.dropbear.id.au> wrote:
> > 
> > > 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>
> > > ---
> > 
> > This needs some more care. Incoming migration of older existing machine
> > types breaks:
> > 
> > qemu-system-ppc64: cap-xics higher level (1) in incoming stream than on destination (0)
> > qemu-system-ppc64: error while loading state for instance 0x0 of device 'spapr'
> > qemu-system-ppc64: load of migration failed: Invalid argument
> 
> Ah, right, thanks for testing that.  What machine type exactly was
> broken?

Never mind, found it.  And in fact it was broken with the lastest
machine type and ic-mode=xics as well.  Turns out I wrote the
vmstatedescription for the new caps, but didn't wire them up.

It's a real pain the number of places that need to be adjusted to get
a new cap properly working, unfortunately, I've not come up with a
good way to avoid it.

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

* Re: [PATCH v3 00/34] spapr: IRQ subsystem cleanup
  2019-10-02  2:51 [PATCH v3 00/34] spapr: IRQ subsystem cleanup David Gibson
                   ` (33 preceding siblings ...)
  2019-10-02  2:52 ` [PATCH v3 34/34] spapr: Remove last pieces of SpaprIrq David Gibson
@ 2019-10-03  6:18 ` David Gibson
  34 siblings, 0 replies; 64+ messages in thread
From: David Gibson @ 2019-10-03  6:18 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug, Paolo Bonzini,
	Marc-André Lureau, philmd

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

On Wed, Oct 02, 2019 at 12:51:34PM +1000, David Gibson wrote:
> 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.

Since there seems to be general agreement on that part, I've now
merged the first 20 patches of this series into ppc-for-4.2, which I
intend to send a PR for tomorroow.

> 
> Changes since v2:
>  * Fixed a bug where the "move handling multiple irq frees" to
>    frontend patch was actually freeing one irq over and over, rather
>    than freeing multiple irqs
>  * Fixed some places I missed still using only-Error * style, and flow
>    on adjustments
>  * New idiom to iterate across all constructed backends for the things
>    that need that (cpu_intc_create, claim & freem), rather than
>    open-coding a call on the xics, then xive versions.
> 
> 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 (34):
>   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: Add return value to spapr_irq_check()
>   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              |  57 ++-
>  hw/ppc/spapr_caps.c         |  64 +++
>  hw/ppc/spapr_cpu_core.c     |   3 +-
>  hw/ppc/spapr_hcall.c        |   7 +-
>  hw/ppc/spapr_irq.c          | 847 +++++++++++-------------------------
>  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  |  89 ++--
>  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 |  10 +-
>  include/hw/ppc/xive.h       |   2 +-
>  25 files changed, 897 insertions(+), 997 deletions(-)
> 

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

end of thread, other threads:[~2019-10-03  6:19 UTC | newest]

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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).