All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/20] spapr: IRQ subsystem cleanups
@ 2019-09-25  6:45 David Gibson
  2019-09-25  6:45 ` [PATCH 01/20] xics: Use incomplete type for XICSFabric David Gibson
                   ` (19 more replies)
  0 siblings, 20 replies; 93+ messages in thread
From: David Gibson @ 2019-09-25  6:45 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, philmd, David Gibson

This is a first batch of a number of cleanups to 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.

These are first steps towards even more cleanups that should make the
"dual" irq model less confusing.

David Gibson (20):
  xics: Use incomplete type for XICSFabric
  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
  spapr: Remove unused return value in claim path
  xive: Improve irq claim/free path
  spapr: Use less cryptic representation of which irq backends are
    supported
  spapr: Eliminate SpaprIrq::init hook

 hw/char/spapr_vty.c         |   3 +-
 hw/intc/spapr_xive.c        |  23 ++-
 hw/intc/trace-events        |  10 +-
 hw/intc/xics.c              | 210 ++++++++--------------
 hw/intc/xics_spapr.c        |  46 ++++-
 hw/net/spapr_llan.c         |   3 +-
 hw/ppc/pnv_psi.c            |   6 +-
 hw/ppc/spapr.c              |  15 +-
 hw/ppc/spapr_hcall.c        |   6 +-
 hw/ppc/spapr_irq.c          | 342 ++++++++++++++----------------------
 hw/ppc/spapr_pci.c          |   3 +-
 hw/ppc/spapr_vio.c          |   3 +-
 hw/ppc/trace-events         |   4 -
 include/hw/pci-host/spapr.h |   7 -
 include/hw/ppc/spapr_irq.h  |  31 ++--
 include/hw/ppc/spapr_vio.h  |   5 +-
 include/hw/ppc/spapr_xive.h |   5 +-
 include/hw/ppc/xics.h       |  31 ++--
 include/hw/ppc/xics_spapr.h |   5 +-
 19 files changed, 320 insertions(+), 438 deletions(-)

-- 
2.21.0



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

* [PATCH 01/20] xics: Use incomplete type for XICSFabric
  2019-09-25  6:45 [PATCH 00/20] spapr: IRQ subsystem cleanups David Gibson
@ 2019-09-25  6:45 ` David Gibson
  2019-09-25  6:55   ` Cédric Le Goater
  2019-09-25  7:45   ` Greg Kurz
  2019-09-25  6:45 ` [PATCH 02/20] xics: Eliminate 'reject', 'resend' and 'eoi' class hooks David Gibson
                   ` (18 subsequent siblings)
  19 siblings, 2 replies; 93+ messages in thread
From: David Gibson @ 2019-09-25  6:45 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, 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.

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

diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index 64a2c8862a..1ae34ce9cd 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -147,9 +147,7 @@ struct ICSIRQState {
     uint8_t flags;
 };
 
-struct XICSFabric {
-    Object parent;
-};
+typedef struct XICSFabric XICSFabric;
 
 #define TYPE_XICS_FABRIC "xics-fabric"
 #define XICS_FABRIC(obj)                                     \
-- 
2.21.0



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

* [PATCH 02/20] xics: Eliminate 'reject', 'resend' and 'eoi' class hooks
  2019-09-25  6:45 [PATCH 00/20] spapr: IRQ subsystem cleanups David Gibson
  2019-09-25  6:45 ` [PATCH 01/20] xics: Use incomplete type for XICSFabric David Gibson
@ 2019-09-25  6:45 ` David Gibson
  2019-09-25  6:45 ` [PATCH 03/20] xics: Rename misleading ics_simple_*() functions David Gibson
                   ` (17 subsequent siblings)
  19 siblings, 0 replies; 93+ messages in thread
From: David Gibson @ 2019-09-25  6:45 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, 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 1ae34ce9cd..d7d8e846b4 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] 93+ messages in thread

* [PATCH 03/20] xics: Rename misleading ics_simple_*() functions
  2019-09-25  6:45 [PATCH 00/20] spapr: IRQ subsystem cleanups David Gibson
  2019-09-25  6:45 ` [PATCH 01/20] xics: Use incomplete type for XICSFabric David Gibson
  2019-09-25  6:45 ` [PATCH 02/20] xics: Eliminate 'reject', 'resend' and 'eoi' class hooks David Gibson
@ 2019-09-25  6:45 ` David Gibson
  2019-09-25  6:45 ` [PATCH 04/20] xics: Eliminate reset hook David Gibson
                   ` (16 subsequent siblings)
  19 siblings, 0 replies; 93+ messages in thread
From: David Gibson @ 2019-09-25  6:45 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, 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 d7d8e846b4..e72fb67968 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -169,9 +169,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] 93+ messages in thread

* [PATCH 04/20] xics: Eliminate reset hook
  2019-09-25  6:45 [PATCH 00/20] spapr: IRQ subsystem cleanups David Gibson
                   ` (2 preceding siblings ...)
  2019-09-25  6:45 ` [PATCH 03/20] xics: Rename misleading ics_simple_*() functions David Gibson
@ 2019-09-25  6:45 ` David Gibson
  2019-09-25  7:33   ` Cédric Le Goater
  2019-09-25  7:59   ` Greg Kurz
  2019-09-25  6:45 ` [PATCH 05/20] xics: Merge TYPE_ICS_BASE and TYPE_ICS_SIMPLE classes David Gibson
                   ` (15 subsequent siblings)
  19 siblings, 2 replies; 93+ messages in thread
From: David Gibson @ 2019-09-25  6:45 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, 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>
---
 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 e72fb67968..18fcd2b11c 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] 93+ messages in thread

* [PATCH 05/20] xics: Merge TYPE_ICS_BASE and TYPE_ICS_SIMPLE classes
  2019-09-25  6:45 [PATCH 00/20] spapr: IRQ subsystem cleanups David Gibson
                   ` (3 preceding siblings ...)
  2019-09-25  6:45 ` [PATCH 04/20] xics: Eliminate reset hook David Gibson
@ 2019-09-25  6:45 ` David Gibson
  2019-09-25  8:16   ` Greg Kurz
  2019-09-25 12:47   ` Cédric Le Goater
  2019-09-25  6:45 ` [PATCH 06/20] xics: Create sPAPR specific ICS subtype David Gibson
                   ` (14 subsequent siblings)
  19 siblings, 2 replies; 93+ messages in thread
From: David Gibson @ 2019-09-25  6:45 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, philmd, David Gibson

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

So, collapse the two classes together into just TYPE_ICS.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 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 18fcd2b11c..5a9b73d144 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] 93+ messages in thread

* [PATCH 06/20] xics: Create sPAPR specific ICS subtype
  2019-09-25  6:45 [PATCH 00/20] spapr: IRQ subsystem cleanups David Gibson
                   ` (4 preceding siblings ...)
  2019-09-25  6:45 ` [PATCH 05/20] xics: Merge TYPE_ICS_BASE and TYPE_ICS_SIMPLE classes David Gibson
@ 2019-09-25  6:45 ` David Gibson
  2019-09-25  7:34   ` Cédric Le Goater
  2019-09-25  8:40   ` Greg Kurz
  2019-09-25  6:45 ` [PATCH 07/20] spapr: Fold spapr_phb_lsi_qirq() into its single caller David Gibson
                   ` (13 subsequent siblings)
  19 siblings, 2 replies; 93+ messages in thread
From: David Gibson @ 2019-09-25  6:45 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, 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>
---
 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] 93+ messages in thread

* [PATCH 07/20] spapr: Fold spapr_phb_lsi_qirq() into its single caller
  2019-09-25  6:45 [PATCH 00/20] spapr: IRQ subsystem cleanups David Gibson
                   ` (5 preceding siblings ...)
  2019-09-25  6:45 ` [PATCH 06/20] xics: Create sPAPR specific ICS subtype David Gibson
@ 2019-09-25  6:45 ` David Gibson
  2019-09-25  6:58   ` Cédric Le Goater
                     ` (2 more replies)
  2019-09-25  6:45 ` [PATCH 08/20] spapr: Replace spapr_vio_qirq() helper with spapr_vio_irq_pulse() helper David Gibson
                   ` (12 subsequent siblings)
  19 siblings, 3 replies; 93+ messages in thread
From: David Gibson @ 2019-09-25  6:45 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, 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>
---
 hw/ppc/spapr_pci.c          | 3 ++-
 include/hw/pci-host/spapr.h | 7 -------
 2 files changed, 2 insertions(+), 8 deletions(-)

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



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

* [PATCH 08/20] spapr: Replace spapr_vio_qirq() helper with spapr_vio_irq_pulse() helper
  2019-09-25  6:45 [PATCH 00/20] spapr: IRQ subsystem cleanups David Gibson
                   ` (6 preceding siblings ...)
  2019-09-25  6:45 ` [PATCH 07/20] spapr: Fold spapr_phb_lsi_qirq() into its single caller David Gibson
@ 2019-09-25  6:45 ` David Gibson
  2019-09-25  6:58   ` Cédric Le Goater
                     ` (2 more replies)
  2019-09-25  6:45 ` [PATCH 09/20] spapr: Clarify and fix handling of nr_irqs David Gibson
                   ` (11 subsequent siblings)
  19 siblings, 3 replies; 93+ messages in thread
From: David Gibson @ 2019-09-25  6:45 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, 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>
---
 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] 93+ messages in thread

* [PATCH 09/20] spapr: Clarify and fix handling of nr_irqs
  2019-09-25  6:45 [PATCH 00/20] spapr: IRQ subsystem cleanups David Gibson
                   ` (7 preceding siblings ...)
  2019-09-25  6:45 ` [PATCH 08/20] spapr: Replace spapr_vio_qirq() helper with spapr_vio_irq_pulse() helper David Gibson
@ 2019-09-25  6:45 ` David Gibson
  2019-09-25  7:05   ` Cédric Le Goater
  2019-09-25 17:13   ` Greg Kurz
  2019-09-25  6:45 ` [PATCH 10/20] spapr: Eliminate nr_irqs parameter to SpaprIrq::init David Gibson
                   ` (10 subsequent siblings)
  19 siblings, 2 replies; 93+ messages in thread
From: David Gibson @ 2019-09-25  6:45 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, 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 use move to using common constants in most of the
irq configurations, to make it clearer that the IRQ space looks the same
to the guest (and emulated devices), even if the backend is different.

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

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 8c26fa2d1e..5190a33e08 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;
     }
 
@@ -409,12 +405,9 @@ static void spapr_irq_init_kvm_xive(SpaprMachineState *spapr, Error **errp)
  * 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 +443,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 +579,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 +683,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 +794,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] 93+ messages in thread

* [PATCH 10/20] spapr: Eliminate nr_irqs parameter to SpaprIrq::init
  2019-09-25  6:45 [PATCH 00/20] spapr: IRQ subsystem cleanups David Gibson
                   ` (8 preceding siblings ...)
  2019-09-25  6:45 ` [PATCH 09/20] spapr: Clarify and fix handling of nr_irqs David Gibson
@ 2019-09-25  6:45 ` David Gibson
  2019-09-25  7:06   ` Cédric Le Goater
  2019-09-25 17:16   ` Greg Kurz
  2019-09-25  6:45 ` [PATCH 11/20] spapr: Fix indexing of XICS irqs David Gibson
                   ` (9 subsequent siblings)
  19 siblings, 2 replies; 93+ messages in thread
From: David Gibson @ 2019-09-25  6:45 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, 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>
---
 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 5190a33e08..300c65be3a 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
      */
@@ -443,18 +443,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;
@@ -683,7 +682,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] 93+ messages in thread

* [PATCH 11/20] spapr: Fix indexing of XICS irqs
  2019-09-25  6:45 [PATCH 00/20] spapr: IRQ subsystem cleanups David Gibson
                   ` (9 preceding siblings ...)
  2019-09-25  6:45 ` [PATCH 10/20] spapr: Eliminate nr_irqs parameter to SpaprIrq::init David Gibson
@ 2019-09-25  6:45 ` David Gibson
  2019-09-25  7:11   ` Cédric Le Goater
  2019-09-25 20:17   ` Greg Kurz
  2019-09-25  6:45 ` [PATCH 12/20] spapr: Simplify spapr_qirq() handling David Gibson
                   ` (8 subsequent siblings)
  19 siblings, 2 replies; 93+ messages in thread
From: David Gibson @ 2019-09-25  6:45 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, 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>
---
 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 300c65be3a..9a9e486eb5 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);
     }
 }
 
@@ -563,11 +563,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] 93+ messages in thread

* [PATCH 12/20] spapr: Simplify spapr_qirq() handling
  2019-09-25  6:45 [PATCH 00/20] spapr: IRQ subsystem cleanups David Gibson
                   ` (10 preceding siblings ...)
  2019-09-25  6:45 ` [PATCH 11/20] spapr: Fix indexing of XICS irqs David Gibson
@ 2019-09-25  6:45 ` David Gibson
  2019-09-25  7:16   ` Cédric Le Goater
                     ` (2 more replies)
  2019-09-25  6:45 ` [PATCH 13/20] spapr: Eliminate SpaprIrq:get_nodename method David Gibson
                   ` (7 subsequent siblings)
  19 siblings, 3 replies; 93+ messages in thread
From: David Gibson @ 2019-09-25  6:45 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, philmd, David Gibson

Currently spapr_qirq() 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>
---
 hw/ppc/spapr_irq.c         | 47 ++++++++++----------------------------
 include/hw/ppc/spapr_irq.h |  1 -
 2 files changed, 12 insertions(+), 36 deletions(-)

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 9a9e486eb5..038bfffff4 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)
 {
@@ -413,7 +387,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,
@@ -487,11 +460,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);
@@ -586,7 +554,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,
@@ -700,7 +667,18 @@ void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
 
 qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq)
 {
-    return spapr->irq->qirq(spapr, irq);
+    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)
@@ -803,7 +781,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] 93+ messages in thread

* [PATCH 13/20] spapr: Eliminate SpaprIrq:get_nodename method
  2019-09-25  6:45 [PATCH 00/20] spapr: IRQ subsystem cleanups David Gibson
                   ` (11 preceding siblings ...)
  2019-09-25  6:45 ` [PATCH 12/20] spapr: Simplify spapr_qirq() handling David Gibson
@ 2019-09-25  6:45 ` David Gibson
  2019-09-25  7:19   ` Cédric Le Goater
                     ` (2 more replies)
  2019-09-25  6:45 ` [PATCH 14/20] spapr: Remove unhelpful tracepoints from spapr_irq_free_xics() David Gibson
                   ` (6 subsequent siblings)
  19 siblings, 3 replies; 93+ messages in thread
From: David Gibson @ 2019-09-25  6:45 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, 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.

So, the method is unnecessary.

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

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 038bfffff4..79167ccc68 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()) {
@@ -393,7 +382,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,
 };
 
@@ -538,11 +526,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
  */
@@ -560,7 +543,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 */
 };
 
@@ -697,13 +679,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;
     }
 
@@ -787,6 +769,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;
 
-- 
2.21.0



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

* [PATCH 14/20] spapr: Remove unhelpful tracepoints from spapr_irq_free_xics()
  2019-09-25  6:45 [PATCH 00/20] spapr: IRQ subsystem cleanups David Gibson
                   ` (12 preceding siblings ...)
  2019-09-25  6:45 ` [PATCH 13/20] spapr: Eliminate SpaprIrq:get_nodename method David Gibson
@ 2019-09-25  6:45 ` David Gibson
  2019-09-25  7:20   ` Cédric Le Goater
                     ` (2 more replies)
  2019-09-25  6:45 ` [PATCH 15/20] spapr: Handle freeing of multiple irqs in frontend only David Gibson
                   ` (5 subsequent siblings)
  19 siblings, 3 replies; 93+ messages in thread
From: David Gibson @ 2019-09-25  6:45 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, 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>
---
 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 79167ccc68..db6755f3ab 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] 93+ messages in thread

* [PATCH 15/20] spapr: Handle freeing of multiple irqs in frontend only
  2019-09-25  6:45 [PATCH 00/20] spapr: IRQ subsystem cleanups David Gibson
                   ` (13 preceding siblings ...)
  2019-09-25  6:45 ` [PATCH 14/20] spapr: Remove unhelpful tracepoints from spapr_irq_free_xics() David Gibson
@ 2019-09-25  6:45 ` David Gibson
  2019-09-25  7:21   ` Cédric Le Goater
  2019-09-26  7:52   ` Greg Kurz
  2019-09-25  6:45 ` [PATCH 16/20] spapr, xics, xive: Better use of assert()s on irq claim/free paths David Gibson
                   ` (4 subsequent siblings)
  19 siblings, 2 replies; 93+ messages in thread
From: David Gibson @ 2019-09-25  6:45 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, 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 db6755f3ab..c40357a985 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,
@@ -438,10 +431,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)
@@ -640,7 +633,11 @@ int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
 
 void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
 {
-    spapr->irq->free(spapr, irq, num);
+    int i;
+
+    for (i = irq; i < (irq + num); i++) {
+        spapr->irq->free(spapr, irq);
+    }
 }
 
 qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq)
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index 9b60378e28..ed88b4599a 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -43,7 +43,7 @@ typedef struct SpaprIrq {
 
     void (*init)(SpaprMachineState *spapr, Error **errp);
     int (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
-    void (*free)(SpaprMachineState *spapr, int irq, int num);
+    void (*free)(SpaprMachineState *spapr, int irq);
     void (*print_info)(SpaprMachineState *spapr, Monitor *mon);
     void (*dt_populate)(SpaprMachineState *spapr, uint32_t nr_servers,
                         void *fdt, uint32_t phandle);
-- 
2.21.0



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

* [PATCH 16/20] spapr, xics, xive: Better use of assert()s on irq claim/free paths
  2019-09-25  6:45 [PATCH 00/20] spapr: IRQ subsystem cleanups David Gibson
                   ` (14 preceding siblings ...)
  2019-09-25  6:45 ` [PATCH 15/20] spapr: Handle freeing of multiple irqs in frontend only David Gibson
@ 2019-09-25  6:45 ` David Gibson
  2019-09-25  7:22   ` Cédric Le Goater
  2019-09-26  8:08   ` Greg Kurz
  2019-09-25  6:45 ` [PATCH 17/20] spapr: Remove unused return value in claim path David Gibson
                   ` (3 subsequent siblings)
  19 siblings, 2 replies; 93+ messages in thread
From: David Gibson @ 2019-09-25  6:45 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, 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>
---
 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 c40357a985..261d66ba17 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)
@@ -628,6 +624,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);
 }
 
@@ -635,6 +634,9 @@ void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
 {
     int i;
 
+    assert(irq >= SPAPR_XIRQ_BASE);
+    assert((irq+num) <= (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
+
     for (i = irq; i < (irq + num); i++) {
         spapr->irq->free(spapr, irq);
     }
-- 
2.21.0



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

* [PATCH 17/20] spapr: Remove unused return value in claim path
  2019-09-25  6:45 [PATCH 00/20] spapr: IRQ subsystem cleanups David Gibson
                   ` (15 preceding siblings ...)
  2019-09-25  6:45 ` [PATCH 16/20] spapr, xics, xive: Better use of assert()s on irq claim/free paths David Gibson
@ 2019-09-25  6:45 ` David Gibson
  2019-09-25  7:23   ` Cédric Le Goater
                     ` (2 more replies)
  2019-09-25  6:45 ` [PATCH 18/20] xive: Improve irq claim/free path David Gibson
                   ` (2 subsequent siblings)
  19 siblings, 3 replies; 93+ messages in thread
From: David Gibson @ 2019-09-25  6:45 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, philmd, David Gibson

spapr_irq_claim() and the hooks it is based on return an integer error code
as well as taking an Error ** parameter.  But none of the callers check the
integer, so we can remove it and just use the richer Error **.

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

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 261d66ba17..2673a90604 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -112,8 +112,8 @@ static void spapr_irq_init_xics(SpaprMachineState *spapr, Error **errp)
     spapr->ics = ICS_SPAPR(obj);
 }
 
-static int spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
-                                Error **errp)
+static void spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
+                                 Error **errp)
 {
     ICSState *ics = spapr->ics;
 
@@ -122,11 +122,10 @@ static int spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
 
     if (!ics_irq_free(ics, irq - ics->offset)) {
         error_setg(errp, "IRQ %d is not free", irq);
-        return -1;
+        return;
     }
 
     ics_set_irq_type(ics, irq - ics->offset, lsi);
-    return 0;
 }
 
 static void spapr_irq_free_xics(SpaprMachineState *spapr, int irq)
@@ -252,14 +251,12 @@ static void spapr_irq_init_xive(SpaprMachineState *spapr, Error **errp)
     spapr_xive_hcall_init(spapr);
 }
 
-static int spapr_irq_claim_xive(SpaprMachineState *spapr, int irq, bool lsi,
-                                Error **errp)
+static void 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;
 }
 
 static void spapr_irq_free_xive(SpaprMachineState *spapr, int irq)
@@ -406,25 +403,22 @@ static void spapr_irq_init_dual(SpaprMachineState *spapr, Error **errp)
     }
 }
 
-static int spapr_irq_claim_dual(SpaprMachineState *spapr, int irq, bool lsi,
-                                Error **errp)
+static void 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);
+    spapr_irq_xics.claim(spapr, irq, lsi, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
-        return ret;
+        return;
     }
 
-    ret = spapr_irq_xive.claim(spapr, irq, lsi, &local_err);
+    spapr_irq_xive.claim(spapr, irq, lsi, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
-        return ret;
+        return;
     }
-
-    return ret;
 }
 
 static void spapr_irq_free_dual(SpaprMachineState *spapr, int irq)
@@ -622,12 +616,12 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
                                       spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
 }
 
-int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
+void 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);
+    spapr->irq->claim(spapr, irq, lsi, errp);
 }
 
 void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index ed88b4599a..75279ca137 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -42,7 +42,7 @@ typedef struct SpaprIrq {
     uint8_t     ov5;
 
     void (*init)(SpaprMachineState *spapr, Error **errp);
-    int (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
+    void (*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,
@@ -61,7 +61,7 @@ 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_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
 void spapr_irq_free(SpaprMachineState *spapr, int irq, int num);
 qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq);
 int spapr_irq_post_load(SpaprMachineState *spapr, int version_id);
-- 
2.21.0



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

* [PATCH 18/20] xive: Improve irq claim/free path
  2019-09-25  6:45 [PATCH 00/20] spapr: IRQ subsystem cleanups David Gibson
                   ` (16 preceding siblings ...)
  2019-09-25  6:45 ` [PATCH 17/20] spapr: Remove unused return value in claim path David Gibson
@ 2019-09-25  6:45 ` David Gibson
  2019-09-25  7:25   ` Cédric Le Goater
  2019-09-25  6:45 ` [PATCH 19/20] spapr: Use less cryptic representation of which irq backends are supported David Gibson
  2019-09-25  6:45 ` [PATCH 20/20] spapr: Eliminate SpaprIrq::init hook David Gibson
  19 siblings, 1 reply; 93+ messages in thread
From: David Gibson @ 2019-09-25  6:45 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, philmd, David Gibson

spapr_xive_irq_claim() returns a bool to indicate if it succeeded.  But
most of the callers and one callee use a richer Error * instead.  So use
that instead of a bool return so we can actually pass more informative
errors up the stack.

In addition it 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, so
just drop it.

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

diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index 47b5ec0b56..5a56a58299 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -528,12 +528,18 @@ 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)
+void spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi,
+                          Error **errp)
 {
     XiveSource *xsrc = &xive->source;
 
     assert(lisn < xive->nr_irqs);
 
+    if (be64_to_cpu(xive->eat[lisn].w) & EAS_VALID) {
+        error_setg(errp, "IRQ %d is not free", lisn);
+        return;
+    }
+
     /*
      * Set default values when allocating an IRQ number
      */
@@ -547,20 +553,17 @@ bool spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi)
 
         kvmppc_xive_source_reset_one(xsrc, lisn, &local_err);
         if (local_err) {
-            error_report_err(local_err);
-            return false;
+            error_propagate(errp, local_err);
+            return;
         }
     }
-
-    return true;
 }
 
-bool spapr_xive_irq_free(SpaprXive *xive, uint32_t lisn)
+void spapr_xive_irq_free(SpaprXive *xive, uint32_t lisn)
 {
     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 2673a90604..f53544e45e 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -245,7 +245,13 @@ static void spapr_irq_init_xive(SpaprMachineState *spapr, Error **errp)
 
     /* Enable the CPU IPIs */
     for (i = 0; i < nr_servers; ++i) {
-        spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i, false);
+        Error *local_err = NULL;
+
+        spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i, false, &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            return;
+        }
     }
 
     spapr_xive_hcall_init(spapr);
@@ -254,9 +260,7 @@ static void spapr_irq_init_xive(SpaprMachineState *spapr, Error **errp)
 static void 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);
-    }
+    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..69df3793e1 100644
--- a/include/hw/ppc/spapr_xive.h
+++ b/include/hw/ppc/spapr_xive.h
@@ -54,8 +54,9 @@ 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);
+void spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi,
+                          Error **errp);
+void spapr_xive_irq_free(SpaprXive *xive, uint32_t 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] 93+ messages in thread

* [PATCH 19/20] spapr: Use less cryptic representation of which irq backends are supported
  2019-09-25  6:45 [PATCH 00/20] spapr: IRQ subsystem cleanups David Gibson
                   ` (17 preceding siblings ...)
  2019-09-25  6:45 ` [PATCH 18/20] xive: Improve irq claim/free path David Gibson
