[RFC PATCH v2 131/137] hw: Parent board-created CPUs under the machine

Alexander Graf <[email protected]>
Newsgroups org.nongnu.qemu-arm,org.nongnu.qemu-devel,org.nongnu.qemu-riscv
Message-ID <[email protected]>
A number of boards create CPUs via object_new(cpu_type) followed
by property setting and qdev_realize(NULL), rather than through
cpu_create().  These CPUs currently fall into /machine/unattached
via the device_set_realized() fallback.  Parent them explicitly
under the machine (or the CPS/SoC container that owns them) as
"cpu[*]", matching the naming convention used by cpu_create().

The subsequent object_unref() and qdev_realize_and_unref() calls
are converted to plain qdev_realize() (or dropped) since the
parent's child<> property now holds the reference.  Error paths
switch to object_unparent().

The transient introspection object_new() in hw/arm/virt.c
machvirt_init() (probing pa_bits) is deliberately left as-is;
it is unref'd immediately without being realized.

  hw/arm:       integratorcp mps3r realview sbsa-ref versatilepb
                vexpress virt xilinx-zynq
  hw/hexagon:   hexagon_dsp virt
  hw/i386:      x86-common xen-pvh
  hw/loongarch: virt
  hw/mips:      cps
  hw/ppc:       e500 spapr (cpu-core)
  hw/riscv:     cps microblaze-v-generic
  hw/s390x:     s390-virtio-ccw
  hw/sparc:     leon3 sun4m
  hw/sparc64:   sparc64

Hot-plugged CPUs (via -device / device_add) continue to be parented
under /machine/peripheral by the user's id=; only cold-boot
board-created CPUs move under /machine/cpu[*].

Reviewed-by: Brian Cain <[email protected]> # hexagon only
Acked-by: Bernhard Beschow <[email protected]> # e500 only
AI-used-for: code (refactoring)
Signed-off-by: Alexander Graf <[email protected]>
---
 hw/arm/integratorcp.c           |  3 ++-
 hw/arm/mps3r.c                  |  4 ++--
 hw/arm/realview.c               |  3 ++-
 hw/arm/sbsa-ref.c               |  5 +++--
 hw/arm/versatilepb.c            |  3 ++-
 hw/arm/vexpress.c               |  3 ++-
 hw/arm/virt.c                   |  5 +++--
 hw/arm/xilinx_zynq.c            |  3 ++-
 hw/hexagon/hexagon_dsp.c        |  5 +++--
 hw/hexagon/virt.c               |  5 +++--
 hw/i386/x86-common.c            |  9 ++++-----
 hw/i386/xen/xen-pvh.c           |  5 ++---
 hw/loongarch/virt.c             |  6 ++++--
 hw/mips/cps.c                   |  5 +++--
 hw/ppc/e500.c                   |  5 +++--
 hw/ppc/spapr.c                  |  5 +++--
 hw/riscv/cps.c                  |  5 +++--
 hw/riscv/microblaze-v-generic.c |  3 ++-
 hw/s390x/s390-virtio-ccw.c      | 16 +++++++---------
 hw/sparc/leon3.c                |  3 ++-
 hw/sparc/sun4m.c                |  5 +++--
 hw/sparc64/sparc64.c            |  3 ++-
 22 files changed, 62 insertions(+), 47 deletions(-)

diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
index 81c0bce8f9..30a6a940c5 100644
--- a/hw/arm/integratorcp.c
+++ b/hw/arm/integratorcp.c
@@ -598,7 +598,8 @@ static void integratorcp_init(MachineState *machine)
     DriveInfo *dinfo;
     int i;
 
