From: Liu Yi L <yi.l.liu@xxxxxxxxx> The PASID quota is per-application (VM) according to vfio's PASID management rule. For better flexibility, quota shall be user tunable . This patch provides a VFIO based user interface for which quota can be adjusted. However, quota cannot be adjusted downward below the number of outstanding PASIDs. This patch only makes the per-VM PASID quota tunable. While for the way to tune the default PASID quota, it may require a new vfio module option or other way. This may be another patchset in future. Previous discussions: https://patchwork.kernel.org/patch/11209429/ Cc: Kevin Tian <kevin.tian@xxxxxxxxx> CC: Jacob Pan <jacob.jun.pan@xxxxxxxxxxxxxxx> Cc: Alex Williamson <alex.williamson@xxxxxxxxxx> Cc: Eric Auger <eric.auger@xxxxxxxxxx> Cc: Jean-Philippe Brucker <jean-philippe.brucker@xxxxxxx> Signed-off-by: Liu Yi L <yi.l.liu@xxxxxxxxx> --- drivers/vfio/vfio_iommu_type1.c | 33 +++++++++++++++++++++++++++++++++ include/uapi/linux/vfio.h | 22 ++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c index e836d04..1cf75f5 100644 --- a/drivers/vfio/vfio_iommu_type1.c +++ b/drivers/vfio/vfio_iommu_type1.c @@ -2243,6 +2243,27 @@ static int vfio_iommu_type1_pasid_free(struct vfio_iommu *iommu, return ret; } +static int vfio_iommu_type1_set_pasid_quota(struct vfio_iommu *iommu, + u32 quota) +{ + struct vfio_mm *vmm = iommu->vmm; + int ret = 0; + + mutex_lock(&iommu->lock); + mutex_lock(&vmm->pasid_lock); + if (vmm->pasid_count > quota) { + ret = -EINVAL; + goto out_unlock; + } + vmm->pasid_quota = quota; + ret = quota; + +out_unlock: + mutex_unlock(&vmm->pasid_lock); + mutex_unlock(&iommu->lock); + return ret; +} + static long vfio_iommu_type1_ioctl(void *iommu_data, unsigned int cmd, unsigned long arg) { @@ -2389,6 +2410,18 @@ static long vfio_iommu_type1_ioctl(void *iommu_data, default: return -EINVAL; } + } else if (cmd == VFIO_IOMMU_SET_PASID_QUOTA) { + struct vfio_iommu_type1_pasid_quota quota; + + minsz = offsetofend(struct vfio_iommu_type1_pasid_quota, + quota); + + if (copy_from_user("a, (void __user *)arg, minsz)) + return -EFAULT; + + if (quota.argsz < minsz) + return -EINVAL; + return vfio_iommu_type1_set_pasid_quota(iommu, quota.quota); } return -ENOTTY; diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h index 298ac80..d4bf415 100644 --- a/include/uapi/linux/vfio.h +++ b/include/uapi/linux/vfio.h @@ -835,6 +835,28 @@ struct vfio_iommu_type1_pasid_request { */ #define VFIO_IOMMU_PASID_REQUEST _IO(VFIO_TYPE, VFIO_BASE + 22) +/** + * @quota: the new pasid quota which a userspace application (e.g. VM) + * is configured. + */ +struct vfio_iommu_type1_pasid_quota { + __u32 argsz; + __u32 flags; + __u32 quota; +}; + +/** + * VFIO_IOMMU_SET_PASID_QUOTA - _IOW(VFIO_TYPE, VFIO_BASE + 23, + * struct vfio_iommu_type1_pasid_quota) + * + * Availability of this feature depends on PASID support in the device, + * its bus, the underlying IOMMU and the CPU architecture. In VFIO, it + * is available after VFIO_SET_IOMMU. + * + * returns: latest quota on success, -errno on failure. + */ +#define VFIO_IOMMU_SET_PASID_QUOTA _IO(VFIO_TYPE, VFIO_BASE + 23) + /* -------- Additional API for SPAPR TCE (Server POWERPC) IOMMU -------- */ /* -- 2.7.4