On 19/02/2026 16.18, Igor Mammedov wrote:
On Thu, 19 Feb 2026 16:06:41 +0100
Igor Mammedov <[email protected]> wrote:

On Tue, 17 Feb 2026 07:55:12 +0100
Thomas Huth <[email protected]> wrote:

From: Thomas Huth <[email protected]>

PCI devices that are added via pci_create_simple_multifunction(),
pci_create_simple() or pci_init_nic_in_slot() currently show up
under "/machine/unattached" in the QOM tree. This is somewhat ugly,
the parent should rather be the PCI bus node instead, so let's add
the proper relation here.

Signed-off-by: Thomas Huth <[email protected]>
---
  hw/pci/pci.c | 14 ++++++++++++++
  1 file changed, 14 insertions(+)

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 90d6d71efdc..2f4d2be50fd 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -2071,6 +2071,15 @@ const pci_class_desc *get_class_desc(int class)
      return desc;
  }
+static void pci_dev_property_add_child(PCIBus *bus, const char *name,
+                                       PCIDevice *dev)
+{
+    g_autofree char *childname = g_strdup_printf("%s[%d.%d]", name,
+                                                 PCI_SLOT(dev->devfn),
+                                                 PCI_FUNC(dev->devfn));
+    object_property_add_child(OBJECT(bus), childname, OBJECT(dev));
+}
+
  void pci_init_nic_devices(PCIBus *bus, const char *default_model)
  {
      qemu_create_nic_bus_devices(&bus->qbus, TYPE_PCI_DEVICE, default_model,
@@ -2114,6 +2123,7 @@ bool pci_init_nic_in_slot(PCIBus *rootbus, const char 
*model,
pci_dev = pci_new(devfn, model);
there are a few more places that have similar pattern, should we fix them to?

You mean the various spots in the device models that call pci_new() or pci_new_multifunction(), followed by a pci_realize_and_unref() without adding the child property in between? ... yes, I think most of those likely need fixing, too.

I wonder whether I should rather drop this patch and add some logic to pci_realize_and_unref() instead to fix it there, so all spots would benefit from that change automatically? WDYT?

      qdev_set_nic_properties(&pci_dev->qdev, nd);
+    pci_dev_property_add_child(bus, model, pci_dev);

      pci_realize_and_unref(pci_dev, bus, &error_fatal);
this one also takes bus as an argument, and then goes down to
  qdev_realize_and_unref->qdev_realize->qdev_set_parent_bus->bus_add_child
that eventually creates a link to device.

wouldn't pci_dev_property_add_child() create a duplicate entry
as a child with different name component there?

No, it's two different concepts in QEMU: QOM vs. qdev !

The thing that you found is qdev, and that's already looking fine (when you use "info qtree" on the HMP prompt, you can see that e.g. the VGA device should already show up as child of the "pci.0" bus for the i440fx machine).

My patch is about QOM, where e.g. the VGA node shows up in /machine/unattached instead of /machine/i440fx/pci.0

another question, should we 'fix' qdev_set_parent_bus->bus_add_child
to add a child instead of a link? That would do what patch intends
but consistently for all devices with parent bus.

I've got another patch on the list that does fiddle with qdev_realize (right after calling qdev_set_parent_bus):

 https://lore.kernel.org/qemu-devel/[email protected]/

But I think we still want something here for PCI devices so that we can take advantage of the dev->devfn for creating the location on the bus in the square brackets.

and then this rises a question if the bus should be a parent or
the owner of the bus is the parent?
With my patch, the qom-tree looks like this:

QEMU 10.2.50 monitor - type 'help' for more information
(qemu) info qom-tree
/machine (pc-i440fx-11.0-machine)
  /fw_cfg (fw_cfg_io)
    /\x2from@etc\x2facpi\x2frsdp[0] (memory-region)
    /\x2from@etc\x2facpi\x2ftables[0] (memory-region)
    /\x2from@etc\x2ftable-loader[0] (memory-region)
    /fwcfg.dma[0] (memory-region)
    /fwcfg[0] (memory-region)
  /i440fx (i440FX-pcihost)
    /ioapic (ioapic)
      /ioapic[0] (memory-region)
      /unnamed-gpio-in[0] (irq)
      /unnamed-gpio-in[10] (irq)
      /unnamed-gpio-in[11] (irq)
      /unnamed-gpio-in[12] (irq)
      /unnamed-gpio-in[13] (irq)
      /unnamed-gpio-in[14] (irq)
      /unnamed-gpio-in[15] (irq)
      /unnamed-gpio-in[16] (irq)
      /unnamed-gpio-in[17] (irq)
      /unnamed-gpio-in[18] (irq)
      /unnamed-gpio-in[19] (irq)
      /unnamed-gpio-in[1] (irq)
      /unnamed-gpio-in[20] (irq)
      /unnamed-gpio-in[21] (irq)
      /unnamed-gpio-in[22] (irq)
      /unnamed-gpio-in[23] (irq)
      /unnamed-gpio-in[2] (irq)
      /unnamed-gpio-in[3] (irq)
      /unnamed-gpio-in[4] (irq)
      /unnamed-gpio-in[5] (irq)
      /unnamed-gpio-in[6] (irq)
      /unnamed-gpio-in[7] (irq)
      /unnamed-gpio-in[8] (irq)
      /unnamed-gpio-in[9] (irq)
    /pci-conf-data[0] (memory-region)
    /pci-conf-idx[0] (memory-region)
    /pci.0 (PCI)
      /VGA[31.7] (VGA)
        /bochs dispi interface[0] (memory-region)
        /bus master container[0] (memory-region)
        /bus master[0] (memory-region)
        /edid[0] (memory-region)
        /qemu extended regs[0] (memory-region)
        /vbe[0] (memory-region)
        /vga ioports remapped[0] (memory-region)
        /vga-lowmem[0] (memory-region)
        /vga.mmio[0] (memory-region)
        /vga.rom[0] (memory-region)
        /vga.vram[0] (memory-region)
        /vga[0] (memory-region)
        /vga[1] (memory-region)
        /vga[2] (memory-region)
        /vga[3] (memory-region)
        /vga[4] (memory-region)
      /i440FX[0.0] (i440FX)
        /bus master container[0] (memory-region)
        /bus master[0] (memory-region)
        /pam-pci[0] (memory-region)
        /pam-pci[10] (memory-region)
        /pam-pci[11] (memory-region)
        /pam-pci[12] (memory-region)
        /pam-pci[13] (memory-region)
        /pam-pci[14] (memory-region)
        /pam-pci[15] (memory-region)
        /pam-pci[16] (memory-region)
        /pam-pci[17] (memory-region)
        /pam-pci[18] (memory-region)
        /pam-pci[19] (memory-region)
        /pam-pci[1] (memory-region)
        /pam-pci[20] (memory-region)
        /pam-pci[21] (memory-region)
        /pam-pci[22] (memory-region)
        /pam-pci[23] (memory-region)
        /pam-pci[24] (memory-region)
        /pam-pci[25] (memory-region)
        /pam-pci[2] (memory-region)
        /pam-pci[3] (memory-region)
        /pam-pci[4] (memory-region)
        /pam-pci[5] (memory-region)
        /pam-pci[6] (memory-region)
        /pam-pci[7] (memory-region)
        /pam-pci[8] (memory-region)
        /pam-pci[9] (memory-region)
        /pam-ram[0] (memory-region)
        /pam-ram[10] (memory-region)
        /pam-ram[11] (memory-region)
        /pam-ram[12] (memory-region)
        /pam-ram[1] (memory-region)
        /pam-ram[2] (memory-region)
        /pam-ram[3] (memory-region)
        /pam-ram[4] (memory-region)
        /pam-ram[5] (memory-region)
        /pam-ram[6] (memory-region)
        /pam-ram[7] (memory-region)
        /pam-ram[8] (memory-region)
        /pam-ram[9] (memory-region)
        /pam-rom[0] (memory-region)
        /pam-rom[10] (memory-region)
        /pam-rom[11] (memory-region)
        /pam-rom[12] (memory-region)
        /pam-rom[1] (memory-region)
        /pam-rom[2] (memory-region)
        /pam-rom[3] (memory-region)
        /pam-rom[4] (memory-region)
        /pam-rom[5] (memory-region)
        /pam-rom[6] (memory-region)
        /pam-rom[7] (memory-region)
        /pam-rom[8] (memory-region)
        /pam-rom[9] (memory-region)
        /smram-low[0] (memory-region)
        /smram-region[0] (memory-region)
        /smram[0] (memory-region)
  /peripheral (container)
  /peripheral-anon (container)
  /unattached (container)
    /device[0] (qemu64-x86_64-cpu)
      /lapic (apic)
        /apic-msi[0] (memory-region)
      /memory[0] (memory-region)
      /memory[1] (memory-region)
      /smram[0] (memory-region)
    /device[10] (isa-parallel)
      /parallel[0] (memory-region)
    /device[11] (isa-fdc)
      /fdc[0] (memory-region)
      /fdc[1] (memory-region)
      /floppy-bus.0 (floppy-bus)
    /device[12] (floppy)
    /device[13] (i8042)
      /i8042-cmd[0] (memory-region)
      /i8042-data[0] (memory-region)
      /ps2-kbd-input-irq[0] (irq)
      /ps2-mouse-input-irq[0] (irq)
      /ps2kbd (ps2-kbd)
      /ps2mouse (ps2-mouse)
    /device[14] (vmport)
      /vmport[0] (memory-region)
    /device[15] (vmmouse)
    /device[16] (port92)
      /port92[0] (memory-region)
    /device[17] (e1000)
      /bus master container[0] (memory-region)
      /bus master[0] (memory-region)
      /e1000-io[0] (memory-region)
      /e1000-mmio[0] (memory-region)
      /e1000.rom[0] (memory-region)
    /device[18] (smbus-eeprom)
    /device[19] (smbus-eeprom)
    /device[1] (kvmvapic)
      /kvmvapic[0] (memory-region)
    /device[20] (smbus-eeprom)
    /device[21] (smbus-eeprom)
    /device[22] (smbus-eeprom)
    /device[23] (smbus-eeprom)
    /device[24] (smbus-eeprom)
    /device[25] (smbus-eeprom)
    /device[2] (PIIX3)
      /bus master container[0] (memory-region)
      /bus master[0] (memory-region)
      /dma[0] (i8257)
        /dma-chan[0] (memory-region)
        /dma-cont[0] (memory-region)
        /dma-page[0] (memory-region)
        /dma-page[1] (memory-region)
      /dma[1] (i8257)
        /dma-chan[0] (memory-region)
        /dma-cont[0] (memory-region)
        /dma-page[0] (memory-region)
        /dma-page[1] (memory-region)
      /ide (piix3-ide)
        /bmdma[0] (memory-region)
        /bmdma[1] (memory-region)
        /bus master container[0] (memory-region)
        /bus master[0] (memory-region)
        /ide.0 (IDE)
        /ide.1 (IDE)
        /piix-bmdma-container[0] (memory-region)
        /piix-bmdma[0] (memory-region)
        /piix-bmdma[1] (memory-region)
      /isa.0 (ISA)
      /piix-reset-control[0] (memory-region)
      /pm (PIIX4_PM)
        /acpi-cnt[0] (memory-region)
        /acpi-cpu-hotplug[0] (memory-region)
        /acpi-evt[0] (memory-region)
        /acpi-gpe0[0] (memory-region)
        /acpi-pci-hotplug[0] (memory-region)
        /acpi-tmr[0] (memory-region)
        /apm-io[0] (memory-region)
        /bus master container[0] (memory-region)
        /bus master[0] (memory-region)
        /i2c (i2c-bus)
        /piix4-pm[0] (memory-region)
        /pm-smbus[0] (memory-region)
      /rtc (mc146818rtc)
        /rtc-index[0] (memory-region)
        /rtc[0] (memory-region)
    /device[3] (ide-cd)
    /device[4] (isa-i8259)
      /elcr[0] (memory-region)
      /pic[0] (memory-region)
      /unnamed-gpio-in[0] (irq)
      /unnamed-gpio-in[1] (irq)
      /unnamed-gpio-in[2] (irq)
      /unnamed-gpio-in[3] (irq)
      /unnamed-gpio-in[4] (irq)
      /unnamed-gpio-in[5] (irq)
      /unnamed-gpio-in[6] (irq)
      /unnamed-gpio-in[7] (irq)
    /device[5] (isa-i8259)
      /elcr[0] (memory-region)
      /pic[0] (memory-region)
      /unnamed-gpio-in[0] (irq)
      /unnamed-gpio-in[1] (irq)
      /unnamed-gpio-in[2] (irq)
      /unnamed-gpio-in[3] (irq)
      /unnamed-gpio-in[4] (irq)
      /unnamed-gpio-in[5] (irq)
      /unnamed-gpio-in[6] (irq)
      /unnamed-gpio-in[7] (irq)
    /device[6] (hpet)
      /hpet[0] (memory-region)
      /unnamed-gpio-in[0] (irq)
      /unnamed-gpio-in[1] (irq)
    /device[7] (isa-pit)
      /pit[0] (memory-region)
      /unnamed-gpio-in[0] (irq)
    /device[8] (isa-pcspk)
      /pcspk[0] (memory-region)
    /device[9] (isa-serial)
      /serial (serial)
      /serial[0] (memory-region)
    /ide[0] (memory-region)
    /ide[1] (memory-region)
    /ide[2] (memory-region)
    /ide[3] (memory-region)
    /io[0] (memory-region)
    /ioport80[0] (memory-region)
    /ioportF0[0] (memory-region)
    /isa-bios[0] (memory-region)
    /non-qdev-gpio[0] (irq)
    /non-qdev-gpio[10] (irq)
    /non-qdev-gpio[11] (irq)
    /non-qdev-gpio[12] (irq)
    /non-qdev-gpio[13] (irq)
    /non-qdev-gpio[14] (irq)
    /non-qdev-gpio[15] (irq)
    /non-qdev-gpio[16] (irq)
    /non-qdev-gpio[17] (irq)
    /non-qdev-gpio[18] (irq)
    /non-qdev-gpio[19] (irq)
    /non-qdev-gpio[1] (irq)
    /non-qdev-gpio[20] (irq)
    /non-qdev-gpio[21] (irq)
    /non-qdev-gpio[22] (irq)
    /non-qdev-gpio[23] (irq)
    /non-qdev-gpio[24] (irq)
    /non-qdev-gpio[25] (irq)
    /non-qdev-gpio[26] (irq)
    /non-qdev-gpio[27] (irq)
    /non-qdev-gpio[2] (irq)
    /non-qdev-gpio[3] (irq)
    /non-qdev-gpio[4] (irq)
    /non-qdev-gpio[5] (irq)
    /non-qdev-gpio[6] (irq)
    /non-qdev-gpio[7] (irq)
    /non-qdev-gpio[8] (irq)
    /non-qdev-gpio[9] (irq)
    /pc.bios[0] (memory-region)
    /pc.rom[0] (memory-region)
    /pci[0] (memory-region)
    /ram-below-4g[0] (memory-region)
    /sysbus (System)
    /system[0] (memory-region)

You can see that e.g. the VGA node now shows up under /machine/i440fx/pci.0 ... and that sounds like the right location to me. So I don't think that the owner of the bus should be the parent here.

 Thomas


Reply via email to