[PATCH] hw/pci: Avoid adding PCI devices to the "unattached" QOM tree node

Thomas Huth posted 1 patch 1 month, 3 weeks ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260217065512.245237-1-thuth@redhat.com
Maintainers: "Michael S. Tsirkin" <mst@redhat.com>, Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
hw/pci/pci.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
[PATCH] hw/pci: Avoid adding PCI devices to the "unattached" QOM tree node
Posted by Thomas Huth 1 month, 3 weeks ago
From: Thomas Huth <thuth@redhat.com>

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 <thuth@redhat.com>
---
 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);
     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);
     return true;
 }
@@ -2412,6 +2422,8 @@ PCIDevice *pci_create_simple_multifunction(PCIBus *bus, int devfn,
                                            const char *name)
 {
     PCIDevice *dev = pci_new_multifunction(devfn, name);
+
+    pci_dev_property_add_child(bus, name, dev);
     pci_realize_and_unref(dev, bus, &error_fatal);
     return dev;
 }
@@ -2419,6 +2431,8 @@ PCIDevice *pci_create_simple_multifunction(PCIBus *bus, int devfn,
 PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name)
 {
     PCIDevice *dev = pci_new(devfn, name);
+
+    pci_dev_property_add_child(bus, name, dev);
     pci_realize_and_unref(dev, bus, &error_fatal);
     return dev;
 }
-- 
2.53.0
Re: [PATCH] hw/pci: Avoid adding PCI devices to the "unattached" QOM tree node
Posted by Igor Mammedov 1 month, 3 weeks ago
On Tue, 17 Feb 2026 07:55:12 +0100
Thomas Huth <thuth@redhat.com> wrote:

> From: Thomas Huth <thuth@redhat.com>
> 
> 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 <thuth@redhat.com>
> ---
>  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?

>      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?

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.


>      return true;
>  }
> @@ -2412,6 +2422,8 @@ PCIDevice *pci_create_simple_multifunction(PCIBus *bus, int devfn,
>                                             const char *name)
>  {
>      PCIDevice *dev = pci_new_multifunction(devfn, name);
> +
> +    pci_dev_property_add_child(bus, name, dev);
>      pci_realize_and_unref(dev, bus, &error_fatal);
>      return dev;
>  }
> @@ -2419,6 +2431,8 @@ PCIDevice *pci_create_simple_multifunction(PCIBus *bus, int devfn,
>  PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name)
>  {
>      PCIDevice *dev = pci_new(devfn, name);
> +
> +    pci_dev_property_add_child(bus, name, dev);
>      pci_realize_and_unref(dev, bus, &error_fatal);
>      return dev;
>  }
Re: [PATCH] hw/pci: Avoid adding PCI devices to the "unattached" QOM tree node
Posted by Igor Mammedov 1 month, 3 weeks ago
On Thu, 19 Feb 2026 16:06:41 +0100
Igor Mammedov <imammedo@redhat.com> wrote:

> On Tue, 17 Feb 2026 07:55:12 +0100
> Thomas Huth <thuth@redhat.com> wrote:
> 
> > From: Thomas Huth <thuth@redhat.com>
> > 
> > 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 <thuth@redhat.com>
> > ---
> >  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?
> 
> >      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?
> 
> 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.

and then this rises a question if the bus should be a parent or
the owner of the bus is the parent?

> 
> 
> >      return true;
> >  }
> > @@ -2412,6 +2422,8 @@ PCIDevice *pci_create_simple_multifunction(PCIBus *bus, int devfn,
> >                                             const char *name)
> >  {
> >      PCIDevice *dev = pci_new_multifunction(devfn, name);
> > +
> > +    pci_dev_property_add_child(bus, name, dev);
> >      pci_realize_and_unref(dev, bus, &error_fatal);
> >      return dev;
> >  }
> > @@ -2419,6 +2431,8 @@ PCIDevice *pci_create_simple_multifunction(PCIBus *bus, int devfn,
> >  PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name)
> >  {
> >      PCIDevice *dev = pci_new(devfn, name);
> > +
> > +    pci_dev_property_add_child(bus, name, dev);
> >      pci_realize_and_unref(dev, bus, &error_fatal);
> >      return dev;
> >  }  
>
Re: [PATCH] hw/pci: Avoid adding PCI devices to the "unattached" QOM tree node
Posted by Markus Armbruster 1 month, 1 week ago
Igor Mammedov <imammedo@redhat.com> writes:

> On Thu, 19 Feb 2026 16:06:41 +0100
> Igor Mammedov <imammedo@redhat.com> wrote:
>
>> On Tue, 17 Feb 2026 07:55:12 +0100
>> Thomas Huth <thuth@redhat.com> wrote:
>> 
>> > From: Thomas Huth <thuth@redhat.com>
>> > 
>> > 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 <thuth@redhat.com>
>> > ---
>> >  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?
>> 
>> >      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?
>> 
>> 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.
>
> and then this rises a question if the bus should be a parent or
> the owner of the bus is the parent?

This question is about the QOM composition tree (the thing "info
qom-tree" shows).

There is also the qdev tree (the thing "info qtree" shows).  In the qdev
tree, the PCI device's parent is a PCI bus, and the PCI bus's parent is
the device providing the bus.  An edge from qdev to parent qbus means
qdev plugs into qbus.  An edge from qbus to parent qdev means qbus is
provided by qdev.

Example: an i440FX machine's device i440FX-pcihost is parent of PCI bus
"pci.0" is parent of device PIIX3.

In the QOM composition tree, an edge from child to parent means parent
contains child.

Example: a i440FX machine's i440FX-pcihost device object /machine/i440fx
is the parent of PCI bus object /machine/i440fx/pci.0.  Makes sense.
i440FX-pcihost also contains a PIIX3 PCI device wired to its PCI bus.
Should PIIX3 be the QOM child of the i440FX-pcihost device, or of its
PCI bus?  This is Igor's question.  Due to sloppy modeling, it's
currently neither: it's at /machine/unattached/device[3] instead.

Is there any non-sloppy precedence to guide us?

QOM maintainers, do you have any advice?

[...]
Re: [PATCH] hw/pci: Avoid adding PCI devices to the "unattached" QOM tree node
Posted by Thomas Huth 1 month, 2 weeks ago
On 19/02/2026 16.18, Igor Mammedov wrote:
> On Thu, 19 Feb 2026 16:06:41 +0100
> Igor Mammedov <imammedo@redhat.com> wrote:
> 
>> On Tue, 17 Feb 2026 07:55:12 +0100
>> Thomas Huth <thuth@redhat.com> wrote:
>>
>>> From: Thomas Huth <thuth@redhat.com>
>>>
>>> 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 <thuth@redhat.com>
>>> ---
>>>   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/20260217164049.543975-1-thuth@redhat.com/

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