Hi Shameer,

On 9/29/25 3:36 PM, Shameer Kolothum wrote:
> From: Nicolin Chen <[email protected]>
>
> 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 <[email protected]>
> Signed-off-by: Shameer Kolothum <[email protected]>
> Signed-off-by: Shameer Kolothum <[email protected]>
> ---
>  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


Reply via email to