All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alexander Graf <graf@amazon.com>
To: <qemu-devel@nongnu.org>
Cc: qemu-arm@nongnu.org, qemu-ppc@nongnu.org, qemu-riscv@nongnu.org,
	qemu-s390x@nongnu.org, "Song Gao" <17746591750@163.com>,
	"Aditya Gupta" <adityag@linux.ibm.com>,
	"Alexey Kardashevskiy" <aik@ozlabs.ru>,
	"Farhan Ali" <alifm@linux.ibm.com>,
	"Alistair Francis" <alistair.francis@wdc.com>,
	"Alistair Francis" <alistair@alistair23.me>,
	"Antony Pavlov" <antonynpavlov@gmail.com>,
	"Markus Armbruster" <armbru@redhat.com>,
	"Artyom Tarasenko" <atar4qemu@gmail.com>,
	"BALATON Zoltan" <balaton@eik.bme.hu>,
	"Felipe Balbi" <balbi@kernel.org>,
	"Christian Borntraeger" <borntraeger@linux.ibm.com>,
	"Brian Cain" <brian.cain@oss.qualcomm.com>,
	"Hendrik Brueckner" <brueckner@linux.ibm.com>,
	"Chao Liu" <chao.liu@processmission.com>,
	"Huacai Chen" <chenhuacai@kernel.org>,
	"Clément Chigot" <chigot@adacore.com>,
	"Cédric Le Goater" <clg@kaod.org>, "Helge Deller" <deller@gmx.de>,
	"Dorjoy Chowdhury" <dorjoychy111@gmail.com>,
	"Edgar E . Iglesias" <edgar.iglesias@gmail.com>,
	"Alexandre Iooss" <erdnaxe@crans.org>,
	"Eric Farman" <farman@linux.ibm.com>,
	"Francisco Iglesias" <francisco.iglesias@amd.com>,
	"Gaurav Sharma" <gaurav.sharma_7@nxp.com>,
	"Gautam Gala" <ggala@linux.ibm.com>,
	"Harsh Prateek Bora" <harshpb@linux.ibm.com>,
	"Hervé Poussineau" <hpoussin@reactos.org>,
	"Jan Kiszka" <jan.kiszka@web.de>,
	"Max Filippov" <jcmvbkbc@gmail.com>,
	"Joel Stanley" <joel@jms.id.au>,
	"Jared Rossi" <jrossi@linux.ibm.com>,
	"Tyrone Ting" <kfting@nuvoton.com>,
	"Frederic Konrad" <konrad.frederic@yahoo.fr>,
	"Laurent Vivier" <laurent@vivier.eu>,
	"Manos Pitsidianakis" <manos.pitsidianakis@linaro.org>,
	"Bibo Mao" <maobibo@loongson.cn>,
	"Mark Cave-Ayland" <mark.cave-ayland@ilande.co.uk>,
	"Glenn Miles" <milesg@linux.ibm.com>,
	"Matthew Rosato" <mjrosato@linux.ibm.com>,
	"Michael Rolnik" <mrolnik@gmail.com>,
	"Michael S . Tsirkin" <mst@redhat.com>,
	"Niek Linnenbank" <nieklinnenbank@gmail.com>,
	"Nicholas Piggin" <npiggin@gmail.com>,
	"Palmer Dabbelt" <palmer@dabbelt.com>,
	"Halil Pasic" <pasic@linux.ibm.com>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Peter Maydell" <peter.maydell@linaro.org>,
	"Philippe Mathieu-Daudé" <philmd@mailo.com>,
	"Pierrick Bouvier" <pierrick.bouvier@oss.qualcomm.com>,
	"Richard Henderson" <richard.henderson@linaro.org>,
	"Sai Pavan Boddu" <sai.pavan.boddu@amd.com>,
	"Samuel Tardieu" <sam@rfc1149.net>,
	"Bernhard Beschow" <shentey@gmail.com>,
	"Stafford Horne" <shorne@gmail.com>,
	"Sergio Lopez" <slp@redhat.com>,
	"Subbaraya Sundeep" <sundeep.lkml@gmail.com>,
	"Thomas Huth" <th.huth+qemu@posteo.eu>,
	"Ran Wang" <wangran@bosc.ac.cn>, "Hao Wu" <wuhaotsh@google.com>,
	"Daniel P . Berrangé" <berrange@redhat.com>