@ 2019-09-25  6:45 ` David Gibson
  2019-09-25  7:28   ` Cédric Le Goater
  2019-09-26  9:16   ` Greg Kurz
  2019-09-25  6:45 ` [PATCH 20/20] spapr: Eliminate SpaprIrq::init hook David Gibson
  19 siblings, 2 replies; 93+ messages in thread
From: David Gibson @ 2019-09-25  6:45 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, 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>
---
 hw/ppc/spapr.c             | 15 ++++++++++++---
 hw/ppc/spapr_hcall.c       |  6 +++---
 hw/ppc/spapr_irq.c         | 12 ++++++++----
 include/hw/ppc/spapr_irq.h |  3 ++-
 4 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 3742a8cf06..795f6ab505 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1136,19 +1136,28 @@ static void spapr_dt_ov5_platform_support(SpaprMachineState *spapr, void *fdt,
     PowerPCCPU *first_ppc_cpu = POWERPC_CPU(first_cpu);
 
     char val[2 * 4] = {
-        23, spapr->irq->ov5, /* Xive mode. */
+        23, 0x00, /* XICS / XIVE mode */
         24, 0x00, /* Hash/Radix, filled in below. */
         25, 0x00, /* Hash options: Segment Tables == no, GTSE == no. */
         26, 0x40, /* Radix options: GTSE == yes. */
     };
 
+    if (spapr->irq->xics && spapr->irq->xive) {
+        val[1] = SPAPR_OV5_XIVE_BOTH;
+    } else if (spapr->irq->xive) {
+        val[1] = SPAPR_OV5_XIVE_EXPLOIT;
+    } else {
+        assert(spapr->irq->xics);
+        val[1] = SPAPR_OV5_XIVE_LEGACY;
+    }
+
     if (!ppc_check_compat(first_ppc_cpu, CPU_POWERPC_LOGICAL_3_00, 0,
                           first_ppc_cpu->compat_pvr)) {
         /*
          * If we're in a pre POWER9 compat mode then the guest should
          * do hash and use the legacy interrupt mode
          */
-        val[1] = 0x00; /* XICS */
+        val[1] = SPAPR_OV5_XIVE_LEGACY; /* XICS */
         val[3] = 0x00; /* Hash */
     } else if (kvm_enabled()) {
         if (kvmppc_has_cap_mmu_radix() && kvmppc_has_cap_mmu_hash_v3()) {
@@ -2837,7 +2846,7 @@ static void spapr_machine_init(MachineState *machine)
     spapr_ovec_set(spapr->ov5, OV5_DRMEM_V2);
 
     /* advertise XIVE on POWER9 machines */
-    if (spapr->irq->ov5 & (SPAPR_OV5_XIVE_EXPLOIT | SPAPR_OV5_XIVE_BOTH)) {
+    if (spapr->irq->xive) {
         spapr_ovec_set(spapr->ov5, OV5_XIVE_EXPLOIT);
     }
 
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 3d3a67149a..140f05c1c6 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -1784,13 +1784,13 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
      * terminate the boot.
      */
     if (guest_xive) {
-        if (spapr->irq->ov5 == SPAPR_OV5_XIVE_LEGACY) {
+        if (!spapr->irq->xive) {
             error_report(
 "Guest requested unavailable interrupt mode (XIVE), try the ic-mode=xive or ic-mode=dual machine property");
             exit(EXIT_FAILURE);
         }
     } else {
-        if (spapr->irq->ov5 == SPAPR_OV5_XIVE_EXPLOIT) {
+        if (!spapr->irq->xics) {
             error_report(
 "Guest requested unavailable interrupt mode (XICS), either don't set the ic-mode machine property or try ic-mode=xics or ic-mode=dual");
             exit(EXIT_FAILURE);
@@ -1804,7 +1804,7 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
      */
     if (!spapr->cas_reboot) {
         spapr->cas_reboot = spapr_ovec_test(ov5_updates, OV5_XIVE_EXPLOIT)
-            && spapr->irq->ov5 & SPAPR_OV5_XIVE_BOTH;
+            && spapr->irq->xics && spapr->irq->xive;
     }
 
     spapr_ovec_cleanup(ov5_updates);
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index f53544e45e..073f375ba2 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -209,7 +209,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,
@@ -357,7 +358,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,
@@ -515,7 +517,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,
@@ -751,7 +754,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 75279ca137..6816cb0500 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);
     void (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
-- 
2.21.0



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

* [PATCH 20/20] spapr: Eliminate SpaprIrq::init hook
  2019-09-25  6:45 [PATCH 00/20] spapr: IRQ subsystem cleanups David Gibson
                   ` (18 preceding siblings ...)
  2019-09-25  6:45 ` [PATCH 19/20] spapr: Use less cryptic representation of which irq backends are supported David Gibson
@ 2019-09-25  6:45 ` David Gibson
  2019-09-25  7:31   ` Cédric Le Goater
  2019-09-26 15:39   ` Greg Kurz
  19 siblings, 2 replies; 93+ messages in thread
From: David Gibson @ 2019-09-25  6:45 UTC (permalink / raw)
  To: qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, 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>
---
 hw/ppc/spapr_irq.c          | 138 ++++++++++++++++--------------------
 include/hw/ppc/spapr_irq.h  |   1 -
 include/hw/ppc/xics_spapr.h |   1 +
 3 files changed, 63 insertions(+), 77 deletions(-)

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 073f375ba2..62647dd5a3 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -91,27 +91,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 void spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
                                  Error **errp)
 {
@@ -212,7 +191,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,
@@ -227,37 +205,6 @@ SpaprIrq spapr_irq_xics = {
 /*
  * XIVE IRQ backend.
  */
-static void spapr_irq_init_xive(SpaprMachineState *spapr, Error **errp)
-{
-    uint32_t nr_servers = spapr_max_server_number(spapr);
-    DeviceState *dev;
-    int i;
-
-    dev = qdev_create(NULL, TYPE_SPAPR_XIVE);
-    qdev_prop_set_uint32(dev, "nr-irqs",
-                         spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
-    /*
-     * 8 XIVE END structures per CPU. One for each available priority
-     */
-    qdev_prop_set_uint32(dev, "nr-ends", nr_servers << 3);
-    qdev_init_nofail(dev);
-
-    spapr->xive = SPAPR_XIVE(dev);
-
-    /* Enable the CPU IPIs */
-    for (i = 0; i < nr_servers; ++i) {
-        Error *local_err = NULL;
-
-        spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i, false, &local_err);
-        if (local_err) {
-            error_propagate(errp, local_err);
-            return;
-        }
-    }
-
-    spapr_xive_hcall_init(spapr);
-}
-
 static void spapr_irq_claim_xive(SpaprMachineState *spapr, int irq, bool lsi,
                                  Error **errp)
 {
@@ -361,7 +308,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,
@@ -392,23 +338,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 void spapr_irq_claim_dual(SpaprMachineState *spapr, int irq, bool lsi,
                                  Error **errp)
 {
@@ -520,7 +449,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,
@@ -608,8 +536,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
 
     spapr_irq_check(spapr, &local_err);
     if (local_err) {
-        error_propagate(errp, local_err);
-        return;
+        goto out;
     }
 
     /* Initialize the MSI IRQ allocator. */
@@ -617,10 +544,70 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
         spapr_irq_msi_init(spapr, spapr->irq->nr_msis);
     }
 
-    spapr->irq->init(spapr, errp);
+    if (spapr->irq->xics) {
+        Object *obj;
+
+        obj = object_new(TYPE_ICS_SPAPR);
+        object_property_add_child(OBJECT(spapr), "ics", obj, &local_err);
+        if (local_err) {
+            goto out;
+        }
+
+        object_property_add_const_link(obj, ICS_PROP_XICS, OBJECT(spapr),
+                                       &local_err);
+        if (local_err) {
+            goto out;
+        }
+
+        object_property_set_int(obj, spapr->irq->nr_xirqs, "nr-irqs",
+                                &local_err);
+        if (local_err) {
+            goto out;
+        }
+
+        object_property_set_bool(obj, true, "realized", &local_err);
+        if (local_err) {
+            goto out;
+        }
+
+        spapr->ics = ICS_SPAPR(obj);
+    }
+
+    if (spapr->irq->xive) {
+        uint32_t nr_servers = spapr_max_server_number(spapr);
+        DeviceState *dev;
+        int i;
+
+        dev = qdev_create(NULL, TYPE_SPAPR_XIVE);
+        qdev_prop_set_uint32(dev, "nr-irqs",
+                             spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
+        /*
+         * 8 XIVE END structures per CPU. One for each available
+         * priority
+         */
+        qdev_prop_set_uint32(dev, "nr-ends", nr_servers << 3);
+        qdev_init_nofail(dev);
+
+        spapr->xive = SPAPR_XIVE(dev);
+
+        /* Enable the CPU IPIs */
+        for (i = 0; i < nr_servers; ++i) {
+            Error *local_err = NULL;
+
+            spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i, false, &local_err);
+            if (local_err) {
+                goto out;
+            }
+        }
+
+        spapr_xive_hcall_init(spapr);
+    }
 
     spapr->qirqs = qemu_allocate_irqs(spapr->irq->set_irq, spapr,
                                       spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
+
+out:
+    error_propagate(errp, local_err);
 }
 
 void spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
@@ -757,7 +744,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 6816cb0500..fa862c665b 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);
     void (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
     void (*free)(SpaprMachineState *spapr, int irq);
     void (*print_info)(SpaprMachineState *spapr, Monitor *mon);
diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h
index 691a6d00f7..267984a97b 100644
--- a/include/hw/ppc/xics_spapr.h
+++ b/include/hw/ppc/xics_spapr.h
@@ -34,6 +34,7 @@
 #define TYPE_ICS_SPAPR "ics-spapr"
 #define ICS_SPAPR(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SPAPR)
 
+void ics_spapr_create(SpaprMachineState *spapr, int nr_xirqs, Error **errp);
 void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
                    uint32_t phandle);
 int xics_kvm_connect(SpaprMachineState *spapr, Error **errp);
-- 
2.21.0



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

* Re: [PATCH 01/20] xics: Use incomplete type for XICSFabric
  2019-09-25  6:45 ` [PATCH 01/20] xics: Use incomplete type for XICSFabric David Gibson
@ 2019-09-25  6:55   ` Cédric Le Goater
  2019-09-25  7:48     ` Greg Kurz
  2019-09-25  7:45   ` Greg Kurz
  1 sibling, 1 reply; 93+ messages in thread
From: Cédric Le Goater @ 2019-09-25  6:55 UTC (permalink / raw)
  To: David Gibson, qemu-ppc, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, philmd

On 25/09/2019 08:45, 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.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---
>  include/hw/ppc/xics.h | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
> index 64a2c8862a..1ae34ce9cd 100644
> --- a/include/hw/ppc/xics.h
> +++ b/include/hw/ppc/xics.h
> @@ -147,9 +147,7 @@ struct ICSIRQState {
>      uint8_t flags;
>  };
>  
> -struct XICSFabric {
> -    Object parent;
> -};
> +typedef struct XICSFabric XICSFabric;
>  
>  #define TYPE_XICS_FABRIC "xics-fabric"
>  #define XICS_FABRIC(obj)                                     \
> 

you should also change :

#define XICS_FABRIC(obj)                                     \
    OBJECT_CHECK(XICSFabric, (obj), TYPE_XICS_FABRIC)


and use INTERFACE_CHECK()

C.


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

* Re: [PATCH 07/20] spapr: Fold spapr_phb_lsi_qirq() into its single caller
  2019-09-25  6:45 ` [PATCH 07/20] spapr: Fold spapr_phb_lsi_qirq() into its single caller David Gibson
@ 2019-09-25  6:58   ` Cédric Le Goater
  2019-09-25  8:56   ` Greg Kurz
  2019-09-26  7:08   ` Philippe Mathieu-Daudé
  2 siblings, 0 replies; 93+ messages in thread
From: Cédric Le Goater @ 2019-09-25  6:58 UTC (permalink / raw)
  To: David Gibson, qemu-ppc, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, philmd

On 25/09/2019 08:45, David Gibson wrote:
> 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>

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



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

* Re: [PATCH 08/20] spapr: Replace spapr_vio_qirq() helper with spapr_vio_irq_pulse() helper
  2019-09-25  6:45 ` [PATCH 08/20] spapr: Replace spapr_vio_qirq() helper with spapr_vio_irq_pulse() helper David Gibson
@ 2019-09-25  6:58   ` Cédric Le Goater
  2019-09-25  8:57   ` Greg Kurz
  2019-09-26  7:08   ` Philippe Mathieu-Daudé
  2 siblings, 0 replies; 93+ messages in thread
From: Cédric Le Goater @ 2019-09-25  6:58 UTC (permalink / raw)
  To: David Gibson, qemu-ppc, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, philmd

On 25/09/2019 08:45, David Gibson wrote:
> 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>

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



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

* Re: [PATCH 09/20] spapr: Clarify and fix handling of nr_irqs
  2019-09-25  6:45 ` [PATCH 09/20] spapr: Clarify and fix handling of nr_irqs David Gibson
@ 2019-09-25  7:05   ` Cédric Le Goater
  2019-09-26  1:03     ` David Gibson
  2019-09-25 17:13   ` Greg Kurz
  1 sibling, 1 reply; 93+ messages in thread
From: Cédric Le Goater @ 2019-09-25  7:05 UTC (permalink / raw)
  To: David Gibson, qemu-ppc, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, philmd

On 25/09/2019 08:45, 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 use 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: Cédric Le Goater <clg@kaod.org>

one comment below,

> ---
>  hw/ppc/spapr_irq.c         | 48 +++++++++++++++-----------------------
>  include/hw/ppc/spapr_irq.h | 19 +++++++++------
>  2 files changed, 31 insertions(+), 36 deletions(-)
> 
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index 8c26fa2d1e..5190a33e08 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)) {

So IPIs cannot be pulsed ? I think that is OK in QEMU.

XIVE unifies all the interrupts at the controller level. Any one can trigger 
an interrupt with a store on the associate ESB page.

>          return NULL;
>      }
>  
> @@ -409,12 +405,9 @@ static void spapr_irq_init_kvm_xive(SpaprMachineState *spapr, Error **errp)
>   * 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 +443,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 +579,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 +683,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 +794,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] 93+ messages in thread

* Re: [PATCH 10/20] spapr: Eliminate nr_irqs parameter to SpaprIrq::init
  2019-09-25  6:45 ` [PATCH 10/20] spapr: Eliminate nr_irqs parameter to SpaprIrq::init David Gibson
@ 2019-09-25  7:06   ` Cédric Le Goater
  2019-09-25 17:16   ` Greg Kurz
  1 sibling, 0 replies; 93+ messages in thread
From: Cédric Le Goater @ 2019-09-25  7:06 UTC (permalink / raw)
  To: David Gibson, qemu-ppc, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, philmd

On 25/09/2019 08:45, David Gibson wrote:
> The only reason this parameter was needed was to work around the
> inconsistent meaning of nr_irqs between xics and xive.  Now that we've
> fixed that, we can consistently use the number directly in the SpaprIrq
> configuration.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>

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

> ---
>  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 5190a33e08..300c65be3a 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
>       */
> @@ -443,18 +443,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;
> @@ -683,7 +682,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>          spapr_irq_msi_init(spapr, spapr->irq->nr_msis);
>      }
>  
> -    spapr->irq->init(spapr, spapr->irq->nr_xirqs, errp);
> +    spapr->irq->init(spapr, errp);
>  
>      spapr->qirqs = qemu_allocate_irqs(spapr->irq->set_irq, spapr,
>                                        spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index a8f9a2ab11..7e26288fcd 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -41,7 +41,7 @@ typedef struct SpaprIrq {
>      uint32_t    nr_msis;
>      uint8_t     ov5;
>  
> -    void (*init)(SpaprMachineState *spapr, int nr_irqs, Error **errp);
> +    void (*init)(SpaprMachineState *spapr, Error **errp);
>      int (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
>      void (*free)(SpaprMachineState *spapr, int irq, int num);
>      qemu_irq (*qirq)(SpaprMachineState *spapr, int irq);
> 



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

* Re: [PATCH 11/20] spapr: Fix indexing of XICS irqs
  2019-09-25  6:45 ` [PATCH 11/20] spapr: Fix indexing of XICS irqs David Gibson
@ 2019-09-25  7:11   ` Cédric Le Goater
  2019-09-25 20:17   ` Greg Kurz
  1 sibling, 0 replies; 93+ messages in thread
From: Cédric Le Goater @ 2019-09-25  7:11 UTC (permalink / raw)
  To: David Gibson, qemu-ppc, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, philmd

On 25/09/2019 08:45, David Gibson wrote:
> 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>

The commit log clearly reflects what you think of the current solution 
in the code :) 

It is hideous, but it worked fine and this is even better :) 

Reviewed-by: Cédric Le Goater <clg@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 300c65be3a..9a9e486eb5 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);
>      }
>  }
>  
> @@ -563,11 +563,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)
> 



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

* Re: [PATCH 12/20] spapr: Simplify spapr_qirq() handling
  2019-09-25  6:45 ` [PATCH 12/20] spapr: Simplify spapr_qirq() handling David Gibson
@ 2019-09-25  7:16   ` Cédric Le Goater
  2019-09-25 20:30   ` Greg Kurz
  2019-09-26  7:10   ` Philippe Mathieu-Daudé
  2 siblings, 0 replies; 93+ messages in thread
From: Cédric Le Goater @ 2019-09-25  7:16 UTC (permalink / raw)
  To: David Gibson, qemu-ppc, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, philmd

On 25/09/2019 08:45, David Gibson wrote:
> Currently spapr_qirq() 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.

nice,
 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>

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

C.

> ---
>  hw/ppc/spapr_irq.c         | 47 ++++++++++----------------------------
>  include/hw/ppc/spapr_irq.h |  1 -
>  2 files changed, 12 insertions(+), 36 deletions(-)
> 
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index 9a9e486eb5..038bfffff4 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)
>  {
> @@ -413,7 +387,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,
> @@ -487,11 +460,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);
> @@ -586,7 +554,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,
> @@ -700,7 +667,18 @@ void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
>  
>  qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq)
>  {
> -    return spapr->irq->qirq(spapr, irq);
> +    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)
> @@ -803,7 +781,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);
> 



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

* Re: [PATCH 13/20] spapr: Eliminate SpaprIrq:get_nodename method
  2019-09-25  6:45 ` [PATCH 13/20] spapr: Eliminate SpaprIrq:get_nodename method David Gibson
@ 2019-09-25  7:19   ` Cédric Le Goater
  2019-09-26  7:11   ` Philippe Mathieu-Daudé
  2019-09-26  7:48   ` Greg Kurz
  2 siblings, 0 replies; 93+ messages in thread
From: Cédric Le Goater @ 2019-09-25  7:19 UTC (permalink / raw)
  To: David Gibson, qemu-ppc, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, philmd

On 25/09/2019 08:45, David Gibson wrote:
> 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.
> 
> So, the method is unnecessary.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>

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

> ---
>  hw/ppc/spapr_irq.c         | 25 +++----------------------
>  include/hw/ppc/spapr_irq.h |  1 -
>  2 files changed, 3 insertions(+), 23 deletions(-)
> 
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index 038bfffff4..79167ccc68 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()) {
> @@ -393,7 +382,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,
>  };
>  
> @@ -538,11 +526,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
>   */
> @@ -560,7 +543,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 */
>  };
>  
> @@ -697,13 +679,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;
>      }
>  
> @@ -787,6 +769,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;
>  
> 



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

* Re: [PATCH 14/20] spapr: Remove unhelpful tracepoints from spapr_irq_free_xics()
  2019-09-25  6:45 ` [PATCH 14/20] spapr: Remove unhelpful tracepoints from spapr_irq_free_xics() David Gibson
@ 2019-09-25  7:20   ` Cédric Le Goater
  2019-09-26  7:11   ` Philippe Mathieu-Daudé
  2019-09-26  7:50   ` Greg Kurz
  2 siblings, 0 replies; 93+ messages in thread
From: Cédric Le Goater @ 2019-09-25  7:20 UTC (permalink / raw)
  To: David Gibson, qemu-ppc, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, philmd

On 25/09/2019 08:45, David Gibson wrote:
> 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.

yes. they were always in the way of other changes.  

> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>

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

> ---
>  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 79167ccc68..db6755f3ab 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
> 



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

* Re: [PATCH 15/20] spapr: Handle freeing of multiple irqs in frontend only
  2019-09-25  6:45 ` [PATCH 15/20] spapr: Handle freeing of multiple irqs in frontend only David Gibson
@ 2019-09-25  7:21   ` Cédric Le Goater
  2019-09-26  7:52   ` Greg Kurz
  1 sibling, 0 replies; 93+ messages in thread
From: Cédric Le Goater @ 2019-09-25  7:21 UTC (permalink / raw)
  To: David Gibson, qemu-ppc, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, philmd

On 25/09/2019 08:45, 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.

ok. That was the legacy API. The new one is fine.

> 
> 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 db6755f3ab..c40357a985 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,
> @@ -438,10 +431,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)
> @@ -640,7 +633,11 @@ int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
>  
>  void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
>  {
> -    spapr->irq->free(spapr, irq, num);
> +    int i;
> +
> +    for (i = irq; i < (irq + num); i++) {
> +        spapr->irq->free(spapr, irq);
> +    }
>  }
>  
>  qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq)
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index 9b60378e28..ed88b4599a 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -43,7 +43,7 @@ typedef struct SpaprIrq {
>  
>      void (*init)(SpaprMachineState *spapr, Error **errp);
>      int (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
> -    void (*free)(SpaprMachineState *spapr, int irq, int num);
> +    void (*free)(SpaprMachineState *spapr, int irq);
>      void (*print_info)(SpaprMachineState *spapr, Monitor *mon);
>      void (*dt_populate)(SpaprMachineState *spapr, uint32_t nr_servers,
>                          void *fdt, uint32_t phandle);
> 



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

* Re: [PATCH 16/20] spapr, xics, xive: Better use of assert()s on irq claim/free paths
  2019-09-25  6:45 ` [PATCH 16/20] spapr, xics, xive: Better use of assert()s on irq claim/free paths David Gibson
@ 2019-09-25  7:22   ` Cédric Le Goater
  2019-09-26  8:08   ` Greg Kurz
  1 sibling, 0 replies; 93+ messages in thread
From: Cédric Le Goater @ 2019-09-25  7:22 UTC (permalink / raw)
  To: David Gibson, qemu-ppc, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, philmd

On 25/09/2019 08:45, David Gibson wrote:
> 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>

> ---
>  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 c40357a985..261d66ba17 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)
> @@ -628,6 +624,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);
>  }
>  
> @@ -635,6 +634,9 @@ void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
>  {
>      int i;
>  
> +    assert(irq >= SPAPR_XIRQ_BASE);
> +    assert((irq+num) <= (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));
> +
>      for (i = irq; i < (irq + num); i++) {
>          spapr->irq->free(spapr, irq);
>      }
> 



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

* Re: [PATCH 17/20] spapr: Remove unused return value in claim path
  2019-09-25  6:45 ` [PATCH 17/20] spapr: Remove unused return value in claim path David Gibson
@ 2019-09-25  7:23   ` Cédric Le Goater
  2019-09-26  7:13   ` Philippe Mathieu-Daudé
  2019-09-26  8:36   ` Greg Kurz
  2 siblings, 0 replies; 93+ messages in thread
From: Cédric Le Goater @ 2019-09-25  7:23 UTC (permalink / raw)
  To: David Gibson, qemu-ppc, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, philmd

On 25/09/2019 08:45, David Gibson wrote:
> spapr_irq_claim() and the hooks it is based on return an integer error code
> as well as taking an Error ** parameter.  But none of the callers check the
> integer, so we can remove it and just use the richer Error **.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>

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

> ---
>  hw/ppc/spapr_irq.c         | 32 +++++++++++++-------------------
>  include/hw/ppc/spapr_irq.h |  4 ++--
>  2 files changed, 15 insertions(+), 21 deletions(-)
> 
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index 261d66ba17..2673a90604 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -112,8 +112,8 @@ static void spapr_irq_init_xics(SpaprMachineState *spapr, Error **errp)
>      spapr->ics = ICS_SPAPR(obj);
>  }
>  
> -static int spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
> -                                Error **errp)
> +static void spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
> +                                 Error **errp)
>  {
>      ICSState *ics = spapr->ics;
>  
> @@ -122,11 +122,10 @@ static int spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
>  
>      if (!ics_irq_free(ics, irq - ics->offset)) {
>          error_setg(errp, "IRQ %d is not free", irq);
> -        return -1;
> +        return;
>      }
>  
>      ics_set_irq_type(ics, irq - ics->offset, lsi);
> -    return 0;
>  }
>  
>  static void spapr_irq_free_xics(SpaprMachineState *spapr, int irq)
> @@ -252,14 +251,12 @@ static void spapr_irq_init_xive(SpaprMachineState *spapr, Error **errp)
>      spapr_xive_hcall_init(spapr);
>  }
>  
> -static int spapr_irq_claim_xive(SpaprMachineState *spapr, int irq, bool lsi,
> -                                Error **errp)
> +static void 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;
>  }
>  
>  static void spapr_irq_free_xive(SpaprMachineState *spapr, int irq)
> @@ -406,25 +403,22 @@ static void spapr_irq_init_dual(SpaprMachineState *spapr, Error **errp)
>      }
>  }
>  
> -static int spapr_irq_claim_dual(SpaprMachineState *spapr, int irq, bool lsi,
> -                                Error **errp)
> +static void 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);
> +    spapr_irq_xics.claim(spapr, irq, lsi, &local_err);
>      if (local_err) {
>          error_propagate(errp, local_err);
> -        return ret;
> +        return;
>      }
>  
> -    ret = spapr_irq_xive.claim(spapr, irq, lsi, &local_err);
> +    spapr_irq_xive.claim(spapr, irq, lsi, &local_err);
>      if (local_err) {
>          error_propagate(errp, local_err);
> -        return ret;
> +        return;
>      }
> -
> -    return ret;
>  }
>  
>  static void spapr_irq_free_dual(SpaprMachineState *spapr, int irq)
> @@ -622,12 +616,12 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>                                        spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
>  }
>  
> -int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
> +void 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);
> +    spapr->irq->claim(spapr, irq, lsi, errp);
>  }
>  
>  void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index ed88b4599a..75279ca137 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -42,7 +42,7 @@ typedef struct SpaprIrq {
>      uint8_t     ov5;
>  
>      void (*init)(SpaprMachineState *spapr, Error **errp);
> -    int (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
> +    void (*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,
> @@ -61,7 +61,7 @@ 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_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
>  void spapr_irq_free(SpaprMachineState *spapr, int irq, int num);
>  qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq);
>  int spapr_irq_post_load(SpaprMachineState *spapr, int version_id);
> 



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

* Re: [PATCH 18/20] xive: Improve irq claim/free path
  2019-09-25  6:45 ` [PATCH 18/20] xive: Improve irq claim/free path David Gibson
@ 2019-09-25  7:25   ` Cédric Le Goater
  2019-09-26  1:05     ` David Gibson
  0 siblings, 1 reply; 93+ messages in thread
From: Cédric Le Goater @ 2019-09-25  7:25 UTC (permalink / raw)
  To: David Gibson, qemu-ppc, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, philmd

On 25/09/2019 08:45, David Gibson wrote:
> spapr_xive_irq_claim() returns a bool to indicate if it succeeded.  But
> most of the callers and one callee use a richer Error * instead.  So use
> that instead of a bool return so we can actually pass more informative
> errors up the stack.
> 
> In addition it 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, so
> just drop it.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---
>  hw/intc/spapr_xive.c        | 17 ++++++++++-------
>  hw/ppc/spapr_irq.c          | 12 ++++++++----
>  include/hw/ppc/spapr_xive.h |  5 +++--
>  3 files changed, 21 insertions(+), 13 deletions(-)
> 
> diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
> index 47b5ec0b56..5a56a58299 100644
> --- a/hw/intc/spapr_xive.c
> +++ b/hw/intc/spapr_xive.c
> @@ -528,12 +528,18 @@ 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)
> +void spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi,
> +                          Error **errp)
>  {
>      XiveSource *xsrc = &xive->source;
>  
>      assert(lisn < xive->nr_irqs);
>  
> +    if (be64_to_cpu(xive->eat[lisn].w) & EAS_VALID) {

please use xive_eas_is_valid()

with that change,

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


C. 

> +        error_setg(errp, "IRQ %d is not free", lisn);
> +        return;
> +    }
> +
>      /*
>       * Set default values when allocating an IRQ number
>       */
> @@ -547,20 +553,17 @@ bool spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi)
>  
>          kvmppc_xive_source_reset_one(xsrc, lisn, &local_err);
>          if (local_err) {
> -            error_report_err(local_err);
> -            return false;
> +            error_propagate(errp, local_err);
> +            return;
>          }
>      }
> -
> -    return true;
>  }
>  
> -bool spapr_xive_irq_free(SpaprXive *xive, uint32_t lisn)
> +void spapr_xive_irq_free(SpaprXive *xive, uint32_t lisn)
>  {
>      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 2673a90604..f53544e45e 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -245,7 +245,13 @@ static void spapr_irq_init_xive(SpaprMachineState *spapr, Error **errp)
>  
>      /* Enable the CPU IPIs */
>      for (i = 0; i < nr_servers; ++i) {
> -        spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i, false);
> +        Error *local_err = NULL;
> +
> +        spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i, false, &local_err);
> +        if (local_err) {
> +            error_propagate(errp, local_err);
> +            return;
> +        }
>      }
>  
>      spapr_xive_hcall_init(spapr);
> @@ -254,9 +260,7 @@ static void spapr_irq_init_xive(SpaprMachineState *spapr, Error **errp)
>  static void 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);
> -    }
> +    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..69df3793e1 100644
> --- a/include/hw/ppc/spapr_xive.h
> +++ b/include/hw/ppc/spapr_xive.h
> @@ -54,8 +54,9 @@ 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);
> +void spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi,
> +                          Error **errp);
> +void spapr_xive_irq_free(SpaprXive *xive, uint32_t 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] 93+ messages in thread

* Re: [PATCH 19/20] spapr: Use less cryptic representation of which irq backends are supported
  2019-09-25  6:45 ` [PATCH 19/20] spapr: Use less cryptic representation of which irq backends are supported David Gibson
@ 2019-09-25  7:28   ` Cédric Le Goater
  2019-09-26  9:16   ` Greg Kurz
  1 sibling, 0 replies; 93+ messages in thread
From: Cédric Le Goater @ 2019-09-25  7:28 UTC (permalink / raw)
  To: David Gibson, qemu-ppc, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, philmd

On 25/09/2019 08:45, David Gibson wrote:
> 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.

OK. It looks nice.
 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>


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


> ---
>  hw/ppc/spapr.c             | 15 ++++++++++++---
>  hw/ppc/spapr_hcall.c       |  6 +++---
>  hw/ppc/spapr_irq.c         | 12 ++++++++----
>  include/hw/ppc/spapr_irq.h |  3 ++-
>  4 files changed, 25 insertions(+), 11 deletions(-)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 3742a8cf06..795f6ab505 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -1136,19 +1136,28 @@ static void spapr_dt_ov5_platform_support(SpaprMachineState *spapr, void *fdt,
>      PowerPCCPU *first_ppc_cpu = POWERPC_CPU(first_cpu);
>  
>      char val[2 * 4] = {
> -        23, spapr->irq->ov5, /* Xive mode. */
> +        23, 0x00, /* XICS / XIVE mode */
>          24, 0x00, /* Hash/Radix, filled in below. */
>          25, 0x00, /* Hash options: Segment Tables == no, GTSE == no. */
>          26, 0x40, /* Radix options: GTSE == yes. */
>      };
>  
> +    if (spapr->irq->xics && spapr->irq->xive) {
> +        val[1] = SPAPR_OV5_XIVE_BOTH;
> +    } else if (spapr->irq->xive) {
> +        val[1] = SPAPR_OV5_XIVE_EXPLOIT;
> +    } else {
> +        assert(spapr->irq->xics);
> +        val[1] = SPAPR_OV5_XIVE_LEGACY;
> +    }
> +
>      if (!ppc_check_compat(first_ppc_cpu, CPU_POWERPC_LOGICAL_3_00, 0,
>                            first_ppc_cpu->compat_pvr)) {
>          /*
>           * If we're in a pre POWER9 compat mode then the guest should
>           * do hash and use the legacy interrupt mode
>           */
> -        val[1] = 0x00; /* XICS */
> +        val[1] = SPAPR_OV5_XIVE_LEGACY; /* XICS */
>          val[3] = 0x00; /* Hash */
>      } else if (kvm_enabled()) {
>          if (kvmppc_has_cap_mmu_radix() && kvmppc_has_cap_mmu_hash_v3()) {
> @@ -2837,7 +2846,7 @@ static void spapr_machine_init(MachineState *machine)
>      spapr_ovec_set(spapr->ov5, OV5_DRMEM_V2);
>  
>      /* advertise XIVE on POWER9 machines */
> -    if (spapr->irq->ov5 & (SPAPR_OV5_XIVE_EXPLOIT | SPAPR_OV5_XIVE_BOTH)) {
> +    if (spapr->irq->xive) {
>          spapr_ovec_set(spapr->ov5, OV5_XIVE_EXPLOIT);
>      }
>  
> diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
> index 3d3a67149a..140f05c1c6 100644
> --- a/hw/ppc/spapr_hcall.c
> +++ b/hw/ppc/spapr_hcall.c
> @@ -1784,13 +1784,13 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
>       * terminate the boot.
>       */
>      if (guest_xive) {
> -        if (spapr->irq->ov5 == SPAPR_OV5_XIVE_LEGACY) {
> +        if (!spapr->irq->xive) {
>              error_report(
>  "Guest requested unavailable interrupt mode (XIVE), try the ic-mode=xive or ic-mode=dual machine property");
>              exit(EXIT_FAILURE);
>          }
>      } else {
> -        if (spapr->irq->ov5 == SPAPR_OV5_XIVE_EXPLOIT) {
> +        if (!spapr->irq->xics) {
>              error_report(
>  "Guest requested unavailable interrupt mode (XICS), either don't set the ic-mode machine property or try ic-mode=xics or ic-mode=dual");
>              exit(EXIT_FAILURE);
> @@ -1804,7 +1804,7 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
>       */
>      if (!spapr->cas_reboot) {
>          spapr->cas_reboot = spapr_ovec_test(ov5_updates, OV5_XIVE_EXPLOIT)
> -            && spapr->irq->ov5 & SPAPR_OV5_XIVE_BOTH;
> +            && spapr->irq->xics && spapr->irq->xive;
>      }
>  
>      spapr_ovec_cleanup(ov5_updates);
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index f53544e45e..073f375ba2 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -209,7 +209,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,
> @@ -357,7 +358,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,
> @@ -515,7 +517,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,
> @@ -751,7 +754,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 75279ca137..6816cb0500 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);
>      void (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
> 



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

* Re: [PATCH 20/20] spapr: Eliminate SpaprIrq::init hook
  2019-09-25  6:45 ` [PATCH 20/20] spapr: Eliminate SpaprIrq::init hook David Gibson
@ 2019-09-25  7:31   ` Cédric Le Goater
  2019-09-26  1:13     ` David Gibson
  2019-09-26 15:39   ` Greg Kurz
  1 sibling, 1 reply; 93+ messages in thread
From: Cédric Le Goater @ 2019-09-25  7:31 UTC (permalink / raw)
  To: David Gibson, qemu-ppc, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, philmd

On 25/09/2019 08:45, David Gibson wrote:
> 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>

one comment below,

> ---
>  hw/ppc/spapr_irq.c          | 138 ++++++++++++++++--------------------
>  include/hw/ppc/spapr_irq.h  |   1 -
>  include/hw/ppc/xics_spapr.h |   1 +
>  3 files changed, 63 insertions(+), 77 deletions(-)
> 
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index 073f375ba2..62647dd5a3 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -91,27 +91,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 void spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
>                                   Error **errp)
>  {
> @@ -212,7 +191,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,
> @@ -227,37 +205,6 @@ SpaprIrq spapr_irq_xics = {
>  /*
>   * XIVE IRQ backend.
>   */
> -static void spapr_irq_init_xive(SpaprMachineState *spapr, Error **errp)
> -{
> -    uint32_t nr_servers = spapr_max_server_number(spapr);
> -    DeviceState *dev;
> -    int i;
> -
> -    dev = qdev_create(NULL, TYPE_SPAPR_XIVE);
> -    qdev_prop_set_uint32(dev, "nr-irqs",
> -                         spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
> -    /*
> -     * 8 XIVE END structures per CPU. One for each available priority
> -     */
> -    qdev_prop_set_uint32(dev, "nr-ends", nr_servers << 3);
> -    qdev_init_nofail(dev);
> -
> -    spapr->xive = SPAPR_XIVE(dev);
> -
> -    /* Enable the CPU IPIs */
> -    for (i = 0; i < nr_servers; ++i) {
> -        Error *local_err = NULL;
> -
> -        spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i, false, &local_err);
> -        if (local_err) {
> -            error_propagate(errp, local_err);
> -            return;
> -        }
> -    }
> -
> -    spapr_xive_hcall_init(spapr);
> -}
> -
>  static void spapr_irq_claim_xive(SpaprMachineState *spapr, int irq, bool lsi,
>                                   Error **errp)
>  {
> @@ -361,7 +308,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,
> @@ -392,23 +338,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 void spapr_irq_claim_dual(SpaprMachineState *spapr, int irq, bool lsi,
>                                   Error **errp)
>  {
> @@ -520,7 +449,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,
> @@ -608,8 +536,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>  
>      spapr_irq_check(spapr, &local_err);
>      if (local_err) {
> -        error_propagate(errp, local_err);
> -        return;
> +        goto out;
>      }
>  
>      /* Initialize the MSI IRQ allocator. */
> @@ -617,10 +544,70 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>          spapr_irq_msi_init(spapr, spapr->irq->nr_msis);
>      }
>  
> -    spapr->irq->init(spapr, errp);
> +    if (spapr->irq->xics) {
> +        Object *obj;
> +
> +        obj = object_new(TYPE_ICS_SPAPR);
> +        object_property_add_child(OBJECT(spapr), "ics", obj, &local_err);
> +        if (local_err) {
> +            goto out;
> +        }
> +
> +        object_property_add_const_link(obj, ICS_PROP_XICS, OBJECT(spapr),
> +                                       &local_err);
> +        if (local_err) {
> +            goto out;
> +        }
> +
> +        object_property_set_int(obj, spapr->irq->nr_xirqs, "nr-irqs",
> +                                &local_err);
> +        if (local_err) {
> +            goto out;
> +        }
> +
> +        object_property_set_bool(obj, true, "realized", &local_err);
> +        if (local_err) {
> +            goto out;
> +        }
> +
> +        spapr->ics = ICS_SPAPR(obj);
> +    }
> +
> +    if (spapr->irq->xive) {
> +        uint32_t nr_servers = spapr_max_server_number(spapr);
> +        DeviceState *dev;
> +        int i;
> +
> +        dev = qdev_create(NULL, TYPE_SPAPR_XIVE);
> +        qdev_prop_set_uint32(dev, "nr-irqs",
> +                             spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
> +        /*
> +         * 8 XIVE END structures per CPU. One for each available
> +         * priority
> +         */
> +        qdev_prop_set_uint32(dev, "nr-ends", nr_servers << 3);
> +        qdev_init_nofail(dev);
> +
> +        spapr->xive = SPAPR_XIVE(dev);
> +
> +        /* Enable the CPU IPIs */
> +        for (i = 0; i < nr_servers; ++i) {
> +            Error *local_err = NULL;
> +
> +            spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i, false, &local_err);
> +            if (local_err) {
> +                goto out;
> +            }
> +        }

We could move the IPI claim part in the realize routine of SPAPR_XIVE.


> +        spapr_xive_hcall_init(spapr);

This also.

It can be done later one.

C.

> +    }
>  
>      spapr->qirqs = qemu_allocate_irqs(spapr->irq->set_irq, spapr,
>                                        spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
> +
> +out:
> +    error_propagate(errp, local_err);
>  }
>  
>  void spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
> @@ -757,7 +744,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 6816cb0500..fa862c665b 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);
>      void (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
>      void (*free)(SpaprMachineState *spapr, int irq);
>      void (*print_info)(SpaprMachineState *spapr, Monitor *mon);
> diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h
> index 691a6d00f7..267984a97b 100644
> --- a/include/hw/ppc/xics_spapr.h
> +++ b/include/hw/ppc/xics_spapr.h
> @@ -34,6 +34,7 @@
>  #define TYPE_ICS_SPAPR "ics-spapr"
>  #define ICS_SPAPR(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SPAPR)
>  
> +void ics_spapr_create(SpaprMachineState *spapr, int nr_xirqs, Error **errp);
>  void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
>                     uint32_t phandle);
>  int xics_kvm_connect(SpaprMachineState *spapr, Error **errp);
> 



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

* Re: [PATCH 04/20] xics: Eliminate reset hook
  2019-09-25  6:45 ` [PATCH 04/20] xics: Eliminate reset hook David Gibson
@ 2019-09-25  7:33   ` Cédric Le Goater
  2019-09-25  7:59   ` Greg Kurz
  1 sibling, 0 replies; 93+ messages in thread
From: Cédric Le Goater @ 2019-09-25  7:33 UTC (permalink / raw)
  To: David Gibson, qemu-ppc, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, philmd

On 25/09/2019 08:45, David Gibson wrote:
> Currently TYPE_XICS_BASE and TYPE_XICS_SIMPLE have their own reset methods,
> using the standard technique for having the subtype call the supertype's
> methods before doing its own thing.
> 
> But TYPE_XICS_SIMPLE is the only subtype of TYPE_XICS_BASE ever
> instantiated, so there's no point having the split here.  Merge them
> together into just an ics_reset() function.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>

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

> ---
>  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 e72fb67968..18fcd2b11c 100644
> --- a/include/hw/ppc/xics.h
> +++ b/include/hw/ppc/xics.h
> @@ -105,7 +105,6 @@ struct ICSStateClass {
>      DeviceClass parent_class;
>  
>      DeviceRealize parent_realize;
> -    DeviceReset parent_reset;
>  };
>  
>  struct ICSState {
> 



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

* Re: [PATCH 06/20] xics: Create sPAPR specific ICS subtype
  2019-09-25  6:45 ` [PATCH 06/20] xics: Create sPAPR specific ICS subtype David Gibson
@ 2019-09-25  7:34   ` Cédric Le Goater
  2019-09-25  8:40   ` Greg Kurz
  1 sibling, 0 replies; 93+ messages in thread
From: Cédric Le Goater @ 2019-09-25  7:34 UTC (permalink / raw)
  To: David Gibson, qemu-ppc, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, philmd

On 25/09/2019 08:45, David Gibson wrote:
> We create a subtype of TYPE_ICS specifically for sPAPR.  For now all this
> does is move the setup of the PAPR specific hcalls and RTAS calls to
> the realize() function for this, rather than requiring the PAPR code to
> explicitly call xics_spapr_init().  In future it will have some more
> function.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>

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


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



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

* Re: [PATCH 01/20] xics: Use incomplete type for XICSFabric
  2019-09-25  6:45 ` [PATCH 01/20] xics: Use incomplete type for XICSFabric David Gibson
  2019-09-25  6:55   ` Cédric Le Goater
@ 2019-09-25  7:45   ` Greg Kurz
  1 sibling, 0 replies; 93+ messages in thread
From: Greg Kurz @ 2019-09-25  7:45 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

On Wed, 25 Sep 2019 16:45:15 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> Interface instances should never be directly dereferenced.  So, the common
> practice is to make them incomplete types to make sure no-one does that.
> XICSFrabric, however, had a dummy type which is less safe.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---
>  include/hw/ppc/xics.h | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
> index 64a2c8862a..1ae34ce9cd 100644
> --- a/include/hw/ppc/xics.h
> +++ b/include/hw/ppc/xics.h
> @@ -147,9 +147,7 @@ struct ICSIRQState {
>      uint8_t flags;
>  };
>  
> -struct XICSFabric {
> -    Object parent;
> -};

Ok.

> +typedef struct XICSFabric XICSFabric;
>  

Nak. We already have this statement earlier in this file and
we must keep it there since it is used in the definition of
some other types. I guess this doesn't cause any compiler
warning because the type is incomplete.

With this duplicate typedef removed,

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

>  #define TYPE_XICS_FABRIC "xics-fabric"
>  #define XICS_FABRIC(obj)                                     \



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

* Re: [PATCH 01/20] xics: Use incomplete type for XICSFabric
  2019-09-25  6:55   ` Cédric Le Goater
@ 2019-09-25  7:48     ` Greg Kurz
  0 siblings, 0 replies; 93+ messages in thread
From: Greg Kurz @ 2019-09-25  7:48 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	Marc-André Lureau, Paolo Bonzini, philmd, David Gibson

On Wed, 25 Sep 2019 08:55:50 +0200
Cédric Le Goater <clg@kaod.org> wrote:

> On 25/09/2019 08:45, 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.
> > 
> > Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> > ---
> >  include/hw/ppc/xics.h | 4 +---
> >  1 file changed, 1 insertion(+), 3 deletions(-)
> > 
> > diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
> > index 64a2c8862a..1ae34ce9cd 100644
> > --- a/include/hw/ppc/xics.h
> > +++ b/include/hw/ppc/xics.h
> > @@ -147,9 +147,7 @@ struct ICSIRQState {
> >      uint8_t flags;
> >  };
> >  
> > -struct XICSFabric {
> > -    Object parent;
> > -};
> > +typedef struct XICSFabric XICSFabric;
> >  
> >  #define TYPE_XICS_FABRIC "xics-fabric"
> >  #define XICS_FABRIC(obj)                                     \
> > 
> 
> you should also change :
> 
> #define XICS_FABRIC(obj)                                     \
>     OBJECT_CHECK(XICSFabric, (obj), TYPE_XICS_FABRIC)
> 
> 
> and use INTERFACE_CHECK()
> 

Yes but I think this deserves a separate patch.

> C.



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

* Re: [PATCH 04/20] xics: Eliminate reset hook
  2019-09-25  6:45 ` [PATCH 04/20] xics: Eliminate reset hook David Gibson
  2019-09-25  7:33   ` Cédric Le Goater
@ 2019-09-25  7:59   ` Greg Kurz
  2019-09-26  2:54     ` David Gibson
  1 sibling, 1 reply; 93+ messages in thread
From: Greg Kurz @ 2019-09-25  7:59 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

On Wed, 25 Sep 2019 16:45:18 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

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

As suggested by Philippe, this could be the opportunity to add
a comment that explain why we rely on qemu_register_reset()
rather than dc->reset.

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

I hadn't spotted it previously but since you're removing the call to
device_class_set_parent_reset(), we don't need dc->reset anymore.

This basically reverts:

commit eeefd43b3cf342d1696128462a16e092995ff1b5
Author: Cédric Le Goater <clg@kaod.org>
Date:   Mon Jun 25 11:17:16 2018 +0200

    ppx/xics: introduce a parent_reset in ICSStateClass
    
    Just like for the realize handlers, this makes possible to move the
    common ICSState code of the reset handlers in the ics-base class.
    
    Signed-off-by: Cédric Le Goater <clg@kaod.org>
    Signed-off-by: David Gibson <david@gibson.dropbear.id.au>

With dc->reset removed,

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

>      dc->vmsd = &vmstate_ics_base;
>  }
>  
> diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
> index e72fb67968..18fcd2b11c 100644
> --- a/include/hw/ppc/xics.h
> +++ b/include/hw/ppc/xics.h
> @@ -105,7 +105,6 @@ struct ICSStateClass {
>      DeviceClass parent_class;
>  
>      DeviceRealize parent_realize;
> -    DeviceReset parent_reset;
>  };
>  
>  struct ICSState {



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

* Re: [PATCH 05/20] xics: Merge TYPE_ICS_BASE and TYPE_ICS_SIMPLE classes
  2019-09-25  6:45 ` [PATCH 05/20] xics: Merge TYPE_ICS_BASE and TYPE_ICS_SIMPLE classes David Gibson
@ 2019-09-25  8:16   ` Greg Kurz
  2019-09-25  8:31     ` Greg Kurz
  2019-09-26  0:52     ` David Gibson
  2019-09-25 12:47   ` Cédric Le Goater
  1 sibling, 2 replies; 93+ messages in thread
From: Greg Kurz @ 2019-09-25  8:16 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

On Wed, 25 Sep 2019 16:45:19 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> TYPE_ICS_SIMPLE is the only subtype of TYPE_ICS_BASE that's ever
> instantiated, and the only one we're ever likely to want.  The
> existence of different classes is just a hang over from when we
> (misguidedly) had separate subtypes for the KVM and non-KVM version of
> the device.
> 
> So, collapse the two classes together into just TYPE_ICS.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---

So this also kills the realize hook, unlike in your previous series
where this was done along with the reset hook change. Makes sense
when merging parent/child class as well.

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 18fcd2b11c..5a9b73d144 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;



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

* Re: [PATCH 05/20] xics: Merge TYPE_ICS_BASE and TYPE_ICS_SIMPLE classes
  2019-09-25  8:16   ` Greg Kurz
@ 2019-09-25  8:31     ` Greg Kurz
  2019-09-26  0:55       ` David Gibson
  2019-09-26  0:52     ` David Gibson
  1 sibling, 1 reply; 93+ messages in thread
From: Greg Kurz @ 2019-09-25  8:31 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, 25 Sep 2019 10:16:10 +0200
Greg Kurz <groug@kaod.org> wrote:

> On Wed, 25 Sep 2019 16:45:19 +1000
> David Gibson <david@gibson.dropbear.id.au> wrote:
> 
> > TYPE_ICS_SIMPLE is the only subtype of TYPE_ICS_BASE that's ever
> > instantiated, and the only one we're ever likely to want.  The
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This seems to be kind of contradicted by the next patch BTW. Maybe just
drop that to avoid confusion ? The rest of the changelog explains why we
should merge the classes well enough IMHO.

> > existence of different classes is just a hang over from when we
> > (misguidedly) had separate subtypes for the KVM and non-KVM version of
> > the device.
> > 
> > So, collapse the two classes together into just TYPE_ICS.
> > 
> > Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> > ---
> 
> So this also kills the realize hook, unlike in your previous series
> where this was done along with the reset hook change. Makes sense
> when merging parent/child class as well.
> 
> 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 18fcd2b11c..5a9b73d144 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;
> 
> 



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

* Re: [PATCH 06/20] xics: Create sPAPR specific ICS subtype
  2019-09-25  6:45 ` [PATCH 06/20] xics: Create sPAPR specific ICS subtype David Gibson
  2019-09-25  7:34   ` Cédric Le Goater
@ 2019-09-25  8:40   ` Greg Kurz
  2019-09-25  8:55     ` Cédric Le Goater
  1 sibling, 1 reply; 93+ messages in thread
From: Greg Kurz @ 2019-09-25  8:40 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

On Wed, 25 Sep 2019 16:45:20 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

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

LGTM, but for extra safety I would also introduce a SpaprIcsState typedef
and use it everywhere where we only expect this subtype. Especially in
the definition of SpaprMachineState.

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



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

* Re: [PATCH 06/20] xics: Create sPAPR specific ICS subtype
  2019-09-25  8:40   ` Greg Kurz
@ 2019-09-25  8:55     ` Cédric Le Goater
  2019-09-25  9:07       ` Greg Kurz
  2019-09-26  0:56       ` David Gibson
  0 siblings, 2 replies; 93+ messages in thread
From: Cédric Le Goater @ 2019-09-25  8:55 UTC (permalink / raw)
  To: Greg Kurz, David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	Marc-André Lureau, Paolo Bonzini, philmd

On 25/09/2019 10:40, Greg Kurz wrote:
> On Wed, 25 Sep 2019 16:45:20 +1000
> David Gibson <david@gibson.dropbear.id.au> wrote:
> 
>> We create a subtype of TYPE_ICS specifically for sPAPR.  For now all this
>> does is move the setup of the PAPR specific hcalls and RTAS calls to
>> the realize() function for this, rather than requiring the PAPR code to
>> explicitly call xics_spapr_init().  In future it will have some more
>> function.
>>
>> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
>> ---
> 
> LGTM, but for extra safety I would also introduce a SpaprIcsState typedef

why ? we have ICS_SPAPR() for the checks already.

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



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

* Re: [PATCH 07/20] spapr: Fold spapr_phb_lsi_qirq() into its single caller
  2019-09-25  6:45 ` [PATCH 07/20] spapr: Fold spapr_phb_lsi_qirq() into its single caller David Gibson
  2019-09-25  6:58   ` Cédric Le Goater
@ 2019-09-25  8:56   ` Greg Kurz
  2019-09-26  7:08   ` Philippe Mathieu-Daudé
  2 siblings, 0 replies; 93+ messages in thread
From: Greg Kurz @ 2019-09-25  8:56 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

On Wed, 25 Sep 2019 16:45:21 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> 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: Greg Kurz <groug@kaod.org>

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



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

* Re: [PATCH 08/20] spapr: Replace spapr_vio_qirq() helper with spapr_vio_irq_pulse() helper
  2019-09-25  6:45 ` [PATCH 08/20] spapr: Replace spapr_vio_qirq() helper with spapr_vio_irq_pulse() helper David Gibson
  2019-09-25  6:58   ` Cédric Le Goater
@ 2019-09-25  8:57   ` Greg Kurz
  2019-09-26  7:08   ` Philippe Mathieu-Daudé
  2 siblings, 0 replies; 93+ messages in thread
From: Greg Kurz @ 2019-09-25  8:57 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

On Wed, 25 Sep 2019 16:45:22 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> 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: Greg Kurz <groug@kaod.org>

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



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

* Re: [PATCH 06/20] xics: Create sPAPR specific ICS subtype
  2019-09-25  8:55     ` Cédric Le Goater
@ 2019-09-25  9:07       ` Greg Kurz
  2019-09-26  0:56       ` David Gibson
  1 sibling, 0 replies; 93+ messages in thread
From: Greg Kurz @ 2019-09-25  9:07 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	Marc-André Lureau, Paolo Bonzini, philmd, David Gibson

On Wed, 25 Sep 2019 10:55:35 +0200
Cédric Le Goater <clg@kaod.org> wrote:

> On 25/09/2019 10:40, Greg Kurz wrote:
> > On Wed, 25 Sep 2019 16:45:20 +1000
> > David Gibson <david@gibson.dropbear.id.au> wrote:
> > 
> >> We create a subtype of TYPE_ICS specifically for sPAPR.  For now all this
> >> does is move the setup of the PAPR specific hcalls and RTAS calls to
> >> the realize() function for this, rather than requiring the PAPR code to
> >> explicitly call xics_spapr_init().  In future it will have some more
> >> function.
> >>
> >> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> >> ---
> > 
> > LGTM, but for extra safety I would also introduce a SpaprIcsState typedef
> 
> why ? we have ICS_SPAPR() for the checks already.
> 

This is a runtime check. Having a typedef would allow to catch
a buggy assignment of a non-sPAPR ICS pointer at compile time.

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



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

* Re: [PATCH 05/20] xics: Merge TYPE_ICS_BASE and TYPE_ICS_SIMPLE classes
  2019-09-25  6:45 ` [PATCH 05/20] xics: Merge TYPE_ICS_BASE and TYPE_ICS_SIMPLE classes David Gibson
  2019-09-25  8:16   ` Greg Kurz
@ 2019-09-25 12:47   ` Cédric Le Goater
  1 sibling, 0 replies; 93+ messages in thread
From: Cédric Le Goater @ 2019-09-25 12:47 UTC (permalink / raw)
  To: David Gibson, qemu-ppc, qemu-devel
  Cc: Jason Wang, Riku Voipio, groug, Laurent Vivier,
	Marc-André Lureau, Paolo Bonzini, philmd

On 25/09/2019 08:45, David Gibson wrote:
> TYPE_ICS_SIMPLE is the only subtype of TYPE_ICS_BASE that's ever
> instantiated, and the only one we're ever likely to want.  The
> existence of different classes is just a hang over from when we
> (misguidedly) had separate subtypes for the KVM and non-KVM version of
> the device.
> 
> 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>

> ---
>  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 18fcd2b11c..5a9b73d144 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;
> 



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

* Re: [PATCH 09/20] spapr: Clarify and fix handling of nr_irqs
  2019-09-25  6:45 ` [PATCH 09/20] spapr: Clarify and fix handling of nr_irqs David Gibson
  2019-09-25  7:05   ` Cédric Le Goater
@ 2019-09-25 17:13   ` Greg Kurz
  1 sibling, 0 replies; 93+ messages in thread
From: Greg Kurz @ 2019-09-25 17:13 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

On Wed, 25 Sep 2019 16:45:23 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> Both the XICS and XIVE interrupt backends have a "nr-irqs" property, but
> it means slightly different things.  For XICS (or, strictly, the ICS) it
> indicates the number of "real" external IRQs.  Those start at XICS_IRQ_BASE
> (0x1000) and don't include the special IPI vector.  For XIVE, however, it
> includes the whole IRQ space, including XIVE's many IPI vectors.
> 
> The spapr code currently doesn't handle this sensibly, with the nr_irqs
> value in SpaprIrq having different meanings depending on the backend.
> We fix this by renaming nr_irqs to nr_xirqs and making it always indicate
> just the number of external irqs, adjusting the value we pass to XIVE
> accordingly.  We also use move to using common constants in most of the
                        ^^^
s/use//

> 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         | 48 +++++++++++++++-----------------------
>  include/hw/ppc/spapr_irq.h | 19 +++++++++------
>  2 files changed, 31 insertions(+), 36 deletions(-)
> 
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index 8c26fa2d1e..5190a33e08 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;
>      }
>  
> @@ -409,12 +405,9 @@ static void spapr_irq_init_kvm_xive(SpaprMachineState *spapr, Error **errp)
>   * 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 +443,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 +579,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 +683,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 +794,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] 93+ messages in thread

