|
@@ -855,6 +855,43 @@ static void vfio_ap_mdev_release(struct mdev_device *mdev)
|
|
|
module_put(THIS_MODULE);
|
|
|
}
|
|
|
|
|
|
+static int vfio_ap_mdev_get_device_info(unsigned long arg)
|
|
|
+{
|
|
|
+ unsigned long minsz;
|
|
|
+ struct vfio_device_info info;
|
|
|
+
|
|
|
+ minsz = offsetofend(struct vfio_device_info, num_irqs);
|
|
|
+
|
|
|
+ if (copy_from_user(&info, (void __user *)arg, minsz))
|
|
|
+ return -EFAULT;
|
|
|
+
|
|
|
+ if (info.argsz < minsz)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ info.flags = VFIO_DEVICE_FLAGS_AP;
|
|
|
+ info.num_regions = 0;
|
|
|
+ info.num_irqs = 0;
|
|
|
+
|
|
|
+ return copy_to_user((void __user *)arg, &info, minsz);
|
|
|
+}
|
|
|
+
|
|
|
+static ssize_t vfio_ap_mdev_ioctl(struct mdev_device *mdev,
|
|
|
+ unsigned int cmd, unsigned long arg)
|
|
|
+{
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ switch (cmd) {
|
|
|
+ case VFIO_DEVICE_GET_INFO:
|
|
|
+ ret = vfio_ap_mdev_get_device_info(arg);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ ret = -EOPNOTSUPP;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
static const struct mdev_parent_ops vfio_ap_matrix_ops = {
|
|
|
.owner = THIS_MODULE,
|
|
|
.supported_type_groups = vfio_ap_mdev_type_groups,
|
|
@@ -863,6 +900,7 @@ static const struct mdev_parent_ops vfio_ap_matrix_ops = {
|
|
|
.remove = vfio_ap_mdev_remove,
|
|
|
.open = vfio_ap_mdev_open,
|
|
|
.release = vfio_ap_mdev_release,
|
|
|
+ .ioctl = vfio_ap_mdev_ioctl,
|
|
|
};
|
|
|
|
|
|
int vfio_ap_mdev_register(void)
|