qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Philippe Mathieu-Daudé" <philmd@linaro.org>
To: qemu-devel@nongnu.org, Peter Maydell <peter.maydell@linaro.org>,
	Markus Armbruster <armbru@redhat.com>
Cc: "Luc Michel" <luc.michel@amd.com>,
	"Daniel Henrique Barboza" <dbarboza@ventanamicro.com>,
	"Alistair Francis" <alistair.francis@wdc.com>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Eduardo Habkost" <eduardo@habkost.net>,
	"Mark Cave-Ayland" <mark.cave-ayland@ilande.co.uk>,
	"Bernhard Beschow" <shentey@gmail.com>,
	qemu-ppc@nongnu.org,
	"Edgar E . Iglesias" <edgar.iglesias@gmail.com>,
	"Daniel P . Berrange" <berrange@redhat.com>,
	"Thomas Huth" <thuth@redhat.com>,
	"Philippe Mathieu-Daudé" <philmd@linaro.org>
Subject: [RFC PATCH 5/5] hw/ppc/e500: Pass array of CPUs as array of canonical QOM paths
Date: Mon, 30 Oct 2023 15:39:56 +0100	[thread overview]
Message-ID: <20231030143957.82988-6-philmd@linaro.org> (raw)
In-Reply-To: <20231030143957.82988-1-philmd@linaro.org>

Devices should avoid calling qemu_get_cpu() because this call
doesn't work as expected with heterogeneous machines. Such
devices often iterate over a cluster of CPUs, which the device's
parent has direct access (when creating the child device).

We can pass QOM as 'link' between objects, but we can't pass an
array of links. Here we exploits QAPI simplicity, by using
DEFINE_PROP_ARRAY and a list of strings, each string being the
CPU canonical path in QOM tree (which is constant and unique).
When the device realizes itself, the original CPU pointer is
recovered via a object_resolve_path() call.

Inspired-by: Peter Maydell <peter.maydell@linaro.org>
Inspired-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
Tested with:
$ make check-qtest-ppc{,64}
$ make check-avocado AVOCADO_TAGS='machine:ppce500 machine:mpc8544ds'

RFC: See cover

FIXME: Should we free spin_cpu_list using g_autoptr(QList)?
---
 hw/ppc/e500.c         |  6 ++++++
 hw/ppc/ppce500_spin.c | 48 ++++++++++++++++++++++++++++++++++++-------
 2 files changed, 47 insertions(+), 7 deletions(-)

diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index e38f46df38..8b31143dca 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -18,6 +18,7 @@
 #include "qemu/datadir.h"
 #include "qemu/units.h"
 #include "qemu/guest-random.h"
+#include "qapi/qmp/qlist.h"
 #include "qapi/error.h"
 #include "e500.h"
 #include "e500-ccsr.h"
@@ -930,11 +931,13 @@ void ppce500_init(MachineState *machine)
     SysBusDevice *s;
     PPCE500CCSRState *ccsr;
     I2CBus *i2c;