* Re: [PATCH 10/20] spapr: Eliminate nr_irqs parameter to SpaprIrq::init
  2019-09-25  6:45 ` [PATCH 10/20] spapr: Eliminate nr_irqs parameter to SpaprIrq::init David Gibson
  2019-09-25  7:06   ` Cédric Le Goater
@ 2019-09-25 17:16   ` Greg Kurz
  1 sibling, 0 replies; 93+ messages in thread
From: Greg Kurz @ 2019-09-25 17:16 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

On Wed, 25 Sep 2019 16:45:24 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

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

Reviewed-by: 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 5190a33e08..300c65be3a 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
>       */
> @@ -443,18 +443,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;
> @@ -683,7 +682,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>          spapr_irq_msi_init(spapr, spapr->irq->nr_msis);
>      }
>  
> -    spapr->irq->init(spapr, spapr->irq->nr_xirqs, errp);
> +    spapr->irq->init(spapr, errp);
>  
>      spapr->qirqs = qemu_allocate_irqs(spapr->irq->set_irq, spapr,
>                                        spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index a8f9a2ab11..7e26288fcd 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -41,7 +41,7 @@ typedef struct SpaprIrq {
>      uint32_t    nr_msis;
>      uint8_t     ov5;
>  
> -    void (*init)(SpaprMachineState *spapr, int nr_irqs, Error **errp);
> +    void (*init)(SpaprMachineState *spapr, Error **errp);
>      int (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
>      void (*free)(SpaprMachineState *spapr, int irq, int num);
>      qemu_irq (*qirq)(SpaprMachineState *spapr, int irq);



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

* Re: [PATCH 11/20] spapr: Fix indexing of XICS irqs
  2019-09-25  6:45 ` [PATCH 11/20] spapr: Fix indexing of XICS irqs David Gibson
  2019-09-25  7:11   ` Cédric Le Goater
@ 2019-09-25 20:17   ` Greg Kurz
  2019-09-26  1:31     ` David Gibson
  1 sibling, 1 reply; 93+ messages in thread
From: Greg Kurz @ 2019-09-25 20:17 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

On Wed, 25 Sep 2019 16:45:25 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> 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: Greg Kurz <groug@kaod.org>

Further cleanup could be to have the XICS backend to only take global
irq numbers and to convert them to ICS source numbers internally. This
would put an end to the confusion between srcno/irq in the frontend
code.

>  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 300c65be3a..9a9e486eb5 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);
>      }
>  }
>  
> @@ -563,11 +563,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)



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

* Re: [PATCH 12/20] spapr: Simplify spapr_qirq() handling
  2019-09-25  6:45 ` [PATCH 12/20] spapr: Simplify spapr_qirq() handling David Gibson
  2019-09-25  7:16   ` Cédric Le Goater
@ 2019-09-25 20:30   ` Greg Kurz
  2019-09-26  7:10   ` Philippe Mathieu-Daudé
  2 siblings, 0 replies; 93+ messages in thread
From: Greg Kurz @ 2019-09-25 20:30 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

On Wed, 25 Sep 2019 16:45:26 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> Currently spapr_qirq() 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: Greg Kurz <groug@kaod.org>

>  hw/ppc/spapr_irq.c         | 47 ++++++++++----------------------------
>  include/hw/ppc/spapr_irq.h |  1 -
>  2 files changed, 12 insertions(+), 36 deletions(-)
> 
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index 9a9e486eb5..038bfffff4 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)
>  {
> @@ -413,7 +387,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,
> @@ -487,11 +460,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);
> @@ -586,7 +554,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,
> @@ -700,7 +667,18 @@ void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
>  
>  qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq)
>  {
> -    return spapr->irq->qirq(spapr, irq);
> +    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)
> @@ -803,7 +781,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);



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

* Re: [PATCH 05/20] xics: Merge TYPE_ICS_BASE and TYPE_ICS_SIMPLE classes
  2019-09-25  8:16   ` Greg Kurz
  2019-09-25  8:31     ` Greg Kurz
@ 2019-09-26  0:52     ` David Gibson
  1 sibling, 0 replies; 93+ messages in thread
