vfio/mdev: Use the driver core to create the 'remove' file
authorJason Gunthorpe <jgg@nvidia.com>
Mon, 11 Apr 2022 14:14:02 +0000 (16:14 +0200)
committerZhi Wang <zhi.a.wang@intel.com>
Thu, 21 Apr 2022 11:36:56 +0000 (07:36 -0400)
The device creator is supposed to use the dev.groups value to add sysfs
files before device_add is called, not call sysfs_create_files() after
device_add() returns. This creates a race with uevent delivery where the
extra attribute will not be visible.

This was being done because the groups had been co-opted by the mdev
driver, now that prior patches have moved the driver's groups to the
struct device_driver the dev.group is properly free for use here.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20220411141403.86980-34-hch@lst.de
Reviewed-by: Kirti Wankhede <kwankhede@nvidia.com>
Reviewed-by: Zhi Wang <zhi.a.wang@intel.com>
drivers/vfio/mdev/mdev_core.c
drivers/vfio/mdev/mdev_private.h
drivers/vfio/mdev/mdev_sysfs.c

index 19a20ff420b7f619937deb8861e2852eaeffe3c4..b8b9e7911e55916ecc631bcae0dac7583d352a95 100644 (file)
@@ -269,6 +269,7 @@ int mdev_device_create(struct mdev_type *type, const guid_t *uuid)
        mdev->dev.parent  = parent->dev;
        mdev->dev.bus = &mdev_bus_type;
        mdev->dev.release = mdev_device_release;
+       mdev->dev.groups = mdev_device_groups;
        mdev->type = type;
        /* Pairs with the put in mdev_device_release() */
        kobject_get(&type->kobj);
index 5a7ffd4e770fde5c469223bdc6c62d4220e7d7ee..7c9fc79f3d838405fd5a4fe20adb5a754717eef2 100644 (file)
@@ -32,6 +32,8 @@ struct mdev_type {
        unsigned int type_group_id;
 };
 
+extern const struct attribute_group *mdev_device_groups[];
+
 #define to_mdev_type_attr(_attr)       \
        container_of(_attr, struct mdev_type_attribute, attr)
 #define to_mdev_type(_kobj)            \
index 5a3873d1a275ae142a37798e8ebda4d547d21c58..0ccfeb3dda2455fbe5555c283c41581999caccb9 100644 (file)
@@ -244,11 +244,20 @@ static ssize_t remove_store(struct device *dev, struct device_attribute *attr,
 
 static DEVICE_ATTR_WO(remove);
 
-static const struct attribute *mdev_device_attrs[] = {
+static struct attribute *mdev_device_attrs[] = {
        &dev_attr_remove.attr,
        NULL,
 };
 
+static const struct attribute_group mdev_device_group = {
+       .attrs = mdev_device_attrs,
+};
+
+const struct attribute_group *mdev_device_groups[] = {
+       &mdev_device_group,
+       NULL
+};
+
 int mdev_create_sysfs_files(struct mdev_device *mdev)
 {
        struct mdev_type *type = mdev->type;
@@ -262,15 +271,8 @@ int mdev_create_sysfs_files(struct mdev_device *mdev)
        ret = sysfs_create_link(kobj, &type->kobj, "mdev_type");
        if (ret)
                goto type_link_failed;
-
-       ret = sysfs_create_files(kobj, mdev_device_attrs);
-       if (ret)
-               goto create_files_failed;
-
        return ret;
 
-create_files_failed:
-       sysfs_remove_link(kobj, "mdev_type");
 type_link_failed:
        sysfs_remove_link(mdev->type->devices_kobj, dev_name(&mdev->dev));
        return ret;
@@ -280,7 +282,6 @@ void mdev_remove_sysfs_files(struct mdev_device *mdev)
 {
        struct kobject *kobj = &mdev->dev.kobj;
 
-       sysfs_remove_files(kobj, mdev_device_attrs);
        sysfs_remove_link(kobj, "mdev_type");
        sysfs_remove_link(mdev->type->devices_kobj, dev_name(&mdev->dev));
 }