1 // SPDX-License-Identifier: GPL-2.0-only
3 * VFIO based driver for Mediated device
5 * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
6 * Author: Neo Jia <cjia@nvidia.com>
7 * Kirti Wankhede <kwankhede@nvidia.com>
10 #include <linux/init.h>
11 #include <linux/module.h>
12 #include <linux/device.h>
13 #include <linux/kernel.h>
14 #include <linux/slab.h>
15 #include <linux/vfio.h>
16 #include <linux/mdev.h>
18 #include "mdev_private.h"
20 #define DRIVER_VERSION "0.1"
21 #define DRIVER_AUTHOR "NVIDIA Corporation"
22 #define DRIVER_DESC "VFIO based driver for Mediated device"
24 static int vfio_mdev_open(void *device_data
)
26 struct mdev_device
*mdev
= device_data
;
27 struct mdev_parent
*parent
= mdev
->parent
;
30 if (unlikely(!parent
->ops
->open
))
33 if (!try_module_get(THIS_MODULE
))
36 ret
= parent
->ops
->open(mdev
);
38 module_put(THIS_MODULE
);
43 static void vfio_mdev_release(void *device_data
)
45 struct mdev_device
*mdev
= device_data
;
46 struct mdev_parent
*parent
= mdev
->parent
;
48 if (likely(parent
->ops
->release
))
49 parent
->ops
->release(mdev
);
51 module_put(THIS_MODULE
);
54 static long vfio_mdev_unlocked_ioctl(void *device_data
,
55 unsigned int cmd
, unsigned long arg
)
57 struct mdev_device
*mdev
= device_data
;
58 struct mdev_parent
*parent
= mdev
->parent
;
60 if (unlikely(!parent
->ops
->ioctl
))
63 return parent
->ops
->ioctl(mdev
, cmd
, arg
);
66 static ssize_t
vfio_mdev_read(void *device_data
, char __user
*buf
,
67 size_t count
, loff_t
*ppos
)
69 struct mdev_device
*mdev
= device_data
;
70 struct mdev_parent
*parent
= mdev
->parent
;
72 if (unlikely(!parent
->ops
->read
))
75 return parent
->ops
->read(mdev
, buf
, count
, ppos
);
78 static ssize_t
vfio_mdev_write(void *device_data
, const char __user
*buf
,
79 size_t count
, loff_t
*ppos
)
81 struct mdev_device
*mdev
= device_data
;
82 struct mdev_parent
*parent
= mdev
->parent
;
84 if (unlikely(!parent
->ops
->write
))
87 return parent
->ops
->write(mdev
, buf
, count
, ppos
);
90 static int vfio_mdev_mmap(void *device_data
, struct vm_area_struct
*vma
)
92 struct mdev_device
*mdev
= device_data
;
93 struct mdev_parent
*parent
= mdev
->parent
;
95 if (unlikely(!parent
->ops
->mmap
))
98 return parent
->ops
->mmap(mdev
, vma
);
101 static const struct vfio_device_ops vfio_mdev_dev_ops
= {
103 .open
= vfio_mdev_open
,
104 .release
= vfio_mdev_release
,
105 .ioctl
= vfio_mdev_unlocked_ioctl
,
106 .read
= vfio_mdev_read
,
107 .write
= vfio_mdev_write
,
108 .mmap
= vfio_mdev_mmap
,
111 static int vfio_mdev_probe(struct device
*dev
)
113 struct mdev_device
*mdev
= to_mdev_device(dev
);
115 return vfio_add_group_dev(dev
, &vfio_mdev_dev_ops
, mdev
);
118 static void vfio_mdev_remove(struct device
*dev
)
120 vfio_del_group_dev(dev
);
123 static struct mdev_driver vfio_mdev_driver
= {
125 .probe
= vfio_mdev_probe
,
126 .remove
= vfio_mdev_remove
,
129 static int __init
vfio_mdev_init(void)
131 return mdev_register_driver(&vfio_mdev_driver
, THIS_MODULE
);
134 static void __exit
vfio_mdev_exit(void)
136 mdev_unregister_driver(&vfio_mdev_driver
);
139 module_init(vfio_mdev_init
)
140 module_exit(vfio_mdev_exit
)
142 MODULE_VERSION(DRIVER_VERSION
);
143 MODULE_LICENSE("GPL v2");
144 MODULE_AUTHOR(DRIVER_AUTHOR
);
145 MODULE_DESCRIPTION(DRIVER_DESC
);