@samitouri / QOSamiQemu / commits / eb7a06e842

hw/arm/smmuv3: Add per-device identifier property

Add an "identifier" property to the SMMUv3 device and use it when building the ACPI IORT SMMUv3 node Identifier field. This avoids relying on device enumeration order and provides a stable per-device identifier. A subsequent patch will use the same identifier when generating the DSDT description for Tegra241 CMDQV, ensuring that the IORT and DSDT entries refer to the same SMMUv3 instance. The identifier is assigned at pre-plug time, accounting for the ITS Group node that build_iort() places before SMMUv3 nodes in the IORT table, so that identifiers are globally unique across all IORT nodes. No functional change: IORT blob content for bios-tables qtest is identical to before. Reviewed-by: Eric Auger <eric.auger@redhat.com> Reviewed-by: Nicolin Chen <nicolinc@nvidia.com> Tested-by: Nicolin Chen <nicolinc@nvidia.com> Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com> Tested-by: Eric Auger <eric.auger@redhat.com> Message-id: 20260609112552.378999-27-skolothumtho@nvidia.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Shameer Kolothum committed Jun 9, 2026 at 12:25 UTC eb7a06e842409f41cbd85b01086d8e6a2b9c4774
4 files changed +19 -1
hw/arm/smmuv3.c
+2
@@ -2126,6 +2126,8 @@ static const Property smmuv3_properties[] = {
2126 * Defaults to stage 1
2127 */
2128 DEFINE_PROP_STRING("stage", SMMUv3State, stage),
2129 + /* Identifier used for ACPI IORT SMMUv3 (and DSDT for CMDQV) generation */
2130 + DEFINE_PROP_UINT8("identifier", SMMUv3State, identifier, 0),
2131 DEFINE_PROP_BOOL("accel", SMMUv3State, accel, false),
2132 /* GPA of MSI doorbell, for SMMUv3 accel use. */
2133 DEFINE_PROP_UINT64("msi-gpa", SMMUv3State, msi_gpa, 0),
hw/arm/virt-acpi-build.c
+4 -1
@@ -349,6 +349,7 @@ static int iort_idmap_compare(gconstpointer a, gconstpointer b)
349 typedef struct AcpiIortSMMUv3Dev {
350 int irq;
351 hwaddr base;
352 + uint8_t id;
353 GArray *rc_smmu_idmaps;
354 /* Offset of the SMMUv3 IORT Node relative to the start of the IORT */
355 size_t offset;
@@ -411,6 +412,7 @@ static int populate_smmuv3_dev(VirtMachineState *vms, GArray *sdev_blob)
412 &error_abort));
413 sdev.accel = object_property_get_bool(obj, "accel", &error_abort);
414 sdev.ats = smmuv3_ats_enabled(ARM_SMMUV3(obj));
415 + sdev.id = object_property_get_uint(obj, "identifier", &error_abort);
416 pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev);
417 sbdev = SYS_BUS_DEVICE(obj);
418 sdev.base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
@@ -637,7 +639,8 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
639 (ID_MAPPING_ENTRY_SIZE * smmu_mapping_count);
640 build_append_int_noprefix(table_data, node_size, 2); /* Length */
641 build_append_int_noprefix(table_data, 4, 1); /* Revision */
640 - build_append_int_noprefix(table_data, id++, 4); /* Identifier */
642 + build_append_int_noprefix(table_data, sdev->id, 4); /* Identifier */
643 + id++; /* advance shared counter for RC/RMR node uniqueness */
644 /* Number of ID mappings */
645 build_append_int_noprefix(table_data, smmu_mapping_count, 4);
646 /* Reference to ID Array */
hw/arm/virt.c
+12
@@ -254,6 +254,9 @@ static MemMapEntry extended_memmap[] = {
254 /* Any CXL Fixed memory windows come here */
255 };
256
257 +/* Counts SMMUv3 devices plugged; used to assign stable IORT identifiers */
258 +static uint8_t smmuv3_dev_id;
259 +
260 static const int a15irqmap[] = {
261 [VIRT_UART0] = 1,
262 [VIRT_RTC] = 2,
@@ -3830,6 +3833,15 @@ static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
3833 OBJECT(vms->sysmem), NULL);
3834 object_property_set_link(OBJECT(dev), "secure-memory",
3835 OBJECT(vms->secure_sysmem), NULL);
3836 + /*
3837 + * In build_iort(), the ITS node(id=0) precedes SMMUv3 nodes
3838 + * when present. Account for it so this SMMUv3's identifier
3839 + * is globally unique across all IORT nodes.
3840 + */
3841 + uint8_t its_offset = (vms->msi_controller == VIRT_MSI_CTRL_ITS)
3842 + ? 1 : 0;
3843 + object_property_set_uint(OBJECT(dev), "identifier",
3844 + its_offset + smmuv3_dev_id++, NULL);
3845 }
3846 if (object_property_get_bool(OBJECT(dev), "accel", &error_abort)) {
3847 hwaddr db_start = 0;
include/hw/arm/smmuv3.h
+1
@@ -65,6 +65,7 @@ struct SMMUv3State {
65 qemu_irq irq[4];
66 QemuMutex mutex;
67 char *stage;
68 + uint8_t identifier;
69
70 /* SMMU has HW accelerator support for nested S1 + s2 */
71 bool accel;