From: David Gibson @ 2019-09-26  0:52 UTC (permalink / raw)
  To: Greg Kurz
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

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

On Wed, Sep 25, 2019 at 10:16:10AM +0200, Greg Kurz wrote:
> On Wed, 25 Sep 2019 16:45:19 +1000
> David Gibson <david@gibson.dropbear.id.au> wrote:
> 
> > TYPE_ICS_SIMPLE is the only subtype of TYPE_ICS_BASE that's ever
> > instantiated, and the only one we're ever likely to want.  The
> > existence of different classes is just a hang over from when we
> > (misguidedly) had separate subtypes for the KVM and non-KVM version of
> > the device.
> > 
> > So, collapse the two classes together into just TYPE_ICS.
> > 
> > Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> > ---
> 
> So this also kills the realize hook, unlike in your previous series
> where this was done along with the reset hook change. Makes sense
> when merging parent/child class as well.

Actually, it doesn't  There's now only one actual implementation of
the realize handler, but I left the parent_realize hook in there for
future use.

> 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 18fcd2b11c..5a9b73d144 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;
> 

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

* Re: [PATCH 05/20] xics: Merge TYPE_ICS_BASE and TYPE_ICS_SIMPLE classes
  2019-09-25  8:31     ` Greg Kurz
@ 2019-09-26  0:55       ` David Gibson
  0 siblings, 0 replies; 93+ messages in thread
From: David Gibson @ 2019-09-26  0:55 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: 11238 bytes --]

On Wed, Sep 25, 2019 at 10:31:12AM +0200, Greg Kurz wrote:
> On Wed, 25 Sep 2019 10:16:10 +0200
> Greg Kurz <groug@kaod.org> wrote:
> 
> > On Wed, 25 Sep 2019 16:45:19 +1000
> > David Gibson <david@gibson.dropbear.id.au> wrote:
> > 
> > > TYPE_ICS_SIMPLE is the only subtype of TYPE_ICS_BASE that's ever
> > > instantiated, and the only one we're ever likely to want.  The
>                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> This seems to be kind of contradicted by the next patch BTW. Maybe just
> drop that to avoid confusion ? The rest of the changelog explains why we
> should merge the classes well enough IMHO.

Yeah, good point.

> 
> > > existence of different classes is just a hang over from when we
> > > (misguidedly) had separate subtypes for the KVM and non-KVM version of
> > > the device.
> > > 
> > > So, collapse the two classes together into just TYPE_ICS.
> > > 
> > > Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> > > ---
> > 
> > So this also kills the realize hook, unlike in your previous series
> > where this was done along with the reset hook change. Makes sense
> > when merging parent/child class as well.
> > 
> > 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 18fcd2b11c..5a9b73d144 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;
> > 
> > 
> 

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

* Re: [PATCH 06/20] xics: Create sPAPR specific ICS subtype
  2019-09-25  8:55     ` Cédric Le Goater
  2019-09-25  9:07       ` Greg Kurz
@ 2019-09-26  0:56       ` David Gibson
  2019-09-26  7:09         ` Cédric Le Goater
  2019-09-27 16:05         ` Greg Kurz
  1 sibling, 2 replies; 93+ messages in thread
From: David Gibson @ 2019-09-26  0:56 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Jason Wang, Riku Voipio, Greg Kurz, qemu-devel, qemu-ppc,
	Marc-André Lureau, Paolo Bonzini, philmd, Laurent Vivier

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

On Wed, Sep 25, 2019 at 10:55:35AM +0200, Cédric Le Goater wrote:
> On 25/09/2019 10:40, Greg Kurz wrote:
> > On Wed, 25 Sep 2019 16:45:20 +1000
> > David Gibson <david@gibson.dropbear.id.au> wrote:
> > 
> >> We create a subtype of TYPE_ICS specifically for sPAPR.  For now all this
> >> does is move the setup of the PAPR specific hcalls and RTAS calls to
> >> the realize() function for this, rather than requiring the PAPR code to
> >> explicitly call xics_spapr_init().  In future it will have some more
> >> function.
> >>
> >> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> >> ---
> > 
> > LGTM, but for extra safety I would also introduce a SpaprIcsState typedef
> 
> why ? we have ICS_SPAPR() for the checks already.

Eh.. using typedefs when we haven't actually extended a base type
isn't common QOM practice.  Yes, it's not as typesafe as it could be,
but I'm not really inclined to go to the extra effort here.

> 
> > and use it everywhere where we only expect this subtype. Especially in
> > the definition of SpaprMachineState.
> > 
> >>  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 */
> > 
> 

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

* Re: [PATCH 09/20] spapr: Clarify and fix handling of nr_irqs
  2019-09-25  7:05   ` Cédric Le Goater
@ 2019-09-26  1:03     ` David Gibson
  2019-09-26  7:02       ` Cédric Le Goater
  0 siblings, 1 reply; 93+ messages in thread
From: David Gibson @ 2019-09-26  1:03 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Jason Wang, Riku Voipio, qemu-devel, groug, qemu-ppc,
	Marc-André Lureau, Paolo Bonzini, philmd, Laurent Vivier

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

On Wed, Sep 25, 2019 at 09:05:34AM +0200, Cédric Le Goater wrote:
> On 25/09/2019 08:45, 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 use 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: Cédric Le Goater <clg@kaod.org>
> 
> one comment below,
> 
> > ---
> >  hw/ppc/spapr_irq.c         | 48 +++++++++++++++-----------------------
> >  include/hw/ppc/spapr_irq.h | 19 +++++++++------
> >  2 files changed, 31 insertions(+), 36 deletions(-)
> > 
> > diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> > index 8c26fa2d1e..5190a33e08 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)) {
> 
> So IPIs cannot be pulsed ? I think that is OK in QEMU.

They can be pulsed, they just can't be retrieved via the spapr_qirq()
interface.  Since that interface basically exists for the spapr root
devices (VIO and PHBs) to find the qemu_irqs to wire themselves up to,
I think that's fine.

If we discover some reason we need to grab IPI qirqs by global number
then we can revisit this.

I'll add a comment to clarify this in the later patch where I unify
the qirq implementations.

> XIVE unifies all the interrupts at the controller level. Any one can trigger 
> an interrupt with a store on the associate ESB page.

Absolutely, and nothing's stopping them.
> 
> >          return NULL;
> >      }
> >  
> > @@ -409,12 +405,9 @@ static void spapr_irq_init_kvm_xive(SpaprMachineState *spapr, Error **errp)
> >   * 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 +443,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 +579,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 +683,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 +794,11 @@ int spapr_irq_find(SpaprMachineState *spapr, int num, bool align, Error **errp)
> >      return first + ics->offset;
> >  }
> >  
> > -#define SPAPR_IRQ_XICS_LEGACY_NR_IRQS     0x400
> > +#define SPAPR_IRQ_XICS_LEGACY_NR_XIRQS     0x400
> >  
> >  SpaprIrq spapr_irq_xics_legacy = {
> > -    .nr_irqs     = SPAPR_IRQ_XICS_LEGACY_NR_IRQS,
> > -    .nr_msis     = SPAPR_IRQ_XICS_LEGACY_NR_IRQS,
> > +    .nr_xirqs    = SPAPR_IRQ_XICS_LEGACY_NR_XIRQS,
> > +    .nr_msis     = SPAPR_IRQ_XICS_LEGACY_NR_XIRQS,
> >      .ov5         = SPAPR_OV5_XIVE_LEGACY,
> >  
> >      .init        = spapr_irq_init_xics,
> > diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> > index 5db305165c..a8f9a2ab11 100644
> > --- a/include/hw/ppc/spapr_irq.h
> > +++ b/include/hw/ppc/spapr_irq.h
> > @@ -16,13 +16,18 @@
> >   * IRQ range offsets per device type
> >   */
> >  #define SPAPR_IRQ_IPI        0x0
> > -#define SPAPR_IRQ_EPOW       0x1000  /* XICS_IRQ_BASE offset */
> > -#define SPAPR_IRQ_HOTPLUG    0x1001
> > -#define SPAPR_IRQ_VIO        0x1100  /* 256 VIO devices */
> > -#define SPAPR_IRQ_PCI_LSI    0x1200  /* 32+ PHBs devices */
> >  
> > -#define SPAPR_IRQ_MSI        0x1300  /* Offset of the dynamic range covered
> > -                                      * by the bitmap allocator */
> > +#define SPAPR_XIRQ_BASE      XICS_IRQ_BASE /* 0x1000 */
> > +#define SPAPR_IRQ_EPOW       (SPAPR_XIRQ_BASE + 0x0000)
> > +#define SPAPR_IRQ_HOTPLUG    (SPAPR_XIRQ_BASE + 0x0001)
> > +#define SPAPR_IRQ_VIO        (SPAPR_XIRQ_BASE + 0x0100)  /* 256 VIO devices */
> > +#define SPAPR_IRQ_PCI_LSI    (SPAPR_XIRQ_BASE + 0x0200)  /* 32+ PHBs devices */
> > +
> > +/* Offset of the dynamic range covered by the bitmap allocator */
> > +#define SPAPR_IRQ_MSI        (SPAPR_XIRQ_BASE + 0x0300)
> > +
> > +#define SPAPR_NR_XIRQS       0x1000
> > +#define SPAPR_NR_MSIS        (SPAPR_XIRQ_BASE + SPAPR_NR_XIRQS - SPAPR_IRQ_MSI)
> >  
> >  typedef struct SpaprMachineState SpaprMachineState;
> >  
> > @@ -32,7 +37,7 @@ int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align,
> >  void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, uint32_t num);
> >  
> >  typedef struct SpaprIrq {
> > -    uint32_t    nr_irqs;
> > +    uint32_t    nr_xirqs;
> >      uint32_t    nr_msis;
> >      uint8_t     ov5;
> >  
> > 
> 

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

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

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

* Re: [PATCH 18/20] xive: Improve irq claim/free path
  2019-09-25  7:25   ` Cédric Le Goater
@ 2019-09-26  1:05     ` David Gibson
  0 siblings, 0 replies; 93+ messages in thread
From: David Gibson @ 2019-09-26  1:05 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Jason Wang, Riku Voipio, qemu-devel, groug, qemu-ppc,
	Marc-André Lureau, Paolo Bonzini, philmd, Laurent Vivier

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

On Wed, Sep 25, 2019 at 09:25:47AM +0200, Cédric Le Goater wrote:
> On 25/09/2019 08:45, David Gibson wrote:
> > spapr_xive_irq_claim() returns a bool to indicate if it succeeded.  But
> > most of the callers and one callee use a richer Error * instead.  So use
> > that instead of a bool return so we can actually pass more informative
> > errors up the stack.
> > 
> > In addition it 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, so
> > just drop it.
> > 
> > Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> > ---
> >  hw/intc/spapr_xive.c        | 17 ++++++++++-------
> >  hw/ppc/spapr_irq.c          | 12 ++++++++----
> >  include/hw/ppc/spapr_xive.h |  5 +++--
> >  3 files changed, 21 insertions(+), 13 deletions(-)
> > 
> > diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
> > index 47b5ec0b56..5a56a58299 100644
> > --- a/hw/intc/spapr_xive.c
> > +++ b/hw/intc/spapr_xive.c
> > @@ -528,12 +528,18 @@ 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)
> > +void spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi,
> > +                          Error **errp)
> >  {
> >      XiveSource *xsrc = &xive->source;
> >  
> >      assert(lisn < xive->nr_irqs);
> >  
> > +    if (be64_to_cpu(xive->eat[lisn].w) & EAS_VALID) {
> 
> please use xive_eas_is_valid()

Oops, missed that that existed.  Fixed.

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

Oops, missed

> 
> 
> C. 
> 
> > +        error_setg(errp, "IRQ %d is not free", lisn);
> > +        return;
> > +    }
> > +
> >      /*
> >       * Set default values when allocating an IRQ number
> >       */
> > @@ -547,20 +553,17 @@ bool spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi)
> >  
> >          kvmppc_xive_source_reset_one(xsrc, lisn, &local_err);
> >          if (local_err) {
> > -            error_report_err(local_err);
> > -            return false;
> > +            error_propagate(errp, local_err);
> > +            return;
> >          }
> >      }
> > -
> > -    return true;
> >  }
> >  
> > -bool spapr_xive_irq_free(SpaprXive *xive, uint32_t lisn)
> > +void spapr_xive_irq_free(SpaprXive *xive, uint32_t lisn)
> >  {
> >      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 2673a90604..f53544e45e 100644
> > --- a/hw/ppc/spapr_irq.c
> > +++ b/hw/ppc/spapr_irq.c
> > @@ -245,7 +245,13 @@ static void spapr_irq_init_xive(SpaprMachineState *spapr, Error **errp)
> >  
> >      /* Enable the CPU IPIs */
> >      for (i = 0; i < nr_servers; ++i) {
> > -        spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i, false);
> > +        Error *local_err = NULL;
> > +
> > +        spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i, false, &local_err);
> > +        if (local_err) {
> > +            error_propagate(errp, local_err);
> > +            return;
> > +        }
> >      }
> >  
> >      spapr_xive_hcall_init(spapr);
> > @@ -254,9 +260,7 @@ static void spapr_irq_init_xive(SpaprMachineState *spapr, Error **errp)
> >  static void 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);
> > -    }
> > +    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..69df3793e1 100644
> > --- a/include/hw/ppc/spapr_xive.h
> > +++ b/include/hw/ppc/spapr_xive.h
> > @@ -54,8 +54,9 @@ 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);
> > +void spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi,
> > +                          Error **errp);
> > +void spapr_xive_irq_free(SpaprXive *xive, uint32_t 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] 93+ messages in thread

