platform/x86: wmi: Fix probe failure when failing to register WMI devices
authorArmin Wolf <W_Armin@gmx.de>
Fri, 20 Oct 2023 21:10:03 +0000 (23:10 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 20 Nov 2023 10:59:07 +0000 (11:59 +0100)
[ Upstream commit ed85891a276edaf7a867de0e9acd0837bc3008f2 ]

When a WMI device besides the first one somehow fails to register,
retval is returned while still containing a negative error code. This
causes the ACPI device fail to probe, leaving behind zombie WMI devices
leading to various errors later.

Handle the single error path separately and return 0 unconditionally
after trying to register all WMI devices to solve the issue. Also
continue to register WMI devices even if some fail to allocate memory.

Fixes: 6ee50aaa9a20 ("platform/x86: wmi: Instantiate all devices before adding them")
Signed-off-by: Armin Wolf <W_Armin@gmx.de>
Link: https://lore.kernel.org/r/20231020211005.38216-4-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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/platform/x86/wmi.c

index a78ddd8..7d11ff5 100644 (file)
@@ -1270,8 +1270,8 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device)
        struct wmi_block *wblock, *next;
        union acpi_object *obj;
        acpi_status status;
-       int retval = 0;
        u32 i, total;
+       int retval;
 
        status = acpi_evaluate_object(device->handle, "_WDG", NULL, &out);
        if (ACPI_FAILURE(status))
@@ -1282,8 +1282,8 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device)
                return -ENXIO;
 
        if (obj->type != ACPI_TYPE_BUFFER) {
-               retval = -ENXIO;
-               goto out_free_pointer;
+               kfree(obj);
+               return -ENXIO;
        }
 
        gblock = (const struct guid_block *)obj->buffer.pointer;
@@ -1298,8 +1298,8 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device)
 
                wblock = kzalloc(sizeof(*wblock), GFP_KERNEL);
                if (!wblock) {
-                       retval = -ENOMEM;
-                       break;
+                       dev_err(wmi_bus_dev, "Failed to allocate %pUL\n", &gblock[i].guid);
+                       continue;
                }
 
                wblock->acpi_device = device;
@@ -1338,9 +1338,9 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device)
                }
        }
 
-out_free_pointer:
-       kfree(out.pointer);
-       return retval;
+       kfree(obj);
+
+       return 0;
 }
 
 /*