aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/vfio-mediated-device.txt27
-rw-r--r--drivers/gpu/drm/i915/gvt/kvmgt.c24
-rw-r--r--drivers/vfio/mdev/mdev_core.c100
-rw-r--r--drivers/vfio/mdev/mdev_private.h29
-rw-r--r--drivers/vfio/mdev/mdev_sysfs.c8
-rw-r--r--drivers/vfio/mdev/vfio_mdev.c12
-rw-r--r--drivers/vfio/pci/vfio_pci.c4
-rw-r--r--drivers/vfio/pci/vfio_pci_rdwr.c5
-rw-r--r--drivers/vfio/vfio_iommu_type1.c98
-rw-r--r--include/linux/mdev.h56
-rw-r--r--samples/Kconfig7
-rw-r--r--samples/Makefile3
-rw-r--r--samples/vfio-mdev/Makefile14
-rw-r--r--samples/vfio-mdev/mtty.c32
14 files changed, 247 insertions, 172 deletions
diff --git a/Documentation/vfio-mediated-device.txt b/Documentation/vfio-mediated-device.txt
index b38afec35edc..d226c7a5ba8b 100644
--- a/Documentation/vfio-mediated-device.txt
+++ b/Documentation/vfio-mediated-device.txt
@@ -127,22 +127,22 @@ the VFIO when devices are unbound from the driver.
127Physical Device Driver Interface 127Physical Device Driver Interface
128-------------------------------- 128--------------------------------
129 129
130The physical device driver interface provides the parent_ops[3] structure to 130The physical device driver interface provides the mdev_parent_ops[3] structure
131define the APIs to manage work in the mediated core driver that is related to 131to define the APIs to manage work in the mediated core driver that is related
132the physical device. 132to the physical device.
133 133
134The structures in the parent_ops structure are as follows: 134The structures in the mdev_parent_ops structure are as follows:
135 135
136* dev_attr_groups: attributes of the parent device 136* dev_attr_groups: attributes of the parent device
137* mdev_attr_groups: attributes of the mediated device 137* mdev_attr_groups: attributes of the mediated device
138* supported_config: attributes to define supported configurations 138* supported_config: attributes to define supported configurations
139 139
140The functions in the parent_ops structure are as follows: 140The functions in the mdev_parent_ops structure are as follows:
141 141
142* create: allocate basic resources in a driver for a mediated device 142* create: allocate basic resources in a driver for a mediated device
143* remove: free resources in a driver when a mediated device is destroyed 143* remove: free resources in a driver when a mediated device is destroyed
144 144
145The callbacks in the parent_ops structure are as follows: 145The callbacks in the mdev_parent_ops structure are as follows:
146 146
147* open: open callback of mediated device 147* open: open callback of mediated device
148* close: close callback of mediated device 148* close: close callback of mediated device
@@ -151,14 +151,14 @@ The callbacks in the parent_ops structure are as follows:
151* write: write emulation callback 151* write: write emulation callback
152* mmap: mmap emulation callback 152* mmap: mmap emulation callback
153 153
154A driver should use the parent_ops structure in the function call to register 154A driver should use the mdev_parent_ops structure in the function call to
155itself with the mdev core driver: 155register itself with the mdev core driver:
156 156
157extern int mdev_register_device(struct device *dev, 157extern int mdev_register_device(struct device *dev,
158 const struct parent_ops *ops); 158 const struct mdev_parent_ops *ops);
159 159
160However, the parent_ops structure is not required in the function call that a 160However, the mdev_parent_ops structure is not required in the function call
161driver should use to unregister itself with the mdev core driver: 161that a driver should use to unregister itself with the mdev core driver:
162 162
163extern void mdev_unregister_device(struct device *dev); 163extern void mdev_unregister_device(struct device *dev);
164 164
@@ -223,6 +223,9 @@ Directories and files under the sysfs for Each Physical Device
223 223
224 sprintf(buf, "%s-%s", dev_driver_string(parent->dev), group->name); 224 sprintf(buf, "%s-%s", dev_driver_string(parent->dev), group->name);
225 225
226 (or using mdev_parent_dev(mdev) to arrive at the parent device outside
227 of the core mdev code)
228
226* device_api 229* device_api
227 230
228 This attribute should show which device API is being created, for example, 231 This attribute should show which device API is being created, for example,
@@ -394,5 +397,5 @@ References
394 397
395[1] See Documentation/vfio.txt for more information on VFIO. 398[1] See Documentation/vfio.txt for more information on VFIO.
396[2] struct mdev_driver in include/linux/mdev.h 399[2] struct mdev_driver in include/linux/mdev.h
397[3] struct parent_ops in include/linux/mdev.h 400[3] struct mdev_parent_ops in include/linux/mdev.h
398[4] struct vfio_iommu_driver_ops in include/linux/vfio.h 401[4] struct vfio_iommu_driver_ops in include/linux/vfio.h
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 934963970288..faaae07ae487 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -169,7 +169,7 @@ static void __gvt_cache_remove_entry(struct intel_vgpu *vgpu,
169 169
170static void gvt_cache_remove(struct intel_vgpu *vgpu, gfn_t gfn) 170static void gvt_cache_remove(struct intel_vgpu *vgpu, gfn_t gfn)
171{ 171{
172 struct device *dev = &vgpu->vdev.mdev->dev; 172 struct device *dev = mdev_dev(vgpu->vdev.mdev);
173 struct gvt_dma *this; 173 struct gvt_dma *this;
174 unsigned long g1; 174 unsigned long g1;
175 int rc; 175 int rc;
@@ -198,7 +198,7 @@ static void gvt_cache_destroy(struct intel_vgpu *vgpu)
198{ 198{
199 struct gvt_dma *dma; 199 struct gvt_dma *dma;
200 struct rb_node *node = NULL; 200 struct rb_node *node = NULL;
201 struct device *dev = &vgpu->vdev.mdev->dev; 201 struct device *dev = mdev_dev(vgpu->vdev.mdev);
202 unsigned long gfn; 202 unsigned long gfn;
203 203
204 mutex_lock(&vgpu->vdev.cache_lock); 204 mutex_lock(&vgpu->vdev.cache_lock);
@@ -399,7 +399,7 @@ static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev)
399 struct device *pdev; 399 struct device *pdev;
400 void *gvt; 400 void *gvt;
401 401
402 pdev = mdev->parent->dev; 402 pdev = mdev_parent_dev(mdev);
403 gvt = kdev_to_i915(pdev)->gvt; 403 gvt = kdev_to_i915(pdev)->gvt;
404 404
405 type = intel_gvt_find_vgpu_type(gvt, kobject_name(kobj)); 405 type = intel_gvt_find_vgpu_type(gvt, kobject_name(kobj));
@@ -421,7 +421,7 @@ static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev)
421 mdev_set_drvdata(mdev, vgpu); 421 mdev_set_drvdata(mdev, vgpu);
422 422
423 gvt_dbg_core("intel_vgpu_create succeeded for mdev: %s\n", 423 gvt_dbg_core("intel_vgpu_create succeeded for mdev: %s\n",
424 dev_name(&mdev->dev)); 424 dev_name(mdev_dev(mdev)));
425 return 0; 425 return 0;
426} 426}
427 427
@@ -485,7 +485,7 @@ static int intel_vgpu_open(struct mdev_device *mdev)
485 vgpu->vdev.group_notifier.notifier_call = intel_vgpu_group_notifier; 485 vgpu->vdev.group_notifier.notifier_call = intel_vgpu_group_notifier;
486 486
487 events = VFIO_IOMMU_NOTIFY_DMA_UNMAP; 487 events = VFIO_IOMMU_NOTIFY_DMA_UNMAP;
488 ret = vfio_register_notifier(&mdev->dev, VFIO_IOMMU_NOTIFY, &events, 488 ret = vfio_register_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY, &events,
489 &vgpu->vdev.iommu_notifier); 489 &vgpu->vdev.iommu_notifier);
490 if (ret != 0) { 490 if (ret != 0) {
491 gvt_err("vfio_register_notifier for iommu failed: %d\n", ret); 491 gvt_err("vfio_register_notifier for iommu failed: %d\n", ret);
@@ -493,7 +493,7 @@ static int intel_vgpu_open(struct mdev_device *mdev)
493 } 493 }
494 494
495 events = VFIO_GROUP_NOTIFY_SET_KVM; 495 events = VFIO_GROUP_NOTIFY_SET_KVM;
496 ret = vfio_register_notifier(&mdev->dev, VFIO_GROUP_NOTIFY, &events, 496 ret = vfio_register_notifier(mdev_dev(mdev), VFIO_GROUP_NOTIFY, &events,
497 &vgpu->vdev.group_notifier); 497 &vgpu->vdev.group_notifier);
498 if (ret != 0) { 498 if (ret != 0) {
499 gvt_err("vfio_register_notifier for group failed: %d\n", ret); 499 gvt_err("vfio_register_notifier for group failed: %d\n", ret);
@@ -508,11 +508,11 @@ static int intel_vgpu_open(struct mdev_device *mdev)
508 return ret; 508 return ret;
509 509
510undo_group: 510undo_group:
511 vfio_unregister_notifier(&mdev->dev, VFIO_GROUP_NOTIFY, 511 vfio_unregister_notifier(mdev_dev(mdev), VFIO_GROUP_NOTIFY,
512 &vgpu->vdev.group_notifier); 512 &vgpu->vdev.group_notifier);
513 513
514undo_iommu: 514undo_iommu:
515 vfio_unregister_notifier(&mdev->dev, VFIO_IOMMU_NOTIFY, 515 vfio_unregister_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY,
516 &vgpu->vdev.iommu_notifier); 516 &vgpu->vdev.iommu_notifier);
517out: 517out:
518 return ret; 518 return ret;
@@ -529,11 +529,11 @@ static void __intel_vgpu_release(struct intel_vgpu *vgpu)
529 if (atomic_cmpxchg(&vgpu->vdev.released, 0, 1)) 529 if (atomic_cmpxchg(&vgpu->vdev.released, 0, 1))
530 return; 530 return;
531 531
532 ret = vfio_unregister_notifier(&vgpu->vdev.mdev->dev, VFIO_IOMMU_NOTIFY, 532 ret = vfio_unregister_notifier(mdev_dev(vgpu->vdev.mdev), VFIO_IOMMU_NOTIFY,
533 &vgpu->vdev.iommu_notifier); 533 &vgpu->vdev.iommu_notifier);
534 WARN(ret, "vfio_unregister_notifier for iommu failed: %d\n", ret); 534 WARN(ret, "vfio_unregister_notifier for iommu failed: %d\n", ret);
535 535
536 ret = vfio_unregister_notifier(&vgpu->vdev.mdev->dev, VFIO_GROUP_NOTIFY, 536 ret = vfio_unregister_notifier(mdev_dev(vgpu->vdev.mdev), VFIO_GROUP_NOTIFY,
537 &vgpu->vdev.group_notifier); 537 &vgpu->vdev.group_notifier);
538 WARN(ret, "vfio_unregister_notifier for group failed: %d\n", ret); 538 WARN(ret, "vfio_unregister_notifier for group failed: %d\n", ret);
539 539
@@ -1111,7 +1111,7 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd,
1111 return 0; 1111 return 0;
1112} 1112}
1113 1113
1114static const struct parent_ops intel_vgpu_ops = { 1114static const struct mdev_parent_ops intel_vgpu_ops = {
1115 .supported_type_groups = intel_vgpu_type_groups, 1115 .supported_type_groups = intel_vgpu_type_groups,
1116 .create = intel_vgpu_create, 1116 .create = intel_vgpu_create,
1117 .remove = intel_vgpu_remove, 1117 .remove = intel_vgpu_remove,
@@ -1398,7 +1398,7 @@ static unsigned long kvmgt_gfn_to_pfn(unsigned long handle, unsigned long gfn)
1398 return pfn; 1398 return pfn;
1399 1399
1400 pfn = INTEL_GVT_INVALID_ADDR; 1400 pfn = INTEL_GVT_INVALID_ADDR;
1401 dev = &info->vgpu->vdev.mdev->dev; 1401 dev = mdev_dev(info->vgpu->vdev.mdev);
1402 rc = vfio_pin_pages(dev, &gfn, 1, IOMMU_READ | IOMMU_WRITE, &pfn); 1402 rc = vfio_pin_pages(dev, &gfn, 1, IOMMU_READ | IOMMU_WRITE, &pfn);
1403 if (rc != 1) { 1403 if (rc != 1) {
1404 gvt_err("vfio_pin_pages failed for gfn 0x%lx: %d\n", gfn, rc); 1404 gvt_err("vfio_pin_pages failed for gfn 0x%lx: %d\n", gfn, rc);
diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c
index be1ee89ee917..36d75c367d22 100644
--- a/drivers/vfio/mdev/mdev_core.c
+++ b/drivers/vfio/mdev/mdev_core.c
@@ -27,6 +27,45 @@ static LIST_HEAD(parent_list);
27static DEFINE_MUTEX(parent_list_lock); 27static DEFINE_MUTEX(parent_list_lock);
28static struct class_compat *mdev_bus_compat_class; 28static struct class_compat *mdev_bus_compat_class;
29 29
30static LIST_HEAD(mdev_list);
31static DEFINE_MUTEX(mdev_list_lock);
32
33struct device *mdev_parent_dev(struct mdev_device *mdev)
34{
35 return mdev->parent->dev;
36}
37EXPORT_SYMBOL(mdev_parent_dev);
38
39void *mdev_get_drvdata(struct mdev_device *mdev)
40{
41 return mdev->driver_data;
42}
43EXPORT_SYMBOL(mdev_get_drvdata);
44
45void mdev_set_drvdata(struct mdev_device *mdev, void *data)
46{
47 mdev->driver_data = data;
48}
49EXPORT_SYMBOL(mdev_set_drvdata);
50
51struct device *mdev_dev(struct mdev_device *mdev)
52{
53 return &mdev->dev;
54}
55EXPORT_SYMBOL(mdev_dev);
56
57struct mdev_device *mdev_from_dev(struct device *dev)
58{
59 return dev_is_mdev(dev) ? to_mdev_device(dev) : NULL;
60}
61EXPORT_SYMBOL(mdev_from_dev);
62
63uuid_le mdev_uuid(struct mdev_device *mdev)
64{
65 return mdev->uuid;
66}
67EXPORT_SYMBOL(mdev_uuid);
68
30static int _find_mdev_device(struct device *dev, void *data) 69static int _find_mdev_device(struct device *dev, void *data)
31{ 70{
32 struct mdev_device *mdev; 71 struct mdev_device *mdev;
@@ -42,7 +81,7 @@ static int _find_mdev_device(struct device *dev, void *data)
42 return 0; 81 return 0;
43} 82}
44 83
45static bool mdev_device_exist(struct parent_device *parent, uuid_le uuid) 84static bool mdev_device_exist(struct mdev_parent *parent, uuid_le uuid)
46{ 85{
47 struct device *dev; 86 struct device *dev;
48 87
@@ -56,9 +95,9 @@ static bool mdev_device_exist(struct parent_device *parent, uuid_le uuid)
56} 95}
57 96
58/* Should be called holding parent_list_lock */ 97/* Should be called holding parent_list_lock */
59static struct parent_device *__find_parent_device(struct device *dev) 98static struct mdev_parent *__find_parent_device(struct device *dev)
60{ 99{
61 struct parent_device *parent; 100 struct mdev_parent *parent;
62 101
63 list_for_each_entry(parent, &parent_list, next) { 102 list_for_each_entry(parent, &parent_list, next) {
64 if (parent->dev == dev) 103 if (parent->dev == dev)
@@ -69,8 +108,8 @@ static struct parent_device *__find_parent_device(struct device *dev)
69 108
70static void mdev_release_parent(struct kref *kref) 109static void mdev_release_parent(struct kref *kref)
71{ 110{
72 struct parent_device *parent = container_of(kref, struct parent_device, 111 struct mdev_parent *parent = container_of(kref, struct mdev_parent,
73 ref); 112 ref);
74 struct device *dev = parent->dev; 113 struct device *dev = parent->dev;
75 114
76 kfree(parent); 115 kfree(parent);
@@ -78,7 +117,7 @@ static void mdev_release_parent(struct kref *kref)
78} 117}
79 118
80static 119static
81inline struct parent_device *mdev_get_parent(struct parent_device *parent) 120inline struct mdev_parent *mdev_get_parent(struct mdev_parent *parent)
82{ 121{
83 if (parent) 122 if (parent)
84 kref_get(&parent->ref); 123 kref_get(&parent->ref);
@@ -86,7 +125,7 @@ inline struct parent_device *mdev_get_parent(struct parent_device *parent)
86 return parent; 125 return parent;
87} 126}
88 127
89static inline void mdev_put_parent(struct parent_device *parent) 128static inline void mdev_put_parent(struct mdev_parent *parent)
90{ 129{
91 if (parent) 130 if (parent)
92 kref_put(&parent->ref, mdev_release_parent); 131 kref_put(&parent->ref, mdev_release_parent);
@@ -95,7 +134,7 @@ static inline void mdev_put_parent(struct parent_device *parent)
95static int mdev_device_create_ops(struct kobject *kobj, 134static int mdev_device_create_ops(struct kobject *kobj,
96 struct mdev_device *mdev) 135 struct mdev_device *mdev)
97{ 136{
98 struct parent_device *parent = mdev->parent; 137 struct mdev_parent *parent = mdev->parent;
99 int ret; 138 int ret;
100 139
101 ret = parent->ops->create(kobj, mdev); 140 ret = parent->ops->create(kobj, mdev);
@@ -122,7 +161,7 @@ static int mdev_device_create_ops(struct kobject *kobj,
122 */ 161 */
123static int mdev_device_remove_ops(struct mdev_device *mdev, bool force_remove) 162static int mdev_device_remove_ops(struct mdev_device *mdev, bool force_remove)
124{ 163{
125 struct parent_device *parent = mdev->parent; 164 struct mdev_parent *parent = mdev->parent;
126 int ret; 165 int ret;
127 166
128 /* 167 /*
@@ -153,10 +192,10 @@ static int mdev_device_remove_cb(struct device *dev, void *data)
153 * Add device to list of registered parent devices. 192 * Add device to list of registered parent devices.
154 * Returns a negative value on error, otherwise 0. 193 * Returns a negative value on error, otherwise 0.
155 */ 194 */
156int mdev_register_device(struct device *dev, const struct parent_ops *ops) 195int mdev_register_device(struct device *dev, const struct mdev_parent_ops *ops)
157{ 196{
158 int ret; 197 int ret;
159 struct parent_device *parent; 198 struct mdev_parent *parent;
160 199
161 /* check for mandatory ops */ 200 /* check for mandatory ops */
162 if (!ops || !ops->create || !ops->remove || !ops->supported_type_groups) 201 if (!ops || !ops->create || !ops->remove || !ops->supported_type_groups)
@@ -229,7 +268,7 @@ EXPORT_SYMBOL(mdev_register_device);
229 268
230void mdev_unregister_device(struct device *dev) 269void mdev_unregister_device(struct device *dev)
231{ 270{
232 struct parent_device *parent; 271 struct mdev_parent *parent;
233 bool force_remove = true; 272 bool force_remove = true;
234 273
235 mutex_lock(&parent_list_lock); 274 mutex_lock(&parent_list_lock);
@@ -266,7 +305,7 @@ int mdev_device_create(struct kobject *kobj, struct device *dev, uuid_le uuid)
266{ 305{
267 int ret; 306 int ret;
268 struct mdev_device *mdev; 307 struct mdev_device *mdev;
269 struct parent_device *parent; 308 struct mdev_parent *parent;
270 struct mdev_type *type = to_mdev_type(kobj); 309 struct mdev_type *type = to_mdev_type(kobj);
271 310
272 parent = mdev_get_parent(type->parent); 311 parent = mdev_get_parent(type->parent);
@@ -316,6 +355,11 @@ int mdev_device_create(struct kobject *kobj, struct device *dev, uuid_le uuid)
316 dev_dbg(&mdev->dev, "MDEV: created\n"); 355 dev_dbg(&mdev->dev, "MDEV: created\n");
317 356
318 mutex_unlock(&parent->lock); 357 mutex_unlock(&parent->lock);
358
359 mutex_lock(&mdev_list_lock);
360 list_add(&mdev->next, &mdev_list);
361 mutex_unlock(&mdev_list_lock);
362
319 return ret; 363 return ret;
320 364
321create_failed: 365create_failed:
@@ -329,12 +373,30 @@ create_err:
329 373
330int mdev_device_remove(struct device *dev, bool force_remove) 374int mdev_device_remove(struct device *dev, bool force_remove)
331{ 375{
332 struct mdev_device *mdev; 376 struct mdev_device *mdev, *tmp;
333 struct parent_device *parent; 377 struct mdev_parent *parent;
334 struct mdev_type *type; 378 struct mdev_type *type;
335 int ret; 379 int ret;
380 bool found = false;
336 381
337 mdev = to_mdev_device(dev); 382 mdev = to_mdev_device(dev);
383
384 mutex_lock(&mdev_list_lock);
385 list_for_each_entry(tmp, &mdev_list, next) {
386 if (tmp == mdev) {
387 found = true;
388 break;
389 }
390 }
391
392 if (found)
393 list_del(&mdev->next);
394
395 mutex_unlock(&mdev_list_lock);
396
397 if (!found)
398 return -ENODEV;
399
338 type = to_mdev_type(mdev->type_kobj); 400 type = to_mdev_type(mdev->type_kobj);
339 parent = mdev->parent; 401 parent = mdev->parent;
340 mutex_lock(&parent->lock); 402 mutex_lock(&parent->lock);
@@ -342,6 +404,11 @@ int mdev_device_remove(struct device *dev, bool force_remove)
342 ret = mdev_device_remove_ops(mdev, force_remove); 404 ret = mdev_device_remove_ops(mdev, force_remove);
343 if (ret) { 405 if (ret) {
344 mutex_unlock(&parent->lock); 406 mutex_unlock(&parent->lock);
407
408 mutex_lock(&mdev_list_lock);
409 list_add(&mdev->next, &mdev_list);
410 mutex_unlock(&mdev_list_lock);
411
345 return ret; 412 return ret;
346 } 413 }
347 414
@@ -349,7 +416,8 @@ int mdev_device_remove(struct device *dev, bool force_remove)
349 device_unregister(dev); 416 device_unregister(dev);
350 mutex_unlock(&parent->lock); 417 mutex_unlock(&parent->lock);
351 mdev_put_parent(parent); 418 mdev_put_parent(parent);
352 return ret; 419
420 return 0;
353} 421}
354 422
355static int __init mdev_init(void) 423static int __init mdev_init(void)
diff --git a/drivers/vfio/mdev/mdev_private.h b/drivers/vfio/mdev/mdev_private.h
index d35097cbf3d7..a9cefd70a705 100644
--- a/drivers/vfio/mdev/mdev_private.h
+++ b/drivers/vfio/mdev/mdev_private.h
@@ -16,10 +16,33 @@
16int mdev_bus_register(void); 16int mdev_bus_register(void);
17void mdev_bus_unregister(void); 17void mdev_bus_unregister(void);
18 18
19struct mdev_parent {
20 struct device *dev;
21 const struct mdev_parent_ops *ops;
22 struct kref ref;
23 struct mutex lock;
24 struct list_head next;
25 struct kset *mdev_types_kset;
26 struct list_head type_list;
27};
28
29struct mdev_device {
30 struct device dev;
31 struct mdev_parent *parent;
32 uuid_le uuid;
33 void *driver_data;
34 struct kref ref;
35 struct list_head next;
36 struct kobject *type_kobj;
37};
38
39#define to_mdev_device(dev) container_of(dev, struct mdev_device, dev)
40#define dev_is_mdev(d) ((d)->bus == &mdev_bus_type)
41
19struct mdev_type { 42struct mdev_type {
20 struct kobject kobj; 43 struct kobject kobj;
21 struct kobject *devices_kobj; 44 struct kobject *devices_kobj;
22 struct parent_device *parent; 45 struct mdev_parent *parent;
23 struct list_head next; 46 struct list_head next;
24 struct attribute_group *group; 47 struct attribute_group *group;
25}; 48};
@@ -29,8 +52,8 @@ struct mdev_type {
29#define to_mdev_type(_kobj) \ 52#define to_mdev_type(_kobj) \
30 container_of(_kobj, struct mdev_type, kobj) 53 container_of(_kobj, struct mdev_type, kobj)
31 54
32int parent_create_sysfs_files(struct parent_device *parent); 55int parent_create_sysfs_files(struct mdev_parent *parent);
33void parent_remove_sysfs_files(struct parent_device *parent); 56void parent_remove_sysfs_files(struct mdev_parent *parent);
34 57
35int mdev_create_sysfs_files(struct device *dev, struct mdev_type *type); 58int mdev_create_sysfs_files(struct device *dev, struct mdev_type *type);
36void mdev_remove_sysfs_files(struct device *dev, struct mdev_type *type); 59void mdev_remove_sysfs_files(struct device *dev, struct mdev_type *type);
diff --git a/drivers/vfio/mdev/mdev_sysfs.c b/drivers/vfio/mdev/mdev_sysfs.c
index 1a53deb2ee10..802df210929b 100644
--- a/drivers/vfio/mdev/mdev_sysfs.c
+++ b/drivers/vfio/mdev/mdev_sysfs.c
@@ -92,7 +92,7 @@ static struct kobj_type mdev_type_ktype = {
92 .release = mdev_type_release, 92 .release = mdev_type_release,
93}; 93};
94 94
95struct mdev_type *add_mdev_supported_type(struct parent_device *parent, 95struct mdev_type *add_mdev_supported_type(struct mdev_parent *parent,
96 struct attribute_group *group) 96 struct attribute_group *group)
97{ 97{
98 struct mdev_type *type; 98 struct mdev_type *type;
@@ -158,7 +158,7 @@ static void remove_mdev_supported_type(struct mdev_type *type)
158 kobject_put(&type->kobj); 158 kobject_put(&type->kobj);
159} 159}
160 160
161static int add_mdev_supported_type_groups(struct parent_device *parent) 161static int add_mdev_supported_type_groups(struct mdev_parent *parent)
162{ 162{
163 int i; 163 int i;
164 164
@@ -183,7 +183,7 @@ static int add_mdev_supported_type_groups(struct parent_device *parent)
183} 183}
184 184
185/* mdev sysfs functions */ 185/* mdev sysfs functions */
186void parent_remove_sysfs_files(struct parent_device *parent) 186void parent_remove_sysfs_files(struct mdev_parent *parent)
187{ 187{
188 struct mdev_type *type, *tmp; 188 struct mdev_type *type, *tmp;
189 189
@@ -196,7 +196,7 @@ void parent_remove_sysfs_files(struct parent_device *parent)
196 kset_unregister(parent->mdev_types_kset); 196 kset_unregister(parent->mdev_types_kset);
197} 197}
198 198
199int parent_create_sysfs_files(struct parent_device *parent) 199int parent_create_sysfs_files(struct mdev_parent *parent)
200{ 200{
201 int ret; 201 int ret;
202 202
diff --git a/drivers/vfio/mdev/vfio_mdev.c b/drivers/vfio/mdev/vfio_mdev.c
index ffc36758cb84..fa848a701b8b 100644
--- a/drivers/vfio/mdev/vfio_mdev.c
+++ b/drivers/vfio/mdev/vfio_mdev.c
@@ -27,7 +27,7 @@
27static int vfio_mdev_open(void *device_data) 27static int vfio_mdev_open(void *device_data)
28{ 28{
29 struct mdev_device *mdev = device_data; 29 struct mdev_device *mdev = device_data;
30 struct parent_device *parent = mdev->parent; 30 struct mdev_parent *parent = mdev->parent;
31 int ret; 31 int ret;
32 32
33 if (unlikely(!parent->ops->open)) 33 if (unlikely(!parent->ops->open))
@@ -46,7 +46,7 @@ static int vfio_mdev_open(void *device_data)
46static void vfio_mdev_release(void *device_data) 46static void vfio_mdev_release(void *device_data)
47{ 47{
48 struct mdev_device *mdev = device_data; 48 struct mdev_device *mdev = device_data;
49 struct parent_device *parent = mdev->parent; 49 struct mdev_parent *parent = mdev->parent;
50 50
51 if (likely(parent->ops->release)) 51 if (likely(parent->ops->release))
52 parent->ops->release(mdev); 52 parent->ops->release(mdev);
@@ -58,7 +58,7 @@ static long vfio_mdev_unlocked_ioctl(void *device_data,
58 unsigned int cmd, unsigned long arg) 58 unsigned int cmd, unsigned long arg)
59{ 59{
60 struct mdev_device *mdev = device_data; 60 struct mdev_device *mdev = device_data;
61 struct parent_device *parent = mdev->parent; 61 struct mdev_parent *parent = mdev->parent;
62 62
63 if (unlikely(!parent->ops->ioctl)) 63 if (unlikely(!parent->ops->ioctl))
64 return -EINVAL; 64 return -EINVAL;
@@ -70,7 +70,7 @@ static ssize_t vfio_mdev_read(void *device_data, char __user *buf,
70 size_t count, loff_t *ppos) 70 size_t count, loff_t *ppos)
71{ 71{
72 struct mdev_device *mdev = device_data; 72 struct mdev_device *mdev = device_data;
73 struct parent_device *parent = mdev->parent; 73 struct mdev_parent *parent = mdev->parent;
74 74
75 if (unlikely(!parent->ops->read)) 75 if (unlikely(!parent->ops->read))
76 return -EINVAL; 76 return -EINVAL;
@@ -82,7 +82,7 @@ static ssize_t vfio_mdev_write(void *device_data, const char __user *buf,
82 size_t count, loff_t *ppos) 82 size_t count, loff_t *ppos)
83{ 83{
84 struct mdev_device *mdev = device_data; 84 struct mdev_device *mdev = device_data;
85 struct parent_device *parent = mdev->parent; 85 struct mdev_parent *parent = mdev->parent;
86 86
87 if (unlikely(!parent->ops->write)) 87 if (unlikely(!parent->ops->write))
88 return -EINVAL; 88 return -EINVAL;
@@ -93,7 +93,7 @@ static ssize_t vfio_mdev_write(void *device_data, const char __user *buf,
93static int vfio_mdev_mmap(void *device_data, struct vm_area_struct *vma) 93static int vfio_mdev_mmap(void *device_data, struct vm_area_struct *vma)
94{ 94{
95 struct mdev_device *mdev = device_data; 95 struct mdev_device *mdev = device_data;
96 struct parent_device *parent = mdev->parent; 96 struct mdev_parent *parent = mdev->parent;
97 97
98 if (unlikely(!parent->ops->mmap)) 98 if (unlikely(!parent->ops->mmap))
99 return -EINVAL; 99 return -EINVAL;
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index dcd7c2a99618..324c52e3a1a4 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -1142,6 +1142,10 @@ static int vfio_pci_mmap(void *device_data, struct vm_area_struct *vma)
1142 return ret; 1142 return ret;
1143 1143
1144 vdev->barmap[index] = pci_iomap(pdev, index, 0); 1144 vdev->barmap[index] = pci_iomap(pdev, index, 0);
1145 if (!vdev->barmap[index]) {
1146 pci_release_selected_regions(pdev, 1 << index);
1147 return -ENOMEM;
1148 }
1145 } 1149 }
1146 1150
1147 vma->vm_private_data = vdev; 1151 vma->vm_private_data = vdev;
diff --git a/drivers/vfio/pci/vfio_pci_rdwr.c b/drivers/vfio/pci/vfio_pci_rdwr.c
index 5ffd1d9ad4bd..357243d76f10 100644
--- a/drivers/vfio/pci/vfio_pci_rdwr.c
+++ b/drivers/vfio/pci/vfio_pci_rdwr.c
@@ -193,7 +193,10 @@ ssize_t vfio_pci_vga_rw(struct vfio_pci_device *vdev, char __user *buf,
193 if (!vdev->has_vga) 193 if (!vdev->has_vga)
194 return -EINVAL; 194 return -EINVAL;
195 195
196 switch (pos) { 196 if (pos > 0xbfffful)
197 return -EINVAL;
198
199 switch ((u32)pos) {
197 case 0xa0000 ... 0xbffff: 200 case 0xa0000 ... 0xbffff:
198 count = min(count, (size_t)(0xc0000 - pos)); 201 count = min(count, (size_t)(0xc0000 - pos));
199 iomem = ioremap_nocache(0xa0000, 0xbffff - 0xa0000 + 1); 202 iomem = ioremap_nocache(0xa0000, 0xbffff - 0xa0000 + 1);
diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index f3726ba12aa6..9266271a787a 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -268,28 +268,38 @@ static void vfio_lock_acct(struct task_struct *task, long npage)
268{ 268{
269 struct vwork *vwork; 269 struct vwork *vwork;
270 struct mm_struct *mm; 270 struct mm_struct *mm;
271 bool is_current;
271 272
272 if (!npage) 273 if (!npage)
273 return; 274 return;
274 275
275 mm = get_task_mm(task); 276 is_current = (task->mm == current->mm);
277
278 mm = is_current ? task->mm : get_task_mm(task);
276 if (!mm) 279 if (!mm)
277 return; /* process exited or nothing to do */ 280 return; /* process exited */
278 281
279 if (down_write_trylock(&mm->mmap_sem)) { 282 if (down_write_trylock(&mm->mmap_sem)) {
280 mm->locked_vm += npage; 283 mm->locked_vm += npage;
281 up_write(&mm->mmap_sem); 284 up_write(&mm->mmap_sem);
282 mmput(mm); 285 if (!is_current)
286 mmput(mm);
283 return; 287 return;
284 } 288 }
285 289
290 if (is_current) {
291 mm = get_task_mm(task);
292 if (!mm)
293 return;
294 }
295
286 /* 296 /*
287 * Couldn't get mmap_sem lock, so must setup to update 297 * Couldn't get mmap_sem lock, so must setup to update
288 * mm->locked_vm later. If locked_vm were atomic, we 298 * mm->locked_vm later. If locked_vm were atomic, we
289 * wouldn't need this silliness 299 * wouldn't need this silliness
290 */ 300 */
291 vwork = kmalloc(sizeof(struct vwork), GFP_KERNEL); 301 vwork = kmalloc(sizeof(struct vwork), GFP_KERNEL);
292 if (!vwork) { 302 if (WARN_ON(!vwork)) {
293 mmput(mm); 303 mmput(mm);
294 return; 304 return;
295 } 305 }
@@ -393,77 +403,71 @@ static int vaddr_get_pfn(struct mm_struct *mm, unsigned long vaddr,
393static long vfio_pin_pages_remote(struct vfio_dma *dma, unsigned long vaddr, 403static long vfio_pin_pages_remote(struct vfio_dma *dma, unsigned long vaddr,
394 long npage, unsigned long *pfn_base) 404 long npage, unsigned long *pfn_base)
395{ 405{
396 unsigned long limit; 406 unsigned long limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
397 bool lock_cap = ns_capable(task_active_pid_ns(dma->task)->user_ns, 407 bool lock_cap = capable(CAP_IPC_LOCK);
398 CAP_IPC_LOCK); 408 long ret, pinned = 0, lock_acct = 0;
399 struct mm_struct *mm;
400 long ret, i = 0, lock_acct = 0;
401 bool rsvd; 409 bool rsvd;
402 dma_addr_t iova = vaddr - dma->vaddr + dma->iova; 410 dma_addr_t iova = vaddr - dma->vaddr + dma->iova;
403 411
404 mm = get_task_mm(dma->task); 412 /* This code path is only user initiated */
405 if (!mm) 413 if (!current->mm)
406 return -ENODEV; 414 return -ENODEV;
407 415
408 ret = vaddr_get_pfn(mm, vaddr, dma->prot, pfn_base); 416 ret = vaddr_get_pfn(current->mm, vaddr, dma->prot, pfn_base);
409 if (ret) 417 if (ret)
410 goto pin_pg_remote_exit; 418 return ret;
411 419
420 pinned++;
412 rsvd = is_invalid_reserved_pfn(*pfn_base); 421 rsvd = is_invalid_reserved_pfn(*pfn_base);
413 limit = task_rlimit(dma->task, RLIMIT_MEMLOCK) >> PAGE_SHIFT;
414 422
415 /* 423 /*
416 * Reserved pages aren't counted against the user, externally pinned 424 * Reserved pages aren't counted against the user, externally pinned
417 * pages are already counted against the user. 425 * pages are already counted against the user.
418 */ 426 */
419 if (!rsvd && !vfio_find_vpfn(dma, iova)) { 427 if (!rsvd && !vfio_find_vpfn(dma, iova)) {
420 if (!lock_cap && mm->locked_vm + 1 > limit) { 428 if (!lock_cap && current->mm->locked_vm + 1 > limit) {
421 put_pfn(*pfn_base, dma->prot); 429 put_pfn(*pfn_base, dma->prot);
422 pr_warn("%s: RLIMIT_MEMLOCK (%ld) exceeded\n", __func__, 430 pr_warn("%s: RLIMIT_MEMLOCK (%ld) exceeded\n", __func__,
423 limit << PAGE_SHIFT); 431 limit << PAGE_SHIFT);
424 ret = -ENOMEM; 432 return -ENOMEM;
425 goto pin_pg_remote_exit;
426 } 433 }
427 lock_acct++; 434 lock_acct++;
428 } 435 }
429 436
430 i++; 437 if (unlikely(disable_hugepages))
431 if (likely(!disable_hugepages)) { 438 goto out;
432 /* Lock all the consecutive pages from pfn_base */
433 for (vaddr += PAGE_SIZE, iova += PAGE_SIZE; i < npage;
434 i++, vaddr += PAGE_SIZE, iova += PAGE_SIZE) {
435 unsigned long pfn = 0;
436 439
437 ret = vaddr_get_pfn(mm, vaddr, dma->prot, &pfn); 440 /* Lock all the consecutive pages from pfn_base */
438 if (ret) 441 for (vaddr += PAGE_SIZE, iova += PAGE_SIZE; pinned < npage;
439 break; 442 pinned++, vaddr += PAGE_SIZE, iova += PAGE_SIZE) {
443 unsigned long pfn = 0;
440 444
441 if (pfn != *pfn_base + i || 445 ret = vaddr_get_pfn(current->mm, vaddr, dma->prot, &pfn);
442 rsvd != is_invalid_reserved_pfn(pfn)) { 446 if (ret)
447 break;
448
449 if (pfn != *pfn_base + pinned ||
450 rsvd != is_invalid_reserved_pfn(pfn)) {
451 put_pfn(pfn, dma->prot);
452 break;
453 }
454
455 if (!rsvd && !vfio_find_vpfn(dma, iova)) {
456 if (!lock_cap &&
457 current->mm->locked_vm + lock_acct + 1 > limit) {
443 put_pfn(pfn, dma->prot); 458 put_pfn(pfn, dma->prot);
459 pr_warn("%s: RLIMIT_MEMLOCK (%ld) exceeded\n",
460 __func__, limit << PAGE_SHIFT);
444 break; 461 break;
445 } 462 }
446 463 lock_acct++;
447 if (!rsvd && !vfio_find_vpfn(dma, iova)) {
448 if (!lock_cap &&
449 mm->locked_vm + lock_acct + 1 > limit) {
450 put_pfn(pfn, dma->prot);
451 pr_warn("%s: RLIMIT_MEMLOCK (%ld) "
452 "exceeded\n", __func__,
453 limit << PAGE_SHIFT);
454 break;
455 }
456 lock_acct++;
457 }
458 } 464 }
459 } 465 }
460 466
461 vfio_lock_acct(dma->task, lock_acct); 467out:
462 ret = i; 468 vfio_lock_acct(current, lock_acct);
463 469
464pin_pg_remote_exit: 470 return pinned;
465 mmput(mm);
466 return ret;
467} 471}
468 472
469static long vfio_unpin_pages_remote(struct vfio_dma *dma, dma_addr_t iova, 473static long vfio_unpin_pages_remote(struct vfio_dma *dma, dma_addr_t iova,
@@ -473,10 +477,10 @@ static long vfio_unpin_pages_remote(struct vfio_dma *dma, dma_addr_t iova,
473 long unlocked = 0, locked = 0; 477 long unlocked = 0, locked = 0;
474 long i; 478 long i;
475 479
476 for (i = 0; i < npage; i++) { 480 for (i = 0; i < npage; i++, iova += PAGE_SIZE) {
477 if (put_pfn(pfn++, dma->prot)) { 481 if (put_pfn(pfn++, dma->prot)) {
478 unlocked++; 482 unlocked++;
479 if (vfio_find_vpfn(dma, iova + (i << PAGE_SHIFT))) 483 if (vfio_find_vpfn(dma, iova))
480 locked++; 484 locked++;
481 } 485 }
482 } 486 }
diff --git a/include/linux/mdev.h b/include/linux/mdev.h
index ec819e9a115a..b6e048e1045f 100644
--- a/include/linux/mdev.h
+++ b/include/linux/mdev.h
@@ -13,34 +13,10 @@
13#ifndef MDEV_H 13#ifndef MDEV_H
14#define MDEV_H 14#define MDEV_H
15 15
16/* Parent device */ 16struct mdev_device;
17struct parent_device {
18 struct device *dev;
19 const struct parent_ops *ops;
20
21 /* internal */
22 struct kref ref;
23 struct mutex lock;
24 struct list_head next;
25 struct kset *mdev_types_kset;
26 struct list_head type_list;
27};
28
29/* Mediated device */
30struct mdev_device {
31 struct device dev;
32 struct parent_device *parent;
33 uuid_le uuid;
34 void *driver_data;
35
36 /* internal */
37 struct kref ref;
38 struct list_head next;
39 struct kobject *type_kobj;
40};
41 17
42/** 18/**
43 * struct parent_ops - Structure to be registered for each parent device to 19 * struct mdev_parent_ops - Structure to be registered for each parent device to
44 * register the device to mdev module. 20 * register the device to mdev module.
45 * 21 *
46 * @owner: The module owner. 22 * @owner: The module owner.
@@ -86,10 +62,9 @@ struct mdev_device {
86 * @mdev: mediated device structure 62 * @mdev: mediated device structure
87 * @vma: vma structure 63 * @vma: vma structure
88 * Parent device that support mediated device should be registered with mdev 64 * Parent device that support mediated device should be registered with mdev
89 * module with parent_ops structure. 65 * module with mdev_parent_ops structure.
90 **/ 66 **/
91 67struct mdev_parent_ops {
92struct parent_ops {
93 struct module *owner; 68 struct module *owner;
94 const struct attribute_group **dev_attr_groups; 69 const struct attribute_group **dev_attr_groups;
95 const struct attribute_group **mdev_attr_groups; 70 const struct attribute_group **mdev_attr_groups;
@@ -103,7 +78,7 @@ struct parent_ops {
103 size_t count, loff_t *ppos); 78 size_t count, loff_t *ppos);
104 ssize_t (*write)(struct mdev_device *mdev, const char __user *buf, 79 ssize_t (*write)(struct mdev_device *mdev, const char __user *buf,
105 size_t count, loff_t *ppos); 80 size_t count, loff_t *ppos);
106 ssize_t (*ioctl)(struct mdev_device *mdev, unsigned int cmd, 81 long (*ioctl)(struct mdev_device *mdev, unsigned int cmd,
107 unsigned long arg); 82 unsigned long arg);
108 int (*mmap)(struct mdev_device *mdev, struct vm_area_struct *vma); 83 int (*mmap)(struct mdev_device *mdev, struct vm_area_struct *vma);
109}; 84};
@@ -142,27 +117,22 @@ struct mdev_driver {
142}; 117};
143 118
144#define to_mdev_driver(drv) container_of(drv, struct mdev_driver, driver) 119#define to_mdev_driver(drv) container_of(drv, struct mdev_driver, driver)
145#define to_mdev_device(dev) container_of(dev, struct mdev_device, dev)
146
147static inline void *mdev_get_drvdata(struct mdev_device *mdev)
148{
149 return mdev->driver_data;
150}
151 120
152static inline void mdev_set_drvdata(struct mdev_device *mdev, void *data) 121extern void *mdev_get_drvdata(struct mdev_device *mdev);
153{ 122extern void mdev_set_drvdata(struct mdev_device *mdev, void *data);
154 mdev->driver_data = data; 123extern uuid_le mdev_uuid(struct mdev_device *mdev);
155}
156 124
157extern struct bus_type mdev_bus_type; 125extern struct bus_type mdev_bus_type;
158 126
159#define dev_is_mdev(d) ((d)->bus == &mdev_bus_type)
160
161extern int mdev_register_device(struct device *dev, 127extern int mdev_register_device(struct device *dev,
162 const struct parent_ops *ops); 128 const struct mdev_parent_ops *ops);
163extern void mdev_unregister_device(struct device *dev); 129extern void mdev_unregister_device(struct device *dev);
164 130
165extern int mdev_register_driver(struct mdev_driver *drv, struct module *owner); 131extern int mdev_register_driver(struct mdev_driver *drv, struct module *owner);
166extern void mdev_unregister_driver(struct mdev_driver *drv); 132extern void mdev_unregister_driver(struct mdev_driver *drv);
167 133
134extern struct device *mdev_parent_dev(struct mdev_device *mdev);
135extern struct device *mdev_dev(struct mdev_device *mdev);
136extern struct mdev_device *mdev_from_dev(struct device *dev);
137
168#endif /* MDEV_H */ 138#endif /* MDEV_H */
diff --git a/samples/Kconfig b/samples/Kconfig
index a6d2a43bbf2e..b124f62ed6cb 100644
--- a/samples/Kconfig
+++ b/samples/Kconfig
@@ -105,4 +105,11 @@ config SAMPLE_BLACKFIN_GPTIMERS
105 help 105 help
106 Build samples of blackfin gptimers sample module. 106 Build samples of blackfin gptimers sample module.
107 107
108config SAMPLE_VFIO_MDEV_MTTY
109 tristate "Build VFIO mtty example mediated device sample code -- loadable modules only"
110 depends on VFIO_MDEV_DEVICE && m
111 help
112 Build a virtual tty sample driver for use as a VFIO
113 mediated device
114
108endif # SAMPLES 115endif # SAMPLES
diff --git a/samples/Makefile b/samples/Makefile
index e17d66d77f09..86a137e451d9 100644
--- a/samples/Makefile
+++ b/samples/Makefile
@@ -2,4 +2,5 @@
2 2
3obj-$(CONFIG_SAMPLES) += kobject/ kprobes/ trace_events/ livepatch/ \ 3obj-$(CONFIG_SAMPLES) += kobject/ kprobes/ trace_events/ livepatch/ \
4 hw_breakpoint/ kfifo/ kdb/ hidraw/ rpmsg/ seccomp/ \ 4 hw_breakpoint/ kfifo/ kdb/ hidraw/ rpmsg/ seccomp/ \
5 configfs/ connector/ v4l/ trace_printk/ blackfin/ 5 configfs/ connector/ v4l/ trace_printk/ blackfin/ \
6 vfio-mdev/
diff --git a/samples/vfio-mdev/Makefile b/samples/vfio-mdev/Makefile
index a932edbe38eb..cbbd868a50a8 100644
--- a/samples/vfio-mdev/Makefile
+++ b/samples/vfio-mdev/Makefile
@@ -1,13 +1 @@
1# obj-$(CONFIG_SAMPLE_VFIO_MDEV_MTTY) += mtty.o
2# Makefile for mtty.c file
3#
4KERNEL_DIR:=/lib/modules/$(shell uname -r)/build
5
6obj-m:=mtty.o
7
8modules clean modules_install:
9 $(MAKE) -C $(KERNEL_DIR) SUBDIRS=$(PWD) $@
10
11default: modules
12
13module: modules
diff --git a/samples/vfio-mdev/mtty.c b/samples/vfio-mdev/mtty.c
index 6b633a4ea333..1fc57a5093a7 100644
--- a/samples/vfio-mdev/mtty.c
+++ b/samples/vfio-mdev/mtty.c
@@ -164,7 +164,7 @@ static struct mdev_state *find_mdev_state_by_uuid(uuid_le uuid)
164 struct mdev_state *mds; 164 struct mdev_state *mds;
165 165
166 list_for_each_entry(mds, &mdev_devices_list, next) { 166 list_for_each_entry(mds, &mdev_devices_list, next) {
167 if (uuid_le_cmp(mds->mdev->uuid, uuid) == 0) 167 if (uuid_le_cmp(mdev_uuid(mds->mdev), uuid) == 0)
168 return mds; 168 return mds;
169 } 169 }
170 170
@@ -341,7 +341,8 @@ static void handle_bar_write(unsigned int index, struct mdev_state *mdev_state,
341 pr_err("Serial port %d: Fifo level trigger\n", 341 pr_err("Serial port %d: Fifo level trigger\n",
342 index); 342 index);
343#endif 343#endif
344 mtty_trigger_interrupt(mdev_state->mdev->uuid); 344 mtty_trigger_interrupt(
345 mdev_uuid(mdev_state->mdev));
345 } 346 }
346 } else { 347 } else {
347#if defined(DEBUG_INTR) 348#if defined(DEBUG_INTR)
@@ -355,7 +356,8 @@ static void handle_bar_write(unsigned int index, struct mdev_state *mdev_state,
355 */ 356 */
356 if (mdev_state->s[index].uart_reg[UART_IER] & 357 if (mdev_state->s[index].uart_reg[UART_IER] &
357 UART_IER_RLSI) 358 UART_IER_RLSI)
358 mtty_trigger_interrupt(mdev_state->mdev->uuid); 359 mtty_trigger_interrupt(
360 mdev_uuid(mdev_state->mdev));
359 } 361 }
360 mutex_unlock(&mdev_state->rxtx_lock); 362 mutex_unlock(&mdev_state->rxtx_lock);
361 break; 363 break;
@@ -374,7 +376,8 @@ static void handle_bar_write(unsigned int index, struct mdev_state *mdev_state,
374 pr_err("Serial port %d: IER_THRI write\n", 376 pr_err("Serial port %d: IER_THRI write\n",
375 index); 377 index);
376#endif 378#endif
377 mtty_trigger_interrupt(mdev_state->mdev->uuid); 379 mtty_trigger_interrupt(
380 mdev_uuid(mdev_state->mdev));
378 } 381 }
379 382
380 mutex_unlock(&mdev_state->rxtx_lock); 383 mutex_unlock(&mdev_state->rxtx_lock);
@@ -445,7 +448,7 @@ static void handle_bar_write(unsigned int index, struct mdev_state *mdev_state,
445#if defined(DEBUG_INTR) 448#if defined(DEBUG_INTR)
446 pr_err("Serial port %d: MCR_OUT2 write\n", index); 449 pr_err("Serial port %d: MCR_OUT2 write\n", index);
447#endif 450#endif
448 mtty_trigger_interrupt(mdev_state->mdev->uuid); 451 mtty_trigger_interrupt(mdev_uuid(mdev_state->mdev));
449 } 452 }
450 453
451 if ((mdev_state->s[index].uart_reg[UART_IER] & UART_IER_MSI) && 454 if ((mdev_state->s[index].uart_reg[UART_IER] & UART_IER_MSI) &&
@@ -453,7 +456,7 @@ static void handle_bar_write(unsigned int index, struct mdev_state *mdev_state,
453#if defined(DEBUG_INTR) 456#if defined(DEBUG_INTR)
454 pr_err("Serial port %d: MCR RTS/DTR write\n", index); 457 pr_err("Serial port %d: MCR RTS/DTR write\n", index);
455#endif 458#endif
456 mtty_trigger_interrupt(mdev_state->mdev->uuid); 459 mtty_trigger_interrupt(mdev_uuid(mdev_state->mdev));
457 } 460 }
458 break; 461 break;
459 462
@@ -504,7 +507,8 @@ static void handle_bar_read(unsigned int index, struct mdev_state *mdev_state,
504#endif 507#endif
505 if (mdev_state->s[index].uart_reg[UART_IER] & 508 if (mdev_state->s[index].uart_reg[UART_IER] &
506 UART_IER_THRI) 509 UART_IER_THRI)
507 mtty_trigger_interrupt(mdev_state->mdev->uuid); 510 mtty_trigger_interrupt(
511 mdev_uuid(mdev_state->mdev));
508 } 512 }
509 mutex_unlock(&mdev_state->rxtx_lock); 513 mutex_unlock(&mdev_state->rxtx_lock);
510 514
@@ -734,7 +738,7 @@ int mtty_create(struct kobject *kobj, struct mdev_device *mdev)
734 738
735 for (i = 0; i < 2; i++) { 739 for (i = 0; i < 2; i++) {
736 snprintf(name, MTTY_STRING_LEN, "%s-%d", 740 snprintf(name, MTTY_STRING_LEN, "%s-%d",
737 dev_driver_string(mdev->parent->dev), i + 1); 741 dev_driver_string(mdev_parent_dev(mdev)), i + 1);
738 if (!strcmp(kobj->name, name)) { 742 if (!strcmp(kobj->name, name)) {
739 nr_ports = i + 1; 743 nr_ports = i + 1;
740 break; 744 break;
@@ -1298,10 +1302,8 @@ static ssize_t
1298sample_mdev_dev_show(struct device *dev, struct device_attribute *attr, 1302sample_mdev_dev_show(struct device *dev, struct device_attribute *attr,
1299 char *buf) 1303 char *buf)
1300{ 1304{
1301 struct mdev_device *mdev = to_mdev_device(dev); 1305 if (mdev_from_dev(dev))
1302 1306 return sprintf(buf, "This is MDEV %s\n", dev_name(dev));
1303 if (mdev)
1304 return sprintf(buf, "This is MDEV %s\n", dev_name(&mdev->dev));
1305 1307
1306 return sprintf(buf, "\n"); 1308 return sprintf(buf, "\n");
1307} 1309}
@@ -1402,7 +1404,7 @@ struct attribute_group *mdev_type_groups[] = {
1402 NULL, 1404 NULL,
1403}; 1405};
1404 1406
1405struct parent_ops mdev_fops = { 1407struct mdev_parent_ops mdev_fops = {
1406 .owner = THIS_MODULE, 1408 .owner = THIS_MODULE,
1407 .dev_attr_groups = mtty_dev_groups, 1409 .dev_attr_groups = mtty_dev_groups,
1408 .mdev_attr_groups = mdev_dev_groups, 1410 .mdev_attr_groups = mdev_dev_groups,
@@ -1447,6 +1449,7 @@ static int __init mtty_dev_init(void)
1447 1449
1448 if (IS_ERR(mtty_dev.vd_class)) { 1450 if (IS_ERR(mtty_dev.vd_class)) {
1449 pr_err("Error: failed to register mtty_dev class\n"); 1451 pr_err("Error: failed to register mtty_dev class\n");
1452 ret = PTR_ERR(mtty_dev.vd_class);
1450 goto failed1; 1453 goto failed1;
1451 } 1454 }
1452 1455
@@ -1458,7 +1461,8 @@ static int __init mtty_dev_init(void)
1458 if (ret) 1461 if (ret)
1459 goto failed2; 1462 goto failed2;
1460 1463
1461 if (mdev_register_device(&mtty_dev.dev, &mdev_fops) != 0) 1464 ret = mdev_register_device(&mtty_dev.dev, &mdev_fops);
1465 if (ret)
1462 goto failed3; 1466 goto failed3;
1463 1467
1464 mutex_init(&mdev_list_lock); 1468 mutex_init(&mdev_list_lock);