Subject: [RFC PATCH 129/134] hw: Parent board-created CPUs under the machine
Date: Sat, 11 Jul 2026 22:37:02 +0000	[thread overview]
Message-ID: <20260711223707.42139-130-graf@amazon.com> (raw)
In-Reply-To: <20260711223707.42139-1-graf@amazon.com>

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

Assisted-by: Kiro
Signed-off-by: Alexander Graf <graf@amazon.com>
---
 hw/arm/integratorcp.c           |  3 ++-
 hw/arm/mps3r.c                  |  4 ++--
 hw/arm/realview.c               |  3 ++-
 hw/arm/sbsa-ref.c               |  4 ++--
 hw/arm/versatilepb.c            |  3 ++-
 hw/arm/vexpress.c               |  3 ++-
 hw/arm/virt.c                   |  4 ++--
 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             |  5 +++--
 hw/mips/cps.c                   |  5 +++--
 hw/ppc/e500.c                   |  5 +++--
 hw/ppc/spapr.c                  |  4 ++--
 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, 58 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 c9adc972c1..3b759d9209 100644
--- a/hw/arm/sbsa-ref.c
+++ b/hw/arm/sbsa-ref.c
@@ -783,7 +783,8 @@ static void sbsa_ref_init(MachineState *machine)
             break;
         }
 
-        cpuobj = object_new(possible_cpus->cpus[n].type);
+        cpuobj = object_new_child(OBJECT(sms), "cpu[*]",
+                                        possible_cpus->cpus[n].type);
         object_property_set_int(cpuobj, "mp-affinity",
                                 possible_cpus->cpus[n].arch_id, NULL);
 
@@ -808,7 +809,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 f2249a0b72..95e087d692 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -3039,7 +3039,8 @@ static void machvirt_init(MachineState *machine)
             break;
         }
 
-        cpuobj = object_new(possible_cpus->cpus[n].type);
+        cpuobj = object_new_child(OBJECT(vms), "cpu[*]",
+                                  possible_cpus->cpus[n].type);
         object_property_set_int(cpuobj, "mp-affinity",
                                 possible_cpus->cpus[n].arch_id, NULL);
 