* Re: [PATCH 20/20] spapr: Eliminate SpaprIrq::init hook
  2019-09-25  7:31   ` Cédric Le Goater
@ 2019-09-26  1:13     ` David Gibson
  2019-09-26  7:05       ` Cédric Le Goater
  0 siblings, 1 reply; 93+ messages in thread
From: David Gibson @ 2019-09-26  1:13 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Jason Wang, Riku Voipio, qemu-devel, groug, qemu-ppc,
	Marc-André Lureau, Paolo Bonzini, philmd, Laurent Vivier

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

On Wed, Sep 25, 2019 at 09:31:54AM +0200, Cédric Le Goater wrote:
> On 25/09/2019 08:45, David Gibson wrote:
> > 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>
> 
> one comment below,
> 
> > ---
> >  hw/ppc/spapr_irq.c          | 138 ++++++++++++++++--------------------
> >  include/hw/ppc/spapr_irq.h  |   1 -
> >  include/hw/ppc/xics_spapr.h |   1 +
> >  3 files changed, 63 insertions(+), 77 deletions(-)
> > 
> > diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> > index 073f375ba2..62647dd5a3 100644
> > --- a/hw/ppc/spapr_irq.c
> > +++ b/hw/ppc/spapr_irq.c
> > @@ -91,27 +91,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 void spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
> >                                   Error **errp)
> >  {
> > @@ -212,7 +191,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,
> > @@ -227,37 +205,6 @@ SpaprIrq spapr_irq_xics = {
> >  /*
> >   * XIVE IRQ backend.
> >   */
> > -static void spapr_irq_init_xive(SpaprMachineState *spapr, Error **errp)
> > -{
> > -    uint32_t nr_servers = spapr_max_server_number(spapr);
> > -    DeviceState *dev;
> > -    int i;
> > -
> > -    dev = qdev_create(NULL, TYPE_SPAPR_XIVE);
> > -    qdev_prop_set_uint32(dev, "nr-irqs",
> > -                         spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
> > -    /*
> > -     * 8 XIVE END structures per CPU. One for each available priority
> > -     */
> > -    qdev_prop_set_uint32(dev, "nr-ends", nr_servers << 3);
> > -    qdev_init_nofail(dev);
> > -
> > -    spapr->xive = SPAPR_XIVE(dev);
> > -
> > -    /* Enable the CPU IPIs */
> > -    for (i = 0; i < nr_servers; ++i) {
> > -        Error *local_err = NULL;
> > -
> > -        spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i, false, &local_err);
> > -        if (local_err) {
> > -            error_propagate(errp, local_err);
> > -            return;
> > -        }
> > -    }
> > -
> > -    spapr_xive_hcall_init(spapr);
> > -}
> > -
> >  static void spapr_irq_claim_xive(SpaprMachineState *spapr, int irq, bool lsi,
> >                                   Error **errp)
> >  {
> > @@ -361,7 +308,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,
> > @@ -392,23 +338,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 void spapr_irq_claim_dual(SpaprMachineState *spapr, int irq, bool lsi,
> >                                   Error **errp)
> >  {
> > @@ -520,7 +449,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,
> > @@ -608,8 +536,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
> >  
> >      spapr_irq_check(spapr, &local_err);
> >      if (local_err) {
> > -        error_propagate(errp, local_err);
> > -        return;
> > +        goto out;
> >      }
> >  
> >      /* Initialize the MSI IRQ allocator. */
> > @@ -617,10 +544,70 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
> >          spapr_irq_msi_init(spapr, spapr->irq->nr_msis);
> >      }
> >  
> > -    spapr->irq->init(spapr, errp);
> > +    if (spapr->irq->xics) {
> > +        Object *obj;
> > +
> > +        obj = object_new(TYPE_ICS_SPAPR);
> > +        object_property_add_child(OBJECT(spapr), "ics", obj, &local_err);
> > +        if (local_err) {
> > +            goto out;
> > +        }
> > +
> > +        object_property_add_const_link(obj, ICS_PROP_XICS, OBJECT(spapr),
> > +                                       &local_err);
> > +        if (local_err) {
> > +            goto out;
> > +        }
> > +
> > +        object_property_set_int(obj, spapr->irq->nr_xirqs, "nr-irqs",
> > +                                &local_err);
> > +        if (local_err) {
> > +            goto out;
> > +        }
> > +
> > +        object_property_set_bool(obj, true, "realized", &local_err);
> > +        if (local_err) {
> > +            goto out;
> > +        }
> > +
> > +        spapr->ics = ICS_SPAPR(obj);
> > +    }
> > +
> > +    if (spapr->irq->xive) {
> > +        uint32_t nr_servers = spapr_max_server_number(spapr);
> > +        DeviceState *dev;
> > +        int i;
> > +
> > +        dev = qdev_create(NULL, TYPE_SPAPR_XIVE);
> > +        qdev_prop_set_uint32(dev, "nr-irqs",
> > +                             spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
> > +        /*
> > +         * 8 XIVE END structures per CPU. One for each available
> > +         * priority
> > +         */
> > +        qdev_prop_set_uint32(dev, "nr-ends", nr_servers << 3);
> > +        qdev_init_nofail(dev);
> > +
> > +        spapr->xive = SPAPR_XIVE(dev);
> > +
> > +        /* Enable the CPU IPIs */
> > +        for (i = 0; i < nr_servers; ++i) {
> > +            Error *local_err = NULL;
> > +
> > +            spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i, false, &local_err);
> > +            if (local_err) {
> > +                goto out;
> > +            }
> > +        }
> 
> We could move the IPI claim part in the realize routine of SPAPR_XIVE.

Yeah, I know.  I thought about this, but there's a slight complication
in that the XIVE part doesn't know nr_servers directly.  There's
several possible ways to handle that, but I wasn't 100% happy with any
that I came up with yet.
> 
> > +        spapr_xive_hcall_init(spapr);
> 
> This also.

Right.

> It can be done later one.

That's my intention.

> 
> C.
> 
> > +    }
> >  
> >      spapr->qirqs = qemu_allocate_irqs(spapr->irq->set_irq, spapr,
> >                                        spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
> > +
> > +out:
> > +    error_propagate(errp, local_err);
> >  }
> >  
> >  void spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
> > @@ -757,7 +744,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 6816cb0500..fa862c665b 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);
> >      void (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
> >      void (*free)(SpaprMachineState *spapr, int irq);
> >      void (*print_info)(SpaprMachineState *spapr, Monitor *mon);
> > diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h
> > index 691a6d00f7..267984a97b 100644
> > --- a/include/hw/ppc/xics_spapr.h
> > +++ b/include/hw/ppc/xics_spapr.h
> > @@ -34,6 +34,7 @@
> >  #define TYPE_ICS_SPAPR "ics-spapr"
> >  #define ICS_SPAPR(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SPAPR)
> >  
> > +void ics_spapr_create(SpaprMachineState *spapr, int nr_xirqs, Error **errp);
> >  void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
> >                     uint32_t phandle);
> >  int xics_kvm_connect(SpaprMachineState *spapr, Error **errp);
> > 
> 

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

* Re: [PATCH 11/20] spapr: Fix indexing of XICS irqs
  2019-09-25 20:17   ` Greg Kurz
@ 2019-09-26  1:31     ` David Gibson
  2019-09-26  7:21       ` Greg Kurz
  0 siblings, 1 reply; 93+ messages in thread
From: David Gibson @ 2019-09-26  1:31 UTC (permalink / raw)
  To: Greg Kurz
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

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

On Wed, Sep 25, 2019 at 10:17:46PM +0200, Greg Kurz wrote:
> On Wed, 25 Sep 2019 16:45:25 +1000
> David Gibson <david@gibson.dropbear.id.au> wrote:
> 
> > 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: Greg Kurz <groug@kaod.org>
> 
> Further cleanup could be to have the XICS backend to only take global
> irq numbers and to convert them to ICS source numbers internally. This
> would put an end to the confusion between srcno/irq in the frontend
> code.

Yeah, maybe.  But the local srcnos do actually make sense from within
the perspective of ICS, so I'm not all that keen to do that.

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

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

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

On Wed, Sep 25, 2019 at 09:59:52AM +0200, Greg Kurz wrote:
> On Wed, 25 Sep 2019 16:45:18 +1000
> David Gibson <david@gibson.dropbear.id.au> wrote:
> 
> > Currently TYPE_XICS_BASE and TYPE_XICS_SIMPLE have their own reset methods,
> > using the standard technique for having the subtype call the supertype's
> > methods before doing its own thing.
> > 
> > But TYPE_XICS_SIMPLE is the only subtype of TYPE_XICS_BASE ever
> > instantiated, so there's no point having the split here.  Merge them
> > together into just an ics_reset() function.
> > 
> > Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> > ---
> >  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);
> 
> As suggested by Philippe, this could be the opportunity to add
> a comment that explain why we rely on qemu_register_reset()
> rather than dc->reset.

I don't thinmk it's really in scope for this patch, since it was there
just as bare before.  I'm considering it for another patch, but I'm
still thinking about exactly what I want to do with the reset.

> 
> >  }
> >  
> >  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;
> 
> I hadn't spotted it previously but since you're removing the call to
> device_class_set_parent_reset(), we don't need dc->reset anymore.

Hrm, I'd prefer to leave it in there, even though it's not strictly
necessary - this way calling device_reset() on the ICS will do what
you'd expect

> 
> This basically reverts:
> 
> commit eeefd43b3cf342d1696128462a16e092995ff1b5
> Author: Cédric Le Goater <clg@kaod.org>
> Date:   Mon Jun 25 11:17:16 2018 +0200
> 
>     ppx/xics: introduce a parent_reset in ICSStateClass
>     
>     Just like for the realize handlers, this makes possible to move the
>     common ICSState code of the reset handlers in the ics-base class.
>     
>     Signed-off-by: Cédric Le Goater <clg@kaod.org>
>     Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> 
> With dc->reset removed,
> 
> Reviewed-by: Greg Kurz <groug@kaod.org>
> 
> >      dc->vmsd = &vmstate_ics_base;
> >  }
> >  
> > diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
> > index e72fb67968..18fcd2b11c 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 {
> 

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

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

On 26/09/2019 03:03, David Gibson wrote:
> On Wed, Sep 25, 2019 at 09:05:34AM +0200, Cédric Le Goater wrote:
>> On 25/09/2019 08:45, 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 use 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: Cédric Le Goater <clg@kaod.org>
>>
>> one comment below,
>>
>>> ---
>>>  hw/ppc/spapr_irq.c         | 48 +++++++++++++++-----------------------
>>>  include/hw/ppc/spapr_irq.h | 19 +++++++++------
>>>  2 files changed, 31 insertions(+), 36 deletions(-)
>>>
>>> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
>>> index 8c26fa2d1e..5190a33e08 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)) {
>>
>> So IPIs cannot be pulsed ? I think that is OK in QEMU.
> 
> They can be pulsed, they just can't be retrieved via the spapr_qirq()
> interface.  Since that interface basically exists for the spapr root
> devices (VIO and PHBs) to find the qemu_irqs to wire themselves up to,
> I think that's fine.
> 
> If we discover some reason we need to grab IPI qirqs by global number
> then we can revisit this.

Not from QEMU I think. This is fine.

C. 

> 
> I'll add a comment to clarify this in the later patch where I unify
> the qirq implementations.
> 
>> XIVE unifies all the interrupts at the controller level. Any one can trigger 
>> an interrupt with a store on the associate ESB page.
> 
> Absolutely, and nothing's stopping them.
>>
>>>          return NULL;
>>>      }
>>>  
>>> @@ -409,12 +405,9 @@ static void spapr_irq_init_kvm_xive(SpaprMachineState *spapr, Error **errp)
>>>   * 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 +443,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 +579,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 +683,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 +794,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] 93+ messages in thread

* Re: [PATCH 20/20] spapr: Eliminate SpaprIrq::init hook
  2019-09-26  1:13     ` David Gibson
@ 2019-09-26  7:05       ` Cédric Le Goater
  2019-09-26 11:29         ` David Gibson
  2019-09-26 15:35         ` Greg Kurz
  0 siblings, 2 replies; 93+ messages in thread
From: Cédric Le Goater @ 2019-09-26  7:05 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, groug, qemu-ppc,
	Marc-André Lureau, Paolo Bonzini, philmd, Laurent Vivier

>>> +    if (spapr->irq->xive) {
>>> +        uint32_t nr_servers = spapr_max_server_number(spapr);
>>> +        DeviceState *dev;
>>> +        int i;
>>> +
>>> +        dev = qdev_create(NULL, TYPE_SPAPR_XIVE);
>>> +        qdev_prop_set_uint32(dev, "nr-irqs",
>>> +                             spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
>>> +        /*
>>> +         * 8 XIVE END structures per CPU. One for each available
>>> +         * priority
>>> +         */
>>> +        qdev_prop_set_uint32(dev, "nr-ends", nr_servers << 3);
>>> +        qdev_init_nofail(dev);
>>> +
>>> +        spapr->xive = SPAPR_XIVE(dev);
>>> +
>>> +        /* Enable the CPU IPIs */
>>> +        for (i = 0; i < nr_servers; ++i) {
>>> +            Error *local_err = NULL;
>>> +
>>> +            spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i, false, &local_err);
>>> +            if (local_err) {
>>> +                goto out;
>>> +            }
>>> +        }
>>
>> We could move the IPI claim part in the realize routine of SPAPR_XIVE.
> 
> Yeah, I know.  I thought about this, but there's a slight complication
> in that the XIVE part doesn't know nr_servers directly.  There's
> several possible ways to handle that, but I wasn't 100% happy with any
> that I came up with yet.

The "nr-ends" property was inappropriate, "nr-servers" would have been
better and we would have hidden the calculation of ENDs 'nr_servers << 3'
in the realize routine of SpaprXive. 

I don't think we can change that without breaking migration though :/

C.

>>
>>> +        spapr_xive_hcall_init(spapr);
>>
>> This also.
> 
> Right.
> 
>> It can be done later one.
> 
> That's my intention.
> 
>>
>> C.
>>
>>> +    }
>>>  
>>>      spapr->qirqs = qemu_allocate_irqs(spapr->irq->set_irq, spapr,
>>>                                        spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
>>> +
>>> +out:
>>> +    error_propagate(errp, local_err);
>>>  }
>>>  
>>>  void spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
>>> @@ -757,7 +744,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 6816cb0500..fa862c665b 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);
>>>      void (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
>>>      void (*free)(SpaprMachineState *spapr, int irq);
>>>      void (*print_info)(SpaprMachineState *spapr, Monitor *mon);
>>> diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h
>>> index 691a6d00f7..267984a97b 100644
>>> --- a/include/hw/ppc/xics_spapr.h
>>> +++ b/include/hw/ppc/xics_spapr.h
>>> @@ -34,6 +34,7 @@
>>>  #define TYPE_ICS_SPAPR "ics-spapr"
>>>  #define ICS_SPAPR(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SPAPR)
>>>  
>>> +void ics_spapr_create(SpaprMachineState *spapr, int nr_xirqs, Error **errp);
>>>  void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
>>>                     uint32_t phandle);
>>>  int xics_kvm_connect(SpaprMachineState *spapr, Error **errp);
>>>
>>
> 



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

* Re: [PATCH 08/20] spapr: Replace spapr_vio_qirq() helper with spapr_vio_irq_pulse() helper
  2019-09-25  6:45 ` [PATCH 08/20] spapr: Replace spapr_vio_qirq() helper with spapr_vio_irq_pulse() helper David Gibson
  2019-09-25  6:58   ` Cédric Le Goater
  2019-09-25  8:57   ` Greg Kurz
@ 2019-09-26  7:08   ` Philippe Mathieu-Daudé
  2 siblings, 0 replies; 93+ messages in thread
From: Philippe Mathieu-Daudé @ 2019-09-26  7:08 UTC (permalink / raw)
  To: David Gibson, qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug,
	Marc-André Lureau, Paolo Bonzini

On 9/25/19 8:45 AM, David Gibson wrote:
> 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>
> ---
>  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);

Good place to add a trace event.

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>

> +    qemu_irq_pulse(spapr_qirq(spapr, dev->irq));
>  }
>  
>  static inline bool spapr_vio_dma_valid(SpaprVioDevice *dev, uint64_t taddr,
> 


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

* Re: [PATCH 07/20] spapr: Fold spapr_phb_lsi_qirq() into its single caller
  2019-09-25  6:45 ` [PATCH 07/20] spapr: Fold spapr_phb_lsi_qirq() into its single caller David Gibson
  2019-09-25  6:58   ` Cédric Le Goater
  2019-09-25  8:56   ` Greg Kurz
@ 2019-09-26  7:08   ` Philippe Mathieu-Daudé
  2 siblings, 0 replies; 93+ messages in thread
From: Philippe Mathieu-Daudé @ 2019-09-26  7:08 UTC (permalink / raw)
  To: David Gibson, qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug,
	Marc-André Lureau, Paolo Bonzini

On 9/25/19 8:45 AM, David Gibson wrote:
> 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>
> ---
>  hw/ppc/spapr_pci.c          | 3 ++-
>  include/hw/pci-host/spapr.h | 7 -------
>  2 files changed, 2 insertions(+), 8 deletions(-)
> 
> diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
> index 7b71ad7c74..6934d506a7 100644
> --- a/hw/ppc/spapr_pci.c
> +++ b/hw/ppc/spapr_pci.c
> @@ -721,9 +721,10 @@ static void pci_spapr_set_irq(void *opaque, int irq_num, int level)
>       * corresponding qemu_irq.
>       */
>      SpaprPhbState *phb = opaque;
> +    SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
>  
>      trace_spapr_pci_lsi_set(phb->dtbusname, irq_num, phb->lsi_table[irq_num].irq);
> -    qemu_set_irq(spapr_phb_lsi_qirq(phb, irq_num), level);
> +    qemu_set_irq(spapr_qirq(spapr, phb->lsi_table[irq_num].irq), level);
>  }
>  
>  static PCIINTxRoute spapr_route_intx_pin_to_irq(void *opaque, int pin)
> diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h
> index abd87605b2..23506f05d9 100644
> --- a/include/hw/pci-host/spapr.h
> +++ b/include/hw/pci-host/spapr.h
> @@ -128,13 +128,6 @@ struct SpaprPhbState {
>  #define SPAPR_PCI_NV2ATSD_WIN_SIZE   (NVGPU_MAX_NUM * NVGPU_MAX_LINKS * \
>                                        64 * KiB)
>  
> -static inline qemu_irq spapr_phb_lsi_qirq(struct SpaprPhbState *phb, int pin)
> -{
> -    SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
> -
> -    return spapr_qirq(spapr, phb->lsi_table[pin].irq);
> -}
> -
>  int spapr_dt_phb(SpaprPhbState *phb, uint32_t intc_phandle, void *fdt,
>                   uint32_t nr_msis, int *node_offset);
>  
> 

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>


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

* Re: [PATCH 06/20] xics: Create sPAPR specific ICS subtype
  2019-09-26  0:56       ` David Gibson
@ 2019-09-26  7:09         ` Cédric Le Goater
  2019-09-27 16:05         ` Greg Kurz
  1 sibling, 0 replies; 93+ messages in thread
From: Cédric Le Goater @ 2019-09-26  7:09 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, Greg Kurz, qemu-devel, qemu-ppc,
	Marc-André Lureau, Paolo Bonzini, philmd, Laurent Vivier

On 26/09/2019 02:56, David Gibson wrote:
> On Wed, Sep 25, 2019 at 10:55:35AM +0200, Cédric Le Goater wrote:
>> On 25/09/2019 10:40, Greg Kurz wrote:
>>> On Wed, 25 Sep 2019 16:45:20 +1000
>>> David Gibson <david@gibson.dropbear.id.au> wrote:
>>>
>>>> We create a subtype of TYPE_ICS specifically for sPAPR.  For now all this
>>>> does is move the setup of the PAPR specific hcalls and RTAS calls to
>>>> the realize() function for this, rather than requiring the PAPR code to
>>>> explicitly call xics_spapr_init().  In future it will have some more
>>>> function.
>>>>
>>>> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
>>>> ---
>>>
>>> LGTM, but for extra safety I would also introduce a SpaprIcsState typedef
>>
>> why ? we have ICS_SPAPR() for the checks already.
> 
> Eh.. using typedefs when we haven't actually extended a base type
> isn't common QOM practice.  Yes, it's not as typesafe as it could be,
> but I'm not really inclined to go to the extra effort here.

I agree. It is really a pain.

C. 

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



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

* Re: [PATCH 12/20] spapr: Simplify spapr_qirq() handling
  2019-09-25  6:45 ` [PATCH 12/20] spapr: Simplify spapr_qirq() handling David Gibson
  2019-09-25  7:16   ` Cédric Le Goater
  2019-09-25 20:30   ` Greg Kurz
@ 2019-09-26  7:10   ` Philippe Mathieu-Daudé
  2 siblings, 0 replies; 93+ messages in thread
From: Philippe Mathieu-Daudé @ 2019-09-26  7:10 UTC (permalink / raw)
  To: David Gibson, qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug,
	Marc-André Lureau, Paolo Bonzini

On 9/25/19 8:45 AM, David Gibson wrote:
> Currently spapr_qirq() 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>
> ---
>  hw/ppc/spapr_irq.c         | 47 ++++++++++----------------------------
>  include/hw/ppc/spapr_irq.h |  1 -
>  2 files changed, 12 insertions(+), 36 deletions(-)
> 
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index 9a9e486eb5..038bfffff4 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)
>  {
> @@ -413,7 +387,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,
> @@ -487,11 +460,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);
> @@ -586,7 +554,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,
> @@ -700,7 +667,18 @@ void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
>  
>  qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq)
>  {
> -    return spapr->irq->qirq(spapr, irq);
> +    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)
> @@ -803,7 +781,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);

Yay, cleanup!

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>

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

* Re: [PATCH 13/20] spapr: Eliminate SpaprIrq:get_nodename method
  2019-09-25  6:45 ` [PATCH 13/20] spapr: Eliminate SpaprIrq:get_nodename method David Gibson
  2019-09-25  7:19   ` Cédric Le Goater
@ 2019-09-26  7:11   ` Philippe Mathieu-Daudé
  2019-09-26  7:48   ` Greg Kurz
  2 siblings, 0 replies; 93+ messages in thread
From: Philippe Mathieu-Daudé @ 2019-09-26  7:11 UTC (permalink / raw)
  To: David Gibson, qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug,
	Marc-André Lureau, Paolo Bonzini

On 9/25/19 8:45 AM, David Gibson wrote:
> 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.
> 
> So, the method is unnecessary.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---
>  hw/ppc/spapr_irq.c         | 25 +++----------------------
>  include/hw/ppc/spapr_irq.h |  1 -
>  2 files changed, 3 insertions(+), 23 deletions(-)
> 
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index 038bfffff4..79167ccc68 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()) {
> @@ -393,7 +382,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,
>  };
>  
> @@ -538,11 +526,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
>   */
> @@ -560,7 +543,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 */
>  };
>  
> @@ -697,13 +679,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;
>      }
>  
> @@ -787,6 +769,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);

Another Yay!

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>

>      void (*init_kvm)(SpaprMachineState *spapr, Error **errp);
>  } SpaprIrq;
>  
> 


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

* Re: [PATCH 14/20] spapr: Remove unhelpful tracepoints from spapr_irq_free_xics()
  2019-09-25  6:45 ` [PATCH 14/20] spapr: Remove unhelpful tracepoints from spapr_irq_free_xics() David Gibson
  2019-09-25  7:20   ` Cédric Le Goater
@ 2019-09-26  7:11   ` Philippe Mathieu-Daudé
  2019-09-26  7:50   ` Greg Kurz
  2 siblings, 0 replies; 93+ messages in thread
From: Philippe Mathieu-Daudé @ 2019-09-26  7:11 UTC (permalink / raw)
  To: David Gibson, qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug,
	Marc-André Lureau, Paolo Bonzini

On 9/25/19 8:45 AM, David Gibson wrote:
> 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>
> ---
>  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 79167ccc68..db6755f3ab 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
> 

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>


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

* Re: [PATCH 17/20] spapr: Remove unused return value in claim path
  2019-09-25  6:45 ` [PATCH 17/20] spapr: Remove unused return value in claim path David Gibson
  2019-09-25  7:23   ` Cédric Le Goater
@ 2019-09-26  7:13   ` Philippe Mathieu-Daudé
  2019-09-26  8:36   ` Greg Kurz
  2 siblings, 0 replies; 93+ messages in thread
From: Philippe Mathieu-Daudé @ 2019-09-26  7:13 UTC (permalink / raw)
  To: David Gibson, qemu-ppc, clg, qemu-devel
  Cc: Jason Wang, Riku Voipio, Laurent Vivier, groug,
	Marc-André Lureau, Paolo Bonzini

On 9/25/19 8:45 AM, David Gibson wrote:
> spapr_irq_claim() and the hooks it is based on return an integer error code
> as well as taking an Error ** parameter.  But none of the callers check the
> integer, so we can remove it and just use the richer Error **.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---
>  hw/ppc/spapr_irq.c         | 32 +++++++++++++-------------------
>  include/hw/ppc/spapr_irq.h |  4 ++--
>  2 files changed, 15 insertions(+), 21 deletions(-)
> 
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index 261d66ba17..2673a90604 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -112,8 +112,8 @@ static void spapr_irq_init_xics(SpaprMachineState *spapr, Error **errp)
>      spapr->ics = ICS_SPAPR(obj);
>  }
>  
> -static int spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
> -                                Error **errp)
> +static void spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
> +                                 Error **errp)
>  {
>      ICSState *ics = spapr->ics;
>  
> @@ -122,11 +122,10 @@ static int spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
>  
>      if (!ics_irq_free(ics, irq - ics->offset)) {
>          error_setg(errp, "IRQ %d is not free", irq);
> -        return -1;
> +        return;
>      }
>  
>      ics_set_irq_type(ics, irq - ics->offset, lsi);
> -    return 0;
>  }
>  
>  static void spapr_irq_free_xics(SpaprMachineState *spapr, int irq)
> @@ -252,14 +251,12 @@ static void spapr_irq_init_xive(SpaprMachineState *spapr, Error **errp)
>      spapr_xive_hcall_init(spapr);
>  }
>  
> -static int spapr_irq_claim_xive(SpaprMachineState *spapr, int irq, bool lsi,
> -                                Error **errp)
> +static void 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;
>  }
>  
>  static void spapr_irq_free_xive(SpaprMachineState *spapr, int irq)
> @@ -406,25 +403,22 @@ static void spapr_irq_init_dual(SpaprMachineState *spapr, Error **errp)
>      }
>  }
>  
> -static int spapr_irq_claim_dual(SpaprMachineState *spapr, int irq, bool lsi,
> -                                Error **errp)
> +static void 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);
> +    spapr_irq_xics.claim(spapr, irq, lsi, &local_err);
>      if (local_err) {
>          error_propagate(errp, local_err);
> -        return ret;
> +        return;
>      }
>  
> -    ret = spapr_irq_xive.claim(spapr, irq, lsi, &local_err);
> +    spapr_irq_xive.claim(spapr, irq, lsi, &local_err);
>      if (local_err) {
>          error_propagate(errp, local_err);
> -        return ret;
> +        return;
>      }
> -
> -    return ret;
>  }
>  
>  static void spapr_irq_free_dual(SpaprMachineState *spapr, int irq)
> @@ -622,12 +616,12 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>                                        spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
>  }
>  
> -int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
> +void 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);
> +    spapr->irq->claim(spapr, irq, lsi, errp);
>  }
>  
>  void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index ed88b4599a..75279ca137 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -42,7 +42,7 @@ typedef struct SpaprIrq {
>      uint8_t     ov5;
>  
>      void (*init)(SpaprMachineState *spapr, Error **errp);
> -    int (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
> +    void (*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,
> @@ -61,7 +61,7 @@ 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_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
>  void spapr_irq_free(SpaprMachineState *spapr, int irq, int num);
>  qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq);
>  int spapr_irq_post_load(SpaprMachineState *spapr, int version_id);
> 

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>


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

* Re: [PATCH 11/20] spapr: Fix indexing of XICS irqs
  2019-09-26  1:31     ` David Gibson
