>-----Original Message-----
>From: Cédric Le Goater <[email protected]>
>Subject: Re: [RFC PATCH 03/14] vfio/iommufd: Create nesting parent hwpt with
>IOMMU_HWPT_ALLOC_PASID flag
>
>On 2/5/26 04:11, Zhenzhong Duan wrote:
>> When both host device and vIOMMU have PASID enabled, then guest may
>> setup pasid attached translation.
>>
>> We need to create the nesting parent hwpt with IOMMU_HWPT_ALLOC_PASID
>> flag because according to uAPI, any domain attached to the non-PASID
>> part of the device must also be flagged, otherwise attaching a PASID
>> will blocked.
>>
>> Introduce a vfio_device_get_viommu_flags_pasid_supported() helper to
>> facilitate this implementation.
>>
>> Signed-off-by: Zhenzhong Duan <[email protected]>
>> ---
>>   include/hw/vfio/vfio-device.h |  1 +
>>   hw/vfio/device.c              | 11 +++++++++++
>>   hw/vfio/iommufd.c             |  8 +++++++-
>>   3 files changed, 19 insertions(+), 1 deletion(-)
>>
>> diff --git a/include/hw/vfio/vfio-device.h b/include/hw/vfio/vfio-device.h
>> index 35a5ec6d92..983eb0ecce 100644
>> --- a/include/hw/vfio/vfio-device.h
>> +++ b/include/hw/vfio/vfio-device.h
>> @@ -268,6 +268,7 @@ void vfio_device_prepare(VFIODevice *vbasedev,
>VFIOContainer *bcontainer,
>>   void vfio_device_unprepare(VFIODevice *vbasedev);
>>
>>   bool vfio_device_get_viommu_flags_want_nesting(VFIODevice *vbasedev);
>> +bool vfio_device_get_viommu_flags_pasid_supported(VFIODevice *vbasedev);
>>   bool vfio_device_get_host_iommu_quirk_bypass_ro(VFIODevice *vbasedev,
>>                                                   uint32_t type, void *caps,
>>                                                   uint32_t size);
>> diff --git a/hw/vfio/device.c b/hw/vfio/device.c
>> index 973fc35b59..b15ca6ef0a 100644
>> --- a/hw/vfio/device.c
>> +++ b/hw/vfio/device.c
>> @@ -533,6 +533,17 @@ bool
>vfio_device_get_viommu_flags_want_nesting(VFIODevice *vbasedev)
>>       return false;
>>   }
>>
>> +bool vfio_device_get_viommu_flags_pasid_supported(VFIODevice *vbasedev)
>> +{
>> +    VFIOPCIDevice *vdev = vfio_pci_from_vfio_device(vbasedev);
>> +
>> +    if (vdev) {
>> +        return !!(pci_device_get_viommu_flags(PCI_DEVICE(vdev)) &
>> +                  VIOMMU_FLAG_PASID_SUPPORTED);
>> +    }
>> +    return false;
>> +}
>> +
>>   bool vfio_device_get_host_iommu_quirk_bypass_ro(VFIODevice *vbasedev,
>>                                                   uint32_t type, void *caps,
>>                                                   uint32_t size)
>> diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
>> index 96735f1fc8..9605bf73b7 100644
>> --- a/hw/vfio/iommufd.c
>> +++ b/hw/vfio/iommufd.c
>> @@ -354,6 +354,7 @@ static bool
>iommufd_cdev_autodomains_get(VFIODevice *vbasedev,
>>       VendorCaps caps;
>>       VFIOIOASHwpt *hwpt;
>>       uint32_t hwpt_id;
>> +    uint8_t max_pasid_log2;
>
>I think this should be initialized to some default value.

OK, will add max_pasid_log2 = 0;

>
>>       int ret;
>>
>>       /* Try to find a domain */
>> @@ -398,7 +399,7 @@ static bool
>iommufd_cdev_autodomains_get(VFIODevice *vbasedev,
>>        */
>>       if (!iommufd_backend_get_device_info(vbasedev->iommufd, vbasedev-
>>devid,
>>                                            &type, &caps, sizeof(caps), 
>> &hw_caps,
>> -                                         NULL, errp)) {
>> +                                         &max_pasid_log2, errp)) {
>>           return false;
>>       }
>>
>> @@ -420,6 +421,11 @@ static bool
>iommufd_cdev_autodomains_get(VFIODevice *vbasedev,
>>           }
>>       }
>>
>> +    if (max_pasid_log2 &&
>> +        vfio_device_get_viommu_flags_pasid_supported(vbasedev)) {
>
>Can an IOMMU backend not support PASID while the vIOMMU device does ?
>That would be a problem no ?

If IOMMU backend doesn't support PASID, max_pasid_log2 will be 0 returned by 
get_device_info().
Then QEMU will not expose vPASID capability of VFIO device to guest, then guest 
cannot enable PASID on this VFIO device even though vIOMMU support PASID.

Thanks
Zhenzhong

>
>> +        flags |= IOMMU_HWPT_ALLOC_PASID;
>> +    }
>> +
>>       if (cpr_is_incoming()) {
>>           hwpt_id = vbasedev->cpr.hwpt_id;
>>           goto skip_alloc;

Reply via email to