The powernv machine uses the object hierarchy to populate the device tree and each device should be parented to the chip it belongs to. This is not the case for user created devices which are parented to the container "/unattached".
Make sure a PHB3 device is parented to its chip by reparenting the object if necessary. Reviewed-by: Daniel Henrique Barboza <danielhb...@gmail.com> Reviewed-by: Frederic Barrat <fbar...@linux.ibm.com> Signed-off-by: Cédric Le Goater <c...@kaod.org> --- include/hw/ppc/pnv.h | 1 + hw/pci-host/pnv_phb3.c | 6 ++++++ hw/ppc/pnv.c | 17 +++++++++++++++++ 3 files changed, 24 insertions(+) diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h index 9b06a9e9948d..ca27bd39f0ac 100644 --- a/include/hw/ppc/pnv.h +++ b/include/hw/ppc/pnv.h @@ -177,6 +177,7 @@ DECLARE_INSTANCE_CHECKER(PnvChip, PNV_CHIP_POWER10, TYPE_PNV_CHIP_POWER10) PowerPCCPU *pnv_chip_find_cpu(PnvChip *chip, uint32_t pir); +void pnv_chip_parent_fixup(PnvChip *chip, Object *obj, int index); #define TYPE_PNV_MACHINE MACHINE_TYPE_NAME("powernv") typedef struct PnvMachineClass PnvMachineClass; diff --git a/hw/pci-host/pnv_phb3.c b/hw/pci-host/pnv_phb3.c index 4a022de7c1dc..62a184c9ddc9 100644 --- a/hw/pci-host/pnv_phb3.c +++ b/hw/pci-host/pnv_phb3.c @@ -1000,6 +1000,12 @@ static void pnv_phb3_realize(DeviceState *dev, Error **errp) error_setg(errp, "invalid chip id: %d", phb->chip_id); return; } + + /* + * Reparent user created devices to the chip to build + * correctly the device tree. + */ + pnv_chip_parent_fixup(phb->chip, OBJECT(phb), phb->phb_id); } if (phb->phb_id >= PNV_CHIP_GET_CLASS(phb->chip)->num_phbs) { diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index d134eca0ee9d..ac048a0a5d24 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -1806,6 +1806,23 @@ static ICSState *pnv_ics_get(XICSFabric *xi, int irq) return NULL; } +void pnv_chip_parent_fixup(PnvChip *chip, Object *obj, int index) +{ + Object *parent = OBJECT(chip); + g_autofree char *default_id = + g_strdup_printf("%s[%d]", object_get_typename(obj), index); + + if (obj->parent == parent) { + return; + } + + object_ref(obj); + object_unparent(obj); + object_property_add_child( + parent, DEVICE(obj)->id ? DEVICE(obj)->id : default_id, obj); + object_unref(obj); +} + PnvChip *pnv_get_chip(PnvMachineState *pnv, uint32_t chip_id) { int i; -- 2.31.1