diff options
| -rw-r--r-- | drivers/vfio/mdev/mdev_core.c | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c index be1ee89ee917..6bb4d4c469ab 100644 --- a/drivers/vfio/mdev/mdev_core.c +++ b/drivers/vfio/mdev/mdev_core.c | |||
| @@ -27,6 +27,9 @@ static LIST_HEAD(parent_list); | |||
| 27 | static DEFINE_MUTEX(parent_list_lock); | 27 | static DEFINE_MUTEX(parent_list_lock); |
| 28 | static struct class_compat *mdev_bus_compat_class; | 28 | static struct class_compat *mdev_bus_compat_class; |
| 29 | 29 | ||
| 30 | static LIST_HEAD(mdev_list); | ||
| 31 | static DEFINE_MUTEX(mdev_list_lock); | ||
| 32 | |||
| 30 | static int _find_mdev_device(struct device *dev, void *data) | 33 | static int _find_mdev_device(struct device *dev, void *data) |
| 31 | { | 34 | { |
| 32 | struct mdev_device *mdev; | 35 | struct mdev_device *mdev; |
| @@ -316,6 +319,11 @@ int mdev_device_create(struct kobject *kobj, struct device *dev, uuid_le uuid) | |||
| 316 | dev_dbg(&mdev->dev, "MDEV: created\n"); | 319 | dev_dbg(&mdev->dev, "MDEV: created\n"); |
| 317 | 320 | ||
| 318 | mutex_unlock(&parent->lock); | 321 | mutex_unlock(&parent->lock); |
| 322 | |||
| 323 | mutex_lock(&mdev_list_lock); | ||
| 324 | list_add(&mdev->next, &mdev_list); | ||
| 325 | mutex_unlock(&mdev_list_lock); | ||
| 326 | |||
| 319 | return ret; | 327 | return ret; |
| 320 | 328 | ||
| 321 | create_failed: | 329 | create_failed: |
| @@ -329,12 +337,30 @@ create_err: | |||
| 329 | 337 | ||
| 330 | int mdev_device_remove(struct device *dev, bool force_remove) | 338 | int mdev_device_remove(struct device *dev, bool force_remove) |
| 331 | { | 339 | { |
| 332 | struct mdev_device *mdev; | 340 | struct mdev_device *mdev, *tmp; |
| 333 | struct parent_device *parent; | 341 | struct parent_device *parent; |
| 334 | struct mdev_type *type; | 342 | struct mdev_type *type; |
| 335 | int ret; | 343 | int ret; |
| 344 | bool found = false; | ||
| 336 | 345 | ||
| 337 | mdev = to_mdev_device(dev); | 346 | mdev = to_mdev_device(dev); |
| 347 | |||
| 348 | mutex_lock(&mdev_list_lock); | ||
| 349 | list_for_each_entry(tmp, &mdev_list, next) { | ||
| 350 | if (tmp == mdev) { | ||
| 351 | found = true; | ||
| 352 | break; | ||
| 353 | } | ||
| 354 | } | ||
| 355 | |||
| 356 | if (found) | ||
| 357 | list_del(&mdev->next); | ||
| 358 | |||
| 359 | mutex_unlock(&mdev_list_lock); | ||
| 360 | |||
| 361 | if (!found) | ||
| 362 | return -ENODEV; | ||
| 363 | |||
| 338 | type = to_mdev_type(mdev->type_kobj); | 364 | type = to_mdev_type(mdev->type_kobj); |
| 339 | parent = mdev->parent; | 365 | parent = mdev->parent; |
| 340 | mutex_lock(&parent->lock); | 366 | mutex_lock(&parent->lock); |
| @@ -342,6 +368,11 @@ int mdev_device_remove(struct device *dev, bool force_remove) | |||
| 342 | ret = mdev_device_remove_ops(mdev, force_remove); | 368 | ret = mdev_device_remove_ops(mdev, force_remove); |
| 343 | if (ret) { | 369 | if (ret) { |
| 344 | mutex_unlock(&parent->lock); | 370 | mutex_unlock(&parent->lock); |
| 371 | |||
| 372 | mutex_lock(&mdev_list_lock); | ||
| 373 | list_add(&mdev->next, &mdev_list); | ||
| 374 | mutex_unlock(&mdev_list_lock); | ||
| 375 | |||
| 345 | return ret; | 376 | return ret; |
| 346 | } | 377 | } |
| 347 | 378 | ||
| @@ -349,7 +380,8 @@ int mdev_device_remove(struct device *dev, bool force_remove) | |||
| 349 | device_unregister(dev); | 380 | device_unregister(dev); |
| 350 | mutex_unlock(&parent->lock); | 381 | mutex_unlock(&parent->lock); |
| 351 | mdev_put_parent(parent); | 382 | mdev_put_parent(parent); |
| 352 | return ret; | 383 | |
| 384 | return 0; | ||
| 353 | } | 385 | } |
| 354 | 386 | ||
| 355 | static int __init mdev_init(void) | 387 | static int __init mdev_init(void) |
