]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
platform/x86: dell-smbios-wmi: Stop touching WMI device ID
authorArmin Wolf <W_Armin@gmx.de>
Tue, 22 Jul 2025 18:38:41 +0000 (20:38 +0200)
committerIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Tue, 12 Aug 2025 12:00:32 +0000 (15:00 +0300)
The Dell SMBIOS driver uses the "id" field inside struct device for
prioritizing the WMI backend over the SMM backend. Because of this
the WMI backend modifies the "id" field of the underlying WMI device.
However the WMI core itself uses wdev->dev.id internally to track
device IDs, so modifying this value will result in a resource leak.

Fix this by not using the "id" field inside struct device for SMBIOS
prioritization. Instead extend struct smbios_device with a separate
"priority" field.

Tested on a Dell Inspiron 3505.

Fixes: 73f0f2b52c5e ("platform/x86: wmi: Fix WMI device naming issue")
Signed-off-by: Armin Wolf <W_Armin@gmx.de>
Link: https://lore.kernel.org/r/20250722183841.9552-1-W_Armin@gmx.de
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
drivers/platform/x86/dell/dell-smbios-base.c
drivers/platform/x86/dell/dell-smbios-smm.c
drivers/platform/x86/dell/dell-smbios-wmi.c
drivers/platform/x86/dell/dell-smbios.h

index 01c72b91a50d44b14b214f96aabedca08b5bf7bf..444786102f020b39a24a7e10da2a2b7d9aaa819c 100644 (file)
@@ -39,6 +39,7 @@ struct token_sysfs_data {
 struct smbios_device {
        struct list_head list;
        struct device *device;
+       int priority;
        int (*call_fn)(struct calling_interface_buffer *arg);
 };
 
@@ -145,7 +146,7 @@ int dell_smbios_error(int value)
 }
 EXPORT_SYMBOL_GPL(dell_smbios_error);
 
-int dell_smbios_register_device(struct device *d, void *call_fn)
+int dell_smbios_register_device(struct device *d, int priority, void *call_fn)
 {
        struct smbios_device *priv;
 
@@ -154,6 +155,7 @@ int dell_smbios_register_device(struct device *d, void *call_fn)
                return -ENOMEM;
        get_device(d);
        priv->device = d;
+       priv->priority = priority;
        priv->call_fn = call_fn;
        mutex_lock(&smbios_mutex);
        list_add_tail(&priv->list, &smbios_device_list);
@@ -292,28 +294,25 @@ EXPORT_SYMBOL_GPL(dell_smbios_call_filter);
 
 int dell_smbios_call(struct calling_interface_buffer *buffer)
 {
-       int (*call_fn)(struct calling_interface_buffer *) = NULL;
-       struct device *selected_dev = NULL;
+       struct smbios_device *selected = NULL;
        struct smbios_device *priv;
        int ret;
 
        mutex_lock(&smbios_mutex);
        list_for_each_entry(priv, &smbios_device_list, list) {
-               if (!selected_dev || priv->device->id >= selected_dev->id) {
-                       dev_dbg(priv->device, "Trying device ID: %d\n",
-                               priv->device->id);
-                       call_fn = priv->call_fn;
-                       selected_dev = priv->device;
+               if (!selected || priv->priority >= selected->priority) {
+                       dev_dbg(priv->device, "Trying device ID: %d\n", priv->priority);
+                       selected = priv;
                }
        }
 
-       if (!selected_dev) {
+       if (!selected) {
                ret = -ENODEV;
                pr_err("No dell-smbios drivers are loaded\n");
                goto out_smbios_call;
        }
 
-       ret = call_fn(buffer);
+       ret = selected->call_fn(buffer);
 
 out_smbios_call:
        mutex_unlock(&smbios_mutex);
index 4d375985c85f8203546a70d30aba8e3f3621b68a..7055e2c40f3494d08d136628ff8fa8a039cb94e0 100644 (file)
@@ -125,8 +125,7 @@ int init_dell_smbios_smm(void)
        if (ret)
                goto fail_platform_device_add;
 
-       ret = dell_smbios_register_device(&platform_device->dev,
-                                         &dell_smbios_smm_call);
+       ret = dell_smbios_register_device(&platform_device->dev, 0, &dell_smbios_smm_call);
        if (ret)
                goto fail_register;
 
index ae9012549560c4cc435725de1ec3ac0ec7235f10..a7dca8c59d6027983a90175545e37c6bf2ea37a8 100644 (file)
@@ -264,9 +264,7 @@ static int dell_smbios_wmi_probe(struct wmi_device *wdev, const void *context)
        if (ret)
                return ret;
 
-       /* ID is used by dell-smbios to set priority of drivers */
-       wdev->dev.id = 1;
-       ret = dell_smbios_register_device(&wdev->dev, &dell_smbios_wmi_call);
+       ret = dell_smbios_register_device(&wdev->dev, 1, &dell_smbios_wmi_call);
        if (ret)
                return ret;
 
index 77baa15eb5236554fe99309cebb69fda726901f3..f421b8533a9e1ac27eeff5d37c5b6ede3bbc6a54 100644 (file)
@@ -64,7 +64,7 @@ struct calling_interface_structure {
        struct calling_interface_token tokens[];
 } __packed;
 
-int dell_smbios_register_device(struct device *d, void *call_fn);
+int dell_smbios_register_device(struct device *d, int priority, void *call_fn);
 void dell_smbios_unregister_device(struct device *d);
 
 int dell_smbios_error(int value);