From: Denis Benato <denis.benato@linux.dev>
To: linux-kernel@vger.kernel.org
Cc: linux-input@vger.kernel.org,
"Benjamin Tissoires" <bentiss@kernel.org>,
"Jiri Kosina" <jikos@kernel.org>,
"Luke D . Jones" <luke@ljones.dev>,
"Mateusz Schyboll" <dragonn@op.pl>,
"Denis Benato" <benato.denis96@gmail.com>,
"Denis Benato" <denis.benato@linux.dev>,
"Antheas Kapenekakis" <lkml@antheas.dev>,
"Connor Belli" <connorbelli2003@gmail.com>,
sahiko-bot@kernel.org
Subject: [PATCH v3 5/8] HID: asus: avoid sleeping calls in atomic context
Date: Sat, 13 Jun 2026 15:30:26 +0000 [thread overview]
Message-ID: <20260613153029.2559774-6-denis.benato@linux.dev> (raw)
In-Reply-To: <20260613153029.2559774-1-denis.benato@linux.dev>
Avoid possibly calling asus_wmi_send_event(): a method that can sleep in
asus_raw_event() that is called in atomic context.
This commit changes when methods are called, not method parameters:
the driver behaves as before.
Fixes: 1489a34e97ef ("HID: asus: Implement Fn+F5 fan control key handler")
Reported-by: sahiko-bot@kernel.org
Signed-off-by: Denis Benato <denis.benato@linux.dev>
---
drivers/hid/hid-asus.c | 67 +++++++++++++++++++++++++++++++++++-------
1 file changed, 56 insertions(+), 11 deletions(-)
diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
index f38b18ad65c6..a6467172c455 100644
--- a/drivers/hid/hid-asus.c
+++ b/drivers/hid/hid-asus.c
@@ -150,6 +150,13 @@ struct asus_drvdata {
unsigned long battery_next_query;
struct work_struct fn_lock_sync_work;
bool fn_lock;
+#if IS_REACHABLE(CONFIG_ASUS_WMI)
+ struct work_struct wmi_work;
+ bool wmi_work_disabled;
+ u8 wmi_data[FEATURE_KBD_REPORT_SIZE];
+ int wmi_size;
+ spinlock_t wmi_lock;
+#endif
struct asus_xgm_led *xgm_led;
};
@@ -338,6 +345,7 @@ static int asus_e1239t_event(struct asus_drvdata *drvdat, u8 *data, int size)
return 0;
}
+#if IS_REACHABLE(CONFIG_ASUS_WMI)
/*
* Send events to asus-wmi driver for handling special keys
*/
@@ -361,6 +369,32 @@ static int asus_wmi_send_event(struct asus_drvdata *drvdata, u8 code)
return 0;
}
+static void asus_wmi_work(struct work_struct *work)
+{
+ struct asus_drvdata *drvdata = container_of(work, struct asus_drvdata, wmi_work);
+ u8 report_data[FEATURE_KBD_REPORT_SIZE];
+ int report_size;
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&drvdata->wmi_lock, flags);
+ memcpy(report_data, drvdata->wmi_data, drvdata->wmi_size);
+ report_size = drvdata->wmi_size;
+ spin_unlock_irqrestore(&drvdata->wmi_lock, flags);
+
+ ret = asus_wmi_send_event(drvdata, ASUS_FAN_CTRL_KEY_CODE);
+ if (ret) {
+ if (ret != -ENODEV)
+ hid_warn(drvdata->hdev, "Failed to notify asus-wmi: %d\n", ret);
+
+ /* Fallback: pass the raw event to the HID core */
+ hid_report_raw_event(drvdata->hdev, HID_INPUT_REPORT,
+ report_data, report_size,
+ report_size, 1);
+ }
+}
+#endif
+
static int asus_event(struct hid_device *hdev, struct hid_field *field,
struct hid_usage *usage, __s32 value)
{
@@ -397,6 +431,9 @@ static int asus_raw_event(struct hid_device *hdev,
struct hid_report *report, u8 *data, int size)
{
struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
+#if IS_REACHABLE(CONFIG_ASUS_WMI)
+ unsigned long flags;
+#endif
if (drvdata->battery && data[0] == BATTERY_REPORT_ID)
return asus_report_battery(drvdata, data, size);
@@ -422,19 +459,18 @@ static int asus_raw_event(struct hid_device *hdev,
* pass to userspace so it can implement its own fan control.
*/
if (data[1] == ASUS_FAN_CTRL_KEY_CODE) {
- int ret = asus_wmi_send_event(drvdata, ASUS_FAN_CTRL_KEY_CODE);
-
- if (ret == 0) {
- /* Successfully handled by asus-wmi, block event */
+#if IS_REACHABLE(CONFIG_ASUS_WMI)
+ spin_lock_irqsave(&drvdata->wmi_lock, flags);
+ memcpy(drvdata->wmi_data, data, min_t(int, size, sizeof(drvdata->wmi_data)));
+ drvdata->wmi_size = size;
+ spin_unlock_irqrestore(&drvdata->wmi_lock, flags);
+
+ if (!drvdata->wmi_work_disabled) {
+ schedule_work(&drvdata->wmi_work);
+ /* Successfully handled asynchronously, block event */
return -1;
}
-
- /*
- * Warn if asus-wmi failed (but not if it's unavailable).
- * Let the event reach userspace in all failure cases.
- */
- if (ret != -ENODEV)
- hid_warn(hdev, "Failed to notify asus-wmi: %d\n", ret);
+#endif
}
/*
@@ -1350,6 +1386,10 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS;
drvdata->hdev = hdev;
+#if IS_REACHABLE(CONFIG_ASUS_WMI)
+ INIT_WORK(&drvdata->wmi_work, asus_wmi_work);
+ spin_lock_init(&drvdata->wmi_lock);
+#endif
if (drvdata->quirks & (QUIRK_T100CHI | QUIRK_T90CHI)) {
ret = asus_battery_probe(hdev);
@@ -1460,6 +1500,11 @@ static void asus_remove(struct hid_device *hdev)
if (drvdata->quirks & QUIRK_HID_FN_LOCK)
cancel_work_sync(&drvdata->fn_lock_sync_work);
+#if IS_REACHABLE(CONFIG_ASUS_WMI)
+ drvdata->wmi_work_disabled = true;
+ cancel_work_sync(&drvdata->wmi_work);
+#endif
+
if (drvdata->xgm_led)
led_classdev_unregister(&drvdata->xgm_led->cdev);
--
2.47.3
next prev parent reply other threads:[~2026-06-13 15:30 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-13 15:30 [PATCH v3 0/8] HID: asus: security fixes and more hardware support Denis Benato
2026-06-13 15:30 ` [PATCH v3 1/8] HID: asus: mitigate possible use-after-free Denis Benato
2026-06-13 15:47 ` sashiko-bot
2026-06-13 15:59 ` Antheas Kapenekakis
2026-06-13 15:30 ` [PATCH v3 2/8] HID: asus: prevent wrong pointer cast Denis Benato
2026-06-13 15:30 ` [PATCH v3 3/8] HID: asus: add support for xgm led Denis Benato
2026-06-13 15:42 ` sashiko-bot
2026-06-13 15:30 ` [PATCH v3 4/8] HID: asus: cleanup keyboard listener on failure: avoid use-after-free Denis Benato
2026-06-13 15:42 ` sashiko-bot
2026-06-13 15:57 ` Antheas Kapenekakis
2026-06-13 15:30 ` Denis Benato [this message]
2026-06-13 15:43 ` [PATCH v3 5/8] HID: asus: avoid sleeping calls in atomic context sashiko-bot
2026-06-13 16:15 ` Antheas Kapenekakis
2026-06-13 15:30 ` [PATCH v3 6/8] HID: asus: prevent a late KEY_FN_ESC to trigger a use-after-free Denis Benato
2026-06-13 15:53 ` sashiko-bot
2026-06-13 16:04 ` Antheas Kapenekakis
2026-06-13 15:30 ` [PATCH v3 7/8] HID: asus: add i2c entry for FA808UM and other TUFs Denis Benato
2026-06-13 15:45 ` sashiko-bot
2026-06-13 15:30 ` [PATCH v3 8/8] HID: asus: remove unnecessary OOM message Denis Benato
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260613153029.2559774-6-denis.benato@linux.dev \
--to=denis.benato@linux.dev \
--cc=benato.denis96@gmail.com \
--cc=bentiss@kernel.org \
--cc=connorbelli2003@gmail.com \
--cc=dragonn@op.pl \
--cc=jikos@kernel.org \
--cc=linux-input@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lkml@antheas.dev \
--cc=luke@ljones.dev \
--cc=sahiko-bot@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.