1 /* 2 * Mediated device Core Driver 3 * 4 * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. 5 * Author: Neo Jia <cjia@nvidia.com> 6 * Kirti Wankhede <kwankhede@nvidia.com> 7 * 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. 11 */ 12 13 #include <linux/module.h> 14 #include <linux/device.h> 15 #include <linux/slab.h> 16 #include <linux/uuid.h> 17 #include <linux/sysfs.h> 18 #include <linux/mdev.h> 19 20 #include "mdev_private.h" 21 22 #define DRIVER_VERSION "0.1" 23 #define DRIVER_AUTHOR "NVIDIA Corporation" 24 #define DRIVER_DESC "Mediated device Core Driver" 25 26 static LIST_HEAD(parent_list); 27 static DEFINE_MUTEX(parent_list_lock); 28 static struct class_compat *mdev_bus_compat_class; 29 30 static int _find_mdev_device(struct device *dev, void *data) 31 { 32 struct mdev_device *mdev; 33 34 if (!dev_is_mdev(dev)) 35 return 0; 36 37 mdev = to_mdev_device(dev); 38 39 if (uuid_le_cmp(mdev->uuid, *(uuid_le *)data) == 0) 40 return 1; 41 42 return 0; 43 } 44 45 static bool mdev_device_exist(struct parent_device *parent, uuid_le uuid) 46 { 47 struct device *dev; 48 49 dev = device_find_child(parent->dev, &uuid, _find_mdev_device); 50 if (dev) { 51 put_device(dev); 52 return true; 53 } 54 55 return false; 56 } 57 58 /* Should be called holding parent_list_lock */ 59 static struct parent_device *__find_parent_device(struct device *dev) 60 { 61 struct parent_device *parent; 62 63 list_for_each_entry(parent, &parent_list, next) { 64 if (parent->dev == dev) 65 return parent; 66 } 67 return NULL; 68 } 69 70 static void mdev_release_parent(struct kref *kref) 71 { 72 struct parent_device *parent = container_of(kref, struct parent_device, 73 ref); 74 struct device *dev = parent->dev; 75 76 kfree(parent); 77 put_device(dev); 78 } 79 80 static 81 inline struct parent_device *mdev_get_parent(struct parent_device *parent) 82 { 83 if (parent) 84 kref_get(&parent->ref); 85 86 return parent; 87 } 88 89 static inline void mdev_put_parent(struct parent_device *parent) 90 { 91 if (parent) 92 kref_put(&parent->ref, mdev_release_parent); 93 } 94 95 static int mdev_device_create_ops(struct kobject *kobj, 96 struct mdev_device *mdev) 97 { 98 struct parent_device *parent = mdev->parent; 99 int ret; 100 101 ret = parent->ops->create(kobj, mdev); 102 if (ret) 103 return ret; 104 105 ret = sysfs_create_groups(&mdev->dev.kobj, 106 parent->ops->mdev_attr_groups); 107 if (ret) 108 parent->ops->remove(mdev); 109 110 return ret; 111 } 112 113 /* 114 * mdev_device_remove_ops gets called from sysfs's 'remove' and when parent 115 * device is being unregistered from mdev device framework. 116 * - 'force_remove' is set to 'false' when called from sysfs's 'remove' which 117 * indicates that if the mdev device is active, used by VMM or userspace 118 * application, vendor driver could return error then don't remove the device. 119 * - 'force_remove' is set to 'true' when called from mdev_unregister_device() 120 * which indicate that parent device is being removed from mdev device 121 * framework so remove mdev device forcefully. 122 */ 123 static int mdev_device_remove_ops(struct mdev_device *mdev, bool force_remove) 124 { 125 struct parent_device *parent = mdev->parent; 126 int ret; 127 128 /* 129 * Vendor driver can return error if VMM or userspace application is 130 * using this mdev device. 131 */ 132 ret = parent->ops->remove(mdev); 133 if (ret && !force_remove) 134 return -EBUSY; 135 136 sysfs_remove_groups(&mdev->dev.kobj, parent->ops->mdev_attr_groups); 137 return 0; 138 } 139 140 static int mdev_device_remove_cb(struct device *dev, void *data) 141 { 142 if (!dev_is_mdev(dev)) 143 return 0; 144 145 return mdev_device_remove(dev, data ? *(bool *)data : true); 146 } 147 148 /* 149 * mdev_register_device : Register a device 150 * @dev: device structure representing parent device. 151 * @ops: Parent device operation structure to be registered. 152 * 153 * Add device to list of registered parent devices. 154 * Returns a negative value on error, otherwise 0. 155 */ 156 int mdev_register_device(struct device *dev, const struct parent_ops *ops) 157 { 158 int ret; 159 struct parent_device *parent; 160 161 /* check for mandatory ops */ 162 if (!ops || !ops->create || !ops->remove || !ops->supported_type_groups) 163 return -EINVAL; 164 165 dev = get_device(dev); 166 if (!dev) 167 return -EINVAL; 168 169 mutex_lock(&parent_list_lock); 170 171 /* Check for duplicate */ 172 parent = __find_parent_device(dev); 173 if (parent) { 174 ret = -EEXIST; 175 goto add_dev_err; 176 } 177 178 parent = kzalloc(sizeof(*parent), GFP_KERNEL); 179 if (!parent) { 180 ret = -ENOMEM; 181 goto add_dev_err; 182 } 183 184 kref_init(&parent->ref); 185 mutex_init(&parent->lock); 186 187 parent->dev = dev; 188 parent->ops = ops; 189 190 if (!mdev_bus_compat_class) { 191 mdev_bus_compat_class = class_compat_register("mdev_bus"); 192 if (!mdev_bus_compat_class) { 193 ret = -ENOMEM; 194 goto add_dev_err; 195 } 196 } 197 198 ret = parent_create_sysfs_files(parent); 199 if (ret) 200 goto add_dev_err; 201 202 ret = class_compat_create_link(mdev_bus_compat_class, dev, NULL); 203 if (ret) 204 dev_warn(dev, "Failed to create compatibility class link\n"); 205 206 list_add(&parent->next, &parent_list); 207 mutex_unlock(&parent_list_lock); 208 209 dev_info(dev, "MDEV: Registered\n"); 210 return 0; 211 212 add_dev_err: 213 mutex_unlock(&parent_list_lock); 214 if (parent) 215 mdev_put_parent(parent); 216 else 217 put_device(dev); 218 return ret; 219 } 220 EXPORT_SYMBOL(mdev_register_device); 221 222 /* 223 * mdev_unregister_device : Unregister a parent device 224 * @dev: device structure representing parent device. 225 * 226 * Remove device from list of registered parent devices. Give a chance to free 227 * existing mediated devices for given device. 228 */ 229 230 void mdev_unregister_device(struct device *dev) 231 { 232 struct parent_device *parent; 233 bool force_remove = true; 234 235 mutex_lock(&parent_list_lock); 236 parent = __find_parent_device(dev); 237 238 if (!parent) { 239 mutex_unlock(&parent_list_lock); 240 return; 241 } 242 dev_info(dev, "MDEV: Unregistering\n"); 243 244 list_del(&parent->next); 245 class_compat_remove_link(mdev_bus_compat_class, dev, NULL); 246 247 device_for_each_child(dev, (void *)&force_remove, 248 mdev_device_remove_cb); 249 250 parent_remove_sysfs_files(parent); 251 252 mutex_unlock(&parent_list_lock); 253 mdev_put_parent(parent); 254 } 255 EXPORT_SYMBOL(mdev_unregister_device); 256 257 static void mdev_device_release(struct device *dev) 258 { 259 struct mdev_device *mdev = to_mdev_device(dev); 260 261 dev_dbg(&mdev->dev, "MDEV: destroying\n"); 262 kfree(mdev); 263 } 264 265 int mdev_device_create(struct kobject *kobj, struct device *dev, uuid_le uuid) 266 { 267 int ret; 268 struct mdev_device *mdev; 269 struct parent_device *parent; 270 struct mdev_type *type = to_mdev_type(kobj); 271 272 parent = mdev_get_parent(type->parent); 273 if (!parent) 274 return -EINVAL; 275 276 mutex_lock(&parent->lock); 277 278 /* Check for duplicate */ 279 if (mdev_device_exist(parent, uuid)) { 280 ret = -EEXIST; 281 goto create_err; 282 } 283 284 mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); 285 if (!mdev) { 286 ret = -ENOMEM; 287 goto create_err; 288 } 289 290 memcpy(&mdev->uuid, &uuid, sizeof(uuid_le)); 291 mdev->parent = parent; 292 kref_init(&mdev->ref); 293 294 mdev->dev.parent = dev; 295 mdev->dev.bus = &mdev_bus_type; 296 mdev->dev.release = mdev_device_release; 297 dev_set_name(&mdev->dev, "%pUl", uuid.b); 298 299 ret = device_register(&mdev->dev); 300 if (ret) { 301 put_device(&mdev->dev); 302 goto create_err; 303 } 304 305 ret = mdev_device_create_ops(kobj, mdev); 306 if (ret) 307 goto create_failed; 308 309 ret = mdev_create_sysfs_files(&mdev->dev, type); 310 if (ret) { 311 mdev_device_remove_ops(mdev, true); 312 goto create_failed; 313 } 314 315 mdev->type_kobj = kobj; 316 dev_dbg(&mdev->dev, "MDEV: created\n"); 317 318 mutex_unlock(&parent->lock); 319 return ret; 320 321 create_failed: 322 device_unregister(&mdev->dev); 323 324 create_err: 325 mutex_unlock(&parent->lock); 326 mdev_put_parent(parent); 327 return ret; 328 } 329 330 int mdev_device_remove(struct device *dev, bool force_remove) 331 { 332 struct mdev_device *mdev; 333 struct parent_device *parent; 334 struct mdev_type *type; 335 int ret; 336 337 mdev = to_mdev_device(dev); 338 type = to_mdev_type(mdev->type_kobj); 339 parent = mdev->parent; 340 mutex_lock(&parent->lock); 341 342 ret = mdev_device_remove_ops(mdev, force_remove); 343 if (ret) { 344 mutex_unlock(&parent->lock); 345 return ret; 346 } 347 348 mdev_remove_sysfs_files(dev, type); 349 device_unregister(dev); 350 mutex_unlock(&parent->lock); 351 mdev_put_parent(parent); 352 return ret; 353 } 354 355 static int __init mdev_init(void) 356 { 357 int ret; 358 359 ret = mdev_bus_register(); 360 361 /* 362 * Attempt to load known vfio_mdev. This gives us a working environment 363 * without the user needing to explicitly load vfio_mdev driver. 364 */ 365 if (!ret) 366 request_module_nowait("vfio_mdev"); 367 368 return ret; 369 } 370 371 static void __exit mdev_exit(void) 372 { 373 if (mdev_bus_compat_class) 374 class_compat_unregister(mdev_bus_compat_class); 375 376 mdev_bus_unregister(); 377 } 378 379 module_init(mdev_init) 380 module_exit(mdev_exit) 381 382 MODULE_VERSION(DRIVER_VERSION); 383 MODULE_LICENSE("GPL v2"); 384 MODULE_AUTHOR(DRIVER_AUTHOR); 385 MODULE_DESCRIPTION(DRIVER_DESC); 386