+    QList *spin_cpu_list = qlist_new();
 
     irqs = g_new0(IrqLines, smp_cpus);
     for (i = 0; i < smp_cpus; i++) {
         PowerPCCPU *cpu;
         CPUState *cs;
+        g_autofree char *cpu_qompath;
 
         cpu = POWERPC_CPU(object_new(machine->cpu_type));
         env = &cpu->env;
@@ -954,6 +957,8 @@ void ppce500_init(MachineState *machine)
         object_property_set_bool(OBJECT(cs), "start-powered-off", i != 0,
                                  &error_fatal);
         qdev_realize_and_unref(DEVICE(cs), NULL, &error_fatal);
+        cpu_qompath = object_get_canonical_path(OBJECT(cs));
+        qlist_append_str(spin_cpu_list, cpu_qompath);
 
         if (!firstenv) {
             firstenv = env;
@@ -1083,6 +1088,7 @@ void ppce500_init(MachineState *machine)
 
     /* Register spinning region */
     dev = qdev_new("e500-spin");
+    qdev_prop_set_array(dev, "cpus-qom-path", spin_cpu_list);
     sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
     sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, pmc->spin_base);
 
diff --git a/hw/ppc/ppce500_spin.c b/hw/ppc/ppce500_spin.c
index e3608d8c16..a67046b2ea 100644
--- a/hw/ppc/ppce500_spin.c
+++ b/hw/ppc/ppce500_spin.c
@@ -30,11 +30,13 @@
 #include "qemu/osdep.h"
 #include "qemu/module.h"
 #include "qemu/units.h"
+#include "qapi/error.h"
 #include "hw/hw.h"
 #include "hw/sysbus.h"
 #include "sysemu/hw_accel.h"
 #include "e500.h"
 #include "qom/object.h"
+#include "hw/qdev-properties.h"
 
 #define MAX_CPUS 32
 
@@ -46,6 +48,10 @@ typedef struct spin_info {
     uint64_t reserved;
 } QEMU_PACKED SpinInfo;
 
+/*
+ * QEMU interface:
+ *  + QOM array property "cpus-qom-path": QOM canonical path of each CPU.
+ */
 #define TYPE_E500_SPIN "e500-spin"
 OBJECT_DECLARE_SIMPLE_TYPE(SpinState, E500_SPIN)
 
@@ -54,6 +60,9 @@ struct SpinState {
 
     MemoryRegion iomem;
     SpinInfo spin[MAX_CPUS];
+    uint32_t cpu_count;
+    char **cpu_canonical_path;
+    CPUState **cpu;
 };
 
 static void spin_reset(DeviceState *dev)
@@ -121,16 +130,10 @@ static void spin_write(void *opaque, hwaddr addr, uint64_t value,
 {
     SpinState *s = opaque;
     int env_idx = addr / sizeof(SpinInfo);
-    CPUState *cpu;
+    CPUState *cpu = s->cpu[env_idx];
     SpinInfo *curspin = &s->spin[env_idx];
     uint8_t *curspin_p = (uint8_t*)curspin;
 
-    cpu = qemu_get_cpu(env_idx);
-    if (cpu == NULL) {
-        /* Unknown CPU */
-        return;
-    }
-
     if (cpu->cpu_index == 0) {
         /* primary CPU doesn't spin */
         return;
@@ -188,11 +191,42 @@ static void ppce500_spin_initfn(Object *obj)
     sysbus_init_mmio(dev, &s->iomem);
 }
 
+static void ppce500_spin_realize(DeviceState *dev, Error **errp)
+{
+    SpinState *s = E500_SPIN(dev);
+
+    if (s->cpu_count == 0) {
+        error_setg(errp, "'cpus-qom-path' property array must be set");
+        return;
+    } else if (s->cpu_count > MAX_CPUS) {
+        error_setg(errp, "at most %d CPUs are supported", MAX_CPUS);
+        return;
+    }
+
+    s->cpu = g_new(CPUState *, s->cpu_count);
+    for (unsigned i = 0; i < s->cpu_count; i++) {
+        bool ambiguous;
+        Object *obj;
+
+        obj = object_resolve_path(s->cpu_canonical_path[i], &ambiguous);
+        assert(!ambiguous);
+        s->cpu[i] = CPU(obj);
+    }
+}
+
+static Property ppce500_spin_properties[] = {
+    DEFINE_PROP_ARRAY("cpus-qom-path", SpinState, cpu_count,
+                      cpu_canonical_path, qdev_prop_string, char *),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void ppce500_spin_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
 
     dc->reset = spin_reset;
+    dc->realize = ppce500_spin_realize;
+    device_class_set_props(dc, ppce500_spin_properties);
 }
 
 static const TypeInfo ppce500_spin_types[] = {
-- 
2.41.0



  parent reply	other threads:[~2023-10-30 14:41 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-10-30 14:39 [RFC PATCH 0/5] hw/ppc/e500: Pass array of CPUs as array of canonical QOM paths Philippe Mathieu-Daudé
2023-10-30 14:39 ` [PATCH 1/5] qdev: Add qdev_prop_set_array() Philippe Mathieu-Daudé
2023-10-30 14:39 ` [PATCH 2/5] hw/ppc/e500: Declare CPU QOM types using DEFINE_TYPES() macro Philippe Mathieu-Daudé
2023-10-31 21:01   ` Daniel Henrique Barboza
2023-11-02 10:58   ` Kevin Wolf
2023-10-30 14:39 ` [PATCH 3/5] hw/ppc/e500: QOM-attach CPUs to the machine container Philippe Mathieu-Daudé
2023-10-31 21:01   ` Daniel Henrique Barboza
2023-11-03  7:40   ` Markus Armbruster
2023-11-03 11:09     ` Philippe Mathieu-Daudé
2023-11-03 16:24       ` Markus Armbruster
2023-10-30 14:39 ` [PATCH 4/5] hw/ppc/e500: Inline sysbus_create_simple(E500_SPIN) Philippe Mathieu-Daudé
2023-10-31 21:03   ` Daniel Henrique Barboza
2023-10-30 14:39 ` Philippe Mathieu-Daudé [this message]
2023-10-31 21:16   ` [RFC PATCH 5/5] hw/ppc/e500: Pass array of CPUs as array of canonical QOM paths Daniel Henrique Barboza
2023-11-02  7:33     ` Philippe Mathieu-Daudé
2023-11-03  8:03   ` Markus Armbruster
2023-10-31 21:49 ` [RFC PATCH 0/5] " Daniel Henrique Barboza
2023-11-02  7:49   ` Philippe Mathieu-Daudé
2023-11-03 14:45     ` Daniel Henrique Barboza
2023-11-02  7:56   ` Philippe Mathieu-Daudé

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231030143957.82988-6-philmd@linaro.org \
    --to=philmd@linaro.org \
    --cc=alistair.francis@wdc.com \
    --cc=armbru@redhat.com \
    --cc=berrange@redhat.com \
    --cc=dbarboza@ventanamicro.com \
    --cc=edgar.iglesias@gmail.com \
    --cc=eduardo@habkost.net \
    --cc=luc.michel@amd.com \
    --cc=mark.cave-ayland@ilande.co.uk \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    --cc=shentey@gmail.com \
    --cc=thuth@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).