Skip to content

Commit ad744ed

Browse files
yiliu1765jgunthorpe
authored andcommitted
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/[email protected] Reviewed-by: Alex Williamson <[email protected]> Reviewed-by: Kevin Tian <[email protected]> Reviewed-by: Nicolin Chen <[email protected]> Tested-by: Nicolin Chen <[email protected]> Signed-off-by: Yi Liu <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent 2906413 commit ad744ed

File tree

2 files changed

+71
-18
lines changed

2 files changed

+71
-18
lines changed

drivers/vfio/device_cdev.c

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -162,21 +162,44 @@ void vfio_df_unbind_iommufd(struct vfio_device_file *df)
162162
int vfio_df_ioctl_attach_pt(struct vfio_device_file *df,
163163
struct vfio_device_attach_iommufd_pt __user *arg)
164164
{
165-
struct vfio_device *device = df->device;
166165
struct vfio_device_attach_iommufd_pt attach;
167-
unsigned long minsz;
166+
struct vfio_device *device = df->device;
167+
unsigned long minsz, xend = 0;
168168
int ret;
169169

170170
minsz = offsetofend(struct vfio_device_attach_iommufd_pt, pt_id);
171171

172172
if (copy_from_user(&attach, arg, minsz))
173173
return -EFAULT;
174174

175-
if (attach.argsz < minsz || attach.flags)
175+
if (attach.argsz < minsz)
176176
return -EINVAL;
177177

178+
if (attach.flags & ~VFIO_DEVICE_ATTACH_PASID)
179+
return -EINVAL;
180+
181+
if (attach.flags & VFIO_DEVICE_ATTACH_PASID) {
182+
if (!device->ops->pasid_attach_ioas)
183+
return -EOPNOTSUPP;
184+
xend = offsetofend(struct vfio_device_attach_iommufd_pt, pasid);
185+
}
186+
187+
if (xend) {
188+
if (attach.argsz < xend)
189+
return -EINVAL;
190+
191+
if (copy_from_user((void *)&attach + minsz,
192+
(void __user *)arg + minsz, xend - minsz))
193+
return -EFAULT;
194+
}
195+
178196
mutex_lock(&device->dev_set->lock);
179-
ret = device->ops->attach_ioas(device, &attach.pt_id);
197+
if (attach.flags & VFIO_DEVICE_ATTACH_PASID)
198+
ret = device->ops->pasid_attach_ioas(device,
199+
attach.pasid,
200+
&attach.pt_id);
201+
else
202+
ret = device->ops->attach_ioas(device, &attach.pt_id);
180203
if (ret)
181204
goto out_unlock;
182205

@@ -198,20 +221,41 @@ int vfio_df_ioctl_attach_pt(struct vfio_device_file *df,
198221
int vfio_df_ioctl_detach_pt(struct vfio_device_file *df,
199222
struct vfio_device_detach_iommufd_pt __user *arg)
200223
{
201-
struct vfio_device *device = df->device;
202224
struct vfio_device_detach_iommufd_pt detach;
203-
unsigned long minsz;
225+
struct vfio_device *device = df->device;
226+
unsigned long minsz, xend = 0;
204227

205228
minsz = offsetofend(struct vfio_device_detach_iommufd_pt, flags);
206229

207230
if (copy_from_user(&detach, arg, minsz))
208231
return -EFAULT;
209232

210-
if (detach.argsz < minsz || detach.flags)
233+
if (detach.argsz < minsz)
211234
return -EINVAL;
212235

236+
if (detach.flags & ~VFIO_DEVICE_DETACH_PASID)
237+
return -EINVAL;
238+
239+
if (detach.flags & VFIO_DEVICE_DETACH_PASID) {
240+
if (!device->ops->pasid_detach_ioas)
241+
return -EOPNOTSUPP;
242+
xend = offsetofend(struct vfio_device_detach_iommufd_pt, pasid);
243+
}
244+
245+
if (xend) {
246+
if (detach.argsz < xend)
247+
return -EINVAL;
248+
249+
if (copy_from_user((void *)&detach + minsz,
250+
(void __user *)arg + minsz, xend - minsz))
251+
return -EFAULT;
252+
}
253+
213254
mutex_lock(&device->dev_set->lock);
214-
device->ops->detach_ioas(device);
255+
if (detach.flags & VFIO_DEVICE_DETACH_PASID)
256+
device->ops->pasid_detach_ioas(device, detach.pasid);
257+
else
258+
device->ops->detach_ioas(device);
215259
mutex_unlock(&device->dev_set->lock);
216260

217261
return 0;

include/uapi/linux/vfio.h

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -931,29 +931,34 @@ struct vfio_device_bind_iommufd {
931931
* VFIO_DEVICE_ATTACH_IOMMUFD_PT - _IOW(VFIO_TYPE, VFIO_BASE + 19,
932932
* struct vfio_device_attach_iommufd_pt)
933933
* @argsz: User filled size of this data.
934-
* @flags: Must be 0.
934+
* @flags: Flags for attach.
935935
* @pt_id: Input the target id which can represent an ioas or a hwpt
936936
* allocated via iommufd subsystem.
937937
* Output the input ioas id or the attached hwpt id which could
938938
* be the specified hwpt itself or a hwpt automatically created
939939
* for the specified ioas by kernel during the attachment.
940+
* @pasid: The pasid to be attached, only meaningful when
941+
* VFIO_DEVICE_ATTACH_PASID is set in @flags
940942
*
941943
* Associate the device with an address space within the bound iommufd.
942944
* Undo by VFIO_DEVICE_DETACH_IOMMUFD_PT or device fd close. This is only
943945
* allowed on cdev fds.
944946
*
945-
* If a vfio device is currently attached to a valid hw_pagetable, without doing
946-
* a VFIO_DEVICE_DETACH_IOMMUFD_PT, a second VFIO_DEVICE_ATTACH_IOMMUFD_PT ioctl
947-
* passing in another hw_pagetable (hwpt) id is allowed. This action, also known
948-
* as a hw_pagetable replacement, will replace the device's currently attached
949-
* hw_pagetable with a new hw_pagetable corresponding to the given pt_id.
947+
* If a vfio device or a pasid of this device is currently attached to a valid
948+
* hw_pagetable (hwpt), without doing a VFIO_DEVICE_DETACH_IOMMUFD_PT, a second
949+
* VFIO_DEVICE_ATTACH_IOMMUFD_PT ioctl passing in another hwpt id is allowed.
950+
* This action, also known as a hw_pagetable replacement, will replace the
951+
* currently attached hwpt of the device or the pasid of this device with a new
952+
* hwpt corresponding to the given pt_id.
950953
*
951954
* Return: 0 on success, -errno on failure.
952955
*/
953956
struct vfio_device_attach_iommufd_pt {
954957
__u32 argsz;
955958
__u32 flags;
959+
#define VFIO_DEVICE_ATTACH_PASID (1 << 0)
956960
__u32 pt_id;
961+
__u32 pasid;
957962
};
958963

959964
#define VFIO_DEVICE_ATTACH_IOMMUFD_PT _IO(VFIO_TYPE, VFIO_BASE + 19)
@@ -962,17 +967,21 @@ struct vfio_device_attach_iommufd_pt {
962967
* VFIO_DEVICE_DETACH_IOMMUFD_PT - _IOW(VFIO_TYPE, VFIO_BASE + 20,
963968
* struct vfio_device_detach_iommufd_pt)
964969
* @argsz: User filled size of this data.
965-
* @flags: Must be 0.
970+
* @flags: Flags for detach.
971+
* @pasid: The pasid to be detached, only meaningful when
972+
* VFIO_DEVICE_DETACH_PASID is set in @flags
966973
*
967-
* Remove the association of the device and its current associated address
968-
* space. After it, the device should be in a blocking DMA state. This is only
969-
* allowed on cdev fds.
974+
* Remove the association of the device or a pasid of the device and its current
975+
* associated address space. After it, the device or the pasid should be in a
976+
* blocking DMA state. This is only allowed on cdev fds.
970977
*
971978
* Return: 0 on success, -errno on failure.
972979
*/
973980
struct vfio_device_detach_iommufd_pt {
974981
__u32 argsz;
975982
__u32 flags;
983+
#define VFIO_DEVICE_DETACH_PASID (1 << 0)
984+
__u32 pasid;
976985
};
977986

978987
#define VFIO_DEVICE_DETACH_IOMMUFD_PT _IO(VFIO_TYPE, VFIO_BASE + 20)

0 commit comments

Comments
 (0)