-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
vfio: VFIO based driver for Mediated devices
vfio_mdev driver registers with mdev core driver. mdev core driver creates mediated device and calls probe routine of vfio_mdev driver for each device. Probe routine of vfio_mdev driver adds mediated device to VFIO core module This driver forms a shim layer that pass through VFIO devices operations to vendor driver for mediated devices. Signed-off-by: Kirti Wankhede <kwankhede@nvidia.com> Signed-off-by: Neo Jia <cjia@nvidia.com> Reviewed-by: Jike Song <jike.song@intel.com> Reviewed-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
- Loading branch information
Kirti Wankhede
authored and
Alex Williamson
committed
Nov 17, 2016
1 parent
7b96953
commit fa3da00
Showing
4 changed files
with
168 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
/* | ||
* 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> | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License version 2 as | ||
* published by the Free Software Foundation. | ||
*/ | ||
|
||
#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" | ||
|
||
#define DRIVER_VERSION "0.1" | ||
#define DRIVER_AUTHOR "NVIDIA Corporation" | ||
#define DRIVER_DESC "VFIO based driver for Mediated device" | ||
|
||
static int vfio_mdev_open(void *device_data) | ||
{ | ||
struct mdev_device *mdev = device_data; | ||
struct parent_device *parent = mdev->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(void *device_data) | ||
{ | ||
struct mdev_device *mdev = device_data; | ||
struct parent_device *parent = mdev->parent; | ||
|
||
if (likely(parent->ops->release)) | ||
parent->ops->release(mdev); | ||
|
||
module_put(THIS_MODULE); | ||
} | ||
|
||
static long vfio_mdev_unlocked_ioctl(void *device_data, | ||
unsigned int cmd, unsigned long arg) | ||
{ | ||
struct mdev_device *mdev = device_data; | ||
struct parent_device *parent = mdev->parent; | ||
|
||
if (unlikely(!parent->ops->ioctl)) | ||
return -EINVAL; | ||
|
||
return parent->ops->ioctl(mdev, cmd, arg); | ||
} | ||
|
||
static ssize_t vfio_mdev_read(void *device_data, char __user *buf, | ||
size_t count, loff_t *ppos) | ||
{ | ||
struct mdev_device *mdev = device_data; | ||
struct parent_device *parent = mdev->parent; | ||
|
||
if (unlikely(!parent->ops->read)) | ||
return -EINVAL; | ||
|
||
return parent->ops->read(mdev, buf, count, ppos); | ||
} | ||
|
||
static ssize_t vfio_mdev_write(void *device_data, const char __user *buf, | ||
size_t count, loff_t *ppos) | ||
{ | ||
struct mdev_device *mdev = device_data; | ||
struct parent_device *parent = mdev->parent; | ||
|
||
if (unlikely(!parent->ops->write)) | ||
return -EINVAL; | ||
|
||
return parent->ops->write(mdev, buf, count, ppos); | ||
} | ||
|
||
static int vfio_mdev_mmap(void *device_data, struct vm_area_struct *vma) | ||
{ | ||
struct mdev_device *mdev = device_data; | ||
struct parent_device *parent = mdev->parent; | ||
|
||
if (unlikely(!parent->ops->mmap)) | ||
return -EINVAL; | ||
|
||
return parent->ops->mmap(mdev, vma); | ||
} | ||
|
||
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, | ||
}; | ||
|
||
int vfio_mdev_probe(struct device *dev) | ||
{ | ||
struct mdev_device *mdev = to_mdev_device(dev); | ||
|
||
return vfio_add_group_dev(dev, &vfio_mdev_dev_ops, mdev); | ||
} | ||
|
||
void vfio_mdev_remove(struct device *dev) | ||
{ | ||
vfio_del_group_dev(dev); | ||
} | ||
|
||
struct mdev_driver vfio_mdev_driver = { | ||
.name = "vfio_mdev", | ||
.probe = vfio_mdev_probe, | ||
.remove = vfio_mdev_remove, | ||
}; | ||
|
||
static int __init vfio_mdev_init(void) | ||
{ | ||
return mdev_register_driver(&vfio_mdev_driver, THIS_MODULE); | ||
} | ||
|
||
static void __exit vfio_mdev_exit(void) | ||
{ | ||
mdev_unregister_driver(&vfio_mdev_driver); | ||
} | ||
|
||
module_init(vfio_mdev_init) | ||
module_exit(vfio_mdev_exit) | ||
|
||
MODULE_VERSION(DRIVER_VERSION); | ||
MODULE_LICENSE("GPL v2"); | ||
MODULE_AUTHOR(DRIVER_AUTHOR); | ||
MODULE_DESCRIPTION(DRIVER_DESC); |