On 2/26/26 11:50 AM, Shameer Kolothum wrote:
> 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 <[email protected]>
> ---
>  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)
nit: I would prefer vms to be the 1st arg
>  {
> -    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);
So did you check this does not break existing bios qtests (as we change
the way we iterate on the devices)? If so maybe add a comment in commit
description.
>      }
>  
>      num_smmus = smmuv3_devs->len;
I would squash previous patch in that one.

Reviewed-by: Eric Auger <[email protected]>

Eric


Reply via email to