Stop walking the object tree to discover SMMUv3 devices when building
the IORT table.
Use the SMMUv3 device array maintained by the virt machine instead,
avoiding recursive object traversal.
No functional change intended.
Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
---
hw/arm/virt-acpi-build.c | 70 ++++++++++++++++++----------------------
1 file changed, 31 insertions(+), 39 deletions(-)
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 544004615d..ae78e9b9e0 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -385,49 +385,41 @@ static int smmuv3_dev_idmap_compare(gconstpointer a, gconstpointer b)
return map_a->input_base - map_b->input_base;
}
-static int iort_smmuv3_devices(Object *obj, void *opaque)
-{
- VirtMachineState *vms = VIRT_MACHINE(qdev_get_machine());
- AcpiIortSMMUv3Dev sdev = {0};
- GArray *sdev_blob = opaque;
- AcpiIortIdMapping idmap;
- PlatformBusDevice *pbus;
- int min_bus, max_bus;
- SysBusDevice *sbdev;
- PCIBus *bus;
-
- if (!object_dynamic_cast(obj, TYPE_ARM_SMMUV3)) {
- return 0;
- }
-
- bus = PCI_BUS(object_property_get_link(obj, "primary-bus", &error_abort));
- sdev.accel = object_property_get_bool(obj, "accel", &error_abort);
- sdev.ats = object_property_get_bool(obj, "ats", &error_abort);
- pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev);
- sbdev = SYS_BUS_DEVICE(obj);
- sdev.base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
- sdev.base += vms->memmap[VIRT_PLATFORM_BUS].base;
- sdev.irq = platform_bus_get_irqn(pbus, sbdev, 0);
- sdev.irq += vms->irqmap[VIRT_PLATFORM_BUS];
- sdev.irq += ARM_SPI_BASE;
-
- pci_bus_range(bus, &min_bus, &max_bus);
- sdev.rc_smmu_idmaps = g_array_new(false, true, sizeof(AcpiIortIdMapping));
- idmap.input_base = min_bus << 8,
- idmap.id_count = (max_bus - min_bus + 1) << 8,
- g_array_append_val(sdev.rc_smmu_idmaps, idmap);
- g_array_append_val(sdev_blob, sdev);
- return 0;
-}
-
/*
* Populate the struct AcpiIortSMMUv3Dev for all SMMUv3 devices and
* return the total number of idmaps.
*/
-static int populate_smmuv3_dev(GArray *sdev_blob)
+static int populate_smmuv3_dev(GArray *sdev_blob, VirtMachineState *vms)
{
- object_child_foreach_recursive(object_get_root(),
- iort_smmuv3_devices, sdev_blob);
+ for (int i = 0; i < vms->smmuv3_devices->len; i++) {
+ Object *obj = OBJECT(g_ptr_array_index(vms->smmuv3_devices, i));
+ AcpiIortSMMUv3Dev sdev = {0};
+ AcpiIortIdMapping idmap;
+ PlatformBusDevice *pbus;
+ int min_bus, max_bus;
+ SysBusDevice *sbdev;
+ PCIBus *bus;
+
+ bus = PCI_BUS(object_property_get_link(obj, "primary-bus",
+ &error_abort));
+ sdev.accel = object_property_get_bool(obj, "accel", &error_abort);
+ sdev.ats = object_property_get_bool(obj, "ats", &error_abort);
+ pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev);
+ sbdev = SYS_BUS_DEVICE(obj);
+ sdev.base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
+ sdev.base += vms->memmap[VIRT_PLATFORM_BUS].base;
+ sdev.irq = platform_bus_get_irqn(pbus, sbdev, 0);
+ sdev.irq += vms->irqmap[VIRT_PLATFORM_BUS];
+ sdev.irq += ARM_SPI_BASE;
+
+ pci_bus_range(bus, &min_bus, &max_bus);
+ sdev.rc_smmu_idmaps = g_array_new(false, true,
+ sizeof(AcpiIortIdMapping));
+ idmap.input_base = min_bus << 8;
+ idmap.id_count = (max_bus - min_bus + 1) << 8;
+ g_array_append_val(sdev.rc_smmu_idmaps, idmap);
+ g_array_append_val(sdev_blob, sdev);
+ }
/* Sort the smmuv3 devices(if any) by smmu idmap input_base */
g_array_sort(sdev_blob, smmuv3_dev_idmap_compare);
/*
@@ -561,7 +553,7 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
if (vms->legacy_smmuv3_present) {
rc_smmu_idmaps_len = populate_smmuv3_legacy_dev(smmuv3_devs);
} else {
- rc_smmu_idmaps_len = populate_smmuv3_dev(smmuv3_devs);
+ rc_smmu_idmaps_len = populate_smmuv3_dev(smmuv3_devs, vms);
}
num_smmus = smmuv3_devs->len;
--
2.43.0