@ 2019-09-26  7:21       ` Greg Kurz
  2019-09-26 11:32         ` David Gibson
  0 siblings, 1 reply; 93+ messages in thread
From: Greg Kurz @ 2019-09-26  7:21 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

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

On Thu, 26 Sep 2019 11:31:48 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> On Wed, Sep 25, 2019 at 10:17:46PM +0200, Greg Kurz wrote:
> > On Wed, 25 Sep 2019 16:45:25 +1000
> > David Gibson <david@gibson.dropbear.id.au> wrote:
> > 
> > > 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: Greg Kurz <groug@kaod.org>
> > 
> > Further cleanup could be to have the XICS backend to only take global
> > irq numbers and to convert them to ICS source numbers internally. This
> > would put an end to the confusion between srcno/irq in the frontend
> > code.
> 
> Yeah, maybe.  But the local srcnos do actually make sense from within
> the perspective of ICS, so I'm not all that keen to do that.
> 

Not sure to understand what you mean by "within the perspective of ICS".

My concern is actually to get rid of ics->offset users in spapr_irq.c.

eg,

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

It looks like we should do something like:

static void spapr_irq_set_irq_xics(void *opaque, int irq, int val)
{
    SpaprMachineState *spapr = opaque;

    ics_set_irq(spapr->ics, irq, val);
}

and have ics_set_irq() do:

    uint32_t srcno = irq - spapr->ics->offset;

Are you inferring that it is better to keep the irq to srcno conversions
in spapr_irq.c ?

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

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

* Re: [PATCH 13/20] spapr: Eliminate SpaprIrq:get_nodename method
  2019-09-25  6:45 ` [PATCH 13/20] spapr: Eliminate SpaprIrq:get_nodename method David Gibson
  2019-09-25  7:19   ` Cédric Le Goater
  2019-09-26  7:11   ` Philippe Mathieu-Daudé
@ 2019-09-26  7:48   ` Greg Kurz
  2019-09-26 11:36     ` David Gibson
  2 siblings, 1 reply; 93+ messages in thread
From: Greg Kurz @ 2019-09-26  7:48 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

On Wed, 25 Sep 2019 16:45:27 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> 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.
> 
> So, the method is unnecessary.
> 

So is the XICS_NODENAME macro which was introduced by the same
commit 743ed566c1d80, and it seems that "interrupt-controller"
is a well-known string that is used everywhere:

[greg@bahia qemu-spapr]$ git grep -E \"interrupt-controller\"
hw/arm/virt.c:    qemu_fdt_setprop(vms->fdt, nodename, "interrupt-controller", NULL, 0);
hw/arm/xlnx-versal-virt.c:    qemu_fdt_setprop(s->fdt, nodename, "interrupt-controller", NULL, 0);
hw/intc/sh_intc.c:                          "interrupt-controller", 0x100000000ULL);
hw/intc/spapr_xive.c:    _FDT(fdt_setprop(fdt, node, "interrupt-controller", NULL, 0));
hw/intc/xics_spapr.c:    _FDT(fdt_setprop(fdt, node, "interrupt-controller", NULL, 0));
hw/pci/pci.c:    { 0x0800, "Interrupt controller", "interrupt-controller"},
hw/ppc/e500.c:    qemu_fdt_setprop(fdt, mpic, "interrupt-controller", NULL, 0);
hw/ppc/pnv.c:    _FDT((fdt_setprop(fdt, offset, "interrupt-controller", NULL, 0)));
hw/ppc/spapr_events.c:    _FDT((fdt_setprop(fdt, event_sources, "interrupt-controller", NULL, 0)));
hw/ppc/spapr_irq.c:    const char *nodename = "interrupt-controller";
hw/ppc/spapr_pci.c:    { PCI_CLASS_SYSTEM_PIC, "interrupt-controller", pic_iface },
hw/ppc/spapr_vio.c:    _FDT(fdt_setprop(fdt, node, "interrupt-controller", NULL, 0));
hw/riscv/sifive_u.c:        qemu_fdt_setprop(fdt, intc, "interrupt-controller", NULL, 0);
hw/riscv/sifive_u.c:    qemu_fdt_setprop(fdt, nodename, "interrupt-controller", NULL, 0);
hw/riscv/spike.c:        qemu_fdt_setprop(fdt, intc, "interrupt-controller", NULL, 0);
hw/riscv/virt.c:        qemu_fdt_setprop(fdt, intc, "interrupt-controller", NULL, 0);
hw/riscv/virt.c:    qemu_fdt_setprop(fdt, nodename, "interrupt-controller", NULL, 0);
include/hw/ppc/spapr.h: * "interrupt-controller" node has its "#interrupt-cells" property set to 2 (ie,
include/hw/ppc/xics_spapr.h:#define XICS_NODENAME "interrupt-controller"

Maybe drop XICS_NODENAME as well while here ?

With or without that,

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

> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---
>  hw/ppc/spapr_irq.c         | 25 +++----------------------
>  include/hw/ppc/spapr_irq.h |  1 -
>  2 files changed, 3 insertions(+), 23 deletions(-)
> 
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index 038bfffff4..79167ccc68 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()) {
> @@ -393,7 +382,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,
>  };
>  
> @@ -538,11 +526,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
>   */
> @@ -560,7 +543,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 */
>  };
>  
> @@ -697,13 +679,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;
>      }
>  
> @@ -787,6 +769,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;
>  



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

* Re: [PATCH 14/20] spapr: Remove unhelpful tracepoints from spapr_irq_free_xics()
  2019-09-25  6:45 ` [PATCH 14/20] spapr: Remove unhelpful tracepoints from spapr_irq_free_xics() David Gibson
  2019-09-25  7:20   ` Cédric Le Goater
  2019-09-26  7:11   ` Philippe Mathieu-Daudé
@ 2019-09-26  7:50   ` Greg Kurz
  2 siblings, 0 replies; 93+ messages in thread
From: Greg Kurz @ 2019-09-26  7:50 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

On Wed, 25 Sep 2019 16:45:28 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> 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: Greg Kurz <groug@kaod.org>

>  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 79167ccc68..db6755f3ab 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



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

* Re: [PATCH 15/20] spapr: Handle freeing of multiple irqs in frontend only
  2019-09-25  6:45 ` [PATCH 15/20] spapr: Handle freeing of multiple irqs in frontend only David Gibson
  2019-09-25  7:21   ` Cédric Le Goater
@ 2019-09-26  7:52   ` Greg Kurz
  1 sibling, 0 replies; 93+ messages in thread
From: Greg Kurz @ 2019-09-26  7:52 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

On Wed, 25 Sep 2019 16:45:29 +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>
> ---

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

>  hw/ppc/spapr_irq.c         | 27 ++++++++++++---------------
>  include/hw/ppc/spapr_irq.h |  2 +-
>  2 files changed, 13 insertions(+), 16 deletions(-)
> 
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index db6755f3ab..c40357a985 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,
> @@ -438,10 +431,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)
> @@ -640,7 +633,11 @@ int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
>  
>  void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
>  {
> -    spapr->irq->free(spapr, irq, num);
> +    int i;
> +
> +    for (i = irq; i < (irq + num); i++) {
> +        spapr->irq->free(spapr, irq);
> +    }
>  }
>  
>  qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq)
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index 9b60378e28..ed88b4599a 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -43,7 +43,7 @@ typedef struct SpaprIrq {
>  
>      void (*init)(SpaprMachineState *spapr, Error **errp);
>      int (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
> -    void (*free)(SpaprMachineState *spapr, int irq, int num);
> +    void (*free)(SpaprMachineState *spapr, int irq);
>      void (*print_info)(SpaprMachineState *spapr, Monitor *mon);
>      void (*dt_populate)(SpaprMachineState *spapr, uint32_t nr_servers,
>                          void *fdt, uint32_t phandle);



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

* Re: [PATCH 16/20] spapr, xics, xive: Better use of assert()s on irq claim/free paths
  2019-09-25  6:45 ` [PATCH 16/20] spapr, xics, xive: Better use of assert()s on irq claim/free paths David Gibson
  2019-09-25  7:22   ` Cédric Le Goater
@ 2019-09-26  8:08   ` Greg Kurz
  2019-09-26 11:39     ` David Gibson
  1 sibling, 1 reply; 93+ messages in thread
From: Greg Kurz @ 2019-09-26  8:08 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

On Wed, 25 Sep 2019 16:45:30 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> 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>
> ---
>  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 c40357a985..261d66ba17 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)
> @@ -628,6 +624,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);
>  }
>  
> @@ -635,6 +634,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));

Non surprisingly this makes checkpatch unhappy:

ERROR: spaces required around that '+' (ctx:VxV)
#91: FILE: hw/ppc/spapr_irq.c:638:
+    assert((irq+num) <= (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));

With that fixed,

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

> +
>      for (i = irq; i < (irq + num); i++) {
>          spapr->irq->free(spapr, irq);
>      }



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

* Re: [PATCH 17/20] spapr: Remove unused return value in claim path
  2019-09-25  6:45 ` [PATCH 17/20] spapr: Remove unused return value in claim path David Gibson
  2019-09-25  7:23   ` Cédric Le Goater
  2019-09-26  7:13   ` Philippe Mathieu-Daudé
@ 2019-09-26  8:36   ` Greg Kurz
  2019-09-27  1:47     ` David Gibson
  2 siblings, 1 reply; 93+ messages in thread
From: Greg Kurz @ 2019-09-26  8:36 UTC (permalink / raw)
  To: David Gibson
  Cc: Daniel P. Berrangé,
	Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

On Wed, 25 Sep 2019 16:45:31 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> spapr_irq_claim() and the hooks it is based on return an integer error code
> as well as taking an Error ** parameter.  But none of the callers check the
> integer, so we can remove it and just use the richer Error **.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---

FYI, the very same topic of using the return value versus Error ** to
check errors was discussed recently in this thread:

https://lists.gnu.org/archive/html/qemu-devel/2019-09/msg04197.html

I tend to agree with Daniel (Cc'd) at first thought, but I don't have a strong
opinion about this yet. It is mostly to inform you that people are currently
discussing/working on it.

>  hw/ppc/spapr_irq.c         | 32 +++++++++++++-------------------
>  include/hw/ppc/spapr_irq.h |  4 ++--
>  2 files changed, 15 insertions(+), 21 deletions(-)
> 
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index 261d66ba17..2673a90604 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -112,8 +112,8 @@ static void spapr_irq_init_xics(SpaprMachineState *spapr, Error **errp)
>      spapr->ics = ICS_SPAPR(obj);
>  }
>  
> -static int spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
> -                                Error **errp)
> +static void spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
> +                                 Error **errp)
>  {
>      ICSState *ics = spapr->ics;
>  
> @@ -122,11 +122,10 @@ static int spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
>  
>      if (!ics_irq_free(ics, irq - ics->offset)) {
>          error_setg(errp, "IRQ %d is not free", irq);
> -        return -1;
> +        return;
>      }
>  
>      ics_set_irq_type(ics, irq - ics->offset, lsi);
> -    return 0;
>  }
>  
>  static void spapr_irq_free_xics(SpaprMachineState *spapr, int irq)
> @@ -252,14 +251,12 @@ static void spapr_irq_init_xive(SpaprMachineState *spapr, Error **errp)
>      spapr_xive_hcall_init(spapr);
>  }
>  
> -static int spapr_irq_claim_xive(SpaprMachineState *spapr, int irq, bool lsi,
> -                                Error **errp)
> +static void 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;
>  }
>  
>  static void spapr_irq_free_xive(SpaprMachineState *spapr, int irq)
> @@ -406,25 +403,22 @@ static void spapr_irq_init_dual(SpaprMachineState *spapr, Error **errp)
>      }
>  }
>  
> -static int spapr_irq_claim_dual(SpaprMachineState *spapr, int irq, bool lsi,
> -                                Error **errp)
> +static void 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);
> +    spapr_irq_xics.claim(spapr, irq, lsi, &local_err);
>      if (local_err) {
>          error_propagate(errp, local_err);
> -        return ret;
> +        return;
>      }
>  
> -    ret = spapr_irq_xive.claim(spapr, irq, lsi, &local_err);
> +    spapr_irq_xive.claim(spapr, irq, lsi, &local_err);
>      if (local_err) {
>          error_propagate(errp, local_err);
> -        return ret;
> +        return;
>      }
> -
> -    return ret;
>  }
>  
>  static void spapr_irq_free_dual(SpaprMachineState *spapr, int irq)
> @@ -622,12 +616,12 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>                                        spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
>  }
>  
> -int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
> +void 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);
> +    spapr->irq->claim(spapr, irq, lsi, errp);
>  }
>  
>  void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
> diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> index ed88b4599a..75279ca137 100644
> --- a/include/hw/ppc/spapr_irq.h
> +++ b/include/hw/ppc/spapr_irq.h
> @@ -42,7 +42,7 @@ typedef struct SpaprIrq {
>      uint8_t     ov5;
>  
>      void (*init)(SpaprMachineState *spapr, Error **errp);
> -    int (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
> +    void (*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,
> @@ -61,7 +61,7 @@ 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_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
>  void spapr_irq_free(SpaprMachineState *spapr, int irq, int num);
>  qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq);
>  int spapr_irq_post_load(SpaprMachineState *spapr, int version_id);



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

* Re: [PATCH 19/20] spapr: Use less cryptic representation of which irq backends are supported
  2019-09-25  6:45 ` [PATCH 19/20] spapr: Use less cryptic representation of which irq backends are supported David Gibson
  2019-09-25  7:28   ` Cédric Le Goater
@ 2019-09-26  9:16   ` Greg Kurz
  1 sibling, 0 replies; 93+ messages in thread
From: Greg Kurz @ 2019-09-26  9:16 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

On Wed, 25 Sep 2019 16:45:33 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> 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: Greg Kurz <groug@kaod.org>

>  hw/ppc/spapr.c             | 15 ++++++++++++---
>  hw/ppc/spapr_hcall.c       |  6 +++---
>  hw/ppc/spapr_irq.c         | 12 ++++++++----
>  include/hw/ppc/spapr_irq.h |  3 ++-
>  4 files changed, 25 insertions(+), 11 deletions(-)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 3742a8cf06..795f6ab505 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -1136,19 +1136,28 @@ static void spapr_dt_ov5_platform_support(SpaprMachineState *spapr, void *fdt,
>      PowerPCCPU *first_ppc_cpu = POWERPC_CPU(first_cpu);
>  
>      char val[2 * 4] = {
> -        23, spapr->irq->ov5, /* Xive mode. */
> +        23, 0x00, /* XICS / XIVE mode */
>          24, 0x00, /* Hash/Radix, filled in below. */
>          25, 0x00, /* Hash options: Segment Tables == no, GTSE == no. */
>          26, 0x40, /* Radix options: GTSE == yes. */
>      };
>  
> +    if (spapr->irq->xics && spapr->irq->xive) {
> +        val[1] = SPAPR_OV5_XIVE_BOTH;
> +    } else if (spapr->irq->xive) {
> +        val[1] = SPAPR_OV5_XIVE_EXPLOIT;
> +    } else {
> +        assert(spapr->irq->xics);
> +        val[1] = SPAPR_OV5_XIVE_LEGACY;
> +    }
> +
>      if (!ppc_check_compat(first_ppc_cpu, CPU_POWERPC_LOGICAL_3_00, 0,
>                            first_ppc_cpu->compat_pvr)) {
>          /*
>           * If we're in a pre POWER9 compat mode then the guest should
>           * do hash and use the legacy interrupt mode
>           */
> -        val[1] = 0x00; /* XICS */
> +        val[1] = SPAPR_OV5_XIVE_LEGACY; /* XICS */
>          val[3] = 0x00; /* Hash */
>      } else if (kvm_enabled()) {
>          if (kvmppc_has_cap_mmu_radix() && kvmppc_has_cap_mmu_hash_v3()) {
> @@ -2837,7 +2846,7 @@ static void spapr_machine_init(MachineState *machine)
>      spapr_ovec_set(spapr->ov5, OV5_DRMEM_V2);
>  
>      /* advertise XIVE on POWER9 machines */
> -    if (spapr->irq->ov5 & (SPAPR_OV5_XIVE_EXPLOIT | SPAPR_OV5_XIVE_BOTH)) {
> +    if (spapr->irq->xive) {
>          spapr_ovec_set(spapr->ov5, OV5_XIVE_EXPLOIT);
>      }
>  
> diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
> index 3d3a67149a..140f05c1c6 100644
> --- a/hw/ppc/spapr_hcall.c
> +++ b/hw/ppc/spapr_hcall.c
> @@ -1784,13 +1784,13 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
>       * terminate the boot.
>       */
>      if (guest_xive) {
> -        if (spapr->irq->ov5 == SPAPR_OV5_XIVE_LEGACY) {
> +        if (!spapr->irq->xive) {
>              error_report(
>  "Guest requested unavailable interrupt mode (XIVE), try the ic-mode=xive or ic-mode=dual machine property");
>              exit(EXIT_FAILURE);
>          }
>      } else {
> -        if (spapr->irq->ov5 == SPAPR_OV5_XIVE_EXPLOIT) {
> +        if (!spapr->irq->xics) {
>              error_report(
>  "Guest requested unavailable interrupt mode (XICS), either don't set the ic-mode machine property or try ic-mode=xics or ic-mode=dual");
>              exit(EXIT_FAILURE);
> @@ -1804,7 +1804,7 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
>       */
>      if (!spapr->cas_reboot) {
>          spapr->cas_reboot = spapr_ovec_test(ov5_updates, OV5_XIVE_EXPLOIT)
> -            && spapr->irq->ov5 & SPAPR_OV5_XIVE_BOTH;
> +            && spapr->irq->xics && spapr->irq->xive;
>      }
>  
>      spapr_ovec_cleanup(ov5_updates);
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index f53544e45e..073f375ba2 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -209,7 +209,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,
> @@ -357,7 +358,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,
> @@ -515,7 +517,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,
> @@ -751,7 +754,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 75279ca137..6816cb0500 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);
>      void (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);



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

* Re: [PATCH 20/20] spapr: Eliminate SpaprIrq::init hook
  2019-09-26  7:05       ` Cédric Le Goater
@ 2019-09-26 11:29         ` David Gibson
  2019-09-26 15:35         ` Greg Kurz
  1 sibling, 0 replies; 93+ messages in thread
From: David Gibson @ 2019-09-26 11:29 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Jason Wang, Riku Voipio, qemu-devel, groug, qemu-ppc,
	Marc-André Lureau, Paolo Bonzini, philmd, Laurent Vivier

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

On Thu, Sep 26, 2019 at 09:05:56AM +0200, Cédric Le Goater wrote:
> >>> +    if (spapr->irq->xive) {
> >>> +        uint32_t nr_servers = spapr_max_server_number(spapr);
> >>> +        DeviceState *dev;
> >>> +        int i;
> >>> +
> >>> +        dev = qdev_create(NULL, TYPE_SPAPR_XIVE);
> >>> +        qdev_prop_set_uint32(dev, "nr-irqs",
> >>> +                             spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
> >>> +        /*
> >>> +         * 8 XIVE END structures per CPU. One for each available
> >>> +         * priority
> >>> +         */
> >>> +        qdev_prop_set_uint32(dev, "nr-ends", nr_servers << 3);
> >>> +        qdev_init_nofail(dev);
> >>> +
> >>> +        spapr->xive = SPAPR_XIVE(dev);
> >>> +
> >>> +        /* Enable the CPU IPIs */
> >>> +        for (i = 0; i < nr_servers; ++i) {
> >>> +            Error *local_err = NULL;
> >>> +
> >>> +            spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i, false, &local_err);
> >>> +            if (local_err) {
> >>> +                goto out;
> >>> +            }
> >>> +        }
> >>
> >> We could move the IPI claim part in the realize routine of SPAPR_XIVE.
> > 
> > Yeah, I know.  I thought about this, but there's a slight complication
> > in that the XIVE part doesn't know nr_servers directly.  There's
> > several possible ways to handle that, but I wasn't 100% happy with any
> > that I came up with yet.
> 
> The "nr-ends" property was inappropriate, "nr-servers" would have been
> better and we would have hidden the calculation of ENDs 'nr_servers << 3'
> in the realize routine of SpaprXive. 

Ah, interesting.

> I don't think we can change that without breaking migration though
> :/

Hm, there might be a way around it, I'll see what I can do, but
probably as a rather later patch.

> 
> C.
> 
> >>
> >>> +        spapr_xive_hcall_init(spapr);
> >>
> >> This also.
> > 
> > Right.
> > 
> >> It can be done later one.
> > 
> > That's my intention.
> > 
> >>
> >> C.
> >>
> >>> +    }
> >>>  
> >>>      spapr->qirqs = qemu_allocate_irqs(spapr->irq->set_irq, spapr,
> >>>                                        spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
> >>> +
> >>> +out:
> >>> +    error_propagate(errp, local_err);
> >>>  }
> >>>  
> >>>  void spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
> >>> @@ -757,7 +744,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 6816cb0500..fa862c665b 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);
> >>>      void (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
> >>>      void (*free)(SpaprMachineState *spapr, int irq);
> >>>      void (*print_info)(SpaprMachineState *spapr, Monitor *mon);
> >>> diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h
> >>> index 691a6d00f7..267984a97b 100644
> >>> --- a/include/hw/ppc/xics_spapr.h
> >>> +++ b/include/hw/ppc/xics_spapr.h
> >>> @@ -34,6 +34,7 @@
> >>>  #define TYPE_ICS_SPAPR "ics-spapr"
> >>>  #define ICS_SPAPR(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SPAPR)
> >>>  
> >>> +void ics_spapr_create(SpaprMachineState *spapr, int nr_xirqs, Error **errp);
> >>>  void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
> >>>                     uint32_t phandle);
> >>>  int xics_kvm_connect(SpaprMachineState *spapr, Error **errp);
> >>>
> >>
> > 
> 

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

* Re: [PATCH 11/20] spapr: Fix indexing of XICS irqs
  2019-09-26  7:21       ` Greg Kurz
@ 2019-09-26 11:32         ` David Gibson
  2019-09-26 14:44           ` Greg Kurz
  0 siblings, 1 reply; 93+ messages in thread
From: David Gibson @ 2019-09-26 11:32 UTC (permalink / raw)
  To: Greg Kurz
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

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

On Thu, Sep 26, 2019 at 09:21:41AM +0200, Greg Kurz wrote:
> On Thu, 26 Sep 2019 11:31:48 +1000
> David Gibson <david@gibson.dropbear.id.au> wrote:
> 
> > On Wed, Sep 25, 2019 at 10:17:46PM +0200, Greg Kurz wrote:
> > > On Wed, 25 Sep 2019 16:45:25 +1000
> > > David Gibson <david@gibson.dropbear.id.au> wrote:
> > > 
> > > > 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: Greg Kurz <groug@kaod.org>
> > > 
> > > Further cleanup could be to have the XICS backend to only take global
> > > irq numbers and to convert them to ICS source numbers internally. This
> > > would put an end to the confusion between srcno/irq in the frontend
> > > code.
> > 
> > Yeah, maybe.  But the local srcnos do actually make sense from within
> > the perspective of ICS, so I'm not all that keen to do that.
> > 
> 
> Not sure to understand what you mean by "within the perspective of ICS".
> 
> My concern is actually to get rid of ics->offset users in spapr_irq.c.
> 
> eg,
> 
> 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);
> }
> 
> It looks like we should do something like:
> 
> static void spapr_irq_set_irq_xics(void *opaque, int irq, int val)
> {
>     SpaprMachineState *spapr = opaque;
> 
>     ics_set_irq(spapr->ics, irq, val);
> }
> 
> and have ics_set_irq() do:
> 
>     uint32_t srcno = irq - spapr->ics->offset;
> 
> Are you inferring that it is better to keep the irq to srcno conversions
> in spapr_irq.c ?

Ah, I see what you mean.  So, the reason srcno appears here is that
ics_set_irq() is arguably an internal xics function that we shouldn't
be calling directly from here, but do because of.. reasons.

As it happens, I have another patch in the works which will move this
function back into xics_spapr.c and bind it more tightly to the xics
code, so I think that will address your concern.

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

* Re: [PATCH 13/20] spapr: Eliminate SpaprIrq:get_nodename method
  2019-09-26  7:48   ` Greg Kurz
@ 2019-09-26 11:36     ` David Gibson
  0 siblings, 0 replies; 93+ messages in thread
From: David Gibson @ 2019-09-26 11:36 UTC (permalink / raw)
  To: Greg Kurz
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

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

On Thu, Sep 26, 2019 at 09:48:39AM +0200, Greg Kurz wrote:
> On Wed, 25 Sep 2019 16:45:27 +1000
> David Gibson <david@gibson.dropbear.id.au> wrote:
> 
> > 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.
> > 
> > So, the method is unnecessary.
> > 
> 
> So is the XICS_NODENAME macro which was introduced by the same
> commit 743ed566c1d80, and it seems that "interrupt-controller"
> is a well-known string that is used everywhere:
> 
> [greg@bahia qemu-spapr]$ git grep -E \"interrupt-controller\"
> hw/arm/virt.c:    qemu_fdt_setprop(vms->fdt, nodename, "interrupt-controller", NULL, 0);
> hw/arm/xlnx-versal-virt.c:    qemu_fdt_setprop(s->fdt, nodename, "interrupt-controller", NULL, 0);
> hw/intc/sh_intc.c:                          "interrupt-controller", 0x100000000ULL);
> hw/intc/spapr_xive.c:    _FDT(fdt_setprop(fdt, node, "interrupt-controller", NULL, 0));
> hw/intc/xics_spapr.c:    _FDT(fdt_setprop(fdt, node, "interrupt-controller", NULL, 0));
> hw/pci/pci.c:    { 0x0800, "Interrupt controller", "interrupt-controller"},
> hw/ppc/e500.c:    qemu_fdt_setprop(fdt, mpic, "interrupt-controller", NULL, 0);
> hw/ppc/pnv.c:    _FDT((fdt_setprop(fdt, offset, "interrupt-controller", NULL, 0)));
> hw/ppc/spapr_events.c:    _FDT((fdt_setprop(fdt, event_sources, "interrupt-controller", NULL, 0)));
> hw/ppc/spapr_irq.c:    const char *nodename = "interrupt-controller";
> hw/ppc/spapr_pci.c:    { PCI_CLASS_SYSTEM_PIC, "interrupt-controller", pic_iface },
> hw/ppc/spapr_vio.c:    _FDT(fdt_setprop(fdt, node, "interrupt-controller", NULL, 0));
> hw/riscv/sifive_u.c:        qemu_fdt_setprop(fdt, intc, "interrupt-controller", NULL, 0);
> hw/riscv/sifive_u.c:    qemu_fdt_setprop(fdt, nodename, "interrupt-controller", NULL, 0);
> hw/riscv/spike.c:        qemu_fdt_setprop(fdt, intc, "interrupt-controller", NULL, 0);
> hw/riscv/virt.c:        qemu_fdt_setprop(fdt, intc, "interrupt-controller", NULL, 0);
> hw/riscv/virt.c:    qemu_fdt_setprop(fdt, nodename, "interrupt-controller", NULL, 0);
> include/hw/ppc/spapr.h: * "interrupt-controller" node has its "#interrupt-cells" property set to 2 (ie,
> include/hw/ppc/xics_spapr.h:#define XICS_NODENAME "interrupt-controller"
> 
> Maybe drop XICS_NODENAME as well while here ?

Fair point, done.

> 
> With or without that,
> 
> Reviewed-by: Greg Kurz <groug@kaod.org>
> 
> > Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> > ---
> >  hw/ppc/spapr_irq.c         | 25 +++----------------------
> >  include/hw/ppc/spapr_irq.h |  1 -
> >  2 files changed, 3 insertions(+), 23 deletions(-)
> > 
> > diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> > index 038bfffff4..79167ccc68 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()) {
> > @@ -393,7 +382,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,
> >  };
> >  
> > @@ -538,11 +526,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
> >   */
> > @@ -560,7 +543,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 */
> >  };
> >  
> > @@ -697,13 +679,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;
> >      }
> >  
> > @@ -787,6 +769,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;
> >  
> 

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

* Re: [PATCH 16/20] spapr, xics, xive: Better use of assert()s on irq claim/free paths
  2019-09-26  8:08   ` Greg Kurz
@ 2019-09-26 11:39     ` David Gibson
  0 siblings, 0 replies; 93+ messages in thread
From: David Gibson @ 2019-09-26 11:39 UTC (permalink / raw)
  To: Greg Kurz
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

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

On Thu, Sep 26, 2019 at 10:08:41AM +0200, Greg Kurz wrote:
> On Wed, 25 Sep 2019 16:45:30 +1000
> David Gibson <david@gibson.dropbear.id.au> wrote:
> 
> > 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>
> > ---
> >  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 c40357a985..261d66ba17 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)
> > @@ -628,6 +624,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);
> >  }
> >  
> > @@ -635,6 +634,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));
> 
> Non surprisingly this makes checkpatch unhappy:
> 
> ERROR: spaces required around that '+' (ctx:VxV)
> #91: FILE: hw/ppc/spapr_irq.c:638:
> +    assert((irq+num) <= (spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE));

