diff options
Diffstat (limited to 'drivers/vfio/platform/vfio_platform_common.c')
-rw-r--r-- | drivers/vfio/platform/vfio_platform_common.c | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/drivers/vfio/platform/vfio_platform_common.c b/drivers/vfio/platform/vfio_platform_common.c index d7fe2c71e8bc..908d5101e053 100644 --- a/drivers/vfio/platform/vfio_platform_common.c +++ b/drivers/vfio/platform/vfio_platform_common.c @@ -101,6 +101,7 @@ static void vfio_platform_release(void *device_data) if (!(--vdev->refcnt)) { vfio_platform_regions_cleanup(vdev); + vfio_platform_irq_cleanup(vdev); } mutex_unlock(&driver_lock); @@ -122,6 +123,10 @@ static int vfio_platform_open(void *device_data) ret = vfio_platform_regions_init(vdev); if (ret) goto err_reg; + + ret = vfio_platform_irq_init(vdev); + if (ret) + goto err_irq; } vdev->refcnt++; @@ -129,6 +134,8 @@ static int vfio_platform_open(void *device_data) mutex_unlock(&driver_lock); return 0; +err_irq: + vfio_platform_regions_cleanup(vdev); err_reg: mutex_unlock(&driver_lock); module_put(THIS_MODULE); @@ -154,7 +161,7 @@ static long vfio_platform_ioctl(void *device_data, info.flags = vdev->flags; info.num_regions = vdev->num_regions; - info.num_irqs = 0; + info.num_irqs = vdev->num_irqs; return copy_to_user((void __user *)arg, &info, minsz); @@ -179,10 +186,26 @@ static long vfio_platform_ioctl(void *device_data, return copy_to_user((void __user *)arg, &info, minsz); - } else if (cmd == VFIO_DEVICE_GET_IRQ_INFO) - return -EINVAL; + } else if (cmd == VFIO_DEVICE_GET_IRQ_INFO) { + 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 >= vdev->num_irqs) + return -EINVAL; + + info.flags = vdev->irqs[info.index].flags; + info.count = vdev->irqs[info.index].count; + + return copy_to_user((void __user *)arg, &info, minsz); - else if (cmd == VFIO_DEVICE_SET_IRQS) + } else if (cmd == VFIO_DEVICE_SET_IRQS) return -EINVAL; else if (cmd == VFIO_DEVICE_RESET) |