Hi Nicolin, On Wed, 6 Aug 2025 at 01:55, Nicolin Chen <nicol...@nvidia.com> wrote: > > Hi Shameer, > > On Mon, Jul 14, 2025 at 04:59:32PM +0100, Shameer Kolothum wrote: > > @@ -25,30 +31,72 @@ static SMMUv3AccelDevice > > *smmuv3_accel_get_dev(SMMUState *bs, SMMUPciBus *sbus, > > > > sbus->pbdev[devfn] = sdev; > > smmu_init_sdev(bs, sdev, bus, devfn); > > + address_space_init(&accel_dev->as_sysmem, &s->s_accel->root, > > + "smmuv3-accel-sysmem"); > > } > > > > return accel_dev; > > } > [..] > > static AddressSpace *smmuv3_accel_find_add_as(PCIBus *bus, void *opaque, > > int devfn) > > { > > + PCIDevice *pdev = pci_find_device(bus, pci_bus_num(bus), devfn); > > SMMUState *bs = opaque; > > + bool vfio_pci = false; > > SMMUPciBus *sbus; > > SMMUv3AccelDevice *accel_dev; > > SMMUDevice *sdev; > > > > + if (pdev && !smmuv3_accel_pdev_allowed(pdev, &vfio_pci)) { > > + error_report("Device(%s) not allowed. Only PCIe root complex > > devices " > > + "or PCI bridge devices or vfio-pci endpoint devices > > with " > > + "iommufd as backend is allowed with > > arm-smmuv3,accel=on", > > + pdev->name); > > + exit(1); > > + } > > sbus = smmu_get_sbus(bs, bus); > > accel_dev = smmuv3_accel_get_dev(bs, sbus, bus, devfn); > > sdev = &accel_dev->sdev; > > > > - return &sdev->as; > > + if (vfio_pci) { > > + return &accel_dev->as_sysmem; > > I found a new problem here that we initialize new as_sysmem per > VFIO device. So, sdevs would return own individual AS pointers > here at this get_address_space function, although they point to > the same system address space. > > Since address space pointers are returned differently for VFIO > devices, this fails to reuse ioas_id in iommufd_cdev_attach(), > and ends up with allocating a new ioas for each device. > > I think we can try the following change to make sure all accel > linked VFIO devices would share the same ioas_id, though I am > not sure if SMMUBaseClass is the right place to go. Please take > a look.
Ok. I think it is better to move that to SMMUv3AccelState and call address_space_init() in smmuv3_accel_init() instead. Something like below. Please take a look and let me know. Thanks, Shameer diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c index 3b2f45bd88..e7feae931d 100644 --- a/hw/arm/smmuv3-accel.c +++ b/hw/arm/smmuv3-accel.c @@ -339,7 +339,6 @@ void smmuv3_accel_batch_cmd(SMMUState *bs, SMMUDevice *sdev, static SMMUv3AccelDevice *smmuv3_accel_get_dev(SMMUState *bs, SMMUPciBus *sbus, PCIBus *bus, int devfn) { - SMMUv3State *s = ARM_SMMUV3(bs); SMMUDevice *sdev = sbus->pbdev[devfn]; SMMUv3AccelDevice *accel_dev; @@ -351,8 +350,6 @@ static SMMUv3AccelDevice *smmuv3_accel_get_dev(SMMUState *bs, SMMUPciBus *sbus, sbus->pbdev[devfn] = sdev; smmu_init_sdev(bs, sdev, bus, devfn); - address_space_init(&accel_dev->as_sysmem, &s->s_accel->root, - "smmuv3-accel-sysmem"); } return accel_dev; @@ -518,6 +515,7 @@ static AddressSpace *smmuv3_accel_find_msi_as(PCIBus *bus, void *opaque, int devfn) { SMMUState *bs = opaque; + SMMUv3State *s = ARM_SMMUV3(bs); SMMUPciBus *sbus; SMMUv3AccelDevice *accel_dev; SMMUDevice *sdev; @@ -534,7 +532,7 @@ static AddressSpace *smmuv3_accel_find_msi_as(PCIBus *bus, void *opaque, if (accel_dev->s1_hwpt) { return &sdev->as; } else { - return &accel_dev->as_sysmem; + return &s->s_accel->as_sysmem; } } @@ -558,6 +556,7 @@ static AddressSpace *smmuv3_accel_find_add_as(PCIBus *bus, void *opaque, { PCIDevice *pdev = pci_find_device(bus, pci_bus_num(bus), devfn); SMMUState *bs = opaque; + SMMUv3State *s = ARM_SMMUV3(bs); bool vfio_pci = false; SMMUPciBus *sbus; SMMUv3AccelDevice *accel_dev; @@ -575,7 +574,7 @@ static AddressSpace *smmuv3_accel_find_add_as(PCIBus *bus, void *opaque, sdev = &accel_dev->sdev; if (vfio_pci) { - return &accel_dev->as_sysmem; + return &s->s_accel->as_sysmem; } else { return &sdev->as; } @@ -612,6 +611,8 @@ void smmuv3_accel_init(SMMUv3State *s) "smmuv3-accel-sysmem", get_system_memory(), 0, memory_region_size(get_system_memory())); memory_region_add_subregion(&s_accel->root, 0, &s_accel->sysmem); + address_space_init(&s_accel->as_sysmem, &s_accel->root, + "smmuv3-accel-sysmem"); } static void smmuv3_accel_class_init(ObjectClass *oc, const void *data) diff --git a/hw/arm/smmuv3-accel.h b/hw/arm/smmuv3-accel.h index e1e99598b4..8f04f2fa5d 100644 --- a/hw/arm/smmuv3-accel.h +++ b/hw/arm/smmuv3-accel.h @@ -37,7 +37,6 @@ typedef struct SMMUS1Hwpt { typedef struct SMMUv3AccelDevice { SMMUDevice sdev; - AddressSpace as_sysmem; HostIOMMUDeviceIOMMUFD *idev; SMMUS1Hwpt *s1_hwpt; SMMUViommu *viommu; @@ -48,6 +47,7 @@ typedef struct SMMUv3AccelDevice { typedef struct SMMUv3AccelState { MemoryRegion root; MemoryRegion sysmem; + AddressSpace as_sysmem; SMMUViommu *viommu; struct iommu_hw_info_arm_smmuv3 info; } SMMUv3AccelState;