@@ -137,25 +137,6 @@ The structures in the mdev_parent_ops structure are as follows:
* mdev_attr_groups: attributes of the mediated device
* supported_config: attributes to define supported configurations
-The functions in the mdev_parent_ops structure are as follows:
-
-* create: allocate basic resources in a driver for a mediated device
-* remove: free resources in a driver when a mediated device is destroyed
-
-(Note that mdev-core provides no implicit serialization of create/remove
-callbacks per mdev parent device, per mdev type, or any other categorization.
-Vendor drivers are expected to be fully asynchronous in this respect or
-provide their own internal resource protection.)
-
-The callbacks in the mdev_parent_ops structure are as follows:
-
-* open: open callback of mediated device
-* close: close callback of mediated device
-* ioctl: ioctl callback of mediated device
-* read : read emulation callback
-* write: write emulation callback
-* mmap: mmap emulation callback
-
A driver should use the mdev_parent_ops structure in the function call to
register itself with the mdev core driver::
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-only
-mdev-y := mdev_core.o mdev_sysfs.o mdev_driver.o vfio_mdev.o
+mdev-y := mdev_core.o mdev_sysfs.o mdev_driver.o
obj-$(CONFIG_VFIO_MDEV) += mdev.o
@@ -89,17 +89,10 @@ void mdev_release_parent(struct kref *kref)
static void mdev_device_remove_common(struct mdev_device *mdev)
{
struct mdev_parent *parent = mdev->type->parent;
- int ret;
mdev_remove_sysfs_files(mdev);
device_del(&mdev->dev);
lockdep_assert_held(&parent->unreg_sem);
- if (parent->ops->remove) {
- ret = parent->ops->remove(mdev);
- if (ret)
- dev_err(&mdev->dev, "Remove failed: err=%d\n", ret);
- }
-
/* Balances with device_initialize() */
put_device(&mdev->dev);
}
@@ -131,17 +124,13 @@ int mdev_register_device(struct device *dev, const struct mdev_parent_ops *ops)
/* check for mandatory ops */
if (!ops || !ops->supported_type_groups)
return -EINVAL;
- if (!ops->device_driver && (!ops->create || !ops->remove))
+ if (!ops->device_driver)
return -EINVAL;
dev = get_device(dev);
if (!dev)
return -EINVAL;
- /* Not mandatory, but its absence could be a problem */
- if (!ops->request)
- dev_info(dev, "Driver cannot be asked to release device\n");
-
mutex_lock(&parent_list_lock);
/* Check for duplicate */
@@ -263,15 +252,12 @@ static void mdev_device_release(struct device *dev)
*/
static int mdev_bind_driver(struct mdev_device *mdev)
{
- struct mdev_driver *drv = mdev->type->parent->ops->device_driver;
int ret;
- if (!drv)
- drv = &vfio_mdev_driver;
-
while (1) {
device_lock(&mdev->dev);
- if (mdev->dev.driver == &drv->driver) {
+ if (mdev->dev.driver ==
+ &mdev->type->parent->ops->device_driver->driver) {
ret = 0;
goto out_unlock;
}
@@ -337,15 +323,9 @@ int mdev_device_create(struct mdev_type *type, const guid_t *uuid)
goto out_put_device;
}
- if (parent->ops->create) {
- ret = parent->ops->create(mdev);
- if (ret)
- goto out_unlock;
- }
-
ret = device_add(&mdev->dev);
if (ret)
- goto out_remove;
+ goto out_unlock;
ret = mdev_bind_driver(mdev);
if (ret)
@@ -363,9 +343,6 @@ int mdev_device_create(struct mdev_type *type, const guid_t *uuid)
out_del:
device_del(&mdev->dev);
-out_remove:
- if (parent->ops->remove)
- parent->ops->remove(mdev);
out_unlock:
up_read(&parent->unreg_sem);
out_put_device:
@@ -408,28 +385,14 @@ int mdev_device_remove(struct mdev_device *mdev)
static int __init mdev_init(void)
{
- int rc;
-
- rc = mdev_bus_register();
- if (rc)
- return rc;
- rc = mdev_register_driver(&vfio_mdev_driver);
- if (rc)
- goto err_bus;
- return 0;
-err_bus:
- mdev_bus_unregister();
- return rc;
+ return bus_register(&mdev_bus_type);
}
static void __exit mdev_exit(void)
{
- mdev_unregister_driver(&vfio_mdev_driver);
-
if (mdev_bus_compat_class)
class_compat_unregister(mdev_bus_compat_class);
-
- mdev_bus_unregister();
+ bus_unregister(&mdev_bus_type);
}
module_init(mdev_init)
@@ -74,15 +74,8 @@ static int mdev_remove(struct device *dev)
static int mdev_match(struct device *dev, struct device_driver *drv)
{
struct mdev_device *mdev = to_mdev_device(dev);
- struct mdev_driver *target = mdev->type->parent->ops->device_driver;
-
- /*
- * The ops specify the device driver to connect, fall back to the old
- * shim driver if the driver hasn't been converted.
- */
- if (!target)
- target = &vfio_mdev_driver;
- return drv == &target->driver;
+
+ return drv == &mdev->type->parent->ops->device_driver->driver;
}
struct bus_type mdev_bus_type = {
@@ -118,13 +111,3 @@ void mdev_unregister_driver(struct mdev_driver *drv)
driver_unregister(&drv->driver);
}
EXPORT_SYMBOL(mdev_unregister_driver);
-
-int mdev_bus_register(void)
-{
- return bus_register(&mdev_bus_type);
-}
-
-void mdev_bus_unregister(void)
-{
- bus_unregister(&mdev_bus_type);
-}
@@ -37,8 +37,6 @@ struct mdev_type {
#define to_mdev_type(_kobj) \
container_of(_kobj, struct mdev_type, kobj)
-extern struct mdev_driver vfio_mdev_driver;
-
int parent_create_sysfs_files(struct mdev_parent *parent);
void parent_remove_sysfs_files(struct mdev_parent *parent);
deleted file mode 100644
@@ -1,158 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * VFIO based driver for Mediated device
- *
- * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
- * Author: Neo Jia <cjia@nvidia.com>
- * Kirti Wankhede <kwankhede@nvidia.com>
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/vfio.h>
-#include <linux/mdev.h>
-
-#include "mdev_private.h"
-
-static int vfio_mdev_open(struct vfio_device *core_vdev)
-{
- struct mdev_device *mdev = to_mdev_device(core_vdev->dev);
- struct mdev_parent *parent = mdev->type->parent;
-
- int ret;
-
- if (unlikely(!parent->ops->open))
- return -EINVAL;
-
- if (!try_module_get(THIS_MODULE))
- return -ENODEV;
-
- ret = parent->ops->open(mdev);
- if (ret)
- module_put(THIS_MODULE);
-
- return ret;
-}
-
-static void vfio_mdev_release(struct vfio_device *core_vdev)
-{
- struct mdev_device *mdev = to_mdev_device(core_vdev->dev);
- struct mdev_parent *parent = mdev->type->parent;
-
- if (likely(parent->ops->release))
- parent->ops->release(mdev);
-
- module_put(THIS_MODULE);
-}
-
-static long vfio_mdev_unlocked_ioctl(struct vfio_device *core_vdev,
- unsigned int cmd, unsigned long arg)
-{
- struct mdev_device *mdev = to_mdev_device(core_vdev->dev);
- struct mdev_parent *parent = mdev->type->parent;
-
- if (unlikely(!parent->ops->ioctl))
- return -EINVAL;
-
- return parent->ops->ioctl(mdev, cmd, arg);
-}
-
-static ssize_t vfio_mdev_read(struct vfio_device *core_vdev, char __user *buf,
- size_t count, loff_t *ppos)
-{
- struct mdev_device *mdev = to_mdev_device(core_vdev->dev);
- struct mdev_parent *parent = mdev->type->parent;
-
- if (unlikely(!parent->ops->read))
- return -EINVAL;
-
- return parent->ops->read(mdev, buf, count, ppos);
-}
-
-static ssize_t vfio_mdev_write(struct vfio_device *core_vdev,
- const char __user *buf, size_t count,
- loff_t *ppos)
-{
- struct mdev_device *mdev = to_mdev_device(core_vdev->dev);
- struct mdev_parent *parent = mdev->type->parent;
-
- if (unlikely(!parent->ops->write))
- return -EINVAL;
-
- return parent->ops->write(mdev, buf, count, ppos);
-}
-
-static int vfio_mdev_mmap(struct vfio_device *core_vdev,
- struct vm_area_struct *vma)
-{
- struct mdev_device *mdev = to_mdev_device(core_vdev->dev);
- struct mdev_parent *parent = mdev->type->parent;
-
- if (unlikely(!parent->ops->mmap))
- return -EINVAL;
-
- return parent->ops->mmap(mdev, vma);
-}
-
-static void vfio_mdev_request(struct vfio_device *core_vdev, unsigned int count)
-{
- struct mdev_device *mdev = to_mdev_device(core_vdev->dev);
- struct mdev_parent *parent = mdev->type->parent;
-
- if (parent->ops->request)
- parent->ops->request(mdev, count);
- else if (count == 0)
- dev_notice(mdev_dev(mdev),
- "No mdev vendor driver request callback support, blocked until released by user\n");
-}
-
-static const struct vfio_device_ops vfio_mdev_dev_ops = {
- .name = "vfio-mdev",
- .open = vfio_mdev_open,
- .release = vfio_mdev_release,
- .ioctl = vfio_mdev_unlocked_ioctl,
- .read = vfio_mdev_read,
- .write = vfio_mdev_write,
- .mmap = vfio_mdev_mmap,
- .request = vfio_mdev_request,
-};
-
-static int vfio_mdev_probe(struct mdev_device *mdev)
-{
- struct vfio_device *vdev;
- int ret;
-
- vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
- if (!vdev)
- return -ENOMEM;
-
- vfio_init_group_dev(vdev, &mdev->dev, &vfio_mdev_dev_ops);
- ret = vfio_register_group_dev(vdev);
- if (ret) {
- kfree(vdev);
- return ret;
- }
- dev_set_drvdata(&mdev->dev, vdev);
- return 0;
-}
-
-static void vfio_mdev_remove(struct mdev_device *mdev)
-{
- struct vfio_device *vdev = dev_get_drvdata(&mdev->dev);
-
- vfio_unregister_group_dev(vdev);
- kfree(vdev);
-}
-
-struct mdev_driver vfio_mdev_driver = {
- .driver = {
- .name = "vfio_mdev",
- .owner = THIS_MODULE,
- .mod_name = KBUILD_MODNAME,
- },
- .probe = vfio_mdev_probe,
- .remove = vfio_mdev_remove,
-};
@@ -747,7 +747,7 @@ void vfio_init_group_dev(struct vfio_device *device, struct device *dev,
device->dev = dev;
device->ops = ops;
}
-EXPORT_SYMBOL_GPL(vfio_init_group_dev);
+EXPORT_SYMBOL(vfio_init_group_dev);
int vfio_register_group_dev(struct vfio_device *device)
{
@@ -796,7 +796,7 @@ int vfio_register_group_dev(struct vfio_device *device)
return 0;
}
-EXPORT_SYMBOL_GPL(vfio_register_group_dev);
+EXPORT_SYMBOL(vfio_register_group_dev);
/**
* Get a reference to the vfio_device for a device. Even if the
@@ -927,7 +927,7 @@ void vfio_unregister_group_dev(struct vfio_device *device)
/* Matches the get in vfio_register_group_dev() */
vfio_group_put(group);
}
-EXPORT_SYMBOL_GPL(vfio_unregister_group_dev);
+EXPORT_SYMBOL(vfio_unregister_group_dev);
/**
* VFIO base fd, /dev/vfio/vfio
@@ -61,45 +61,6 @@ struct device *mtype_get_parent_dev(struct mdev_type *mtype);
* @mdev_attr_groups: Attributes of the mediated device.
* @supported_type_groups: Attributes to define supported types. It is mandatory
* to provide supported types.
- * @create: Called to allocate basic resources in parent device's
- * driver for a particular mediated device. It is
- * mandatory to provide create ops.
- * @mdev: mdev_device structure on of mediated device
- * that is being created
- * Returns integer: success (0) or error (< 0)
- * @remove: Called to free resources in parent device's driver for
- * a mediated device. It is mandatory to provide 'remove'
- * ops.
- * @mdev: mdev_device device structure which is being
- * destroyed
- * Returns integer: success (0) or error (< 0)
- * @open: Open mediated device.
- * @mdev: mediated device.
- * Returns integer: success (0) or error (< 0)
- * @release: release mediated device
- * @mdev: mediated device.
- * @read: Read emulation callback
- * @mdev: mediated device structure
- * @buf: read buffer
- * @count: number of bytes to read
- * @ppos: address.
- * Retuns number on bytes read on success or error.
- * @write: Write emulation callback
- * @mdev: mediated device structure
- * @buf: write buffer
- * @count: number of bytes to be written
- * @ppos: address.
- * Retuns number on bytes written on success or error.
- * @ioctl: IOCTL callback
- * @mdev: mediated device structure
- * @cmd: ioctl command
- * @arg: arguments to ioctl
- * @mmap: mmap callback
- * @mdev: mediated device structure
- * @vma: vma structure
- * @request: request callback to release device
- * @mdev: mediated device structure
- * @count: request sequence number
* Parent device that support mediated device should be registered with mdev
* module with mdev_parent_ops structure.
**/
@@ -109,19 +70,6 @@ struct mdev_parent_ops {
const struct attribute_group **dev_attr_groups;
const struct attribute_group **mdev_attr_groups;
struct attribute_group **supported_type_groups;
-
- int (*create)(struct mdev_device *mdev);
- int (*remove)(struct mdev_device *mdev);
- int (*open)(struct mdev_device *mdev);
- void (*release)(struct mdev_device *mdev);
- ssize_t (*read)(struct mdev_device *mdev, char __user *buf,
- size_t count, loff_t *ppos);
- ssize_t (*write)(struct mdev_device *mdev, const char __user *buf,
- size_t count, loff_t *ppos);
- long (*ioctl)(struct mdev_device *mdev, unsigned int cmd,
- unsigned long arg);
- int (*mmap)(struct mdev_device *mdev, struct vm_area_struct *vma);
- void (*request)(struct mdev_device *mdev, unsigned int count);
};
/* interface for exporting mdev supported type attributes */
@@ -64,6 +64,10 @@ void vfio_init_group_dev(struct vfio_device *device, struct device *dev,
int vfio_register_group_dev(struct vfio_device *device);
void vfio_unregister_group_dev(struct vfio_device *device);
extern struct vfio_device *vfio_device_get_from_dev(struct device *dev);
+static inline void vfio_device_get(struct vfio_device *device)
+{
+ refcount_inc(&device->refcount);
+}
extern void vfio_device_put(struct vfio_device *device);
/* events for the backend driver notify callback */
Now that all mdev drivers directly create their own mdev_device driver and directly register with the vfio core's vfio_device_ops this is all dead code. Delete vfio_mdev.c and the mdev_parent_ops members that are connected to it. Preserve VFIO's design of allowing mdev drivers to be !GPL by allowing the three functions that replace this module for !GPL usage. This goes along with the other 19 symbols that are already marked !GPL in VFIO. Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> --- .../driver-api/vfio-mediated-device.rst | 19 --- drivers/vfio/mdev/Makefile | 2 +- drivers/vfio/mdev/mdev_core.c | 49 +----- drivers/vfio/mdev/mdev_driver.c | 21 +-- drivers/vfio/mdev/mdev_private.h | 2 - drivers/vfio/mdev/vfio_mdev.c | 158 ------------------ drivers/vfio/vfio.c | 6 +- include/linux/mdev.h | 52 ------ include/linux/vfio.h | 4 + 9 files changed, 16 insertions(+), 297 deletions(-) delete mode 100644 drivers/vfio/mdev/vfio_mdev.c