All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 00/22] ppc/xics: simplify ICS and ICP creation
@ 2017-02-16 13:47 Cédric Le Goater
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 01/22] ppc/xics: remove set_nr_irqs() handler from XICSStateClass Cédric Le Goater
                   ` (22 more replies)
  0 siblings, 23 replies; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-16 13:47 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

Hello,

The goal behind this series is to simplify the XICS interface by
moving back in the machine the way the ICS and ICP objects interact
together. It's up to the machine to implement this "fabric" logic by
providing a set of handlers of a QOM interface. These handlers are
used to grab an ICS or an ICP object and also do irq resends. This
idea was suggested by David Gibson.

The patchset is organised as follow. It starts with a preliminary
cleanup to get rid of the set_nr_irqs() and set_nr_servers()
handlers. It also moves the creation of the ICS and ICP objects from
the XICS object to the sPAPR machine. This simplifies the code
significantly and prepares ground for future changes.

As the sPAPR machine only makes use of a single ICS, we can store it
at the machine level. This lets us remove dependencies on the list of
ICS of the XICS object and simplify even more the code for the
following changes.

The QOM interface to interact with the ICS and ICP objects is then
introduced. These are moved under the machine and cleanups are done
accordingly.

Finally, the XICSState classes are removed as they have been
deprecated by the QOM interface.


After the initial cleanups, which are rather big, I have tried to keep
the each patch small enough to ease the review and to spot any
problem. Each should be bisectable. The tree is available here :

	   https://github.com/legoater/qemu/tree/ppc-2.9


Thanks,

C.


Changes since v1:

 - address the full picture.

Cédric Le Goater (22):
  ppc/xics: remove set_nr_irqs() handler from XICSStateClass
  ppc/xics: remove set_nr_servers() handler from XICSStateClass
  ppc/xics: store the ICS object under the sPAPR machine
  ppc/xics: add an InterruptStatsProvider interface to ICS and ICP
    objects
  ppc/xics: introduce a QOM interface to handle ICSs
  ppc/xics: use the QOM interface under the sPAPR machine
  ppc/xics: use the QOM interface to get irqs
  ppc/xics: use the QOM interface to resend irqs
  ppc/xics: remove xics_find_source()
  ppc/xics: register the reset handler of ICS objects
  ppc/xics: remove the XICS list of ICS
  ppc/xics: extend the QOM interface to handle ICPs
  ppc/xics: simplify the cpu_setup() handler
  ppc/xics: use the QOM interface to grab an ICP
  ppc/xics: simplify spapr_dt_xics() interface
  ppc/xics: register the reset handler of ICP objects
  ppc/xics: move the ICP array under the sPAPR machine
  ppc/xics: move kernel_xics_fd out of KVMXICSState
  ppc/xics: move the cpu_setup() handler under the ICPState class
  ppc/xics: remove the 'xics' backlinks
  ppc/xics: export the XICS init routines
  ppc/xics: remove the XICSState classes

 hw/intc/xics.c              | 295 +++++++++++++-------------------------------
 hw/intc/xics_kvm.c          | 154 ++++++-----------------
 hw/intc/xics_spapr.c        | 128 ++++---------------
 hw/ppc/spapr.c              | 116 +++++++++++++----
 hw/ppc/spapr_cpu_core.c     |   4 +-
 hw/ppc/spapr_events.c       |  10 +-
 hw/ppc/spapr_pci.c          |  10 +-
 hw/ppc/spapr_vio.c          |   2 +-
 include/hw/pci-host/spapr.h |   2 +-
 include/hw/ppc/spapr.h      |   5 +-
 include/hw/ppc/spapr_vio.h  |   2 +-
 include/hw/ppc/xics.h       |  93 ++++++--------
 12 files changed, 294 insertions(+), 527 deletions(-)

-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 01/22] ppc/xics: remove set_nr_irqs() handler from XICSStateClass
  2017-02-16 13:47 [Qemu-devel] [PATCH v2 00/22] ppc/xics: simplify ICS and ICP creation Cédric Le Goater
@ 2017-02-16 13:47 ` Cédric Le Goater
  2017-02-22  3:21   ` David Gibson
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 02/22] ppc/xics: remove set_nr_servers() " Cédric Le Goater
                   ` (21 subsequent siblings)
  22 siblings, 1 reply; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-16 13:47 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

Today, the ICS (Interrupt Controller Source) object is created and
realized by the init and realize routines of the XICS object, but some
of the parameters are only known at the machine level.

These parameters are passed from the sPAPR machine to the ICS object
in a rather convoluted way using property handlers and a class handler
of the XICS object. The number of irqs required to allocate the IRQ
state objects in the ICS realize routine is one of them.

Let's simplify the process by creating the ICS object along with the
XICS object at the machine level and link the ICS into the XICS list
of ICSs at this level also. In the sPAPR machine, there is only a
single ICS but that will change with the PowerNV machine.

Also, QOMify the creation of the objects and get rid of the
superfluous code.

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

 Changes since v1:

 - added a XICS link to the ICS object

 hw/intc/xics.c        | 51 ++++++++++++++++---------------------------------
 hw/intc/xics_kvm.c    | 44 ++++++++++--------------------------------
 hw/intc/xics_spapr.c  | 34 ---------------------------------
 hw/ppc/spapr.c        | 53 +++++++++++++++++++++++++++++++++++----------------
 include/hw/ppc/xics.h |  2 --
 5 files changed, 63 insertions(+), 121 deletions(-)

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 372b8311fb8b..e70d3b8b1095 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -151,38 +151,6 @@ static void xics_common_reset(DeviceState *d)
     }
 }
 
-static void xics_prop_get_nr_irqs(Object *obj, Visitor *v, const char *name,
-                                  void *opaque, Error **errp)
-{
-    XICSState *xics = XICS_COMMON(obj);
-    int64_t value = xics->nr_irqs;
-
-    visit_type_int(v, name, &value, errp);
-}
-
-static void xics_prop_set_nr_irqs(Object *obj, Visitor *v, const char *name,
-                                  void *opaque, Error **errp)
-{
-    XICSState *xics = XICS_COMMON(obj);
-    XICSStateClass *info = XICS_COMMON_GET_CLASS(xics);
-    Error *error = NULL;
-    int64_t value;
-
-    visit_type_int(v, name, &value, &error);
-    if (error) {
-        error_propagate(errp, error);
-        return;
-    }
-    if (xics->nr_irqs) {
-        error_setg(errp, "Number of interrupts is already set to %u",
-                   xics->nr_irqs);
-        return;
-    }
-
-    assert(info->set_nr_irqs);
-    info->set_nr_irqs(xics, value, errp);
-}
-
 void xics_set_nr_servers(XICSState *xics, uint32_t nr_servers,
                          const char *typename, Error **errp)
 {
@@ -241,9 +209,6 @@ static void xics_common_initfn(Object *obj)
     XICSState *xics = XICS_COMMON(obj);
 
     QLIST_INIT(&xics->ics);
-    object_property_add(obj, "nr_irqs", "int",
-                        xics_prop_get_nr_irqs, xics_prop_set_nr_irqs,
-                        NULL, NULL, NULL);
     object_property_add(obj, "nr_servers", "int",
                         xics_prop_get_nr_servers, xics_prop_set_nr_servers,
                         NULL, NULL, NULL);
@@ -737,6 +702,16 @@ static void ics_simple_initfn(Object *obj)
 static void ics_simple_realize(DeviceState *dev, Error **errp)
 {
     ICSState *ics = ICS_SIMPLE(dev);
+    Object *obj;
+    Error *err = NULL;
+
+    obj = object_property_get_link(OBJECT(dev), "xics", &err);
+    if (!obj) {
+        error_setg(errp, "%s: required link 'xics' not found: %s",
+                   __func__, error_get_pretty(err));
+        return;
+    }
+    ics->xics = XICS_COMMON(obj);
 
     if (!ics->nr_irqs) {
         error_setg(errp, "Number of interrupts needs to be greater 0");
@@ -746,12 +721,18 @@ static void ics_simple_realize(DeviceState *dev, Error **errp)
     ics->qirqs = qemu_allocate_irqs(ics_simple_set_irq, ics, ics->nr_irqs);
 }
 
+static Property ics_simple_properties[] = {
+    DEFINE_PROP_UINT32("nr-irqs", ICSState, nr_irqs, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void ics_simple_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
     ICSStateClass *isc = ICS_BASE_CLASS(klass);
 
     dc->realize = ics_simple_realize;
+    dc->props = ics_simple_properties;
     dc->vmsd = &vmstate_ics_simple;
     dc->reset = ics_simple_reset;
     isc->post_load = ics_simple_post_load;
diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index 17694eaa8709..4a6c0522feb6 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -294,6 +294,16 @@ static void ics_kvm_reset(DeviceState *dev)
 static void ics_kvm_realize(DeviceState *dev, Error **errp)
 {
     ICSState *ics = ICS_SIMPLE(dev);
+    Object *obj;
+    Error *err = NULL;
+
+    obj = object_property_get_link(OBJECT(dev), "xics", &err);
+    if (!obj) {
+        error_setg(errp, "%s: required link 'xics' not found: %s",
+                   __func__, error_get_pretty(err));
+        return;
+    }
+    ics->xics = XICS_COMMON(obj);
 
     if (!ics->nr_irqs) {
         error_setg(errp, "Number of interrupts needs to be greater 0");
@@ -358,18 +368,6 @@ static void xics_kvm_cpu_setup(XICSState *xics, PowerPCCPU *cpu)
     ss->cap_irq_xics_enabled = true;
 }
 
-static void xics_kvm_set_nr_irqs(XICSState *xics, uint32_t nr_irqs,
-                                 Error **errp)
-{
-    ICSState *ics = QLIST_FIRST(&xics->ics);
-
-    /* This needs to be deprecated ... */
-    xics->nr_irqs = nr_irqs;
-    if (ics) {
-        ics->nr_irqs = nr_irqs;
-    }
-}
-
 static void xics_kvm_set_nr_servers(XICSState *xics, uint32_t nr_servers,
                                     Error **errp)
 {
@@ -389,7 +387,6 @@ static void xics_kvm_realize(DeviceState *dev, Error **errp)
 {
     KVMXICSState *xicskvm = XICS_SPAPR_KVM(dev);
     XICSState *xics = XICS_COMMON(dev);
-    ICSState *ics;
     int i, rc;
     Error *error = NULL;
     struct kvm_create_device xics_create_device = {
@@ -441,14 +438,6 @@ static void xics_kvm_realize(DeviceState *dev, Error **errp)
 
     xicskvm->kernel_xics_fd = xics_create_device.fd;
 
-    QLIST_FOREACH(ics, &xics->ics, list) {
-        object_property_set_bool(OBJECT(ics), true, "realized", &error);
-        if (error) {
-            error_propagate(errp, error);
-            goto fail;
-        }
-    }
-
     assert(xics->nr_servers);
     for (i = 0; i < xics->nr_servers; i++) {
         object_property_set_bool(OBJECT(&xics->ss[i]), true, "realized",
@@ -472,17 +461,6 @@ fail:
     kvmppc_define_rtas_kernel_token(0, "ibm,int-off");
 }
 
-static void xics_kvm_initfn(Object *obj)
-{
-    XICSState *xics = XICS_COMMON(obj);
-    ICSState *ics;
-
-    ics = ICS_SIMPLE(object_new(TYPE_ICS_KVM));
-    object_property_add_child(obj, "ics", OBJECT(ics), NULL);
-    ics->xics = xics;
-    QLIST_INSERT_HEAD(&xics->ics, ics, list);
-}
-
 static void xics_kvm_class_init(ObjectClass *oc, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(oc);
@@ -490,7 +468,6 @@ static void xics_kvm_class_init(ObjectClass *oc, void *data)
 
     dc->realize = xics_kvm_realize;
     xsc->cpu_setup = xics_kvm_cpu_setup;
-    xsc->set_nr_irqs = xics_kvm_set_nr_irqs;
     xsc->set_nr_servers = xics_kvm_set_nr_servers;
 }
 
@@ -499,7 +476,6 @@ static const TypeInfo xics_spapr_kvm_info = {
     .parent        = TYPE_XICS_COMMON,
     .instance_size = sizeof(KVMXICSState),
     .class_init    = xics_kvm_class_init,
-    .instance_init = xics_kvm_initfn,
 };
 
 static void xics_kvm_register_types(void)
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 2e3f1c5e95b2..03e42a866603 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -239,18 +239,6 @@ static void rtas_int_on(PowerPCCPU *cpu, sPAPRMachineState *spapr,
     rtas_st(rets, 0, RTAS_OUT_SUCCESS);
 }
 
-static void xics_spapr_set_nr_irqs(XICSState *xics, uint32_t nr_irqs,
-                                   Error **errp)
-{
-    ICSState *ics = QLIST_FIRST(&xics->ics);
-
-    /* This needs to be deprecated ... */
-    xics->nr_irqs = nr_irqs;
-    if (ics) {
-        ics->nr_irqs = nr_irqs;
-    }
-}
-
 static void xics_spapr_set_nr_servers(XICSState *xics, uint32_t nr_servers,
                                       Error **errp)
 {
@@ -260,7 +248,6 @@ static void xics_spapr_set_nr_servers(XICSState *xics, uint32_t nr_servers,
 static void xics_spapr_realize(DeviceState *dev, Error **errp)
 {
     XICSState *xics = XICS_SPAPR(dev);
-    ICSState *ics;
     Error *error = NULL;
     int i;
 
@@ -282,14 +269,6 @@ static void xics_spapr_realize(DeviceState *dev, Error **errp)
     spapr_register_hypercall(H_EOI, h_eoi);
     spapr_register_hypercall(H_IPOLL, h_ipoll);
 
-    QLIST_FOREACH(ics, &xics->ics, list) {
-        object_property_set_bool(OBJECT(ics), true, "realized", &error);
-        if (error) {
-            error_propagate(errp, error);
-            return;
-        }
-    }
-
     for (i = 0; i < xics->nr_servers; i++) {
         object_property_set_bool(OBJECT(&xics->ss[i]), true, "realized",
                                  &error);
@@ -300,24 +279,12 @@ static void xics_spapr_realize(DeviceState *dev, Error **errp)
     }
 }
 
-static void xics_spapr_initfn(Object *obj)
-{
-    XICSState *xics = XICS_SPAPR(obj);
-    ICSState *ics;
-
-    ics = ICS_SIMPLE(object_new(TYPE_ICS_SIMPLE));
-    object_property_add_child(obj, "ics", OBJECT(ics), NULL);
-    ics->xics = xics;
-    QLIST_INSERT_HEAD(&xics->ics, ics, list);
-}
-
 static void xics_spapr_class_init(ObjectClass *oc, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(oc);
     XICSStateClass *xsc = XICS_SPAPR_CLASS(oc);
 
     dc->realize = xics_spapr_realize;
-    xsc->set_nr_irqs = xics_spapr_set_nr_irqs;
     xsc->set_nr_servers = xics_spapr_set_nr_servers;
 }
 
@@ -327,7 +294,6 @@ static const TypeInfo xics_spapr_info = {
     .instance_size = sizeof(XICSState),
     .class_size = sizeof(XICSStateClass),
     .class_init    = xics_spapr_class_init,
-    .instance_init = xics_spapr_initfn,
 };
 
 #define ICS_IRQ_FREE(ics, srcno)   \
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 9b6ad0f2fd77..94b1e8e3227a 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -95,22 +95,42 @@
 
 #define HTAB_SIZE(spapr)        (1ULL << ((spapr)->htab_shift))
 
-static XICSState *try_create_xics(const char *type, int nr_servers,
-                                  int nr_irqs, Error **errp)
-{
-    Error *err = NULL;
-    DeviceState *dev;
+static XICSState *try_create_xics(const char *type, const char *type_ics,
+                                  int nr_servers, int nr_irqs, Error **errp)
+{
+    Error *err = NULL, *local_err = NULL;
+    XICSState *xics;
+    ICSState *ics = NULL;
+
+    xics = XICS_COMMON(object_new(type));
+    qdev_set_parent_bus(DEVICE(xics), sysbus_get_default());
+    object_property_set_int(OBJECT(xics), nr_servers, "nr_servers", &err);
+    object_property_set_bool(OBJECT(xics), true, "realized", &local_err);
+    error_propagate(&err, local_err);
+    if (err) {
+        goto error;
+    }
 
-    dev = DEVICE(object_new(type));
-    qdev_prop_set_uint32(dev, "nr_servers", nr_servers);
-    qdev_prop_set_uint32(dev, "nr_irqs", nr_irqs);
-    object_property_set_bool(OBJECT(dev), true, "realized", &err);
+    ics = ICS_SIMPLE(object_new(type_ics));
+    object_property_add_child(OBJECT(xics), "ics", OBJECT(ics), NULL);
+    object_property_set_int(OBJECT(ics), nr_irqs, "nr-irqs", &err);
+    object_property_add_const_link(OBJECT(ics), "xics", OBJECT(xics), NULL);
+    object_property_set_bool(OBJECT(ics), true, "realized", &local_err);
+    error_propagate(&err, local_err);
     if (err) {
-        error_propagate(errp, err);
-        object_unparent(OBJECT(dev));
-        return NULL;
+        goto error;
     }
-    return XICS_COMMON(dev);
+    QLIST_INSERT_HEAD(&xics->ics, ics, list);
+
+    return xics;
+
+error:
+    error_propagate(errp, err);
+    if (ics) {
+        object_unparent(OBJECT(ics));
+    }
+    object_unparent(OBJECT(xics));
+    return NULL;
 }
 
 static XICSState *xics_system_init(MachineState *machine,
@@ -122,8 +142,8 @@ static XICSState *xics_system_init(MachineState *machine,
         Error *err = NULL;
 
         if (machine_kernel_irqchip_allowed(machine)) {
-            xics = try_create_xics(TYPE_XICS_SPAPR_KVM, nr_servers, nr_irqs,
-                                   &err);
+            xics = try_create_xics(TYPE_XICS_SPAPR_KVM, TYPE_ICS_KVM,
+                                   nr_servers, nr_irqs, &err);
         }
         if (machine_kernel_irqchip_required(machine) && !xics) {
             error_reportf_err(err,
@@ -134,7 +154,8 @@ static XICSState *xics_system_init(MachineState *machine,
     }
 
     if (!xics) {
-        xics = try_create_xics(TYPE_XICS_SPAPR, nr_servers, nr_irqs, errp);
+        xics = try_create_xics(TYPE_XICS_SPAPR, TYPE_ICS_SIMPLE, nr_servers,
+                               nr_irqs, errp);
     }
 
     return xics;
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index 3f0c31610aa4..8fe3c4d2ceab 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -74,7 +74,6 @@ struct XICSStateClass {
     DeviceClass parent_class;
 
     void (*cpu_setup)(XICSState *icp, PowerPCCPU *cpu);
-    void (*set_nr_irqs)(XICSState *icp, uint32_t nr_irqs, Error **errp);
     void (*set_nr_servers)(XICSState *icp, uint32_t nr_servers, Error **errp);
 };
 
@@ -83,7 +82,6 @@ struct XICSState {
     SysBusDevice parent_obj;
     /*< public >*/
     uint32_t nr_servers;
-    uint32_t nr_irqs;
     ICPState *ss;
     QLIST_HEAD(, ICSState) ics;
 };
-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 02/22] ppc/xics: remove set_nr_servers() handler from XICSStateClass
  2017-02-16 13:47 [Qemu-devel] [PATCH v2 00/22] ppc/xics: simplify ICS and ICP creation Cédric Le Goater
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 01/22] ppc/xics: remove set_nr_irqs() handler from XICSStateClass Cédric Le Goater
@ 2017-02-16 13:47 ` Cédric Le Goater
  2017-02-22  6:23   ` David Gibson
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 03/22] ppc/xics: store the ICS object under the sPAPR machine Cédric Le Goater
                   ` (20 subsequent siblings)
  22 siblings, 1 reply; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-16 13:47 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

Today, the ICP (Interrupt Controller Presenter) objects are created by
the 'nr_servers' property handler of the XICS object and a class
handler. They are realized in the XICS object realize routine.

Let's simplify the process by creating the ICP objects along with the
XICS object at the machine level.

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

 Changes since v1:

 - added a XICS link to the ICS object
 - removed xics_set_nr_servers() routine
 - removed set_nr_servers() class handler

 hw/intc/xics.c        | 74 +++++++++++++--------------------------------------
 hw/intc/xics_kvm.c    | 21 +--------------
 hw/intc/xics_spapr.c  | 26 ------------------
 hw/ppc/spapr.c        | 30 ++++++++++++++++-----
 include/hw/ppc/xics.h |  3 ---
 5 files changed, 42 insertions(+), 112 deletions(-)

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index e70d3b8b1095..9f22814815c9 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -151,67 +151,11 @@ static void xics_common_reset(DeviceState *d)
     }
 }
 
-void xics_set_nr_servers(XICSState *xics, uint32_t nr_servers,
-                         const char *typename, Error **errp)
-{
-    int i;
-
-    xics->nr_servers = nr_servers;
-
-    xics->ss = g_malloc0(xics->nr_servers * sizeof(ICPState));
-    for (i = 0; i < xics->nr_servers; i++) {
-        char name[32];
-        ICPState *icp = &xics->ss[i];
-
-        object_initialize(icp, sizeof(*icp), typename);
-        snprintf(name, sizeof(name), "icp[%d]", i);
-        object_property_add_child(OBJECT(xics), name, OBJECT(icp), errp);
-        icp->xics = xics;
-    }
-}
-
-static void xics_prop_get_nr_servers(Object *obj, Visitor *v,
-                                     const char *name, void *opaque,
-                                     Error **errp)
-{
-    XICSState *xics = XICS_COMMON(obj);
-    int64_t value = xics->nr_servers;
-
-    visit_type_int(v, name, &value, errp);
-}
-
-static void xics_prop_set_nr_servers(Object *obj, Visitor *v,
-                                     const char *name, void *opaque,
-                                     Error **errp)
-{
-    XICSState *xics = XICS_COMMON(obj);
-    XICSStateClass *xsc = XICS_COMMON_GET_CLASS(xics);
-    Error *error = NULL;
-    int64_t value;
-
-    visit_type_int(v, name, &value, &error);
-    if (error) {
-        error_propagate(errp, error);
-        return;
-    }
-    if (xics->nr_servers) {
-        error_setg(errp, "Number of servers is already set to %u",
-                   xics->nr_servers);
-        return;
-    }
-
-    assert(xsc->set_nr_servers);
-    xsc->set_nr_servers(xics, value, errp);
-}
-
 static void xics_common_initfn(Object *obj)
 {
     XICSState *xics = XICS_COMMON(obj);
 
     QLIST_INIT(&xics->ics);
-    object_property_add(obj, "nr_servers", "int",
-                        xics_prop_get_nr_servers, xics_prop_set_nr_servers,
-                        NULL, NULL, NULL);
 }
 
 static void xics_common_class_init(ObjectClass *oc, void *data)
@@ -450,12 +394,30 @@ static void icp_reset(DeviceState *dev)
     qemu_set_irq(icp->output, 0);
 }
 
+static void icp_realize(DeviceState *dev, Error **errp)
+{
+    ICPState *icp = ICP(dev);
+    Object *obj;
+    Error *err = NULL;
+
+    obj = object_property_get_link(OBJECT(dev), "xics", &err);
+    if (!obj) {
+        error_setg(errp, "%s: required link 'xics' not found: %s",
+                   __func__, error_get_pretty(err));
+        return;
+    }
+
+    icp->xics = XICS_COMMON(obj);
+}
+
+
 static void icp_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
 
     dc->reset = icp_reset;
     dc->vmsd = &vmstate_icp_server;
+    dc->realize = icp_realize;
 }
 
 static const TypeInfo icp_info = {
diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index 4a6c0522feb6..6cabc11f6be1 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -368,12 +368,6 @@ static void xics_kvm_cpu_setup(XICSState *xics, PowerPCCPU *cpu)
     ss->cap_irq_xics_enabled = true;
 }
 
-static void xics_kvm_set_nr_servers(XICSState *xics, uint32_t nr_servers,
-                                    Error **errp)
-{
-    xics_set_nr_servers(xics, nr_servers, TYPE_KVM_ICP, errp);
-}
-
 static void rtas_dummy(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                        uint32_t token,
                        uint32_t nargs, target_ulong args,
@@ -386,9 +380,7 @@ static void rtas_dummy(PowerPCCPU *cpu, sPAPRMachineState *spapr,
 static void xics_kvm_realize(DeviceState *dev, Error **errp)
 {
     KVMXICSState *xicskvm = XICS_SPAPR_KVM(dev);
-    XICSState *xics = XICS_COMMON(dev);
-    int i, rc;
-    Error *error = NULL;
+    int rc;
     struct kvm_create_device xics_create_device = {
         .type = KVM_DEV_TYPE_XICS,
         .flags = 0,
@@ -438,16 +430,6 @@ static void xics_kvm_realize(DeviceState *dev, Error **errp)
 
     xicskvm->kernel_xics_fd = xics_create_device.fd;
 
-    assert(xics->nr_servers);
-    for (i = 0; i < xics->nr_servers; i++) {
-        object_property_set_bool(OBJECT(&xics->ss[i]), true, "realized",
-                                 &error);
-        if (error) {
-            error_propagate(errp, error);
-            goto fail;
-        }
-    }
-
     kvm_kernel_irqchip = true;
     kvm_msi_via_irqfd_allowed = true;
     kvm_gsi_direct_mapping = true;
@@ -468,7 +450,6 @@ static void xics_kvm_class_init(ObjectClass *oc, void *data)
 
     dc->realize = xics_kvm_realize;
     xsc->cpu_setup = xics_kvm_cpu_setup;
-    xsc->set_nr_servers = xics_kvm_set_nr_servers;
 }
 
 static const TypeInfo xics_spapr_kvm_info = {
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 03e42a866603..859b5675e175 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -239,23 +239,8 @@ static void rtas_int_on(PowerPCCPU *cpu, sPAPRMachineState *spapr,
     rtas_st(rets, 0, RTAS_OUT_SUCCESS);
 }
 
-static void xics_spapr_set_nr_servers(XICSState *xics, uint32_t nr_servers,
-                                      Error **errp)
-{
-    xics_set_nr_servers(xics, nr_servers, TYPE_ICP, errp);
-}
-
 static void xics_spapr_realize(DeviceState *dev, Error **errp)
 {
-    XICSState *xics = XICS_SPAPR(dev);
-    Error *error = NULL;
-    int i;
-
-    if (!xics->nr_servers) {
-        error_setg(errp, "Number of servers needs to be greater 0");
-        return;
-    }
-
     /* Registration of global state belongs into realize */
     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);
@@ -268,24 +253,13 @@ static void xics_spapr_realize(DeviceState *dev, Error **errp)
     spapr_register_hypercall(H_XIRR_X, h_xirr_x);
     spapr_register_hypercall(H_EOI, h_eoi);
     spapr_register_hypercall(H_IPOLL, h_ipoll);
-
-    for (i = 0; i < xics->nr_servers; i++) {
-        object_property_set_bool(OBJECT(&xics->ss[i]), true, "realized",
-                                 &error);
-        if (error) {
-            error_propagate(errp, error);
-            return;
-        }
-    }
 }
 
 static void xics_spapr_class_init(ObjectClass *oc, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(oc);
-    XICSStateClass *xsc = XICS_SPAPR_CLASS(oc);
 
     dc->realize = xics_spapr_realize;
-    xsc->set_nr_servers = xics_spapr_set_nr_servers;
 }
 
 static const TypeInfo xics_spapr_info = {
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 94b1e8e3227a..5d7c35de8cd9 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -96,17 +96,17 @@
 #define HTAB_SIZE(spapr)        (1ULL << ((spapr)->htab_shift))
 
 static XICSState *try_create_xics(const char *type, const char *type_ics,
-                                  int nr_servers, int nr_irqs, Error **errp)
+                                  const char *type_icp, int nr_servers,
+                                  int nr_irqs, Error **errp)
 {
     Error *err = NULL, *local_err = NULL;
     XICSState *xics;
     ICSState *ics = NULL;
+    int i;
 
     xics = XICS_COMMON(object_new(type));
     qdev_set_parent_bus(DEVICE(xics), sysbus_get_default());
-    object_property_set_int(OBJECT(xics), nr_servers, "nr_servers", &err);
-    object_property_set_bool(OBJECT(xics), true, "realized", &local_err);
-    error_propagate(&err, local_err);
+    object_property_set_bool(OBJECT(xics), true, "realized", &err);
     if (err) {
         goto error;
     }
@@ -122,6 +122,22 @@ static XICSState *try_create_xics(const char *type, const char *type_ics,
     }
     QLIST_INSERT_HEAD(&xics->ics, ics, list);
 
+    xics->ss = g_malloc0(nr_servers * sizeof(ICPState));
+    xics->nr_servers = nr_servers;
+
+    for (i = 0; i < nr_servers; i++) {
+        ICPState *icp = &xics->ss[i];
+
+        object_initialize(icp, sizeof(*icp), type_icp);
+        object_property_add_child(OBJECT(xics), "icp[*]", OBJECT(icp), NULL);
+        object_property_add_const_link(OBJECT(icp), "xics", OBJECT(xics), NULL);
+        object_property_set_bool(OBJECT(icp), true, "realized", &err);
+        if (err) {
+            goto error;
+        }
+        object_unref(OBJECT(icp));
+    }
+
     return xics;
 
 error:
@@ -143,7 +159,7 @@ static XICSState *xics_system_init(MachineState *machine,
 
         if (machine_kernel_irqchip_allowed(machine)) {
             xics = try_create_xics(TYPE_XICS_SPAPR_KVM, TYPE_ICS_KVM,
-                                   nr_servers, nr_irqs, &err);
+                                   TYPE_KVM_ICP, nr_servers, nr_irqs, &err);
         }
         if (machine_kernel_irqchip_required(machine) && !xics) {
             error_reportf_err(err,
@@ -154,8 +170,8 @@ static XICSState *xics_system_init(MachineState *machine,
     }
 
     if (!xics) {
-        xics = try_create_xics(TYPE_XICS_SPAPR, TYPE_ICS_SIMPLE, nr_servers,
-                               nr_irqs, errp);
+        xics = try_create_xics(TYPE_XICS_SPAPR, TYPE_ICS_SIMPLE, TYPE_ICP,
+                               nr_servers, nr_irqs, errp);
     }
 
     return xics;
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index 8fe3c4d2ceab..fc4abcd4e796 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -74,7 +74,6 @@ struct XICSStateClass {
     DeviceClass parent_class;
 
     void (*cpu_setup)(XICSState *icp, PowerPCCPU *cpu);
-    void (*set_nr_servers)(XICSState *icp, uint32_t nr_servers, Error **errp);
 };
 
 struct XICSState {
@@ -189,8 +188,6 @@ void spapr_dt_xics(XICSState *xics, void *fdt, uint32_t phandle);
 
 void xics_cpu_setup(XICSState *icp, PowerPCCPU *cpu);
 void xics_cpu_destroy(XICSState *icp, PowerPCCPU *cpu);
-void xics_set_nr_servers(XICSState *xics, uint32_t nr_servers,
-                         const char *typename, Error **errp);
 
 /* Internal XICS interfaces */
 int xics_get_cpu_index_by_dt_id(int cpu_dt_id);
-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 03/22] ppc/xics: store the ICS object under the sPAPR machine
  2017-02-16 13:47 [Qemu-devel] [PATCH v2 00/22] ppc/xics: simplify ICS and ICP creation Cédric Le Goater
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 01/22] ppc/xics: remove set_nr_irqs() handler from XICSStateClass Cédric Le Goater
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 02/22] ppc/xics: remove set_nr_servers() " Cédric Le Goater
@ 2017-02-16 13:47 ` Cédric Le Goater
  2017-02-22  6:59   ` David Gibson
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 04/22] ppc/xics: add an InterruptStatsProvider interface to ICS and ICP objects Cédric Le Goater
                   ` (19 subsequent siblings)
  22 siblings, 1 reply; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-16 13:47 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

A list of ICS objects was introduced under the XICS object for the
PowerNV machine, but, for the sPAPR machine, it brings extra complexity
as there is only a single ICS. To simplify the code, let's add the ICS
pointer under the sPAPR machine and try to reduce the use of this list
where possible.

Also, change the xics_spapr_*() routines to use an ICS object instead
of an XICSState and change their name to reflect that these are
specific to the sPAPR ICS object.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/intc/xics_spapr.c   | 22 +++++++++-------------
 hw/ppc/spapr.c         | 29 ++++++++++++++++-------------
 hw/ppc/spapr_events.c  |  4 ++--
 hw/ppc/spapr_pci.c     |  8 ++++----
 hw/ppc/spapr_vio.c     |  2 +-
 include/hw/ppc/spapr.h |  1 +
 include/hw/ppc/xics.h  |  6 +++---
 7 files changed, 36 insertions(+), 36 deletions(-)

diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 859b5675e175..1501e796e5e0 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -118,7 +118,7 @@ static void rtas_set_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                           uint32_t nargs, target_ulong args,
                           uint32_t nret, target_ulong rets)
 {
-    ICSState *ics = QLIST_FIRST(&spapr->xics->ics);
+    ICSState *ics = spapr->ics;
     uint32_t nr, srcno, server, priority;
 
     if ((nargs != 3) || (nret != 1)) {
@@ -151,7 +151,7 @@ static void rtas_get_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                           uint32_t nargs, target_ulong args,
                           uint32_t nret, target_ulong rets)
 {
-    ICSState *ics = QLIST_FIRST(&spapr->xics->ics);
+    ICSState *ics = spapr->ics;
     uint32_t nr, srcno;
 
     if ((nargs != 1) || (nret != 3)) {
@@ -181,7 +181,7 @@ static void rtas_int_off(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                          uint32_t nargs, target_ulong args,
                          uint32_t nret, target_ulong rets)
 {
-    ICSState *ics = QLIST_FIRST(&spapr->xics->ics);
+    ICSState *ics = spapr->ics;
     uint32_t nr, srcno;
 
     if ((nargs != 1) || (nret != 1)) {
@@ -212,7 +212,7 @@ static void rtas_int_on(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                         uint32_t nargs, target_ulong args,
                         uint32_t nret, target_ulong rets)
 {
-    ICSState *ics = QLIST_FIRST(&spapr->xics->ics);
+    ICSState *ics = spapr->ics;
     uint32_t nr, srcno;
 
     if ((nargs != 1) || (nret != 1)) {
@@ -294,9 +294,8 @@ static int ics_find_free_block(ICSState *ics, int num, int alignnum)
     return -1;
 }
 
-int xics_spapr_alloc(XICSState *xics, int irq_hint, bool lsi, Error **errp)
+int spapr_ics_alloc(ICSState *ics, int irq_hint, bool lsi, Error **errp)
 {
-    ICSState *ics = QLIST_FIRST(&xics->ics);
     int irq;
 
     if (!ics) {
@@ -327,10 +326,9 @@ int xics_spapr_alloc(XICSState *xics, int irq_hint, bool lsi, Error **errp)
  * Allocate block of consecutive IRQs, and return the number of the first IRQ in
  * the block. If align==true, aligns the first IRQ number to num.
  */
-int xics_spapr_alloc_block(XICSState *xics, int num, bool lsi, bool align,
-                           Error **errp)
+int spapr_ics_alloc_block(ICSState *ics, int num, bool lsi,
+                          bool align, Error **errp)
 {
-    ICSState *ics = QLIST_FIRST(&xics->ics);
     int i, first = -1;
 
     if (!ics) {
@@ -380,11 +378,9 @@ static void ics_free(ICSState *ics, int srcno, int num)
     }
 }
 
-void xics_spapr_free(XICSState *xics, int irq, int num)
+void spapr_ics_free(ICSState *ics, int irq, int num)
 {
-    ICSState *ics = xics_find_source(xics, irq);
-
-    if (ics) {
+    if (ics_valid_irq(ics, irq)) {
         trace_xics_ics_free(0, irq, num);
         ics_free(ics, irq - ics->offset, num);
     }
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 5d7c35de8cd9..045f2323a4e9 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -95,13 +95,13 @@
 
 #define HTAB_SIZE(spapr)        (1ULL << ((spapr)->htab_shift))
 
-static XICSState *try_create_xics(const char *type, const char *type_ics,
+static XICSState *try_create_xics(sPAPRMachineState *spapr,
+                                  const char *type, const char *type_ics,
                                   const char *type_icp, int nr_servers,
                                   int nr_irqs, Error **errp)
 {
     Error *err = NULL, *local_err = NULL;
     XICSState *xics;
-    ICSState *ics = NULL;
     int i;
 
     xics = XICS_COMMON(object_new(type));
@@ -111,16 +111,17 @@ static XICSState *try_create_xics(const char *type, const char *type_ics,
         goto error;
     }
 
-    ics = ICS_SIMPLE(object_new(type_ics));
-    object_property_add_child(OBJECT(xics), "ics", OBJECT(ics), NULL);
-    object_property_set_int(OBJECT(ics), nr_irqs, "nr-irqs", &err);
-    object_property_add_const_link(OBJECT(ics), "xics", OBJECT(xics), NULL);
-    object_property_set_bool(OBJECT(ics), true, "realized", &local_err);
+    spapr->ics = ICS_SIMPLE(object_new(type_ics));
+    object_property_add_child(OBJECT(spapr), "ics", OBJECT(spapr->ics), NULL);
+    object_property_set_int(OBJECT(spapr->ics), nr_irqs, "nr-irqs", &err);
+    object_property_add_const_link(OBJECT(spapr->ics), "xics", OBJECT(xics),
+                                   NULL);
+    object_property_set_bool(OBJECT(spapr->ics), true, "realized", &local_err);
     error_propagate(&err, local_err);
     if (err) {
         goto error;
     }
-    QLIST_INSERT_HEAD(&xics->ics, ics, list);
+    QLIST_INSERT_HEAD(&xics->ics, spapr->ics, list);
 
     xics->ss = g_malloc0(nr_servers * sizeof(ICPState));
     xics->nr_servers = nr_servers;
@@ -142,8 +143,8 @@ static XICSState *try_create_xics(const char *type, const char *type_ics,
 
 error:
     error_propagate(errp, err);
-    if (ics) {
-        object_unparent(OBJECT(ics));
+    if (spapr->ics) {
+        object_unparent(OBJECT(spapr->ics));
     }
     object_unparent(OBJECT(xics));
     return NULL;
@@ -158,7 +159,8 @@ static XICSState *xics_system_init(MachineState *machine,
         Error *err = NULL;
 
         if (machine_kernel_irqchip_allowed(machine)) {
-            xics = try_create_xics(TYPE_XICS_SPAPR_KVM, TYPE_ICS_KVM,
+            xics = try_create_xics(SPAPR_MACHINE(machine),
+                                   TYPE_XICS_SPAPR_KVM, TYPE_ICS_KVM,
                                    TYPE_KVM_ICP, nr_servers, nr_irqs, &err);
         }
         if (machine_kernel_irqchip_required(machine) && !xics) {
@@ -170,8 +172,9 @@ static XICSState *xics_system_init(MachineState *machine,
     }
 
     if (!xics) {
-        xics = try_create_xics(TYPE_XICS_SPAPR, TYPE_ICS_SIMPLE, TYPE_ICP,
-                               nr_servers, nr_irqs, errp);
+        xics = try_create_xics(SPAPR_MACHINE(machine),
+                               TYPE_XICS_SPAPR, TYPE_ICS_SIMPLE,
+                               TYPE_ICP, nr_servers, nr_irqs, errp);
     }
 
     return xics;
diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
index f85a9c32a7fc..38b4258a9be7 100644
--- a/hw/ppc/spapr_events.c
+++ b/hw/ppc/spapr_events.c
@@ -752,7 +752,7 @@ void spapr_events_init(sPAPRMachineState *spapr)
     spapr->event_sources = spapr_event_sources_new();
 
     spapr_event_sources_register(spapr->event_sources, EVENT_CLASS_EPOW,
-                                 xics_spapr_alloc(spapr->xics, 0, false,
+                                 spapr_ics_alloc(spapr->ics, 0, false,
                                                   &error_fatal));
 
     /* NOTE: if machine supports modern/dedicated hotplug event source,
@@ -765,7 +765,7 @@ void spapr_events_init(sPAPRMachineState *spapr)
      */
     if (spapr->use_hotplug_event_source) {
         spapr_event_sources_register(spapr->event_sources, EVENT_CLASS_HOT_PLUG,
-                                     xics_spapr_alloc(spapr->xics, 0, false,
+                                     spapr_ics_alloc(spapr->ics, 0, false,
                                                       &error_fatal));
     }
 
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index fd6fc1d95344..01d5c92425ed 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -325,7 +325,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
             return;
         }
 
-        xics_spapr_free(spapr->xics, msi->first_irq, msi->num);
+        spapr_ics_free(spapr->ics, msi->first_irq, msi->num);
         if (msi_present(pdev)) {
             spapr_msi_setmsg(pdev, 0, false, 0, 0);
         }
@@ -363,7 +363,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
     }
 
     /* Allocate MSIs */
-    irq = xics_spapr_alloc_block(spapr->xics, req_num, false,
+    irq = spapr_ics_alloc_block(spapr->ics, req_num, false,
                            ret_intr_type == RTAS_TYPE_MSI, &err);
     if (err) {
         error_reportf_err(err, "Can't allocate MSIs for device %x: ",
@@ -374,7 +374,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
 
     /* Release previous MSIs */
     if (msi) {
-        xics_spapr_free(spapr->xics, msi->first_irq, msi->num);
+        spapr_ics_free(spapr->ics, msi->first_irq, msi->num);
         g_hash_table_remove(phb->msi, &config_addr);
     }
 
@@ -1485,7 +1485,7 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
         uint32_t irq;
         Error *local_err = NULL;
 
-        irq = xics_spapr_alloc_block(spapr->xics, 1, true, false, &local_err);
+        irq = spapr_ics_alloc_block(spapr->ics, 1, true, false, &local_err);
         if (local_err) {
             error_propagate(errp, local_err);
             error_prepend(errp, "can't allocate LSIs: ");
diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c
index 8bfc5f971f8e..a0ee4fd26586 100644
--- a/hw/ppc/spapr_vio.c
+++ b/hw/ppc/spapr_vio.c
@@ -454,7 +454,7 @@ static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp)
         dev->qdev.id = id;
     }
 
-    dev->irq = xics_spapr_alloc(spapr->xics, dev->irq, false, &local_err);
+    dev->irq = spapr_ics_alloc(spapr->ics, dev->irq, false, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
         return;
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index f9b17d860a75..21e506b13cfa 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -59,6 +59,7 @@ struct sPAPRMachineState {
     QLIST_HEAD(, sPAPRPHBState) phbs;
     struct sPAPRNVRAM *nvram;
     XICSState *xics;
+    ICSState *ics;
     DeviceState *rtc;
 
     void *htab;
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index fc4abcd4e796..6d443ce09dba 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -180,10 +180,10 @@ struct ICSIRQState {
 #define XICS_IRQS_SPAPR               1024
 
 qemu_irq xics_get_qirq(XICSState *icp, int irq);
-int xics_spapr_alloc(XICSState *icp, int irq_hint, bool lsi, Error **errp);
-int xics_spapr_alloc_block(XICSState *icp, int num, bool lsi, bool align,
+int spapr_ics_alloc(ICSState *ics, int irq_hint, bool lsi, Error **errp);
+int spapr_ics_alloc_block(ICSState *ics, int num, bool lsi, bool align,
                            Error **errp);
-void xics_spapr_free(XICSState *icp, int irq, int num);
+void spapr_ics_free(ICSState *ics, int irq, int num);
 void spapr_dt_xics(XICSState *xics, void *fdt, uint32_t phandle);
 
 void xics_cpu_setup(XICSState *icp, PowerPCCPU *cpu);
-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 04/22] ppc/xics: add an InterruptStatsProvider interface to ICS and ICP objects
  2017-02-16 13:47 [Qemu-devel] [PATCH v2 00/22] ppc/xics: simplify ICS and ICP creation Cédric Le Goater
                   ` (2 preceding siblings ...)
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 03/22] ppc/xics: store the ICS object under the sPAPR machine Cédric Le Goater
@ 2017-02-16 13:47 ` Cédric Le Goater
  2017-02-23  2:15   ` David Gibson
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 05/22] ppc/xics: introduce a QOM interface to handle ICSs Cédric Le Goater
                   ` (18 subsequent siblings)
  22 siblings, 1 reply; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-16 13:47 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

This is, again, to reduce the use of the list of ICS objects. Let's
make each individual ICS and ICP object an InterruptStatsProvider and
remove this same interface from XICSState.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/intc/xics.c | 76 +++++++++++++++++++++++++++++++---------------------------
 1 file changed, 41 insertions(+), 35 deletions(-)

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 9f22814815c9..b1294417a0ae 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -92,44 +92,44 @@ void xics_cpu_setup(XICSState *xics, PowerPCCPU *cpu)
     }
 }
 
-static void xics_common_pic_print_info(InterruptStatsProvider *obj,
-                                       Monitor *mon)
+static void icp_pic_print_info(InterruptStatsProvider *obj,
+                           Monitor *mon)
 {
-    XICSState *xics = XICS_COMMON(obj);
-    ICSState *ics;
+    ICPState *icp = ICP(obj);
+    int cpu_index = icp->cs ? icp->cs->cpu_index : -1;
+
+    if (!icp->output) {
+        return;
+    }
+    monitor_printf(mon, "CPU %d XIRR=%08x (%p) PP=%02x MFRR=%02x\n",
+                   cpu_index, icp->xirr, icp->xirr_owner,
+                   icp->pending_priority, icp->mfrr);
+}
+
+static void ics_simple_pic_print_info(InterruptStatsProvider *obj,
+                                      Monitor *mon)
+{
+    ICSState *ics = ICS_SIMPLE(obj);
     uint32_t i;
 
-    for (i = 0; i < xics->nr_servers; i++) {
-        ICPState *icp = &xics->ss[i];
+    monitor_printf(mon, "ICS %4x..%4x %p\n",
+                   ics->offset, ics->offset + ics->nr_irqs - 1, ics);
 
-        if (!icp->output) {
-            continue;
-        }
-        monitor_printf(mon, "CPU %d XIRR=%08x (%p) PP=%02x MFRR=%02x\n",
-                       i, icp->xirr, icp->xirr_owner,
-                       icp->pending_priority, icp->mfrr);
+    if (!ics->irqs) {
+        return;
     }
 
-    QLIST_FOREACH(ics, &xics->ics, list) {
-        monitor_printf(mon, "ICS %4x..%4x %p\n",
-                       ics->offset, ics->offset + ics->nr_irqs - 1, ics);
+    for (i = 0; i < ics->nr_irqs; i++) {
+        ICSIRQState *irq = ics->irqs + i;
 
-        if (!ics->irqs) {
+        if (!(irq->flags & XICS_FLAGS_IRQ_MASK)) {
             continue;
         }
-
-        for (i = 0; i < ics->nr_irqs; i++) {
-            ICSIRQState *irq = ics->irqs + i;
-
-            if (!(irq->flags & XICS_FLAGS_IRQ_MASK)) {
-                continue;
-            }
-            monitor_printf(mon, "  %4x %s %02x %02x\n",
-                           ics->offset + i,
-                           (irq->flags & XICS_FLAGS_IRQ_LSI) ?
-                           "LSI" : "MSI",
-                           irq->priority, irq->status);
-        }
+        monitor_printf(mon, "  %4x %s %02x %02x\n",
+                       ics->offset + i,
+                       (irq->flags & XICS_FLAGS_IRQ_LSI) ?
+                       "LSI" : "MSI",
+                       irq->priority, irq->status);
     }
 }
 
@@ -161,10 +161,8 @@ static void xics_common_initfn(Object *obj)
 static void xics_common_class_init(ObjectClass *oc, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(oc);
-    InterruptStatsProviderClass *ic = INTERRUPT_STATS_PROVIDER_CLASS(oc);
 
     dc->reset = xics_common_reset;
-    ic->print_info = xics_common_pic_print_info;
 }
 
 static const TypeInfo xics_common_info = {
@@ -174,10 +172,6 @@ static const TypeInfo xics_common_info = {
     .class_size    = sizeof(XICSStateClass),
     .instance_init = xics_common_initfn,
     .class_init    = xics_common_class_init,
-    .interfaces = (InterfaceInfo[]) {
-        { TYPE_INTERRUPT_STATS_PROVIDER },
-        { }
-    },
 };
 
 /*
@@ -414,10 +408,12 @@ static void icp_realize(DeviceState *dev, Error **errp)
 static void icp_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    InterruptStatsProviderClass *ic = INTERRUPT_STATS_PROVIDER_CLASS(klass);
 
     dc->reset = icp_reset;
     dc->vmsd = &vmstate_icp_server;
     dc->realize = icp_realize;
+    ic->print_info = icp_pic_print_info;
 }
 
 static const TypeInfo icp_info = {
@@ -426,6 +422,10 @@ static const TypeInfo icp_info = {
     .instance_size = sizeof(ICPState),
     .class_init = icp_class_init,
     .class_size = sizeof(ICPStateClass),
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_INTERRUPT_STATS_PROVIDER },
+        { }
+    },
 };
 
 /*
@@ -692,6 +692,7 @@ static void ics_simple_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
     ICSStateClass *isc = ICS_BASE_CLASS(klass);
+    InterruptStatsProviderClass *ic = INTERRUPT_STATS_PROVIDER_CLASS(klass);
 
     dc->realize = ics_simple_realize;
     dc->props = ics_simple_properties;
@@ -701,6 +702,7 @@ static void ics_simple_class_init(ObjectClass *klass, void *data)
     isc->reject = ics_simple_reject;
     isc->resend = ics_simple_resend;
     isc->eoi = ics_simple_eoi;
+    ic->print_info = ics_simple_pic_print_info;
 }
 
 static const TypeInfo ics_simple_info = {
@@ -710,6 +712,10 @@ static const TypeInfo ics_simple_info = {
     .class_init = ics_simple_class_init,
     .class_size = sizeof(ICSStateClass),
     .instance_init = ics_simple_initfn,
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_INTERRUPT_STATS_PROVIDER },
+        { }
+    },
 };
 
 static const TypeInfo ics_base_info = {
-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 05/22] ppc/xics: introduce a QOM interface to handle ICSs
  2017-02-16 13:47 [Qemu-devel] [PATCH v2 00/22] ppc/xics: simplify ICS and ICP creation Cédric Le Goater
                   ` (3 preceding siblings ...)
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 04/22] ppc/xics: add an InterruptStatsProvider interface to ICS and ICP objects Cédric Le Goater
@ 2017-02-16 13:47 ` Cédric Le Goater
  2017-02-23  2:18   ` David Gibson
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 06/22] ppc/xics: use the QOM interface under the sPAPR machine Cédric Le Goater
                   ` (17 subsequent siblings)
  22 siblings, 1 reply; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-16 13:47 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

This QOM interface provides two simple handlers. One is to get an ICS
object from an irq number and a second to resend the irqs when needed.

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

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index b1294417a0ae..3e80d2d0f0d9 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -726,6 +726,12 @@ static const TypeInfo ics_base_info = {
     .class_size = sizeof(ICSStateClass),
 };
 
+static const TypeInfo xics_interface_info = {
+    .name = TYPE_XICS_INTERFACE,
+    .parent = TYPE_INTERFACE,
+    .class_size = sizeof(XICSInterfaceClass),
+};
+
 /*
  * Exported functions
  */
@@ -766,6 +772,7 @@ static void xics_register_types(void)
     type_register_static(&ics_simple_info);
     type_register_static(&ics_base_info);
     type_register_static(&icp_info);
+    type_register_static(&xics_interface_info);
 }
 
 type_init(xics_register_types)
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index 6d443ce09dba..fe2bb5c8ef54 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -177,6 +177,24 @@ struct ICSIRQState {
     uint8_t flags;
 };
 
+typedef struct XICSInterface {
+    Object parent;
+} XICSInterface;
+
+#define TYPE_XICS_INTERFACE "xics-interface"
+#define XICS_INTERFACE(obj)                                     \
+    OBJECT_CHECK(XICSInterface, (obj), TYPE_XICS_INTERFACE)
+#define XICS_INTERFACE_CLASS(klass)                                     \
+    OBJECT_CLASS_CHECK(XICSInterfaceClass, (klass), TYPE_XICS_INTERFACE)
+#define XICS_INTERFACE_GET_CLASS(obj)                                   \
+    OBJECT_GET_CLASS(XICSInterfaceClass, (obj), TYPE_XICS_INTERFACE)
+
+typedef struct XICSInterfaceClass {
+    InterfaceClass parent;
+    ICSState *(*ics_get)(XICSInterface *xi, int irq);
+    void (*ics_resend)(XICSInterface *xi);
+} XICSInterfaceClass;
+
 #define XICS_IRQS_SPAPR               1024
 
 qemu_irq xics_get_qirq(XICSState *icp, int irq);
-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 06/22] ppc/xics: use the QOM interface under the sPAPR machine
  2017-02-16 13:47 [Qemu-devel] [PATCH v2 00/22] ppc/xics: simplify ICS and ICP creation Cédric Le Goater
                   ` (4 preceding siblings ...)
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 05/22] ppc/xics: introduce a QOM interface to handle ICSs Cédric Le Goater
@ 2017-02-16 13:47 ` Cédric Le Goater
  2017-02-23  2:21   ` David Gibson
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 07/22] ppc/xics: use the QOM interface to get irqs Cédric Le Goater
                   ` (16 subsequent siblings)
  22 siblings, 1 reply; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-16 13:47 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

Add 'ics_get' and 'ics_resend' handlers to the sPAPR machine. These
are relatively simple for a single ICS.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/intc/xics.c        |  2 +-
 hw/ppc/spapr.c        | 18 ++++++++++++++++++
 include/hw/ppc/xics.h |  1 +
 3 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 3e80d2d0f0d9..39c442f70116 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -193,7 +193,7 @@ static void ics_reject(ICSState *ics, uint32_t nr)
     }
 }
 
-static void ics_resend(ICSState *ics)
+void ics_resend(ICSState *ics)
 {
     ICSStateClass *k = ICS_BASE_GET_CLASS(ics);
 
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 045f2323a4e9..85a973cce7ae 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -2901,6 +2901,20 @@ static void spapr_phb_placement(sPAPRMachineState *spapr, uint32_t index,
     *mmio64 = SPAPR_PCI_BASE + (index + 1) * SPAPR_PCI_MEM64_WIN_SIZE;
 }
 
+static ICSState *spapr_ics_get(XICSInterface *dev, int irq)
+{
+    sPAPRMachineState *spapr = SPAPR_MACHINE(dev);
+
+    return ics_valid_irq(spapr->ics, irq) ? spapr->ics : NULL;
+}
+
+static void spapr_ics_resend(XICSInterface *dev)
+{
+    sPAPRMachineState *spapr = SPAPR_MACHINE(dev);
+
+    ics_resend(spapr->ics);
+}
+
 static void spapr_machine_class_init(ObjectClass *oc, void *data)
 {
     MachineClass *mc = MACHINE_CLASS(oc);
@@ -2909,6 +2923,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
     NMIClass *nc = NMI_CLASS(oc);
     HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
     PPCVirtualHypervisorClass *vhc = PPC_VIRTUAL_HYPERVISOR_CLASS(oc);
+    XICSInterfaceClass *xic = XICS_INTERFACE_CLASS(oc);
 
     mc->desc = "pSeries Logical Partition (PAPR compliant)";
 
@@ -2942,6 +2957,8 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
     nc->nmi_monitor_handler = spapr_nmi;
     smc->phb_placement = spapr_phb_placement;
     vhc->hypercall = emulate_spapr_hypercall;
+    xic->ics_get = spapr_ics_get;
+    xic->ics_resend = spapr_ics_resend;
 }
 
 static const TypeInfo spapr_machine_info = {
@@ -2958,6 +2975,7 @@ static const TypeInfo spapr_machine_info = {
         { TYPE_NMI },
         { TYPE_HOTPLUG_HANDLER },
         { TYPE_PPC_VIRTUAL_HYPERVISOR },
+        { TYPE_XICS_INTERFACE },
         { }
     },
 };
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index fe2bb5c8ef54..640603b3d76d 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -222,5 +222,6 @@ void ics_simple_write_xive(ICSState *ics, int nr, int server,
 void ics_set_irq_type(ICSState *ics, int srcno, bool lsi);
 
 ICSState *xics_find_source(XICSState *icp, int irq);
+void ics_resend(ICSState *ics);
 
 #endif /* XICS_H */
-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 07/22] ppc/xics: use the QOM interface to get irqs
  2017-02-16 13:47 [Qemu-devel] [PATCH v2 00/22] ppc/xics: simplify ICS and ICP creation Cédric Le Goater
                   ` (5 preceding siblings ...)
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 06/22] ppc/xics: use the QOM interface under the sPAPR machine Cédric Le Goater
@ 2017-02-16 13:47 ` Cédric Le Goater
  2017-02-23  2:25   ` David Gibson
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 08/22] ppc/xics: use the QOM interface to resend irqs Cédric Le Goater
                   ` (15 subsequent siblings)
  22 siblings, 1 reply; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-16 13:47 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/intc/xics.c              | 5 +++--
 hw/ppc/spapr_events.c       | 6 +++---
 hw/ppc/spapr_pci.c          | 2 +-
 include/hw/pci-host/spapr.h | 2 +-
 include/hw/ppc/spapr_vio.h  | 2 +-
 include/hw/ppc/xics.h       | 3 ++-
 6 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 39c442f70116..0ffdf09c5304 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -747,9 +747,10 @@ ICSState *xics_find_source(XICSState *xics, int irq)
     return NULL;
 }
 
-qemu_irq xics_get_qirq(XICSState *xics, int irq)
+qemu_irq xics_get_qirq(XICSInterface *xi, int irq)
 {
-    ICSState *ics = xics_find_source(xics, irq);
+    XICSInterfaceClass *xic = XICS_INTERFACE_GET_CLASS(xi);
+    ICSState *ics = xic->ics_get(xi, irq);
 
     if (ics) {
         return ics->qirqs[irq - ics->offset];
diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
index 38b4258a9be7..aa627dc13008 100644
--- a/hw/ppc/spapr_events.c
+++ b/hw/ppc/spapr_events.c
@@ -481,7 +481,7 @@ static void spapr_powerdown_req(Notifier *n, void *opaque)
 
     rtas_event_log_queue(RTAS_LOG_TYPE_EPOW, new_epow, true);
 
-    qemu_irq_pulse(xics_get_qirq(spapr->xics,
+    qemu_irq_pulse(xics_get_qirq(XICS_INTERFACE(spapr),
                                  rtas_event_log_to_irq(spapr,
                                                        RTAS_LOG_TYPE_EPOW)));
 }
@@ -574,7 +574,7 @@ static void spapr_hotplug_req_event(uint8_t hp_id, uint8_t hp_action,
 
     rtas_event_log_queue(RTAS_LOG_TYPE_HOTPLUG, new_hp, true);
 
-    qemu_irq_pulse(xics_get_qirq(spapr->xics,
+    qemu_irq_pulse(xics_get_qirq(XICS_INTERFACE(spapr),
                                  rtas_event_log_to_irq(spapr,
                                                        RTAS_LOG_TYPE_HOTPLUG)));
 }
@@ -695,7 +695,7 @@ static void check_exception(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                 spapr_event_sources_get_source(spapr->event_sources, i);
 
             g_assert(source->enabled);
-            qemu_irq_pulse(xics_get_qirq(spapr->xics, source->irq));
+            qemu_irq_pulse(xics_get_qirq(XICS_INTERFACE(spapr), source->irq));
         }
     }
 
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 01d5c92425ed..e52d6e993c9e 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -736,7 +736,7 @@ static void spapr_msi_write(void *opaque, hwaddr addr,
 
     trace_spapr_pci_msi_write(addr, data, irq);
 
-    qemu_irq_pulse(xics_get_qirq(spapr->xics, irq));
+    qemu_irq_pulse(xics_get_qirq(XICS_INTERFACE(spapr), irq));
 }
 
 static const MemoryRegionOps spapr_msi_ops = {
diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h
index 092294ed5a65..bfd307be30ca 100644
--- a/include/hw/pci-host/spapr.h
+++ b/include/hw/pci-host/spapr.h
@@ -106,7 +106,7 @@ static inline qemu_irq spapr_phb_lsi_qirq(struct sPAPRPHBState *phb, int pin)
 {
     sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
 
-    return xics_get_qirq(spapr->xics, phb->lsi_table[pin].irq);
+    return xics_get_qirq(XICS_INTERFACE(spapr), phb->lsi_table[pin].irq);
 }
 
 PCIHostState *spapr_create_phb(sPAPRMachineState *spapr, int index);
diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h
index fc6f673ea086..1b04523b683d 100644
--- a/include/hw/ppc/spapr_vio.h
+++ b/include/hw/ppc/spapr_vio.h
@@ -87,7 +87,7 @@ static inline qemu_irq spapr_vio_qirq(VIOsPAPRDevice *dev)
 {
     sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
 
-    return xics_get_qirq(spapr->xics, dev->irq);
+    return xics_get_qirq(XICS_INTERFACE(spapr), dev->irq);
 }
 
 static inline bool spapr_vio_dma_valid(VIOsPAPRDevice *dev, uint64_t taddr,
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index 640603b3d76d..896fa5d87c1c 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -197,7 +197,8 @@ typedef struct XICSInterfaceClass {
 
 #define XICS_IRQS_SPAPR               1024
 
-qemu_irq xics_get_qirq(XICSState *icp, int irq);
+qemu_irq xics_get_qirq(XICSInterface *xi, int irq);
+
 int spapr_ics_alloc(ICSState *ics, int irq_hint, bool lsi, Error **errp);
 int spapr_ics_alloc_block(ICSState *ics, int num, bool lsi, bool align,
                            Error **errp);
-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 08/22] ppc/xics: use the QOM interface to resend irqs
  2017-02-16 13:47 [Qemu-devel] [PATCH v2 00/22] ppc/xics: simplify ICS and ICP creation Cédric Le Goater
                   ` (6 preceding siblings ...)
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 07/22] ppc/xics: use the QOM interface to get irqs Cédric Le Goater
@ 2017-02-16 13:47 ` Cédric Le Goater
  2017-02-23  2:29   ` David Gibson
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 09/22] ppc/xics: remove xics_find_source() Cédric Le Goater
                   ` (14 subsequent siblings)
  22 siblings, 1 reply; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-16 13:47 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

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

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 0ffdf09c5304..2decb921e4e3 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -229,16 +229,15 @@ static void icp_check_ipi(ICPState *ss)
     qemu_irq_raise(ss->output);
 }
 
-static void icp_resend(ICPState *ss)
+static void icp_resend(XICSInterface *xi, ICPState *ss)
 {
-    ICSState *ics;
+    XICSInterfaceClass *xic = XICS_INTERFACE_GET_CLASS(xi);
 
     if (ss->mfrr < CPPR(ss)) {
         icp_check_ipi(ss);
     }
-    QLIST_FOREACH(ics, &ss->xics->ics, list) {
-        ics_resend(ics);
-    }
+
+    xic->ics_resend(xi);
 }
 
 void icp_set_cppr(ICPState *ss, uint8_t cppr)
@@ -262,7 +261,7 @@ void icp_set_cppr(ICPState *ss, uint8_t cppr)
         }
     } else {
         if (!XISR(ss)) {
-            icp_resend(ss);
+            icp_resend(XICS_INTERFACE(qdev_get_machine()), ss);
         }
     }
 }
@@ -299,6 +298,8 @@ uint32_t icp_ipoll(ICPState *ss, uint32_t *mfrr)
 
 void icp_eoi(ICPState *ss, uint32_t xirr)
 {
+    XICSInterface *xi = XICS_INTERFACE(qdev_get_machine());
+    XICSInterfaceClass *xic = XICS_INTERFACE_GET_CLASS(xi);
     ICSState *ics;
     uint32_t irq;
 
@@ -306,13 +307,13 @@ void icp_eoi(ICPState *ss, uint32_t xirr)
     ss->xirr = (ss->xirr & ~CPPR_MASK) | (xirr & CPPR_MASK);
     trace_xics_icp_eoi(ss->cs->cpu_index, xirr, ss->xirr);
     irq = xirr & XISR_MASK;
-    QLIST_FOREACH(ics, &ss->xics->ics, list) {
-        if (ics_valid_irq(ics, irq)) {
-            ics_eoi(ics, irq);
-        }
+
+    ics = xic->ics_get(xi, irq);
+    if (ics) {
+        ics_eoi(ics, irq);
     }
     if (!XISR(ss)) {
-        icp_resend(ss);
+        icp_resend(xi, ss);
     }
 }
 
@@ -592,10 +593,11 @@ static void ics_simple_reset(DeviceState *dev)
 
 static int ics_simple_post_load(ICSState *ics, int version_id)
 {
+    XICSInterface *xi = XICS_INTERFACE(qdev_get_machine());
     int i;
 
     for (i = 0; i < ics->xics->nr_servers; i++) {
-        icp_resend(&ics->xics->ss[i]);
+        icp_resend(xi, &ics->xics->ss[i]);
     }
 
     return 0;
-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 09/22] ppc/xics: remove xics_find_source()
  2017-02-16 13:47 [Qemu-devel] [PATCH v2 00/22] ppc/xics: simplify ICS and ICP creation Cédric Le Goater
                   ` (7 preceding siblings ...)
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 08/22] ppc/xics: use the QOM interface to resend irqs Cédric Le Goater
@ 2017-02-16 13:47 ` Cédric Le Goater
  2017-02-23  2:31   ` David Gibson
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 10/22] ppc/xics: register the reset handler of ICS objects Cédric Le Goater
                   ` (13 subsequent siblings)
  22 siblings, 1 reply; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-16 13:47 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

It is not used anymore now that we have the QOM interface for XICS.

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

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 2decb921e4e3..bfd3a539561a 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -737,18 +737,6 @@ static const TypeInfo xics_interface_info = {
 /*
  * Exported functions
  */
-ICSState *xics_find_source(XICSState *xics, int irq)
-{
-    ICSState *ics;
-
-    QLIST_FOREACH(ics, &xics->ics, list) {
-        if (ics_valid_irq(ics, irq)) {
-            return ics;
-        }
-    }
-    return NULL;
-}
-
 qemu_irq xics_get_qirq(XICSInterface *xi, int irq)
 {
     XICSInterfaceClass *xic = XICS_INTERFACE_GET_CLASS(xi);
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index 896fa5d87c1c..e10426e98e31 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -222,7 +222,6 @@ void ics_simple_write_xive(ICSState *ics, int nr, int server,
 
 void ics_set_irq_type(ICSState *ics, int srcno, bool lsi);
 
-ICSState *xics_find_source(XICSState *icp, int irq);
 void ics_resend(ICSState *ics);
 
 #endif /* XICS_H */
-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 10/22] ppc/xics: register the reset handler of ICS objects
  2017-02-16 13:47 [Qemu-devel] [PATCH v2 00/22] ppc/xics: simplify ICS and ICP creation Cédric Le Goater
                   ` (8 preceding siblings ...)
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 09/22] ppc/xics: remove xics_find_source() Cédric Le Goater
@ 2017-02-16 13:47 ` Cédric Le Goater
  2017-02-23  2:33   ` David Gibson
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 11/22] ppc/xics: remove the XICS list of ICS Cédric Le Goater
                   ` (12 subsequent siblings)
  22 siblings, 1 reply; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-16 13:47 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

The reset of the ICS objects is currently handled by XICS but this can
be done for each individual ICS. This also reduces the use of the XICS
list of ICS.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/intc/xics.c | 5 -----
 hw/ppc/spapr.c | 1 +
 2 files changed, 1 insertion(+), 5 deletions(-)

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index bfd3a539561a..d679313cd49f 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -139,16 +139,11 @@ static void ics_simple_pic_print_info(InterruptStatsProvider *obj,
 static void xics_common_reset(DeviceState *d)
 {
     XICSState *xics = XICS_COMMON(d);
-    ICSState *ics;
     int i;
 
     for (i = 0; i < xics->nr_servers; i++) {
         device_reset(DEVICE(&xics->ss[i]));
     }
-
-    QLIST_FOREACH(ics, &xics->ics, list) {
-        device_reset(DEVICE(ics));
-    }
 }
 
 static void xics_common_initfn(Object *obj)
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 85a973cce7ae..a2a64d7de41d 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -112,6 +112,7 @@ static XICSState *try_create_xics(sPAPRMachineState *spapr,
     }
 
     spapr->ics = ICS_SIMPLE(object_new(type_ics));
+    qdev_set_parent_bus(DEVICE(spapr->ics), sysbus_get_default());
     object_property_add_child(OBJECT(spapr), "ics", OBJECT(spapr->ics), NULL);
     object_property_set_int(OBJECT(spapr->ics), nr_irqs, "nr-irqs", &err);
     object_property_add_const_link(OBJECT(spapr->ics), "xics", OBJECT(xics),
-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 11/22] ppc/xics: remove the XICS list of ICS
  2017-02-16 13:47 [Qemu-devel] [PATCH v2 00/22] ppc/xics: simplify ICS and ICP creation Cédric Le Goater
                   ` (9 preceding siblings ...)
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 10/22] ppc/xics: register the reset handler of ICS objects Cédric Le Goater
@ 2017-02-16 13:47 ` Cédric Le Goater
  2017-02-23  2:33   ` David Gibson
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 12/22] ppc/xics: extend the QOM interface to handle ICPs Cédric Le Goater
                   ` (11 subsequent siblings)
  22 siblings, 1 reply; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-16 13:47 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

This is not used anymore.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/intc/xics.c        | 8 --------
 hw/ppc/spapr.c        | 1 -
 include/hw/ppc/xics.h | 2 --
 3 files changed, 11 deletions(-)

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index d679313cd49f..5131587ce088 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -146,13 +146,6 @@ static void xics_common_reset(DeviceState *d)
     }
 }
 
-static void xics_common_initfn(Object *obj)
-{
-    XICSState *xics = XICS_COMMON(obj);
-
-    QLIST_INIT(&xics->ics);
-}
-
 static void xics_common_class_init(ObjectClass *oc, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(oc);
@@ -165,7 +158,6 @@ static const TypeInfo xics_common_info = {
     .parent        = TYPE_DEVICE,
     .instance_size = sizeof(XICSState),
     .class_size    = sizeof(XICSStateClass),
-    .instance_init = xics_common_initfn,
     .class_init    = xics_common_class_init,
 };
 
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index a2a64d7de41d..d1946ebcac69 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -122,7 +122,6 @@ static XICSState *try_create_xics(sPAPRMachineState *spapr,
     if (err) {
         goto error;
     }
-    QLIST_INSERT_HEAD(&xics->ics, spapr->ics, list);
 
     xics->ss = g_malloc0(nr_servers * sizeof(ICPState));
     xics->nr_servers = nr_servers;
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index e10426e98e31..c15d8e2a8ae6 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -82,7 +82,6 @@ struct XICSState {
     /*< public >*/
     uint32_t nr_servers;
     ICPState *ss;
-    QLIST_HEAD(, ICSState) ics;
 };
 
 #define TYPE_ICP "icp"
@@ -152,7 +151,6 @@ struct ICSState {
     qemu_irq *qirqs;
     ICSIRQState *irqs;
     XICSState *xics;
-    QLIST_ENTRY(ICSState) list;
 };
 
 static inline bool ics_valid_irq(ICSState *ics, uint32_t nr)
-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 12/22] ppc/xics: extend the QOM interface to handle ICPs
  2017-02-16 13:47 [Qemu-devel] [PATCH v2 00/22] ppc/xics: simplify ICS and ICP creation Cédric Le Goater
                   ` (10 preceding siblings ...)
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 11/22] ppc/xics: remove the XICS list of ICS Cédric Le Goater
@ 2017-02-16 13:47 ` Cédric Le Goater
  2017-02-23  2:39   ` David Gibson
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 13/22] ppc/xics: simplify the cpu_setup() handler Cédric Le Goater
                   ` (10 subsequent siblings)
  22 siblings, 1 reply; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-16 13:47 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

Let's add two new handlers for ICPs. One is to get an ICP object from
a server number and a second is to resend the irqs when needed.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/intc/xics.c        |  2 +-
 hw/ppc/spapr.c        | 20 ++++++++++++++++++++
 include/hw/ppc/xics.h |  3 +++
 3 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 5131587ce088..7168c2cfd8a1 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -216,7 +216,7 @@ static void icp_check_ipi(ICPState *ss)
     qemu_irq_raise(ss->output);
 }
 
-static void icp_resend(XICSInterface *xi, ICPState *ss)
+void icp_resend(XICSInterface *xi, ICPState *ss)
 {
     XICSInterfaceClass *xic = XICS_INTERFACE_GET_CLASS(xi);
 
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index d1946ebcac69..eb7da32296d8 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -2915,6 +2915,24 @@ static void spapr_ics_resend(XICSInterface *dev)
     ics_resend(spapr->ics);
 }
 
+static ICPState *spapr_icp_get(XICSInterface *xi, int server)
+{
+    sPAPRMachineState *spapr = SPAPR_MACHINE(xi);
+
+    return (server < spapr->xics->nr_servers) ? &spapr->xics->ss[server] :
+        NULL;
+}
+
+static void spapr_icp_resend(XICSInterface *xi)
+{
+    sPAPRMachineState *spapr = SPAPR_MACHINE(xi);
+    int i;
+
+    for (i = 0; i < spapr->xics->nr_servers; i++) {
+        icp_resend(xi, &spapr->xics->ss[i]);
+    }
+}
+
 static void spapr_machine_class_init(ObjectClass *oc, void *data)
 {
     MachineClass *mc = MACHINE_CLASS(oc);
@@ -2959,6 +2977,8 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
     vhc->hypercall = emulate_spapr_hypercall;
     xic->ics_get = spapr_ics_get;
     xic->ics_resend = spapr_ics_resend;
+    xic->icp_get = spapr_icp_get;
+    xic->icp_resend = spapr_icp_resend;
 }
 
 static const TypeInfo spapr_machine_info = {
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index c15d8e2a8ae6..7004c851e250 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -191,6 +191,8 @@ typedef struct XICSInterfaceClass {
     InterfaceClass parent;
     ICSState *(*ics_get)(XICSInterface *xi, int irq);
     void (*ics_resend)(XICSInterface *xi);
+    ICPState *(*icp_get)(XICSInterface *xi, int server);
+    void (*icp_resend)(XICSInterface *xi);
 } XICSInterfaceClass;
 
 #define XICS_IRQS_SPAPR               1024
@@ -221,5 +223,6 @@ void ics_simple_write_xive(ICSState *ics, int nr, int server,
 void ics_set_irq_type(ICSState *ics, int srcno, bool lsi);
 
 void ics_resend(ICSState *ics);
+void icp_resend(XICSInterface *xi, ICPState *ss);
 
 #endif /* XICS_H */
-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 13/22] ppc/xics: simplify the cpu_setup() handler
  2017-02-16 13:47 [Qemu-devel] [PATCH v2 00/22] ppc/xics: simplify ICS and ICP creation Cédric Le Goater
                   ` (11 preceding siblings ...)
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 12/22] ppc/xics: extend the QOM interface to handle ICPs Cédric Le Goater
@ 2017-02-16 13:47 ` Cédric Le Goater
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 14/22] ppc/xics: use the QOM interface to grab an ICP Cédric Le Goater
                   ` (9 subsequent siblings)
  22 siblings, 0 replies; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-16 13:47 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

The cpu_setup() handler currently takes a 'XICSState *' argument to
grab the kernel ICP file descriptor. This interface can be simplified
by using the 'xics' backlink of the ICP object.

This change is also required by subsequent patches which makes use of
the QOM interface for XICS.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/intc/xics.c        |  5 +++--
 hw/intc/xics_kvm.c    | 11 +++--------
 include/hw/ppc/xics.h |  2 +-
 3 files changed, 7 insertions(+), 11 deletions(-)

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 7168c2cfd8a1..c14797fb1964 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -66,14 +66,15 @@ void xics_cpu_setup(XICSState *xics, PowerPCCPU *cpu)
     CPUState *cs = CPU(cpu);
     CPUPPCState *env = &cpu->env;
     ICPState *ss = &xics->ss[cs->cpu_index];
-    XICSStateClass *info = XICS_COMMON_GET_CLASS(xics);
+    XICSStateClass *info;
 
     assert(cs->cpu_index < xics->nr_servers);
 
     ss->cs = cs;
 
+    info = XICS_COMMON_GET_CLASS(ss->xics);
     if (info->cpu_setup) {
-        info->cpu_setup(xics, cpu);
+        info->cpu_setup(ss, cpu);
     }
 
     switch (PPC_INPUT(env)) {
diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index 6cabc11f6be1..3941f31c5b3f 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -334,17 +334,12 @@ static const TypeInfo ics_kvm_info = {
 /*
  * XICS-KVM
  */
-static void xics_kvm_cpu_setup(XICSState *xics, PowerPCCPU *cpu)
+static void xics_kvm_cpu_setup(ICPState *ss, PowerPCCPU *cpu)
 {
-    CPUState *cs;
-    ICPState *ss;
-    KVMXICSState *xicskvm = XICS_SPAPR_KVM(xics);
+    CPUState *cs = CPU(cpu);
+    KVMXICSState *xicskvm = XICS_SPAPR_KVM(ss->xics);
     int ret;
 
-    cs = CPU(cpu);
-    ss = &xics->ss[cs->cpu_index];
-
-    assert(cs->cpu_index < xics->nr_servers);
     if (xicskvm->kernel_xics_fd == -1) {
         abort();
     }
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index 7004c851e250..0375d7d481ef 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -73,7 +73,7 @@ typedef struct ICSIRQState ICSIRQState;
 struct XICSStateClass {
     DeviceClass parent_class;
 
-    void (*cpu_setup)(XICSState *icp, PowerPCCPU *cpu);
+    void (*cpu_setup)(ICPState *icp, PowerPCCPU *cpu);
 };
 
 struct XICSState {
-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 14/22] ppc/xics: use the QOM interface to grab an ICP
  2017-02-16 13:47 [Qemu-devel] [PATCH v2 00/22] ppc/xics: simplify ICS and ICP creation Cédric Le Goater
                   ` (12 preceding siblings ...)
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 13/22] ppc/xics: simplify the cpu_setup() handler Cédric Le Goater
@ 2017-02-16 13:47 ` Cédric Le Goater
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 15/22] ppc/xics: simplify spapr_dt_xics() interface Cédric Le Goater
                   ` (8 subsequent siblings)
  22 siblings, 0 replies; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-16 13:47 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

Also introduce a xics_icp_get() helper to simplify the changes.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/intc/xics.c          | 31 ++++++++++++++++++-------------
 hw/intc/xics_spapr.c    | 17 +++++++++--------
 hw/ppc/spapr_cpu_core.c |  4 ++--
 include/hw/ppc/xics.h   |  8 ++++----
 4 files changed, 33 insertions(+), 27 deletions(-)

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index c14797fb1964..dd41340d41a5 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -49,26 +49,26 @@ int xics_get_cpu_index_by_dt_id(int cpu_dt_id)
     return -1;
 }
 
-void xics_cpu_destroy(XICSState *xics, PowerPCCPU *cpu)
+void xics_cpu_destroy(XICSInterface *xi, PowerPCCPU *cpu)
 {
     CPUState *cs = CPU(cpu);
-    ICPState *ss = &xics->ss[cs->cpu_index];
+    ICPState *ss = xics_icp_get(xi, cs->cpu_index);
 
-    assert(cs->cpu_index < xics->nr_servers);
+    assert(ss);
     assert(cs == ss->cs);
 
     ss->output = NULL;
     ss->cs = NULL;
 }
 
-void xics_cpu_setup(XICSState *xics, PowerPCCPU *cpu)
+void xics_cpu_setup(XICSInterface *xi, PowerPCCPU *cpu)
 {
     CPUState *cs = CPU(cpu);
     CPUPPCState *env = &cpu->env;
-    ICPState *ss = &xics->ss[cs->cpu_index];
+    ICPState *ss = xics_icp_get(xi, cs->cpu_index);
     XICSStateClass *info;
 
-    assert(cs->cpu_index < xics->nr_servers);
+    assert(ss);
 
     ss->cs = cs;
 
@@ -307,8 +307,9 @@ void icp_eoi(ICPState *ss, uint32_t xirr)
 
 static void icp_irq(ICSState *ics, int server, int nr, uint8_t priority)
 {
-    XICSState *xics = ics->xics;
-    ICPState *ss = xics->ss + server;
+    XICSInterface *xi = XICS_INTERFACE(qdev_get_machine());
+    XICSInterfaceClass *xic = XICS_INTERFACE_GET_CLASS(xi);
+    ICPState *ss = xic->icp_get(xi, server);
 
     trace_xics_icp_irq(server, nr, priority);
 
@@ -582,12 +583,9 @@ static void ics_simple_reset(DeviceState *dev)
 static int ics_simple_post_load(ICSState *ics, int version_id)
 {
     XICSInterface *xi = XICS_INTERFACE(qdev_get_machine());
-    int i;
-
-    for (i = 0; i < ics->xics->nr_servers; i++) {
-        icp_resend(xi, &ics->xics->ss[i]);
-    }
+    XICSInterfaceClass *xic = XICS_INTERFACE_GET_CLASS(xi);
 
+    xic->icp_resend(xi);
     return 0;
 }
 
@@ -737,6 +735,13 @@ qemu_irq xics_get_qirq(XICSInterface *xi, int irq)
     return NULL;
 }
 
+ICPState *xics_icp_get(XICSInterface *xi, int server)
+{
+    XICSInterfaceClass *xic = XICS_INTERFACE_GET_CLASS(xi);
+
+    return xic->icp_get(xi, server);
+}
+
 void ics_set_irq_type(ICSState *ics, int srcno, bool lsi)
 {
     assert(!(ics->irqs[srcno].flags & XICS_FLAGS_IRQ_MASK));
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 1501e796e5e0..a837ca655f87 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -44,7 +44,7 @@ static target_ulong h_cppr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                            target_ulong opcode, target_ulong *args)
 {
     CPUState *cs = CPU(cpu);
-    ICPState *icp = &spapr->xics->ss[cs->cpu_index];
+    ICPState *icp = xics_icp_get(XICS_INTERFACE(spapr), cs->cpu_index);
     target_ulong cppr = args[0];
 
     icp_set_cppr(icp, cppr);
@@ -56,12 +56,13 @@ static target_ulong h_ipi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
 {
     target_ulong server = xics_get_cpu_index_by_dt_id(args[0]);
     target_ulong mfrr = args[1];
+    ICPState *icp = xics_icp_get(XICS_INTERFACE(spapr), server);
 
-    if (server >= spapr->xics->nr_servers) {
+    if (!icp) {
         return H_PARAMETER;
     }
 
-    icp_set_mfrr(spapr->xics->ss + server, mfrr);
+    icp_set_mfrr(icp, mfrr);
     return H_SUCCESS;
 }
 
@@ -69,7 +70,7 @@ static target_ulong h_xirr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                            target_ulong opcode, target_ulong *args)
 {
     CPUState *cs = CPU(cpu);
-    ICPState *icp = &spapr->xics->ss[cs->cpu_index];
+    ICPState *icp = xics_icp_get(XICS_INTERFACE(spapr), cs->cpu_index);
     uint32_t xirr = icp_accept(icp);
 
     args[0] = xirr;
@@ -80,7 +81,7 @@ static target_ulong h_xirr_x(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                              target_ulong opcode, target_ulong *args)
 {
     CPUState *cs = CPU(cpu);
-    ICPState *icp = &spapr->xics->ss[cs->cpu_index];
+    ICPState *icp = xics_icp_get(XICS_INTERFACE(spapr), cs->cpu_index);
     uint32_t xirr = icp_accept(icp);
 
     args[0] = xirr;
@@ -92,7 +93,7 @@ static target_ulong h_eoi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                           target_ulong opcode, target_ulong *args)
 {
     CPUState *cs = CPU(cpu);
-    ICPState *icp = &spapr->xics->ss[cs->cpu_index];
+    ICPState *icp = xics_icp_get(XICS_INTERFACE(spapr), cs->cpu_index);
     target_ulong xirr = args[0];
 
     icp_eoi(icp, xirr);
@@ -103,7 +104,7 @@ static target_ulong h_ipoll(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                             target_ulong opcode, target_ulong *args)
 {
     CPUState *cs = CPU(cpu);
-    ICPState *icp = &spapr->xics->ss[cs->cpu_index];
+    ICPState *icp = xics_icp_get(XICS_INTERFACE(spapr), cs->cpu_index);
     uint32_t mfrr;
     uint32_t xirr = icp_ipoll(icp, &mfrr);
 
@@ -134,7 +135,7 @@ static void rtas_set_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr,
     server = xics_get_cpu_index_by_dt_id(rtas_ld(args, 1));
     priority = rtas_ld(args, 2);
 
-    if (!ics_valid_irq(ics, nr) || (server >= ics->xics->nr_servers)
+    if (!ics_valid_irq(ics, nr) || !xics_icp_get(XICS_INTERFACE(spapr), server)
         || (priority > 0xff)) {
         rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
         return;
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index 55cd0456ebe8..2c289a6c72e2 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -42,7 +42,7 @@ static void spapr_cpu_destroy(PowerPCCPU *cpu)
 {
     sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
 
-    xics_cpu_destroy(spapr->xics, cpu);
+    xics_cpu_destroy(XICS_INTERFACE(spapr), cpu);
     qemu_unregister_reset(spapr_cpu_reset, cpu);
 }
 
@@ -76,7 +76,7 @@ static void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu,
             cs->numa_node = i;
     }
 
-    xics_cpu_setup(spapr->xics, cpu);
+    xics_cpu_setup(XICS_INTERFACE(spapr), cpu);
 
     qemu_register_reset(spapr_cpu_reset, cpu);
     spapr_cpu_reset(cpu);
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index 0375d7d481ef..498f187c0dd2 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -197,16 +197,16 @@ typedef struct XICSInterfaceClass {
 
 #define XICS_IRQS_SPAPR               1024
 
-qemu_irq xics_get_qirq(XICSInterface *xi, int irq);
-
 int spapr_ics_alloc(ICSState *ics, int irq_hint, bool lsi, Error **errp);
 int spapr_ics_alloc_block(ICSState *ics, int num, bool lsi, bool align,
                            Error **errp);
 void spapr_ics_free(ICSState *ics, int irq, int num);
 void spapr_dt_xics(XICSState *xics, void *fdt, uint32_t phandle);
 
-void xics_cpu_setup(XICSState *icp, PowerPCCPU *cpu);
-void xics_cpu_destroy(XICSState *icp, PowerPCCPU *cpu);
+qemu_irq xics_get_qirq(XICSInterface *xi, int irq);
+ICPState *xics_icp_get(XICSInterface *xi, int server);
+void xics_cpu_setup(XICSInterface *xi, PowerPCCPU *cpu);
+void xics_cpu_destroy(XICSInterface *xi, PowerPCCPU *cpu);
 
 /* Internal XICS interfaces */
 int xics_get_cpu_index_by_dt_id(int cpu_dt_id);
-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 15/22] ppc/xics: simplify spapr_dt_xics() interface
  2017-02-16 13:47 [Qemu-devel] [PATCH v2 00/22] ppc/xics: simplify ICS and ICP creation Cédric Le Goater
                   ` (13 preceding siblings ...)
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 14/22] ppc/xics: use the QOM interface to grab an ICP Cédric Le Goater
@ 2017-02-16 13:47 ` Cédric Le Goater
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 16/22] ppc/xics: register the reset handler of ICP objects Cédric Le Goater
                   ` (7 subsequent siblings)
  22 siblings, 0 replies; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-16 13:47 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

spapr_dt_xics() only needs the number of servers to build the device
tree nodes. Let's change the routine interface to reflect that.

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

diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index a837ca655f87..cb6325ee64fd 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -387,10 +387,10 @@ void spapr_ics_free(ICSState *ics, int irq, int num)
     }
 }
 
-void spapr_dt_xics(XICSState *xics, void *fdt, uint32_t phandle)
+void spapr_dt_xics(int nr_servers, void *fdt, uint32_t phandle)
 {
     uint32_t interrupt_server_ranges_prop[] = {
-        0, cpu_to_be32(xics->nr_servers),
+        0, cpu_to_be32(nr_servers),
     };
     int node;
 
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index eb7da32296d8..9c1772f93155 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -964,7 +964,7 @@ static void *spapr_build_fdt(sPAPRMachineState *spapr,
     _FDT(fdt_setprop_cell(fdt, 0, "#size-cells", 2));
 
     /* /interrupt controller */
-    spapr_dt_xics(spapr->xics, fdt, PHANDLE_XICP);
+    spapr_dt_xics(spapr->xics->nr_servers, fdt, PHANDLE_XICP);
 
     ret = spapr_populate_memory(spapr, fdt);
     if (ret < 0) {
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index 498f187c0dd2..e320a4c91bb1 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -201,7 +201,7 @@ int spapr_ics_alloc(ICSState *ics, int irq_hint, bool lsi, Error **errp);
 int spapr_ics_alloc_block(ICSState *ics, int num, bool lsi, bool align,
                            Error **errp);
 void spapr_ics_free(ICSState *ics, int irq, int num);
-void spapr_dt_xics(XICSState *xics, void *fdt, uint32_t phandle);
+void spapr_dt_xics(int nr_servers, void *fdt, uint32_t phandle);
 
 qemu_irq xics_get_qirq(XICSInterface *xi, int irq);
 ICPState *xics_icp_get(XICSInterface *xi, int server);
-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 16/22] ppc/xics: register the reset handler of ICP objects
  2017-02-16 13:47 [Qemu-devel] [PATCH v2 00/22] ppc/xics: simplify ICS and ICP creation Cédric Le Goater
                   ` (14 preceding siblings ...)
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 15/22] ppc/xics: simplify spapr_dt_xics() interface Cédric Le Goater
@ 2017-02-16 13:47 ` Cédric Le Goater
  2017-02-23  2:42   ` David Gibson
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 17/22] ppc/xics: move the ICP array under the sPAPR machine Cédric Le Goater
                   ` (6 subsequent siblings)
  22 siblings, 1 reply; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-16 13:47 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

The reset of the ICP objects is currently handled by XICS but this can
be done for each individual ICP.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/intc/xics.c | 18 ------------------
 hw/ppc/spapr.c |  1 +
 2 files changed, 1 insertion(+), 18 deletions(-)

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index dd41340d41a5..3ad7e8cf8ec4 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -137,29 +137,11 @@ static void ics_simple_pic_print_info(InterruptStatsProvider *obj,
 /*
  * XICS Common class - parent for emulated XICS and KVM-XICS
  */
-static void xics_common_reset(DeviceState *d)
-{
-    XICSState *xics = XICS_COMMON(d);
-    int i;
-
-    for (i = 0; i < xics->nr_servers; i++) {
-        device_reset(DEVICE(&xics->ss[i]));
-    }
-}
-
-static void xics_common_class_init(ObjectClass *oc, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(oc);
-
-    dc->reset = xics_common_reset;
-}
-
 static const TypeInfo xics_common_info = {
     .name          = TYPE_XICS_COMMON,
     .parent        = TYPE_DEVICE,
     .instance_size = sizeof(XICSState),
     .class_size    = sizeof(XICSStateClass),
-    .class_init    = xics_common_class_init,
 };
 
 /*
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 9c1772f93155..445d9a6ddad4 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -130,6 +130,7 @@ static XICSState *try_create_xics(sPAPRMachineState *spapr,
         ICPState *icp = &xics->ss[i];
 
         object_initialize(icp, sizeof(*icp), type_icp);
+        qdev_set_parent_bus(DEVICE(icp), sysbus_get_default());
         object_property_add_child(OBJECT(xics), "icp[*]", OBJECT(icp), NULL);
         object_property_add_const_link(OBJECT(icp), "xics", OBJECT(xics), NULL);
         object_property_set_bool(OBJECT(icp), true, "realized", &err);
-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 17/22] ppc/xics: move the ICP array under the sPAPR machine
  2017-02-16 13:47 [Qemu-devel] [PATCH v2 00/22] ppc/xics: simplify ICS and ICP creation Cédric Le Goater
                   ` (15 preceding siblings ...)
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 16/22] ppc/xics: register the reset handler of ICP objects Cédric Le Goater
@ 2017-02-16 13:47 ` Cédric Le Goater
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 18/22] ppc/xics: move kernel_xics_fd out of KVMXICSState Cédric Le Goater
                   ` (5 subsequent siblings)
  22 siblings, 0 replies; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-16 13:47 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/ppc/spapr.c         | 17 ++++++++---------
 include/hw/ppc/spapr.h |  3 +++
 include/hw/ppc/xics.h  |  2 --
 3 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 445d9a6ddad4..6b35b48f818a 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -123,15 +123,15 @@ static XICSState *try_create_xics(sPAPRMachineState *spapr,
         goto error;
     }
 
-    xics->ss = g_malloc0(nr_servers * sizeof(ICPState));
-    xics->nr_servers = nr_servers;
+    spapr->icps = g_malloc0(nr_servers * sizeof(ICPState));
+    spapr->nr_servers = nr_servers;
 
     for (i = 0; i < nr_servers; i++) {
-        ICPState *icp = &xics->ss[i];
+        ICPState *icp = &spapr->icps[i];
 
         object_initialize(icp, sizeof(*icp), type_icp);
         qdev_set_parent_bus(DEVICE(icp), sysbus_get_default());
-        object_property_add_child(OBJECT(xics), "icp[*]", OBJECT(icp), NULL);
+        object_property_add_child(OBJECT(spapr), "icp[*]", OBJECT(icp), NULL);
         object_property_add_const_link(OBJECT(icp), "xics", OBJECT(xics), NULL);
         object_property_set_bool(OBJECT(icp), true, "realized", &err);
         if (err) {
@@ -965,7 +965,7 @@ static void *spapr_build_fdt(sPAPRMachineState *spapr,
     _FDT(fdt_setprop_cell(fdt, 0, "#size-cells", 2));
 
     /* /interrupt controller */
-    spapr_dt_xics(spapr->xics->nr_servers, fdt, PHANDLE_XICP);
+    spapr_dt_xics(spapr->nr_servers, fdt, PHANDLE_XICP);
 
     ret = spapr_populate_memory(spapr, fdt);
     if (ret < 0) {
@@ -2920,8 +2920,7 @@ static ICPState *spapr_icp_get(XICSInterface *xi, int server)
 {
     sPAPRMachineState *spapr = SPAPR_MACHINE(xi);
 
-    return (server < spapr->xics->nr_servers) ? &spapr->xics->ss[server] :
-        NULL;
+    return (server < spapr->nr_servers) ? &spapr->icps[server] : NULL;
 }
 
 static void spapr_icp_resend(XICSInterface *xi)
@@ -2929,8 +2928,8 @@ static void spapr_icp_resend(XICSInterface *xi)
     sPAPRMachineState *spapr = SPAPR_MACHINE(xi);
     int i;
 
-    for (i = 0; i < spapr->xics->nr_servers; i++) {
-        icp_resend(xi, &spapr->xics->ss[i]);
+    for (i = 0; i < spapr->nr_servers; i++) {
+        icp_resend(xi, &spapr->icps[i]);
     }
 }
 
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 21e506b13cfa..f5bbb040f941 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -95,6 +95,9 @@ struct sPAPRMachineState {
     /*< public >*/
     char *kvm_type;
     MemoryHotplugState hotplug_memory;
+
+    uint32_t nr_servers;
+    ICPState *icps;
 };
 
 #define H_SUCCESS         0
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index e320a4c91bb1..726492c948db 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -80,8 +80,6 @@ struct XICSState {
     /*< private >*/
     SysBusDevice parent_obj;
     /*< public >*/
-    uint32_t nr_servers;
-    ICPState *ss;
 };
 
 #define TYPE_ICP "icp"
-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 18/22] ppc/xics: move kernel_xics_fd out of KVMXICSState
  2017-02-16 13:47 [Qemu-devel] [PATCH v2 00/22] ppc/xics: simplify ICS and ICP creation Cédric Le Goater
                   ` (16 preceding siblings ...)
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 17/22] ppc/xics: move the ICP array under the sPAPR machine Cédric Le Goater
@ 2017-02-16 13:47 ` Cédric Le Goater
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 19/22] ppc/xics: move the cpu_setup() handler under the ICPState class Cédric Le Goater
                   ` (4 subsequent siblings)
  22 siblings, 0 replies; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-16 13:47 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

The kernel ICP file descriptor is the only reason behind the
KVMXICSState class and it's in the way of more cleanups. Let's make it
a static for the moment and move forward.

If this is problem, we could use an attribute under the sPAPR machine
later on.

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

diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index 3941f31c5b3f..19c55fa74412 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -40,6 +40,8 @@
 
 #include <sys/ioctl.h>
 
+static int kernel_xics_fd = -1;
+
 typedef struct KVMXICSState {
     XICSState parent_obj;
 
@@ -145,7 +147,6 @@ static const TypeInfo icp_kvm_info = {
  */
 static void ics_get_kvm_state(ICSState *ics)
 {
-    KVMXICSState *xicskvm = XICS_SPAPR_KVM(ics->xics);
     uint64_t state;
     struct kvm_device_attr attr = {
         .flags = 0,
@@ -160,7 +161,7 @@ static void ics_get_kvm_state(ICSState *ics)
 
         attr.attr = i + ics->offset;
 
-        ret = ioctl(xicskvm->kernel_xics_fd, KVM_GET_DEVICE_ATTR, &attr);
+        ret = ioctl(kernel_xics_fd, KVM_GET_DEVICE_ATTR, &attr);
         if (ret != 0) {
             error_report("Unable to retrieve KVM interrupt controller state"
                     " for IRQ %d: %s", i + ics->offset, strerror(errno));
@@ -204,7 +205,6 @@ static void ics_get_kvm_state(ICSState *ics)
 
 static int ics_set_kvm_state(ICSState *ics, int version_id)
 {
-    KVMXICSState *xicskvm = XICS_SPAPR_KVM(ics->xics);
     uint64_t state;
     struct kvm_device_attr attr = {
         .flags = 0,
@@ -238,7 +238,7 @@ static int ics_set_kvm_state(ICSState *ics, int version_id)
             }
         }
 
-        ret = ioctl(xicskvm->kernel_xics_fd, KVM_SET_DEVICE_ATTR, &attr);
+        ret = ioctl(kernel_xics_fd, KVM_SET_DEVICE_ATTR, &attr);
         if (ret != 0) {
             error_report("Unable to restore KVM interrupt controller state"
                     " for IRQs %d: %s", i + ics->offset, strerror(errno));
@@ -337,10 +337,9 @@ static const TypeInfo ics_kvm_info = {
 static void xics_kvm_cpu_setup(ICPState *ss, PowerPCCPU *cpu)
 {
     CPUState *cs = CPU(cpu);
-    KVMXICSState *xicskvm = XICS_SPAPR_KVM(ss->xics);
     int ret;
 
-    if (xicskvm->kernel_xics_fd == -1) {
+    if (kernel_xics_fd == -1) {
         abort();
     }
 
@@ -353,7 +352,7 @@ static void xics_kvm_cpu_setup(ICPState *ss, PowerPCCPU *cpu)
         return;
     }
 
-    ret = kvm_vcpu_enable_cap(cs, KVM_CAP_IRQ_XICS, 0, xicskvm->kernel_xics_fd,
+    ret = kvm_vcpu_enable_cap(cs, KVM_CAP_IRQ_XICS, 0, kernel_xics_fd,
                               kvm_arch_vcpu_id(cs));
     if (ret < 0) {
         error_report("Unable to connect CPU%ld to kernel XICS: %s",
@@ -374,7 +373,6 @@ static void rtas_dummy(PowerPCCPU *cpu, sPAPRMachineState *spapr,
 
 static void xics_kvm_realize(DeviceState *dev, Error **errp)
 {
-    KVMXICSState *xicskvm = XICS_SPAPR_KVM(dev);
     int rc;
     struct kvm_create_device xics_create_device = {
         .type = KVM_DEV_TYPE_XICS,
@@ -423,7 +421,7 @@ static void xics_kvm_realize(DeviceState *dev, Error **errp)
         goto fail;
     }
 
-    xicskvm->kernel_xics_fd = xics_create_device.fd;
+    kernel_xics_fd = xics_create_device.fd;
 
     kvm_kernel_irqchip = true;
     kvm_msi_via_irqfd_allowed = true;
-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 19/22] ppc/xics: move the cpu_setup() handler under the ICPState class
  2017-02-16 13:47 [Qemu-devel] [PATCH v2 00/22] ppc/xics: simplify ICS and ICP creation Cédric Le Goater
                   ` (17 preceding siblings ...)
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 18/22] ppc/xics: move kernel_xics_fd out of KVMXICSState Cédric Le Goater
@ 2017-02-16 13:47 ` Cédric Le Goater
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 20/22] ppc/xics: remove the 'xics' backlinks Cédric Le Goater
                   ` (3 subsequent siblings)
  22 siblings, 0 replies; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-16 13:47 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

The cpu_setup() handler is currenlty under the XICSState class but it
really belongs under ICPState as it is setting up a vCPU.

It makes use of the kernel ICP file descriptor which could be a
problem.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/intc/xics.c        |  8 +++----
 hw/intc/xics_kvm.c    | 58 +++++++++++++++++++++++++--------------------------
 include/hw/ppc/xics.h |  3 +--
 3 files changed, 34 insertions(+), 35 deletions(-)

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 3ad7e8cf8ec4..78e08e23e3d6 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -66,15 +66,15 @@ void xics_cpu_setup(XICSInterface *xi, PowerPCCPU *cpu)
     CPUState *cs = CPU(cpu);
     CPUPPCState *env = &cpu->env;
     ICPState *ss = xics_icp_get(xi, cs->cpu_index);
-    XICSStateClass *info;
+    ICPStateClass *icpc;
 
     assert(ss);
 
     ss->cs = cs;
 
-    info = XICS_COMMON_GET_CLASS(ss->xics);
-    if (info->cpu_setup) {
-        info->cpu_setup(ss, cpu);
+    icpc = ICP_GET_CLASS(ss);
+    if (icpc->cpu_setup) {
+        icpc->cpu_setup(ss, cpu);
     }
 
     switch (PPC_INPUT(env)) {
diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index 19c55fa74412..850777eab913 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -124,6 +124,34 @@ static void icp_kvm_reset(DeviceState *dev)
     icp_set_kvm_state(icp, 1);
 }
 
+static void icp_kvm_cpu_setup(ICPState *ss, PowerPCCPU *cpu)
+{
+    CPUState *cs = CPU(cpu);
+    int ret;
+
+    if (kernel_xics_fd == -1) {
+        abort();
+    }
+
+    /*
+     * If we are reusing a parked vCPU fd corresponding to the CPU
+     * which was hot-removed earlier we don't have to renable
+     * KVM_CAP_IRQ_XICS capability again.
+     */
+    if (ss->cap_irq_xics_enabled) {
+        return;
+    }
+
+    ret = kvm_vcpu_enable_cap(cs, KVM_CAP_IRQ_XICS, 0, kernel_xics_fd,
+                              kvm_arch_vcpu_id(cs));
+    if (ret < 0) {
+        error_report("Unable to connect CPU%ld to kernel XICS: %s",
+                     kvm_arch_vcpu_id(cs), strerror(errno));
+        exit(1);
+    }
+    ss->cap_irq_xics_enabled = true;
+}
+
 static void icp_kvm_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -132,6 +160,7 @@ static void icp_kvm_class_init(ObjectClass *klass, void *data)
     dc->reset = icp_kvm_reset;
     icpc->pre_save = icp_get_kvm_state;
     icpc->post_load = icp_set_kvm_state;
+    icpc->cpu_setup = icp_kvm_cpu_setup;
 }
 
 static const TypeInfo icp_kvm_info = {
@@ -334,33 +363,6 @@ static const TypeInfo ics_kvm_info = {
 /*
  * XICS-KVM
  */
-static void xics_kvm_cpu_setup(ICPState *ss, PowerPCCPU *cpu)
-{
-    CPUState *cs = CPU(cpu);
-    int ret;
-
-    if (kernel_xics_fd == -1) {
-        abort();
-    }
-
-    /*
-     * If we are reusing a parked vCPU fd corresponding to the CPU
-     * which was hot-removed earlier we don't have to renable
-     * KVM_CAP_IRQ_XICS capability again.
-     */
-    if (ss->cap_irq_xics_enabled) {
-        return;
-    }
-
-    ret = kvm_vcpu_enable_cap(cs, KVM_CAP_IRQ_XICS, 0, kernel_xics_fd,
-                              kvm_arch_vcpu_id(cs));
-    if (ret < 0) {
-        error_report("Unable to connect CPU%ld to kernel XICS: %s",
-                     kvm_arch_vcpu_id(cs), strerror(errno));
-        exit(1);
-    }
-    ss->cap_irq_xics_enabled = true;
-}
 
 static void rtas_dummy(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                        uint32_t token,
@@ -439,10 +441,8 @@ fail:
 static void xics_kvm_class_init(ObjectClass *oc, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(oc);
-    XICSStateClass *xsc = XICS_COMMON_CLASS(oc);
 
     dc->realize = xics_kvm_realize;
-    xsc->cpu_setup = xics_kvm_cpu_setup;
 }
 
 static const TypeInfo xics_spapr_kvm_info = {
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index 726492c948db..f7f89c1d18d7 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -72,8 +72,6 @@ typedef struct ICSIRQState ICSIRQState;
 
 struct XICSStateClass {
     DeviceClass parent_class;
-
-    void (*cpu_setup)(ICPState *icp, PowerPCCPU *cpu);
 };
 
 struct XICSState {
@@ -98,6 +96,7 @@ struct ICPStateClass {
 
     void (*pre_save)(ICPState *s);
     int (*post_load)(ICPState *s, int version_id);
+    void (*cpu_setup)(ICPState *icp, PowerPCCPU *cpu);
 };
 
 struct ICPState {
-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 20/22] ppc/xics: remove the 'xics' backlinks
  2017-02-16 13:47 [Qemu-devel] [PATCH v2 00/22] ppc/xics: simplify ICS and ICP creation Cédric Le Goater
                   ` (18 preceding siblings ...)
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 19/22] ppc/xics: move the cpu_setup() handler under the ICPState class Cédric Le Goater
@ 2017-02-16 13:47 ` Cédric Le Goater
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 21/22] ppc/xics: export the XICS init routines Cédric Le Goater
                   ` (2 subsequent siblings)
  22 siblings, 0 replies; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-16 13:47 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

These are not used anymore. Do the cleanups

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/intc/xics.c        | 28 ----------------------------
 hw/intc/xics_kvm.c    | 10 ----------
 hw/ppc/spapr.c        |  3 ---
 include/hw/ppc/xics.h |  3 ---
 4 files changed, 44 deletions(-)

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 78e08e23e3d6..eb1a9f12fd3a 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -360,23 +360,6 @@ static void icp_reset(DeviceState *dev)
     qemu_set_irq(icp->output, 0);
 }
 
-static void icp_realize(DeviceState *dev, Error **errp)
-{
-    ICPState *icp = ICP(dev);
-    Object *obj;
-    Error *err = NULL;
-
-    obj = object_property_get_link(OBJECT(dev), "xics", &err);
-    if (!obj) {
-        error_setg(errp, "%s: required link 'xics' not found: %s",
-                   __func__, error_get_pretty(err));
-        return;
-    }
-
-    icp->xics = XICS_COMMON(obj);
-}
-
-
 static void icp_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -384,7 +367,6 @@ static void icp_class_init(ObjectClass *klass, void *data)
 
     dc->reset = icp_reset;
     dc->vmsd = &vmstate_icp_server;
-    dc->realize = icp_realize;
     ic->print_info = icp_pic_print_info;
 }
 
@@ -634,16 +616,6 @@ static void ics_simple_initfn(Object *obj)
 static void ics_simple_realize(DeviceState *dev, Error **errp)
 {
     ICSState *ics = ICS_SIMPLE(dev);
-    Object *obj;
-    Error *err = NULL;
-
-    obj = object_property_get_link(OBJECT(dev), "xics", &err);
-    if (!obj) {
-        error_setg(errp, "%s: required link 'xics' not found: %s",
-                   __func__, error_get_pretty(err));
-        return;
-    }
-    ics->xics = XICS_COMMON(obj);
 
     if (!ics->nr_irqs) {
         error_setg(errp, "Number of interrupts needs to be greater 0");
diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index 850777eab913..7c1809873c29 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -323,16 +323,6 @@ static void ics_kvm_reset(DeviceState *dev)
 static void ics_kvm_realize(DeviceState *dev, Error **errp)
 {
     ICSState *ics = ICS_SIMPLE(dev);
-    Object *obj;
-    Error *err = NULL;
-
-    obj = object_property_get_link(OBJECT(dev), "xics", &err);
-    if (!obj) {
-        error_setg(errp, "%s: required link 'xics' not found: %s",
-                   __func__, error_get_pretty(err));
-        return;
-    }
-    ics->xics = XICS_COMMON(obj);
 
     if (!ics->nr_irqs) {
         error_setg(errp, "Number of interrupts needs to be greater 0");
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 6b35b48f818a..059408a81b8a 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -115,8 +115,6 @@ static XICSState *try_create_xics(sPAPRMachineState *spapr,
     qdev_set_parent_bus(DEVICE(spapr->ics), sysbus_get_default());
     object_property_add_child(OBJECT(spapr), "ics", OBJECT(spapr->ics), NULL);
     object_property_set_int(OBJECT(spapr->ics), nr_irqs, "nr-irqs", &err);
-    object_property_add_const_link(OBJECT(spapr->ics), "xics", OBJECT(xics),
-                                   NULL);
     object_property_set_bool(OBJECT(spapr->ics), true, "realized", &local_err);
     error_propagate(&err, local_err);
     if (err) {
@@ -132,7 +130,6 @@ static XICSState *try_create_xics(sPAPRMachineState *spapr,
         object_initialize(icp, sizeof(*icp), type_icp);
         qdev_set_parent_bus(DEVICE(icp), sysbus_get_default());
         object_property_add_child(OBJECT(spapr), "icp[*]", OBJECT(icp), NULL);
-        object_property_add_const_link(OBJECT(icp), "xics", OBJECT(xics), NULL);
         object_property_set_bool(OBJECT(icp), true, "realized", &err);
         if (err) {
             goto error;
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index f7f89c1d18d7..20c792fccfc3 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -110,8 +110,6 @@ struct ICPState {
     uint8_t mfrr;
     qemu_irq output;
     bool cap_irq_xics_enabled;
-
-    XICSState *xics;
 };
 
 #define TYPE_ICS_BASE "ics-base"
@@ -147,7 +145,6 @@ struct ICSState {
     uint32_t offset;
     qemu_irq *qirqs;
     ICSIRQState *irqs;
-    XICSState *xics;
 };
 
 static inline bool ics_valid_irq(ICSState *ics, uint32_t nr)
-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 21/22] ppc/xics: export the XICS init routines
  2017-02-16 13:47 [Qemu-devel] [PATCH v2 00/22] ppc/xics: simplify ICS and ICP creation Cédric Le Goater
                   ` (19 preceding siblings ...)
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 20/22] ppc/xics: remove the 'xics' backlinks Cédric Le Goater
@ 2017-02-16 13:47 ` Cédric Le Goater
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 22/22] ppc/xics: remove the XICSState classes Cédric Le Goater
  2017-02-22  3:34 ` [Qemu-devel] [PATCH v2 00/22] ppc/xics: simplify ICS and ICP creation David Gibson
  22 siblings, 0 replies; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-16 13:47 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

There is nothing left related to the XICS object in the realize
functions of the KVMXICSState and XICSState class. So adapt the
interfaces to call these routines directly from the sPAPR machine init
sequence.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/intc/xics_kvm.c    | 13 +++----------
 hw/intc/xics_spapr.c  | 11 ++---------
 hw/ppc/spapr.c        |  4 +++-
 include/hw/ppc/xics.h |  5 +++++
 4 files changed, 13 insertions(+), 20 deletions(-)

diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index 7c1809873c29..4ea34ea6dac5 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -363,7 +363,7 @@ static void rtas_dummy(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                  __func__);
 }
 
-static void xics_kvm_realize(DeviceState *dev, Error **errp)
+int xics_kvm_init(sPAPRMachineState *spapr, Error **errp)
 {
     int rc;
     struct kvm_create_device xics_create_device = {
@@ -419,27 +419,20 @@ static void xics_kvm_realize(DeviceState *dev, Error **errp)
     kvm_msi_via_irqfd_allowed = true;
     kvm_gsi_direct_mapping = true;
 
-    return;
+    return rc;
 
 fail:
     kvmppc_define_rtas_kernel_token(0, "ibm,set-xive");
     kvmppc_define_rtas_kernel_token(0, "ibm,get-xive");
     kvmppc_define_rtas_kernel_token(0, "ibm,int-on");
     kvmppc_define_rtas_kernel_token(0, "ibm,int-off");
-}
-
-static void xics_kvm_class_init(ObjectClass *oc, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(oc);
-
-    dc->realize = xics_kvm_realize;
+    return -1;
 }
 
 static const TypeInfo xics_spapr_kvm_info = {
     .name          = TYPE_XICS_SPAPR_KVM,
     .parent        = TYPE_XICS_COMMON,
     .instance_size = sizeof(KVMXICSState),
-    .class_init    = xics_kvm_class_init,
 };
 
 static void xics_kvm_register_types(void)
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index cb6325ee64fd..5c1ddee1e8e9 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -240,7 +240,7 @@ static void rtas_int_on(PowerPCCPU *cpu, sPAPRMachineState *spapr,
     rtas_st(rets, 0, RTAS_OUT_SUCCESS);
 }
 
-static void xics_spapr_realize(DeviceState *dev, Error **errp)
+int xics_spapr_init(sPAPRMachineState *spapr, Error **errp)
 {
     /* Registration of global state belongs into realize */
     spapr_rtas_register(RTAS_IBM_SET_XIVE, "ibm,set-xive", rtas_set_xive);
@@ -254,13 +254,7 @@ static void xics_spapr_realize(DeviceState *dev, Error **errp)
     spapr_register_hypercall(H_XIRR_X, h_xirr_x);
     spapr_register_hypercall(H_EOI, h_eoi);
     spapr_register_hypercall(H_IPOLL, h_ipoll);
-}
-
-static void xics_spapr_class_init(ObjectClass *oc, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(oc);
-
-    dc->realize = xics_spapr_realize;
+    return 0;
 }
 
 static const TypeInfo xics_spapr_info = {
@@ -268,7 +262,6 @@ static const TypeInfo xics_spapr_info = {
     .parent        = TYPE_XICS_COMMON,
     .instance_size = sizeof(XICSState),
     .class_size = sizeof(XICSStateClass),
-    .class_init    = xics_spapr_class_init,
 };
 
 #define ICS_IRQ_FREE(ics, srcno)   \
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 059408a81b8a..2f1b45200813 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -156,7 +156,8 @@ static XICSState *xics_system_init(MachineState *machine,
     if (kvm_enabled()) {
         Error *err = NULL;
 
-        if (machine_kernel_irqchip_allowed(machine)) {
+        if (machine_kernel_irqchip_allowed(machine) &&
+            !xics_kvm_init(SPAPR_MACHINE(machine), errp)) {
             xics = try_create_xics(SPAPR_MACHINE(machine),
                                    TYPE_XICS_SPAPR_KVM, TYPE_ICS_KVM,
                                    TYPE_KVM_ICP, nr_servers, nr_irqs, &err);
@@ -170,6 +171,7 @@ static XICSState *xics_system_init(MachineState *machine,
     }
 
     if (!xics) {
+        xics_spapr_init(SPAPR_MACHINE(machine), errp);
         xics = try_create_xics(SPAPR_MACHINE(machine),
                                TYPE_XICS_SPAPR, TYPE_ICS_SIMPLE,
                                TYPE_ICP, nr_servers, nr_irqs, errp);
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index 20c792fccfc3..bfbc59ad2a05 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -219,4 +219,9 @@ void ics_set_irq_type(ICSState *ics, int srcno, bool lsi);
 void ics_resend(ICSState *ics);
 void icp_resend(XICSInterface *xi, ICPState *ss);
 
+typedef struct sPAPRMachineState sPAPRMachineState;
+
+int xics_kvm_init(sPAPRMachineState *spapr, Error **errp);
+int xics_spapr_init(sPAPRMachineState *spapr, Error **errp);
+
 #endif /* XICS_H */
-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 22/22] ppc/xics: remove the XICSState classes
  2017-02-16 13:47 [Qemu-devel] [PATCH v2 00/22] ppc/xics: simplify ICS and ICP creation Cédric Le Goater
                   ` (20 preceding siblings ...)
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 21/22] ppc/xics: export the XICS init routines Cédric Le Goater
@ 2017-02-16 13:47 ` Cédric Le Goater
  2017-02-22  3:34 ` [Qemu-devel] [PATCH v2 00/22] ppc/xics: simplify ICS and ICP creation David Gibson
  22 siblings, 0 replies; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-16 13:47 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

These classed are not used anymore. They have been deprecated by the
QOM interface. Do the cleanups.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/intc/xics.c         | 11 -----------
 hw/intc/xics_kvm.c     | 13 -------------
 hw/intc/xics_spapr.c   | 14 --------------
 hw/ppc/spapr.c         | 41 +++++++++++++++--------------------------
 include/hw/ppc/spapr.h |  1 -
 include/hw/ppc/xics.h  | 35 -----------------------------------
 6 files changed, 15 insertions(+), 100 deletions(-)

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index eb1a9f12fd3a..f3acd06eb6a1 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -135,16 +135,6 @@ static void ics_simple_pic_print_info(InterruptStatsProvider *obj,
 }
 
 /*
- * XICS Common class - parent for emulated XICS and KVM-XICS
- */
-static const TypeInfo xics_common_info = {
-    .name          = TYPE_XICS_COMMON,
-    .parent        = TYPE_DEVICE,
-    .instance_size = sizeof(XICSState),
-    .class_size    = sizeof(XICSStateClass),
-};
-
-/*
  * ICP: Presentation layer
  */
 
@@ -706,7 +696,6 @@ void ics_set_irq_type(ICSState *ics, int srcno, bool lsi)
 
 static void xics_register_types(void)
 {
-    type_register_static(&xics_common_info);
     type_register_static(&ics_simple_info);
     type_register_static(&ics_base_info);
     type_register_static(&icp_info);
diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index 4ea34ea6dac5..15e3e338f39c 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -42,12 +42,6 @@
 
 static int kernel_xics_fd = -1;
 
-typedef struct KVMXICSState {
-    XICSState parent_obj;
-
-    int kernel_xics_fd;
-} KVMXICSState;
-
 /*
  * ICP-KVM
  */
@@ -429,15 +423,8 @@ fail:
     return -1;
 }
 
-static const TypeInfo xics_spapr_kvm_info = {
-    .name          = TYPE_XICS_SPAPR_KVM,
-    .parent        = TYPE_XICS_COMMON,
-    .instance_size = sizeof(KVMXICSState),
-};
-
 static void xics_kvm_register_types(void)
 {
-    type_register_static(&xics_spapr_kvm_info);
     type_register_static(&ics_kvm_info);
     type_register_static(&icp_kvm_info);
 }
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 5c1ddee1e8e9..4868755ab7bf 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -257,13 +257,6 @@ int xics_spapr_init(sPAPRMachineState *spapr, Error **errp)
     return 0;
 }
 
-static const TypeInfo xics_spapr_info = {
-    .name          = TYPE_XICS_SPAPR,
-    .parent        = TYPE_XICS_COMMON,
-    .instance_size = sizeof(XICSState),
-    .class_size = sizeof(XICSStateClass),
-};
-
 #define ICS_IRQ_FREE(ics, srcno)   \
     (!((ics)->irqs[(srcno)].flags & (XICS_FLAGS_IRQ_MASK)))
 
@@ -400,10 +393,3 @@ void spapr_dt_xics(int nr_servers, void *fdt, uint32_t phandle)
     _FDT(fdt_setprop_cell(fdt, node, "linux,phandle", phandle));
     _FDT(fdt_setprop_cell(fdt, node, "phandle", phandle));
 }
-
-static void xics_spapr_register_types(void)
-{
-    type_register_static(&xics_spapr_info);
-}
-
-type_init(xics_spapr_register_types)
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 2f1b45200813..6d1f3f756292 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -95,22 +95,13 @@
 
 #define HTAB_SIZE(spapr)        (1ULL << ((spapr)->htab_shift))
 
-static XICSState *try_create_xics(sPAPRMachineState *spapr,
-                                  const char *type, const char *type_ics,
+static int try_create_xics(sPAPRMachineState *spapr, const char *type_ics,
                                   const char *type_icp, int nr_servers,
                                   int nr_irqs, Error **errp)
 {
     Error *err = NULL, *local_err = NULL;
-    XICSState *xics;
     int i;
 
-    xics = XICS_COMMON(object_new(type));
-    qdev_set_parent_bus(DEVICE(xics), sysbus_get_default());
-    object_property_set_bool(OBJECT(xics), true, "realized", &err);
-    if (err) {
-        goto error;
-    }
-
     spapr->ics = ICS_SIMPLE(object_new(type_ics));
     qdev_set_parent_bus(DEVICE(spapr->ics), sysbus_get_default());
     object_property_add_child(OBJECT(spapr), "ics", OBJECT(spapr->ics), NULL);
@@ -137,32 +128,31 @@ static XICSState *try_create_xics(sPAPRMachineState *spapr,
         object_unref(OBJECT(icp));
     }
 
-    return xics;
+    return 0;
 
 error:
     error_propagate(errp, err);
     if (spapr->ics) {
         object_unparent(OBJECT(spapr->ics));
     }
-    object_unparent(OBJECT(xics));
-    return NULL;
+    return -1;
 }
 
-static XICSState *xics_system_init(MachineState *machine,
-                                   int nr_servers, int nr_irqs, Error **errp)
+static int xics_system_init(MachineState *machine,
+                            int nr_servers, int nr_irqs, Error **errp)
 {
-    XICSState *xics = NULL;
+    int rc = -1;
 
     if (kvm_enabled()) {
         Error *err = NULL;
 
         if (machine_kernel_irqchip_allowed(machine) &&
             !xics_kvm_init(SPAPR_MACHINE(machine), errp)) {
-            xics = try_create_xics(SPAPR_MACHINE(machine),
-                                   TYPE_XICS_SPAPR_KVM, TYPE_ICS_KVM,
+            rc = try_create_xics(SPAPR_MACHINE(machine),
+                                   TYPE_ICS_KVM,
                                    TYPE_KVM_ICP, nr_servers, nr_irqs, &err);
         }
-        if (machine_kernel_irqchip_required(machine) && !xics) {
+        if (machine_kernel_irqchip_required(machine) && rc < 0) {
             error_reportf_err(err,
                               "kernel_irqchip requested but unavailable: ");
         } else {
@@ -170,14 +160,14 @@ static XICSState *xics_system_init(MachineState *machine,
         }
     }
 
-    if (!xics) {
+    if (rc < 0) {
         xics_spapr_init(SPAPR_MACHINE(machine), errp);
-        xics = try_create_xics(SPAPR_MACHINE(machine),
-                               TYPE_XICS_SPAPR, TYPE_ICS_SIMPLE,
+        rc = try_create_xics(SPAPR_MACHINE(machine),
+                               TYPE_ICS_SIMPLE,
                                TYPE_ICP, nr_servers, nr_irqs, errp);
     }
 
-    return xics;
+    return rc;
 }
 
 static int spapr_fixup_cpu_smt_dt(void *fdt, int offset, PowerPCCPU *cpu,
@@ -1939,9 +1929,8 @@ static void ppc_spapr_init(MachineState *machine)
     load_limit = MIN(spapr->rma_size, RTAS_MAX_ADDR) - FW_OVERHEAD;
 
     /* Set up Interrupt Controller before we create the VCPUs */
-    spapr->xics = xics_system_init(machine,
-                                   DIV_ROUND_UP(max_cpus * smt, smp_threads),
-                                   XICS_IRQS_SPAPR, &error_fatal);
+    xics_system_init(machine, DIV_ROUND_UP(max_cpus * smt, smp_threads),
+                     XICS_IRQS_SPAPR, &error_fatal);
 
     /* Set up containers for ibm,client-set-architecture negotiated options */
     spapr->ov5 = spapr_ovec_new();
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index f5bbb040f941..cfd271129dd0 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -58,7 +58,6 @@ struct sPAPRMachineState {
     struct VIOsPAPRBus *vio_bus;
     QLIST_HEAD(, sPAPRPHBState) phbs;
     struct sPAPRNVRAM *nvram;
-    XICSState *xics;
     ICSState *ics;
     DeviceState *rtc;
 
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index bfbc59ad2a05..4060fcfe84ba 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -30,29 +30,6 @@
 
 #include "hw/sysbus.h"
 
-#define TYPE_XICS_COMMON "xics-common"
-#define XICS_COMMON(obj) OBJECT_CHECK(XICSState, (obj), TYPE_XICS_COMMON)
-
-/*
- * Retain xics as the type name to be compatible for migration. Rest all the
- * functions, class and variables are renamed as xics_spapr.
- */
-#define TYPE_XICS_SPAPR "xics"
-#define XICS_SPAPR(obj) OBJECT_CHECK(XICSState, (obj), TYPE_XICS_SPAPR)
-
-#define TYPE_XICS_SPAPR_KVM "xics-spapr-kvm"
-#define XICS_SPAPR_KVM(obj) \
-     OBJECT_CHECK(KVMXICSState, (obj), TYPE_XICS_SPAPR_KVM)
-
-#define XICS_COMMON_CLASS(klass) \
-     OBJECT_CLASS_CHECK(XICSStateClass, (klass), TYPE_XICS_COMMON)
-#define XICS_SPAPR_CLASS(klass) \
-     OBJECT_CLASS_CHECK(XICSStateClass, (klass), TYPE_XICS_SPAPR)
-#define XICS_COMMON_GET_CLASS(obj) \
-     OBJECT_GET_CLASS(XICSStateClass, (obj), TYPE_XICS_COMMON)
-#define XICS_SPAPR_GET_CLASS(obj) \
-     OBJECT_GET_CLASS(XICSStateClass, (obj), TYPE_XICS_SPAPR)
-
 #define XICS_IPI        0x2
 #define XICS_BUID       0x1
 #define XICS_IRQ_BASE   (XICS_BUID << 12)
@@ -62,24 +39,12 @@
  * (the kernel implementation supports more but we don't exploit
  *  that yet)
  */
-typedef struct XICSStateClass XICSStateClass;
-typedef struct XICSState XICSState;
 typedef struct ICPStateClass ICPStateClass;
 typedef struct ICPState ICPState;
 typedef struct ICSStateClass ICSStateClass;
 typedef struct ICSState ICSState;
 typedef struct ICSIRQState ICSIRQState;
 
-struct XICSStateClass {
-    DeviceClass parent_class;
-};
-
-struct XICSState {
-    /*< private >*/
-    SysBusDevice parent_obj;
-    /*< public >*/
-};
-
 #define TYPE_ICP "icp"
 #define ICP(obj) OBJECT_CHECK(ICPState, (obj), TYPE_ICP)
 
-- 
2.7.4

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

* Re: [Qemu-devel] [PATCH v2 01/22] ppc/xics: remove set_nr_irqs() handler from XICSStateClass
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 01/22] ppc/xics: remove set_nr_irqs() handler from XICSStateClass Cédric Le Goater
@ 2017-02-22  3:21   ` David Gibson
  2017-02-24 10:46     ` Cédric Le Goater
  0 siblings, 1 reply; 59+ messages in thread
From: David Gibson @ 2017-02-22  3:21 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Thu, Feb 16, 2017 at 02:47:24PM +0100, Cédric Le Goater wrote:
> Today, the ICS (Interrupt Controller Source) object is created and
> realized by the init and realize routines of the XICS object, but some
> of the parameters are only known at the machine level.
> 
> These parameters are passed from the sPAPR machine to the ICS object
> in a rather convoluted way using property handlers and a class handler
> of the XICS object. The number of irqs required to allocate the IRQ
> state objects in the ICS realize routine is one of them.
> 
> Let's simplify the process by creating the ICS object along with the
> XICS object at the machine level and link the ICS into the XICS list
> of ICSs at this level also. In the sPAPR machine, there is only a
> single ICS but that will change with the PowerNV machine.
> 
> Also, QOMify the creation of the objects and get rid of the
> superfluous code.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
> 
>  Changes since v1:
> 
>  - added a XICS link to the ICS object
> 
>  hw/intc/xics.c        | 51 ++++++++++++++++---------------------------------
>  hw/intc/xics_kvm.c    | 44 ++++++++++--------------------------------
>  hw/intc/xics_spapr.c  | 34 ---------------------------------
>  hw/ppc/spapr.c        | 53 +++++++++++++++++++++++++++++++++++----------------
>  include/hw/ppc/xics.h |  2 --
>  5 files changed, 63 insertions(+), 121 deletions(-)
> 
> diff --git a/hw/intc/xics.c b/hw/intc/xics.c
> index 372b8311fb8b..e70d3b8b1095 100644
> --- a/hw/intc/xics.c
> +++ b/hw/intc/xics.c
> @@ -151,38 +151,6 @@ static void xics_common_reset(DeviceState *d)
>      }
>  }
>  
> -static void xics_prop_get_nr_irqs(Object *obj, Visitor *v, const char *name,
> -                                  void *opaque, Error **errp)
> -{
> -    XICSState *xics = XICS_COMMON(obj);
> -    int64_t value = xics->nr_irqs;
> -
> -    visit_type_int(v, name, &value, errp);
> -}
> -
> -static void xics_prop_set_nr_irqs(Object *obj, Visitor *v, const char *name,
> -                                  void *opaque, Error **errp)
> -{
> -    XICSState *xics = XICS_COMMON(obj);
> -    XICSStateClass *info = XICS_COMMON_GET_CLASS(xics);
> -    Error *error = NULL;
> -    int64_t value;
> -
> -    visit_type_int(v, name, &value, &error);
> -    if (error) {
> -        error_propagate(errp, error);
> -        return;
> -    }
> -    if (xics->nr_irqs) {
> -        error_setg(errp, "Number of interrupts is already set to %u",
> -                   xics->nr_irqs);
> -        return;
> -    }
> -
> -    assert(info->set_nr_irqs);
> -    info->set_nr_irqs(xics, value, errp);
> -}
> -
>  void xics_set_nr_servers(XICSState *xics, uint32_t nr_servers,
>                           const char *typename, Error **errp)
>  {
> @@ -241,9 +209,6 @@ static void xics_common_initfn(Object *obj)
>      XICSState *xics = XICS_COMMON(obj);
>  
>      QLIST_INIT(&xics->ics);
> -    object_property_add(obj, "nr_irqs", "int",
> -                        xics_prop_get_nr_irqs, xics_prop_set_nr_irqs,
> -                        NULL, NULL, NULL);
>      object_property_add(obj, "nr_servers", "int",
>                          xics_prop_get_nr_servers, xics_prop_set_nr_servers,
>                          NULL, NULL, NULL);
> @@ -737,6 +702,16 @@ static void ics_simple_initfn(Object *obj)
>  static void ics_simple_realize(DeviceState *dev, Error **errp)
>  {
>      ICSState *ics = ICS_SIMPLE(dev);
> +    Object *obj;
> +    Error *err = NULL;
> +
> +    obj = object_property_get_link(OBJECT(dev), "xics", &err);
> +    if (!obj) {
> +        error_setg(errp, "%s: required link 'xics' not found: %s",
> +                   __func__, error_get_pretty(err));
> +        return;
> +    }
> +    ics->xics = XICS_COMMON(obj);
>  
>      if (!ics->nr_irqs) {
>          error_setg(errp, "Number of interrupts needs to be greater 0");
> @@ -746,12 +721,18 @@ static void ics_simple_realize(DeviceState *dev, Error **errp)
>      ics->qirqs = qemu_allocate_irqs(ics_simple_set_irq, ics, ics->nr_irqs);
>  }
>  
> +static Property ics_simple_properties[] = {
> +    DEFINE_PROP_UINT32("nr-irqs", ICSState, nr_irqs, 0),
> +    DEFINE_PROP_END_OF_LIST(),
> +};
> +
>  static void ics_simple_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
>      ICSStateClass *isc = ICS_BASE_CLASS(klass);
>  
>      dc->realize = ics_simple_realize;
> +    dc->props = ics_simple_properties;
>      dc->vmsd = &vmstate_ics_simple;
>      dc->reset = ics_simple_reset;
>      isc->post_load = ics_simple_post_load;
> diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
> index 17694eaa8709..4a6c0522feb6 100644
> --- a/hw/intc/xics_kvm.c
> +++ b/hw/intc/xics_kvm.c
> @@ -294,6 +294,16 @@ static void ics_kvm_reset(DeviceState *dev)
>  static void ics_kvm_realize(DeviceState *dev, Error **errp)
>  {
>      ICSState *ics = ICS_SIMPLE(dev);
> +    Object *obj;
> +    Error *err = NULL;
> +
> +    obj = object_property_get_link(OBJECT(dev), "xics", &err);
> +    if (!obj) {
> +        error_setg(errp, "%s: required link 'xics' not found: %s",
> +                   __func__, error_get_pretty(err));
> +        return;
> +    }
> +    ics->xics = XICS_COMMON(obj);

Couldn't you have this logic in the base class rather than repeating
it in ics simple and ics kvm?

>      if (!ics->nr_irqs) {
>          error_setg(errp, "Number of interrupts needs to be greater 0");
> @@ -358,18 +368,6 @@ static void xics_kvm_cpu_setup(XICSState *xics, PowerPCCPU *cpu)
>      ss->cap_irq_xics_enabled = true;
>  }
>  
> -static void xics_kvm_set_nr_irqs(XICSState *xics, uint32_t nr_irqs,
> -                                 Error **errp)
> -{
> -    ICSState *ics = QLIST_FIRST(&xics->ics);
> -
> -    /* This needs to be deprecated ... */
> -    xics->nr_irqs = nr_irqs;
> -    if (ics) {
> -        ics->nr_irqs = nr_irqs;
> -    }
> -}
> -
>  static void xics_kvm_set_nr_servers(XICSState *xics, uint32_t nr_servers,
>                                      Error **errp)
>  {
> @@ -389,7 +387,6 @@ static void xics_kvm_realize(DeviceState *dev, Error **errp)
>  {
>      KVMXICSState *xicskvm = XICS_SPAPR_KVM(dev);
>      XICSState *xics = XICS_COMMON(dev);
> -    ICSState *ics;
>      int i, rc;
>      Error *error = NULL;
>      struct kvm_create_device xics_create_device = {
> @@ -441,14 +438,6 @@ static void xics_kvm_realize(DeviceState *dev, Error **errp)
>  
>      xicskvm->kernel_xics_fd = xics_create_device.fd;
>  
> -    QLIST_FOREACH(ics, &xics->ics, list) {
> -        object_property_set_bool(OBJECT(ics), true, "realized", &error);
> -        if (error) {
> -            error_propagate(errp, error);
> -            goto fail;
> -        }
> -    }
> -
>      assert(xics->nr_servers);
>      for (i = 0; i < xics->nr_servers; i++) {
>          object_property_set_bool(OBJECT(&xics->ss[i]), true, "realized",
> @@ -472,17 +461,6 @@ fail:
>      kvmppc_define_rtas_kernel_token(0, "ibm,int-off");
>  }
>  
> -static void xics_kvm_initfn(Object *obj)
> -{
> -    XICSState *xics = XICS_COMMON(obj);
> -    ICSState *ics;
> -
> -    ics = ICS_SIMPLE(object_new(TYPE_ICS_KVM));
> -    object_property_add_child(obj, "ics", OBJECT(ics), NULL);
> -    ics->xics = xics;
> -    QLIST_INSERT_HEAD(&xics->ics, ics, list);
> -}
> -
>  static void xics_kvm_class_init(ObjectClass *oc, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(oc);
> @@ -490,7 +468,6 @@ static void xics_kvm_class_init(ObjectClass *oc, void *data)
>  
>      dc->realize = xics_kvm_realize;
>      xsc->cpu_setup = xics_kvm_cpu_setup;
> -    xsc->set_nr_irqs = xics_kvm_set_nr_irqs;
>      xsc->set_nr_servers = xics_kvm_set_nr_servers;
>  }
>  
> @@ -499,7 +476,6 @@ static const TypeInfo xics_spapr_kvm_info = {
>      .parent        = TYPE_XICS_COMMON,
>      .instance_size = sizeof(KVMXICSState),
>      .class_init    = xics_kvm_class_init,
> -    .instance_init = xics_kvm_initfn,
>  };
>  
>  static void xics_kvm_register_types(void)
> diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
> index 2e3f1c5e95b2..03e42a866603 100644
> --- a/hw/intc/xics_spapr.c
> +++ b/hw/intc/xics_spapr.c
> @@ -239,18 +239,6 @@ static void rtas_int_on(PowerPCCPU *cpu, sPAPRMachineState *spapr,
>      rtas_st(rets, 0, RTAS_OUT_SUCCESS);
>  }
>  
> -static void xics_spapr_set_nr_irqs(XICSState *xics, uint32_t nr_irqs,
> -                                   Error **errp)
> -{
> -    ICSState *ics = QLIST_FIRST(&xics->ics);
> -
> -    /* This needs to be deprecated ... */
> -    xics->nr_irqs = nr_irqs;
> -    if (ics) {
> -        ics->nr_irqs = nr_irqs;
> -    }
> -}
> -
>  static void xics_spapr_set_nr_servers(XICSState *xics, uint32_t nr_servers,
>                                        Error **errp)
>  {
> @@ -260,7 +248,6 @@ static void xics_spapr_set_nr_servers(XICSState *xics, uint32_t nr_servers,
>  static void xics_spapr_realize(DeviceState *dev, Error **errp)
>  {
>      XICSState *xics = XICS_SPAPR(dev);
> -    ICSState *ics;
>      Error *error = NULL;
>      int i;
>  
> @@ -282,14 +269,6 @@ static void xics_spapr_realize(DeviceState *dev, Error **errp)
>      spapr_register_hypercall(H_EOI, h_eoi);
>      spapr_register_hypercall(H_IPOLL, h_ipoll);
>  
> -    QLIST_FOREACH(ics, &xics->ics, list) {
> -        object_property_set_bool(OBJECT(ics), true, "realized", &error);
> -        if (error) {
> -            error_propagate(errp, error);
> -            return;
> -        }
> -    }
> -
>      for (i = 0; i < xics->nr_servers; i++) {
>          object_property_set_bool(OBJECT(&xics->ss[i]), true, "realized",
>                                   &error);
> @@ -300,24 +279,12 @@ static void xics_spapr_realize(DeviceState *dev, Error **errp)
>      }
>  }
>  
> -static void xics_spapr_initfn(Object *obj)
> -{
> -    XICSState *xics = XICS_SPAPR(obj);
> -    ICSState *ics;
> -
> -    ics = ICS_SIMPLE(object_new(TYPE_ICS_SIMPLE));
> -    object_property_add_child(obj, "ics", OBJECT(ics), NULL);
> -    ics->xics = xics;
> -    QLIST_INSERT_HEAD(&xics->ics, ics, list);
> -}
> -
>  static void xics_spapr_class_init(ObjectClass *oc, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(oc);
>      XICSStateClass *xsc = XICS_SPAPR_CLASS(oc);
>  
>      dc->realize = xics_spapr_realize;
> -    xsc->set_nr_irqs = xics_spapr_set_nr_irqs;
>      xsc->set_nr_servers = xics_spapr_set_nr_servers;
>  }
>  
> @@ -327,7 +294,6 @@ static const TypeInfo xics_spapr_info = {
>      .instance_size = sizeof(XICSState),
>      .class_size = sizeof(XICSStateClass),
>      .class_init    = xics_spapr_class_init,
> -    .instance_init = xics_spapr_initfn,
>  };
>  
>  #define ICS_IRQ_FREE(ics, srcno)   \
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 9b6ad0f2fd77..94b1e8e3227a 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -95,22 +95,42 @@
>  
>  #define HTAB_SIZE(spapr)        (1ULL << ((spapr)->htab_shift))
>  
> -static XICSState *try_create_xics(const char *type, int nr_servers,
> -                                  int nr_irqs, Error **errp)
> -{
> -    Error *err = NULL;
> -    DeviceState *dev;
> +static XICSState *try_create_xics(const char *type, const char *type_ics,
> +                                  int nr_servers, int nr_irqs, Error **errp)
> +{
> +    Error *err = NULL, *local_err = NULL;
> +    XICSState *xics;
> +    ICSState *ics = NULL;
> +
> +    xics = XICS_COMMON(object_new(type));
> +    qdev_set_parent_bus(DEVICE(xics), sysbus_get_default());
> +    object_property_set_int(OBJECT(xics), nr_servers, "nr_servers", &err);
> +    object_property_set_bool(OBJECT(xics), true, "realized", &local_err);
> +    error_propagate(&err, local_err);
> +    if (err) {
> +        goto error;
> +    }
>  
> -    dev = DEVICE(object_new(type));
> -    qdev_prop_set_uint32(dev, "nr_servers", nr_servers);
> -    qdev_prop_set_uint32(dev, "nr_irqs", nr_irqs);
> -    object_property_set_bool(OBJECT(dev), true, "realized", &err);
> +    ics = ICS_SIMPLE(object_new(type_ics));
> +    object_property_add_child(OBJECT(xics), "ics", OBJECT(ics), NULL);
> +    object_property_set_int(OBJECT(ics), nr_irqs, "nr-irqs", &err);
> +    object_property_add_const_link(OBJECT(ics), "xics", OBJECT(xics), NULL);
> +    object_property_set_bool(OBJECT(ics), true, "realized", &local_err);
> +    error_propagate(&err, local_err);
>      if (err) {
> -        error_propagate(errp, err);
> -        object_unparent(OBJECT(dev));
> -        return NULL;
> +        goto error;
>      }
> -    return XICS_COMMON(dev);
> +    QLIST_INSERT_HEAD(&xics->ics, ics, list);
> +
> +    return xics;
> +
> +error:
> +    error_propagate(errp, err);
> +    if (ics) {
> +        object_unparent(OBJECT(ics));
> +    }
> +    object_unparent(OBJECT(xics));
> +    return NULL;
>  }
>  
>  static XICSState *xics_system_init(MachineState *machine,
> @@ -122,8 +142,8 @@ static XICSState *xics_system_init(MachineState *machine,
>          Error *err = NULL;
>  
>          if (machine_kernel_irqchip_allowed(machine)) {
> -            xics = try_create_xics(TYPE_XICS_SPAPR_KVM, nr_servers, nr_irqs,
> -                                   &err);
> +            xics = try_create_xics(TYPE_XICS_SPAPR_KVM, TYPE_ICS_KVM,
> +                                   nr_servers, nr_irqs, &err);
>          }
>          if (machine_kernel_irqchip_required(machine) && !xics) {
>              error_reportf_err(err,
> @@ -134,7 +154,8 @@ static XICSState *xics_system_init(MachineState *machine,
>      }
>  
>      if (!xics) {
> -        xics = try_create_xics(TYPE_XICS_SPAPR, nr_servers, nr_irqs, errp);
> +        xics = try_create_xics(TYPE_XICS_SPAPR, TYPE_ICS_SIMPLE, nr_servers,
> +                               nr_irqs, errp);
>      }
>  
>      return xics;
> diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
> index 3f0c31610aa4..8fe3c4d2ceab 100644
> --- a/include/hw/ppc/xics.h
> +++ b/include/hw/ppc/xics.h
> @@ -74,7 +74,6 @@ struct XICSStateClass {
>      DeviceClass parent_class;
>  
>      void (*cpu_setup)(XICSState *icp, PowerPCCPU *cpu);
> -    void (*set_nr_irqs)(XICSState *icp, uint32_t nr_irqs, Error **errp);
>      void (*set_nr_servers)(XICSState *icp, uint32_t nr_servers, Error **errp);
>  };
>  
> @@ -83,7 +82,6 @@ struct XICSState {
>      SysBusDevice parent_obj;
>      /*< public >*/
>      uint32_t nr_servers;
> -    uint32_t nr_irqs;
>      ICPState *ss;
>      QLIST_HEAD(, ICSState) ics;
>  };

-- 
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: 819 bytes --]

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

* Re: [Qemu-devel] [PATCH v2 00/22] ppc/xics: simplify ICS and ICP creation
  2017-02-16 13:47 [Qemu-devel] [PATCH v2 00/22] ppc/xics: simplify ICS and ICP creation Cédric Le Goater
                   ` (21 preceding siblings ...)
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 22/22] ppc/xics: remove the XICSState classes Cédric Le Goater
@ 2017-02-22  3:34 ` David Gibson
  2017-02-22 10:55   ` Cédric Le Goater
  22 siblings, 1 reply; 59+ messages in thread
From: David Gibson @ 2017-02-22  3:34 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Thu, Feb 16, 2017 at 02:47:23PM +0100, Cédric Le Goater wrote:
> Hello,
> 
> The goal behind this series is to simplify the XICS interface by
> moving back in the machine the way the ICS and ICP objects interact
> together. It's up to the machine to implement this "fabric" logic by
> providing a set of handlers of a QOM interface. These handlers are
> used to grab an ICS or an ICP object and also do irq resends. This
> idea was suggested by David Gibson.
> 
> The patchset is organised as follow. It starts with a preliminary
> cleanup to get rid of the set_nr_irqs() and set_nr_servers()
> handlers. It also moves the creation of the ICS and ICP objects from
> the XICS object to the sPAPR machine. This simplifies the code
> significantly and prepares ground for future changes.
> 
> As the sPAPR machine only makes use of a single ICS, we can store it
> at the machine level. This lets us remove dependencies on the list of
> ICS of the XICS object and simplify even more the code for the
> following changes.
> 
> The QOM interface to interact with the ICS and ICP objects is then
> introduced. These are moved under the machine and cleanups are done
> accordingly.
> 
> Finally, the XICSState classes are removed as they have been
> deprecated by the QOM interface.
> 
> 
> After the initial cleanups, which are rather big, I have tried to keep
> the each patch small enough to ease the review and to spot any
> problem. Each should be bisectable. The tree is available here :
> 
> 	   https://github.com/legoater/qemu/tree/ppc-2.9

So, after you posted this, I discover the patch I sent the other day -
changing XICS away from a SysBusDevice breaks the postcopy migration
test on KVM.  I haven't had a chance to debug this yet, so for the
time being I've pulled my patch from ppc-for-2.9.  I've moved it into
a new 'xics-cleanup' branch.

> 
> 
> Thanks,
> 
> C.
> 
> 
> Changes since v1:
> 
>  - address the full picture.
> 
> Cédric Le Goater (22):
>   ppc/xics: remove set_nr_irqs() handler from XICSStateClass
>   ppc/xics: remove set_nr_servers() handler from XICSStateClass
>   ppc/xics: store the ICS object under the sPAPR machine
>   ppc/xics: add an InterruptStatsProvider interface to ICS and ICP
>     objects
>   ppc/xics: introduce a QOM interface to handle ICSs
>   ppc/xics: use the QOM interface under the sPAPR machine
>   ppc/xics: use the QOM interface to get irqs
>   ppc/xics: use the QOM interface to resend irqs
>   ppc/xics: remove xics_find_source()
>   ppc/xics: register the reset handler of ICS objects
>   ppc/xics: remove the XICS list of ICS
>   ppc/xics: extend the QOM interface to handle ICPs
>   ppc/xics: simplify the cpu_setup() handler
>   ppc/xics: use the QOM interface to grab an ICP
>   ppc/xics: simplify spapr_dt_xics() interface
>   ppc/xics: register the reset handler of ICP objects
>   ppc/xics: move the ICP array under the sPAPR machine
>   ppc/xics: move kernel_xics_fd out of KVMXICSState
>   ppc/xics: move the cpu_setup() handler under the ICPState class
>   ppc/xics: remove the 'xics' backlinks
>   ppc/xics: export the XICS init routines
>   ppc/xics: remove the XICSState classes
> 
>  hw/intc/xics.c              | 295 +++++++++++++-------------------------------
>  hw/intc/xics_kvm.c          | 154 ++++++-----------------
>  hw/intc/xics_spapr.c        | 128 ++++---------------
>  hw/ppc/spapr.c              | 116 +++++++++++++----
>  hw/ppc/spapr_cpu_core.c     |   4 +-
>  hw/ppc/spapr_events.c       |  10 +-
>  hw/ppc/spapr_pci.c          |  10 +-
>  hw/ppc/spapr_vio.c          |   2 +-
>  include/hw/pci-host/spapr.h |   2 +-
>  include/hw/ppc/spapr.h      |   5 +-
>  include/hw/ppc/spapr_vio.h  |   2 +-
>  include/hw/ppc/xics.h       |  93 ++++++--------
>  12 files changed, 294 insertions(+), 527 deletions(-)
> 

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

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

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

* Re: [Qemu-devel] [PATCH v2 02/22] ppc/xics: remove set_nr_servers() handler from XICSStateClass
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 02/22] ppc/xics: remove set_nr_servers() " Cédric Le Goater
@ 2017-02-22  6:23   ` David Gibson
  0 siblings, 0 replies; 59+ messages in thread
From: David Gibson @ 2017-02-22  6:23 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Thu, Feb 16, 2017 at 02:47:25PM +0100, Cédric Le Goater wrote:
> Today, the ICP (Interrupt Controller Presenter) objects are created by
> the 'nr_servers' property handler of the XICS object and a class
> handler. They are realized in the XICS object realize routine.
> 
> Let's simplify the process by creating the ICP objects along with the
> XICS object at the machine level.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

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

> ---
> 
>  Changes since v1:
> 
>  - added a XICS link to the ICS object
>  - removed xics_set_nr_servers() routine
>  - removed set_nr_servers() class handler
> 
>  hw/intc/xics.c        | 74 +++++++++++++--------------------------------------
>  hw/intc/xics_kvm.c    | 21 +--------------
>  hw/intc/xics_spapr.c  | 26 ------------------
>  hw/ppc/spapr.c        | 30 ++++++++++++++++-----
>  include/hw/ppc/xics.h |  3 ---
>  5 files changed, 42 insertions(+), 112 deletions(-)
> 
> diff --git a/hw/intc/xics.c b/hw/intc/xics.c
> index e70d3b8b1095..9f22814815c9 100644
> --- a/hw/intc/xics.c
> +++ b/hw/intc/xics.c
> @@ -151,67 +151,11 @@ static void xics_common_reset(DeviceState *d)
>      }
>  }
>  
> -void xics_set_nr_servers(XICSState *xics, uint32_t nr_servers,
> -                         const char *typename, Error **errp)
> -{
> -    int i;
> -
> -    xics->nr_servers = nr_servers;
> -
> -    xics->ss = g_malloc0(xics->nr_servers * sizeof(ICPState));
> -    for (i = 0; i < xics->nr_servers; i++) {
> -        char name[32];
> -        ICPState *icp = &xics->ss[i];
> -
> -        object_initialize(icp, sizeof(*icp), typename);
> -        snprintf(name, sizeof(name), "icp[%d]", i);
> -        object_property_add_child(OBJECT(xics), name, OBJECT(icp), errp);
> -        icp->xics = xics;
> -    }
> -}
> -
> -static void xics_prop_get_nr_servers(Object *obj, Visitor *v,
> -                                     const char *name, void *opaque,
> -                                     Error **errp)
> -{
> -    XICSState *xics = XICS_COMMON(obj);
> -    int64_t value = xics->nr_servers;
> -
> -    visit_type_int(v, name, &value, errp);
> -}
> -
> -static void xics_prop_set_nr_servers(Object *obj, Visitor *v,
> -                                     const char *name, void *opaque,
> -                                     Error **errp)
> -{
> -    XICSState *xics = XICS_COMMON(obj);
> -    XICSStateClass *xsc = XICS_COMMON_GET_CLASS(xics);
> -    Error *error = NULL;
> -    int64_t value;
> -
> -    visit_type_int(v, name, &value, &error);
> -    if (error) {
> -        error_propagate(errp, error);
> -        return;
> -    }
> -    if (xics->nr_servers) {
> -        error_setg(errp, "Number of servers is already set to %u",
> -                   xics->nr_servers);
> -        return;
> -    }
> -
> -    assert(xsc->set_nr_servers);
> -    xsc->set_nr_servers(xics, value, errp);
> -}
> -
>  static void xics_common_initfn(Object *obj)
>  {
>      XICSState *xics = XICS_COMMON(obj);
>  
>      QLIST_INIT(&xics->ics);
> -    object_property_add(obj, "nr_servers", "int",
> -                        xics_prop_get_nr_servers, xics_prop_set_nr_servers,
> -                        NULL, NULL, NULL);
>  }
>  
>  static void xics_common_class_init(ObjectClass *oc, void *data)
> @@ -450,12 +394,30 @@ static void icp_reset(DeviceState *dev)
>      qemu_set_irq(icp->output, 0);
>  }
>  
> +static void icp_realize(DeviceState *dev, Error **errp)
> +{
> +    ICPState *icp = ICP(dev);
> +    Object *obj;
> +    Error *err = NULL;
> +
> +    obj = object_property_get_link(OBJECT(dev), "xics", &err);
> +    if (!obj) {
> +        error_setg(errp, "%s: required link 'xics' not found: %s",
> +                   __func__, error_get_pretty(err));
> +        return;
> +    }
> +
> +    icp->xics = XICS_COMMON(obj);
> +}
> +
> +
>  static void icp_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
>  
>      dc->reset = icp_reset;
>      dc->vmsd = &vmstate_icp_server;
> +    dc->realize = icp_realize;
>  }
>  
>  static const TypeInfo icp_info = {
> diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
> index 4a6c0522feb6..6cabc11f6be1 100644
> --- a/hw/intc/xics_kvm.c
> +++ b/hw/intc/xics_kvm.c
> @@ -368,12 +368,6 @@ static void xics_kvm_cpu_setup(XICSState *xics, PowerPCCPU *cpu)
>      ss->cap_irq_xics_enabled = true;
>  }
>  
> -static void xics_kvm_set_nr_servers(XICSState *xics, uint32_t nr_servers,
> -                                    Error **errp)
> -{
> -    xics_set_nr_servers(xics, nr_servers, TYPE_KVM_ICP, errp);
> -}
> -
>  static void rtas_dummy(PowerPCCPU *cpu, sPAPRMachineState *spapr,
>                         uint32_t token,
>                         uint32_t nargs, target_ulong args,
> @@ -386,9 +380,7 @@ static void rtas_dummy(PowerPCCPU *cpu, sPAPRMachineState *spapr,
>  static void xics_kvm_realize(DeviceState *dev, Error **errp)
>  {
>      KVMXICSState *xicskvm = XICS_SPAPR_KVM(dev);
> -    XICSState *xics = XICS_COMMON(dev);
> -    int i, rc;
> -    Error *error = NULL;
> +    int rc;
>      struct kvm_create_device xics_create_device = {
>          .type = KVM_DEV_TYPE_XICS,
>          .flags = 0,
> @@ -438,16 +430,6 @@ static void xics_kvm_realize(DeviceState *dev, Error **errp)
>  
>      xicskvm->kernel_xics_fd = xics_create_device.fd;
>  
> -    assert(xics->nr_servers);
> -    for (i = 0; i < xics->nr_servers; i++) {
> -        object_property_set_bool(OBJECT(&xics->ss[i]), true, "realized",
> -                                 &error);
> -        if (error) {
> -            error_propagate(errp, error);
> -            goto fail;
> -        }
> -    }
> -
>      kvm_kernel_irqchip = true;
>      kvm_msi_via_irqfd_allowed = true;
>      kvm_gsi_direct_mapping = true;
> @@ -468,7 +450,6 @@ static void xics_kvm_class_init(ObjectClass *oc, void *data)
>  
>      dc->realize = xics_kvm_realize;
>      xsc->cpu_setup = xics_kvm_cpu_setup;
> -    xsc->set_nr_servers = xics_kvm_set_nr_servers;
>  }
>  
>  static const TypeInfo xics_spapr_kvm_info = {
> diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
> index 03e42a866603..859b5675e175 100644
> --- a/hw/intc/xics_spapr.c
> +++ b/hw/intc/xics_spapr.c
> @@ -239,23 +239,8 @@ static void rtas_int_on(PowerPCCPU *cpu, sPAPRMachineState *spapr,
>      rtas_st(rets, 0, RTAS_OUT_SUCCESS);
>  }
>  
> -static void xics_spapr_set_nr_servers(XICSState *xics, uint32_t nr_servers,
> -                                      Error **errp)
> -{
> -    xics_set_nr_servers(xics, nr_servers, TYPE_ICP, errp);
> -}
> -
>  static void xics_spapr_realize(DeviceState *dev, Error **errp)
>  {
> -    XICSState *xics = XICS_SPAPR(dev);
> -    Error *error = NULL;
> -    int i;
> -
> -    if (!xics->nr_servers) {
> -        error_setg(errp, "Number of servers needs to be greater 0");
> -        return;
> -    }
> -
>      /* Registration of global state belongs into realize */
>      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);
> @@ -268,24 +253,13 @@ static void xics_spapr_realize(DeviceState *dev, Error **errp)
>      spapr_register_hypercall(H_XIRR_X, h_xirr_x);
>      spapr_register_hypercall(H_EOI, h_eoi);
>      spapr_register_hypercall(H_IPOLL, h_ipoll);
> -
> -    for (i = 0; i < xics->nr_servers; i++) {
> -        object_property_set_bool(OBJECT(&xics->ss[i]), true, "realized",
> -                                 &error);
> -        if (error) {
> -            error_propagate(errp, error);
> -            return;
> -        }
> -    }
>  }
>  
>  static void xics_spapr_class_init(ObjectClass *oc, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(oc);
> -    XICSStateClass *xsc = XICS_SPAPR_CLASS(oc);
>  
>      dc->realize = xics_spapr_realize;
> -    xsc->set_nr_servers = xics_spapr_set_nr_servers;
>  }
>  
>  static const TypeInfo xics_spapr_info = {
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 94b1e8e3227a..5d7c35de8cd9 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -96,17 +96,17 @@
>  #define HTAB_SIZE(spapr)        (1ULL << ((spapr)->htab_shift))
>  
>  static XICSState *try_create_xics(const char *type, const char *type_ics,
> -                                  int nr_servers, int nr_irqs, Error **errp)
> +                                  const char *type_icp, int nr_servers,
> +                                  int nr_irqs, Error **errp)
>  {
>      Error *err = NULL, *local_err = NULL;
>      XICSState *xics;
>      ICSState *ics = NULL;
> +    int i;
>  
>      xics = XICS_COMMON(object_new(type));
>      qdev_set_parent_bus(DEVICE(xics), sysbus_get_default());
> -    object_property_set_int(OBJECT(xics), nr_servers, "nr_servers", &err);
> -    object_property_set_bool(OBJECT(xics), true, "realized", &local_err);
> -    error_propagate(&err, local_err);
> +    object_property_set_bool(OBJECT(xics), true, "realized", &err);
>      if (err) {
>          goto error;
>      }
> @@ -122,6 +122,22 @@ static XICSState *try_create_xics(const char *type, const char *type_ics,
>      }
>      QLIST_INSERT_HEAD(&xics->ics, ics, list);
>  
> +    xics->ss = g_malloc0(nr_servers * sizeof(ICPState));
> +    xics->nr_servers = nr_servers;
> +
> +    for (i = 0; i < nr_servers; i++) {
> +        ICPState *icp = &xics->ss[i];
> +
> +        object_initialize(icp, sizeof(*icp), type_icp);
> +        object_property_add_child(OBJECT(xics), "icp[*]", OBJECT(icp), NULL);
> +        object_property_add_const_link(OBJECT(icp), "xics", OBJECT(xics), NULL);
> +        object_property_set_bool(OBJECT(icp), true, "realized", &err);
> +        if (err) {
> +            goto error;
> +        }
> +        object_unref(OBJECT(icp));
> +    }
> +
>      return xics;
>  
>  error:
> @@ -143,7 +159,7 @@ static XICSState *xics_system_init(MachineState *machine,
>  
>          if (machine_kernel_irqchip_allowed(machine)) {
>              xics = try_create_xics(TYPE_XICS_SPAPR_KVM, TYPE_ICS_KVM,
> -                                   nr_servers, nr_irqs, &err);
> +                                   TYPE_KVM_ICP, nr_servers, nr_irqs, &err);
>          }
>          if (machine_kernel_irqchip_required(machine) && !xics) {
>              error_reportf_err(err,
> @@ -154,8 +170,8 @@ static XICSState *xics_system_init(MachineState *machine,
>      }
>  
>      if (!xics) {
> -        xics = try_create_xics(TYPE_XICS_SPAPR, TYPE_ICS_SIMPLE, nr_servers,
> -                               nr_irqs, errp);
> +        xics = try_create_xics(TYPE_XICS_SPAPR, TYPE_ICS_SIMPLE, TYPE_ICP,
> +                               nr_servers, nr_irqs, errp);
>      }
>  
>      return xics;
> diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
> index 8fe3c4d2ceab..fc4abcd4e796 100644
> --- a/include/hw/ppc/xics.h
> +++ b/include/hw/ppc/xics.h
> @@ -74,7 +74,6 @@ struct XICSStateClass {
>      DeviceClass parent_class;
>  
>      void (*cpu_setup)(XICSState *icp, PowerPCCPU *cpu);
> -    void (*set_nr_servers)(XICSState *icp, uint32_t nr_servers, Error **errp);
>  };
>  
>  struct XICSState {
> @@ -189,8 +188,6 @@ void spapr_dt_xics(XICSState *xics, void *fdt, uint32_t phandle);
>  
>  void xics_cpu_setup(XICSState *icp, PowerPCCPU *cpu);
>  void xics_cpu_destroy(XICSState *icp, PowerPCCPU *cpu);
> -void xics_set_nr_servers(XICSState *xics, uint32_t nr_servers,
> -                         const char *typename, Error **errp);
>  
>  /* Internal XICS interfaces */
>  int xics_get_cpu_index_by_dt_id(int cpu_dt_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: 819 bytes --]

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

* Re: [Qemu-devel] [PATCH v2 03/22] ppc/xics: store the ICS object under the sPAPR machine
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 03/22] ppc/xics: store the ICS object under the sPAPR machine Cédric Le Goater
@ 2017-02-22  6:59   ` David Gibson
  2017-02-24 10:47     ` Cédric Le Goater
  0 siblings, 1 reply; 59+ messages in thread
From: David Gibson @ 2017-02-22  6:59 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Thu, Feb 16, 2017 at 02:47:26PM +0100, Cédric Le Goater wrote:
> A list of ICS objects was introduced under the XICS object for the
> PowerNV machine, but, for the sPAPR machine, it brings extra complexity
> as there is only a single ICS. To simplify the code, let's add the ICS
> pointer under the sPAPR machine and try to reduce the use of this list
> where possible.
> 
> Also, change the xics_spapr_*() routines to use an ICS object instead
> of an XICSState and change their name to reflect that these are
> specific to the sPAPR ICS object.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Looks good apart from a minor point noted below.

> ---
>  hw/intc/xics_spapr.c   | 22 +++++++++-------------
>  hw/ppc/spapr.c         | 29 ++++++++++++++++-------------
>  hw/ppc/spapr_events.c  |  4 ++--
>  hw/ppc/spapr_pci.c     |  8 ++++----
>  hw/ppc/spapr_vio.c     |  2 +-
>  include/hw/ppc/spapr.h |  1 +
>  include/hw/ppc/xics.h  |  6 +++---
>  7 files changed, 36 insertions(+), 36 deletions(-)
> 
> diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
> index 859b5675e175..1501e796e5e0 100644
> --- a/hw/intc/xics_spapr.c
> +++ b/hw/intc/xics_spapr.c
> @@ -118,7 +118,7 @@ static void rtas_set_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr,
>                            uint32_t nargs, target_ulong args,
>                            uint32_t nret, target_ulong rets)
>  {
> -    ICSState *ics = QLIST_FIRST(&spapr->xics->ics);
> +    ICSState *ics = spapr->ics;
>      uint32_t nr, srcno, server, priority;
>  
>      if ((nargs != 3) || (nret != 1)) {
> @@ -151,7 +151,7 @@ static void rtas_get_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr,
>                            uint32_t nargs, target_ulong args,
>                            uint32_t nret, target_ulong rets)
>  {
> -    ICSState *ics = QLIST_FIRST(&spapr->xics->ics);
> +    ICSState *ics = spapr->ics;
>      uint32_t nr, srcno;
>  
>      if ((nargs != 1) || (nret != 3)) {
> @@ -181,7 +181,7 @@ static void rtas_int_off(PowerPCCPU *cpu, sPAPRMachineState *spapr,
>                           uint32_t nargs, target_ulong args,
>                           uint32_t nret, target_ulong rets)
>  {
> -    ICSState *ics = QLIST_FIRST(&spapr->xics->ics);
> +    ICSState *ics = spapr->ics;
>      uint32_t nr, srcno;
>  
>      if ((nargs != 1) || (nret != 1)) {
> @@ -212,7 +212,7 @@ static void rtas_int_on(PowerPCCPU *cpu, sPAPRMachineState *spapr,
>                          uint32_t nargs, target_ulong args,
>                          uint32_t nret, target_ulong rets)
>  {
> -    ICSState *ics = QLIST_FIRST(&spapr->xics->ics);
> +    ICSState *ics = spapr->ics;
>      uint32_t nr, srcno;
>  
>      if ((nargs != 1) || (nret != 1)) {
> @@ -294,9 +294,8 @@ static int ics_find_free_block(ICSState *ics, int num, int alignnum)
>      return -1;
>  }
>  
> -int xics_spapr_alloc(XICSState *xics, int irq_hint, bool lsi, Error **errp)
> +int spapr_ics_alloc(ICSState *ics, int irq_hint, bool lsi, Error **errp)
>  {
> -    ICSState *ics = QLIST_FIRST(&xics->ics);
>      int irq;
>  
>      if (!ics) {
> @@ -327,10 +326,9 @@ int xics_spapr_alloc(XICSState *xics, int irq_hint, bool lsi, Error **errp)
>   * Allocate block of consecutive IRQs, and return the number of the first IRQ in
>   * the block. If align==true, aligns the first IRQ number to num.
>   */
> -int xics_spapr_alloc_block(XICSState *xics, int num, bool lsi, bool align,
> -                           Error **errp)
> +int spapr_ics_alloc_block(ICSState *ics, int num, bool lsi,
> +                          bool align, Error **errp)
>  {
> -    ICSState *ics = QLIST_FIRST(&xics->ics);
>      int i, first = -1;
>  
>      if (!ics) {
> @@ -380,11 +378,9 @@ static void ics_free(ICSState *ics, int srcno, int num)
>      }
>  }
>  
> -void xics_spapr_free(XICSState *xics, int irq, int num)
> +void spapr_ics_free(ICSState *ics, int irq, int num)
>  {
> -    ICSState *ics = xics_find_source(xics, irq);
> -
> -    if (ics) {
> +    if (ics_valid_irq(ics, irq)) {
>          trace_xics_ics_free(0, irq, num);
>          ics_free(ics, irq - ics->offset, num);
>      }
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 5d7c35de8cd9..045f2323a4e9 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -95,13 +95,13 @@
>  
>  #define HTAB_SIZE(spapr)        (1ULL << ((spapr)->htab_shift))
>  
> -static XICSState *try_create_xics(const char *type, const char *type_ics,
> +static XICSState *try_create_xics(sPAPRMachineState *spapr,
> +                                  const char *type, const char *type_ics,
>                                    const char *type_icp, int nr_servers,
>                                    int nr_irqs, Error **errp)
>  {
>      Error *err = NULL, *local_err = NULL;
>      XICSState *xics;
> -    ICSState *ics = NULL;

I'd prefer to keep this local and just update spapr->ics at the end of
the function.  It won't really make a difference, since if the xics
doesn't initialize nothing will work, but currently if this fails it
could leave spapr->ics with a bogus but non-NULL pointer, which isn't
good practice.

>      int i;
>  
>      xics = XICS_COMMON(object_new(type));
> @@ -111,16 +111,17 @@ static XICSState *try_create_xics(const char *type, const char *type_ics,
>          goto error;
>      }
>  
> -    ics = ICS_SIMPLE(object_new(type_ics));
> -    object_property_add_child(OBJECT(xics), "ics", OBJECT(ics), NULL);
> -    object_property_set_int(OBJECT(ics), nr_irqs, "nr-irqs", &err);
> -    object_property_add_const_link(OBJECT(ics), "xics", OBJECT(xics), NULL);
> -    object_property_set_bool(OBJECT(ics), true, "realized", &local_err);
> +    spapr->ics = ICS_SIMPLE(object_new(type_ics));
> +    object_property_add_child(OBJECT(spapr), "ics", OBJECT(spapr->ics), NULL);
> +    object_property_set_int(OBJECT(spapr->ics), nr_irqs, "nr-irqs", &err);
> +    object_property_add_const_link(OBJECT(spapr->ics), "xics", OBJECT(xics),
> +                                   NULL);
> +    object_property_set_bool(OBJECT(spapr->ics), true, "realized", &local_err);
>      error_propagate(&err, local_err);
>      if (err) {
>          goto error;
>      }
> -    QLIST_INSERT_HEAD(&xics->ics, ics, list);
> +    QLIST_INSERT_HEAD(&xics->ics, spapr->ics, list);
>  
>      xics->ss = g_malloc0(nr_servers * sizeof(ICPState));
>      xics->nr_servers = nr_servers;
> @@ -142,8 +143,8 @@ static XICSState *try_create_xics(const char *type, const char *type_ics,
>  
>  error:
>      error_propagate(errp, err);
> -    if (ics) {
> -        object_unparent(OBJECT(ics));
> +    if (spapr->ics) {
> +        object_unparent(OBJECT(spapr->ics));
>      }
>      object_unparent(OBJECT(xics));
>      return NULL;
> @@ -158,7 +159,8 @@ static XICSState *xics_system_init(MachineState *machine,
>          Error *err = NULL;
>  
>          if (machine_kernel_irqchip_allowed(machine)) {
> -            xics = try_create_xics(TYPE_XICS_SPAPR_KVM, TYPE_ICS_KVM,
> +            xics = try_create_xics(SPAPR_MACHINE(machine),
> +                                   TYPE_XICS_SPAPR_KVM, TYPE_ICS_KVM,
>                                     TYPE_KVM_ICP, nr_servers, nr_irqs, &err);
>          }
>          if (machine_kernel_irqchip_required(machine) && !xics) {
> @@ -170,8 +172,9 @@ static XICSState *xics_system_init(MachineState *machine,
>      }
>  
>      if (!xics) {
> -        xics = try_create_xics(TYPE_XICS_SPAPR, TYPE_ICS_SIMPLE, TYPE_ICP,
> -                               nr_servers, nr_irqs, errp);
> +        xics = try_create_xics(SPAPR_MACHINE(machine),
> +                               TYPE_XICS_SPAPR, TYPE_ICS_SIMPLE,
> +                               TYPE_ICP, nr_servers, nr_irqs, errp);
>      }
>  
>      return xics;
> diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
> index f85a9c32a7fc..38b4258a9be7 100644
> --- a/hw/ppc/spapr_events.c
> +++ b/hw/ppc/spapr_events.c
> @@ -752,7 +752,7 @@ void spapr_events_init(sPAPRMachineState *spapr)
>      spapr->event_sources = spapr_event_sources_new();
>  
>      spapr_event_sources_register(spapr->event_sources, EVENT_CLASS_EPOW,
> -                                 xics_spapr_alloc(spapr->xics, 0, false,
> +                                 spapr_ics_alloc(spapr->ics, 0, false,
>                                                    &error_fatal));
>  
>      /* NOTE: if machine supports modern/dedicated hotplug event source,
> @@ -765,7 +765,7 @@ void spapr_events_init(sPAPRMachineState *spapr)
>       */
>      if (spapr->use_hotplug_event_source) {
>          spapr_event_sources_register(spapr->event_sources, EVENT_CLASS_HOT_PLUG,
> -                                     xics_spapr_alloc(spapr->xics, 0, false,
> +                                     spapr_ics_alloc(spapr->ics, 0, false,
>                                                        &error_fatal));
>      }
>  
> diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
> index fd6fc1d95344..01d5c92425ed 100644
> --- a/hw/ppc/spapr_pci.c
> +++ b/hw/ppc/spapr_pci.c
> @@ -325,7 +325,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
>              return;
>          }
>  
> -        xics_spapr_free(spapr->xics, msi->first_irq, msi->num);
> +        spapr_ics_free(spapr->ics, msi->first_irq, msi->num);
>          if (msi_present(pdev)) {
>              spapr_msi_setmsg(pdev, 0, false, 0, 0);
>          }
> @@ -363,7 +363,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
>      }
>  
>      /* Allocate MSIs */
> -    irq = xics_spapr_alloc_block(spapr->xics, req_num, false,
> +    irq = spapr_ics_alloc_block(spapr->ics, req_num, false,
>                             ret_intr_type == RTAS_TYPE_MSI, &err);
>      if (err) {
>          error_reportf_err(err, "Can't allocate MSIs for device %x: ",
> @@ -374,7 +374,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
>  
>      /* Release previous MSIs */
>      if (msi) {
> -        xics_spapr_free(spapr->xics, msi->first_irq, msi->num);
> +        spapr_ics_free(spapr->ics, msi->first_irq, msi->num);
>          g_hash_table_remove(phb->msi, &config_addr);
>      }
>  
> @@ -1485,7 +1485,7 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
>          uint32_t irq;
>          Error *local_err = NULL;
>  
> -        irq = xics_spapr_alloc_block(spapr->xics, 1, true, false, &local_err);
> +        irq = spapr_ics_alloc_block(spapr->ics, 1, true, false, &local_err);
>          if (local_err) {
>              error_propagate(errp, local_err);
>              error_prepend(errp, "can't allocate LSIs: ");
> diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c
> index 8bfc5f971f8e..a0ee4fd26586 100644
> --- a/hw/ppc/spapr_vio.c
> +++ b/hw/ppc/spapr_vio.c
> @@ -454,7 +454,7 @@ static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp)
>          dev->qdev.id = id;
>      }
>  
> -    dev->irq = xics_spapr_alloc(spapr->xics, dev->irq, false, &local_err);
> +    dev->irq = spapr_ics_alloc(spapr->ics, dev->irq, false, &local_err);
>      if (local_err) {
>          error_propagate(errp, local_err);
>          return;
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index f9b17d860a75..21e506b13cfa 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -59,6 +59,7 @@ struct sPAPRMachineState {
>      QLIST_HEAD(, sPAPRPHBState) phbs;
>      struct sPAPRNVRAM *nvram;
>      XICSState *xics;
> +    ICSState *ics;
>      DeviceState *rtc;
>  
>      void *htab;
> diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
> index fc4abcd4e796..6d443ce09dba 100644
> --- a/include/hw/ppc/xics.h
> +++ b/include/hw/ppc/xics.h
> @@ -180,10 +180,10 @@ struct ICSIRQState {
>  #define XICS_IRQS_SPAPR               1024
>  
>  qemu_irq xics_get_qirq(XICSState *icp, int irq);
> -int xics_spapr_alloc(XICSState *icp, int irq_hint, bool lsi, Error **errp);
> -int xics_spapr_alloc_block(XICSState *icp, int num, bool lsi, bool align,
> +int spapr_ics_alloc(ICSState *ics, int irq_hint, bool lsi, Error **errp);
> +int spapr_ics_alloc_block(ICSState *ics, int num, bool lsi, bool align,
>                             Error **errp);
> -void xics_spapr_free(XICSState *icp, int irq, int num);
> +void spapr_ics_free(ICSState *ics, int irq, int num);
>  void spapr_dt_xics(XICSState *xics, void *fdt, uint32_t phandle);
>  
>  void xics_cpu_setup(XICSState *icp, PowerPCCPU *cpu);

-- 
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: 819 bytes --]

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

* Re: [Qemu-devel] [PATCH v2 00/22] ppc/xics: simplify ICS and ICP creation
  2017-02-22  3:34 ` [Qemu-devel] [PATCH v2 00/22] ppc/xics: simplify ICS and ICP creation David Gibson
@ 2017-02-22 10:55   ` Cédric Le Goater
  2017-02-23  3:07     ` David Gibson
  0 siblings, 1 reply; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-22 10:55 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel

On 02/22/2017 04:34 AM, David Gibson wrote:
> On Thu, Feb 16, 2017 at 02:47:23PM +0100, Cédric Le Goater wrote:
>> Hello,
>>
>> The goal behind this series is to simplify the XICS interface by
>> moving back in the machine the way the ICS and ICP objects interact
>> together. It's up to the machine to implement this "fabric" logic by
>> providing a set of handlers of a QOM interface. These handlers are
>> used to grab an ICS or an ICP object and also do irq resends. This
>> idea was suggested by David Gibson.
>>
>> The patchset is organised as follow. It starts with a preliminary
>> cleanup to get rid of the set_nr_irqs() and set_nr_servers()
>> handlers. It also moves the creation of the ICS and ICP objects from
>> the XICS object to the sPAPR machine. This simplifies the code
>> significantly and prepares ground for future changes.
>>
>> As the sPAPR machine only makes use of a single ICS, we can store it
>> at the machine level. This lets us remove dependencies on the list of
>> ICS of the XICS object and simplify even more the code for the
>> following changes.
>>
>> The QOM interface to interact with the ICS and ICP objects is then
>> introduced. These are moved under the machine and cleanups are done
>> accordingly.
>>
>> Finally, the XICSState classes are removed as they have been
>> deprecated by the QOM interface.
>>
>>
>> After the initial cleanups, which are rather big, I have tried to keep
>> the each patch small enough to ease the review and to spot any
>> problem. Each should be bisectable. The tree is available here :
>>
>> 	   https://github.com/legoater/qemu/tree/ppc-2.9
> 
> So, after you posted this, I discover the patch I sent the other day -
> changing XICS away from a SysBusDevice breaks the postcopy migration
> test on KVM.  I haven't had a chance to debug this yet, so for the
> time being I've pulled my patch from ppc-for-2.9.  I've moved it into
> a new 'xics-cleanup' branch.

It is even worse than that, the kernel does not start. This is because
the ICS and ICP objects are not reseted  anymore and so the mfrr and
irq priority values are incorrect : 0x0 instead of 0xFF. 

Before that patch, the reset was implicit because the device was a 
SysBusDevice and all the devices were reseted when the bus was.  

Other devices (not on a bus or/and QOM objects) need to register on 
SysBus to be reseted :
  
	qdev_set_parent_bus(dev, sysbus_get_default());

or use a handler for :

	qemu_register_reset()

which will be called by qemu_devices_reset()

I fell into this trap a few times with PowerNV and I should have 
spotted it before adding my Reviewed-by. Sorry about that.


So, to move on, we can use the fix below (You can merge it in your 
patch). I also updated my branch with it : 

	https://github.com/legoater/qemu/commits/ppc-2.9

I have checked that KVM and TCG migration still worked with the 
patchset and also rebased PowerNV on it. All seem to work. Tell
me if you want a resend. The patchset needs some review any how 
and there should be some comment to address so it might be a bit 
too early for a resend. 



FYI, the xics-cleanup branch has some issue with migration :

qemu-system-ppc64: VQ 0 size 0x80 < last_avail_idx 0x9f9 - used_idx 0x0
qemu-system-ppc64: Failed to load virtio-blk:virtio
qemu-system-ppc64: error while loading state for instance 0x0 of device 'pci@800000020000000:01.0/virtio-blk'

This is most probably a temporary regression, unrelated to XICS 
though. 
 
Thanks,

C.

>From f01dd87954b818096e4fb8c85265ea71a0075975 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= <clg@kaod.org>
Date: Wed, 22 Feb 2017 10:50:25 +0100
Subject: [PATCH] ppc/xics: fix ICP and ICS reset
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

commit 5b17c7207938 ("xics: XICS should not be a SysBusDevice")
changed the nature of the XICS object to be a descendent of
TYPE_DEVICE. By doing so, the object is not on a bus and its reset
handler is not called anymore. The direct consequence is that the ICP
and ICS objects are not correctly initialized and so the IRQ subsystem
is broken in the guest.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/ppc/spapr.c        | 1 +
 include/hw/ppc/xics.h | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 8af54494f166..fa6a2947c791 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -104,6 +104,7 @@ static XICSState *try_create_xics(const char *type, int nr_servers,
     dev = DEVICE(object_new(type));
     qdev_prop_set_uint32(dev, "nr_servers", nr_servers);
     qdev_prop_set_uint32(dev, "nr_irqs", nr_irqs);
+    qdev_set_parent_bus(dev, sysbus_get_default());
     object_property_set_bool(OBJECT(dev), true, "realized", &err);
     if (err) {
         error_propagate(errp, err);
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index 3f0c31610aa4..1aefd3d52257 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -80,7 +80,7 @@ struct XICSStateClass {
 
 struct XICSState {
     /*< private >*/
-    SysBusDevice parent_obj;
+    DeviceState parent_obj;
     /*< public >*/
     uint32_t nr_servers;
     uint32_t nr_irqs;
-- 
2.7.4

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

* Re: [Qemu-devel] [PATCH v2 04/22] ppc/xics: add an InterruptStatsProvider interface to ICS and ICP objects
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 04/22] ppc/xics: add an InterruptStatsProvider interface to ICS and ICP objects Cédric Le Goater
@ 2017-02-23  2:15   ` David Gibson
  2017-02-24 10:52     ` [Qemu-devel] [Qemu-ppc] " Cédric Le Goater
  0 siblings, 1 reply; 59+ messages in thread
From: David Gibson @ 2017-02-23  2:15 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Thu, Feb 16, 2017 at 02:47:27PM +0100, Cédric Le Goater wrote:
> This is, again, to reduce the use of the list of ICS objects. Let's
> make each individual ICS and ICP object an InterruptStatsProvider and
> remove this same interface from XICSState.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

I'm a little hesitant about this, because it means that getting the
interrupt stats information is now spread out over the qom tree,
whereas previously there was a single location to get a good summary
of the systems overall interrupt status.  The previous behaviour seems
like it would be more convenient for debugging.

That said, I see the structural advantages of this split.  Hmm.. still
thinking..

> ---
>  hw/intc/xics.c | 76 +++++++++++++++++++++++++++++++---------------------------
>  1 file changed, 41 insertions(+), 35 deletions(-)
> 
> diff --git a/hw/intc/xics.c b/hw/intc/xics.c
> index 9f22814815c9..b1294417a0ae 100644
> --- a/hw/intc/xics.c
> +++ b/hw/intc/xics.c
> @@ -92,44 +92,44 @@ void xics_cpu_setup(XICSState *xics, PowerPCCPU *cpu)
>      }
>  }
>  
> -static void xics_common_pic_print_info(InterruptStatsProvider *obj,
> -                                       Monitor *mon)
> +static void icp_pic_print_info(InterruptStatsProvider *obj,
> +                           Monitor *mon)
>  {
> -    XICSState *xics = XICS_COMMON(obj);
> -    ICSState *ics;
> +    ICPState *icp = ICP(obj);
> +    int cpu_index = icp->cs ? icp->cs->cpu_index : -1;
> +
> +    if (!icp->output) {
> +        return;
> +    }
> +    monitor_printf(mon, "CPU %d XIRR=%08x (%p) PP=%02x MFRR=%02x\n",
> +                   cpu_index, icp->xirr, icp->xirr_owner,
> +                   icp->pending_priority, icp->mfrr);
> +}
> +
> +static void ics_simple_pic_print_info(InterruptStatsProvider *obj,
> +                                      Monitor *mon)
> +{
> +    ICSState *ics = ICS_SIMPLE(obj);
>      uint32_t i;
>  
> -    for (i = 0; i < xics->nr_servers; i++) {
> -        ICPState *icp = &xics->ss[i];
> +    monitor_printf(mon, "ICS %4x..%4x %p\n",
> +                   ics->offset, ics->offset + ics->nr_irqs - 1, ics);
>  
> -        if (!icp->output) {
> -            continue;
> -        }
> -        monitor_printf(mon, "CPU %d XIRR=%08x (%p) PP=%02x MFRR=%02x\n",
> -                       i, icp->xirr, icp->xirr_owner,
> -                       icp->pending_priority, icp->mfrr);
> +    if (!ics->irqs) {
> +        return;
>      }
>  
> -    QLIST_FOREACH(ics, &xics->ics, list) {
> -        monitor_printf(mon, "ICS %4x..%4x %p\n",
> -                       ics->offset, ics->offset + ics->nr_irqs - 1, ics);
> +    for (i = 0; i < ics->nr_irqs; i++) {
> +        ICSIRQState *irq = ics->irqs + i;
>  
> -        if (!ics->irqs) {
> +        if (!(irq->flags & XICS_FLAGS_IRQ_MASK)) {
>              continue;
>          }
> -
> -        for (i = 0; i < ics->nr_irqs; i++) {
> -            ICSIRQState *irq = ics->irqs + i;
> -
> -            if (!(irq->flags & XICS_FLAGS_IRQ_MASK)) {
> -                continue;
> -            }
> -            monitor_printf(mon, "  %4x %s %02x %02x\n",
> -                           ics->offset + i,
> -                           (irq->flags & XICS_FLAGS_IRQ_LSI) ?
> -                           "LSI" : "MSI",
> -                           irq->priority, irq->status);
> -        }
> +        monitor_printf(mon, "  %4x %s %02x %02x\n",
> +                       ics->offset + i,
> +                       (irq->flags & XICS_FLAGS_IRQ_LSI) ?
> +                       "LSI" : "MSI",
> +                       irq->priority, irq->status);
>      }
>  }
>  
> @@ -161,10 +161,8 @@ static void xics_common_initfn(Object *obj)
>  static void xics_common_class_init(ObjectClass *oc, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(oc);
> -    InterruptStatsProviderClass *ic = INTERRUPT_STATS_PROVIDER_CLASS(oc);
>  
>      dc->reset = xics_common_reset;
> -    ic->print_info = xics_common_pic_print_info;
>  }
>  
>  static const TypeInfo xics_common_info = {
> @@ -174,10 +172,6 @@ static const TypeInfo xics_common_info = {
>      .class_size    = sizeof(XICSStateClass),
>      .instance_init = xics_common_initfn,
>      .class_init    = xics_common_class_init,
> -    .interfaces = (InterfaceInfo[]) {
> -        { TYPE_INTERRUPT_STATS_PROVIDER },
> -        { }
> -    },
>  };
>  
>  /*
> @@ -414,10 +408,12 @@ static void icp_realize(DeviceState *dev, Error **errp)
>  static void icp_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
> +    InterruptStatsProviderClass *ic = INTERRUPT_STATS_PROVIDER_CLASS(klass);
>  
>      dc->reset = icp_reset;
>      dc->vmsd = &vmstate_icp_server;
>      dc->realize = icp_realize;
> +    ic->print_info = icp_pic_print_info;
>  }
>  
>  static const TypeInfo icp_info = {
> @@ -426,6 +422,10 @@ static const TypeInfo icp_info = {
>      .instance_size = sizeof(ICPState),
>      .class_init = icp_class_init,
>      .class_size = sizeof(ICPStateClass),
> +    .interfaces = (InterfaceInfo[]) {
> +        { TYPE_INTERRUPT_STATS_PROVIDER },
> +        { }
> +    },
>  };
>  
>  /*
> @@ -692,6 +692,7 @@ static void ics_simple_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
>      ICSStateClass *isc = ICS_BASE_CLASS(klass);
> +    InterruptStatsProviderClass *ic = INTERRUPT_STATS_PROVIDER_CLASS(klass);
>  
>      dc->realize = ics_simple_realize;
>      dc->props = ics_simple_properties;
> @@ -701,6 +702,7 @@ static void ics_simple_class_init(ObjectClass *klass, void *data)
>      isc->reject = ics_simple_reject;
>      isc->resend = ics_simple_resend;
>      isc->eoi = ics_simple_eoi;
> +    ic->print_info = ics_simple_pic_print_info;
>  }
>  
>  static const TypeInfo ics_simple_info = {
> @@ -710,6 +712,10 @@ static const TypeInfo ics_simple_info = {
>      .class_init = ics_simple_class_init,
>      .class_size = sizeof(ICSStateClass),
>      .instance_init = ics_simple_initfn,
> +    .interfaces = (InterfaceInfo[]) {
> +        { TYPE_INTERRUPT_STATS_PROVIDER },
> +        { }
> +    },
>  };
>  
>  static const TypeInfo ics_base_info = {

-- 
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: 819 bytes --]

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

* Re: [Qemu-devel] [PATCH v2 05/22] ppc/xics: introduce a QOM interface to handle ICSs
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 05/22] ppc/xics: introduce a QOM interface to handle ICSs Cédric Le Goater
@ 2017-02-23  2:18   ` David Gibson
  2017-02-24 10:55     ` Cédric Le Goater
  0 siblings, 1 reply; 59+ messages in thread
From: David Gibson @ 2017-02-23  2:18 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Thu, Feb 16, 2017 at 02:47:28PM +0100, Cédric Le Goater wrote:
> This QOM interface provides two simple handlers. One is to get an ICS
> object from an irq number and a second to resend the irqs when needed.

Maybe call this XICSFabric rather than XicsInterface.  While it's an
interface from the QOM point-of-view, that doesn't really describe
where it sits in the hardware model, and it's the ics and icp objects
which provide all the interfaces which are visible to the guest or to
interrupt generating devices.

Apart from that,

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

> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
>  hw/intc/xics.c        |  7 +++++++
>  include/hw/ppc/xics.h | 18 ++++++++++++++++++
>  2 files changed, 25 insertions(+)
> 
> diff --git a/hw/intc/xics.c b/hw/intc/xics.c
> index b1294417a0ae..3e80d2d0f0d9 100644
> --- a/hw/intc/xics.c
> +++ b/hw/intc/xics.c
> @@ -726,6 +726,12 @@ static const TypeInfo ics_base_info = {
>      .class_size = sizeof(ICSStateClass),
>  };
>  
> +static const TypeInfo xics_interface_info = {
> +    .name = TYPE_XICS_INTERFACE,
> +    .parent = TYPE_INTERFACE,
> +    .class_size = sizeof(XICSInterfaceClass),
> +};
> +
>  /*
>   * Exported functions
>   */
> @@ -766,6 +772,7 @@ static void xics_register_types(void)
>      type_register_static(&ics_simple_info);
>      type_register_static(&ics_base_info);
>      type_register_static(&icp_info);
> +    type_register_static(&xics_interface_info);
>  }
>  
>  type_init(xics_register_types)
> diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
> index 6d443ce09dba..fe2bb5c8ef54 100644
> --- a/include/hw/ppc/xics.h
> +++ b/include/hw/ppc/xics.h
> @@ -177,6 +177,24 @@ struct ICSIRQState {
>      uint8_t flags;
>  };
>  
> +typedef struct XICSInterface {
> +    Object parent;
> +} XICSInterface;
> +
> +#define TYPE_XICS_INTERFACE "xics-interface"
> +#define XICS_INTERFACE(obj)                                     \
> +    OBJECT_CHECK(XICSInterface, (obj), TYPE_XICS_INTERFACE)
> +#define XICS_INTERFACE_CLASS(klass)                                     \
> +    OBJECT_CLASS_CHECK(XICSInterfaceClass, (klass), TYPE_XICS_INTERFACE)
> +#define XICS_INTERFACE_GET_CLASS(obj)                                   \
> +    OBJECT_GET_CLASS(XICSInterfaceClass, (obj), TYPE_XICS_INTERFACE)
> +
> +typedef struct XICSInterfaceClass {
> +    InterfaceClass parent;
> +    ICSState *(*ics_get)(XICSInterface *xi, int irq);
> +    void (*ics_resend)(XICSInterface *xi);
> +} XICSInterfaceClass;
> +
>  #define XICS_IRQS_SPAPR               1024
>  
>  qemu_irq xics_get_qirq(XICSState *icp, int 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: 819 bytes --]

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

* Re: [Qemu-devel] [PATCH v2 06/22] ppc/xics: use the QOM interface under the sPAPR machine
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 06/22] ppc/xics: use the QOM interface under the sPAPR machine Cédric Le Goater
@ 2017-02-23  2:21   ` David Gibson
  0 siblings, 0 replies; 59+ messages in thread
From: David Gibson @ 2017-02-23  2:21 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Thu, Feb 16, 2017 at 02:47:29PM +0100, Cédric Le Goater wrote:
> Add 'ics_get' and 'ics_resend' handlers to the sPAPR machine. These
> are relatively simple for a single ICS.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

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

> ---
>  hw/intc/xics.c        |  2 +-
>  hw/ppc/spapr.c        | 18 ++++++++++++++++++
>  include/hw/ppc/xics.h |  1 +
>  3 files changed, 20 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/intc/xics.c b/hw/intc/xics.c
> index 3e80d2d0f0d9..39c442f70116 100644
> --- a/hw/intc/xics.c
> +++ b/hw/intc/xics.c
> @@ -193,7 +193,7 @@ static void ics_reject(ICSState *ics, uint32_t nr)
>      }
>  }
>  
> -static void ics_resend(ICSState *ics)
> +void ics_resend(ICSState *ics)
>  {
>      ICSStateClass *k = ICS_BASE_GET_CLASS(ics);
>  
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 045f2323a4e9..85a973cce7ae 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -2901,6 +2901,20 @@ static void spapr_phb_placement(sPAPRMachineState *spapr, uint32_t index,
>      *mmio64 = SPAPR_PCI_BASE + (index + 1) * SPAPR_PCI_MEM64_WIN_SIZE;
>  }
>  
> +static ICSState *spapr_ics_get(XICSInterface *dev, int irq)
> +{
> +    sPAPRMachineState *spapr = SPAPR_MACHINE(dev);
> +
> +    return ics_valid_irq(spapr->ics, irq) ? spapr->ics : NULL;
> +}
> +
> +static void spapr_ics_resend(XICSInterface *dev)
> +{
> +    sPAPRMachineState *spapr = SPAPR_MACHINE(dev);
> +
> +    ics_resend(spapr->ics);
> +}
> +
>  static void spapr_machine_class_init(ObjectClass *oc, void *data)
>  {
>      MachineClass *mc = MACHINE_CLASS(oc);
> @@ -2909,6 +2923,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
>      NMIClass *nc = NMI_CLASS(oc);
>      HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
>      PPCVirtualHypervisorClass *vhc = PPC_VIRTUAL_HYPERVISOR_CLASS(oc);
> +    XICSInterfaceClass *xic = XICS_INTERFACE_CLASS(oc);
>  
>      mc->desc = "pSeries Logical Partition (PAPR compliant)";
>  
> @@ -2942,6 +2957,8 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
>      nc->nmi_monitor_handler = spapr_nmi;
>      smc->phb_placement = spapr_phb_placement;
>      vhc->hypercall = emulate_spapr_hypercall;
> +    xic->ics_get = spapr_ics_get;
> +    xic->ics_resend = spapr_ics_resend;
>  }
>  
>  static const TypeInfo spapr_machine_info = {
> @@ -2958,6 +2975,7 @@ static const TypeInfo spapr_machine_info = {
>          { TYPE_NMI },
>          { TYPE_HOTPLUG_HANDLER },
>          { TYPE_PPC_VIRTUAL_HYPERVISOR },
> +        { TYPE_XICS_INTERFACE },
>          { }
>      },
>  };
> diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
> index fe2bb5c8ef54..640603b3d76d 100644
> --- a/include/hw/ppc/xics.h
> +++ b/include/hw/ppc/xics.h
> @@ -222,5 +222,6 @@ void ics_simple_write_xive(ICSState *ics, int nr, int server,
>  void ics_set_irq_type(ICSState *ics, int srcno, bool lsi);
>  
>  ICSState *xics_find_source(XICSState *icp, int irq);
> +void ics_resend(ICSState *ics);
>  
>  #endif /* XICS_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: 819 bytes --]

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

* Re: [Qemu-devel] [PATCH v2 07/22] ppc/xics: use the QOM interface to get irqs
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 07/22] ppc/xics: use the QOM interface to get irqs Cédric Le Goater
@ 2017-02-23  2:25   ` David Gibson
  0 siblings, 0 replies; 59+ messages in thread
From: David Gibson @ 2017-02-23  2:25 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Thu, Feb 16, 2017 at 02:47:30PM +0100, Cédric Le Goater wrote:
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

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

> ---
>  hw/intc/xics.c              | 5 +++--
>  hw/ppc/spapr_events.c       | 6 +++---
>  hw/ppc/spapr_pci.c          | 2 +-
>  include/hw/pci-host/spapr.h | 2 +-
>  include/hw/ppc/spapr_vio.h  | 2 +-
>  include/hw/ppc/xics.h       | 3 ++-
>  6 files changed, 11 insertions(+), 9 deletions(-)
> 
> diff --git a/hw/intc/xics.c b/hw/intc/xics.c
> index 39c442f70116..0ffdf09c5304 100644
> --- a/hw/intc/xics.c
> +++ b/hw/intc/xics.c
> @@ -747,9 +747,10 @@ ICSState *xics_find_source(XICSState *xics, int irq)
>      return NULL;
>  }
>  
> -qemu_irq xics_get_qirq(XICSState *xics, int irq)
> +qemu_irq xics_get_qirq(XICSInterface *xi, int irq)
>  {
> -    ICSState *ics = xics_find_source(xics, irq);
> +    XICSInterfaceClass *xic = XICS_INTERFACE_GET_CLASS(xi);
> +    ICSState *ics = xic->ics_get(xi, irq);
>  
>      if (ics) {
>          return ics->qirqs[irq - ics->offset];
> diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
> index 38b4258a9be7..aa627dc13008 100644
> --- a/hw/ppc/spapr_events.c
> +++ b/hw/ppc/spapr_events.c
> @@ -481,7 +481,7 @@ static void spapr_powerdown_req(Notifier *n, void *opaque)
>  
>      rtas_event_log_queue(RTAS_LOG_TYPE_EPOW, new_epow, true);
>  
> -    qemu_irq_pulse(xics_get_qirq(spapr->xics,
> +    qemu_irq_pulse(xics_get_qirq(XICS_INTERFACE(spapr),
>                                   rtas_event_log_to_irq(spapr,
>                                                         RTAS_LOG_TYPE_EPOW)));
>  }
> @@ -574,7 +574,7 @@ static void spapr_hotplug_req_event(uint8_t hp_id, uint8_t hp_action,
>  
>      rtas_event_log_queue(RTAS_LOG_TYPE_HOTPLUG, new_hp, true);
>  
> -    qemu_irq_pulse(xics_get_qirq(spapr->xics,
> +    qemu_irq_pulse(xics_get_qirq(XICS_INTERFACE(spapr),
>                                   rtas_event_log_to_irq(spapr,
>                                                         RTAS_LOG_TYPE_HOTPLUG)));
>  }
> @@ -695,7 +695,7 @@ static void check_exception(PowerPCCPU *cpu, sPAPRMachineState *spapr,
>                  spapr_event_sources_get_source(spapr->event_sources, i);
>  
>              g_assert(source->enabled);
> -            qemu_irq_pulse(xics_get_qirq(spapr->xics, source->irq));
> +            qemu_irq_pulse(xics_get_qirq(XICS_INTERFACE(spapr), source->irq));
>          }
>      }
>  
> diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
> index 01d5c92425ed..e52d6e993c9e 100644
> --- a/hw/ppc/spapr_pci.c
> +++ b/hw/ppc/spapr_pci.c
> @@ -736,7 +736,7 @@ static void spapr_msi_write(void *opaque, hwaddr addr,
>  
>      trace_spapr_pci_msi_write(addr, data, irq);
>  
> -    qemu_irq_pulse(xics_get_qirq(spapr->xics, irq));
> +    qemu_irq_pulse(xics_get_qirq(XICS_INTERFACE(spapr), irq));
>  }
>  
>  static const MemoryRegionOps spapr_msi_ops = {
> diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h
> index 092294ed5a65..bfd307be30ca 100644
> --- a/include/hw/pci-host/spapr.h
> +++ b/include/hw/pci-host/spapr.h
> @@ -106,7 +106,7 @@ static inline qemu_irq spapr_phb_lsi_qirq(struct sPAPRPHBState *phb, int pin)
>  {
>      sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
>  
> -    return xics_get_qirq(spapr->xics, phb->lsi_table[pin].irq);
> +    return xics_get_qirq(XICS_INTERFACE(spapr), phb->lsi_table[pin].irq);
>  }
>  
>  PCIHostState *spapr_create_phb(sPAPRMachineState *spapr, int index);
> diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h
> index fc6f673ea086..1b04523b683d 100644
> --- a/include/hw/ppc/spapr_vio.h
> +++ b/include/hw/ppc/spapr_vio.h
> @@ -87,7 +87,7 @@ static inline qemu_irq spapr_vio_qirq(VIOsPAPRDevice *dev)
>  {
>      sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
>  
> -    return xics_get_qirq(spapr->xics, dev->irq);
> +    return xics_get_qirq(XICS_INTERFACE(spapr), dev->irq);
>  }
>  
>  static inline bool spapr_vio_dma_valid(VIOsPAPRDevice *dev, uint64_t taddr,
> diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
> index 640603b3d76d..896fa5d87c1c 100644
> --- a/include/hw/ppc/xics.h
> +++ b/include/hw/ppc/xics.h
> @@ -197,7 +197,8 @@ typedef struct XICSInterfaceClass {
>  
>  #define XICS_IRQS_SPAPR               1024
>  
> -qemu_irq xics_get_qirq(XICSState *icp, int irq);
> +qemu_irq xics_get_qirq(XICSInterface *xi, int irq);
> +
>  int spapr_ics_alloc(ICSState *ics, int irq_hint, bool lsi, Error **errp);
>  int spapr_ics_alloc_block(ICSState *ics, int num, bool lsi, bool align,
>                             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: 819 bytes --]

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

* Re: [Qemu-devel] [PATCH v2 08/22] ppc/xics: use the QOM interface to resend irqs
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 08/22] ppc/xics: use the QOM interface to resend irqs Cédric Le Goater
@ 2017-02-23  2:29   ` David Gibson
  2017-02-24 11:12     ` [Qemu-devel] [Qemu-ppc] " Cédric Le Goater
  0 siblings, 1 reply; 59+ messages in thread
From: David Gibson @ 2017-02-23  2:29 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Thu, Feb 16, 2017 at 02:47:31PM +0100, Cédric Le Goater wrote:
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
>  hw/intc/xics.c | 26 ++++++++++++++------------
>  1 file changed, 14 insertions(+), 12 deletions(-)
> 
> diff --git a/hw/intc/xics.c b/hw/intc/xics.c
> index 0ffdf09c5304..2decb921e4e3 100644
> --- a/hw/intc/xics.c
> +++ b/hw/intc/xics.c
> @@ -229,16 +229,15 @@ static void icp_check_ipi(ICPState *ss)
>      qemu_irq_raise(ss->output);
>  }
>  
> -static void icp_resend(ICPState *ss)
> +static void icp_resend(XICSInterface *xi, ICPState *ss)
>  {
> -    ICSState *ics;
> +    XICSInterfaceClass *xic = XICS_INTERFACE_GET_CLASS(xi);
>  
>      if (ss->mfrr < CPPR(ss)) {
>          icp_check_ipi(ss);
>      }
> -    QLIST_FOREACH(ics, &ss->xics->ics, list) {
> -        ics_resend(ics);
> -    }
> +
> +    xic->ics_resend(xi);
>  }
>  
>  void icp_set_cppr(ICPState *ss, uint8_t cppr)
> @@ -262,7 +261,7 @@ void icp_set_cppr(ICPState *ss, uint8_t cppr)
>          }
>      } else {
>          if (!XISR(ss)) {
> -            icp_resend(ss);
> +            icp_resend(XICS_INTERFACE(qdev_get_machine()), ss);

Here you're assuming that the machine is the implementor of the xics
interface, which is kinda ugly.  The ICP should have a pointer to the
xics interface, which will eventually replace the pointer to the
overall xics object it has now.

But I haven't read the rest of the series yet, maybe this is just
transitional.

>          }
>      }
>  }
> @@ -299,6 +298,8 @@ uint32_t icp_ipoll(ICPState *ss, uint32_t *mfrr)
>  
>  void icp_eoi(ICPState *ss, uint32_t xirr)
>  {
> +    XICSInterface *xi = XICS_INTERFACE(qdev_get_machine());
> +    XICSInterfaceClass *xic = XICS_INTERFACE_GET_CLASS(xi);
>      ICSState *ics;
>      uint32_t irq;
>  
> @@ -306,13 +307,13 @@ void icp_eoi(ICPState *ss, uint32_t xirr)
>      ss->xirr = (ss->xirr & ~CPPR_MASK) | (xirr & CPPR_MASK);
>      trace_xics_icp_eoi(ss->cs->cpu_index, xirr, ss->xirr);
>      irq = xirr & XISR_MASK;
> -    QLIST_FOREACH(ics, &ss->xics->ics, list) {
> -        if (ics_valid_irq(ics, irq)) {
> -            ics_eoi(ics, irq);
> -        }
> +
> +    ics = xic->ics_get(xi, irq);
> +    if (ics) {
> +        ics_eoi(ics, irq);
>      }
>      if (!XISR(ss)) {
> -        icp_resend(ss);
> +        icp_resend(xi, ss);
>      }
>  }
>  
> @@ -592,10 +593,11 @@ static void ics_simple_reset(DeviceState *dev)
>  
>  static int ics_simple_post_load(ICSState *ics, int version_id)
>  {
> +    XICSInterface *xi = XICS_INTERFACE(qdev_get_machine());
>      int i;
>  
>      for (i = 0; i < ics->xics->nr_servers; i++) {
> -        icp_resend(&ics->xics->ss[i]);
> +        icp_resend(xi, &ics->xics->ss[i]);
>      }

This resend triggering needs to get moved to the xics interface
implementor - i.e. the machine.  It's actually already broken right
now, since it incorrectly relies on the ordering of the ics and icp
restore during migration.

>      return 0;

-- 
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: 819 bytes --]

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

* Re: [Qemu-devel] [PATCH v2 09/22] ppc/xics: remove xics_find_source()
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 09/22] ppc/xics: remove xics_find_source() Cédric Le Goater
@ 2017-02-23  2:31   ` David Gibson
  2017-02-24 11:13     ` [Qemu-devel] [Qemu-ppc] " Cédric Le Goater
  0 siblings, 1 reply; 59+ messages in thread
From: David Gibson @ 2017-02-23  2:31 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Thu, Feb 16, 2017 at 02:47:32PM +0100, Cédric Le Goater wrote:
> It is not used anymore now that we have the QOM interface for XICS.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

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

Several of these patches are small enough that I wonder if they could
be merged, though.

> ---
>  hw/intc/xics.c        | 12 ------------
>  include/hw/ppc/xics.h |  1 -
>  2 files changed, 13 deletions(-)
> 
> diff --git a/hw/intc/xics.c b/hw/intc/xics.c
> index 2decb921e4e3..bfd3a539561a 100644
> --- a/hw/intc/xics.c
> +++ b/hw/intc/xics.c
> @@ -737,18 +737,6 @@ static const TypeInfo xics_interface_info = {
>  /*
>   * Exported functions
>   */
> -ICSState *xics_find_source(XICSState *xics, int irq)
> -{
> -    ICSState *ics;
> -
> -    QLIST_FOREACH(ics, &xics->ics, list) {
> -        if (ics_valid_irq(ics, irq)) {
> -            return ics;
> -        }
> -    }
> -    return NULL;
> -}
> -
>  qemu_irq xics_get_qirq(XICSInterface *xi, int irq)
>  {
>      XICSInterfaceClass *xic = XICS_INTERFACE_GET_CLASS(xi);
> diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
> index 896fa5d87c1c..e10426e98e31 100644
> --- a/include/hw/ppc/xics.h
> +++ b/include/hw/ppc/xics.h
> @@ -222,7 +222,6 @@ void ics_simple_write_xive(ICSState *ics, int nr, int server,
>  
>  void ics_set_irq_type(ICSState *ics, int srcno, bool lsi);
>  
> -ICSState *xics_find_source(XICSState *icp, int irq);
>  void ics_resend(ICSState *ics);
>  
>  #endif /* XICS_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: 819 bytes --]

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

* Re: [Qemu-devel] [PATCH v2 10/22] ppc/xics: register the reset handler of ICS objects
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 10/22] ppc/xics: register the reset handler of ICS objects Cédric Le Goater
@ 2017-02-23  2:33   ` David Gibson
  0 siblings, 0 replies; 59+ messages in thread
From: David Gibson @ 2017-02-23  2:33 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Thu, Feb 16, 2017 at 02:47:33PM +0100, Cédric Le Goater wrote:
> The reset of the ICS objects is currently handled by XICS but this can
> be done for each individual ICS. This also reduces the use of the XICS
> list of ICS.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

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

> ---
>  hw/intc/xics.c | 5 -----
>  hw/ppc/spapr.c | 1 +
>  2 files changed, 1 insertion(+), 5 deletions(-)
> 
> diff --git a/hw/intc/xics.c b/hw/intc/xics.c
> index bfd3a539561a..d679313cd49f 100644
> --- a/hw/intc/xics.c
> +++ b/hw/intc/xics.c
> @@ -139,16 +139,11 @@ static void ics_simple_pic_print_info(InterruptStatsProvider *obj,
>  static void xics_common_reset(DeviceState *d)
>  {
>      XICSState *xics = XICS_COMMON(d);
> -    ICSState *ics;
>      int i;
>  
>      for (i = 0; i < xics->nr_servers; i++) {
>          device_reset(DEVICE(&xics->ss[i]));
>      }
> -
> -    QLIST_FOREACH(ics, &xics->ics, list) {
> -        device_reset(DEVICE(ics));
> -    }
>  }
>  
>  static void xics_common_initfn(Object *obj)
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 85a973cce7ae..a2a64d7de41d 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -112,6 +112,7 @@ static XICSState *try_create_xics(sPAPRMachineState *spapr,
>      }
>  
>      spapr->ics = ICS_SIMPLE(object_new(type_ics));
> +    qdev_set_parent_bus(DEVICE(spapr->ics), sysbus_get_default());
>      object_property_add_child(OBJECT(spapr), "ics", OBJECT(spapr->ics), NULL);
>      object_property_set_int(OBJECT(spapr->ics), nr_irqs, "nr-irqs", &err);
>      object_property_add_const_link(OBJECT(spapr->ics), "xics", OBJECT(xics),

-- 
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: 819 bytes --]

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

* Re: [Qemu-devel] [PATCH v2 11/22] ppc/xics: remove the XICS list of ICS
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 11/22] ppc/xics: remove the XICS list of ICS Cédric Le Goater
@ 2017-02-23  2:33   ` David Gibson
  0 siblings, 0 replies; 59+ messages in thread
From: David Gibson @ 2017-02-23  2:33 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Thu, Feb 16, 2017 at 02:47:34PM +0100, Cédric Le Goater wrote:
> This is not used anymore.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

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

> ---
>  hw/intc/xics.c        | 8 --------
>  hw/ppc/spapr.c        | 1 -
>  include/hw/ppc/xics.h | 2 --
>  3 files changed, 11 deletions(-)
> 
> diff --git a/hw/intc/xics.c b/hw/intc/xics.c
> index d679313cd49f..5131587ce088 100644
> --- a/hw/intc/xics.c
> +++ b/hw/intc/xics.c
> @@ -146,13 +146,6 @@ static void xics_common_reset(DeviceState *d)
>      }
>  }
>  
> -static void xics_common_initfn(Object *obj)
> -{
> -    XICSState *xics = XICS_COMMON(obj);
> -
> -    QLIST_INIT(&xics->ics);
> -}
> -
>  static void xics_common_class_init(ObjectClass *oc, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(oc);
> @@ -165,7 +158,6 @@ static const TypeInfo xics_common_info = {
>      .parent        = TYPE_DEVICE,
>      .instance_size = sizeof(XICSState),
>      .class_size    = sizeof(XICSStateClass),
> -    .instance_init = xics_common_initfn,
>      .class_init    = xics_common_class_init,
>  };
>  
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index a2a64d7de41d..d1946ebcac69 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -122,7 +122,6 @@ static XICSState *try_create_xics(sPAPRMachineState *spapr,
>      if (err) {
>          goto error;
>      }
> -    QLIST_INSERT_HEAD(&xics->ics, spapr->ics, list);
>  
>      xics->ss = g_malloc0(nr_servers * sizeof(ICPState));
>      xics->nr_servers = nr_servers;
> diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
> index e10426e98e31..c15d8e2a8ae6 100644
> --- a/include/hw/ppc/xics.h
> +++ b/include/hw/ppc/xics.h
> @@ -82,7 +82,6 @@ struct XICSState {
>      /*< public >*/
>      uint32_t nr_servers;
>      ICPState *ss;
> -    QLIST_HEAD(, ICSState) ics;
>  };
>  
>  #define TYPE_ICP "icp"
> @@ -152,7 +151,6 @@ struct ICSState {
>      qemu_irq *qirqs;
>      ICSIRQState *irqs;
>      XICSState *xics;
> -    QLIST_ENTRY(ICSState) list;
>  };
>  
>  static inline bool ics_valid_irq(ICSState *ics, uint32_t nr)

-- 
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: 819 bytes --]

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

* Re: [Qemu-devel] [PATCH v2 12/22] ppc/xics: extend the QOM interface to handle ICPs
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 12/22] ppc/xics: extend the QOM interface to handle ICPs Cédric Le Goater
@ 2017-02-23  2:39   ` David Gibson
  2017-02-24 11:15     ` [Qemu-devel] [Qemu-ppc] " Cédric Le Goater
  0 siblings, 1 reply; 59+ messages in thread
From: David Gibson @ 2017-02-23  2:39 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Thu, Feb 16, 2017 at 02:47:35PM +0100, Cédric Le Goater wrote:
> Let's add two new handlers for ICPs. One is to get an ICP object from
> a server number and a second is to resend the irqs when needed.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
>  hw/intc/xics.c        |  2 +-
>  hw/ppc/spapr.c        | 20 ++++++++++++++++++++
>  include/hw/ppc/xics.h |  3 +++
>  3 files changed, 24 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/intc/xics.c b/hw/intc/xics.c
> index 5131587ce088..7168c2cfd8a1 100644
> --- a/hw/intc/xics.c
> +++ b/hw/intc/xics.c
> @@ -216,7 +216,7 @@ static void icp_check_ipi(ICPState *ss)
>      qemu_irq_raise(ss->output);
>  }
>  
> -static void icp_resend(XICSInterface *xi, ICPState *ss)
> +void icp_resend(XICSInterface *xi, ICPState *ss)
>  {
>      XICSInterfaceClass *xic = XICS_INTERFACE_GET_CLASS(xi);
>  
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index d1946ebcac69..eb7da32296d8 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -2915,6 +2915,24 @@ static void spapr_ics_resend(XICSInterface *dev)
>      ics_resend(spapr->ics);
>  }
>  
> +static ICPState *spapr_icp_get(XICSInterface *xi, int server)
> +{
> +    sPAPRMachineState *spapr = SPAPR_MACHINE(xi);
> +
> +    return (server < spapr->xics->nr_servers) ? &spapr->xics->ss[server] :
> +        NULL;
> +}
> +
> +static void spapr_icp_resend(XICSInterface *xi)
> +{
> +    sPAPRMachineState *spapr = SPAPR_MACHINE(xi);
> +    int i;
> +
> +    for (i = 0; i < spapr->xics->nr_servers; i++) {
> +        icp_resend(xi, &spapr->xics->ss[i]);
> +    }
> +}

I'm not quite sure where you plan to use the resend hook.  AFAICT all
the existing users of this path can do fine using icp_get() then
icp_resend() directly.

> +
>  static void spapr_machine_class_init(ObjectClass *oc, void *data)
>  {
>      MachineClass *mc = MACHINE_CLASS(oc);
> @@ -2959,6 +2977,8 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
>      vhc->hypercall = emulate_spapr_hypercall;
>      xic->ics_get = spapr_ics_get;
>      xic->ics_resend = spapr_ics_resend;
> +    xic->icp_get = spapr_icp_get;
> +    xic->icp_resend = spapr_icp_resend;
>  }
>  
>  static const TypeInfo spapr_machine_info = {
> diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
> index c15d8e2a8ae6..7004c851e250 100644
> --- a/include/hw/ppc/xics.h
> +++ b/include/hw/ppc/xics.h
> @@ -191,6 +191,8 @@ typedef struct XICSInterfaceClass {
>      InterfaceClass parent;
>      ICSState *(*ics_get)(XICSInterface *xi, int irq);
>      void (*ics_resend)(XICSInterface *xi);
> +    ICPState *(*icp_get)(XICSInterface *xi, int server);
> +    void (*icp_resend)(XICSInterface *xi);
>  } XICSInterfaceClass;
>  
>  #define XICS_IRQS_SPAPR               1024
> @@ -221,5 +223,6 @@ void ics_simple_write_xive(ICSState *ics, int nr, int server,
>  void ics_set_irq_type(ICSState *ics, int srcno, bool lsi);
>  
>  void ics_resend(ICSState *ics);
> +void icp_resend(XICSInterface *xi, ICPState *ss);
>  
>  #endif /* XICS_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: 819 bytes --]

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

* Re: [Qemu-devel] [PATCH v2 16/22] ppc/xics: register the reset handler of ICP objects
  2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 16/22] ppc/xics: register the reset handler of ICP objects Cédric Le Goater
@ 2017-02-23  2:42   ` David Gibson
  2017-02-24 11:27     ` [Qemu-devel] [Qemu-ppc] " Cédric Le Goater
  0 siblings, 1 reply; 59+ messages in thread
From: David Gibson @ 2017-02-23  2:42 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Thu, Feb 16, 2017 at 02:47:39PM +0100, Cédric Le Goater wrote:
> The reset of the ICP objects is currently handled by XICS but this can
> be done for each individual ICP.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Hrm.  I think whether device_reset() gets called automatically depends
on how the device is wired into the composition tree, and I'm not sure
the icps are in the right place for it to work.

This doesn't replace the code in xics_common_reset() so if it does
work it means we must have previously been resetting the ICPs twice.
Is that right?

> ---
>  hw/intc/xics.c | 18 ------------------
>  hw/ppc/spapr.c |  1 +
>  2 files changed, 1 insertion(+), 18 deletions(-)
> 
> diff --git a/hw/intc/xics.c b/hw/intc/xics.c
> index dd41340d41a5..3ad7e8cf8ec4 100644
> --- a/hw/intc/xics.c
> +++ b/hw/intc/xics.c
> @@ -137,29 +137,11 @@ static void ics_simple_pic_print_info(InterruptStatsProvider *obj,
>  /*
>   * XICS Common class - parent for emulated XICS and KVM-XICS
>   */
> -static void xics_common_reset(DeviceState *d)
> -{
> -    XICSState *xics = XICS_COMMON(d);
> -    int i;
> -
> -    for (i = 0; i < xics->nr_servers; i++) {
> -        device_reset(DEVICE(&xics->ss[i]));
> -    }
> -}
> -
> -static void xics_common_class_init(ObjectClass *oc, void *data)
> -{
> -    DeviceClass *dc = DEVICE_CLASS(oc);
> -
> -    dc->reset = xics_common_reset;
> -}
> -
>  static const TypeInfo xics_common_info = {
>      .name          = TYPE_XICS_COMMON,
>      .parent        = TYPE_DEVICE,
>      .instance_size = sizeof(XICSState),
>      .class_size    = sizeof(XICSStateClass),
> -    .class_init    = xics_common_class_init,
>  };
>  
>  /*
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 9c1772f93155..445d9a6ddad4 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -130,6 +130,7 @@ static XICSState *try_create_xics(sPAPRMachineState *spapr,
>          ICPState *icp = &xics->ss[i];
>  
>          object_initialize(icp, sizeof(*icp), type_icp);
> +        qdev_set_parent_bus(DEVICE(icp), sysbus_get_default());
>          object_property_add_child(OBJECT(xics), "icp[*]", OBJECT(icp), NULL);
>          object_property_add_const_link(OBJECT(icp), "xics", OBJECT(xics), NULL);
>          object_property_set_bool(OBJECT(icp), true, "realized", &err);

-- 
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: 819 bytes --]

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

* Re: [Qemu-devel] [PATCH v2 00/22] ppc/xics: simplify ICS and ICP creation
  2017-02-22 10:55   ` Cédric Le Goater
@ 2017-02-23  3:07     ` David Gibson
  2017-02-23  6:49       ` Cédric Le Goater
  2017-02-23  7:19       ` [Qemu-devel] [Qemu-ppc] " Cédric Le Goater
  0 siblings, 2 replies; 59+ messages in thread
From: David Gibson @ 2017-02-23  3:07 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Wed, Feb 22, 2017 at 11:55:40AM +0100, Cédric Le Goater wrote:
> On 02/22/2017 04:34 AM, David Gibson wrote:
> > On Thu, Feb 16, 2017 at 02:47:23PM +0100, Cédric Le Goater wrote:
> >> Hello,
> >>
> >> The goal behind this series is to simplify the XICS interface by
> >> moving back in the machine the way the ICS and ICP objects interact
> >> together. It's up to the machine to implement this "fabric" logic by
> >> providing a set of handlers of a QOM interface. These handlers are
> >> used to grab an ICS or an ICP object and also do irq resends. This
> >> idea was suggested by David Gibson.
> >>
> >> The patchset is organised as follow. It starts with a preliminary
> >> cleanup to get rid of the set_nr_irqs() and set_nr_servers()
> >> handlers. It also moves the creation of the ICS and ICP objects from
> >> the XICS object to the sPAPR machine. This simplifies the code
> >> significantly and prepares ground for future changes.
> >>
> >> As the sPAPR machine only makes use of a single ICS, we can store it
> >> at the machine level. This lets us remove dependencies on the list of
> >> ICS of the XICS object and simplify even more the code for the
> >> following changes.
> >>
> >> The QOM interface to interact with the ICS and ICP objects is then
> >> introduced. These are moved under the machine and cleanups are done
> >> accordingly.
> >>
> >> Finally, the XICSState classes are removed as they have been
> >> deprecated by the QOM interface.
> >>
> >>
> >> After the initial cleanups, which are rather big, I have tried to keep
> >> the each patch small enough to ease the review and to spot any
> >> problem. Each should be bisectable. The tree is available here :
> >>
> >> 	   https://github.com/legoater/qemu/tree/ppc-2.9
> > 
> > So, after you posted this, I discover the patch I sent the other day -
> > changing XICS away from a SysBusDevice breaks the postcopy migration
> > test on KVM.  I haven't had a chance to debug this yet, so for the
> > time being I've pulled my patch from ppc-for-2.9.  I've moved it into
> > a new 'xics-cleanup' branch.
> 
> It is even worse than that, the kernel does not start. This is because
> the ICS and ICP objects are not reseted  anymore and so the mfrr and
> irq priority values are incorrect : 0x0 instead of 0xFF. 
> 
> Before that patch, the reset was implicit because the device was a 
> SysBusDevice and all the devices were reseted when the bus was.  
> 
> Other devices (not on a bus or/and QOM objects) need to register on 
> SysBus to be reseted :
>   
> 	qdev_set_parent_bus(dev, sysbus_get_default());
> 
> or use a handler for :
> 
> 	qemu_register_reset()
> 
> which will be called by qemu_devices_reset()
> 
> I fell into this trap a few times with PowerNV and I should have 
> spotted it before adding my Reviewed-by. Sorry about that.

Ah!  Well, thanks for spotting it now and saving me the debugging.

> 
> So, to move on, we can use the fix below (You can merge it in your 
> patch). I also updated my branch with it : 
> 
> 	https://github.com/legoater/qemu/commits/ppc-2.9
> 
> I have checked that KVM and TCG migration still worked with the 
> patchset and also rebased PowerNV on it. All seem to work. Tell
> me if you want a resend. The patchset needs some review any how 
> and there should be some comment to address so it might be a bit 
> too early for a resend. 
> 
> 
> 
> FYI, the xics-cleanup branch has some issue with migration :
> 
> qemu-system-ppc64: VQ 0 size 0x80 < last_avail_idx 0x9f9 - used_idx 0x0
> qemu-system-ppc64: Failed to load virtio-blk:virtio
> qemu-system-ppc64: error while loading state for instance 0x0 of device 'pci@800000020000000:01.0/virtio-blk'
> 
> This is most probably a temporary regression, unrelated to XICS 
> though.

Hmm.  I'm lss sure.  This series changes the qom paths of ics and icp
devices, which I'd expect to mess with migration, though I haven't had
a chance to actually check yet.

So, as mentioned in one of my patch comments it hadn't been my
intention for the ICS and ICPs to assume that the machine implements
the fabric, but rather to replace their current "concrete" xics
pointer with a xics interface pointer that would point to the (spapr)
machine in practice.

Apart from that I'm pretty happy with the endpoint you reach.  I'm a
bit less convinced about the path taken to get there.  I'm not sure if
it's worth the churn of doing this reorg, but I think we'd get there
more clearly and with less intermediate abstraction violations if it
was done by:

     1. Introduce the xics qom interface, but have it implemented by
        the existing xics object
     2. Change the ics and icp to only interact with the xics object
        via the qom interface
     3. Implement the qom interface in the spapr machine
     4. Change to spapr directly creating ics and icp objects,
        pointing back to itself as the xics interface provider
     5. Remove the xics concrete object

This also has the advantage that the qom path changing parts are
isolated to step (4), meaning problems with migration should be easier
to localize.

-- 
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: 819 bytes --]

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

* Re: [Qemu-devel] [PATCH v2 00/22] ppc/xics: simplify ICS and ICP creation
  2017-02-23  3:07     ` David Gibson
@ 2017-02-23  6:49       ` Cédric Le Goater
  2017-02-23  7:19       ` [Qemu-devel] [Qemu-ppc] " Cédric Le Goater
  1 sibling, 0 replies; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-23  6:49 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel

On 02/23/2017 04:07 AM, David Gibson wrote:
>> FYI, the xics-cleanup branch has some issue with migration :
>>
>> qemu-system-ppc64: VQ 0 size 0x80 < last_avail_idx 0x9f9 - used_idx 0x0
>> qemu-system-ppc64: Failed to load virtio-blk:virtio
>> qemu-system-ppc64: error while loading state for instance 0x0 of device 'pci@800000020000000:01.0/virtio-blk'
>>
>> This is most probably a temporary regression, unrelated to XICS 
>> though.
> Hmm.  I'm lss sure.  This series changes the qom paths of ics and icp
> devices, which I'd expect to mess with migration, though I haven't had
> a chance to actually check yet.
> 

Just to be clear, the problem occurs without this patchset. 
It's inherent to the branch, but you will need the fix on 
XICS to start the guest.

C.

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

* Re: [Qemu-devel] [Qemu-ppc] [PATCH v2 00/22] ppc/xics: simplify ICS and ICP creation
  2017-02-23  3:07     ` David Gibson
  2017-02-23  6:49       ` Cédric Le Goater
@ 2017-02-23  7:19       ` Cédric Le Goater
  2017-02-23 22:55         ` David Gibson
  1 sibling, 1 reply; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-23  7:19 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel

> Apart from that I'm pretty happy with the endpoint you reach.  I'm a
> bit less convinced about the path taken to get there.  I'm not sure if
> it's worth the churn of doing this reorg, but I think we'd get there
> more clearly and with less intermediate abstraction violations if it
> was done by:
> 
>      1. Introduce the xics qom interface, but have it implemented by
>         the existing xics object
>      2. Change the ics and icp to only interact with the xics object
>         via the qom interface
>      3. Implement the qom interface in the spapr machine
>      4. Change to spapr directly creating ics and icp objects,
>         pointing back to itself as the xics interface provider
>      5. Remove the xics concrete object

So that's a full rewrite of the patchset to reach the same point. 
I can only grumble for such a proposal :/ 

> This also has the advantage that the qom path changing parts are
> isolated to step (4), meaning problems with migration should be easier
> to localize.

and migration works.

C.

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

* Re: [Qemu-devel] [Qemu-ppc] [PATCH v2 00/22] ppc/xics: simplify ICS and ICP creation
  2017-02-23  7:19       ` [Qemu-devel] [Qemu-ppc] " Cédric Le Goater
@ 2017-02-23 22:55         ` David Gibson
  0 siblings, 0 replies; 59+ messages in thread
From: David Gibson @ 2017-02-23 22:55 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Thu, Feb 23, 2017 at 08:19:31AM +0100, Cédric Le Goater wrote:
> > Apart from that I'm pretty happy with the endpoint you reach.  I'm a
> > bit less convinced about the path taken to get there.  I'm not sure if
> > it's worth the churn of doing this reorg, but I think we'd get there
> > more clearly and with less intermediate abstraction violations if it
> > was done by:
> > 
> >      1. Introduce the xics qom interface, but have it implemented by
> >         the existing xics object
> >      2. Change the ics and icp to only interact with the xics object
> >         via the qom interface
> >      3. Implement the qom interface in the spapr machine
> >      4. Change to spapr directly creating ics and icp objects,
> >         pointing back to itself as the xics interface provider
> >      5. Remove the xics concrete object
> 
> So that's a full rewrite of the patchset to reach the same point. 
> I can only grumble for such a proposal :/ 

Yeah.. point taken.

> > This also has the advantage that the qom path changing parts are
> > isolated to step (4), meaning problems with migration should be easier
> > to localize.
> 
> and migration works.

Oh, that's a nice surprise.  Ok never mind about the rework, just
address the other comments and repost.

-- 
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: 819 bytes --]

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

* Re: [Qemu-devel] [PATCH v2 01/22] ppc/xics: remove set_nr_irqs() handler from XICSStateClass
  2017-02-22  3:21   ` David Gibson
@ 2017-02-24 10:46     ` Cédric Le Goater
  0 siblings, 0 replies; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-24 10:46 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel

On 02/22/2017 04:21 AM, David Gibson wrote:
> On Thu, Feb 16, 2017 at 02:47:24PM +0100, Cédric Le Goater wrote:
>> Today, the ICS (Interrupt Controller Source) object is created and
>> realized by the init and realize routines of the XICS object, but some
>> of the parameters are only known at the machine level.
>>
>> These parameters are passed from the sPAPR machine to the ICS object
>> in a rather convoluted way using property handlers and a class handler
>> of the XICS object. The number of irqs required to allocate the IRQ
>> state objects in the ICS realize routine is one of them.
>>
>> Let's simplify the process by creating the ICS object along with the
>> XICS object at the machine level and link the ICS into the XICS list
>> of ICSs at this level also. In the sPAPR machine, there is only a
>> single ICS but that will change with the PowerNV machine.
>>
>> Also, QOMify the creation of the objects and get rid of the
>> superfluous code.
>>
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>> ---
>>
>>  Changes since v1:
>>
>>  - added a XICS link to the ICS object
>>
>>  hw/intc/xics.c        | 51 ++++++++++++++++---------------------------------
>>  hw/intc/xics_kvm.c    | 44 ++++++++++--------------------------------
>>  hw/intc/xics_spapr.c  | 34 ---------------------------------
>>  hw/ppc/spapr.c        | 53 +++++++++++++++++++++++++++++++++++----------------
>>  include/hw/ppc/xics.h |  2 --
>>  5 files changed, 63 insertions(+), 121 deletions(-)
>>
>> diff --git a/hw/intc/xics.c b/hw/intc/xics.c
>> index 372b8311fb8b..e70d3b8b1095 100644
>> --- a/hw/intc/xics.c
>> +++ b/hw/intc/xics.c
>> @@ -151,38 +151,6 @@ static void xics_common_reset(DeviceState *d)
>>      }
>>  }
>>  
>> -static void xics_prop_get_nr_irqs(Object *obj, Visitor *v, const char *name,
>> -                                  void *opaque, Error **errp)
>> -{
>> -    XICSState *xics = XICS_COMMON(obj);
>> -    int64_t value = xics->nr_irqs;
>> -
>> -    visit_type_int(v, name, &value, errp);
>> -}
>> -
>> -static void xics_prop_set_nr_irqs(Object *obj, Visitor *v, const char *name,
>> -                                  void *opaque, Error **errp)
>> -{
>> -    XICSState *xics = XICS_COMMON(obj);
>> -    XICSStateClass *info = XICS_COMMON_GET_CLASS(xics);
>> -    Error *error = NULL;
>> -    int64_t value;
>> -
>> -    visit_type_int(v, name, &value, &error);
>> -    if (error) {
>> -        error_propagate(errp, error);
>> -        return;
>> -    }
>> -    if (xics->nr_irqs) {
>> -        error_setg(errp, "Number of interrupts is already set to %u",
>> -                   xics->nr_irqs);
>> -        return;
>> -    }
>> -
>> -    assert(info->set_nr_irqs);
>> -    info->set_nr_irqs(xics, value, errp);
>> -}
>> -
>>  void xics_set_nr_servers(XICSState *xics, uint32_t nr_servers,
>>                           const char *typename, Error **errp)
>>  {
>> @@ -241,9 +209,6 @@ static void xics_common_initfn(Object *obj)
>>      XICSState *xics = XICS_COMMON(obj);
>>  
>>      QLIST_INIT(&xics->ics);
>> -    object_property_add(obj, "nr_irqs", "int",
>> -                        xics_prop_get_nr_irqs, xics_prop_set_nr_irqs,
>> -                        NULL, NULL, NULL);
>>      object_property_add(obj, "nr_servers", "int",
>>                          xics_prop_get_nr_servers, xics_prop_set_nr_servers,
>>                          NULL, NULL, NULL);
>> @@ -737,6 +702,16 @@ static void ics_simple_initfn(Object *obj)
>>  static void ics_simple_realize(DeviceState *dev, Error **errp)
>>  {
>>      ICSState *ics = ICS_SIMPLE(dev);
>> +    Object *obj;
>> +    Error *err = NULL;
>> +
>> +    obj = object_property_get_link(OBJECT(dev), "xics", &err);
>> +    if (!obj) {
>> +        error_setg(errp, "%s: required link 'xics' not found: %s",
>> +                   __func__, error_get_pretty(err));
>> +        return;
>> +    }
>> +    ics->xics = XICS_COMMON(obj);
>>  
>>      if (!ics->nr_irqs) {
>>          error_setg(errp, "Number of interrupts needs to be greater 0");
>> @@ -746,12 +721,18 @@ static void ics_simple_realize(DeviceState *dev, Error **errp)
>>      ics->qirqs = qemu_allocate_irqs(ics_simple_set_irq, ics, ics->nr_irqs);
>>  }
>>  
>> +static Property ics_simple_properties[] = {
>> +    DEFINE_PROP_UINT32("nr-irqs", ICSState, nr_irqs, 0),
>> +    DEFINE_PROP_END_OF_LIST(),
>> +};
>> +
>>  static void ics_simple_class_init(ObjectClass *klass, void *data)
>>  {
>>      DeviceClass *dc = DEVICE_CLASS(klass);
>>      ICSStateClass *isc = ICS_BASE_CLASS(klass);
>>  
>>      dc->realize = ics_simple_realize;
>> +    dc->props = ics_simple_properties;
>>      dc->vmsd = &vmstate_ics_simple;
>>      dc->reset = ics_simple_reset;
>>      isc->post_load = ics_simple_post_load;
>> diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
>> index 17694eaa8709..4a6c0522feb6 100644
>> --- a/hw/intc/xics_kvm.c
>> +++ b/hw/intc/xics_kvm.c
>> @@ -294,6 +294,16 @@ static void ics_kvm_reset(DeviceState *dev)
>>  static void ics_kvm_realize(DeviceState *dev, Error **errp)
>>  {
>>      ICSState *ics = ICS_SIMPLE(dev);
>> +    Object *obj;
>> +    Error *err = NULL;
>> +
>> +    obj = object_property_get_link(OBJECT(dev), "xics", &err);
>> +    if (!obj) {
>> +        error_setg(errp, "%s: required link 'xics' not found: %s",
>> +                   __func__, error_get_pretty(err));
>> +        return;
>> +    }
>> +    ics->xics = XICS_COMMON(obj);
> 
> Couldn't you have this logic in the base class rather than repeating
> it in ics simple and ics kvm?

Yes we could. But, as I am getting rid of the backlinks at the end of 
the patchset, the redundancy is not much of a problem.

Thanks,

C.  

>>      if (!ics->nr_irqs) {
>>          error_setg(errp, "Number of interrupts needs to be greater 0");
>> @@ -358,18 +368,6 @@ static void xics_kvm_cpu_setup(XICSState *xics, PowerPCCPU *cpu)
>>      ss->cap_irq_xics_enabled = true;
>>  }
>>  
>> -static void xics_kvm_set_nr_irqs(XICSState *xics, uint32_t nr_irqs,
>> -                                 Error **errp)
>> -{
>> -    ICSState *ics = QLIST_FIRST(&xics->ics);
>> -
>> -    /* This needs to be deprecated ... */
>> -    xics->nr_irqs = nr_irqs;
>> -    if (ics) {
>> -        ics->nr_irqs = nr_irqs;
>> -    }
>> -}
>> -
>>  static void xics_kvm_set_nr_servers(XICSState *xics, uint32_t nr_servers,
>>                                      Error **errp)
>>  {
>> @@ -389,7 +387,6 @@ static void xics_kvm_realize(DeviceState *dev, Error **errp)
>>  {
>>      KVMXICSState *xicskvm = XICS_SPAPR_KVM(dev);
>>      XICSState *xics = XICS_COMMON(dev);
>> -    ICSState *ics;
>>      int i, rc;
>>      Error *error = NULL;
>>      struct kvm_create_device xics_create_device = {
>> @@ -441,14 +438,6 @@ static void xics_kvm_realize(DeviceState *dev, Error **errp)
>>  
>>      xicskvm->kernel_xics_fd = xics_create_device.fd;
>>  
>> -    QLIST_FOREACH(ics, &xics->ics, list) {
>> -        object_property_set_bool(OBJECT(ics), true, "realized", &error);
>> -        if (error) {
>> -            error_propagate(errp, error);
>> -            goto fail;
>> -        }
>> -    }
>> -
>>      assert(xics->nr_servers);
>>      for (i = 0; i < xics->nr_servers; i++) {
>>          object_property_set_bool(OBJECT(&xics->ss[i]), true, "realized",
>> @@ -472,17 +461,6 @@ fail:
>>      kvmppc_define_rtas_kernel_token(0, "ibm,int-off");
>>  }
>>  
>> -static void xics_kvm_initfn(Object *obj)
>> -{
>> -    XICSState *xics = XICS_COMMON(obj);
>> -    ICSState *ics;
>> -
>> -    ics = ICS_SIMPLE(object_new(TYPE_ICS_KVM));
>> -    object_property_add_child(obj, "ics", OBJECT(ics), NULL);
>> -    ics->xics = xics;
>> -    QLIST_INSERT_HEAD(&xics->ics, ics, list);
>> -}
>> -
>>  static void xics_kvm_class_init(ObjectClass *oc, void *data)
>>  {
>>      DeviceClass *dc = DEVICE_CLASS(oc);
>> @@ -490,7 +468,6 @@ static void xics_kvm_class_init(ObjectClass *oc, void *data)
>>  
>>      dc->realize = xics_kvm_realize;
>>      xsc->cpu_setup = xics_kvm_cpu_setup;
>> -    xsc->set_nr_irqs = xics_kvm_set_nr_irqs;
>>      xsc->set_nr_servers = xics_kvm_set_nr_servers;
>>  }
>>  
>> @@ -499,7 +476,6 @@ static const TypeInfo xics_spapr_kvm_info = {
>>      .parent        = TYPE_XICS_COMMON,
>>      .instance_size = sizeof(KVMXICSState),
>>      .class_init    = xics_kvm_class_init,
>> -    .instance_init = xics_kvm_initfn,
>>  };
>>  
>>  static void xics_kvm_register_types(void)
>> diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
>> index 2e3f1c5e95b2..03e42a866603 100644
>> --- a/hw/intc/xics_spapr.c
>> +++ b/hw/intc/xics_spapr.c
>> @@ -239,18 +239,6 @@ static void rtas_int_on(PowerPCCPU *cpu, sPAPRMachineState *spapr,
>>      rtas_st(rets, 0, RTAS_OUT_SUCCESS);
>>  }
>>  
>> -static void xics_spapr_set_nr_irqs(XICSState *xics, uint32_t nr_irqs,
>> -                                   Error **errp)
>> -{
>> -    ICSState *ics = QLIST_FIRST(&xics->ics);
>> -
>> -    /* This needs to be deprecated ... */
>> -    xics->nr_irqs = nr_irqs;
>> -    if (ics) {
>> -        ics->nr_irqs = nr_irqs;
>> -    }
>> -}
>> -
>>  static void xics_spapr_set_nr_servers(XICSState *xics, uint32_t nr_servers,
>>                                        Error **errp)
>>  {
>> @@ -260,7 +248,6 @@ static void xics_spapr_set_nr_servers(XICSState *xics, uint32_t nr_servers,
>>  static void xics_spapr_realize(DeviceState *dev, Error **errp)
>>  {
>>      XICSState *xics = XICS_SPAPR(dev);
>> -    ICSState *ics;
>>      Error *error = NULL;
>>      int i;
>>  
>> @@ -282,14 +269,6 @@ static void xics_spapr_realize(DeviceState *dev, Error **errp)
>>      spapr_register_hypercall(H_EOI, h_eoi);
>>      spapr_register_hypercall(H_IPOLL, h_ipoll);
>>  
>> -    QLIST_FOREACH(ics, &xics->ics, list) {
>> -        object_property_set_bool(OBJECT(ics), true, "realized", &error);
>> -        if (error) {
>> -            error_propagate(errp, error);
>> -            return;
>> -        }
>> -    }
>> -
>>      for (i = 0; i < xics->nr_servers; i++) {
>>          object_property_set_bool(OBJECT(&xics->ss[i]), true, "realized",
>>                                   &error);
>> @@ -300,24 +279,12 @@ static void xics_spapr_realize(DeviceState *dev, Error **errp)
>>      }
>>  }
>>  
>> -static void xics_spapr_initfn(Object *obj)
>> -{
>> -    XICSState *xics = XICS_SPAPR(obj);
>> -    ICSState *ics;
>> -
>> -    ics = ICS_SIMPLE(object_new(TYPE_ICS_SIMPLE));
>> -    object_property_add_child(obj, "ics", OBJECT(ics), NULL);
>> -    ics->xics = xics;
>> -    QLIST_INSERT_HEAD(&xics->ics, ics, list);
>> -}
>> -
>>  static void xics_spapr_class_init(ObjectClass *oc, void *data)
>>  {
>>      DeviceClass *dc = DEVICE_CLASS(oc);
>>      XICSStateClass *xsc = XICS_SPAPR_CLASS(oc);
>>  
>>      dc->realize = xics_spapr_realize;
>> -    xsc->set_nr_irqs = xics_spapr_set_nr_irqs;
>>      xsc->set_nr_servers = xics_spapr_set_nr_servers;
>>  }
>>  
>> @@ -327,7 +294,6 @@ static const TypeInfo xics_spapr_info = {
>>      .instance_size = sizeof(XICSState),
>>      .class_size = sizeof(XICSStateClass),
>>      .class_init    = xics_spapr_class_init,
>> -    .instance_init = xics_spapr_initfn,
>>  };
>>  
>>  #define ICS_IRQ_FREE(ics, srcno)   \
>> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
>> index 9b6ad0f2fd77..94b1e8e3227a 100644
>> --- a/hw/ppc/spapr.c
>> +++ b/hw/ppc/spapr.c
>> @@ -95,22 +95,42 @@
>>  
>>  #define HTAB_SIZE(spapr)        (1ULL << ((spapr)->htab_shift))
>>  
>> -static XICSState *try_create_xics(const char *type, int nr_servers,
>> -                                  int nr_irqs, Error **errp)
>> -{
>> -    Error *err = NULL;
>> -    DeviceState *dev;
>> +static XICSState *try_create_xics(const char *type, const char *type_ics,
>> +                                  int nr_servers, int nr_irqs, Error **errp)
>> +{
>> +    Error *err = NULL, *local_err = NULL;
>> +    XICSState *xics;
>> +    ICSState *ics = NULL;
>> +
>> +    xics = XICS_COMMON(object_new(type));
>> +    qdev_set_parent_bus(DEVICE(xics), sysbus_get_default());
>> +    object_property_set_int(OBJECT(xics), nr_servers, "nr_servers", &err);
>> +    object_property_set_bool(OBJECT(xics), true, "realized", &local_err);
>> +    error_propagate(&err, local_err);
>> +    if (err) {
>> +        goto error;
>> +    }
>>  
>> -    dev = DEVICE(object_new(type));
>> -    qdev_prop_set_uint32(dev, "nr_servers", nr_servers);
>> -    qdev_prop_set_uint32(dev, "nr_irqs", nr_irqs);
>> -    object_property_set_bool(OBJECT(dev), true, "realized", &err);
>> +    ics = ICS_SIMPLE(object_new(type_ics));
>> +    object_property_add_child(OBJECT(xics), "ics", OBJECT(ics), NULL);
>> +    object_property_set_int(OBJECT(ics), nr_irqs, "nr-irqs", &err);
>> +    object_property_add_const_link(OBJECT(ics), "xics", OBJECT(xics), NULL);
>> +    object_property_set_bool(OBJECT(ics), true, "realized", &local_err);
>> +    error_propagate(&err, local_err);
>>      if (err) {
>> -        error_propagate(errp, err);
>> -        object_unparent(OBJECT(dev));
>> -        return NULL;
>> +        goto error;
>>      }
>> -    return XICS_COMMON(dev);
>> +    QLIST_INSERT_HEAD(&xics->ics, ics, list);
>> +
>> +    return xics;
>> +
>> +error:
>> +    error_propagate(errp, err);
>> +    if (ics) {
>> +        object_unparent(OBJECT(ics));
>> +    }
>> +    object_unparent(OBJECT(xics));
>> +    return NULL;
>>  }
>>  
>>  static XICSState *xics_system_init(MachineState *machine,
>> @@ -122,8 +142,8 @@ static XICSState *xics_system_init(MachineState *machine,
>>          Error *err = NULL;
>>  
>>          if (machine_kernel_irqchip_allowed(machine)) {
>> -            xics = try_create_xics(TYPE_XICS_SPAPR_KVM, nr_servers, nr_irqs,
>> -                                   &err);
>> +            xics = try_create_xics(TYPE_XICS_SPAPR_KVM, TYPE_ICS_KVM,
>> +                                   nr_servers, nr_irqs, &err);
>>          }
>>          if (machine_kernel_irqchip_required(machine) && !xics) {
>>              error_reportf_err(err,
>> @@ -134,7 +154,8 @@ static XICSState *xics_system_init(MachineState *machine,
>>      }
>>  
>>      if (!xics) {
>> -        xics = try_create_xics(TYPE_XICS_SPAPR, nr_servers, nr_irqs, errp);
>> +        xics = try_create_xics(TYPE_XICS_SPAPR, TYPE_ICS_SIMPLE, nr_servers,
>> +                               nr_irqs, errp);
>>      }
>>  
>>      return xics;
>> diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
>> index 3f0c31610aa4..8fe3c4d2ceab 100644
>> --- a/include/hw/ppc/xics.h
>> +++ b/include/hw/ppc/xics.h
>> @@ -74,7 +74,6 @@ struct XICSStateClass {
>>      DeviceClass parent_class;
>>  
>>      void (*cpu_setup)(XICSState *icp, PowerPCCPU *cpu);
>> -    void (*set_nr_irqs)(XICSState *icp, uint32_t nr_irqs, Error **errp);
>>      void (*set_nr_servers)(XICSState *icp, uint32_t nr_servers, Error **errp);
>>  };
>>  
>> @@ -83,7 +82,6 @@ struct XICSState {
>>      SysBusDevice parent_obj;
>>      /*< public >*/
>>      uint32_t nr_servers;
>> -    uint32_t nr_irqs;
>>      ICPState *ss;
>>      QLIST_HEAD(, ICSState) ics;
>>  };
> 

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

* Re: [Qemu-devel] [PATCH v2 03/22] ppc/xics: store the ICS object under the sPAPR machine
  2017-02-22  6:59   ` David Gibson
@ 2017-02-24 10:47     ` Cédric Le Goater
  0 siblings, 0 replies; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-24 10:47 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel

On 02/22/2017 07:59 AM, David Gibson wrote:
> On Thu, Feb 16, 2017 at 02:47:26PM +0100, Cédric Le Goater wrote:
>> A list of ICS objects was introduced under the XICS object for the
>> PowerNV machine, but, for the sPAPR machine, it brings extra complexity
>> as there is only a single ICS. To simplify the code, let's add the ICS
>> pointer under the sPAPR machine and try to reduce the use of this list
>> where possible.
>>
>> Also, change the xics_spapr_*() routines to use an ICS object instead
>> of an XICSState and change their name to reflect that these are
>> specific to the sPAPR ICS object.
>>
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> 
> Looks good apart from a minor point noted below.
> 
>> ---
>>  hw/intc/xics_spapr.c   | 22 +++++++++-------------
>>  hw/ppc/spapr.c         | 29 ++++++++++++++++-------------
>>  hw/ppc/spapr_events.c  |  4 ++--
>>  hw/ppc/spapr_pci.c     |  8 ++++----
>>  hw/ppc/spapr_vio.c     |  2 +-
>>  include/hw/ppc/spapr.h |  1 +
>>  include/hw/ppc/xics.h  |  6 +++---
>>  7 files changed, 36 insertions(+), 36 deletions(-)
>>
>> diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
>> index 859b5675e175..1501e796e5e0 100644
>> --- a/hw/intc/xics_spapr.c
>> +++ b/hw/intc/xics_spapr.c
>> @@ -118,7 +118,7 @@ static void rtas_set_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr,
>>                            uint32_t nargs, target_ulong args,
>>                            uint32_t nret, target_ulong rets)
>>  {
>> -    ICSState *ics = QLIST_FIRST(&spapr->xics->ics);
>> +    ICSState *ics = spapr->ics;
>>      uint32_t nr, srcno, server, priority;
>>  
>>      if ((nargs != 3) || (nret != 1)) {
>> @@ -151,7 +151,7 @@ static void rtas_get_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr,
>>                            uint32_t nargs, target_ulong args,
>>                            uint32_t nret, target_ulong rets)
>>  {
>> -    ICSState *ics = QLIST_FIRST(&spapr->xics->ics);
>> +    ICSState *ics = spapr->ics;
>>      uint32_t nr, srcno;
>>  
>>      if ((nargs != 1) || (nret != 3)) {
>> @@ -181,7 +181,7 @@ static void rtas_int_off(PowerPCCPU *cpu, sPAPRMachineState *spapr,
>>                           uint32_t nargs, target_ulong args,
>>                           uint32_t nret, target_ulong rets)
>>  {
>> -    ICSState *ics = QLIST_FIRST(&spapr->xics->ics);
>> +    ICSState *ics = spapr->ics;
>>      uint32_t nr, srcno;
>>  
>>      if ((nargs != 1) || (nret != 1)) {
>> @@ -212,7 +212,7 @@ static void rtas_int_on(PowerPCCPU *cpu, sPAPRMachineState *spapr,
>>                          uint32_t nargs, target_ulong args,
>>                          uint32_t nret, target_ulong rets)
>>  {
>> -    ICSState *ics = QLIST_FIRST(&spapr->xics->ics);
>> +    ICSState *ics = spapr->ics;
>>      uint32_t nr, srcno;
>>  
>>      if ((nargs != 1) || (nret != 1)) {
>> @@ -294,9 +294,8 @@ static int ics_find_free_block(ICSState *ics, int num, int alignnum)
>>      return -1;
>>  }
>>  
>> -int xics_spapr_alloc(XICSState *xics, int irq_hint, bool lsi, Error **errp)
>> +int spapr_ics_alloc(ICSState *ics, int irq_hint, bool lsi, Error **errp)
>>  {
>> -    ICSState *ics = QLIST_FIRST(&xics->ics);
>>      int irq;
>>  
>>      if (!ics) {
>> @@ -327,10 +326,9 @@ int xics_spapr_alloc(XICSState *xics, int irq_hint, bool lsi, Error **errp)
>>   * Allocate block of consecutive IRQs, and return the number of the first IRQ in
>>   * the block. If align==true, aligns the first IRQ number to num.
>>   */
>> -int xics_spapr_alloc_block(XICSState *xics, int num, bool lsi, bool align,
>> -                           Error **errp)
>> +int spapr_ics_alloc_block(ICSState *ics, int num, bool lsi,
>> +                          bool align, Error **errp)
>>  {
>> -    ICSState *ics = QLIST_FIRST(&xics->ics);
>>      int i, first = -1;
>>  
>>      if (!ics) {
>> @@ -380,11 +378,9 @@ static void ics_free(ICSState *ics, int srcno, int num)
>>      }
>>  }
>>  
>> -void xics_spapr_free(XICSState *xics, int irq, int num)
>> +void spapr_ics_free(ICSState *ics, int irq, int num)
>>  {
>> -    ICSState *ics = xics_find_source(xics, irq);
>> -
>> -    if (ics) {
>> +    if (ics_valid_irq(ics, irq)) {
>>          trace_xics_ics_free(0, irq, num);
>>          ics_free(ics, irq - ics->offset, num);
>>      }
>> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
>> index 5d7c35de8cd9..045f2323a4e9 100644
>> --- a/hw/ppc/spapr.c
>> +++ b/hw/ppc/spapr.c
>> @@ -95,13 +95,13 @@
>>  
>>  #define HTAB_SIZE(spapr)        (1ULL << ((spapr)->htab_shift))
>>  
>> -static XICSState *try_create_xics(const char *type, const char *type_ics,
>> +static XICSState *try_create_xics(sPAPRMachineState *spapr,
>> +                                  const char *type, const char *type_ics,
>>                                    const char *type_icp, int nr_servers,
>>                                    int nr_irqs, Error **errp)
>>  {
>>      Error *err = NULL, *local_err = NULL;
>>      XICSState *xics;
>> -    ICSState *ics = NULL;
> 
> I'd prefer to keep this local and just update spapr->ics at the end of
> the function.  It won't really make a difference, since if the xics
> doesn't initialize nothing will work, but currently if this fails it
> could leave spapr->ics with a bogus but non-NULL pointer, which isn't
> good practice.

Indeed. I will make the change. 

Thanks,

C. 

> 
>>      int i;
>>  
>>      xics = XICS_COMMON(object_new(type));
>> @@ -111,16 +111,17 @@ static XICSState *try_create_xics(const char *type, const char *type_ics,
>>          goto error;
>>      }
>>  
>> -    ics = ICS_SIMPLE(object_new(type_ics));
>> -    object_property_add_child(OBJECT(xics), "ics", OBJECT(ics), NULL);
>> -    object_property_set_int(OBJECT(ics), nr_irqs, "nr-irqs", &err);
>> -    object_property_add_const_link(OBJECT(ics), "xics", OBJECT(xics), NULL);
>> -    object_property_set_bool(OBJECT(ics), true, "realized", &local_err);
>> +    spapr->ics = ICS_SIMPLE(object_new(type_ics));
>> +    object_property_add_child(OBJECT(spapr), "ics", OBJECT(spapr->ics), NULL);
>> +    object_property_set_int(OBJECT(spapr->ics), nr_irqs, "nr-irqs", &err);
>> +    object_property_add_const_link(OBJECT(spapr->ics), "xics", OBJECT(xics),
>> +                                   NULL);
>> +    object_property_set_bool(OBJECT(spapr->ics), true, "realized", &local_err);
>>      error_propagate(&err, local_err);
>>      if (err) {
>>          goto error;
>>      }
>> -    QLIST_INSERT_HEAD(&xics->ics, ics, list);
>> +    QLIST_INSERT_HEAD(&xics->ics, spapr->ics, list);
>>  
>>      xics->ss = g_malloc0(nr_servers * sizeof(ICPState));
>>      xics->nr_servers = nr_servers;
>> @@ -142,8 +143,8 @@ static XICSState *try_create_xics(const char *type, const char *type_ics,
>>  
>>  error:
>>      error_propagate(errp, err);
>> -    if (ics) {
>> -        object_unparent(OBJECT(ics));
>> +    if (spapr->ics) {
>> +        object_unparent(OBJECT(spapr->ics));
>>      }
>>      object_unparent(OBJECT(xics));
>>      return NULL;
>> @@ -158,7 +159,8 @@ static XICSState *xics_system_init(MachineState *machine,
>>          Error *err = NULL;
>>  
>>          if (machine_kernel_irqchip_allowed(machine)) {
>> -            xics = try_create_xics(TYPE_XICS_SPAPR_KVM, TYPE_ICS_KVM,
>> +            xics = try_create_xics(SPAPR_MACHINE(machine),
>> +                                   TYPE_XICS_SPAPR_KVM, TYPE_ICS_KVM,
>>                                     TYPE_KVM_ICP, nr_servers, nr_irqs, &err);
>>          }
>>          if (machine_kernel_irqchip_required(machine) && !xics) {
>> @@ -170,8 +172,9 @@ static XICSState *xics_system_init(MachineState *machine,
>>      }
>>  
>>      if (!xics) {
>> -        xics = try_create_xics(TYPE_XICS_SPAPR, TYPE_ICS_SIMPLE, TYPE_ICP,
>> -                               nr_servers, nr_irqs, errp);
>> +        xics = try_create_xics(SPAPR_MACHINE(machine),
>> +                               TYPE_XICS_SPAPR, TYPE_ICS_SIMPLE,
>> +                               TYPE_ICP, nr_servers, nr_irqs, errp);
>>      }
>>  
>>      return xics;
>> diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
>> index f85a9c32a7fc..38b4258a9be7 100644
>> --- a/hw/ppc/spapr_events.c
>> +++ b/hw/ppc/spapr_events.c
>> @@ -752,7 +752,7 @@ void spapr_events_init(sPAPRMachineState *spapr)
>>      spapr->event_sources = spapr_event_sources_new();
>>  
>>      spapr_event_sources_register(spapr->event_sources, EVENT_CLASS_EPOW,
>> -                                 xics_spapr_alloc(spapr->xics, 0, false,
>> +                                 spapr_ics_alloc(spapr->ics, 0, false,
>>                                                    &error_fatal));
>>  
>>      /* NOTE: if machine supports modern/dedicated hotplug event source,
>> @@ -765,7 +765,7 @@ void spapr_events_init(sPAPRMachineState *spapr)
>>       */
>>      if (spapr->use_hotplug_event_source) {
>>          spapr_event_sources_register(spapr->event_sources, EVENT_CLASS_HOT_PLUG,
>> -                                     xics_spapr_alloc(spapr->xics, 0, false,
>> +                                     spapr_ics_alloc(spapr->ics, 0, false,
>>                                                        &error_fatal));
>>      }
>>  
>> diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
>> index fd6fc1d95344..01d5c92425ed 100644
>> --- a/hw/ppc/spapr_pci.c
>> +++ b/hw/ppc/spapr_pci.c
>> @@ -325,7 +325,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
>>              return;
>>          }
>>  
>> -        xics_spapr_free(spapr->xics, msi->first_irq, msi->num);
>> +        spapr_ics_free(spapr->ics, msi->first_irq, msi->num);
>>          if (msi_present(pdev)) {
>>              spapr_msi_setmsg(pdev, 0, false, 0, 0);
>>          }
>> @@ -363,7 +363,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
>>      }
>>  
>>      /* Allocate MSIs */
>> -    irq = xics_spapr_alloc_block(spapr->xics, req_num, false,
>> +    irq = spapr_ics_alloc_block(spapr->ics, req_num, false,
>>                             ret_intr_type == RTAS_TYPE_MSI, &err);
>>      if (err) {
>>          error_reportf_err(err, "Can't allocate MSIs for device %x: ",
>> @@ -374,7 +374,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
>>  
>>      /* Release previous MSIs */
>>      if (msi) {
>> -        xics_spapr_free(spapr->xics, msi->first_irq, msi->num);
>> +        spapr_ics_free(spapr->ics, msi->first_irq, msi->num);
>>          g_hash_table_remove(phb->msi, &config_addr);
>>      }
>>  
>> @@ -1485,7 +1485,7 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
>>          uint32_t irq;
>>          Error *local_err = NULL;
>>  
>> -        irq = xics_spapr_alloc_block(spapr->xics, 1, true, false, &local_err);
>> +        irq = spapr_ics_alloc_block(spapr->ics, 1, true, false, &local_err);
>>          if (local_err) {
>>              error_propagate(errp, local_err);
>>              error_prepend(errp, "can't allocate LSIs: ");
>> diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c
>> index 8bfc5f971f8e..a0ee4fd26586 100644
>> --- a/hw/ppc/spapr_vio.c
>> +++ b/hw/ppc/spapr_vio.c
>> @@ -454,7 +454,7 @@ static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp)
>>          dev->qdev.id = id;
>>      }
>>  
>> -    dev->irq = xics_spapr_alloc(spapr->xics, dev->irq, false, &local_err);
>> +    dev->irq = spapr_ics_alloc(spapr->ics, dev->irq, false, &local_err);
>>      if (local_err) {
>>          error_propagate(errp, local_err);
>>          return;
>> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
>> index f9b17d860a75..21e506b13cfa 100644
>> --- a/include/hw/ppc/spapr.h
>> +++ b/include/hw/ppc/spapr.h
>> @@ -59,6 +59,7 @@ struct sPAPRMachineState {
>>      QLIST_HEAD(, sPAPRPHBState) phbs;
>>      struct sPAPRNVRAM *nvram;
>>      XICSState *xics;
>> +    ICSState *ics;
>>      DeviceState *rtc;
>>  
>>      void *htab;
>> diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
>> index fc4abcd4e796..6d443ce09dba 100644
>> --- a/include/hw/ppc/xics.h
>> +++ b/include/hw/ppc/xics.h
>> @@ -180,10 +180,10 @@ struct ICSIRQState {
>>  #define XICS_IRQS_SPAPR               1024
>>  
>>  qemu_irq xics_get_qirq(XICSState *icp, int irq);
>> -int xics_spapr_alloc(XICSState *icp, int irq_hint, bool lsi, Error **errp);
>> -int xics_spapr_alloc_block(XICSState *icp, int num, bool lsi, bool align,
>> +int spapr_ics_alloc(ICSState *ics, int irq_hint, bool lsi, Error **errp);
>> +int spapr_ics_alloc_block(ICSState *ics, int num, bool lsi, bool align,
>>                             Error **errp);
>> -void xics_spapr_free(XICSState *icp, int irq, int num);
>> +void spapr_ics_free(ICSState *ics, int irq, int num);
>>  void spapr_dt_xics(XICSState *xics, void *fdt, uint32_t phandle);
>>  
>>  void xics_cpu_setup(XICSState *icp, PowerPCCPU *cpu);
> 

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

* Re: [Qemu-devel] [Qemu-ppc] [PATCH v2 04/22] ppc/xics: add an InterruptStatsProvider interface to ICS and ICP objects
  2017-02-23  2:15   ` David Gibson
@ 2017-02-24 10:52     ` Cédric Le Goater
  2017-02-26 23:43       ` David Gibson
  0 siblings, 1 reply; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-24 10:52 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel

On 02/23/2017 03:15 AM, David Gibson wrote:
> On Thu, Feb 16, 2017 at 02:47:27PM +0100, Cédric Le Goater wrote:
>> This is, again, to reduce the use of the list of ICS objects. Let's
>> make each individual ICS and ICP object an InterruptStatsProvider and
>> remove this same interface from XICSState.
>>
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> 
> I'm a little hesitant about this, because it means that getting the
> interrupt stats information is now spread out over the qom tree,
> whereas previously there was a single location to get a good summary
> of the systems overall interrupt status.  The previous behaviour seems
> like it would be more convenient for debugging.
> 
> That said, I see the structural advantages of this split.  Hmm.. still
> thinking..

This is true. Another argument in favour of what you are saying 
is the order in which these are printed. See below.  

What we could do after the cleanup is to make the machine an 
InterruptStatsProvider to clarify things. 

Thanks,

C. 


(qemu) info pic 
CPU 18 XIRR=00000000 ((nil)) PP=ff MFRR=ff
CPU 0 XIRR=00000000 ((nil)) PP=ff MFRR=ff
CPU 21 XIRR=00000000 ((nil)) PP=ff MFRR=ff
CPU 2 XIRR=00000000 ((nil)) PP=ff MFRR=ff
CPU 23 XIRR=00000000 ((nil)) PP=ff MFRR=ff
CPU 4 XIRR=00000000 ((nil)) PP=ff MFRR=ff
CPU 11 XIRR=00000000 ((nil)) PP=ff MFRR=ff
CPU 25 XIRR=00000000 ((nil)) PP=ff MFRR=ff
CPU 6 XIRR=00000000 ((nil)) PP=ff MFRR=ff
CPU 13 XIRR=00000000 ((nil)) PP=ff MFRR=ff
CPU 27 XIRR=00000000 ((nil)) PP=ff MFRR=ff
CPU 8 XIRR=00000000 ((nil)) PP=ff MFRR=ff
CPU 15 XIRR=00000000 ((nil)) PP=ff MFRR=ff
CPU 29 XIRR=00000000 ((nil)) PP=ff MFRR=ff
CPU 30 XIRR=00000000 ((nil)) PP=ff MFRR=ff
CPU 17 XIRR=00000000 ((nil)) PP=ff MFRR=ff
CPU 20 XIRR=00000000 ((nil)) PP=ff MFRR=ff
CPU 19 XIRR=00000000 ((nil)) PP=ff MFRR=ff
CPU 1 XIRR=00000000 ((nil)) PP=ff MFRR=ff
ICS 1000..13ff 0x10018f1ea40
  1000 MSI ff 00
  1001 MSI ff 00
  1002 MSI ff 00
  1003 MSI ff 00
  1004 LSI ff 00
  1005 LSI ff 00
  1006 LSI ff 00
  1007 LSI ff 00
  1008 MSI ff 00
  1009 MSI ff 00
  100a MSI ff 00
  100b MSI ff 00
  100c MSI ff 00
CPU 22 XIRR=00000000 ((nil)) PP=ff MFRR=ff
CPU 3 XIRR=00000000 ((nil)) PP=ff MFRR=ff
CPU 10 XIRR=00000000 ((nil)) PP=ff MFRR=ff
CPU 24 XIRR=00000000 ((nil)) PP=ff MFRR=ff
CPU 5 XIRR=00000000 ((nil)) PP=ff MFRR=ff
CPU 12 XIRR=00000000 ((nil)) PP=ff MFRR=ff
CPU 26 XIRR=00000000 ((nil)) PP=ff MFRR=ff
CPU 7 XIRR=00000000 ((nil)) PP=ff MFRR=ff
CPU 14 XIRR=00000000 ((nil)) PP=ff MFRR=ff
CPU 28 XIRR=00000000 ((nil)) PP=ff MFRR=ff
CPU 9 XIRR=00000000 ((nil)) PP=ff MFRR=ff
CPU 16 XIRR=00000000 ((nil)) PP=ff MFRR=ff
CPU 31 XIRR=00000000 ((nil)) PP=ff MFRR=ff

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

* Re: [Qemu-devel] [PATCH v2 05/22] ppc/xics: introduce a QOM interface to handle ICSs
  2017-02-23  2:18   ` David Gibson
@ 2017-02-24 10:55     ` Cédric Le Goater
  0 siblings, 0 replies; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-24 10:55 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel

On 02/23/2017 03:18 AM, David Gibson wrote:
> On Thu, Feb 16, 2017 at 02:47:28PM +0100, Cédric Le Goater wrote:
>> This QOM interface provides two simple handlers. One is to get an ICS
>> object from an irq number and a second to resend the irqs when needed.
> 
> Maybe call this XICSFabric rather than XicsInterface.  While it's an
> interface from the QOM point-of-view, that doesn't really describe
> where it sits in the hardware model, and it's the ics and icp objects
> which provide all the interfaces which are visible to the guest or to
> interrupt generating devices.

Curiously, this is the only email that was not trashed by my bogus 
filters and so this is the only change I did in v3 ... 
 
C. 


> Apart from that,
> 
> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
> 
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>> ---
>>  hw/intc/xics.c        |  7 +++++++
>>  include/hw/ppc/xics.h | 18 ++++++++++++++++++
>>  2 files changed, 25 insertions(+)
>>
>> diff --git a/hw/intc/xics.c b/hw/intc/xics.c
>> index b1294417a0ae..3e80d2d0f0d9 100644
>> --- a/hw/intc/xics.c
>> +++ b/hw/intc/xics.c
>> @@ -726,6 +726,12 @@ static const TypeInfo ics_base_info = {
>>      .class_size = sizeof(ICSStateClass),
>>  };
>>  
>> +static const TypeInfo xics_interface_info = {
>> +    .name = TYPE_XICS_INTERFACE,
>> +    .parent = TYPE_INTERFACE,
>> +    .class_size = sizeof(XICSInterfaceClass),
>> +};
>> +
>>  /*
>>   * Exported functions
>>   */
>> @@ -766,6 +772,7 @@ static void xics_register_types(void)
>>      type_register_static(&ics_simple_info);
>>      type_register_static(&ics_base_info);
>>      type_register_static(&icp_info);
>> +    type_register_static(&xics_interface_info);
>>  }
>>  
>>  type_init(xics_register_types)
>> diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
>> index 6d443ce09dba..fe2bb5c8ef54 100644
>> --- a/include/hw/ppc/xics.h
>> +++ b/include/hw/ppc/xics.h
>> @@ -177,6 +177,24 @@ struct ICSIRQState {
>>      uint8_t flags;
>>  };
>>  
>> +typedef struct XICSInterface {
>> +    Object parent;
>> +} XICSInterface;
>> +
>> +#define TYPE_XICS_INTERFACE "xics-interface"
>> +#define XICS_INTERFACE(obj)                                     \
>> +    OBJECT_CHECK(XICSInterface, (obj), TYPE_XICS_INTERFACE)
>> +#define XICS_INTERFACE_CLASS(klass)                                     \
>> +    OBJECT_CLASS_CHECK(XICSInterfaceClass, (klass), TYPE_XICS_INTERFACE)
>> +#define XICS_INTERFACE_GET_CLASS(obj)                                   \
>> +    OBJECT_GET_CLASS(XICSInterfaceClass, (obj), TYPE_XICS_INTERFACE)
>> +
>> +typedef struct XICSInterfaceClass {
>> +    InterfaceClass parent;
>> +    ICSState *(*ics_get)(XICSInterface *xi, int irq);
>> +    void (*ics_resend)(XICSInterface *xi);
>> +} XICSInterfaceClass;
>> +
>>  #define XICS_IRQS_SPAPR               1024
>>  
>>  qemu_irq xics_get_qirq(XICSState *icp, int irq);
> 

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

* Re: [Qemu-devel] [Qemu-ppc] [PATCH v2 08/22] ppc/xics: use the QOM interface to resend irqs
  2017-02-23  2:29   ` David Gibson
@ 2017-02-24 11:12     ` Cédric Le Goater
  2017-02-24 17:34       ` Cédric Le Goater
  2017-02-27  0:30       ` David Gibson
  0 siblings, 2 replies; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-24 11:12 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel

On 02/23/2017 03:29 AM, David Gibson wrote:
> On Thu, Feb 16, 2017 at 02:47:31PM +0100, Cédric Le Goater wrote:
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>> ---
>>  hw/intc/xics.c | 26 ++++++++++++++------------
>>  1 file changed, 14 insertions(+), 12 deletions(-)
>>
>> diff --git a/hw/intc/xics.c b/hw/intc/xics.c
>> index 0ffdf09c5304..2decb921e4e3 100644
>> --- a/hw/intc/xics.c
>> +++ b/hw/intc/xics.c
>> @@ -229,16 +229,15 @@ static void icp_check_ipi(ICPState *ss)
>>      qemu_irq_raise(ss->output);
>>  }
>>  
>> -static void icp_resend(ICPState *ss)
>> +static void icp_resend(XICSInterface *xi, ICPState *ss)
>>  {
>> -    ICSState *ics;
>> +    XICSInterfaceClass *xic = XICS_INTERFACE_GET_CLASS(xi);
>>  
>>      if (ss->mfrr < CPPR(ss)) {
>>          icp_check_ipi(ss);
>>      }
>> -    QLIST_FOREACH(ics, &ss->xics->ics, list) {
>> -        ics_resend(ics);
>> -    }
>> +
>> +    xic->ics_resend(xi);
>>  }
>>  
>>  void icp_set_cppr(ICPState *ss, uint8_t cppr)
>> @@ -262,7 +261,7 @@ void icp_set_cppr(ICPState *ss, uint8_t cppr)
>>          }
>>      } else {
>>          if (!XISR(ss)) {
>> -            icp_resend(ss);
>> +            icp_resend(XICS_INTERFACE(qdev_get_machine()), ss);
> 
> Here you're assuming that the machine is the implementor of the xics
> interface, which is kinda ugly.  The ICP should have a pointer to the
> xics interface, which will eventually replace the pointer to the
> overall xics object it has now.

yes. I will try improve that. I don't like those calls to 
qdev_get_machine()either. 

There are done in a couple of places though, under spapr_cpu_core
to get XICS for instance.

> But I haven't read the rest of the series yet, maybe this is just
> transitional.
> 
>>          }
>>      }
>>  }
>> @@ -299,6 +298,8 @@ uint32_t icp_ipoll(ICPState *ss, uint32_t *mfrr)
>>  
>>  void icp_eoi(ICPState *ss, uint32_t xirr)
>>  {
>> +    XICSInterface *xi = XICS_INTERFACE(qdev_get_machine());
>> +    XICSInterfaceClass *xic = XICS_INTERFACE_GET_CLASS(xi);
>>      ICSState *ics;
>>      uint32_t irq;
>>  
>> @@ -306,13 +307,13 @@ void icp_eoi(ICPState *ss, uint32_t xirr)
>>      ss->xirr = (ss->xirr & ~CPPR_MASK) | (xirr & CPPR_MASK);
>>      trace_xics_icp_eoi(ss->cs->cpu_index, xirr, ss->xirr);
>>      irq = xirr & XISR_MASK;
>> -    QLIST_FOREACH(ics, &ss->xics->ics, list) {
>> -        if (ics_valid_irq(ics, irq)) {
>> -            ics_eoi(ics, irq);
>> -        }
>> +
>> +    ics = xic->ics_get(xi, irq);
>> +    if (ics) {
>> +        ics_eoi(ics, irq);
>>      }
>>      if (!XISR(ss)) {
>> -        icp_resend(ss);
>> +        icp_resend(xi, ss);
>>      }
>>  }
>>  
>> @@ -592,10 +593,11 @@ static void ics_simple_reset(DeviceState *dev)
>>  
>>  static int ics_simple_post_load(ICSState *ics, int version_id)
>>  {
>> +    XICSInterface *xi = XICS_INTERFACE(qdev_get_machine());
>>      int i;
>>  
>>      for (i = 0; i < ics->xics->nr_servers; i++) {
>> -        icp_resend(&ics->xics->ss[i]);
>> +        icp_resend(xi, &ics->xics->ss[i]);
>>      }
> 
> This resend triggering needs to get moved to the xics interface
> implementor - i.e. the machine.  It's actually already broken right
> now, since it incorrectly relies on the ordering of the ics and icp
> restore during migration.

I'm adding a icp_resend() handler in patch 12 and using it patch 14.
Maybe we can move the post_load() handler out of ICS simple now ? 

Thanks,

C. 

 
>>      return 0;
> 

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

* Re: [Qemu-devel] [Qemu-ppc] [PATCH v2 09/22] ppc/xics: remove xics_find_source()
  2017-02-23  2:31   ` David Gibson
@ 2017-02-24 11:13     ` Cédric Le Goater
  0 siblings, 0 replies; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-24 11:13 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel

On 02/23/2017 03:31 AM, David Gibson wrote:
> On Thu, Feb 16, 2017 at 02:47:32PM +0100, Cédric Le Goater wrote:
>> It is not used anymore now that we have the QOM interface for XICS.
>>
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> 
> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
> 
> Several of these patches are small enough that I wonder if they could
> be merged, though.

yes I could probably keep all the removal at the end. I will take
a look at that.

Thanks,

C. 

 
> 
>> ---
>>  hw/intc/xics.c        | 12 ------------
>>  include/hw/ppc/xics.h |  1 -
>>  2 files changed, 13 deletions(-)
>>
>> diff --git a/hw/intc/xics.c b/hw/intc/xics.c
>> index 2decb921e4e3..bfd3a539561a 100644
>> --- a/hw/intc/xics.c
>> +++ b/hw/intc/xics.c
>> @@ -737,18 +737,6 @@ static const TypeInfo xics_interface_info = {
>>  /*
>>   * Exported functions
>>   */
>> -ICSState *xics_find_source(XICSState *xics, int irq)
>> -{
>> -    ICSState *ics;
>> -
>> -    QLIST_FOREACH(ics, &xics->ics, list) {
>> -        if (ics_valid_irq(ics, irq)) {
>> -            return ics;
>> -        }
>> -    }
>> -    return NULL;
>> -}
>> -
>>  qemu_irq xics_get_qirq(XICSInterface *xi, int irq)
>>  {
>>      XICSInterfaceClass *xic = XICS_INTERFACE_GET_CLASS(xi);
>> diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
>> index 896fa5d87c1c..e10426e98e31 100644
>> --- a/include/hw/ppc/xics.h
>> +++ b/include/hw/ppc/xics.h
>> @@ -222,7 +222,6 @@ void ics_simple_write_xive(ICSState *ics, int nr, int server,
>>  
>>  void ics_set_irq_type(ICSState *ics, int srcno, bool lsi);
>>  
>> -ICSState *xics_find_source(XICSState *icp, int irq);
>>  void ics_resend(ICSState *ics);
>>  
>>  #endif /* XICS_H */
> 

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

* Re: [Qemu-devel] [Qemu-ppc] [PATCH v2 12/22] ppc/xics: extend the QOM interface to handle ICPs
  2017-02-23  2:39   ` David Gibson
@ 2017-02-24 11:15     ` Cédric Le Goater
  2017-02-27  0:57       ` David Gibson
  0 siblings, 1 reply; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-24 11:15 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel

On 02/23/2017 03:39 AM, David Gibson wrote:
> On Thu, Feb 16, 2017 at 02:47:35PM +0100, Cédric Le Goater wrote:
>> Let's add two new handlers for ICPs. One is to get an ICP object from
>> a server number and a second is to resend the irqs when needed.
>>
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>> ---
>>  hw/intc/xics.c        |  2 +-
>>  hw/ppc/spapr.c        | 20 ++++++++++++++++++++
>>  include/hw/ppc/xics.h |  3 +++
>>  3 files changed, 24 insertions(+), 1 deletion(-)
>>
>> diff --git a/hw/intc/xics.c b/hw/intc/xics.c
>> index 5131587ce088..7168c2cfd8a1 100644
>> --- a/hw/intc/xics.c
>> +++ b/hw/intc/xics.c
>> @@ -216,7 +216,7 @@ static void icp_check_ipi(ICPState *ss)
>>      qemu_irq_raise(ss->output);
>>  }
>>  
>> -static void icp_resend(XICSInterface *xi, ICPState *ss)
>> +void icp_resend(XICSInterface *xi, ICPState *ss)
>>  {
>>      XICSInterfaceClass *xic = XICS_INTERFACE_GET_CLASS(xi);
>>  
>> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
>> index d1946ebcac69..eb7da32296d8 100644
>> --- a/hw/ppc/spapr.c
>> +++ b/hw/ppc/spapr.c
>> @@ -2915,6 +2915,24 @@ static void spapr_ics_resend(XICSInterface *dev)
>>      ics_resend(spapr->ics);
>>  }
>>  
>> +static ICPState *spapr_icp_get(XICSInterface *xi, int server)
>> +{
>> +    sPAPRMachineState *spapr = SPAPR_MACHINE(xi);
>> +
>> +    return (server < spapr->xics->nr_servers) ? &spapr->xics->ss[server] :
>> +        NULL;
>> +}
>> +
>> +static void spapr_icp_resend(XICSInterface *xi)
>> +{
>> +    sPAPRMachineState *spapr = SPAPR_MACHINE(xi);
>> +    int i;
>> +
>> +    for (i = 0; i < spapr->xics->nr_servers; i++) {
>> +        icp_resend(xi, &spapr->xics->ss[i]);
>> +    }
>> +}
> 
> I'm not quite sure where you plan to use the resend hook.  AFAICT all
> the existing users of this path can do fine using icp_get() then
> icp_resend() directly.

This is for ics_simple_post_load().

C.

> 
>> +
>>  static void spapr_machine_class_init(ObjectClass *oc, void *data)
>>  {
>>      MachineClass *mc = MACHINE_CLASS(oc);
>> @@ -2959,6 +2977,8 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
>>      vhc->hypercall = emulate_spapr_hypercall;
>>      xic->ics_get = spapr_ics_get;
>>      xic->ics_resend = spapr_ics_resend;
>> +    xic->icp_get = spapr_icp_get;
>> +    xic->icp_resend = spapr_icp_resend;
>>  }
>>  
>>  static const TypeInfo spapr_machine_info = {
>> diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
>> index c15d8e2a8ae6..7004c851e250 100644
>> --- a/include/hw/ppc/xics.h
>> +++ b/include/hw/ppc/xics.h
>> @@ -191,6 +191,8 @@ typedef struct XICSInterfaceClass {
>>      InterfaceClass parent;
>>      ICSState *(*ics_get)(XICSInterface *xi, int irq);
>>      void (*ics_resend)(XICSInterface *xi);
>> +    ICPState *(*icp_get)(XICSInterface *xi, int server);
>> +    void (*icp_resend)(XICSInterface *xi);
>>  } XICSInterfaceClass;
>>  
>>  #define XICS_IRQS_SPAPR               1024
>> @@ -221,5 +223,6 @@ void ics_simple_write_xive(ICSState *ics, int nr, int server,
>>  void ics_set_irq_type(ICSState *ics, int srcno, bool lsi);
>>  
>>  void ics_resend(ICSState *ics);
>> +void icp_resend(XICSInterface *xi, ICPState *ss);
>>  
>>  #endif /* XICS_H */
> 

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

* Re: [Qemu-devel] [Qemu-ppc] [PATCH v2 16/22] ppc/xics: register the reset handler of ICP objects
  2017-02-23  2:42   ` David Gibson
@ 2017-02-24 11:27     ` Cédric Le Goater
  2017-02-27  1:00       ` David Gibson
  0 siblings, 1 reply; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-24 11:27 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel

On 02/23/2017 03:42 AM, David Gibson wrote:
> On Thu, Feb 16, 2017 at 02:47:39PM +0100, Cédric Le Goater wrote:
>> The reset of the ICP objects is currently handled by XICS but this can
>> be done for each individual ICP.
>>
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> 
> Hrm.  I think whether device_reset() gets called automatically depends
> on how the device is wired into the composition tree, and I'm not sure
> the icps are in the right place for it to work.

reset gets called only if it under sysbus or if you have registered 
a reset_handler. previously, XICS was a sysbus object so 
xics_common_reset() was getting called automatically.

> This doesn't replace the code in xics_common_reset() so if it does
> work it means we must have previously been resetting the ICPs twice.
> Is that right?

no. but there has been some confusion with the recent changes
on XICS.

What replace the code in xics_common_reset() is :

	qdev_set_parent_bus(DEVICE(icp), sysbus_get_default());

That's how the reset handlers get called from QOM objects. 

C.

>> ---
>>  hw/intc/xics.c | 18 ------------------
>>  hw/ppc/spapr.c |  1 +
>>  2 files changed, 1 insertion(+), 18 deletions(-)
>>
>> diff --git a/hw/intc/xics.c b/hw/intc/xics.c
>> index dd41340d41a5..3ad7e8cf8ec4 100644
>> --- a/hw/intc/xics.c
>> +++ b/hw/intc/xics.c
>> @@ -137,29 +137,11 @@ static void ics_simple_pic_print_info(InterruptStatsProvider *obj,
>>  /*
>>   * XICS Common class - parent for emulated XICS and KVM-XICS
>>   */
>> -static void xics_common_reset(DeviceState *d)
>> -{
>> -    XICSState *xics = XICS_COMMON(d);
>> -    int i;
>> -
>> -    for (i = 0; i < xics->nr_servers; i++) {
>> -        device_reset(DEVICE(&xics->ss[i]));
>> -    }
>> -}
>> -
>> -static void xics_common_class_init(ObjectClass *oc, void *data)
>> -{
>> -    DeviceClass *dc = DEVICE_CLASS(oc);
>> -
>> -    dc->reset = xics_common_reset;
>> -}
>> -
>>  static const TypeInfo xics_common_info = {
>>      .name          = TYPE_XICS_COMMON,
>>      .parent        = TYPE_DEVICE,
>>      .instance_size = sizeof(XICSState),
>>      .class_size    = sizeof(XICSStateClass),
>> -    .class_init    = xics_common_class_init,
>>  };
>>  
>>  /*
>> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
>> index 9c1772f93155..445d9a6ddad4 100644
>> --- a/hw/ppc/spapr.c
>> +++ b/hw/ppc/spapr.c
>> @@ -130,6 +130,7 @@ static XICSState *try_create_xics(sPAPRMachineState *spapr,
>>          ICPState *icp = &xics->ss[i];
>>  
>>          object_initialize(icp, sizeof(*icp), type_icp);
>> +        qdev_set_parent_bus(DEVICE(icp), sysbus_get_default());
>>          object_property_add_child(OBJECT(xics), "icp[*]", OBJECT(icp), NULL);
>>          object_property_add_const_link(OBJECT(icp), "xics", OBJECT(xics), NULL);
>>          object_property_set_bool(OBJECT(icp), true, "realized", &err);
> 

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

* Re: [Qemu-devel] [Qemu-ppc] [PATCH v2 08/22] ppc/xics: use the QOM interface to resend irqs
  2017-02-24 11:12     ` [Qemu-devel] [Qemu-ppc] " Cédric Le Goater
@ 2017-02-24 17:34       ` Cédric Le Goater
  2017-02-27  0:37         ` David Gibson
  2017-02-27  0:30       ` David Gibson
  1 sibling, 1 reply; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-24 17:34 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel

>>> @@ -592,10 +593,11 @@ static void ics_simple_reset(DeviceState *dev)
>>>  
>>>  static int ics_simple_post_load(ICSState *ics, int version_id)
>>>  {
>>> +    XICSInterface *xi = XICS_INTERFACE(qdev_get_machine());
>>>      int i;
>>>  
>>>      for (i = 0; i < ics->xics->nr_servers; i++) {
>>> -        icp_resend(&ics->xics->ss[i]);
>>> +        icp_resend(xi, &ics->xics->ss[i]);
>>>      }
>>
>> This resend triggering needs to get moved to the xics interface
>> implementor - i.e. the machine.  It's actually already broken right
>> now, since it incorrectly relies on the ordering of the ics and icp
>> restore during migration.
> 
> I'm adding a icp_resend() handler in patch 12 and using it patch 14.
> Maybe we can move the post_load() handler out of ICS simple now ? 

Could you give me a little more info on what should be done ? I lack 
context on this problem. 

So should we call : 

    ICPState *ss = opaque;
    ICPStateClass *info = ICP_GET_CLASS(ss);

    if (info->post_load) {
        return info->post_load(ss, version_id);
    }

and then 

    ICSState *ics = opaque;
    ICSStateClass *info = ICS_BASE_GET_CLASS(ics);

    if (info->post_load) {
        return info->post_load(ics, version_id);
    }

from spapr_post_load() ? 

Thanks,

C.

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

* Re: [Qemu-devel] [Qemu-ppc] [PATCH v2 04/22] ppc/xics: add an InterruptStatsProvider interface to ICS and ICP objects
  2017-02-24 10:52     ` [Qemu-devel] [Qemu-ppc] " Cédric Le Goater
@ 2017-02-26 23:43       ` David Gibson
  2017-02-27  8:48         ` Cédric Le Goater
  0 siblings, 1 reply; 59+ messages in thread
From: David Gibson @ 2017-02-26 23:43 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Fri, Feb 24, 2017 at 11:52:01AM +0100, Cédric Le Goater wrote:
> On 02/23/2017 03:15 AM, David Gibson wrote:
> > On Thu, Feb 16, 2017 at 02:47:27PM +0100, Cédric Le Goater wrote:
> >> This is, again, to reduce the use of the list of ICS objects. Let's
> >> make each individual ICS and ICP object an InterruptStatsProvider and
> >> remove this same interface from XICSState.
> >>
> >> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> > 
> > I'm a little hesitant about this, because it means that getting the
> > interrupt stats information is now spread out over the qom tree,
> > whereas previously there was a single location to get a good summary
> > of the systems overall interrupt status.  The previous behaviour seems
> > like it would be more convenient for debugging.
> > 
> > That said, I see the structural advantages of this split.  Hmm.. still
> > thinking..
> 
> This is true. Another argument in favour of what you are saying 
> is the order in which these are printed. See below.  
> 
> What we could do after the cleanup is to make the machine an 
> InterruptStatsProvider to clarify things.

Right.  So "info pic" does at least iterate through all the providers,
but the semi-random order is pretty icky.  I think putting the stats
provider on the machine would be a better idea - I guess it should be
easy enough if the xics code provides a helper.

> 
> Thanks,
> 
> C. 
> 
> 
> (qemu) info pic 
> CPU 18 XIRR=00000000 ((nil)) PP=ff MFRR=ff
> CPU 0 XIRR=00000000 ((nil)) PP=ff MFRR=ff
> CPU 21 XIRR=00000000 ((nil)) PP=ff MFRR=ff
> CPU 2 XIRR=00000000 ((nil)) PP=ff MFRR=ff
> CPU 23 XIRR=00000000 ((nil)) PP=ff MFRR=ff
> CPU 4 XIRR=00000000 ((nil)) PP=ff MFRR=ff
> CPU 11 XIRR=00000000 ((nil)) PP=ff MFRR=ff
> CPU 25 XIRR=00000000 ((nil)) PP=ff MFRR=ff
> CPU 6 XIRR=00000000 ((nil)) PP=ff MFRR=ff
> CPU 13 XIRR=00000000 ((nil)) PP=ff MFRR=ff
> CPU 27 XIRR=00000000 ((nil)) PP=ff MFRR=ff
> CPU 8 XIRR=00000000 ((nil)) PP=ff MFRR=ff
> CPU 15 XIRR=00000000 ((nil)) PP=ff MFRR=ff
> CPU 29 XIRR=00000000 ((nil)) PP=ff MFRR=ff
> CPU 30 XIRR=00000000 ((nil)) PP=ff MFRR=ff
> CPU 17 XIRR=00000000 ((nil)) PP=ff MFRR=ff
> CPU 20 XIRR=00000000 ((nil)) PP=ff MFRR=ff
> CPU 19 XIRR=00000000 ((nil)) PP=ff MFRR=ff
> CPU 1 XIRR=00000000 ((nil)) PP=ff MFRR=ff
> ICS 1000..13ff 0x10018f1ea40
>   1000 MSI ff 00
>   1001 MSI ff 00
>   1002 MSI ff 00
>   1003 MSI ff 00
>   1004 LSI ff 00
>   1005 LSI ff 00
>   1006 LSI ff 00
>   1007 LSI ff 00
>   1008 MSI ff 00
>   1009 MSI ff 00
>   100a MSI ff 00
>   100b MSI ff 00
>   100c MSI ff 00
> CPU 22 XIRR=00000000 ((nil)) PP=ff MFRR=ff
> CPU 3 XIRR=00000000 ((nil)) PP=ff MFRR=ff
> CPU 10 XIRR=00000000 ((nil)) PP=ff MFRR=ff
> CPU 24 XIRR=00000000 ((nil)) PP=ff MFRR=ff
> CPU 5 XIRR=00000000 ((nil)) PP=ff MFRR=ff
> CPU 12 XIRR=00000000 ((nil)) PP=ff MFRR=ff
> CPU 26 XIRR=00000000 ((nil)) PP=ff MFRR=ff
> CPU 7 XIRR=00000000 ((nil)) PP=ff MFRR=ff
> CPU 14 XIRR=00000000 ((nil)) PP=ff MFRR=ff
> CPU 28 XIRR=00000000 ((nil)) PP=ff MFRR=ff
> CPU 9 XIRR=00000000 ((nil)) PP=ff MFRR=ff
> CPU 16 XIRR=00000000 ((nil)) PP=ff MFRR=ff
> CPU 31 XIRR=00000000 ((nil)) PP=ff MFRR=ff
> 
> 

-- 
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: 819 bytes --]

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

* Re: [Qemu-devel] [Qemu-ppc] [PATCH v2 08/22] ppc/xics: use the QOM interface to resend irqs
  2017-02-24 11:12     ` [Qemu-devel] [Qemu-ppc] " Cédric Le Goater
  2017-02-24 17:34       ` Cédric Le Goater
@ 2017-02-27  0:30       ` David Gibson
  2017-02-27  8:45         ` Cédric Le Goater
  1 sibling, 1 reply; 59+ messages in thread
From: David Gibson @ 2017-02-27  0:30 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Fri, Feb 24, 2017 at 12:12:54PM +0100, Cédric Le Goater wrote:
> On 02/23/2017 03:29 AM, David Gibson wrote:
> > On Thu, Feb 16, 2017 at 02:47:31PM +0100, Cédric Le Goater wrote:
> >> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> >> ---
> >>  hw/intc/xics.c | 26 ++++++++++++++------------
> >>  1 file changed, 14 insertions(+), 12 deletions(-)
> >>
> >> diff --git a/hw/intc/xics.c b/hw/intc/xics.c
> >> index 0ffdf09c5304..2decb921e4e3 100644
> >> --- a/hw/intc/xics.c
> >> +++ b/hw/intc/xics.c
> >> @@ -229,16 +229,15 @@ static void icp_check_ipi(ICPState *ss)
> >>      qemu_irq_raise(ss->output);
> >>  }
> >>  
> >> -static void icp_resend(ICPState *ss)
> >> +static void icp_resend(XICSInterface *xi, ICPState *ss)
> >>  {
> >> -    ICSState *ics;
> >> +    XICSInterfaceClass *xic = XICS_INTERFACE_GET_CLASS(xi);
> >>  
> >>      if (ss->mfrr < CPPR(ss)) {
> >>          icp_check_ipi(ss);
> >>      }
> >> -    QLIST_FOREACH(ics, &ss->xics->ics, list) {
> >> -        ics_resend(ics);
> >> -    }
> >> +
> >> +    xic->ics_resend(xi);
> >>  }
> >>  
> >>  void icp_set_cppr(ICPState *ss, uint8_t cppr)
> >> @@ -262,7 +261,7 @@ void icp_set_cppr(ICPState *ss, uint8_t cppr)
> >>          }
> >>      } else {
> >>          if (!XISR(ss)) {
> >> -            icp_resend(ss);
> >> +            icp_resend(XICS_INTERFACE(qdev_get_machine()), ss);
> > 
> > Here you're assuming that the machine is the implementor of the xics
> > interface, which is kinda ugly.  The ICP should have a pointer to the
> > xics interface, which will eventually replace the pointer to the
> > overall xics object it has now.
> 
> yes. I will try improve that. I don't like those calls to 
> qdev_get_machine()either. 
> 
> There are done in a couple of places though, under spapr_cpu_core
> to get XICS for instance.

Right, but I'm happier with it there, in code that's definitely
associated with a particular machine, rather than in the xics code
which is at least somewhat reusable.

> > But I haven't read the rest of the series yet, maybe this is just
> > transitional.
> > 
> >>          }
> >>      }
> >>  }
> >> @@ -299,6 +298,8 @@ uint32_t icp_ipoll(ICPState *ss, uint32_t *mfrr)
> >>  
> >>  void icp_eoi(ICPState *ss, uint32_t xirr)
> >>  {
> >> +    XICSInterface *xi = XICS_INTERFACE(qdev_get_machine());
> >> +    XICSInterfaceClass *xic = XICS_INTERFACE_GET_CLASS(xi);
> >>      ICSState *ics;
> >>      uint32_t irq;
> >>  
> >> @@ -306,13 +307,13 @@ void icp_eoi(ICPState *ss, uint32_t xirr)
> >>      ss->xirr = (ss->xirr & ~CPPR_MASK) | (xirr & CPPR_MASK);
> >>      trace_xics_icp_eoi(ss->cs->cpu_index, xirr, ss->xirr);
> >>      irq = xirr & XISR_MASK;
> >> -    QLIST_FOREACH(ics, &ss->xics->ics, list) {
> >> -        if (ics_valid_irq(ics, irq)) {
> >> -            ics_eoi(ics, irq);
> >> -        }
> >> +
> >> +    ics = xic->ics_get(xi, irq);
> >> +    if (ics) {
> >> +        ics_eoi(ics, irq);
> >>      }
> >>      if (!XISR(ss)) {
> >> -        icp_resend(ss);
> >> +        icp_resend(xi, ss);
> >>      }
> >>  }
> >>  
> >> @@ -592,10 +593,11 @@ static void ics_simple_reset(DeviceState *dev)
> >>  
> >>  static int ics_simple_post_load(ICSState *ics, int version_id)
> >>  {
> >> +    XICSInterface *xi = XICS_INTERFACE(qdev_get_machine());
> >>      int i;
> >>  
> >>      for (i = 0; i < ics->xics->nr_servers; i++) {
> >> -        icp_resend(&ics->xics->ss[i]);
> >> +        icp_resend(xi, &ics->xics->ss[i]);
> >>      }
> > 
> > This resend triggering needs to get moved to the xics interface
> > implementor - i.e. the machine.  It's actually already broken right
> > now, since it incorrectly relies on the ordering of the ics and icp
> > restore during migration.
> 
> I'm adding a icp_resend() handler in patch 12 and using it patch 14.
> Maybe we can move the post_load() handler out of ICS simple now ? 
> 
> Thanks,
> 
> C. 
> 
>  
> >>      return 0;
> > 
> 

-- 
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: 819 bytes --]

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

* Re: [Qemu-devel] [Qemu-ppc] [PATCH v2 08/22] ppc/xics: use the QOM interface to resend irqs
  2017-02-24 17:34       ` Cédric Le Goater
@ 2017-02-27  0:37         ` David Gibson
  0 siblings, 0 replies; 59+ messages in thread
From: David Gibson @ 2017-02-27  0:37 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Fri, Feb 24, 2017 at 06:34:06PM +0100, Cédric Le Goater wrote:
> >>> @@ -592,10 +593,11 @@ static void ics_simple_reset(DeviceState *dev)
> >>>  
> >>>  static int ics_simple_post_load(ICSState *ics, int version_id)
> >>>  {
> >>> +    XICSInterface *xi = XICS_INTERFACE(qdev_get_machine());
> >>>      int i;
> >>>  
> >>>      for (i = 0; i < ics->xics->nr_servers; i++) {
> >>> -        icp_resend(&ics->xics->ss[i]);
> >>> +        icp_resend(xi, &ics->xics->ss[i]);
> >>>      }
> >>
> >> This resend triggering needs to get moved to the xics interface
> >> implementor - i.e. the machine.  It's actually already broken right
> >> now, since it incorrectly relies on the ordering of the ics and icp
> >> restore during migration.
> > 
> > I'm adding a icp_resend() handler in patch 12 and using it patch 14.
> > Maybe we can move the post_load() handler out of ICS simple now ? 
> 
> Could you give me a little more info on what should be done ? I lack 
> context on this problem. 
> 
> So should we call : 
> 
>     ICPState *ss = opaque;
>     ICPStateClass *info = ICP_GET_CLASS(ss);
> 
>     if (info->post_load) {
>         return info->post_load(ss, version_id);
>     }
> 
> and then 
> 
>     ICSState *ics = opaque;
>     ICSStateClass *info = ICS_BASE_GET_CLASS(ics);
> 
>     if (info->post_load) {
>         return info->post_load(ics, version_id);
>     }
> 
> from spapr_post_load() ? 

Uh.. now I'm trying to remember what the correct order is.  Any part
of the post_load which is entirely local to the ics or icp, and
doesn't communicate with the other part should remain in a local
post-load handler.

The part of the resend which involves interaction between ics and icp
should move to the mahine.  Because the ics and icp are both
descendents of the machine, the migration core does guarantee their
local post_lodas will run before the machine's post-load.  At the
moment however, we require either the ics post_loads to run before the
icp or the other way around - I forget which.  Because these are
"cousin" objects, that order is not guaranteed by the migration core.

-- 
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: 819 bytes --]

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

* Re: [Qemu-devel] [Qemu-ppc] [PATCH v2 12/22] ppc/xics: extend the QOM interface to handle ICPs
  2017-02-24 11:15     ` [Qemu-devel] [Qemu-ppc] " Cédric Le Goater
@ 2017-02-27  0:57       ` David Gibson
  0 siblings, 0 replies; 59+ messages in thread
From: David Gibson @ 2017-02-27  0:57 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Fri, Feb 24, 2017 at 12:15:21PM +0100, Cédric Le Goater wrote:
> On 02/23/2017 03:39 AM, David Gibson wrote:
> > On Thu, Feb 16, 2017 at 02:47:35PM +0100, Cédric Le Goater wrote:
> >> Let's add two new handlers for ICPs. One is to get an ICP object from
> >> a server number and a second is to resend the irqs when needed.
> >>
> >> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> >> ---
> >>  hw/intc/xics.c        |  2 +-
> >>  hw/ppc/spapr.c        | 20 ++++++++++++++++++++
> >>  include/hw/ppc/xics.h |  3 +++
> >>  3 files changed, 24 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/hw/intc/xics.c b/hw/intc/xics.c
> >> index 5131587ce088..7168c2cfd8a1 100644
> >> --- a/hw/intc/xics.c
> >> +++ b/hw/intc/xics.c
> >> @@ -216,7 +216,7 @@ static void icp_check_ipi(ICPState *ss)
> >>      qemu_irq_raise(ss->output);
> >>  }
> >>  
> >> -static void icp_resend(XICSInterface *xi, ICPState *ss)
> >> +void icp_resend(XICSInterface *xi, ICPState *ss)
> >>  {
> >>      XICSInterfaceClass *xic = XICS_INTERFACE_GET_CLASS(xi);
> >>  
> >> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> >> index d1946ebcac69..eb7da32296d8 100644
> >> --- a/hw/ppc/spapr.c
> >> +++ b/hw/ppc/spapr.c
> >> @@ -2915,6 +2915,24 @@ static void spapr_ics_resend(XICSInterface *dev)
> >>      ics_resend(spapr->ics);
> >>  }
> >>  
> >> +static ICPState *spapr_icp_get(XICSInterface *xi, int server)
> >> +{
> >> +    sPAPRMachineState *spapr = SPAPR_MACHINE(xi);
> >> +
> >> +    return (server < spapr->xics->nr_servers) ? &spapr->xics->ss[server] :
> >> +        NULL;
> >> +}
> >> +
> >> +static void spapr_icp_resend(XICSInterface *xi)
> >> +{
> >> +    sPAPRMachineState *spapr = SPAPR_MACHINE(xi);
> >> +    int i;
> >> +
> >> +    for (i = 0; i < spapr->xics->nr_servers; i++) {
> >> +        icp_resend(xi, &spapr->xics->ss[i]);
> >> +    }
> >> +}
> > 
> > I'm not quite sure where you plan to use the resend hook.  AFAICT all
> > the existing users of this path can do fine using icp_get() then
> > icp_resend() directly.
> 
> This is for ics_simple_post_load().

Ah, right.  That's the bit that involves co-ordination between ICS and
ICP.  It should therefore move to the machine (well, xics fabric
implementor) so you shouldn't need this callback in the end anyway.

> 
> C.
> 
> > 
> >> +
> >>  static void spapr_machine_class_init(ObjectClass *oc, void *data)
> >>  {
> >>      MachineClass *mc = MACHINE_CLASS(oc);
> >> @@ -2959,6 +2977,8 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
> >>      vhc->hypercall = emulate_spapr_hypercall;
> >>      xic->ics_get = spapr_ics_get;
> >>      xic->ics_resend = spapr_ics_resend;
> >> +    xic->icp_get = spapr_icp_get;
> >> +    xic->icp_resend = spapr_icp_resend;
> >>  }
> >>  
> >>  static const TypeInfo spapr_machine_info = {
> >> diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
> >> index c15d8e2a8ae6..7004c851e250 100644
> >> --- a/include/hw/ppc/xics.h
> >> +++ b/include/hw/ppc/xics.h
> >> @@ -191,6 +191,8 @@ typedef struct XICSInterfaceClass {
> >>      InterfaceClass parent;
> >>      ICSState *(*ics_get)(XICSInterface *xi, int irq);
> >>      void (*ics_resend)(XICSInterface *xi);
> >> +    ICPState *(*icp_get)(XICSInterface *xi, int server);
> >> +    void (*icp_resend)(XICSInterface *xi);
> >>  } XICSInterfaceClass;
> >>  
> >>  #define XICS_IRQS_SPAPR               1024
> >> @@ -221,5 +223,6 @@ void ics_simple_write_xive(ICSState *ics, int nr, int server,
> >>  void ics_set_irq_type(ICSState *ics, int srcno, bool lsi);
> >>  
> >>  void ics_resend(ICSState *ics);
> >> +void icp_resend(XICSInterface *xi, ICPState *ss);
> >>  
> >>  #endif /* XICS_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: 819 bytes --]

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

* Re: [Qemu-devel] [Qemu-ppc] [PATCH v2 16/22] ppc/xics: register the reset handler of ICP objects
  2017-02-24 11:27     ` [Qemu-devel] [Qemu-ppc] " Cédric Le Goater
@ 2017-02-27  1:00       ` David Gibson
  2017-02-27  9:21         ` Cédric Le Goater
  0 siblings, 1 reply; 59+ messages in thread
From: David Gibson @ 2017-02-27  1:00 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Fri, Feb 24, 2017 at 12:27:35PM +0100, Cédric Le Goater wrote:
> On 02/23/2017 03:42 AM, David Gibson wrote:
> > On Thu, Feb 16, 2017 at 02:47:39PM +0100, Cédric Le Goater wrote:
> >> The reset of the ICP objects is currently handled by XICS but this can
> >> be done for each individual ICP.
> >>
> >> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> > 
> > Hrm.  I think whether device_reset() gets called automatically depends
> > on how the device is wired into the composition tree, and I'm not sure
> > the icps are in the right place for it to work.
> 
> reset gets called only if it under sysbus or if you have registered 
> a reset_handler. previously, XICS was a sysbus object so 
> xics_common_reset() was getting called automatically.

Right.  Hmm.  So I think artificially placing the ics under the sysbus
is not the right way to get the reset called - I think explicitly
registering a reset handler is better.

The only thing that concerns me about that is that the MMIO ICS
variants we'll want for powernv really _do_ have a bus presence,
either on sysbus or some descendent, so that will get its reset called
automatically.  I'm not sure what the best way to ensure the reset
gets called exactly once in all cases.

> > This doesn't replace the code in xics_common_reset() so if it does
> > work it means we must have previously been resetting the ICPs twice.
> > Is that right?
> 
> no. but there has been some confusion with the recent changes
> on XICS.
> 
> What replace the code in xics_common_reset() is :
> 
> 	qdev_set_parent_bus(DEVICE(icp), sysbus_get_default());
> 
> That's how the reset handlers get called from QOM objects.

Right, I saw that later on.

> 
> C.
> 
> >> ---
> >>  hw/intc/xics.c | 18 ------------------
> >>  hw/ppc/spapr.c |  1 +
> >>  2 files changed, 1 insertion(+), 18 deletions(-)
> >>
> >> diff --git a/hw/intc/xics.c b/hw/intc/xics.c
> >> index dd41340d41a5..3ad7e8cf8ec4 100644
> >> --- a/hw/intc/xics.c
> >> +++ b/hw/intc/xics.c
> >> @@ -137,29 +137,11 @@ static void ics_simple_pic_print_info(InterruptStatsProvider *obj,
> >>  /*
> >>   * XICS Common class - parent for emulated XICS and KVM-XICS
> >>   */
> >> -static void xics_common_reset(DeviceState *d)
> >> -{
> >> -    XICSState *xics = XICS_COMMON(d);
> >> -    int i;
> >> -
> >> -    for (i = 0; i < xics->nr_servers; i++) {
> >> -        device_reset(DEVICE(&xics->ss[i]));
> >> -    }
> >> -}
> >> -
> >> -static void xics_common_class_init(ObjectClass *oc, void *data)
> >> -{
> >> -    DeviceClass *dc = DEVICE_CLASS(oc);
> >> -
> >> -    dc->reset = xics_common_reset;
> >> -}
> >> -
> >>  static const TypeInfo xics_common_info = {
> >>      .name          = TYPE_XICS_COMMON,
> >>      .parent        = TYPE_DEVICE,
> >>      .instance_size = sizeof(XICSState),
> >>      .class_size    = sizeof(XICSStateClass),
> >> -    .class_init    = xics_common_class_init,
> >>  };
> >>  
> >>  /*
> >> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> >> index 9c1772f93155..445d9a6ddad4 100644
> >> --- a/hw/ppc/spapr.c
> >> +++ b/hw/ppc/spapr.c
> >> @@ -130,6 +130,7 @@ static XICSState *try_create_xics(sPAPRMachineState *spapr,
> >>          ICPState *icp = &xics->ss[i];
> >>  
> >>          object_initialize(icp, sizeof(*icp), type_icp);
> >> +        qdev_set_parent_bus(DEVICE(icp), sysbus_get_default());
> >>          object_property_add_child(OBJECT(xics), "icp[*]", OBJECT(icp), NULL);
> >>          object_property_add_const_link(OBJECT(icp), "xics", OBJECT(xics), NULL);
> >>          object_property_set_bool(OBJECT(icp), true, "realized", &err);
> > 
> 

-- 
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: 819 bytes --]

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

* Re: [Qemu-devel] [Qemu-ppc] [PATCH v2 08/22] ppc/xics: use the QOM interface to resend irqs
  2017-02-27  0:30       ` David Gibson
@ 2017-02-27  8:45         ` Cédric Le Goater
  0 siblings, 0 replies; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-27  8:45 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel

>>>>  void icp_set_cppr(ICPState *ss, uint8_t cppr)
>>>> @@ -262,7 +261,7 @@ void icp_set_cppr(ICPState *ss, uint8_t cppr)
>>>>          }
>>>>      } else {
>>>>          if (!XISR(ss)) {
>>>> -            icp_resend(ss);
>>>> +            icp_resend(XICS_INTERFACE(qdev_get_machine()), ss);
>>>
>>> Here you're assuming that the machine is the implementor of the xics
>>> interface, which is kinda ugly.  The ICP should have a pointer to the
>>> xics interface, which will eventually replace the pointer to the
>>> overall xics object it has now.
>>
>> yes. I will try improve that. I don't like those calls to 
>> qdev_get_machine()either. 
>>
>> There are done in a couple of places though, under spapr_cpu_core
>> to get XICS for instance.
> 
> Right, but I'm happier with it there, in code that's definitely
> associated with a particular machine, rather than in the xics code
> which is at least somewhat reusable.

I fixed that with the backlink on the XICSFabric. 

C.

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

* Re: [Qemu-devel] [Qemu-ppc] [PATCH v2 04/22] ppc/xics: add an InterruptStatsProvider interface to ICS and ICP objects
  2017-02-26 23:43       ` David Gibson
@ 2017-02-27  8:48         ` Cédric Le Goater
  0 siblings, 0 replies; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-27  8:48 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel

On 02/27/2017 12:43 AM, David Gibson wrote:
> On Fri, Feb 24, 2017 at 11:52:01AM +0100, Cédric Le Goater wrote:
>> On 02/23/2017 03:15 AM, David Gibson wrote:
>>> On Thu, Feb 16, 2017 at 02:47:27PM +0100, Cédric Le Goater wrote:
>>>> This is, again, to reduce the use of the list of ICS objects. Let's
>>>> make each individual ICS and ICP object an InterruptStatsProvider and
>>>> remove this same interface from XICSState.
>>>>
>>>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>>>
>>> I'm a little hesitant about this, because it means that getting the
>>> interrupt stats information is now spread out over the qom tree,
>>> whereas previously there was a single location to get a good summary
>>> of the systems overall interrupt status.  The previous behaviour seems
>>> like it would be more convenient for debugging.
>>>
>>> That said, I see the structural advantages of this split.  Hmm.. still
>>> thinking..
>>
>> This is true. Another argument in favour of what you are saying 
>> is the order in which these are printed. See below.  
>>
>> What we could do after the cleanup is to make the machine an 
>> InterruptStatsProvider to clarify things.
> 
> Right.  So "info pic" does at least iterate through all the providers,
> but the semi-random order is pretty icky.  I think putting the stats
> provider on the machine would be a better idea - I guess it should be
> easy enough if the xics code provides a helper.

OK. This is on my TODO list for the next version of the patchset but as 
a followup patch. I don't want to change too much the initial cleanups
as he took me a while to find a working path to redo XICS. 

Thanks,

C.

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

* Re: [Qemu-devel] [Qemu-ppc] [PATCH v2 16/22] ppc/xics: register the reset handler of ICP objects
  2017-02-27  1:00       ` David Gibson
@ 2017-02-27  9:21         ` Cédric Le Goater
  0 siblings, 0 replies; 59+ messages in thread
From: Cédric Le Goater @ 2017-02-27  9:21 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Peter Maydell

[ adding Peter for some insights ] 

On 02/27/2017 02:00 AM, David Gibson wrote:
> On Fri, Feb 24, 2017 at 12:27:35PM +0100, Cédric Le Goater wrote:
>> On 02/23/2017 03:42 AM, David Gibson wrote:
>>> On Thu, Feb 16, 2017 at 02:47:39PM +0100, Cédric Le Goater wrote:
>>>> The reset of the ICP objects is currently handled by XICS but this can
>>>> be done for each individual ICP.
>>>>
>>>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>>>
>>> Hrm.  I think whether device_reset() gets called automatically depends
>>> on how the device is wired into the composition tree, and I'm not sure
>>> the icps are in the right place for it to work.
>>
>> reset gets called only if it under sysbus or if you have registered 
>> a reset_handler. previously, XICS was a sysbus object so 
>> xics_common_reset() was getting called automatically.
> 
> Right.  Hmm.  So I think artificially placing the ics under the sysbus
> is not the right way to get the reset called - I think explicitly
> registering a reset handler is better.
> 
> The only thing that concerns me about that is that the MMIO ICS
> variants we'll want for powernv really _do_ have a bus presence,
> either on sysbus or some descendent, so that will get its reset called
> automatically.  I'm not sure what the best way to ensure the reset
> gets called exactly once in all cases.

Well, I am not sure either. I have reproduced this pattern as it is 
frequently used under ARM which has quite a few QOM'ified machines.

Thanks,

C. 

>>> This doesn't replace the code in xics_common_reset() so if it does
>>> work it means we must have previously been resetting the ICPs twice.
>>> Is that right?
>>
>> no. but there has been some confusion with the recent changes
>> on XICS.
>>
>> What replace the code in xics_common_reset() is :
>>
>> 	qdev_set_parent_bus(DEVICE(icp), sysbus_get_default());
>>
>> That's how the reset handlers get called from QOM objects.
> 
> Right, I saw that later on.
> 
>>
>> C.
>>
>>>> ---
>>>>  hw/intc/xics.c | 18 ------------------
>>>>  hw/ppc/spapr.c |  1 +
>>>>  2 files changed, 1 insertion(+), 18 deletions(-)
>>>>
>>>> diff --git a/hw/intc/xics.c b/hw/intc/xics.c
>>>> index dd41340d41a5..3ad7e8cf8ec4 100644
>>>> --- a/hw/intc/xics.c
>>>> +++ b/hw/intc/xics.c
>>>> @@ -137,29 +137,11 @@ static void ics_simple_pic_print_info(InterruptStatsProvider *obj,
>>>>  /*
>>>>   * XICS Common class - parent for emulated XICS and KVM-XICS
>>>>   */
>>>> -static void xics_common_reset(DeviceState *d)
>>>> -{
>>>> -    XICSState *xics = XICS_COMMON(d);
>>>> -    int i;
>>>> -
>>>> -    for (i = 0; i < xics->nr_servers; i++) {
>>>> -        device_reset(DEVICE(&xics->ss[i]));
>>>> -    }
>>>> -}
>>>> -
>>>> -static void xics_common_class_init(ObjectClass *oc, void *data)
>>>> -{
>>>> -    DeviceClass *dc = DEVICE_CLASS(oc);
>>>> -
>>>> -    dc->reset = xics_common_reset;
>>>> -}
>>>> -
>>>>  static const TypeInfo xics_common_info = {
>>>>      .name          = TYPE_XICS_COMMON,
>>>>      .parent        = TYPE_DEVICE,
>>>>      .instance_size = sizeof(XICSState),
>>>>      .class_size    = sizeof(XICSStateClass),
>>>> -    .class_init    = xics_common_class_init,
>>>>  };
>>>>  
>>>>  /*
>>>> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
>>>> index 9c1772f93155..445d9a6ddad4 100644
>>>> --- a/hw/ppc/spapr.c
>>>> +++ b/hw/ppc/spapr.c
>>>> @@ -130,6 +130,7 @@ static XICSState *try_create_xics(sPAPRMachineState *spapr,
>>>>          ICPState *icp = &xics->ss[i];
>>>>  
>>>>          object_initialize(icp, sizeof(*icp), type_icp);
>>>> +        qdev_set_parent_bus(DEVICE(icp), sysbus_get_default());
>>>>          object_property_add_child(OBJECT(xics), "icp[*]", OBJECT(icp), NULL);
>>>>          object_property_add_const_link(OBJECT(icp), "xics", OBJECT(xics), NULL);
>>>>          object_property_set_bool(OBJECT(icp), true, "realized", &err);
>>>
>>
> 

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

end of thread, other threads:[~2017-02-27  9:21 UTC | newest]

Thread overview: 59+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-16 13:47 [Qemu-devel] [PATCH v2 00/22] ppc/xics: simplify ICS and ICP creation Cédric Le Goater
2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 01/22] ppc/xics: remove set_nr_irqs() handler from XICSStateClass Cédric Le Goater
2017-02-22  3:21   ` David Gibson
2017-02-24 10:46     ` Cédric Le Goater
2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 02/22] ppc/xics: remove set_nr_servers() " Cédric Le Goater
2017-02-22  6:23   ` David Gibson
2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 03/22] ppc/xics: store the ICS object under the sPAPR machine Cédric Le Goater
2017-02-22  6:59   ` David Gibson
2017-02-24 10:47     ` Cédric Le Goater
2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 04/22] ppc/xics: add an InterruptStatsProvider interface to ICS and ICP objects Cédric Le Goater
2017-02-23  2:15   ` David Gibson
2017-02-24 10:52     ` [Qemu-devel] [Qemu-ppc] " Cédric Le Goater
2017-02-26 23:43       ` David Gibson
2017-02-27  8:48         ` Cédric Le Goater
2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 05/22] ppc/xics: introduce a QOM interface to handle ICSs Cédric Le Goater
2017-02-23  2:18   ` David Gibson
2017-02-24 10:55     ` Cédric Le Goater
2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 06/22] ppc/xics: use the QOM interface under the sPAPR machine Cédric Le Goater
2017-02-23  2:21   ` David Gibson
2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 07/22] ppc/xics: use the QOM interface to get irqs Cédric Le Goater
2017-02-23  2:25   ` David Gibson
2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 08/22] ppc/xics: use the QOM interface to resend irqs Cédric Le Goater
2017-02-23  2:29   ` David Gibson
2017-02-24 11:12     ` [Qemu-devel] [Qemu-ppc] " Cédric Le Goater
2017-02-24 17:34       ` Cédric Le Goater
2017-02-27  0:37         ` David Gibson
2017-02-27  0:30       ` David Gibson
2017-02-27  8:45         ` Cédric Le Goater
2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 09/22] ppc/xics: remove xics_find_source() Cédric Le Goater
2017-02-23  2:31   ` David Gibson
2017-02-24 11:13     ` [Qemu-devel] [Qemu-ppc] " Cédric Le Goater
2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 10/22] ppc/xics: register the reset handler of ICS objects Cédric Le Goater
2017-02-23  2:33   ` David Gibson
2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 11/22] ppc/xics: remove the XICS list of ICS Cédric Le Goater
2017-02-23  2:33   ` David Gibson
2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 12/22] ppc/xics: extend the QOM interface to handle ICPs Cédric Le Goater
2017-02-23  2:39   ` David Gibson
2017-02-24 11:15     ` [Qemu-devel] [Qemu-ppc] " Cédric Le Goater
2017-02-27  0:57       ` David Gibson
2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 13/22] ppc/xics: simplify the cpu_setup() handler Cédric Le Goater
2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 14/22] ppc/xics: use the QOM interface to grab an ICP Cédric Le Goater
2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 15/22] ppc/xics: simplify spapr_dt_xics() interface Cédric Le Goater
2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 16/22] ppc/xics: register the reset handler of ICP objects Cédric Le Goater
2017-02-23  2:42   ` David Gibson
2017-02-24 11:27     ` [Qemu-devel] [Qemu-ppc] " Cédric Le Goater
2017-02-27  1:00       ` David Gibson
2017-02-27  9:21         ` Cédric Le Goater
2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 17/22] ppc/xics: move the ICP array under the sPAPR machine Cédric Le Goater
2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 18/22] ppc/xics: move kernel_xics_fd out of KVMXICSState Cédric Le Goater
2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 19/22] ppc/xics: move the cpu_setup() handler under the ICPState class Cédric Le Goater
2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 20/22] ppc/xics: remove the 'xics' backlinks Cédric Le Goater
2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 21/22] ppc/xics: export the XICS init routines Cédric Le Goater
2017-02-16 13:47 ` [Qemu-devel] [PATCH v2 22/22] ppc/xics: remove the XICSState classes Cédric Le Goater
2017-02-22  3:34 ` [Qemu-devel] [PATCH v2 00/22] ppc/xics: simplify ICS and ICP creation David Gibson
2017-02-22 10:55   ` Cédric Le Goater
2017-02-23  3:07     ` David Gibson
2017-02-23  6:49       ` Cédric Le Goater
2017-02-23  7:19       ` [Qemu-devel] [Qemu-ppc] " Cédric Le Goater
2017-02-23 22:55         ` 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.