Hi Shameer,
On 9/29/25 3:36 PM, Shameer Kolothum wrote:
> From: Nicolin Chen <nicolinc@nvidia.com>
>
> Allocate and associate a vDEVICE object for the Guest device with the
> vIOMMU. This will help the host kernel to make a virtual SID --> physical
> SID mapping. Since we pass the raw invalidation commands(eg: CMD_CFGI_CD)
> from Guest directly to host kernel, this provides a way to retrieve the
> correct physical SID.
>
> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
> Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
> Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
> ---
> hw/arm/smmuv3-accel.c | 41 +++++++++++++++++++++++++++++++++++++++++
> hw/arm/smmuv3-accel.h | 1 +
> 2 files changed, 42 insertions(+)
>
> diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
> index 5c3825cecd..790887ac31 100644
> --- a/hw/arm/smmuv3-accel.c
> +++ b/hw/arm/smmuv3-accel.c
> @@ -39,6 +39,35 @@
> #define STE1_MASK (STE1_ETS | STE1_S1STALLD | STE1_S1CSH | STE1_S1COR | \
> STE1_S1CIR | STE1_S1DSS)
>
> +static bool
> +smmuv3_accel_alloc_vdev(SMMUv3AccelDevice *accel_dev, int sid, Error **errp)
> +{
> + SMMUViommu *viommu = accel_dev->viommu;
> + IOMMUFDVdev *vdev;
> + uint32_t vdev_id;
> +
> + if (!accel_dev->idev || accel_dev->vdev) {
> + return true;
> + }
> +
> + if (!iommufd_backend_alloc_vdev(viommu->iommufd, accel_dev->idev->devid,
> + viommu->core.viommu_id, sid,
> + &vdev_id, errp)) {
> + return false;
> + }
> + if (!host_iommu_device_iommufd_attach_hwpt(accel_dev->idev,
> + viommu->bypass_hwpt_id, errp)) {
> + iommufd_backend_free_id(viommu->iommufd, vdev_id);
> + return false;
> + }
> +
> + vdev = g_new(IOMMUFDVdev, 1);
> + vdev->vdev_id = vdev_id;
> + vdev->dev_id = sid;
That's confusing to me it should be virt_id and not dev_id which usually
refers to an iommu object id.
Would be nice in general to stick to the kernel uapi terminology. For
instance vdev_id shall rather vdevice_id although in that case it is
understandable.
+bool iommufd_backend_alloc_vdev(IOMMUFDBackend *be, uint32_t dev_id,
+ uint32_t viommu_id, uint64_t virt_id,
+ uint32_t *out_vdev_id, Error **errp)
* struct iommu_vdevice_alloc - ioctl(IOMMU_VDEVICE_ALLOC)
* @size: sizeof(struct iommu_vdevice_alloc)
* @viommu_id: vIOMMU ID to associate with the virtual device
* @dev_id: The physical device to allocate a virtual instance on the vIOMMU
* @out_vdevice_id: Object handle for the vDevice. Pass to IOMMU_DESTORY
* @virt_id: Virtual device ID per vIOMMU, e.g. vSID of ARM SMMUv3,
vDeviceID
* of AMD IOMMU, and vRID of Intel VT-d
> + accel_dev->vdev = vdev;
> + return true;
> +}
> +
> static bool
> smmuv3_accel_dev_uninstall_nested_ste(SMMUv3AccelDevice *accel_dev, bool abort,
> Error **errp)
> @@ -127,6 +156,10 @@ smmuv3_accel_install_nested_ste(SMMUv3State *s, SMMUDevice *sdev, int sid,
> return true;
> }
>
> + if (!smmuv3_accel_alloc_vdev(accel_dev, sid, errp)) {
> + return false;
> + }
> +
> ret = smmu_find_ste(sdev->smmu, sid, &ste, &event);
> if (ret) {
> error_setg(errp, "Failed to find STE for Device 0x%x", sid);
> @@ -311,6 +344,7 @@ static void smmuv3_accel_unset_iommu_device(PCIBus *bus, void *opaque,
> SMMUPciBus *sbus = g_hash_table_lookup(bs->smmu_pcibus_by_busptr, bus);
> SMMUv3AccelDevice *accel_dev;
> SMMUViommu *viommu;
> + IOMMUFDVdev *vdev;
> SMMUDevice *sdev;
> uint16_t sid;
>
> @@ -337,6 +371,13 @@ static void smmuv3_accel_unset_iommu_device(PCIBus *bus, void *opaque,
> trace_smmuv3_accel_unset_iommu_device(devfn, sid);
>
> viommu = s->s_accel->viommu;
> + vdev = accel_dev->vdev;
> + if (vdev) {
> + iommufd_backend_free_id(viommu->iommufd, vdev->vdev_id);
> + g_free(vdev);
> + accel_dev->vdev = NULL;
> + }
> +
> if (QLIST_EMPTY(&viommu->device_list)) {
> iommufd_backend_free_id(viommu->iommufd, viommu->bypass_hwpt_id);
> iommufd_backend_free_id(viommu->iommufd, viommu->abort_hwpt_id);
> diff --git a/hw/arm/smmuv3-accel.h b/hw/arm/smmuv3-accel.h
> index f631443b09..6242614c00 100644
> --- a/hw/arm/smmuv3-accel.h
> +++ b/hw/arm/smmuv3-accel.h
> @@ -31,6 +31,7 @@ typedef struct SMMUv3AccelDevice {
> SMMUDevice sdev;
> HostIOMMUDeviceIOMMUFD *idev;
> SMMUS1Hwpt *s1_hwpt;
> + IOMMUFDVdev *vdev;
> SMMUViommu *viommu;
> QLIST_ENTRY(SMMUv3AccelDevice) next;
> } SMMUv3AccelDevice;
Thanks
Eric