2 * VFIO based driver for Mediated device
4 * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
5 * Author: Neo Jia <cjia@nvidia.com>
6 * Kirti Wankhede <kwankhede@nvidia.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
13 #include <linux/init.h>
14 #include <linux/module.h>
15 #include <linux/device.h>
16 #include <linux/kernel.h>
17 #include <linux/slab.h>
18 #include <linux/vfio.h>
19 #include <linux/mdev.h>
21 #include "mdev_private.h"
23 #define DRIVER_VERSION "0.1"
24 #define DRIVER_AUTHOR "NVIDIA Corporation"
25 #define DRIVER_DESC "VFIO based driver for Mediated device"
27 static int vfio_mdev_open(void *device_data
)
29 struct mdev_device
*mdev
= device_data
;
30 struct mdev_parent
*parent
= mdev
->parent
;
33 if (unlikely(!parent
->ops
->open
))
36 if (!try_module_get(THIS_MODULE
))
39 ret
= parent
->ops
->open(mdev
);
41 module_put(THIS_MODULE
);
46 static void vfio_mdev_release(void *device_data
)
48 struct mdev_device
*mdev
= device_data
;
49 struct mdev_parent
*parent
= mdev
->parent
;
51 if (likely(parent
->ops
->release
))
52 parent
->ops
->release(mdev
);
54 module_put(THIS_MODULE
);
57 static long vfio_mdev_unlocked_ioctl(void *device_data
,
58 unsigned int cmd
, unsigned long arg
)
60 struct mdev_device
*mdev
= device_data
;
61 struct mdev_parent
*parent
= mdev
->parent
;
63 if (unlikely(!parent
->ops
->ioctl
))
66 return parent
->ops
->ioctl(mdev
, cmd
, arg
);
69 static ssize_t
vfio_mdev_read(void *device_data
, char __user
*buf
,
70 size_t count
, loff_t
*ppos
)
72 struct mdev_device
*mdev
= device_data
;
73 struct mdev_parent
*parent
= mdev
->parent
;
75 if (unlikely(!parent
->ops
->read
))
78 return parent
->ops
->read(mdev
, buf
, count
, ppos
);
81 static ssize_t
vfio_mdev_write(void *device_data
, const char __user
*buf
,
82 size_t count
, loff_t
*ppos
)
84 struct mdev_device
*mdev
= device_data
;
85 struct mdev_parent
*parent
= mdev
->parent
;
87 if (unlikely(!parent
->ops
->write
))
90 return parent
->ops
->write(mdev
, buf
, count
, ppos
);
93 static int vfio_mdev_mmap(void *device_data
, struct vm_area_struct
*vma
)
95 struct mdev_device
*mdev
= device_data
;
96 struct mdev_parent
*parent
= mdev
->parent
;
98 if (unlikely(!parent
->ops
->mmap
))
101 return parent
->ops
->mmap(mdev
, vma
);
104 static const struct vfio_device_ops vfio_mdev_dev_ops
= {
106 .open
= vfio_mdev_open
,
107 .release
= vfio_mdev_release
,
108 .ioctl
= vfio_mdev_unlocked_ioctl
,
109 .read
= vfio_mdev_read
,
110 .write
= vfio_mdev_write
,
111 .mmap
= vfio_mdev_mmap
,
114 static int vfio_mdev_probe(struct device
*dev
)
116 struct mdev_device
*mdev
= to_mdev_device(dev
);
118 return vfio_add_group_dev(dev
, &vfio_mdev_dev_ops
, mdev
);
121 static void vfio_mdev_remove(struct device
*dev
)
123 vfio_del_group_dev(dev
);
126 static struct mdev_driver vfio_mdev_driver
= {
128 .probe
= vfio_mdev_probe
,
129 .remove
= vfio_mdev_remove
,
132 static int __init
vfio_mdev_init(void)
134 return mdev_register_driver(&vfio_mdev_driver
, THIS_MODULE
);
137 static void __exit
vfio_mdev_exit(void)
139 mdev_unregister_driver(&vfio_mdev_driver
);
142 module_init(vfio_mdev_init
)
143 module_exit(vfio_mdev_exit
)
145 MODULE_VERSION(DRIVER_VERSION
);
146 MODULE_LICENSE("GPL v2");
147 MODULE_AUTHOR(DRIVER_AUTHOR
);
148 MODULE_DESCRIPTION(DRIVER_DESC
);