Skip to content

Commit 2906413

Browse files
yiliu1765jgunthorpe
authored andcommitted
vfio-iommufd: Support pasid [at|de]tach for physical VFIO devices
This adds pasid_at|de]tach_ioas ops for attaching hwpt to pasid of a device and the helpers for it. For now, only vfio-pci supports pasid attach/detach. Link: https://patch.msgid.link/r/[email protected] Signed-off-by: Kevin Tian <[email protected]> Reviewed-by: Jason Gunthorpe <[email protected]> Reviewed-by: Alex Williamson <[email protected]> Tested-by: Nicolin Chen <[email protected]> Signed-off-by: Yi Liu <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent 7fe6b98 commit 2906413

File tree

3 files changed

+66
-0
lines changed

3 files changed

+66
-0
lines changed

drivers/vfio/iommufd.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,14 +119,22 @@ int vfio_iommufd_physical_bind(struct vfio_device *vdev,
119119
if (IS_ERR(idev))
120120
return PTR_ERR(idev);
121121
vdev->iommufd_device = idev;
122+
ida_init(&vdev->pasids);
122123
return 0;
123124
}
124125
EXPORT_SYMBOL_GPL(vfio_iommufd_physical_bind);
125126

126127
void vfio_iommufd_physical_unbind(struct vfio_device *vdev)
127128
{
129+
int pasid;
130+
128131
lockdep_assert_held(&vdev->dev_set->lock);
129132

133+
while ((pasid = ida_find_first(&vdev->pasids)) >= 0) {
134+
iommufd_device_detach(vdev->iommufd_device, pasid);
135+
ida_free(&vdev->pasids, pasid);
136+
}
137+
130138
if (vdev->iommufd_attached) {
131139
iommufd_device_detach(vdev->iommufd_device, IOMMU_NO_PASID);
132140
vdev->iommufd_attached = false;
@@ -170,6 +178,48 @@ void vfio_iommufd_physical_detach_ioas(struct vfio_device *vdev)
170178
}
171179
EXPORT_SYMBOL_GPL(vfio_iommufd_physical_detach_ioas);
172180

181+
int vfio_iommufd_physical_pasid_attach_ioas(struct vfio_device *vdev,
182+
u32 pasid, u32 *pt_id)
183+
{
184+
int rc;
185+
186+
lockdep_assert_held(&vdev->dev_set->lock);
187+
188+
if (WARN_ON(!vdev->iommufd_device))
189+
return -EINVAL;
190+
191+
if (ida_exists(&vdev->pasids, pasid))
192+
return iommufd_device_replace(vdev->iommufd_device,
193+
pasid, pt_id);
194+
195+
rc = ida_alloc_range(&vdev->pasids, pasid, pasid, GFP_KERNEL);
196+
if (rc < 0)
197+
return rc;
198+
199+
rc = iommufd_device_attach(vdev->iommufd_device, pasid, pt_id);
200+
if (rc)
201+
ida_free(&vdev->pasids, pasid);
202+
203+
return rc;
204+
}
205+
EXPORT_SYMBOL_GPL(vfio_iommufd_physical_pasid_attach_ioas);
206+
207+
void vfio_iommufd_physical_pasid_detach_ioas(struct vfio_device *vdev,
208+
u32 pasid)
209+
{
210+
lockdep_assert_held(&vdev->dev_set->lock);
211+
212+
if (WARN_ON(!vdev->iommufd_device))
213+
return;
214+
215+
if (!ida_exists(&vdev->pasids, pasid))
216+
return;
217+
218+
iommufd_device_detach(vdev->iommufd_device, pasid);
219+
ida_free(&vdev->pasids, pasid);
220+
}
221+
EXPORT_SYMBOL_GPL(vfio_iommufd_physical_pasid_detach_ioas);
222+
173223
/*
174224
* The emulated standard ops mean that vfio_device is going to use the
175225
* "mdev path" and will call vfio_pin_pages()/vfio_dma_rw(). Drivers using this

drivers/vfio/pci/vfio_pci.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ static const struct vfio_device_ops vfio_pci_ops = {
144144
.unbind_iommufd = vfio_iommufd_physical_unbind,
145145
.attach_ioas = vfio_iommufd_physical_attach_ioas,
146146
.detach_ioas = vfio_iommufd_physical_detach_ioas,
147+
.pasid_attach_ioas = vfio_iommufd_physical_pasid_attach_ioas,
148+
.pasid_detach_ioas = vfio_iommufd_physical_pasid_detach_ioas,
147149
};
148150

149151
static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)

include/linux/vfio.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ struct vfio_device {
6767
struct inode *inode;
6868
#if IS_ENABLED(CONFIG_IOMMUFD)
6969
struct iommufd_device *iommufd_device;
70+
struct ida pasids;
7071
u8 iommufd_attached:1;
7172
#endif
7273
u8 cdev_opened:1;
@@ -91,6 +92,8 @@ struct vfio_device {
9192
* bound iommufd. Undo in unbind_iommufd if @detach_ioas is not
9293
* called.
9394
* @detach_ioas: Opposite of attach_ioas
95+
* @pasid_attach_ioas: The pasid variation of attach_ioas
96+
* @pasid_detach_ioas: Opposite of pasid_attach_ioas
9497
* @open_device: Called when the first file descriptor is opened for this device
9598
* @close_device: Opposite of open_device
9699
* @read: Perform read(2) on device file descriptor
@@ -115,6 +118,9 @@ struct vfio_device_ops {
115118
void (*unbind_iommufd)(struct vfio_device *vdev);
116119
int (*attach_ioas)(struct vfio_device *vdev, u32 *pt_id);
117120
void (*detach_ioas)(struct vfio_device *vdev);
121+
int (*pasid_attach_ioas)(struct vfio_device *vdev, u32 pasid,
122+
u32 *pt_id);
123+
void (*pasid_detach_ioas)(struct vfio_device *vdev, u32 pasid);
118124
int (*open_device)(struct vfio_device *vdev);
119125
void (*close_device)(struct vfio_device *vdev);
120126
ssize_t (*read)(struct vfio_device *vdev, char __user *buf,
@@ -139,6 +145,10 @@ int vfio_iommufd_physical_bind(struct vfio_device *vdev,
139145
void vfio_iommufd_physical_unbind(struct vfio_device *vdev);
140146
int vfio_iommufd_physical_attach_ioas(struct vfio_device *vdev, u32 *pt_id);
141147
void vfio_iommufd_physical_detach_ioas(struct vfio_device *vdev);
148+
int vfio_iommufd_physical_pasid_attach_ioas(struct vfio_device *vdev,
149+
u32 pasid, u32 *pt_id);
150+
void vfio_iommufd_physical_pasid_detach_ioas(struct vfio_device *vdev,
151+
u32 pasid);
142152
int vfio_iommufd_emulated_bind(struct vfio_device *vdev,
143153
struct iommufd_ctx *ictx, u32 *out_device_id);
144154
void vfio_iommufd_emulated_unbind(struct vfio_device *vdev);
@@ -166,6 +176,10 @@ vfio_iommufd_get_dev_id(struct vfio_device *vdev, struct iommufd_ctx *ictx)
166176
((int (*)(struct vfio_device *vdev, u32 *pt_id)) NULL)
167177
#define vfio_iommufd_physical_detach_ioas \
168178
((void (*)(struct vfio_device *vdev)) NULL)
179+
#define vfio_iommufd_physical_pasid_attach_ioas \
180+
((int (*)(struct vfio_device *vdev, u32 pasid, u32 *pt_id)) NULL)
181+
#define vfio_iommufd_physical_pasid_detach_ioas \
182+
((void (*)(struct vfio_device *vdev, u32 pasid)) NULL)
169183
#define vfio_iommufd_emulated_bind \
170184
((int (*)(struct vfio_device *vdev, struct iommufd_ctx *ictx, \
171185
u32 *out_device_id)) NULL)

0 commit comments

Comments
 (0)