mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-09-22 12:44:11 +08:00
vfio-iommufd: Add detach_ioas support for physical VFIO devices
This prepares for adding DETACH ioctl for physical VFIO devices. Reviewed-by: Kevin Tian <kevin.tian@intel.com> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> Tested-by: Terrence Xu <terrence.xu@intel.com> Tested-by: Nicolin Chen <nicolinc@nvidia.com> Tested-by: Matthew Rosato <mjrosato@linux.ibm.com> Tested-by: Yanting Jiang <yanting.jiang@intel.com> Tested-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com> Tested-by: Zhenzhong Duan <zhenzhong.duan@intel.com> Signed-off-by: Yi Liu <yi.l.liu@intel.com> Link: https://lore.kernel.org/r/20230718135551.6592-14-yi.l.liu@intel.com Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
This commit is contained in:
parent
31014aef9e
commit
9048c7341c
@ -279,6 +279,7 @@ similar to a file operations structure::
|
||||
struct iommufd_ctx *ictx, u32 *out_device_id);
|
||||
void (*unbind_iommufd)(struct vfio_device *vdev);
|
||||
int (*attach_ioas)(struct vfio_device *vdev, u32 *pt_id);
|
||||
void (*detach_ioas)(struct vfio_device *vdev);
|
||||
int (*open_device)(struct vfio_device *vdev);
|
||||
void (*close_device)(struct vfio_device *vdev);
|
||||
ssize_t (*read)(struct vfio_device *vdev, char __user *buf,
|
||||
@ -315,9 +316,10 @@ container_of().
|
||||
- The [un]bind_iommufd callbacks are issued when the device is bound to
|
||||
and unbound from iommufd.
|
||||
|
||||
- The attach_ioas callback is issued when the device is attached to an
|
||||
IOAS managed by the bound iommufd. The attached IOAS is automatically
|
||||
detached when the device is unbound from iommufd.
|
||||
- The [de]attach_ioas callback is issued when the device is attached to
|
||||
and detached from an IOAS managed by the bound iommufd. However, the
|
||||
attached IOAS can also be automatically detached when the device is
|
||||
unbound from iommufd.
|
||||
|
||||
- The read/write/mmap callbacks implement the device region access defined
|
||||
by the device's own VFIO_DEVICE_GET_REGION_INFO ioctl.
|
||||
|
@ -593,6 +593,7 @@ static const struct vfio_device_ops vfio_fsl_mc_ops = {
|
||||
.bind_iommufd = vfio_iommufd_physical_bind,
|
||||
.unbind_iommufd = vfio_iommufd_physical_unbind,
|
||||
.attach_ioas = vfio_iommufd_physical_attach_ioas,
|
||||
.detach_ioas = vfio_iommufd_physical_detach_ioas,
|
||||
};
|
||||
|
||||
static struct fsl_mc_driver vfio_fsl_mc_driver = {
|
||||
|
@ -140,6 +140,14 @@ int vfio_iommufd_physical_attach_ioas(struct vfio_device *vdev, u32 *pt_id)
|
||||
{
|
||||
int rc;
|
||||
|
||||
lockdep_assert_held(&vdev->dev_set->lock);
|
||||
|
||||
if (WARN_ON(!vdev->iommufd_device))
|
||||
return -EINVAL;
|
||||
|
||||
if (vdev->iommufd_attached)
|
||||
return -EBUSY;
|
||||
|
||||
rc = iommufd_device_attach(vdev->iommufd_device, pt_id);
|
||||
if (rc)
|
||||
return rc;
|
||||
@ -148,6 +156,18 @@ int vfio_iommufd_physical_attach_ioas(struct vfio_device *vdev, u32 *pt_id)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vfio_iommufd_physical_attach_ioas);
|
||||
|
||||
void vfio_iommufd_physical_detach_ioas(struct vfio_device *vdev)
|
||||
{
|
||||
lockdep_assert_held(&vdev->dev_set->lock);
|
||||
|
||||
if (WARN_ON(!vdev->iommufd_device) || !vdev->iommufd_attached)
|
||||
return;
|
||||
|
||||
iommufd_device_detach(vdev->iommufd_device);
|
||||
vdev->iommufd_attached = false;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vfio_iommufd_physical_detach_ioas);
|
||||
|
||||
/*
|
||||
* The emulated standard ops mean that vfio_device is going to use the
|
||||
* "mdev path" and will call vfio_pin_pages()/vfio_dma_rw(). Drivers using this
|
||||
|
@ -1373,6 +1373,7 @@ static const struct vfio_device_ops hisi_acc_vfio_pci_migrn_ops = {
|
||||
.bind_iommufd = vfio_iommufd_physical_bind,
|
||||
.unbind_iommufd = vfio_iommufd_physical_unbind,
|
||||
.attach_ioas = vfio_iommufd_physical_attach_ioas,
|
||||
.detach_ioas = vfio_iommufd_physical_detach_ioas,
|
||||
};
|
||||
|
||||
static const struct vfio_device_ops hisi_acc_vfio_pci_ops = {
|
||||
@ -1391,6 +1392,7 @@ static const struct vfio_device_ops hisi_acc_vfio_pci_ops = {
|
||||
.bind_iommufd = vfio_iommufd_physical_bind,
|
||||
.unbind_iommufd = vfio_iommufd_physical_unbind,
|
||||
.attach_ioas = vfio_iommufd_physical_attach_ioas,
|
||||
.detach_ioas = vfio_iommufd_physical_detach_ioas,
|
||||
};
|
||||
|
||||
static int hisi_acc_vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
|
@ -1320,6 +1320,7 @@ static const struct vfio_device_ops mlx5vf_pci_ops = {
|
||||
.bind_iommufd = vfio_iommufd_physical_bind,
|
||||
.unbind_iommufd = vfio_iommufd_physical_unbind,
|
||||
.attach_ioas = vfio_iommufd_physical_attach_ioas,
|
||||
.detach_ioas = vfio_iommufd_physical_detach_ioas,
|
||||
};
|
||||
|
||||
static int mlx5vf_pci_probe(struct pci_dev *pdev,
|
||||
|
@ -141,6 +141,7 @@ static const struct vfio_device_ops vfio_pci_ops = {
|
||||
.bind_iommufd = vfio_iommufd_physical_bind,
|
||||
.unbind_iommufd = vfio_iommufd_physical_unbind,
|
||||
.attach_ioas = vfio_iommufd_physical_attach_ioas,
|
||||
.detach_ioas = vfio_iommufd_physical_detach_ioas,
|
||||
};
|
||||
|
||||
static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
|
@ -119,6 +119,7 @@ static const struct vfio_device_ops vfio_amba_ops = {
|
||||
.bind_iommufd = vfio_iommufd_physical_bind,
|
||||
.unbind_iommufd = vfio_iommufd_physical_unbind,
|
||||
.attach_ioas = vfio_iommufd_physical_attach_ioas,
|
||||
.detach_ioas = vfio_iommufd_physical_detach_ioas,
|
||||
};
|
||||
|
||||
static const struct amba_id pl330_ids[] = {
|
||||
|
@ -108,6 +108,7 @@ static const struct vfio_device_ops vfio_platform_ops = {
|
||||
.bind_iommufd = vfio_iommufd_physical_bind,
|
||||
.unbind_iommufd = vfio_iommufd_physical_unbind,
|
||||
.attach_ioas = vfio_iommufd_physical_attach_ioas,
|
||||
.detach_ioas = vfio_iommufd_physical_detach_ioas,
|
||||
};
|
||||
|
||||
static struct platform_driver vfio_platform_driver = {
|
||||
|
@ -273,7 +273,8 @@ static int __vfio_register_dev(struct vfio_device *device,
|
||||
if (WARN_ON(IS_ENABLED(CONFIG_IOMMUFD) &&
|
||||
(!device->ops->bind_iommufd ||
|
||||
!device->ops->unbind_iommufd ||
|
||||
!device->ops->attach_ioas)))
|
||||
!device->ops->attach_ioas ||
|
||||
!device->ops->detach_ioas)))
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
|
@ -73,7 +73,9 @@ struct vfio_device {
|
||||
* @bind_iommufd: Called when binding the device to an iommufd
|
||||
* @unbind_iommufd: Opposite of bind_iommufd
|
||||
* @attach_ioas: Called when attaching device to an IOAS/HWPT managed by the
|
||||
* bound iommufd. Undo in unbind_iommufd.
|
||||
* bound iommufd. Undo in unbind_iommufd if @detach_ioas is not
|
||||
* called.
|
||||
* @detach_ioas: Opposite of attach_ioas
|
||||
* @open_device: Called when the first file descriptor is opened for this device
|
||||
* @close_device: Opposite of open_device
|
||||
* @read: Perform read(2) on device file descriptor
|
||||
@ -97,6 +99,7 @@ struct vfio_device_ops {
|
||||
struct iommufd_ctx *ictx, u32 *out_device_id);
|
||||
void (*unbind_iommufd)(struct vfio_device *vdev);
|
||||
int (*attach_ioas)(struct vfio_device *vdev, u32 *pt_id);
|
||||
void (*detach_ioas)(struct vfio_device *vdev);
|
||||
int (*open_device)(struct vfio_device *vdev);
|
||||
void (*close_device)(struct vfio_device *vdev);
|
||||
ssize_t (*read)(struct vfio_device *vdev, char __user *buf,
|
||||
@ -120,6 +123,7 @@ int vfio_iommufd_physical_bind(struct vfio_device *vdev,
|
||||
struct iommufd_ctx *ictx, u32 *out_device_id);
|
||||
void vfio_iommufd_physical_unbind(struct vfio_device *vdev);
|
||||
int vfio_iommufd_physical_attach_ioas(struct vfio_device *vdev, u32 *pt_id);
|
||||
void vfio_iommufd_physical_detach_ioas(struct vfio_device *vdev);
|
||||
int vfio_iommufd_emulated_bind(struct vfio_device *vdev,
|
||||
struct iommufd_ctx *ictx, u32 *out_device_id);
|
||||
void vfio_iommufd_emulated_unbind(struct vfio_device *vdev);
|
||||
@ -144,6 +148,8 @@ vfio_iommufd_get_dev_id(struct vfio_device *vdev, struct iommufd_ctx *ictx)
|
||||
((void (*)(struct vfio_device *vdev)) NULL)
|
||||
#define vfio_iommufd_physical_attach_ioas \
|
||||
((int (*)(struct vfio_device *vdev, u32 *pt_id)) NULL)
|
||||
#define vfio_iommufd_physical_detach_ioas \
|
||||
((void (*)(struct vfio_device *vdev)) NULL)
|
||||
#define vfio_iommufd_emulated_bind \
|
||||
((int (*)(struct vfio_device *vdev, struct iommufd_ctx *ictx, \
|
||||
u32 *out_device_id)) NULL)
|
||||
|
Loading…
Reference in New Issue
Block a user