summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2025-08-27 07:24:33 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-09-09 19:02:36 +0200
commite7a70326fb26b905cfc8fe2366113aa4394733ef (patch)
treeaf0036b99eaa5cdc9289b74a0fac645f3880ffa6
parent796eac3ab5e490635b89b89defa864bd72a758cb (diff)
platform/x86: asus-wmi: Fix racy registrations
[ Upstream commit 5549202b9c02c2ecbc8634768a3da8d9e82d548d ] asus_wmi_register_driver() may be called from multiple drivers concurrently, which can lead to the racy list operations, eventually corrupting the memory and hitting Oops on some ASUS machines. Also, the error handling is missing, and it forgot to unregister ACPI lps0 dev ops in the error case. This patch covers those issues by introducing a simple mutex at acpi_wmi_register_driver() & *_unregister_driver, and adding the proper call of asus_s2idle_check_unregister() in the error path. Fixes: feea7bd6b02d ("platform/x86: asus-wmi: Refactor Ally suspend/resume") Link: https://bugzilla.suse.com/show_bug.cgi?id=1246924 Link: https://lore.kernel.org/07815053-0e31-4e8e-8049-b652c929323b@kernel.org Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://lore.kernel.org/r/20250827052441.23382-1-tiwai@suse.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>
-rw-r--r--drivers/platform/x86/asus-wmi.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index f7191fdded14..e72a2b5d158e 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -5088,16 +5088,22 @@ static int asus_wmi_probe(struct platform_device *pdev)
asus_s2idle_check_register();
- return asus_wmi_add(pdev);
+ ret = asus_wmi_add(pdev);
+ if (ret)
+ asus_s2idle_check_unregister();
+
+ return ret;
}
static bool used;
+static DEFINE_MUTEX(register_mutex);
int __init_or_module asus_wmi_register_driver(struct asus_wmi_driver *driver)
{
struct platform_driver *platform_driver;
struct platform_device *platform_device;
+ guard(mutex)(&register_mutex);
if (used)
return -EBUSY;
@@ -5120,6 +5126,7 @@ EXPORT_SYMBOL_GPL(asus_wmi_register_driver);
void asus_wmi_unregister_driver(struct asus_wmi_driver *driver)
{
+ guard(mutex)(&register_mutex);
asus_s2idle_check_unregister();
platform_device_unregister(driver->platform_device);