-    cpuobj = object_new(machine->cpu_type);
+    cpuobj = object_new_child(OBJECT(machine), "cpu[0]",
+                                        machine->cpu_type);
 
     /* By default ARM1176 CPUs have EL3 enabled.  This board does not
      * currently support EL3 so the CPU EL3 property is disabled before
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
index d6c29c1172..dd434eaefd 100644
--- a/hw/arm/mps3r.c
+++ b/hw/arm/mps3r.c
@@ -388,13 +388,13 @@ static void mps3r_common_init(MachineState *machine)
         memory_region_add_subregion_overlap(&mms->cpu_sysmem[i], 0,
                                             &mms->sysmem_alias[i], -1);
 
-        mms->cpu[i] = object_new(machine->cpu_type);
+        mms->cpu[i] = object_new_child(OBJECT(mms), "cpu[*]",
+                                        machine->cpu_type);
         object_property_set_link(mms->cpu[i], "memory",
                                  OBJECT(&mms->cpu_sysmem[i]), &error_abort);
         object_property_set_int(mms->cpu[i], "reset-cbar",
                                 PERIPHBASE, &error_abort);
         qdev_realize(DEVICE(mms->cpu[i]), NULL, &error_fatal);
-        object_unref(mms->cpu[i]);
 
         /* Per-CPU RAM */
         memory_region_init_ram(&mms->cpu_ram[i], OBJECT(mms), ramname,
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
index 99591e7d80..f938367131 100644
--- a/hw/arm/realview.c
+++ b/hw/arm/realview.c
@@ -119,7 +119,8 @@ static void realview_init(MachineState *machine,
     }
 
     for (n = 0; n < smp_cpus; n++) {
-        Object *cpuobj = object_new(machine->cpu_type);
+        Object *cpuobj = object_new_child(OBJECT(machine), "cpu[*]",
+                                        machine->cpu_type);
 
         /* By default A9,A15 and ARM1176 CPUs have EL3 enabled.  This board
          * does not currently support EL3 so the CPU EL3 property is disabled
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
index 1df8efd207..eeb55b5334 100644
--- a/hw/arm/sbsa-ref.c
+++ b/hw/arm/sbsa-ref.c
@@ -783,7 +783,9 @@ static void sbsa_ref_init(MachineState *machine)
             break;
         }
 
-        cpuobj = object_new(possible_cpus->cpus[n].type);
+        g_autofree char *cpu_name = g_strdup_printf("cpu[%d]", n);
+        cpuobj = object_new_child(OBJECT(sms), cpu_name,
+                                  possible_cpus->cpus[n].type);
         object_property_set_int(cpuobj, "mp-affinity",
                                 possible_cpus->cpus[n].arch_id, NULL);
 
@@ -808,7 +810,6 @@ static void sbsa_ref_init(MachineState *machine)
                                  OBJECT(secure_sysmem), &error_abort);
 
         qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
-        object_unref(cpuobj);
     }
 
     memory_region_add_subregion(sysmem, sbsa_ref_memmap[SBSA_MEM].base,
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
index f68c4765c6..8d93fff207 100644
--- a/hw/arm/versatilepb.c
+++ b/hw/arm/versatilepb.c
@@ -208,7 +208,8 @@ static void versatile_init(MachineState *machine, int board_id)
         exit(1);
     }
 
-    cpuobj = object_new(machine->cpu_type);
+    cpuobj = object_new_child(OBJECT(machine), "cpu[0]",
+                                        machine->cpu_type);
 
     /* By default ARM1176 CPUs have EL3 enabled.  This board does not
      * currently support EL3 so the CPU EL3 property is disabled before
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
index f877ccf330..986525b9ce 100644
--- a/hw/arm/vexpress.c
+++ b/hw/arm/vexpress.c
@@ -219,7 +219,8 @@ static void init_cpus(MachineState *ms, const char *cpu_type,
 
     /* Create the actual CPUs */
     for (n = 0; n < smp_cpus; n++) {
-        Object *cpuobj = object_new(cpu_type);
+        Object *cpuobj = object_new_child(qdev_get_machine(), "cpu[*]",
+                                        cpu_type);
 
         if (!secure) {
             object_property_set_bool(cpuobj, "has_el3", false, NULL);
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index beb2d481ce..f4f2643b49 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -3039,7 +3039,9 @@ static void machvirt_init(MachineState *machine)
             break;
         }
 
-        cpuobj = object_new(possible_cpus->cpus[n].type);
+        g_autofree char *cpu_name = g_strdup_printf("cpu[%d]", n);
+        cpuobj = object_new_child(OBJECT(vms), cpu_name,
+                                  possible_cpus->cpus[n].type);
         object_property_set_int(cpuobj, "mp-affinity",
                                 possible_cpus->cpus[n].arch_id, NULL);
 
@@ -3139,7 +3141,6 @@ static void machvirt_init(MachineState *machine)
         }
 
         qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
-        object_unref(cpuobj);
     }
 
     /* Now we've created the CPUs we can see if they have the hypvirt timer */
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
index 441289e63f..a2dcdd422d 100644
--- a/hw/arm/xilinx_zynq.c
+++ b/hw/arm/xilinx_zynq.c
@@ -222,7 +222,8 @@ static void zynq_init(MachineState *machine)
     }
 
     for (n = 0; n < smp_cpus; n++) {
-        Object *cpuobj = object_new(machine->cpu_type);
+        Object *cpuobj = object_new_child(OBJECT(machine), "cpu[*]",
+                                        machine->cpu_type);
 
         object_property_set_int(cpuobj, "midr", ZYNQ_BOARD_MIDR,
                                 &error_fatal);
diff --git a/hw/hexagon/hexagon_dsp.c b/hw/hexagon/hexagon_dsp.c
index 53dfe6741e..d78a987dca 100644
--- a/hw/hexagon/hexagon_dsp.c
+++ b/hw/hexagon/hexagon_dsp.c
@@ -143,7 +143,8 @@ static void hexagon_common_init(MachineState *machine, Rev_t rev,
     sysbus_realize(SYS_BUS_DEVICE(tlb_dev), &error_fatal);
 
     for (int i = 0; i < machine->smp.cpus; i++) {
-        HexagonCPU *cpu = HEXAGON_CPU(object_new(machine->cpu_type));
+        HexagonCPU *cpu = HEXAGON_CPU(object_new_child(OBJECT(machine), "cpu[*]",
+                                        machine->cpu_type));
         qemu_register_reset(do_cpu_reset, cpu);
 
         /*
@@ -158,7 +159,7 @@ static void hexagon_common_init(MachineState *machine, Rev_t rev,
                                  OBJECT(glob_regs_dev), &error_fatal);
         object_property_set_link(OBJECT(cpu), "tlb",
                                  OBJECT(tlb_dev), &error_fatal);
-        qdev_realize_and_unref(DEVICE(cpu), NULL, &error_fatal);
+        qdev_realize(DEVICE(cpu), NULL, &error_fatal);
     }
 
     rom_add_blob_fixed_as("config_table.rom", &m_cfg->cfgtable,
diff --git a/hw/hexagon/virt.c b/hw/hexagon/virt.c
index fb23cda19f..48f1e35dd3 100644
--- a/hw/hexagon/virt.c
+++ b/hw/hexagon/virt.c
@@ -280,7 +280,8 @@ static void virt_init(MachineState *ms)
 
     cpu0 = NULL;
     for (int i = 0; i < ms->smp.cpus; i++) {
-        HexagonCPU *cpu = HEXAGON_CPU(object_new(ms->cpu_type));
+        HexagonCPU *cpu = HEXAGON_CPU(object_new_child(OBJECT(ms), "cpu[*]",
+                                        ms->cpu_type));
         qemu_register_reset(do_cpu_reset, cpu);
 
         if (i == 0) {
@@ -300,7 +301,7 @@ static void virt_init(MachineState *ms)
         object_property_set_link(OBJECT(cpu), "tlb",
                                  OBJECT(tlb_dev), &error_fatal);
 
-        qdev_realize_and_unref(DEVICE(cpu), NULL, &error_fatal);
+        qdev_realize(DEVICE(cpu), NULL, &error_fatal);
     }
     fdt_add_cpu_nodes(vms);
     clk_phandle = fdt_add_clocks(vms);
diff --git a/hw/i386/x86-common.c b/hw/i386/x86-common.c
index 151a67ee5f..5bbfee737e 100644
--- a/hw/i386/x86-common.c
+++ b/hw/i386/x86-common.c
@@ -55,15 +55,14 @@ static size_t pvh_start_addr;
 
 static void x86_cpu_new(X86MachineState *x86ms, int64_t apic_id, Error **errp)
 {
-    Object *cpu = object_new(MACHINE(x86ms)->cpu_type);
+    Object *cpu = object_new_child(OBJECT(x86ms), "cpu[*]",
+                                        MACHINE(x86ms)->cpu_type);
 
     if (!object_property_set_uint(cpu, "apic-id", apic_id, errp)) {
-        goto out;
+        object_unparent(cpu);
+        return;
     }
     qdev_realize(DEVICE(cpu), NULL, errp);
-
-out:
-    object_unref(cpu);
 }
 
 void x86_cpus_init(X86MachineState *x86ms, int default_cpu_version)
diff --git a/hw/i386/xen/xen-pvh.c b/hw/i386/xen/xen-pvh.c
index ab90c83a83..7aef48ad61 100644
--- a/hw/i386/xen/xen-pvh.c
+++ b/hw/i386/xen/xen-pvh.c
@@ -29,12 +29,11 @@ struct XenPVHx86State {
 static DeviceState *xen_pvh_cpu_new(MachineState *ms,
                                     int64_t apic_id)
 {
-    Object *cpu = object_new(ms->cpu_type);
+    Object *cpu = object_new_child(OBJECT(ms), "cpu[*]",
+                                        ms->cpu_type);
 
-    object_property_add_child(OBJECT(ms), "cpu[*]", cpu);
     object_property_set_uint(cpu, "apic-id", apic_id, &error_fatal);
     qdev_realize(DEVICE(cpu), NULL, &error_fatal);
-    object_unref(cpu);
 
     return DEVICE(cpu);
 }
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 09c39140bd..8f0725f384 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -948,13 +948,15 @@ static void virt_init(MachineState *machine)
     /* Init CPUs */
     mc->possible_cpu_arch_ids(machine);
     for (i = 0; i < machine->smp.cpus; i++) {
-        cpuobj = object_new(machine->cpu_type);
+        g_autofree char *cpu_name = g_strdup_printf("cpu[%d]", i);
+        cpuobj = object_new_child(OBJECT(machine), cpu_name,
+                                  machine->cpu_type);
         if (cpuobj == NULL) {
             error_report("Fail to create object with type %s ",
                          machine->cpu_type);
             exit(EXIT_FAILURE);
         }
-        qdev_realize_and_unref(DEVICE(cpuobj), NULL, &error_fatal);
+        qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
     }
     virt_check_dmsi(machine);
     fw_cfg_add_memory(machine);
diff --git a/hw/mips/cps.c b/hw/mips/cps.c
index 620ee972f8..b997608373 100644
--- a/hw/mips/cps.c
+++ b/hw/mips/cps.c
@@ -74,7 +74,8 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
     }
 
     for (int i = 0; i < s->num_vp; i++) {
-        MIPSCPU *cpu = MIPS_CPU(object_new(s->cpu_type));
+        MIPSCPU *cpu = MIPS_CPU(object_new_child(OBJECT(s), "cpu[*]",
+                                        s->cpu_type));
         CPUMIPSState *env = &cpu->env;
 
         object_property_set_bool(OBJECT(cpu), "big-endian", s->cpu_is_bigendian,
@@ -87,7 +88,7 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
         /* All cores use the same clock tree */
         qdev_connect_clock_in(DEVICE(cpu), "clk-in", s->clock);
 
-        if (!qdev_realize_and_unref(DEVICE(cpu), NULL, errp)) {
+        if (!qdev_realize(DEVICE(cpu), NULL, errp)) {
             return;
         }
 
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index f3917c0755..a0eb25e956 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -941,7 +941,8 @@ void ppce500_init(MachineState *machine)
         PowerPCCPU *cpu;
         CPUState *cs;
 
-        cpu = POWERPC_CPU(object_new(machine->cpu_type));
+        cpu = POWERPC_CPU(object_new_child(OBJECT(machine), "cpu[*]",
+                                        machine->cpu_type));
         env = &cpu->env;
         cs = CPU(cpu);
 
@@ -956,7 +957,7 @@ void ppce500_init(MachineState *machine)
          */
         object_property_set_bool(OBJECT(cs), "start-powered-off", i != 0,
                                  &error_abort);
-        qdev_realize_and_unref(DEVICE(cs), NULL, &error_fatal);
+        qdev_realize(DEVICE(cs), NULL, &error_fatal);
 
         if (!firstenv) {
             firstenv = env;
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 9b6b5e7257..2719044414 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -2776,7 +2776,9 @@ static void spapr_init_cpus(SpaprMachineState *spapr)
         }
 
         if (i < boot_cores_nr) {
-            Object *core  = object_new(type);
+            g_autofree char *core_name = g_strdup_printf("cpu-core[%d]", i);
+            Object *core  = object_new_child(OBJECT(spapr), core_name,
+                                             type);
             int nr_threads = smp_threads;
 
             /* Handle the partially filled core for older machine types */
@@ -2790,7 +2792,6 @@ static void spapr_init_cpus(SpaprMachineState *spapr)
                                     &error_fatal);
             qdev_realize(DEVICE(core), NULL, &error_fatal);
 
-            object_unref(core);
         }
     }
 }
diff --git a/hw/riscv/cps.c b/hw/riscv/cps.c
index b6b30e05e1..2bf506b61a 100644
--- a/hw/riscv/cps.c
+++ b/hw/riscv/cps.c
@@ -63,13 +63,14 @@ static void riscv_cps_realize(DeviceState *dev, Error **errp)
     int harts_in_cluster = s->num_hart * s->num_core;
     int num_of_clusters = s->num_vp / harts_in_cluster;
     for (i = 0; i < s->num_vp; i++) {
-        cpu = RISCV_CPU(object_new(s->cpu_type));
+        cpu = RISCV_CPU(object_new_child(OBJECT(s), "cpu[*]",
+                                        s->cpu_type));
 
         /* All VPs are halted on reset. Leave powering up to CPC. */
         object_property_set_bool(OBJECT(cpu), "start-powered-off", true,
                                  &error_abort);
 
-        if (!qdev_realize_and_unref(DEVICE(cpu), NULL, errp)) {
+        if (!qdev_realize(DEVICE(cpu), NULL, errp)) {
             return;
         }
 
diff --git a/hw/riscv/microblaze-v-generic.c b/hw/riscv/microblaze-v-generic.c
index 0a83932405..f97ce402e6 100644
--- a/hw/riscv/microblaze-v-generic.c
+++ b/hw/riscv/microblaze-v-generic.c
@@ -65,7 +65,8 @@ static void mb_v_generic_init(MachineState *machine)
     qemu_irq irq[32];
     MemoryRegion *sysmem = get_system_memory();
 
-    cpu = RISCV_CPU(object_new(machine->cpu_type));
+    cpu = RISCV_CPU(object_new_child(OBJECT(machine), "cpu[0]",
+                                        machine->cpu_type));
     object_property_set_bool(OBJECT(cpu), "h", false, NULL);
     object_property_set_bool(OBJECT(cpu), "d", false, NULL);
     qdev_realize(DEVICE(cpu), NULL, &error_abort);
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 037cb6eb5e..0625d4a8df 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -56,20 +56,18 @@ static Error *pv_mig_blocker;
 static S390CPU *s390x_new_cpu(const char *typename, uint32_t core_id,
                               Error **errp)
 {
-    S390CPU *cpu = S390_CPU(object_new(typename));
-    S390CPU *ret = NULL;
+    S390CPU *cpu = S390_CPU(object_new_child(qdev_get_machine(), "cpu[*]",
+                                        typename));
 
     if (!object_property_set_int(OBJECT(cpu), "core-id", core_id, errp)) {
-        goto out;
+        object_unparent(OBJECT(cpu));
+        return NULL;
     }
     if (!qdev_realize(DEVICE(cpu), NULL, errp)) {
-        goto out;
+        object_unparent(OBJECT(cpu));
+        return NULL;
     }
-    ret = cpu;
-
-out:
-    object_unref(OBJECT(cpu));
-    return ret;
+    return cpu;
 }
 
 static void s390_init_cpus(MachineState *machine)
diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c
index f9ef2758e1..a2781bcc32 100644
--- a/hw/sparc/leon3.c
+++ b/hw/sparc/leon3.c
@@ -278,7 +278,8 @@ static void leon3_generic_hw_init(MachineState *machine)
 
     for (i = 0; i < machine->smp.cpus; i++) {
         /* Init CPU */
-        cpu = SPARC_CPU(object_new(machine->cpu_type));
+        cpu = SPARC_CPU(object_new_child(OBJECT(machine), "cpu[*]",
+                                        machine->cpu_type));
         qdev_init_gpio_in_named(DEVICE(cpu), leon3_start_cpu, "start_cpu", 1);
         qdev_init_gpio_in_named(DEVICE(cpu), leon3_set_pil_in, "pil", 1);
         qdev_realize(DEVICE(cpu), NULL, &error_fatal);
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 51f5468a02..1ae9d834ca 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -787,7 +787,8 @@ static DeviceState *cpu_devinit(const char *cpu_type, unsigned int id,
     CPUSPARCState *env;
     DeviceState *cpudev;
 
-    cpu = SPARC_CPU(object_new(cpu_type));
+    cpu = SPARC_CPU(object_new_child(qdev_get_machine(), "cpu[*]",
+                                        cpu_type));
     env = &cpu->env;
     cpudev = DEVICE(cpu);
 
@@ -795,7 +796,7 @@ static DeviceState *cpu_devinit(const char *cpu_type, unsigned int id,
     object_property_set_bool(OBJECT(cpu), "start-powered-off", id != 0,
                              &error_abort);
     qdev_init_gpio_in_named(cpudev, cpu_set_irq, "pil", MAX_PILS);
-    qdev_realize_and_unref(cpudev, NULL, &error_fatal);
+    qdev_realize(cpudev, NULL, &error_fatal);
     cpu_sparc_set_id(env, id);
     env->prom_addr = prom_addr;
     return cpudev;
diff --git a/hw/sparc64/sparc64.c b/hw/sparc64/sparc64.c
index 16f4aa052b..9092c4193e 100644
--- a/hw/sparc64/sparc64.c
+++ b/hw/sparc64/sparc64.c
@@ -272,7 +272,8 @@ SPARCCPU *sparc64_cpu_devinit(const char *cpu_type, uint64_t prom_addr)
     uint32_t  stick_frequency = 100 * 1000000;
     uint32_t hstick_frequency = 100 * 1000000;
 
-    cpu = SPARC_CPU(object_new(cpu_type));
+    cpu = SPARC_CPU(object_new_child(qdev_get_machine(), "cpu[0]",
+                                        cpu_type));
     qdev_init_gpio_in_named(DEVICE(cpu), sparc64_cpu_set_ivec_irq,
                             "ivec-irq", IVEC_MAX);
     qdev_realize(DEVICE(cpu), NULL, &error_fatal);
-- 
2.47.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.