@@ -3139,7 +3140,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 580ef0bb3e..b749aafdbe 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -948,13 +948,14 @@ 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);
+        cpuobj = object_new_child(OBJECT(machine), "cpu[*]",
+                                        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..e6c1b7f0b1 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -2776,7 +2776,8 @@ static void spapr_init_cpus(SpaprMachineState *spapr)
         }
 
         if (i < boot_cores_nr) {
-            Object *core  = object_new(type);
+            Object *core  = object_new_child(OBJECT(spapr), "cpu-core[*]",
+                                        type);
             int nr_threads = smp_threads;
 
             /* Handle the partially filled core for older machine types */
@@ -2790,7 +2791,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



  parent reply	other threads:[~2026-07-11 23:11 UTC|newest]

Thread overview: 156+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-11 22:34 [RFC PATCH 000/134] qom: Make composition-tree parenting mandatory Alexander Graf
2026-07-11 22:34 ` [RFC PATCH 001/134] qom: Introduce object_new_child() Alexander Graf
2026-07-13  8:47   ` Daniel P. Berrangé
2026-07-13  9:01     ` Graf (AWS), Alexander
2026-07-13 16:49   ` Richard Henderson
2026-07-13 18:15     ` Peter Maydell
2026-07-13 18:47       ` Daniel P. Berrangé
2026-07-13 19:07         ` Peter Maydell
2026-07-11 22:34 ` [RFC PATCH 002/134] qdev: Rename qdev_new()/qdev_try_new() to *_orphan() Alexander Graf
2026-07-13  8:22   ` Philippe Mathieu-Daudé
2026-07-11 22:34 ` [RFC PATCH 003/134] qdev: Reintroduce qdev_new() with a mandatory QOM parent Alexander Graf
2026-07-13 10:55   ` Philippe Mathieu-Daudé
2026-07-11 22:34 ` [RFC PATCH 004/134] sysbus: Make sysbus_create_simple()/_varargs() take a " Alexander Graf
2026-07-13 10:54   ` Philippe Mathieu-Daudé
2026-07-11 22:34 ` [RFC PATCH 005/134] pci: Make pci_new*()/pci_create_simple*() " Alexander Graf
2026-07-11 22:34 ` [RFC PATCH 006/134] isa: Make isa_new()/isa_try_new()/isa_create_simple() " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 007/134] i2c: Make i2c_slave_new()/i2c_slave_create_simple() " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 008/134] ssi, usb: Make bus-layer creators " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 009/134] cpu: Make cpu_create() " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 010/134] hw/avr: Give onboard devices " Alexander Graf
2026-07-13  8:25   ` Philippe Mathieu-Daudé
2026-07-11 22:35 ` [RFC PATCH 011/134] hw/tricore: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 012/134] hw/xtensa: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 013/134] hw/alpha: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 014/134] hw/nitro: " Alexander Graf
2026-07-13  8:29   ` Philippe Mathieu-Daudé
2026-07-11 22:35 ` [RFC PATCH 015/134] hw/vmapple: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 016/134] hw/hppa: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 017/134] hw/microblaze: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 018/134] hw/sh4: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 019/134] hw/s390x: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 020/134] hw/or1k: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 021/134] hw/loongarch: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 022/134] hw/intc: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 023/134] hw/pci-host: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 024/134] hw/core: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 025/134] hw/remote: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 026/134] hw/ufs: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 027/134] hw/nvme: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 028/134] hw/vfio: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 029/134] hw/mem: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 030/134] hw/cxl: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 031/134] hw/hexagon: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 032/134] hw/xen: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 033/134] hw/display: " Alexander Graf
2026-07-13  8:32   ` Philippe Mathieu-Daudé
2026-07-11 22:35 ` [RFC PATCH 034/134] hw/nvram: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 035/134] hw/dma: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 036/134] hw/misc: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 037/134] hw/scsi: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 038/134] hw/net: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 039/134] hw/ide: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 040/134] hw/i3c: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 041/134] hw/pci-bridge: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 042/134] hw/sparc64: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 043/134] hw/sparc: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 044/134] hw/m68k: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 045/134] hw/rtc: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 046/134] hw/i2c: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 047/134] hw/block: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 048/134] hw/char: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 049/134] hw/isa: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 050/134] hw/pci: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 051/134] hw/riscv: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 052/134] hw/mips: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 053/134] hw/i386: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 054/134] hw/ppc: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 055/134] hw/pci, hw/isa: Give VGA and slot-NIC helpers " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 056/134] hw/arm/virt: Give onboard devices " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 057/134] hw/arm/sbsa-ref: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 058/134] hw/arm/xilinx-zynq: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 059/134] hw/arm/xlnx-versal, xlnx-zynqmp: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 060/134] hw/arm/realview, integratorcp: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 061/134] hw/arm/npcm: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 062/134] hw/arm/versatile, vexpress: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 063/134] hw/arm/stellaris, musicpal: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 064/134] hw/arm/exynos: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 065/134] hw/arm/allwinner: " Alexander Graf
2026-07-11 22:35 ` [RFC PATCH 066/134] hw/arm/strongarm: " Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 067/134] hw/arm/omap: " Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 068/134] hw/arm/mps2: " Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 069/134] hw/arm/imx: " Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 070/134] hw/arm/misc: " Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 071/134] hw/arm/aspeed: Give onboard devices a QOM parent (part 1) Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 072/134] hw/arm/aspeed: Give onboard devices a QOM parent (part 2) Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 073/134] hw/nvram/at24c: Give at24c_eeprom_init() a QOM parent Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 074/134] hw/i386/pc: Give pcspk " Alexander Graf
2026-07-13  8:34   ` Philippe Mathieu-Daudé
2026-07-11 22:36 ` [RFC PATCH 075/134] hw/timer, hw/net: Give i8254 and isa-ne2000 helpers " Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 076/134] hw/misc/unimp: Give create_unimplemented_device() " Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 077/134] hw/usb: Give -usbdevice and auto-hub devices " Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 078/134] hw/audio: Give -audio model= " Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 079/134] hw/xen: Give xenstore-driven backend " Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 080/134] hw/nitro: Give the vsock bridge " Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 081/134] hw/isa: Give the isabus-bridge " Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 082/134] net, target/mips: Give -nic and CPU-with-clock helpers " Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 083/134] usb, ssi, i2c: Remove *_orphan() creator variants Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 084/134] isa: " Alexander Graf
2026-07-13  8:35   ` Philippe Mathieu-Daudé
2026-07-11 22:36 ` [RFC PATCH 085/134] pci: " Alexander Graf
2026-07-13  8:36   ` Philippe Mathieu-Daudé
2026-07-11 22:36 ` [RFC PATCH 086/134] cpu: Remove cpu_create_orphan() Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 087/134] sysbus: Remove *_orphan() creator variants Alexander Graf
2026-07-13  8:36   ` Philippe Mathieu-Daudé
2026-07-11 22:36 ` [RFC PATCH 088/134] qdev: Remove qdev_new_orphan() and qdev_try_new_orphan() Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 089/134] memory: Accept non-device owners in memory_region_init_ram() Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 090/134] hw/misc-boards: Give memory regions an explicit owner Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 091/134] hw/mips: " Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 092/134] hw/riscv: " Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 093/134] hw/i386: " Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 094/134] hw/arm: " Alexander Graf
2026-07-12 15:12   ` Bernhard Beschow
2026-07-11 22:36 ` [RFC PATCH 095/134] hw/arm/omap1: " Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 096/134] hw/sh4: " Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 097/134] hw/m68k: " Alexander Graf
2026-07-12 14:20   ` Thomas Huth
2026-07-11 22:36 ` [RFC PATCH 098/134] hw/ppc: " Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 099/134] hw/tricore: " Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 100/134] hw/xtensa: " Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 101/134] hw/display: " Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 102/134] hw/arm/omap: Give lcdc and dma " Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 103/134] hw/char: Give parallel and htif " Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 104/134] hw/remote: Give " Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 105/134] system, backends: Give named " Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 106/134] hw/ide: Let ide_init_ioport() take " Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 107/134] memory: Require an owner for named memory regions Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 108/134] irq: Rename qemu_allocate_irq*() and friends to *_orphan() Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 109/134] irq: Reintroduce qemu_allocate_irq*() with a mandatory owner and name Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 110/134] hw/pci, hw/usb, system: Give allocated IRQs an " Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 111/134] hw/i386, hw/xen: " Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 112/134] hw/arm: " Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 113/134] hw/xtensa: " Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 114/134] hw: " Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 115/134] hw/core: Parent GPIO input IRQs and embedded IRQState via QOM Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 116/134] irq: Delete the *_orphan() IRQ allocation variants Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 117/134] sysbus: Parent main-system-bus directly under /machine Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 118/134] accel: Parent the accelerator singleton " Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 119/134] hw/core/reset: Give the root reset container and legacy shims a QOM path Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 120/134] system: Parent per-MR helper objects under their owner Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 121/134] hw/virtio, hw/display: Parent per-device helper objects Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 122/134] hw/i386/amd_iommu: Parent internally-created AMDVI-PCI under the IOMMU Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 123/134] hw/s390x, hw/remote: Parent per-devfn IOMMU objects Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 124/134] hw/pci-host/raven: Parent the OR-IRQ under the host bridge Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 125/134] hw/arm/mps2: Parent the OR-IRQ gates under the machine Alexander Graf
2026-07-11 22:36 ` [RFC PATCH 126/134] hw/arm/digic: Parent the DIGIC SoC " Alexander Graf
2026-07-11 22:37 ` [RFC PATCH 127/134] hw/microblaze: Parent the CPU " Alexander Graf
2026-07-11 22:37 ` [RFC PATCH 128/134] hw: Pair object_initialize_child() with plain realize() Alexander Graf
2026-07-11 22:37 ` Alexander Graf [this message]
2026-07-13 16:35   ` [RFC PATCH 129/134] hw: Parent board-created CPUs under the machine Bernhard Beschow
2026-07-13 20:01   ` Brian Cain
2026-07-11 22:37 ` [RFC PATCH 130/134] hw/pci-host/versatile: Use object_initialize_child() for pci_dev Alexander Graf
2026-07-11 22:37 ` [RFC PATCH 131/134] docs, qapi, scripts, iotests: Update /machine/unattached path references Alexander Graf
2026-07-11 22:37 ` [RFC PATCH 132/134] qom: Delete /machine/unattached and error on unparented realize Alexander Graf
2026-07-11 22:37 ` [RFC PATCH 133/134] docs/devel/qom: Document the composition-tree parenting contract Alexander Graf
2026-07-11 22:37 ` [RFC PATCH 134/134] MAINTAINERS: Add scripts/coccinelle/qom-parent/ under QOM Alexander Graf
2026-07-12 10:56 ` [RFC PATCH 000/134] qom: Make composition-tree parenting mandatory Bernhard Beschow

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=20260711223707.42139-130-graf@amazon.com \
    --to=graf@amazon.com \
    --cc=17746591750@163.com \
    --cc=adityag@linux.ibm.com \
    --cc=aik@ozlabs.ru \
    --cc=alifm@linux.ibm.com \
    --cc=alistair.francis@wdc.com \
    --cc=alistair@alistair23.me \
    --cc=antonynpavlov@gmail.com \
    --cc=armbru@redhat.com \
    --cc=atar4qemu@gmail.com \
    --cc=balaton@eik.bme.hu \
    --cc=balbi@kernel.org \
    --cc=berrange@redhat.com \
    --cc=borntraeger@linux.ibm.com \
    --cc=brian.cain@oss.qualcomm.com \
    --cc=brueckner@linux.ibm.com \
    --cc=chao.liu@processmission.com \
    --cc=chenhuacai@kernel.org \
    --cc=chigot@adacore.com \
    --cc=clg@kaod.org \
    --cc=deller@gmx.de \
    --cc=dorjoychy111@gmail.com \
    --cc=edgar.iglesias@gmail.com \
    --cc=erdnaxe@crans.org \
    --cc=farman@linux.ibm.com \
    --cc=francisco.iglesias@amd.com \
    --cc=gaurav.sharma_7@nxp.com \
    --cc=ggala@linux.ibm.com \
    --cc=harshpb@linux.ibm.com \
    --cc=hpoussin@reactos.org \
    --cc=jan.kiszka@web.de \
    --cc=jcmvbkbc@gmail.com \
    --cc=joel@jms.id.au \
    --cc=jrossi@linux.ibm.com \
    --cc=kfting@nuvoton.com \
    --cc=konrad.frederic@yahoo.fr \
    --cc=laurent@vivier.eu \
    --cc=manos.pitsidianakis@linaro.org \
    --cc=maobibo@loongson.cn \
    --cc=mark.cave-ayland@ilande.co.uk \
    --cc=milesg@linux.ibm.com \
    --cc=mjrosato@linux.ibm.com \
    --cc=mrolnik@gmail.com \
    --cc=mst@redhat.com \
    --cc=nieklinnenbank@gmail.com \
    --cc=npiggin@gmail.com \
    --cc=palmer@dabbelt.com \
    --cc=pasic@linux.ibm.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=philmd@mailo.com \
    --cc=pierrick.bouvier@oss.qualcomm.com \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    --cc=qemu-riscv@nongnu.org \
    --cc=qemu-s390x@nongnu.org \
    --cc=richard.henderson@linaro.org \
    --cc=sai.pavan.boddu@amd.com \
    --cc=sam@rfc1149.net \
    --cc=shentey@gmail.com \
    --cc=shorne@gmail.com \
    --cc=slp@redhat.com \
    --cc=sundeep.lkml@gmail.com \
    --cc=th.huth+qemu@posteo.eu \
    --cc=wangran@bosc.ac.cn \
    --cc=wuhaotsh@google.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 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.