mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-18 22:14:16 +00:00
vfio: VFIO_DEVICE_[AT|DE]TACH_IOMMUFD_PT support pasid
This extends the VFIO_DEVICE_[AT|DE]TACH_IOMMUFD_PT ioctls to attach/detach a given pasid of a vfio device to/from an IOAS/HWPT. Link: https://patch.msgid.link/r/20250321180143.8468-4-yi.l.liu@intel.com Reviewed-by: Alex Williamson <alex.williamson@redhat.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Reviewed-by: Nicolin Chen <nicolinc@nvidia.com> Tested-by: Nicolin Chen <nicolinc@nvidia.com> Signed-off-by: Yi Liu <yi.l.liu@intel.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
This commit is contained in:
parent
290641346d
commit
ad744ed5dd
2 changed files with 71 additions and 18 deletions
|
|
@ -162,9 +162,9 @@ void vfio_df_unbind_iommufd(struct vfio_device_file *df)
|
|||
int vfio_df_ioctl_attach_pt(struct vfio_device_file *df,
|
||||
struct vfio_device_attach_iommufd_pt __user *arg)
|
||||
{
|
||||
struct vfio_device *device = df->device;
|
||||
struct vfio_device_attach_iommufd_pt attach;
|
||||
unsigned long minsz;
|
||||
struct vfio_device *device = df->device;
|
||||
unsigned long minsz, xend = 0;
|
||||
int ret;
|
||||
|
||||
minsz = offsetofend(struct vfio_device_attach_iommufd_pt, pt_id);
|
||||
|
|
@ -172,11 +172,34 @@ int vfio_df_ioctl_attach_pt(struct vfio_device_file *df,
|
|||
if (copy_from_user(&attach, arg, minsz))
|
||||
return -EFAULT;
|
||||
|
||||
if (attach.argsz < minsz || attach.flags)
|
||||
if (attach.argsz < minsz)
|
||||
return -EINVAL;
|
||||
|
||||
if (attach.flags & ~VFIO_DEVICE_ATTACH_PASID)
|
||||
return -EINVAL;
|
||||
|
||||
if (attach.flags & VFIO_DEVICE_ATTACH_PASID) {
|
||||
if (!device->ops->pasid_attach_ioas)
|
||||
return -EOPNOTSUPP;
|
||||
xend = offsetofend(struct vfio_device_attach_iommufd_pt, pasid);
|
||||
}
|
||||
|
||||
if (xend) {
|
||||
if (attach.argsz < xend)
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_from_user((void *)&attach + minsz,
|
||||
(void __user *)arg + minsz, xend - minsz))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
mutex_lock(&device->dev_set->lock);
|
||||
ret = device->ops->attach_ioas(device, &attach.pt_id);
|
||||
if (attach.flags & VFIO_DEVICE_ATTACH_PASID)
|
||||
ret = device->ops->pasid_attach_ioas(device,
|
||||
attach.pasid,
|
||||
&attach.pt_id);
|
||||
else
|
||||
ret = device->ops->attach_ioas(device, &attach.pt_id);
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
|
||||
|
|
@ -198,20 +221,41 @@ out_unlock:
|
|||
int vfio_df_ioctl_detach_pt(struct vfio_device_file *df,
|
||||
struct vfio_device_detach_iommufd_pt __user *arg)
|
||||
{
|
||||
struct vfio_device *device = df->device;
|
||||
struct vfio_device_detach_iommufd_pt detach;
|
||||
unsigned long minsz;
|
||||
struct vfio_device *device = df->device;
|
||||
unsigned long minsz, xend = 0;
|
||||
|
||||
minsz = offsetofend(struct vfio_device_detach_iommufd_pt, flags);
|
||||
|
||||
if (copy_from_user(&detach, arg, minsz))
|
||||
return -EFAULT;
|
||||
|
||||
if (detach.argsz < minsz || detach.flags)
|
||||
if (detach.argsz < minsz)
|
||||
return -EINVAL;
|
||||
|
||||
if (detach.flags & ~VFIO_DEVICE_DETACH_PASID)
|
||||
return -EINVAL;
|
||||
|
||||
if (detach.flags & VFIO_DEVICE_DETACH_PASID) {
|
||||
if (!device->ops->pasid_detach_ioas)
|
||||
return -EOPNOTSUPP;
|
||||
xend = offsetofend(struct vfio_device_detach_iommufd_pt, pasid);
|
||||
}
|
||||
|
||||
if (xend) {
|
||||
if (detach.argsz < xend)
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_from_user((void *)&detach + minsz,
|
||||
(void __user *)arg + minsz, xend - minsz))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
mutex_lock(&device->dev_set->lock);
|
||||
device->ops->detach_ioas(device);
|
||||
if (detach.flags & VFIO_DEVICE_DETACH_PASID)
|
||||
device->ops->pasid_detach_ioas(device, detach.pasid);
|
||||
else
|
||||
device->ops->detach_ioas(device);
|
||||
mutex_unlock(&device->dev_set->lock);
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -931,29 +931,34 @@ struct vfio_device_bind_iommufd {
|
|||
* VFIO_DEVICE_ATTACH_IOMMUFD_PT - _IOW(VFIO_TYPE, VFIO_BASE + 19,
|
||||
* struct vfio_device_attach_iommufd_pt)
|
||||
* @argsz: User filled size of this data.
|
||||
* @flags: Must be 0.
|
||||
* @flags: Flags for attach.
|
||||
* @pt_id: Input the target id which can represent an ioas or a hwpt
|
||||
* allocated via iommufd subsystem.
|
||||
* Output the input ioas id or the attached hwpt id which could
|
||||
* be the specified hwpt itself or a hwpt automatically created
|
||||
* for the specified ioas by kernel during the attachment.
|
||||
* @pasid: The pasid to be attached, only meaningful when
|
||||
* VFIO_DEVICE_ATTACH_PASID is set in @flags
|
||||
*
|
||||
* Associate the device with an address space within the bound iommufd.
|
||||
* Undo by VFIO_DEVICE_DETACH_IOMMUFD_PT or device fd close. This is only
|
||||
* allowed on cdev fds.
|
||||
*
|
||||
* If a vfio device is currently attached to a valid hw_pagetable, without doing
|
||||
* a VFIO_DEVICE_DETACH_IOMMUFD_PT, a second VFIO_DEVICE_ATTACH_IOMMUFD_PT ioctl
|
||||
* passing in another hw_pagetable (hwpt) id is allowed. This action, also known
|
||||
* as a hw_pagetable replacement, will replace the device's currently attached
|
||||
* hw_pagetable with a new hw_pagetable corresponding to the given pt_id.
|
||||
* If a vfio device or a pasid of this device is currently attached to a valid
|
||||
* hw_pagetable (hwpt), without doing a VFIO_DEVICE_DETACH_IOMMUFD_PT, a second
|
||||
* VFIO_DEVICE_ATTACH_IOMMUFD_PT ioctl passing in another hwpt id is allowed.
|
||||
* This action, also known as a hw_pagetable replacement, will replace the
|
||||
* currently attached hwpt of the device or the pasid of this device with a new
|
||||
* hwpt corresponding to the given pt_id.
|
||||
*
|
||||
* Return: 0 on success, -errno on failure.
|
||||
*/
|
||||
struct vfio_device_attach_iommufd_pt {
|
||||
__u32 argsz;
|
||||
__u32 flags;
|
||||
#define VFIO_DEVICE_ATTACH_PASID (1 << 0)
|
||||
__u32 pt_id;
|
||||
__u32 pasid;
|
||||
};
|
||||
|
||||
#define VFIO_DEVICE_ATTACH_IOMMUFD_PT _IO(VFIO_TYPE, VFIO_BASE + 19)
|
||||
|
|
@ -962,17 +967,21 @@ struct vfio_device_attach_iommufd_pt {
|
|||
* VFIO_DEVICE_DETACH_IOMMUFD_PT - _IOW(VFIO_TYPE, VFIO_BASE + 20,
|
||||
* struct vfio_device_detach_iommufd_pt)
|
||||
* @argsz: User filled size of this data.
|
||||
* @flags: Must be 0.
|
||||
* @flags: Flags for detach.
|
||||
* @pasid: The pasid to be detached, only meaningful when
|
||||
* VFIO_DEVICE_DETACH_PASID is set in @flags
|
||||
*
|
||||
* Remove the association of the device and its current associated address
|
||||
* space. After it, the device should be in a blocking DMA state. This is only
|
||||
* allowed on cdev fds.
|
||||
* Remove the association of the device or a pasid of the device and its current
|
||||
* associated address space. After it, the device or the pasid should be in a
|
||||
* blocking DMA state. This is only allowed on cdev fds.
|
||||
*
|
||||
* Return: 0 on success, -errno on failure.
|
||||
*/
|
||||
struct vfio_device_detach_iommufd_pt {
|
||||
__u32 argsz;
|
||||
__u32 flags;
|
||||
#define VFIO_DEVICE_DETACH_PASID (1 << 0)
|
||||
__u32 pasid;
|
||||
};
|
||||
|
||||
#define VFIO_DEVICE_DETACH_IOMMUFD_PT _IO(VFIO_TYPE, VFIO_BASE + 20)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue