History

vfio/mdev: simplify mdev_type handling

Instead of abusing struct attribute_group to control initialization of struct mdev_type, just define the actual attributes in the mdev_driver, allocate the mdev_type structures in the caller and pass them to mdev_register_parent. This allows the caller to use container_of to get at the containing structure and thus significantly simplify the code.

Christoph Hellwig committed 4 years ago

Commit da44c341 parent 89345d517 files · +165 −326Browse files

Unified · Split

17 files
  1. Documentation/driver-api/vfio-mediated-device.rst +1 −1
  2. drivers/gpu/drm/i915/gvt/gvt.h +2 −1
  3. drivers/gpu/drm/i915/gvt/kvmgt.c +14 −88
  4. drivers/gpu/drm/i915/gvt/vgpu.c +12 −1
  5. drivers/s390/cio/vfio_ccw_drv.c +4 −2
  6. drivers/s390/cio/vfio_ccw_ops.c +2 −12
  7. drivers/s390/cio/vfio_ccw_private.h +2 −0
  8. drivers/s390/crypto/vfio_ap_ops.c +6 −13
  9. drivers/s390/crypto/vfio_ap_private.h +2 −0
  10. drivers/vfio/mdev/mdev_core.c +6 −25
  11. drivers/vfio/mdev/mdev_driver.c +2 −3
  12. drivers/vfio/mdev/mdev_private.h +0 −8
  13. drivers/vfio/mdev/mdev_sysfs.c +22 −69
  14. include/linux/mdev.h +18 −8
  15. samples/vfio-mdev/mbochs.c +23 −34
  16. samples/vfio-mdev/mdpy.c +19 −31
  17. samples/vfio-mdev/mtty.c +30 −30