Oops, fixed.  I hadn't done a checkpatch run yet, since I'm still
working actively on the series.

> 
> With that fixed,
> 
> Reviewed-by: Greg Kurz <groug@kaod.org>
> 
> > +
> >      for (i = irq; i < (irq + num); i++) {
> >          spapr->irq->free(spapr, irq);
> >      }
> 

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

* Re: [PATCH 11/20] spapr: Fix indexing of XICS irqs
  2019-09-26 11:32         ` David Gibson
@ 2019-09-26 14:44           ` Greg Kurz
  0 siblings, 0 replies; 93+ messages in thread
From: Greg Kurz @ 2019-09-26 14:44 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

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

On Thu, 26 Sep 2019 21:32:18 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> On Thu, Sep 26, 2019 at 09:21:41AM +0200, Greg Kurz wrote:
> > On Thu, 26 Sep 2019 11:31:48 +1000
> > David Gibson <david@gibson.dropbear.id.au> wrote:
> > 
> > > On Wed, Sep 25, 2019 at 10:17:46PM +0200, Greg Kurz wrote:
> > > > On Wed, 25 Sep 2019 16:45:25 +1000
> > > > David Gibson <david@gibson.dropbear.id.au> wrote:
> > > > 
> > > > > 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: Greg Kurz <groug@kaod.org>
> > > > 
> > > > Further cleanup could be to have the XICS backend to only take global
> > > > irq numbers and to convert them to ICS source numbers internally. This
> > > > would put an end to the confusion between srcno/irq in the frontend
> > > > code.
> > > 
> > > Yeah, maybe.  But the local srcnos do actually make sense from within
> > > the perspective of ICS, so I'm not all that keen to do that.
> > > 
> > 
> > Not sure to understand what you mean by "within the perspective of ICS".
> > 
> > My concern is actually to get rid of ics->offset users in spapr_irq.c.
> > 
> > eg,
> > 
> > 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);
> > }
> > 
> > It looks like we should do something like:
> > 
> > static void spapr_irq_set_irq_xics(void *opaque, int irq, int val)
> > {
> >     SpaprMachineState *spapr = opaque;
> > 
> >     ics_set_irq(spapr->ics, irq, val);
> > }
> > 
> > and have ics_set_irq() do:
> > 
> >     uint32_t srcno = irq - spapr->ics->offset;
> > 
> > Are you inferring that it is better to keep the irq to srcno conversions
> > in spapr_irq.c ?
> 
> Ah, I see what you mean.  So, the reason srcno appears here is that
> ics_set_irq() is arguably an internal xics function that we shouldn't
> be calling directly from here, but do because of.. reasons.
> 
> As it happens, I have another patch in the works which will move this
> function back into xics_spapr.c and bind it more tightly to the xics
> code, so I think that will address your concern.
> 

Great ! :)

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

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

* Re: [PATCH 20/20] spapr: Eliminate SpaprIrq::init hook
  2019-09-26  7:05       ` Cédric Le Goater
  2019-09-26 11:29         ` David Gibson
@ 2019-09-26 15:35         ` Greg Kurz
  2019-09-27  5:51           ` David Gibson
  1 sibling, 1 reply; 93+ messages in thread
From: Greg Kurz @ 2019-09-26 15:35 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	Marc-André Lureau, Paolo Bonzini, philmd, David Gibson

On Thu, 26 Sep 2019 09:05:56 +0200
Cédric Le Goater <clg@kaod.org> wrote:

> >>> +    if (spapr->irq->xive) {
> >>> +        uint32_t nr_servers = spapr_max_server_number(spapr);
> >>> +        DeviceState *dev;
> >>> +        int i;
> >>> +
> >>> +        dev = qdev_create(NULL, TYPE_SPAPR_XIVE);
> >>> +        qdev_prop_set_uint32(dev, "nr-irqs",
> >>> +                             spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
> >>> +        /*
> >>> +         * 8 XIVE END structures per CPU. One for each available
> >>> +         * priority
> >>> +         */
> >>> +        qdev_prop_set_uint32(dev, "nr-ends", nr_servers << 3);
> >>> +        qdev_init_nofail(dev);
> >>> +
> >>> +        spapr->xive = SPAPR_XIVE(dev);
> >>> +
> >>> +        /* Enable the CPU IPIs */
> >>> +        for (i = 0; i < nr_servers; ++i) {
> >>> +            Error *local_err = NULL;
> >>> +
> >>> +            spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i, false, &local_err);
> >>> +            if (local_err) {
> >>> +                goto out;
> >>> +            }
> >>> +        }
> >>
> >> We could move the IPI claim part in the realize routine of SPAPR_XIVE.
> > 
> > Yeah, I know.  I thought about this, but there's a slight complication
> > in that the XIVE part doesn't know nr_servers directly.  There's
> > several possible ways to handle that, but I wasn't 100% happy with any
> > that I came up with yet.
> 
> The "nr-ends" property was inappropriate, "nr-servers" would have been
> better and we would have hidden the calculation of ENDs 'nr_servers << 3'
> in the realize routine of SpaprXive. 
> 

Yeah it would make sense to have nr_servers within the sPAPR XIVE object,
so that we don't have to pass it when building the FDT node. Same stands
for XICS actually.

And as part of my current work to reduce HW VP consumption, I also need
nr_servers to pass it to the KVM device.

> I don't think we can change that without breaking migration though :/
> 

Hmm... why ? The QOM property is just an interface, it doesn't change the
state. In the end we migrate the same number of XiveEND objects.

> C.
> 
> >>
> >>> +        spapr_xive_hcall_init(spapr);
> >>
> >> This also.
> > 
> > Right.
> > 
> >> It can be done later one.
> > 
> > That's my intention.
> > 
> >>
> >> C.
> >>
> >>> +    }
> >>>  
> >>>      spapr->qirqs = qemu_allocate_irqs(spapr->irq->set_irq, spapr,
> >>>                                        spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
> >>> +
> >>> +out:
> >>> +    error_propagate(errp, local_err);
> >>>  }
> >>>  
> >>>  void spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
> >>> @@ -757,7 +744,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 6816cb0500..fa862c665b 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);
> >>>      void (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
> >>>      void (*free)(SpaprMachineState *spapr, int irq);
> >>>      void (*print_info)(SpaprMachineState *spapr, Monitor *mon);
> >>> diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h
> >>> index 691a6d00f7..267984a97b 100644
> >>> --- a/include/hw/ppc/xics_spapr.h
> >>> +++ b/include/hw/ppc/xics_spapr.h
> >>> @@ -34,6 +34,7 @@
> >>>  #define TYPE_ICS_SPAPR "ics-spapr"
> >>>  #define ICS_SPAPR(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SPAPR)
> >>>  
> >>> +void ics_spapr_create(SpaprMachineState *spapr, int nr_xirqs, Error **errp);
> >>>  void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
> >>>                     uint32_t phandle);
> >>>  int xics_kvm_connect(SpaprMachineState *spapr, Error **errp);
> >>>
> >>
> > 
> 



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

* Re: [PATCH 20/20] spapr: Eliminate SpaprIrq::init hook
  2019-09-25  6:45 ` [PATCH 20/20] spapr: Eliminate SpaprIrq::init hook David Gibson
  2019-09-25  7:31   ` Cédric Le Goater
@ 2019-09-26 15:39   ` Greg Kurz
  2019-09-27 14:12     ` Greg Kurz
  1 sibling, 1 reply; 93+ messages in thread
From: Greg Kurz @ 2019-09-26 15:39 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

On Wed, 25 Sep 2019 16:45:34 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> 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: Greg Kurz <groug@kaod.org>

