diff options
author | Diana Craciun <diana.craciun@oss.nxp.com> | 2020-10-05 20:36:51 +0300 |
---|---|---|
committer | Alex Williamson <alex.williamson@redhat.com> | 2020-10-12 11:33:06 -0600 |
commit | 2e0d29561f593a5ab6d37ea032513d2714a007df (patch) | |
tree | 6f34b42f1cee728161c0ffb61b795f0c2cfa7248 /drivers/vfio/fsl-mc/vfio_fsl_mc.c | |
parent | f2ba7e8c947bf38fec799fdf9122e05a6a3e8382 (diff) |
vfio/fsl-mc: Add irq infrastructure for fsl-mc devices
This patch adds the skeleton for interrupt support
for fsl-mc devices. The interrupts are not yet functional,
the functionality will be added by subsequent patches.
Signed-off-by: Bharat Bhushan <Bharat.Bhushan@nxp.com>
Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Diffstat (limited to 'drivers/vfio/fsl-mc/vfio_fsl_mc.c')
-rw-r--r-- | drivers/vfio/fsl-mc/vfio_fsl_mc.c | 52 |
1 files changed, 50 insertions, 2 deletions
diff --git a/drivers/vfio/fsl-mc/vfio_fsl_mc.c b/drivers/vfio/fsl-mc/vfio_fsl_mc.c index b52407c4e1ea..7803a9d6bfd9 100644 --- a/drivers/vfio/fsl-mc/vfio_fsl_mc.c +++ b/drivers/vfio/fsl-mc/vfio_fsl_mc.c @@ -217,11 +217,55 @@ static long vfio_fsl_mc_ioctl(void *device_data, unsigned int cmd, } case VFIO_DEVICE_GET_IRQ_INFO: { - return -ENOTTY; + struct vfio_irq_info info; + + minsz = offsetofend(struct vfio_irq_info, count); + if (copy_from_user(&info, (void __user *)arg, minsz)) + return -EFAULT; + + if (info.argsz < minsz) + return -EINVAL; + + if (info.index >= mc_dev->obj_desc.irq_count) + return -EINVAL; + + info.flags = VFIO_IRQ_INFO_EVENTFD; + info.count = 1; + + return copy_to_user((void __user *)arg, &info, minsz); } case VFIO_DEVICE_SET_IRQS: { - return -ENOTTY; + struct vfio_irq_set hdr; + u8 *data = NULL; + int ret = 0; + size_t data_size = 0; + + minsz = offsetofend(struct vfio_irq_set, count); + + if (copy_from_user(&hdr, (void __user *)arg, minsz)) + return -EFAULT; + + ret = vfio_set_irqs_validate_and_prepare(&hdr, mc_dev->obj_desc.irq_count, + mc_dev->obj_desc.irq_count, &data_size); + if (ret) + return ret; + + if (data_size) { + data = memdup_user((void __user *)(arg + minsz), + data_size); + if (IS_ERR(data)) + return PTR_ERR(data); + } + + mutex_lock(&vdev->igate); + ret = vfio_fsl_mc_set_irqs_ioctl(vdev, hdr.flags, + hdr.index, hdr.start, + hdr.count, data); + mutex_unlock(&vdev->igate); + kfree(data); + + return ret; } case VFIO_DEVICE_RESET: { @@ -423,6 +467,8 @@ static int vfio_fsl_mc_probe(struct fsl_mc_device *mc_dev) if (ret) goto out_reflck; + mutex_init(&vdev->igate); + return 0; out_reflck: @@ -443,6 +489,8 @@ static int vfio_fsl_mc_remove(struct fsl_mc_device *mc_dev) if (!vdev) return -EINVAL; + mutex_destroy(&vdev->igate); + vfio_fsl_mc_reflck_put(vdev->reflck); if (is_fsl_mc_bus_dprc(mc_dev)) { |