mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-18 22:14:16 +00: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
10 changed files with 41 additions and 5 deletions
|
@ -279,6 +279,7 @@ similar to a file operations structure::
|
||||||
struct iommufd_ctx *ictx, u32 *out_device_id);
|
struct iommufd_ctx *ictx, u32 *out_device_id);
|
||||||
void (*unbind_iommufd)(struct vfio_device *vdev);
|
void (*unbind_iommufd)(struct vfio_device *vdev);
|
||||||
int (*attach_ioas)(struct vfio_device *vdev, u32 *pt_id);
|
int (*attach_ioas)(struct vfio_device *vdev, u32 *pt_id);
|
||||||
|
void (*detach_ioas)(struct vfio_device *vdev);
|
||||||
int (*open_device)(struct vfio_device *vdev);
|
int (*open_device)(struct vfio_device *vdev);
|
||||||
void (*close_device)(struct vfio_device *vdev);
|
void (*close_device)(struct vfio_device *vdev);
|
||||||
ssize_t (*read)(struct vfio_device *vdev, char __user *buf,
|
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
|
- The [un]bind_iommufd callbacks are issued when the device is bound to
|
||||||
and unbound from iommufd.
|
and unbound from iommufd.
|
||||||
|
|
||||||
- The attach_ioas callback is issued when the device is attached to an
|
- The [de]attach_ioas callback is issued when the device is attached to
|
||||||
IOAS managed by the bound iommufd. The attached IOAS is automatically
|
and detached from an IOAS managed by the bound iommufd. However, the
|
||||||
detached when the device is unbound from iommufd.
|
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
|
- The read/write/mmap callbacks implement the device region access defined
|
||||||
by the device's own VFIO_DEVICE_GET_REGION_INFO ioctl.
|
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,
|
.bind_iommufd = vfio_iommufd_physical_bind,
|
||||||
.unbind_iommufd = vfio_iommufd_physical_unbind,
|
.unbind_iommufd = vfio_iommufd_physical_unbind,
|
||||||
.attach_ioas = vfio_iommufd_physical_attach_ioas,
|
.attach_ioas = vfio_iommufd_physical_attach_ioas,
|
||||||
|
.detach_ioas = vfio_iommufd_physical_detach_ioas,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct fsl_mc_driver vfio_fsl_mc_driver = {
|
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;
|
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);
|
rc = iommufd_device_attach(vdev->iommufd_device, pt_id);
|
||||||
if (rc)
|
if (rc)
|
||||||
return 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);
|
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
|
* 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
|
* "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,
|
.bind_iommufd = vfio_iommufd_physical_bind,
|
||||||
.unbind_iommufd = vfio_iommufd_physical_unbind,
|
.unbind_iommufd = vfio_iommufd_physical_unbind,
|
||||||
.attach_ioas = vfio_iommufd_physical_attach_ioas,
|
.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 = {
|
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,
|
.bind_iommufd = vfio_iommufd_physical_bind,
|
||||||
.unbind_iommufd = vfio_iommufd_physical_unbind,
|
.unbind_iommufd = vfio_iommufd_physical_unbind,
|
||||||
.attach_ioas = vfio_iommufd_physical_attach_ioas,
|
.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)
|
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,
|
.bind_iommufd = vfio_iommufd_physical_bind,
|
||||||
.unbind_iommufd = vfio_iommufd_physical_unbind,
|
.unbind_iommufd = vfio_iommufd_physical_unbind,
|
||||||
.attach_ioas = vfio_iommufd_physical_attach_ioas,
|
.attach_ioas = vfio_iommufd_physical_attach_ioas,
|
||||||
|
.detach_ioas = vfio_iommufd_physical_detach_ioas,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int mlx5vf_pci_probe(struct pci_dev *pdev,
|
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,
|
.bind_iommufd = vfio_iommufd_physical_bind,
|
||||||
.unbind_iommufd = vfio_iommufd_physical_unbind,
|
.unbind_iommufd = vfio_iommufd_physical_unbind,
|
||||||
.attach_ioas = vfio_iommufd_physical_attach_ioas,
|
.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)
|
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,
|
.bind_iommufd = vfio_iommufd_physical_bind,
|
||||||
.unbind_iommufd = vfio_iommufd_physical_unbind,
|
.unbind_iommufd = vfio_iommufd_physical_unbind,
|
||||||
.attach_ioas = vfio_iommufd_physical_attach_ioas,
|
.attach_ioas = vfio_iommufd_physical_attach_ioas,
|
||||||
|
.detach_ioas = vfio_iommufd_physical_detach_ioas,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct amba_id pl330_ids[] = {
|
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,
|
.bind_iommufd = vfio_iommufd_physical_bind,
|
||||||
.unbind_iommufd = vfio_iommufd_physical_unbind,
|
.unbind_iommufd = vfio_iommufd_physical_unbind,
|
||||||
.attach_ioas = vfio_iommufd_physical_attach_ioas,
|
.attach_ioas = vfio_iommufd_physical_attach_ioas,
|
||||||
|
.detach_ioas = vfio_iommufd_physical_detach_ioas,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct platform_driver vfio_platform_driver = {
|
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) &&
|
if (WARN_ON(IS_ENABLED(CONFIG_IOMMUFD) &&
|
||||||
(!device->ops->bind_iommufd ||
|
(!device->ops->bind_iommufd ||
|
||||||
!device->ops->unbind_iommufd ||
|
!device->ops->unbind_iommufd ||
|
||||||
!device->ops->attach_ioas)))
|
!device->ops->attach_ioas ||
|
||||||
|
!device->ops->detach_ioas)))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -73,7 +73,9 @@ struct vfio_device {
|
||||||
* @bind_iommufd: Called when binding the device to an iommufd
|
* @bind_iommufd: Called when binding the device to an iommufd
|
||||||
* @unbind_iommufd: Opposite of bind_iommufd
|
* @unbind_iommufd: Opposite of bind_iommufd
|
||||||
* @attach_ioas: Called when attaching device to an IOAS/HWPT managed by the
|
* @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
|
* @open_device: Called when the first file descriptor is opened for this device
|
||||||
* @close_device: Opposite of open_device
|
* @close_device: Opposite of open_device
|
||||||
* @read: Perform read(2) on device file descriptor
|
* @read: Perform read(2) on device file descriptor
|
||||||
|
@ -97,6 +99,7 @@ struct vfio_device_ops {
|
||||||
struct iommufd_ctx *ictx, u32 *out_device_id);
|
struct iommufd_ctx *ictx, u32 *out_device_id);
|
||||||
void (*unbind_iommufd)(struct vfio_device *vdev);
|
void (*unbind_iommufd)(struct vfio_device *vdev);
|
||||||
int (*attach_ioas)(struct vfio_device *vdev, u32 *pt_id);
|
int (*attach_ioas)(struct vfio_device *vdev, u32 *pt_id);
|
||||||
|
void (*detach_ioas)(struct vfio_device *vdev);
|
||||||
int (*open_device)(struct vfio_device *vdev);
|
int (*open_device)(struct vfio_device *vdev);
|
||||||
void (*close_device)(struct vfio_device *vdev);
|
void (*close_device)(struct vfio_device *vdev);
|
||||||
ssize_t (*read)(struct vfio_device *vdev, char __user *buf,
|
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);
|
struct iommufd_ctx *ictx, u32 *out_device_id);
|
||||||
void vfio_iommufd_physical_unbind(struct vfio_device *vdev);
|
void vfio_iommufd_physical_unbind(struct vfio_device *vdev);
|
||||||
int vfio_iommufd_physical_attach_ioas(struct vfio_device *vdev, u32 *pt_id);
|
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,
|
int vfio_iommufd_emulated_bind(struct vfio_device *vdev,
|
||||||
struct iommufd_ctx *ictx, u32 *out_device_id);
|
struct iommufd_ctx *ictx, u32 *out_device_id);
|
||||||
void vfio_iommufd_emulated_unbind(struct vfio_device *vdev);
|
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)
|
((void (*)(struct vfio_device *vdev)) NULL)
|
||||||
#define vfio_iommufd_physical_attach_ioas \
|
#define vfio_iommufd_physical_attach_ioas \
|
||||||
((int (*)(struct vfio_device *vdev, u32 *pt_id)) NULL)
|
((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 \
|
#define vfio_iommufd_emulated_bind \
|
||||||
((int (*)(struct vfio_device *vdev, struct iommufd_ctx *ictx, \
|
((int (*)(struct vfio_device *vdev, struct iommufd_ctx *ictx, \
|
||||||
u32 *out_device_id)) NULL)
|
u32 *out_device_id)) NULL)
|
||||||
|
|
Loading…
Add table
Reference in a new issue