>  hw/ppc/spapr_irq.c          | 138 ++++++++++++++++--------------------
>  include/hw/ppc/spapr_irq.h  |   1 -
>  include/hw/ppc/xics_spapr.h |   1 +
>  3 files changed, 63 insertions(+), 77 deletions(-)
> 
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index 073f375ba2..62647dd5a3 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -91,27 +91,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 void spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
>                                   Error **errp)
>  {
> @@ -212,7 +191,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,
> @@ -227,37 +205,6 @@ SpaprIrq spapr_irq_xics = {
>  /*
>   * XIVE IRQ backend.
>   */
> -static void spapr_irq_init_xive(SpaprMachineState *spapr, Error **errp)
> -{
> -    uint32_t nr_servers = spapr_max_server_number(spapr);
> -    DeviceState *dev;
> -    int i;
> -
> -    dev = qdev_create(NULL, TYPE_SPAPR_XIVE);
> -    qdev_prop_set_uint32(dev, "nr-irqs",
> -                         spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
> -    /*
> -     * 8 XIVE END structures per CPU. One for each available priority
> -     */
> -    qdev_prop_set_uint32(dev, "nr-ends", nr_servers << 3);
> -    qdev_init_nofail(dev);
> -
> -    spapr->xive = SPAPR_XIVE(dev);
> -
> -    /* Enable the CPU IPIs */
> -    for (i = 0; i < nr_servers; ++i) {
> -        Error *local_err = NULL;
> -
> -        spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i, false, &local_err);
> -        if (local_err) {
> -            error_propagate(errp, local_err);
> -            return;
> -        }
> -    }
> -
> -    spapr_xive_hcall_init(spapr);
> -}
> -
>  static void spapr_irq_claim_xive(SpaprMachineState *spapr, int irq, bool lsi,
>                                   Error **errp)
>  {
> @@ -361,7 +308,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,
> @@ -392,23 +338,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 void spapr_irq_claim_dual(SpaprMachineState *spapr, int irq, bool lsi,
>                                   Error **errp)
>  {
> @@ -520,7 +449,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,
> @@ -608,8 +536,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>  
>      spapr_irq_check(spapr, &local_err);
>      if (local_err) {
> -        error_propagate(errp, local_err);
> -        return;
> +        goto out;
>      }
>  
>      /* Initialize the MSI IRQ allocator. */
> @@ -617,10 +544,70 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
>          spapr_irq_msi_init(spapr, spapr->irq->nr_msis);
>      }
>  
> -    spapr->irq->init(spapr, errp);
> +    if (spapr->irq->xics) {
> +        Object *obj;
> +
> +        obj = object_new(TYPE_ICS_SPAPR);
> +        object_property_add_child(OBJECT(spapr), "ics", obj, &local_err);
> +        if (local_err) {
> +            goto out;
> +        }
> +
> +        object_property_add_const_link(obj, ICS_PROP_XICS, OBJECT(spapr),
> +                                       &local_err);
> +        if (local_err) {
> +            goto out;
> +        }
> +
> +        object_property_set_int(obj, spapr->irq->nr_xirqs, "nr-irqs",
> +                                &local_err);
> +        if (local_err) {
> +            goto out;
> +        }
> +
> +        object_property_set_bool(obj, true, "realized", &local_err);
> +        if (local_err) {
> +            goto out;
> +        }
> +
> +        spapr->ics = ICS_SPAPR(obj);
> +    }
> +
> +    if (spapr->irq->xive) {
> +        uint32_t nr_servers = spapr_max_server_number(spapr);
> +        DeviceState *dev;
> +        int i;
> +
> +        dev = qdev_create(NULL, TYPE_SPAPR_XIVE);
> +        qdev_prop_set_uint32(dev, "nr-irqs",
> +                             spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
> +        /*
> +         * 8 XIVE END structures per CPU. One for each available
> +         * priority
> +         */
> +        qdev_prop_set_uint32(dev, "nr-ends", nr_servers << 3);
> +        qdev_init_nofail(dev);
> +
> +        spapr->xive = SPAPR_XIVE(dev);
> +
> +        /* Enable the CPU IPIs */
> +        for (i = 0; i < nr_servers; ++i) {
> +            Error *local_err = NULL;
> +
> +            spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i, false, &local_err);
> +            if (local_err) {
> +                goto out;
> +            }
> +        }
> +
> +        spapr_xive_hcall_init(spapr);
> +    }
>  
>      spapr->qirqs = qemu_allocate_irqs(spapr->irq->set_irq, spapr,
>                                        spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
> +
> +out:
> +    error_propagate(errp, local_err);
>  }
>  
>  void spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
> @@ -757,7 +744,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 6816cb0500..fa862c665b 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);
>      void (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
>      void (*free)(SpaprMachineState *spapr, int irq);
>      void (*print_info)(SpaprMachineState *spapr, Monitor *mon);
> diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h
> index 691a6d00f7..267984a97b 100644
> --- a/include/hw/ppc/xics_spapr.h
> +++ b/include/hw/ppc/xics_spapr.h
> @@ -34,6 +34,7 @@
>  #define TYPE_ICS_SPAPR "ics-spapr"
>  #define ICS_SPAPR(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SPAPR)
>  
> +void ics_spapr_create(SpaprMachineState *spapr, int nr_xirqs, Error **errp);
>  void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
>                     uint32_t phandle);
>  int xics_kvm_connect(SpaprMachineState *spapr, Error **errp);



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

* Re: [PATCH 17/20] spapr: Remove unused return value in claim path
  2019-09-26  8:36   ` Greg Kurz
@ 2019-09-27  1:47     ` David Gibson
  0 siblings, 0 replies; 93+ messages in thread
From: David Gibson @ 2019-09-27  1:47 UTC (permalink / raw)
  To: Greg Kurz
  Cc: Daniel P. Berrangé,
	Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

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

On Thu, Sep 26, 2019 at 10:36:02AM +0200, Greg Kurz wrote:
> On Wed, 25 Sep 2019 16:45:31 +1000
> David Gibson <david@gibson.dropbear.id.au> wrote:
> 
> > spapr_irq_claim() and the hooks it is based on return an integer error code
> > as well as taking an Error ** parameter.  But none of the callers check the
> > integer, so we can remove it and just use the richer Error **.
> > 
> > Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> > ---
> 
> FYI, the very same topic of using the return value versus Error ** to
> check errors was discussed recently in this thread:
> 
> https://lists.gnu.org/archive/html/qemu-devel/2019-09/msg04197.html
> 
> I tend to agree with Daniel (Cc'd) at first thought, but I don't have a strong
> opinion about this yet. It is mostly to inform you that people are currently
> discussing/working on it.

So, I made this change mostly because redundant encodings give me an
itch.  But having read that post and then experimented a bit, I found
the approach he proposes does cut down a noticeable amount of
boilerplate.

So I think I'll move towards that approach and drop this patch.

> 
> >  hw/ppc/spapr_irq.c         | 32 +++++++++++++-------------------
> >  include/hw/ppc/spapr_irq.h |  4 ++--
> >  2 files changed, 15 insertions(+), 21 deletions(-)
> > 
> > diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> > index 261d66ba17..2673a90604 100644
> > --- a/hw/ppc/spapr_irq.c
> > +++ b/hw/ppc/spapr_irq.c
> > @@ -112,8 +112,8 @@ static void spapr_irq_init_xics(SpaprMachineState *spapr, Error **errp)
> >      spapr->ics = ICS_SPAPR(obj);
> >  }
> >  
> > -static int spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
> > -                                Error **errp)
> > +static void spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
> > +                                 Error **errp)
> >  {
> >      ICSState *ics = spapr->ics;
> >  
> > @@ -122,11 +122,10 @@ static int spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
> >  
> >      if (!ics_irq_free(ics, irq - ics->offset)) {
> >          error_setg(errp, "IRQ %d is not free", irq);
> > -        return -1;
> > +        return;
> >      }
> >  
> >      ics_set_irq_type(ics, irq - ics->offset, lsi);
> > -    return 0;
> >  }
> >  
> >  static void spapr_irq_free_xics(SpaprMachineState *spapr, int irq)
> > @@ -252,14 +251,12 @@ static void spapr_irq_init_xive(SpaprMachineState *spapr, Error **errp)
> >      spapr_xive_hcall_init(spapr);
> >  }
> >  
> > -static int spapr_irq_claim_xive(SpaprMachineState *spapr, int irq, bool lsi,
> > -                                Error **errp)
> > +static void 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;
> >  }
> >  
> >  static void spapr_irq_free_xive(SpaprMachineState *spapr, int irq)
> > @@ -406,25 +403,22 @@ static void spapr_irq_init_dual(SpaprMachineState *spapr, Error **errp)
> >      }
> >  }
> >  
> > -static int spapr_irq_claim_dual(SpaprMachineState *spapr, int irq, bool lsi,
> > -                                Error **errp)
> > +static void 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);
> > +    spapr_irq_xics.claim(spapr, irq, lsi, &local_err);
> >      if (local_err) {
> >          error_propagate(errp, local_err);
> > -        return ret;
> > +        return;
> >      }
> >  
> > -    ret = spapr_irq_xive.claim(spapr, irq, lsi, &local_err);
> > +    spapr_irq_xive.claim(spapr, irq, lsi, &local_err);
> >      if (local_err) {
> >          error_propagate(errp, local_err);
> > -        return ret;
> > +        return;
> >      }
> > -
> > -    return ret;
> >  }
> >  
> >  static void spapr_irq_free_dual(SpaprMachineState *spapr, int irq)
> > @@ -622,12 +616,12 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
> >                                        spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
> >  }
> >  
> > -int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
> > +void 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);
> > +    spapr->irq->claim(spapr, irq, lsi, errp);
> >  }
> >  
> >  void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
> > diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
> > index ed88b4599a..75279ca137 100644
> > --- a/include/hw/ppc/spapr_irq.h
> > +++ b/include/hw/ppc/spapr_irq.h
> > @@ -42,7 +42,7 @@ typedef struct SpaprIrq {
> >      uint8_t     ov5;
> >  
> >      void (*init)(SpaprMachineState *spapr, Error **errp);
> > -    int (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
> > +    void (*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,
> > @@ -61,7 +61,7 @@ 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_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
> >  void spapr_irq_free(SpaprMachineState *spapr, int irq, int num);
> >  qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq);
> >  int spapr_irq_post_load(SpaprMachineState *spapr, 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] 93+ messages in thread

* Re: [PATCH 20/20] spapr: Eliminate SpaprIrq::init hook
  2019-09-26 15:35         ` Greg Kurz
@ 2019-09-27  5:51           ` David Gibson
  2019-09-27  6:23             ` Greg Kurz
  0 siblings, 1 reply; 93+ messages in thread
From: David Gibson @ 2019-09-27  5:51 UTC (permalink / raw)
  To: Greg Kurz
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	Cédric Le Goater, Marc-André Lureau, Paolo Bonzini,
	philmd

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

On Thu, Sep 26, 2019 at 05:35:39PM +0200, Greg Kurz wrote:
> On Thu, 26 Sep 2019 09:05:56 +0200
> Cédric Le Goater <clg@kaod.org> wrote:
> 
> > >>> +    if (spapr->irq->xive) {
> > >>> +        uint32_t nr_servers = spapr_max_server_number(spapr);
> > >>> +        DeviceState *dev;
> > >>> +        int i;
> > >>> +
> > >>> +        dev = qdev_create(NULL, TYPE_SPAPR_XIVE);
> > >>> +        qdev_prop_set_uint32(dev, "nr-irqs",
> > >>> +                             spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
> > >>> +        /*
> > >>> +         * 8 XIVE END structures per CPU. One for each available
> > >>> +         * priority
> > >>> +         */
> > >>> +        qdev_prop_set_uint32(dev, "nr-ends", nr_servers << 3);
> > >>> +        qdev_init_nofail(dev);
> > >>> +
> > >>> +        spapr->xive = SPAPR_XIVE(dev);
> > >>> +
> > >>> +        /* Enable the CPU IPIs */
> > >>> +        for (i = 0; i < nr_servers; ++i) {
> > >>> +            Error *local_err = NULL;
> > >>> +
> > >>> +            spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i, false, &local_err);
> > >>> +            if (local_err) {
> > >>> +                goto out;
> > >>> +            }
> > >>> +        }
> > >>
> > >> We could move the IPI claim part in the realize routine of SPAPR_XIVE.
> > > 
> > > Yeah, I know.  I thought about this, but there's a slight complication
> > > in that the XIVE part doesn't know nr_servers directly.  There's
> > > several possible ways to handle that, but I wasn't 100% happy with any
> > > that I came up with yet.
> > 
> > The "nr-ends" property was inappropriate, "nr-servers" would have been
> > better and we would have hidden the calculation of ENDs 'nr_servers << 3'
> > in the realize routine of SpaprXive. 
> > 
> 
> Yeah it would make sense to have nr_servers within the sPAPR XIVE object,
> so that we don't have to pass it when building the FDT node. Same stands
> for XICS actually.
> 
> And as part of my current work to reduce HW VP consumption, I also need
> nr_servers to pass it to the KVM device.
> 
> > I don't think we can change that without breaking migration though :/
> > 
> 
> Hmm... why ? The QOM property is just an interface, it doesn't change the
> state. In the end we migrate the same number of XiveEND objects.

Yeah, I think it can probably be done.  I don't really have the energy
left to sort it out for the time being, maybe one day.

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

* Re: [PATCH 20/20] spapr: Eliminate SpaprIrq::init hook
  2019-09-27  5:51           ` David Gibson
@ 2019-09-27  6:23             ` Greg Kurz
  0 siblings, 0 replies; 93+ messages in thread
From: Greg Kurz @ 2019-09-27  6:23 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	Cédric Le Goater, Marc-André Lureau, Paolo Bonzini,
	philmd

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

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

> On Thu, Sep 26, 2019 at 05:35:39PM +0200, Greg Kurz wrote:
> > On Thu, 26 Sep 2019 09:05:56 +0200
> > Cédric Le Goater <clg@kaod.org> wrote:
> > 
> > > >>> +    if (spapr->irq->xive) {
> > > >>> +        uint32_t nr_servers = spapr_max_server_number(spapr);
> > > >>> +        DeviceState *dev;
> > > >>> +        int i;
> > > >>> +
> > > >>> +        dev = qdev_create(NULL, TYPE_SPAPR_XIVE);
> > > >>> +        qdev_prop_set_uint32(dev, "nr-irqs",
> > > >>> +                             spapr->irq->nr_xirqs + SPAPR_XIRQ_BASE);
> > > >>> +        /*
> > > >>> +         * 8 XIVE END structures per CPU. One for each available
> > > >>> +         * priority
> > > >>> +         */
> > > >>> +        qdev_prop_set_uint32(dev, "nr-ends", nr_servers << 3);
> > > >>> +        qdev_init_nofail(dev);
> > > >>> +
> > > >>> +        spapr->xive = SPAPR_XIVE(dev);
> > > >>> +
> > > >>> +        /* Enable the CPU IPIs */
> > > >>> +        for (i = 0; i < nr_servers; ++i) {
> > > >>> +            Error *local_err = NULL;
> > > >>> +
> > > >>> +            spapr_xive_irq_claim(spapr->xive, SPAPR_IRQ_IPI + i, false, &local_err);
> > > >>> +            if (local_err) {
> > > >>> +                goto out;
> > > >>> +            }
> > > >>> +        }
> > > >>
> > > >> We could move the IPI claim part in the realize routine of SPAPR_XIVE.
> > > > 
> > > > Yeah, I know.  I thought about this, but there's a slight complication
> > > > in that the XIVE part doesn't know nr_servers directly.  There's
> > > > several possible ways to handle that, but I wasn't 100% happy with any
> > > > that I came up with yet.
> > > 
> > > The "nr-ends" property was inappropriate, "nr-servers" would have been
> > > better and we would have hidden the calculation of ENDs 'nr_servers << 3'
> > > in the realize routine of SpaprXive. 
> > > 
> > 
> > Yeah it would make sense to have nr_servers within the sPAPR XIVE object,
> > so that we don't have to pass it when building the FDT node. Same stands
> > for XICS actually.
> > 
> > And as part of my current work to reduce HW VP consumption, I also need
> > nr_servers to pass it to the KVM device.
> > 
> > > I don't think we can change that without breaking migration though :/
> > > 
> > 
> > Hmm... why ? The QOM property is just an interface, it doesn't change the
> > state. In the end we migrate the same number of XiveEND objects.
> 
> Yeah, I think it can probably be done.  I don't really have the energy
> left to sort it out for the time being, maybe one day.
> 

As mentioned above I have another need for "nr-servers", I'll have
a look.

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

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

* Re: [PATCH 20/20] spapr: Eliminate SpaprIrq::init hook
  2019-09-26 15:39   ` Greg Kurz
@ 2019-09-27 14:12     ` Greg Kurz
  2019-09-29  9:34       ` David Gibson
  0 siblings, 1 reply; 93+ messages in thread
From: Greg Kurz @ 2019-09-27 14:12 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

On Thu, 26 Sep 2019 17:39:37 +0200
Greg Kurz <groug@kaod.org> wrote:

> On Wed, 25 Sep 2019 16:45:34 +1000
> David Gibson <david@gibson.dropbear.id.au> wrote:
> 
> > 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: Greg Kurz <groug@kaod.org>
> 

Just one nit...

> >  hw/ppc/spapr_irq.c          | 138 ++++++++++++++++--------------------
> >  include/hw/ppc/spapr_irq.h  |   1 -
> >  include/hw/ppc/xics_spapr.h |   1 +
[...]
> > diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h
> > index 691a6d00f7..267984a97b 100644
> > --- a/include/hw/ppc/xics_spapr.h
> > +++ b/include/hw/ppc/xics_spapr.h
> > @@ -34,6 +34,7 @@
> >  #define TYPE_ICS_SPAPR "ics-spapr"
> >  #define ICS_SPAPR(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SPAPR)
> >  
> > +void ics_spapr_create(SpaprMachineState *spapr, int nr_xirqs, Error **errp);

... this looks like a leftover.

> >  void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
> >                     uint32_t phandle);
> >  int xics_kvm_connect(SpaprMachineState *spapr, Error **errp);
> 



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

* Re: [PATCH 06/20] xics: Create sPAPR specific ICS subtype
  2019-09-26  0:56       ` David Gibson
  2019-09-26  7:09         ` Cédric Le Goater
@ 2019-09-27 16:05         ` Greg Kurz
  2019-09-30  8:45           ` David Gibson
  1 sibling, 1 reply; 93+ messages in thread
From: Greg Kurz @ 2019-09-27 16:05 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	Cédric Le Goater, Marc-André Lureau, Paolo Bonzini,
	philmd

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

On Thu, 26 Sep 2019 10:56:46 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> On Wed, Sep 25, 2019 at 10:55:35AM +0200, Cédric Le Goater wrote:
> > On 25/09/2019 10:40, Greg Kurz wrote:
> > > On Wed, 25 Sep 2019 16:45:20 +1000
> > > David Gibson <david@gibson.dropbear.id.au> wrote:
> > > 
> > >> We create a subtype of TYPE_ICS specifically for sPAPR.  For now all this
> > >> does is move the setup of the PAPR specific hcalls and RTAS calls to
> > >> the realize() function for this, rather than requiring the PAPR code to
> > >> explicitly call xics_spapr_init().  In future it will have some more
> > >> function.
> > >>
> > >> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> > >> ---
> > > 
> > > LGTM, but for extra safety I would also introduce a SpaprIcsState typedef
> > 
> > why ? we have ICS_SPAPR() for the checks already.
> 
> Eh.. using typedefs when we haven't actually extended a base type
> isn't common QOM practice.  Yes, it's not as typesafe as it could be,
> but I'm not really inclined to go to the extra effort here.
> 

I'll soon need to extend the base type with a nr_servers field,
and while here with an fd field as well in order to get rid of
the ugly global in xics.c. I'll go to the extra effort :)

> > 
> > > and use it everywhere where we only expect this subtype. Especially in
> > > the definition of SpaprMachineState.
> > > 
> > >>  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 */
> > > 
> > 
> 


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

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

* Re: [PATCH 20/20] spapr: Eliminate SpaprIrq::init hook
  2019-09-27 14:12     ` Greg Kurz
@ 2019-09-29  9:34       ` David Gibson
  0 siblings, 0 replies; 93+ messages in thread
From: David Gibson @ 2019-09-29  9:34 UTC (permalink / raw)
  To: Greg Kurz
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	clg, Marc-André Lureau, Paolo Bonzini, philmd

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

On Fri, Sep 27, 2019 at 04:12:40PM +0200, Greg Kurz wrote:
> On Thu, 26 Sep 2019 17:39:37 +0200
> Greg Kurz <groug@kaod.org> wrote:
> 
> > On Wed, 25 Sep 2019 16:45:34 +1000
> > David Gibson <david@gibson.dropbear.id.au> wrote:
> > 
> > > 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: Greg Kurz <groug@kaod.org>
> > 
> 
> Just one nit...
> 
> > >  hw/ppc/spapr_irq.c          | 138 ++++++++++++++++--------------------
> > >  include/hw/ppc/spapr_irq.h  |   1 -
> > >  include/hw/ppc/xics_spapr.h |   1 +
> [...]
> > > diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h
> > > index 691a6d00f7..267984a97b 100644
> > > --- a/include/hw/ppc/xics_spapr.h
> > > +++ b/include/hw/ppc/xics_spapr.h
> > > @@ -34,6 +34,7 @@
> > >  #define TYPE_ICS_SPAPR "ics-spapr"
> > >  #define ICS_SPAPR(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SPAPR)
> > >  
> > > +void ics_spapr_create(SpaprMachineState *spapr, int nr_xirqs, Error **errp);
> 
> ... this looks like a leftover.

Oops, yes, fixed.

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

* Re: [PATCH 06/20] xics: Create sPAPR specific ICS subtype
  2019-09-27 16:05         ` Greg Kurz
@ 2019-09-30  8:45           ` David Gibson
  2019-09-30 17:00             ` Greg Kurz
  0 siblings, 1 reply; 93+ messages in thread
From: David Gibson @ 2019-09-30  8:45 UTC (permalink / raw)
  To: Greg Kurz
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	Cédric Le Goater, Marc-André Lureau, Paolo Bonzini,
	philmd

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

On Fri, Sep 27, 2019 at 06:05:56PM +0200, Greg Kurz wrote:
> On Thu, 26 Sep 2019 10:56:46 +1000
> David Gibson <david@gibson.dropbear.id.au> wrote:
> 
> > On Wed, Sep 25, 2019 at 10:55:35AM +0200, Cédric Le Goater wrote:
> > > On 25/09/2019 10:40, Greg Kurz wrote:
> > > > On Wed, 25 Sep 2019 16:45:20 +1000
> > > > David Gibson <david@gibson.dropbear.id.au> wrote:
> > > > 
> > > >> We create a subtype of TYPE_ICS specifically for sPAPR.  For now all this
> > > >> does is move the setup of the PAPR specific hcalls and RTAS calls to
> > > >> the realize() function for this, rather than requiring the PAPR code to
> > > >> explicitly call xics_spapr_init().  In future it will have some more
> > > >> function.
> > > >>
> > > >> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> > > >> ---
> > > > 
> > > > LGTM, but for extra safety I would also introduce a SpaprIcsState typedef
> > > 
> > > why ? we have ICS_SPAPR() for the checks already.
> > 
> > Eh.. using typedefs when we haven't actually extended a base type
> > isn't common QOM practice.  Yes, it's not as typesafe as it could be,
> > but I'm not really inclined to go to the extra effort here.
> 
> I'll soon need to extend the base type with a nr_servers field,

Uh.. nr_servers doesn't seem like it belongs in the base ICS type.
That really would conflict with the pnv usage where the ICS is
supposed to just represent the ICS, not the xics as a whole.  If you
need nr_servers information here, it seems like pulling it via a
method in XICSFabric would make more sense.

> and while here with an fd field as well in order to get rid of
> the ugly global in xics.c. I'll go to the extra effort :)

That could go in the derived type.  We already kind of conflate ICS
and XICS-as-a-whole for the PAPR subtype, and the KVM xics is PAPR
only anyway.

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

* Re: [PATCH 06/20] xics: Create sPAPR specific ICS subtype
  2019-09-30  8:45           ` David Gibson
@ 2019-09-30 17:00             ` Greg Kurz
  2019-10-01  1:45               ` David Gibson
  0 siblings, 1 reply; 93+ messages in thread
From: Greg Kurz @ 2019-09-30 17:00 UTC (permalink / raw)
  To: David Gibson
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	Cédric Le Goater, Marc-André Lureau, Paolo Bonzini,
	philmd

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

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

> On Fri, Sep 27, 2019 at 06:05:56PM +0200, Greg Kurz wrote:
> > On Thu, 26 Sep 2019 10:56:46 +1000
> > David Gibson <david@gibson.dropbear.id.au> wrote:
> > 
> > > On Wed, Sep 25, 2019 at 10:55:35AM +0200, Cédric Le Goater wrote:
> > > > On 25/09/2019 10:40, Greg Kurz wrote:
> > > > > On Wed, 25 Sep 2019 16:45:20 +1000
> > > > > David Gibson <david@gibson.dropbear.id.au> wrote:
> > > > > 
> > > > >> We create a subtype of TYPE_ICS specifically for sPAPR.  For now all this
> > > > >> does is move the setup of the PAPR specific hcalls and RTAS calls to
> > > > >> the realize() function for this, rather than requiring the PAPR code to
> > > > >> explicitly call xics_spapr_init().  In future it will have some more
> > > > >> function.
> > > > >>
> > > > >> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> > > > >> ---
> > > > > 
> > > > > LGTM, but for extra safety I would also introduce a SpaprIcsState typedef
> > > > 
> > > > why ? we have ICS_SPAPR() for the checks already.
> > > 
> > > Eh.. using typedefs when we haven't actually extended a base type
> > > isn't common QOM practice.  Yes, it's not as typesafe as it could be,
> > > but I'm not really inclined to go to the extra effort here.
> > 
> > I'll soon need to extend the base type with a nr_servers field,
> 
> Uh.. nr_servers doesn't seem like it belongs in the base ICS type.

Of course ! I re-used the wording "extended a base type" of your sentence,
that I understand as "a subtype extends a base type with some more data".
I'm talking about the sPAPR ICS subtype here, not the base ICS type.

> That really would conflict with the pnv usage where the ICS is
> supposed to just represent the ICS, not the xics as a whole.  If you
> need nr_servers information here, it seems like pulling it via a
> method in XICSFabric would make more sense.
> 
> > and while here with an fd field as well in order to get rid of
> > the ugly global in xics.c. I'll go to the extra effort :)
> 
> That could go in the derived type.  We already kind of conflate ICS
> and XICS-as-a-whole for the PAPR subtype, and the KVM xics is PAPR
> only anyway.
> 

Exactly, so that's why I was thinking about adding nr_servers there,
but it could go to XICSFabric as well I guess.

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

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

* Re: [PATCH 06/20] xics: Create sPAPR specific ICS subtype
  2019-09-30 17:00             ` Greg Kurz
@ 2019-10-01  1:45               ` David Gibson
  0 siblings, 0 replies; 93+ messages in thread
From: David Gibson @ 2019-10-01  1:45 UTC (permalink / raw)
  To: Greg Kurz
  Cc: Jason Wang, Riku Voipio, qemu-devel, Laurent Vivier, qemu-ppc,
	Cédric Le Goater, Marc-André Lureau, Paolo Bonzini,
	philmd

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

On Mon, Sep 30, 2019 at 07:00:43PM +0200, Greg Kurz wrote:
> On Mon, 30 Sep 2019 18:45:30 +1000
> David Gibson <david@gibson.dropbear.id.au> wrote:
> 
> > On Fri, Sep 27, 2019 at 06:05:56PM +0200, Greg Kurz wrote:
> > > On Thu, 26 Sep 2019 10:56:46 +1000
> > > David Gibson <david@gibson.dropbear.id.au> wrote:
> > > 
> > > > On Wed, Sep 25, 2019 at 10:55:35AM +0200, Cédric Le Goater wrote:
> > > > > On 25/09/2019 10:40, Greg Kurz wrote:
> > > > > > On Wed, 25 Sep 2019 16:45:20 +1000
> > > > > > David Gibson <david@gibson.dropbear.id.au> wrote:
> > > > > > 
> > > > > >> We create a subtype of TYPE_ICS specifically for sPAPR.  For now all this
> > > > > >> does is move the setup of the PAPR specific hcalls and RTAS calls to
> > > > > >> the realize() function for this, rather than requiring the PAPR code to
> > > > > >> explicitly call xics_spapr_init().  In future it will have some more
> > > > > >> function.
> > > > > >>
> > > > > >> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> > > > > >> ---
> > > > > > 
> > > > > > LGTM, but for extra safety I would also introduce a SpaprIcsState typedef
> > > > > 
> > > > > why ? we have ICS_SPAPR() for the checks already.
> > > > 
> > > > Eh.. using typedefs when we haven't actually extended a base type
> > > > isn't common QOM practice.  Yes, it's not as typesafe as it could be,
> > > > but I'm not really inclined to go to the extra effort here.
> > > 
> > > I'll soon need to extend the base type with a nr_servers field,
> > 
> > Uh.. nr_servers doesn't seem like it belongs in the base ICS type.
> 
> Of course ! I re-used the wording "extended a base type" of your sentence,
> that I understand as "a subtype extends a base type with some more data".
> I'm talking about the sPAPR ICS subtype here, not the base ICS type.

Ah, ok.

> > That really would conflict with the pnv usage where the ICS is
> > supposed to just represent the ICS, not the xics as a whole.  If you
> > need nr_servers information here, it seems like pulling it via a
> > method in XICSFabric would make more sense.
> > 
> > > and while here with an fd field as well in order to get rid of
> > > the ugly global in xics.c. I'll go to the extra effort :)
> > 
> > That could go in the derived type.  We already kind of conflate ICS
> > and XICS-as-a-whole for the PAPR subtype, and the KVM xics is PAPR
> > only anyway.
> > 
> 
> Exactly, so that's why I was thinking about adding nr_servers there,
> but it could go to XICSFabric as well I guess.



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

end of thread, other threads:[~2019-10-01  1:59 UTC | newest]

Thread overview: 93+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-25  6:45 [PATCH 00/20] spapr: IRQ subsystem cleanups David Gibson
2019-09-25  6:45 ` [PATCH 01/20] xics: Use incomplete type for XICSFabric David Gibson
2019-09-25  6:55   ` Cédric Le Goater
2019-09-25  7:48     ` Greg Kurz
2019-09-25  7:45   ` Greg Kurz
2019-09-25  6:45 ` [PATCH 02/20] xics: Eliminate 'reject', 'resend' and 'eoi' class hooks David Gibson
2019-09-25  6:45 ` [PATCH 03/20] xics: Rename misleading ics_simple_*() functions David Gibson
2019-09-25  6:45 ` [PATCH 04/20] xics: Eliminate reset hook David Gibson
2019-09-25  7:33   ` Cédric Le Goater
2019-09-25  7:59   ` Greg Kurz
2019-09-26  2:54     ` David Gibson
2019-09-25  6:45 ` [PATCH 05/20] xics: Merge TYPE_ICS_BASE and TYPE_ICS_SIMPLE classes David Gibson
2019-09-25  8:16   ` Greg Kurz
2019-09-25  8:31     ` Greg Kurz
2019-09-26  0:55       ` David Gibson
2019-09-26  0:52     ` David Gibson
2019-09-25 12:47   ` Cédric Le Goater
2019-09-25  6:45 ` [PATCH 06/20] xics: Create sPAPR specific ICS subtype David Gibson
2019-09-25  7:34   ` Cédric Le Goater
2019-09-25  8:40   ` Greg Kurz
2019-09-25  8:55     ` Cédric Le Goater
2019-09-25  9:07       ` Greg Kurz
2019-09-26  0:56       ` David Gibson
2019-09-26  7:09         ` Cédric Le Goater
2019-09-27 16:05         ` Greg Kurz
2019-09-30  8:45           ` David Gibson
2019-09-30 17:00             ` Greg Kurz
2019-10-01  1:45               ` David Gibson
2019-09-25  6:45 ` [PATCH 07/20] spapr: Fold spapr_phb_lsi_qirq() into its single caller David Gibson
2019-09-25  6:58   ` Cédric Le Goater
2019-09-25  8:56   ` Greg Kurz
2019-09-26  7:08   ` Philippe Mathieu-Daudé
2019-09-25  6:45 ` [PATCH 08/20] spapr: Replace spapr_vio_qirq() helper with spapr_vio_irq_pulse() helper David Gibson
2019-09-25  6:58   ` Cédric Le Goater
2019-09-25  8:57   ` Greg Kurz
2019-09-26  7:08   ` Philippe Mathieu-Daudé
2019-09-25  6:45 ` [PATCH 09/20] spapr: Clarify and fix handling of nr_irqs David Gibson
2019-09-25  7:05   ` Cédric Le Goater
2019-09-26  1:03     ` David Gibson
2019-09-26  7:02       ` Cédric Le Goater
2019-09-25 17:13   ` Greg Kurz
2019-09-25  6:45 ` [PATCH 10/20] spapr: Eliminate nr_irqs parameter to SpaprIrq::init David Gibson
2019-09-25  7:06   ` Cédric Le Goater
2019-09-25 17:16   ` Greg Kurz
2019-09-25  6:45 ` [PATCH 11/20] spapr: Fix indexing of XICS irqs David Gibson
2019-09-25  7:11   ` Cédric Le Goater
2019-09-25 20:17   ` Greg Kurz
2019-09-26  1:31     ` David Gibson
2019-09-26  7:21       ` Greg Kurz
2019-09-26 11:32         ` David Gibson
2019-09-26 14:44           ` Greg Kurz
2019-09-25  6:45 ` [PATCH 12/20] spapr: Simplify spapr_qirq() handling David Gibson
2019-09-25  7:16   ` Cédric Le Goater
2019-09-25 20:30   ` Greg Kurz
2019-09-26  7:10   ` Philippe Mathieu-Daudé
2019-09-25  6:45 ` [PATCH 13/20] spapr: Eliminate SpaprIrq:get_nodename method David Gibson
2019-09-25  7:19   ` Cédric Le Goater
2019-09-26  7:11   ` Philippe Mathieu-Daudé
2019-09-26  7:48   ` Greg Kurz
2019-09-26 11:36     ` David Gibson
2019-09-25  6:45 ` [PATCH 14/20] spapr: Remove unhelpful tracepoints from spapr_irq_free_xics() David Gibson
2019-09-25  7:20   ` Cédric Le Goater
2019-09-26  7:11   ` Philippe Mathieu-Daudé
2019-09-26  7:50   ` Greg Kurz
2019-09-25  6:45 ` [PATCH 15/20] spapr: Handle freeing of multiple irqs in frontend only David Gibson
2019-09-25  7:21   ` Cédric Le Goater
2019-09-26  7:52   ` Greg Kurz
2019-09-25  6:45 ` [PATCH 16/20] spapr, xics, xive: Better use of assert()s on irq claim/free paths David Gibson
2019-09-25  7:22   ` Cédric Le Goater
2019-09-26  8:08   ` Greg Kurz
2019-09-26 11:39     ` David Gibson
2019-09-25  6:45 ` [PATCH 17/20] spapr: Remove unused return value in claim path David Gibson
2019-09-25  7:23   ` Cédric Le Goater
2019-09-26  7:13   ` Philippe Mathieu-Daudé
2019-09-26  8:36   ` Greg Kurz
2019-09-27  1:47     ` David Gibson
2019-09-25  6:45 ` [PATCH 18/20] xive: Improve irq claim/free path David Gibson
2019-09-25  7:25   ` Cédric Le Goater
2019-09-26  1:05     ` David Gibson
2019-09-25  6:45 ` [PATCH 19/20] spapr: Use less cryptic representation of which irq backends are supported David Gibson
2019-09-25  7:28   ` Cédric Le Goater
2019-09-26  9:16   ` Greg Kurz
2019-09-25  6:45 ` [PATCH 20/20] spapr: Eliminate SpaprIrq::init hook David Gibson
2019-09-25  7:31   ` Cédric Le Goater
2019-09-26  1:13     ` David Gibson
2019-09-26  7:05       ` Cédric Le Goater
2019-09-26 11:29         ` David Gibson
2019-09-26 15:35         ` Greg Kurz
2019-09-27  5:51           ` David Gibson
2019-09-27  6:23             ` Greg Kurz
2019-09-26 15:39   ` Greg Kurz
2019-09-27 14:12     ` Greg Kurz
2019-09-29  9:34       ` David Gibson

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