Skip to content

Commit 90ffd11

Browse files
committed
vfio: VFIO_DEVICE_[AT|DE]TACH_IOMMUFD_PT support pasid
commit ad744ed Author: Yi Liu <yi.l.liu@intel.com> Date: Fri Mar 21 11:01:41 2025 -0700 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> (cherry picked from commit ad744ed) Signed-off-by: Jerry Snitselaar <jsnitsel@redhat.com> Upstream-Status: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git JIRA: https://issues.redhat.com/browse/RHEL-73603
1 parent 2c55f9e commit 90ffd11

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
@@ -932,29 +932,34 @@ struct vfio_device_bind_iommufd {
932932
* VFIO_DEVICE_ATTACH_IOMMUFD_PT - _IOW(VFIO_TYPE, VFIO_BASE + 19,
933933
* struct vfio_device_attach_iommufd_pt)
934934
* @argsz: User filled size of this data.
935-
* @flags: Must be 0.
935+
* @flags: Flags for attach.
936936
* @pt_id: Input the target id which can represent an ioas or a hwpt
937937
* allocated via iommufd subsystem.
938938
* Output the input ioas id or the attached hwpt id which could
939939
* be the specified hwpt itself or a hwpt automatically created
940940
* for the specified ioas by kernel during the attachment.
941+
* @pasid: The pasid to be attached, only meaningful when
942+
* VFIO_DEVICE_ATTACH_PASID is set in @flags
941943
*
942944
* Associate the device with an address space within the bound iommufd.
943945
* Undo by VFIO_DEVICE_DETACH_IOMMUFD_PT or device fd close. This is only
944946
* allowed on cdev fds.
945947
*
946-
* If a vfio device is currently attached to a valid hw_pagetable, without doing
947-
* a VFIO_DEVICE_DETACH_IOMMUFD_PT, a second VFIO_DEVICE_ATTACH_IOMMUFD_PT ioctl
948-
* passing in another hw_pagetable (hwpt) id is allowed. This action, also known
949-
* as a hw_pagetable replacement, will replace the device's currently attached
950-
* hw_pagetable with a new hw_pagetable corresponding to the given pt_id.
948+
* If a vfio device or a pasid of this device is currently attached to a valid
949+
* hw_pagetable (hwpt), without doing a VFIO_DEVICE_DETACH_IOMMUFD_PT, a second
950+
* VFIO_DEVICE_ATTACH_IOMMUFD_PT ioctl passing in another hwpt id is allowed.
951+
* This action, also known as a hw_pagetable replacement, will replace the
952+
* currently attached hwpt of the device or the pasid of this device with a new
953+
* hwpt corresponding to the given pt_id.
951954
*
952955
* Return: 0 on success, -errno on failure.
953956
*/
954957
struct vfio_device_attach_iommufd_pt {
955958
__u32 argsz;
956959
__u32 flags;
960+
#define VFIO_DEVICE_ATTACH_PASID (1 << 0)
957961
__u32 pt_id;
962+
__u32 pasid;
958963
};
959964

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

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

0 commit comments

Comments
 (0)