Documentation/driver-api/vfio-mediated-device.rst+1−1
@@ -103,7 +103,7 @@ structure to represent a mediated device's driver:: · 102 unmodified lines
103103 struct mdev_driver {
104104 int (*probe) (struct mdev_device *dev);
105105 void (*remove) (struct mdev_device *dev);
106− struct attribute_group **supported_type_groups;
106+ const struct attribute * const *types_attrs;
107107 struct device_driver driver;
108108 };
109109
drivers/gpu/drm/i915/gvt/gvt.h+2−1
@@ -310,8 +310,8 @@ struct intel_vgpu_config { · 309 unmodified lines
310310 const char *name;
311311 };
312312
313−#define NR_MAX_INTEL_VGPU_TYPES 20
314313 struct intel_vgpu_type {
314+ struct mdev_type type;
315315 char name[16];
316316 const struct intel_vgpu_config *conf;
317317 unsigned int avail_instance;
@@ -339,6 +339,7 @@ struct intel_gvt { · 21 unmodified lines
339339 struct notifier_block shadow_ctx_notifier_block[I915_NUM_ENGINES];
340340 DECLARE_HASHTABLE(cmd_table, GVT_CMD_HASH_BITS);
341341 struct mdev_parent parent;
342+ struct mdev_type **mdev_types;
342343 struct intel_vgpu_type *types;
343344 unsigned int num_types;
344345 struct intel_vgpu *idle_vgpu;
drivers/gpu/drm/i915/gvt/kvmgt.c+14−88
@@ -117,17 +117,10 @@ static ssize_t available_instances_show(struct mdev_type *mtype, · 116 unmodified lines
117117 struct mdev_type_attribute *attr,
118118 char *buf)
119119 {
120− struct intel_vgpu_type *type;
121− unsigned int num = 0;
122− struct intel_gvt *gvt = kdev_to_i915(mtype_get_parent_dev(mtype))->gvt;
120+ struct intel_vgpu_type *type =
121+ container_of(mtype, struct intel_vgpu_type, type);
123122
124− type = &gvt->types[mtype_get_type_group_id(mtype)];
125− if (!type)
126− num = 0;
127− else
128− num = type->avail_instance;
129−
130− return sprintf(buf, "%u\n", num);
123+ return sprintf(buf, "%u\n", type->avail_instance);
131124 }
132125
133126 static ssize_t device_api_show(struct mdev_type *mtype,
@@ -139,12 +132,8 @@ static ssize_t device_api_show(struct mdev_type *mtype, · 5 unmodified lines
139132 static ssize_t description_show(struct mdev_type *mtype,
140133 struct mdev_type_attribute *attr, char *buf)
141134 {
142− struct intel_vgpu_type *type;
143− struct intel_gvt *gvt = kdev_to_i915(mtype_get_parent_dev(mtype))->gvt;
144−
145− type = &gvt->types[mtype_get_type_group_id(mtype)];
146− if (!type)
147− return 0;
135+ struct intel_vgpu_type *type =
136+ container_of(mtype, struct intel_vgpu_type, type);
148137
149138 return sprintf(buf, "low_gm_size: %dMB\nhigh_gm_size: %dMB\n"
150139 "fence: %d\nresolution: %s\n"
@@ -158,14 +147,7 @@ static ssize_t description_show(struct mdev_type *mtype, · 7 unmodified lines
158147 static ssize_t name_show(struct mdev_type *mtype,
159148 struct mdev_type_attribute *attr, char *buf)
160149 {
161− struct intel_vgpu_type *type;
162− struct intel_gvt *gvt = kdev_to_i915(mtype_get_parent_dev(mtype))->gvt;
163−
164− type = &gvt->types[mtype_get_type_group_id(mtype)];
165− if (!type)
166− return 0;
167−
168− return sprintf(buf, "%s\n", type->name);
150+ return sprintf(buf, "%s\n", mtype->sysfs_name);
169151 }
170152
171153 static MDEV_TYPE_ATTR_RO(available_instances);
@@ -173,7 +155,7 @@ static MDEV_TYPE_ATTR_RO(device_api); · 1 unmodified line
173155 static MDEV_TYPE_ATTR_RO(description);
174156 static MDEV_TYPE_ATTR_RO(name);
175157
176−static struct attribute *gvt_type_attrs[] = {
158+static const struct attribute *gvt_type_attrs[] = {
177159 &mdev_type_attr_available_instances.attr,
178160 &mdev_type_attr_device_api.attr,
179161 &mdev_type_attr_description.attr,
@@ -181,51 +163,6 @@ static struct attribute *gvt_type_attrs[] = { · 1 unmodified line
181163 NULL,
182164 };
183165
184−static struct attribute_group *gvt_vgpu_type_groups[] = {
185− [0 ... NR_MAX_INTEL_VGPU_TYPES - 1] = NULL,
186−};
187−
188−static int intel_gvt_init_vgpu_type_groups(struct intel_gvt *gvt)
189−{
190− int i, j;
191− struct intel_vgpu_type *type;
192− struct attribute_group *group;
193−
194− for (i = 0; i < gvt->num_types; i++) {
195− type = &gvt->types[i];
196−
197− group = kzalloc(sizeof(struct attribute_group), GFP_KERNEL);
198− if (!group)
199− goto unwind;
200−
201− group->name = type->name;
202− group->attrs = gvt_type_attrs;
203− gvt_vgpu_type_groups[i] = group;
204− }
205−
206− return 0;
207−
208−unwind:
209− for (j = 0; j < i; j++) {
210− group = gvt_vgpu_type_groups[j];
211− kfree(group);
212− }
213−
214− return -ENOMEM;
215−}
216−
217−static void intel_gvt_cleanup_vgpu_type_groups(struct intel_gvt *gvt)
218−{
219− int i;
220− struct attribute_group *group;
221−
222− for (i = 0; i < gvt->num_types; i++) {
223− group = gvt_vgpu_type_groups[i];
224− gvt_vgpu_type_groups[i] = NULL;
225− kfree(group);
226− }
227−}
228−
229166 static void gvt_unpin_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
230167 unsigned long size)
231168 {
@@ -1547,16 +1484,11 @@ static const struct attribute_group *intel_vgpu_groups[] = { · 1315 unmodified lines
15471484 static int intel_vgpu_init_dev(struct vfio_device *vfio_dev)
15481485 {
15491486 struct mdev_device *mdev = to_mdev_device(vfio_dev->dev);
1550− struct device *pdev = mdev_parent_dev(mdev);
1551− struct intel_gvt *gvt = kdev_to_i915(pdev)->gvt;
1552− struct intel_vgpu_type *type;
15531487 struct intel_vgpu *vgpu = vfio_dev_to_vgpu(vfio_dev);
1488+ struct intel_vgpu_type *type =
1489+ container_of(mdev->type, struct intel_vgpu_type, type);
15541490
1555− type = &gvt->types[mdev_get_type_group_id(mdev)];
1556− if (!type)
1557− return -EINVAL;
1558−
1559− vgpu->gvt = gvt;
1491+ vgpu->gvt = kdev_to_i915(mdev_parent_dev(mdev))->gvt;
15601492 return intel_gvt_create_vgpu(vgpu, type->conf);
15611493 }
15621494
@@ -1625,7 +1557,7 @@ static struct mdev_driver intel_vgpu_mdev_driver = { · 62 unmodified lines
16251557 },
16261558 .probe = intel_vgpu_probe,
16271559 .remove = intel_vgpu_remove,
1628− .supported_type_groups = gvt_vgpu_type_groups,
1560+ .types_attrs = gvt_type_attrs,
16291561 };
16301562
16311563 int intel_gvt_page_track_add(struct intel_vgpu *info, u64 gfn)
@@ -1924,7 +1856,6 @@ static void intel_gvt_clean_device(struct drm_i915_private *i915) · 292 unmodified lines
19241856 return;
19251857
19261858 mdev_unregister_parent(&gvt->parent);
1927− intel_gvt_cleanup_vgpu_type_groups(gvt);
19281859 intel_gvt_destroy_idle_vgpu(gvt->idle_vgpu);
19291860 intel_gvt_clean_vgpu_types(gvt);
19301861
@@ -2024,20 +1955,15 @@ static int intel_gvt_init_device(struct drm_i915_private *i915) · 93 unmodified lines
20241955
20251956 intel_gvt_debugfs_init(gvt);
20261957
2027− ret = intel_gvt_init_vgpu_type_groups(gvt);
2028− if (ret)
2029− goto out_destroy_idle_vgpu;
2030−
20311958 ret = mdev_register_parent(&gvt->parent, i915->drm.dev,
2032− &intel_vgpu_mdev_driver);
1959+ &intel_vgpu_mdev_driver,
1960+ gvt->mdev_types, gvt->num_types);
20331961 if (ret)
2034− goto out_cleanup_vgpu_type_groups;
1962+ goto out_destroy_idle_vgpu;
20351963
20361964 gvt_dbg_core("gvt device initialization is done\n");
20371965 return 0;
20381966
2039−out_cleanup_vgpu_type_groups:
2040− intel_gvt_cleanup_vgpu_type_groups(gvt);
20411967 out_destroy_idle_vgpu:
20421968 intel_gvt_destroy_idle_vgpu(gvt->idle_vgpu);
20431969 intel_gvt_debugfs_clean(gvt);
drivers/gpu/drm/i915/gvt/vgpu.c+12−1
@@ -113,13 +113,18 @@ int intel_gvt_init_vgpu_types(struct intel_gvt *gvt) · 112 unmodified lines
113113 if (!gvt->types)
114114 return -ENOMEM;
115115
116+ gvt->mdev_types = kcalloc(num_types, sizeof(*gvt->mdev_types),
117+ GFP_KERNEL);
118+ if (!gvt->mdev_types)
119+ goto out_free_types;
120+
116121 for (i = 0; i < num_types; ++i) {
117122 const struct intel_vgpu_config *conf = &intel_vgpu_configs[i];
118123
119124 if (low_avail / conf->low_mm == 0)
120125 break;
121126 if (conf->weight < 1 || conf->weight > VGPU_MAX_WEIGHT)
122− goto out_free_types;
127+ goto out_free_mdev_types;
123128
124129 sprintf(gvt->types[i].name, "GVTg_V%u_%s",
125130 GRAPHICS_VER(gvt->gt->i915) == 8 ? 4 : 5, conf->name);
@@ -131,11 +136,16 @@ int intel_gvt_init_vgpu_types(struct intel_gvt *gvt) · 5 unmodified lines
131136 i, gvt->types[i].name, gvt->types[i].avail_instance,
132137 conf->low_mm, conf->high_mm, conf->fence,
133138 conf->weight, vgpu_edid_str(conf->edid));
139+
140+ gvt->mdev_types[i] = &gvt->types[i].type;
141+ gvt->mdev_types[i]->sysfs_name = gvt->types[i].name;
134142 }
135143
136144 gvt->num_types = i;
137145 return 0;
138146
147+out_free_mdev_types:
148+ kfree(gvt->mdev_types);
139149 out_free_types:
140150 kfree(gvt->types);
141151 return -EINVAL;
@@ -143,6 +153,7 @@ out_free_types: · 1 unmodified line
143153
144154 void intel_gvt_clean_vgpu_types(struct intel_gvt *gvt)
145155 {
156+ kfree(gvt->mdev_types);
146157 kfree(gvt->types);
147158 }
148159
drivers/s390/cio/vfio_ccw_drv.c+4−2
@@ -202,7 +202,6 @@ static void vfio_ccw_free_private(struct vfio_ccw_private *private) · 201 unmodified lines
202202 mutex_destroy(&private->io_mutex);
203203 kfree(private);
204204 }
205−
206205 static int vfio_ccw_sch_probe(struct subchannel *sch)
207206 {
208207 struct pmcw *pmcw = &sch->schib.pmcw;
@@ -221,8 +220,11 @@ static int vfio_ccw_sch_probe(struct subchannel *sch) · 12 unmodified lines
221220
222221 dev_set_drvdata(&sch->dev, private);
223222
223+ private->mdev_type.sysfs_name = "io";
224+ private->mdev_types[0] = &private->mdev_type;
224225 ret = mdev_register_parent(&private->parent, &sch->dev,
225− &vfio_ccw_mdev_driver);
226+ &vfio_ccw_mdev_driver,
227+ private->mdev_types, 1);
226228 if (ret)
227229 goto out_free;
228230
drivers/s390/cio/vfio_ccw_ops.c+2−12
@@ -69,23 +69,13 @@ static ssize_t available_instances_show(struct mdev_type *mtype, · 68 unmodified lines
6969 }
7070 static MDEV_TYPE_ATTR_RO(available_instances);
7171
72−static struct attribute *mdev_types_attrs[] = {
72+static const struct attribute *mdev_types_attrs[] = {
7373 &mdev_type_attr_name.attr,
7474 &mdev_type_attr_device_api.attr,
7575 &mdev_type_attr_available_instances.attr,
7676 NULL,
7777 };
7878
79−static struct attribute_group mdev_type_group = {
80− .name = "io",
81− .attrs = mdev_types_attrs,
82−};
83−
84−static struct attribute_group *mdev_type_groups[] = {
85− &mdev_type_group,
86− NULL,
87−};
88−
8979 static int vfio_ccw_mdev_init_dev(struct vfio_device *vdev)
9080 {
9181 struct vfio_ccw_private *private =
@@ -646,5 +636,5 @@ struct mdev_driver vfio_ccw_mdev_driver = { · 554 unmodified lines
646636 },
647637 .probe = vfio_ccw_mdev_probe,
648638 .remove = vfio_ccw_mdev_remove,
649− .supported_type_groups = mdev_type_groups,
639+ .types_attrs = mdev_types_attrs,
650640 };
drivers/s390/cio/vfio_ccw_private.h+2−0
@@ -120,6 +120,8 @@ struct vfio_ccw_private { · 119 unmodified lines
120120 struct completion release_comp;
121121
122122 struct mdev_parent parent;
123+ struct mdev_type mdev_type;
124+ struct mdev_type *mdev_types[1];
123125 } __aligned(8);
124126
125127 int vfio_ccw_sch_quiesce(struct subchannel *sch);
drivers/s390/crypto/vfio_ap_ops.c+6−13
@@ -816,23 +816,13 @@ static ssize_t device_api_show(struct mdev_type *mtype, · 815 unmodified lines
816816
817817 static MDEV_TYPE_ATTR_RO(device_api);
818818
819−static struct attribute *vfio_ap_mdev_type_attrs[] = {
819+static const struct attribute *vfio_ap_mdev_type_attrs[] = {
820820 &mdev_type_attr_name.attr,
821821 &mdev_type_attr_device_api.attr,
822822 &mdev_type_attr_available_instances.attr,
823823 NULL,
824824 };
825825
826−static struct attribute_group vfio_ap_mdev_hwvirt_type_group = {
827− .name = VFIO_AP_MDEV_TYPE_HWVIRT,
828− .attrs = vfio_ap_mdev_type_attrs,
829−};
830−
831−static struct attribute_group *vfio_ap_mdev_type_groups[] = {
832− &vfio_ap_mdev_hwvirt_type_group,
833− NULL,
834−};
835−
836826 #define MDEV_SHARING_ERR "Userspace may not re-assign queue %02lx.%04lx " \
837827 "already assigned to %s"
838828
@@ -1817,7 +1807,7 @@ static struct mdev_driver vfio_ap_matrix_driver = { · 978 unmodified lines
18171807 },
18181808 .probe = vfio_ap_mdev_probe,
18191809 .remove = vfio_ap_mdev_remove,
1820− .supported_type_groups = vfio_ap_mdev_type_groups,
1810+ .types_attrs = vfio_ap_mdev_type_attrs,
18211811 };
18221812
18231813 int vfio_ap_mdev_register(void)
@@ -1830,8 +1820,11 @@ int vfio_ap_mdev_register(void) · 6 unmodified lines
18301820 if (ret)
18311821 return ret;
18321822
1823+ matrix_dev->mdev_type.sysfs_name = VFIO_AP_MDEV_TYPE_HWVIRT;
1824+ matrix_dev->mdev_types[0] = &matrix_dev->mdev_type;
18331825 ret = mdev_register_parent(&matrix_dev->parent, &matrix_dev->device,
1834− &vfio_ap_matrix_driver);
1826+ &vfio_ap_matrix_driver,
1827+ matrix_dev->mdev_types, 1);
18351828 if (ret)
18361829 goto err_driver;
18371830 return 0;
drivers/s390/crypto/vfio_ap_private.h+2−0
@@ -53,6 +53,8 @@ struct ap_matrix_dev { · 52 unmodified lines
5353 struct ap_driver *vfio_ap_drv;
5454 struct mutex guests_lock; /* serializes access to each KVM guest */
5555 struct mdev_parent parent;
56+ struct mdev_type mdev_type;
57+ struct mdev_type *mdev_types[];
5658 };
5759
5860 extern struct ap_matrix_dev *matrix_dev;
drivers/vfio/mdev/mdev_core.c+6−25
@@ -29,26 +29,6 @@ struct device *mdev_parent_dev(struct mdev_device *mdev) · 28 unmodified lines
2929 }
3030 EXPORT_SYMBOL(mdev_parent_dev);
3131
32−/*
33− * Return the index in supported_type_groups that this mdev_device was created
34− * from.
35− */
36−unsigned int mdev_get_type_group_id(struct mdev_device *mdev)
37−{
38− return mdev->type->type_group_id;
39−}
40−EXPORT_SYMBOL(mdev_get_type_group_id);
41−
42−/*
43− * Used in mdev_type_attribute sysfs functions to return the index in the
44− * supported_type_groups that the sysfs is called from.
45− */
46−unsigned int mtype_get_type_group_id(struct mdev_type *mtype)
47−{
48− return mtype->type_group_id;
49−}
50−EXPORT_SYMBOL(mtype_get_type_group_id);
51−
5232 /*
5333 * Used in mdev_type_attribute sysfs functions to return the parent struct
5434 * device
@@ -85,6 +65,8 @@ static int mdev_device_remove_cb(struct device *dev, void *data) · 30 unmodified lines
8565 * @parent: parent structure registered
8666 * @dev: device structure representing parent device.
8767 * @mdev_driver: Device driver to bind to the newly created mdev
68+ * @types: Array of supported mdev types
69+ * @nr_types: Number of entries in @types
8870 *
8971 * Registers the @parent stucture as a parent for mdev types and thus mdev
9072 * devices. The caller needs to hold a reference on @dev that must not be
@@ -93,20 +75,19 @@ static int mdev_device_remove_cb(struct device *dev, void *data) · 2 unmodified lines
9375 * Returns a negative value on error, otherwise 0.
9476 */
9577 int mdev_register_parent(struct mdev_parent *parent, struct device *dev,
96− struct mdev_driver *mdev_driver)
78+ struct mdev_driver *mdev_driver, struct mdev_type **types,
79+ unsigned int nr_types)
9780 {
9881 char *env_string = "MDEV_STATE=registered";
9982 char *envp[] = { env_string, NULL };
10083 int ret;
10184
102− /* check for mandatory ops */
103− if (!mdev_driver->supported_type_groups)
104− return -EINVAL;
105−
10685 memset(parent, 0, sizeof(*parent));
10786 init_rwsem(&parent->unreg_sem);
10887 parent->dev = dev;
10988 parent->mdev_driver = mdev_driver;
89+ parent->types = types;
90+ parent->nr_types = nr_types;
11091
11192 if (!mdev_bus_compat_class) {
11293 mdev_bus_compat_class = class_compat_register("mdev_bus");
drivers/vfio/mdev/mdev_driver.c+2−3
@@ -56,10 +56,9 @@ EXPORT_SYMBOL_GPL(mdev_bus_type); · 55 unmodified lines
5656 **/
5757 int mdev_register_driver(struct mdev_driver *drv)
5858 {
59− /* initialize common driver fields */
59+ if (!drv->types_attrs)
60+ return -EINVAL;
6061 drv->driver.bus = &mdev_bus_type;
61−
62− /* register with core */
6362 return driver_register(&drv->driver);
6463 }
6564 EXPORT_SYMBOL(mdev_register_driver);
drivers/vfio/mdev/mdev_private.h+0−8
@@ -13,14 +13,6 @@ · 12 unmodified lines
1313 int mdev_bus_register(void);
1414 void mdev_bus_unregister(void);
1515
16−struct mdev_type {
17− struct kobject kobj;
18− struct kobject *devices_kobj;
19− struct mdev_parent *parent;
20− struct list_head next;
21− unsigned int type_group_id;
22−};
23−
2416 extern const struct attribute_group *mdev_device_groups[];
2517
2618 #define to_mdev_type_attr(_attr) \
drivers/vfio/mdev/mdev_sysfs.c+22−69
@@ -82,7 +82,6 @@ static void mdev_type_release(struct kobject *kobj) · 81 unmodified lines
8282 pr_debug("Releasing group %s\n", kobj->name);
8383 /* Pairs with the get in add_mdev_supported_type() */
8484 put_device(type->parent->dev);
85− kfree(type);
8685 }
8786
8887 static struct kobj_type mdev_type_ktype = {
@@ -90,35 +89,21 @@ static struct kobj_type mdev_type_ktype = { · 1 unmodified line
9089 .release = mdev_type_release,
9190 };
9291
93−static struct mdev_type *add_mdev_supported_type(struct mdev_parent *parent,
94− unsigned int type_group_id)
92+static int mdev_type_add(struct mdev_parent *parent, struct mdev_type *type)
9593 {
96− struct mdev_type *type;
97− struct attribute_group *group =
98− parent->mdev_driver->supported_type_groups[type_group_id];
9994 int ret;
10095
101− if (!group->name) {
102− pr_err("%s: Type name empty!\n", __func__);
103− return ERR_PTR(-EINVAL);
104− }
105−
106− type = kzalloc(sizeof(*type), GFP_KERNEL);
107− if (!type)
108− return ERR_PTR(-ENOMEM);
109−
11096 type->kobj.kset = parent->mdev_types_kset;
11197 type->parent = parent;
11298 /* Pairs with the put in mdev_type_release() */
11399 get_device(parent->dev);
114− type->type_group_id = type_group_id;
115100
116101 ret = kobject_init_and_add(&type->kobj, &mdev_type_ktype, NULL,
117102 "%s-%s", dev_driver_string(parent->dev),
118− group->name);
103+ type->sysfs_name);
119104 if (ret) {
120105 kobject_put(&type->kobj);
121− return ERR_PTR(ret);
106+ return ret;
122107 }
123108
124109 ret = sysfs_create_file(&type->kobj, &mdev_type_attr_create.attr);
@@ -131,13 +116,10 @@ static struct mdev_type *add_mdev_supported_type(struct mdev_parent *parent, · 6 unmodified lines
131116 goto attr_devices_failed;
132117 }
133118
134− ret = sysfs_create_files(&type->kobj,
135− (const struct attribute **)group->attrs);
136− if (ret) {
137− ret = -ENOMEM;
119+ ret = sysfs_create_files(&type->kobj, parent->mdev_driver->types_attrs);
120+ if (ret)
138121 goto attrs_failed;
139− }
140− return type;
122+ return 0;
141123
142124 attrs_failed:
143125 kobject_put(type->devices_kobj);
@@ -146,78 +128,49 @@ attr_devices_failed: · 2 unmodified lines
146128 attr_create_failed:
147129 kobject_del(&type->kobj);
148130 kobject_put(&type->kobj);
149− return ERR_PTR(ret);
131+ return ret;
150132 }
151133
152−static void remove_mdev_supported_type(struct mdev_type *type)
134+static void mdev_type_remove(struct mdev_type *type)
153135 {
154− struct attribute_group *group =
155− type->parent->mdev_driver->supported_type_groups[type->type_group_id];
136+ sysfs_remove_files(&type->kobj, type->parent->mdev_driver->types_attrs);
156137
157− sysfs_remove_files(&type->kobj,
158− (const struct attribute **)group->attrs);
159138 kobject_put(type->devices_kobj);
160139 sysfs_remove_file(&type->kobj, &mdev_type_attr_create.attr);
161140 kobject_del(&type->kobj);
162141 kobject_put(&type->kobj);
163142 }
164143
165−static int add_mdev_supported_type_groups(struct mdev_parent *parent)
166−{
167− int i;
168−
169− for (i = 0; parent->mdev_driver->supported_type_groups[i]; i++) {
170− struct mdev_type *type;
171−
172− type = add_mdev_supported_type(parent, i);
173− if (IS_ERR(type)) {
174− struct mdev_type *ltype, *tmp;
175−
176− list_for_each_entry_safe(ltype, tmp, &parent->type_list,
177− next) {
178− list_del(&ltype->next);
179− remove_mdev_supported_type(ltype);
180− }
181− return PTR_ERR(type);
182− }
183− list_add(&type->next, &parent->type_list);
184− }
185− return 0;
186−}
187−
188144 /* mdev sysfs functions */
189145 void parent_remove_sysfs_files(struct mdev_parent *parent)
190146 {
191− struct mdev_type *type, *tmp;
192−
193− list_for_each_entry_safe(type, tmp, &parent->type_list, next) {
194− list_del(&type->next);
195− remove_mdev_supported_type(type);
196− }
147+ int i;
197148
149+ for (i = 0; i < parent->nr_types; i++)
150+ mdev_type_remove(parent->types[i]);
198151 kset_unregister(parent->mdev_types_kset);
199152 }
200153
201154 int parent_create_sysfs_files(struct mdev_parent *parent)
202155 {
203− int ret;
156+ int ret, i;
204157
205158 parent->mdev_types_kset = kset_create_and_add("mdev_supported_types",
206159 NULL, &parent->dev->kobj);
207−
208160 if (!parent->mdev_types_kset)
209161 return -ENOMEM;
210162
211− INIT_LIST_HEAD(&parent->type_list);
212−
213− ret = add_mdev_supported_type_groups(parent);
214− if (ret)
215− goto create_err;
163+ for (i = 0; i < parent->nr_types; i++) {
164+ ret = mdev_type_add(parent, parent->types[i]);
165+ if (ret)
166+ goto out_err;
167+ }
216168 return 0;
217169
218−create_err:
219− kset_unregister(parent->mdev_types_kset);
220− return ret;
170+out_err:
171+ while (--i >= 0)
172+ mdev_type_remove(parent->types[i]);
173+ return 0;
221174 }
222175
223176 static ssize_t remove_store(struct device *dev, struct device_attribute *attr,
include/linux/mdev.h+18−8
@@ -23,14 +23,27 @@ struct mdev_device { · 22 unmodified lines
2323 bool active;
2424 };
2525
26+struct mdev_type {
27+ /* set by the driver before calling mdev_register parent: */
28+ const char *sysfs_name;
29+
30+ /* set by the core, can be used drivers */
31+ struct mdev_parent *parent;
32+
33+ /* internal only */
34+ struct kobject kobj;
35+ struct kobject *devices_kobj;
36+};
37+
2638 /* embedded into the struct device that the mdev devices hang off */
2739 struct mdev_parent {
2840 struct device *dev;
2941 struct mdev_driver *mdev_driver;
3042 struct kset *mdev_types_kset;
31− struct list_head type_list;
3243 /* Synchronize device creation/removal with parent unregistration */
3344 struct rw_semaphore unreg_sem;
45+ struct mdev_type **types;
46+ unsigned int nr_types;
3447 };
3548
3649 static inline struct mdev_device *to_mdev_device(struct device *dev)
@@ -38,8 +51,6 @@ static inline struct mdev_device *to_mdev_device(struct device *dev) · 1 unmodified line
3851 return container_of(dev, struct mdev_device, dev);
3952 }
4053
41−unsigned int mdev_get_type_group_id(struct mdev_device *mdev);
42−unsigned int mtype_get_type_group_id(struct mdev_type *mtype);
4354 struct device *mtype_get_parent_dev(struct mdev_type *mtype);
4455
4556 /* interface for exporting mdev supported type attributes */
@@ -66,22 +77,21 @@ struct mdev_type_attribute mdev_type_attr_##_name = \ · 20 unmodified lines
6677 * struct mdev_driver - Mediated device driver
6778 * @probe: called when new device created
6879 * @remove: called when device removed
69− * @supported_type_groups: Attributes to define supported types. It is mandatory
70− * to provide supported types.
80+ * @types_attrs: attributes to the type kobjects.
7181 * @driver: device driver structure
72− *
7382 **/
7483 struct mdev_driver {
7584 int (*probe)(struct mdev_device *dev);
7685 void (*remove)(struct mdev_device *dev);
77− struct attribute_group **supported_type_groups;
86+ const struct attribute * const *types_attrs;
7887 struct device_driver driver;
7988 };
8089
8190 extern struct bus_type mdev_bus_type;
8291
8392 int mdev_register_parent(struct mdev_parent *parent, struct device *dev,
84− struct mdev_driver *mdev_driver);
93+ struct mdev_driver *mdev_driver, struct mdev_type **types,
94+ unsigned int nr_types);
8595 void mdev_unregister_parent(struct mdev_parent *parent);
8696
8797 int mdev_register_driver(struct mdev_driver *drv);
samples/vfio-mdev/mbochs.c+23−34
@@ -99,23 +99,27 @@ MODULE_PARM_DESC(mem, "megabytes available to " MBOCHS_NAME " devices"); · 98 unmodified lines
9999 #define MBOCHS_TYPE_2 "medium"
100100 #define MBOCHS_TYPE_3 "large"
101101
102−static const struct mbochs_type {
102+static struct mbochs_type {
103+ struct mdev_type type;
103104 const char *name;
104105 u32 mbytes;
105106 u32 max_x;
106107 u32 max_y;
107108 } mbochs_types[] = {
108109 {
110+ .type.sysfs_name = MBOCHS_TYPE_1,
109111 .name = MBOCHS_CLASS_NAME "-" MBOCHS_TYPE_1,
110112 .mbytes = 4,
111113 .max_x = 800,
112114 .max_y = 600,
113115 }, {
116+ .type.sysfs_name = MBOCHS_TYPE_2,
114117 .name = MBOCHS_CLASS_NAME "-" MBOCHS_TYPE_2,
115118 .mbytes = 16,
116119 .max_x = 1920,
117120 .max_y = 1440,
118121 }, {
122+ .type.sysfs_name = MBOCHS_TYPE_3,
119123 .name = MBOCHS_CLASS_NAME "-" MBOCHS_TYPE_3,
120124 .mbytes = 64,
121125 .max_x = 0,
@@ -123,6 +127,11 @@ static const struct mbochs_type { · 1 unmodified line
123127 },
124128 };
125129
130+static struct mdev_type *mbochs_mdev_types[] = {
131+ &mbochs_types[0].type,
132+ &mbochs_types[1].type,
133+ &mbochs_types[2].type,
134+};
126135
127136 static dev_t mbochs_devt;
128137 static struct class *mbochs_class;
@@ -510,8 +519,8 @@ static int mbochs_init_dev(struct vfio_device *vdev) · 381 unmodified lines
510519 struct mdev_state *mdev_state =
511520 container_of(vdev, struct mdev_state, vdev);
512521 struct mdev_device *mdev = to_mdev_device(vdev->dev);
513− const struct mbochs_type *type =
514− &mbochs_types[mdev_get_type_group_id(mdev)];
522+ struct mbochs_type *type =
523+ container_of(mdev->type, struct mbochs_type, type);
515524 int avail_mbytes = atomic_read(&mbochs_avail_mbytes);
516525 int ret = -ENOMEM;
517526
@@ -1345,8 +1354,8 @@ static const struct attribute_group *mdev_dev_groups[] = { · 827 unmodified lines
13451354 static ssize_t name_show(struct mdev_type *mtype,
13461355 struct mdev_type_attribute *attr, char *buf)
13471356 {
1348− const struct mbochs_type *type =
1349− &mbochs_types[mtype_get_type_group_id(mtype)];
1357+ struct mbochs_type *type =
1358+ container_of(mtype, struct mbochs_type, type);
13501359
13511360 return sprintf(buf, "%s\n", type->name);
13521361 }
@@ -1355,8 +1364,8 @@ static MDEV_TYPE_ATTR_RO(name); · 2 unmodified lines
13551364 static ssize_t description_show(struct mdev_type *mtype,
13561365 struct mdev_type_attribute *attr, char *buf)
13571366 {
1358− const struct mbochs_type *type =
1359− &mbochs_types[mtype_get_type_group_id(mtype)];
1367+ struct mbochs_type *type =
1368+ container_of(mtype, struct mbochs_type, type);
13601369
13611370 return sprintf(buf, "virtual display, %d MB video memory\n",
13621371 type ? type->mbytes : 0);
@@ -1367,8 +1376,8 @@ static ssize_t available_instances_show(struct mdev_type *mtype, · 4 unmodified lines
13671376 struct mdev_type_attribute *attr,
13681377 char *buf)
13691378 {
1370− const struct mbochs_type *type =
1371− &mbochs_types[mtype_get_type_group_id(mtype)];
1379+ struct mbochs_type *type =
1380+ container_of(mtype, struct mbochs_type, type);
13721381 int count = atomic_read(&mbochs_avail_mbytes) / type->mbytes;
13731382
13741383 return sprintf(buf, "%d\n", count);
@@ -1382,7 +1391,7 @@ static ssize_t device_api_show(struct mdev_type *mtype, · 7 unmodified lines
13821391 }
13831392 static MDEV_TYPE_ATTR_RO(device_api);
13841393
1385−static struct attribute *mdev_types_attrs[] = {
1394+static const struct attribute *mdev_types_attrs[] = {
13861395 &mdev_type_attr_name.attr,
13871396 &mdev_type_attr_description.attr,
13881397 &mdev_type_attr_device_api.attr,
@@ -1390,28 +1399,6 @@ static struct attribute *mdev_types_attrs[] = { · 1 unmodified line
13901399 NULL,
13911400 };
13921401
1393−static struct attribute_group mdev_type_group1 = {
1394− .name = MBOCHS_TYPE_1,
1395− .attrs = mdev_types_attrs,
1396−};
1397−
1398−static struct attribute_group mdev_type_group2 = {
1399− .name = MBOCHS_TYPE_2,
1400− .attrs = mdev_types_attrs,
1401−};
1402−
1403−static struct attribute_group mdev_type_group3 = {
1404− .name = MBOCHS_TYPE_3,
1405− .attrs = mdev_types_attrs,
1406−};
1407−
1408−static struct attribute_group *mdev_type_groups[] = {
1409− &mdev_type_group1,
1410− &mdev_type_group2,
1411− &mdev_type_group3,
1412− NULL,
1413−};
1414−
14151402 static const struct vfio_device_ops mbochs_dev_ops = {
14161403 .close_device = mbochs_close_device,
14171404 .init = mbochs_init_dev,
@@ -1431,7 +1418,7 @@ static struct mdev_driver mbochs_driver = { · 13 unmodified lines
14311418 },
14321419 .probe = mbochs_probe,
14331420 .remove = mbochs_remove,
1434− .supported_type_groups = mdev_type_groups,
1421+ .types_attrs = mdev_types_attrs,
14351422 };
14361423
14371424 static const struct file_operations vd_fops = {
@@ -1476,7 +1463,9 @@ static int __init mbochs_dev_init(void) · 38 unmodified lines
14761463 if (ret)
14771464 goto err_class;
14781465
1479− ret = mdev_register_parent(&mbochs_parent, &mbochs_dev, &mbochs_driver);
1466+ ret = mdev_register_parent(&mbochs_parent, &mbochs_dev, &mbochs_driver,
1467+ mbochs_mdev_types,
1468+ ARRAY_SIZE(mbochs_mdev_types));
14801469 if (ret)
14811470 goto err_device;
14821471
samples/vfio-mdev/mdpy.c+19−31
@@ -51,7 +51,8 @@ MODULE_PARM_DESC(count, "number of " MDPY_NAME " devices"); · 50 unmodified lines
5151 #define MDPY_TYPE_2 "xga"
5252 #define MDPY_TYPE_3 "hd"
5353
54−static const struct mdpy_type {
54+static struct mdpy_type {
55+ struct mdev_type type;
5556 const char *name;
5657 u32 format;
5758 u32 bytepp;
@@ -59,18 +60,21 @@ static const struct mdpy_type { · 1 unmodified line
5960 u32 height;
6061 } mdpy_types[] = {
6162 {
63+ .type.sysfs_name = MDPY_TYPE_1,
6264 .name = MDPY_CLASS_NAME "-" MDPY_TYPE_1,
6365 .format = DRM_FORMAT_XRGB8888,
6466 .bytepp = 4,
6567 .width = 640,
6668 .height = 480,
6769 }, {
70+ .type.sysfs_name = MDPY_TYPE_2,
6871 .name = MDPY_CLASS_NAME "-" MDPY_TYPE_2,
6972 .format = DRM_FORMAT_XRGB8888,
7073 .bytepp = 4,
7174 .width = 1024,
7275 .height = 768,
7376 }, {
77+ .type.sysfs_name = MDPY_TYPE_3,
7478 .name = MDPY_CLASS_NAME "-" MDPY_TYPE_3,
7579 .format = DRM_FORMAT_XRGB8888,
7680 .bytepp = 4,
@@ -79,6 +83,12 @@ static const struct mdpy_type { · 2 unmodified lines
7983 },
8084 };
8185
86+static struct mdev_type *mdpy_mdev_types[] = {
87+ &mdpy_types[0].type,
88+ &mdpy_types[1].type,
89+ &mdpy_types[2].type,
90+};
91+
8292 static dev_t mdpy_devt;
8393 static struct class *mdpy_class;
8494 static struct cdev mdpy_cdev;
@@ -222,7 +232,7 @@ static int mdpy_init_dev(struct vfio_device *vdev) · 137 unmodified lines
222232 container_of(vdev, struct mdev_state, vdev);
223233 struct mdev_device *mdev = to_mdev_device(vdev->dev);
224234 const struct mdpy_type *type =
225− &mdpy_types[mdev_get_type_group_id(mdev)];
235+ container_of(mdev->type, struct mdpy_type, type);
226236 u32 fbsize;
227237 int ret = -ENOMEM;
228238
@@ -655,8 +665,7 @@ static const struct attribute_group *mdev_dev_groups[] = { · 426 unmodified lines
655665 static ssize_t name_show(struct mdev_type *mtype,
656666 struct mdev_type_attribute *attr, char *buf)
657667 {
658− const struct mdpy_type *type =
659− &mdpy_types[mtype_get_type_group_id(mtype)];
668+ struct mdpy_type *type = container_of(mtype, struct mdpy_type, type);
660669
661670 return sprintf(buf, "%s\n", type->name);
662671 }
@@ -665,8 +674,7 @@ static MDEV_TYPE_ATTR_RO(name); · 2 unmodified lines
665674 static ssize_t description_show(struct mdev_type *mtype,
666675 struct mdev_type_attribute *attr, char *buf)
667676 {
668− const struct mdpy_type *type =
669− &mdpy_types[mtype_get_type_group_id(mtype)];
677+ struct mdpy_type *type = container_of(mtype, struct mdpy_type, type);
670678
671679 return sprintf(buf, "virtual display, %dx%d framebuffer\n",
672680 type->width, type->height);
@@ -688,7 +696,7 @@ static ssize_t device_api_show(struct mdev_type *mtype, · 15 unmodified lines
688696 }
689697 static MDEV_TYPE_ATTR_RO(device_api);
690698
691−static struct attribute *mdev_types_attrs[] = {
699+static const struct attribute *mdev_types_attrs[] = {
692700 &mdev_type_attr_name.attr,
693701 &mdev_type_attr_description.attr,
694702 &mdev_type_attr_device_api.attr,
@@ -696,28 +704,6 @@ static struct attribute *mdev_types_attrs[] = { · 1 unmodified line
696704 NULL,
697705 };
698706
699−static struct attribute_group mdev_type_group1 = {
700− .name = MDPY_TYPE_1,
701− .attrs = mdev_types_attrs,
702−};
703−
704−static struct attribute_group mdev_type_group2 = {
705− .name = MDPY_TYPE_2,
706− .attrs = mdev_types_attrs,
707−};
708−
709−static struct attribute_group mdev_type_group3 = {
710− .name = MDPY_TYPE_3,
711− .attrs = mdev_types_attrs,
712−};
713−
714−static struct attribute_group *mdev_type_groups[] = {
715− &mdev_type_group1,
716− &mdev_type_group2,
717− &mdev_type_group3,
718− NULL,
719−};
720−
721707 static const struct vfio_device_ops mdpy_dev_ops = {
722708 .init = mdpy_init_dev,
723709 .release = mdpy_release_dev,
@@ -736,7 +722,7 @@ static struct mdev_driver mdpy_driver = { · 12 unmodified lines
736722 },
737723 .probe = mdpy_probe,
738724 .remove = mdpy_remove,
739− .supported_type_groups = mdev_type_groups,
725+ .types_attrs = mdev_types_attrs,
740726 };
741727
742728 static const struct file_operations vd_fops = {
@@ -779,7 +765,9 @@ static int __init mdpy_dev_init(void) · 36 unmodified lines
779765 if (ret)
780766 goto err_class;
781767
782− ret = mdev_register_parent(&mdpy_parent, &mdpy_dev, &mdpy_driver);
768+ ret = mdev_register_parent(&mdpy_parent, &mdpy_dev, &mdpy_driver,
769+ mdpy_mdev_types,
770+ ARRAY_SIZE(mdpy_mdev_types));
783771 if (ret)
784772 goto err_device;
785773
samples/vfio-mdev/mtty.c+30−30
@@ -143,6 +143,20 @@ struct mdev_state { · 142 unmodified lines
143143 int nr_ports;
144144 };
145145
146+static struct mtty_type {
147+ struct mdev_type type;
148+ int nr_ports;
149+ const char *name;
150+} mtty_types[2] = {
151+ { .nr_ports = 1, .type.sysfs_name = "1", .name = "Single port serial" },
152+ { .nr_ports = 2, .type.sysfs_name = "2", .name = "Dual port serial" },
153+};
154+
155+static struct mdev_type *mtty_mdev_types[] = {
156+ &mtty_types[0].type,
157+ &mtty_types[1].type,
158+};
159+
146160 static atomic_t mdev_avail_ports = ATOMIC_INIT(MAX_MTTYS);
147161
148162 static const struct file_operations vd_fops = {
@@ -707,17 +721,19 @@ static int mtty_init_dev(struct vfio_device *vdev) · 558 unmodified lines
707721 struct mdev_state *mdev_state =
708722 container_of(vdev, struct mdev_state, vdev);
709723 struct mdev_device *mdev = to_mdev_device(vdev->dev);
710− int nr_ports = mdev_get_type_group_id(mdev) + 1;
724+ struct mtty_type *type =
725+ container_of(mdev->type, struct mtty_type, type);
711726 int avail_ports = atomic_read(&mdev_avail_ports);
712727 int ret;
713728
714729 do {
715− if (avail_ports < nr_ports)
730+ if (avail_ports < type->nr_ports)
716731 return -ENOSPC;
717732 } while (!atomic_try_cmpxchg(&mdev_avail_ports,
718− &avail_ports, avail_ports - nr_ports));
733+ &avail_ports,
734+ avail_ports - type->nr_ports));
719735
720− mdev_state->nr_ports = nr_ports;
736+ mdev_state->nr_ports = type->nr_ports;
721737 mdev_state->irq_index = -1;
722738 mdev_state->s[0].max_fifo_size = MAX_FIFO_SIZE;
723739 mdev_state->s[1].max_fifo_size = MAX_FIFO_SIZE;
@@ -735,7 +751,7 @@ static int mtty_init_dev(struct vfio_device *vdev) · 11 unmodified lines
735751 return 0;
736752
737753 err_nr_ports:
738− atomic_add(nr_ports, &mdev_avail_ports);
754+ atomic_add(type->nr_ports, &mdev_avail_ports);
739755 return ret;
740756 }
741757
@@ -1242,11 +1258,9 @@ static const struct attribute_group *mdev_dev_groups[] = { · 500 unmodified lines
12421258 static ssize_t name_show(struct mdev_type *mtype,
12431259 struct mdev_type_attribute *attr, char *buf)
12441260 {
1245− static const char *name_str[2] = { "Single port serial",
1246− "Dual port serial" };
1261+ struct mtty_type *type = container_of(mtype, struct mtty_type, type);
12471262
1248− return sysfs_emit(buf, "%s\n",
1249− name_str[mtype_get_type_group_id(mtype)]);
1263+ return sysfs_emit(buf, "%s\n", type->name);
12501264 }
12511265
12521266 static MDEV_TYPE_ATTR_RO(name);
@@ -1255,9 +1269,10 @@ static ssize_t available_instances_show(struct mdev_type *mtype, · 2 unmodified lines
12551269 struct mdev_type_attribute *attr,
12561270 char *buf)
12571271 {
1258− unsigned int ports = mtype_get_type_group_id(mtype) + 1;
1272+ struct mtty_type *type = container_of(mtype, struct mtty_type, type);
12591273
1260− return sprintf(buf, "%d\n", atomic_read(&mdev_avail_ports) / ports);
1274+ return sprintf(buf, "%d\n", atomic_read(&mdev_avail_ports) /
1275+ type->nr_ports);
12611276 }
12621277
12631278 static MDEV_TYPE_ATTR_RO(available_instances);
@@ -1270,29 +1285,13 @@ static ssize_t device_api_show(struct mdev_type *mtype, · 6 unmodified lines
12701285
12711286 static MDEV_TYPE_ATTR_RO(device_api);
12721287
1273−static struct attribute *mdev_types_attrs[] = {
1288+static const struct attribute *mdev_types_attrs[] = {
12741289 &mdev_type_attr_name.attr,
12751290 &mdev_type_attr_device_api.attr,
12761291 &mdev_type_attr_available_instances.attr,
12771292 NULL,
12781293 };
12791294
1280−static struct attribute_group mdev_type_group1 = {
1281− .name = "1",
1282− .attrs = mdev_types_attrs,
1283−};
1284−
1285−static struct attribute_group mdev_type_group2 = {
1286− .name = "2",
1287− .attrs = mdev_types_attrs,
1288−};
1289−
1290−static struct attribute_group *mdev_type_groups[] = {
1291− &mdev_type_group1,
1292− &mdev_type_group2,
1293− NULL,
1294−};
1295−
12961295 static const struct vfio_device_ops mtty_dev_ops = {
12971296 .name = "vfio-mtty",
12981297 .init = mtty_init_dev,
@@ -1311,7 +1310,7 @@ static struct mdev_driver mtty_driver = { · 12 unmodified lines
13111310 },
13121311 .probe = mtty_probe,
13131312 .remove = mtty_remove,
1314− .supported_type_groups = mdev_type_groups,
1313+ .types_attrs = mdev_types_attrs,
13151314 };
13161315
13171316 static void mtty_device_release(struct device *dev)
@@ -1363,7 +1362,8 @@ static int __init mtty_dev_init(void) · 45 unmodified lines
13631362 goto err_class;
13641363
13651364 ret = mdev_register_parent(&mtty_dev.parent, &mtty_dev.dev,
1366− &mtty_driver);
1365+ &mtty_driver, mtty_mdev_types,
1366+ ARRAY_SIZE(mtty_mdev_types));
13671367 if (ret)
13681368 goto err_device;
13691369 return 0;