Hi Nicolin,
On Wed, 6 Aug 2025 at 01:55, Nicolin Chen <[email protected]> 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;