Skip to content

Commit e04e2b7

Browse files
Wer-Wolfjwrdegoede
authored andcommitted
platform/x86: wmi: Pass event data directly to legacy notify handlers
The current legacy WMI handlers are susceptible to picking up wrong WMI event data on systems where different WMI devices share some notification IDs. Prevent this by letting the WMI driver core taking care of retrieving the event data. This also simplifies the legacy WMI handlers and their implementation inside the WMI driver core. Reviewed-by: Ilpo Järvinen <[email protected]> Reviewed-by: Hans de Goede <[email protected]> Signed-off-by: Armin Wolf <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Hans de Goede <[email protected]>
1 parent 56d8b78 commit e04e2b7

File tree

11 files changed

+37
-156
lines changed

11 files changed

+37
-156
lines changed

drivers/hwmon/hp-wmi-sensors.c

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1597,15 +1597,13 @@ static void hp_wmi_devm_notify_remove(void *ignored)
15971597
}
15981598

15991599
/* hp_wmi_notify - WMI event notification handler */
1600-
static void hp_wmi_notify(u32 value, void *context)
1600+
static void hp_wmi_notify(union acpi_object *wobj, void *context)
16011601
{
16021602
struct hp_wmi_info *temp_info[HP_WMI_MAX_INSTANCES] = {};
1603-
struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL };
16041603
struct hp_wmi_sensors *state = context;
16051604
struct device *dev = &state->wdev->dev;
16061605
struct hp_wmi_event event = {};
16071606
struct hp_wmi_info *fan_info;
1608-
union acpi_object *wobj;
16091607
acpi_status err;
16101608
int event_type;
16111609
u8 count;
@@ -1630,20 +1628,15 @@ static void hp_wmi_notify(u32 value, void *context)
16301628
* HPBIOS_BIOSEvent instance.
16311629
*/
16321630

1633-
mutex_lock(&state->lock);
1634-
1635-
err = wmi_get_event_data(value, &out);
1636-
if (ACPI_FAILURE(err))
1637-
goto out_unlock;
1638-
1639-
wobj = out.pointer;
16401631
if (!wobj)
1641-
goto out_unlock;
1632+
return;
1633+
1634+
mutex_lock(&state->lock);
16421635

16431636
err = populate_event_from_wobj(dev, &event, wobj);
16441637
if (err) {
16451638
dev_warn(dev, "Bad event data (ACPI type %d)\n", wobj->type);
1646-
goto out_free_wobj;
1639+
goto out_free;
16471640
}
16481641

16491642
event_type = classify_event(event.name, event.category);
@@ -1668,13 +1661,10 @@ static void hp_wmi_notify(u32 value, void *context)
16681661
break;
16691662
}
16701663

1671-
out_free_wobj:
1672-
kfree(wobj);
1673-
1664+
out_free:
16741665
devm_kfree(dev, event.name);
16751666
devm_kfree(dev, event.description);
16761667

1677-
out_unlock:
16781668
mutex_unlock(&state->lock);
16791669
}
16801670

drivers/platform/x86/acer-wmi.c

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2223,39 +2223,25 @@ static void acer_rfkill_exit(void)
22232223
}
22242224
}
22252225

2226-
static void acer_wmi_notify(u32 value, void *context)
2226+
static void acer_wmi_notify(union acpi_object *obj, void *context)
22272227
{
2228-
struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
2229-
union acpi_object *obj;
22302228
struct event_return_value return_value;
2231-
acpi_status status;
22322229
u16 device_state;
22332230
const struct key_entry *key;
22342231
u32 scancode;
22352232

2236-
status = wmi_get_event_data(value, &response);
2237-
if (status != AE_OK) {
2238-
pr_warn("bad event status 0x%x\n", status);
2239-
return;
2240-
}
2241-
2242-
obj = (union acpi_object *)response.pointer;
2243-
22442233
if (!obj)
22452234
return;
22462235
if (obj->type != ACPI_TYPE_BUFFER) {
22472236
pr_warn("Unknown response received %d\n", obj->type);
2248-
kfree(obj);
22492237
return;
22502238
}
22512239
if (obj->buffer.length != 8) {
22522240
pr_warn("Unknown buffer length %d\n", obj->buffer.length);
2253-
kfree(obj);
22542241
return;
22552242
}
22562243

22572244
return_value = *((struct event_return_value *)obj->buffer.pointer);
2258-
kfree(obj);
22592245

22602246
switch (return_value.function) {
22612247
case WMID_HOTKEY_EVENT:

drivers/platform/x86/asus-wmi.c

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4201,28 +4201,15 @@ static void asus_wmi_fnlock_update(struct asus_wmi *asus)
42014201

42024202
/* WMI events *****************************************************************/
42034203

4204-
static int asus_wmi_get_event_code(u32 value)
4204+
static int asus_wmi_get_event_code(union acpi_object *obj)
42054205
{
4206-
struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
4207-
union acpi_object *obj;
4208-
acpi_status status;
42094206
int code;
42104207

4211-
status = wmi_get_event_data(value, &response);
4212-
if (ACPI_FAILURE(status)) {
4213-
pr_warn("Failed to get WMI notify code: %s\n",
4214-
acpi_format_exception(status));
4215-
return -EIO;
4216-
}
4217-
4218-
obj = (union acpi_object *)response.pointer;
4219-
42204208
if (obj && obj->type == ACPI_TYPE_INTEGER)
42214209
code = (int)(obj->integer.value & WMI_EVENT_MASK);
42224210
else
42234211
code = -EIO;
42244212

4225-
kfree(obj);
42264213
return code;
42274214
}
42284215

@@ -4288,10 +4275,10 @@ static void asus_wmi_handle_event_code(int code, struct asus_wmi *asus)
42884275
pr_info("Unknown key code 0x%x\n", code);
42894276
}
42904277

4291-
static void asus_wmi_notify(u32 value, void *context)
4278+
static void asus_wmi_notify(union acpi_object *obj, void *context)
42924279
{
42934280
struct asus_wmi *asus = context;
4294-
int code = asus_wmi_get_event_code(value);
4281+
int code = asus_wmi_get_event_code(obj);
42954282

42964283
if (code < 0) {
42974284
pr_warn("Failed to get notify code: %d\n", code);

drivers/platform/x86/dell/dell-wmi-aio.c

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -70,20 +70,10 @@ static bool dell_wmi_aio_event_check(u8 *buffer, int length)
7070
return false;
7171
}
7272

73-
static void dell_wmi_aio_notify(u32 value, void *context)
73+
static void dell_wmi_aio_notify(union acpi_object *obj, void *context)
7474
{
75-
struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
76-
union acpi_object *obj;
7775
struct dell_wmi_event *event;
78-
acpi_status status;
7976

80-
status = wmi_get_event_data(value, &response);
81-
if (status != AE_OK) {
82-
pr_info("bad event status 0x%x\n", status);
83-
return;
84-
}
85-
86-
obj = (union acpi_object *)response.pointer;
8777
if (obj) {
8878
unsigned int scancode = 0;
8979

@@ -114,7 +104,6 @@ static void dell_wmi_aio_notify(u32 value, void *context)
114104
break;
115105
}
116106
}
117-
kfree(obj);
118107
}
119108

120109
static int __init dell_wmi_aio_input_setup(void)

drivers/platform/x86/hp/hp-wmi.c

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -834,28 +834,16 @@ static struct attribute *hp_wmi_attrs[] = {
834834
};
835835
ATTRIBUTE_GROUPS(hp_wmi);
836836

837-
static void hp_wmi_notify(u32 value, void *context)
837+
static void hp_wmi_notify(union acpi_object *obj, void *context)
838838
{
839-
struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
840839
u32 event_id, event_data;
841-
union acpi_object *obj;
842-
acpi_status status;
843840
u32 *location;
844841
int key_code;
845842

846-
status = wmi_get_event_data(value, &response);
847-
if (status != AE_OK) {
848-
pr_info("bad event status 0x%x\n", status);
849-
return;
850-
}
851-
852-
obj = (union acpi_object *)response.pointer;
853-
854843
if (!obj)
855844
return;
856845
if (obj->type != ACPI_TYPE_BUFFER) {
857846
pr_info("Unknown response received %d\n", obj->type);
858-
kfree(obj);
859847
return;
860848
}
861849

@@ -872,10 +860,8 @@ static void hp_wmi_notify(u32 value, void *context)
872860
event_data = *(location + 2);
873861
} else {
874862
pr_info("Unknown buffer length %d\n", obj->buffer.length);
875-
kfree(obj);
876863
return;
877864
}
878-
kfree(obj);
879865

880866
switch (event_id) {
881867
case HPWMI_DOCK_EVENT:

drivers/platform/x86/huawei-wmi.c

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -734,26 +734,14 @@ static void huawei_wmi_process_key(struct input_dev *idev, int code)
734734
sparse_keymap_report_entry(idev, key, 1, true);
735735
}
736736

737-
static void huawei_wmi_input_notify(u32 value, void *context)
737+
static void huawei_wmi_input_notify(union acpi_object *obj, void *context)
738738
{
739739
struct input_dev *idev = (struct input_dev *)context;
740-
struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
741-
union acpi_object *obj;
742-
acpi_status status;
743740

744-
status = wmi_get_event_data(value, &response);
745-
if (ACPI_FAILURE(status)) {
746-
dev_err(&idev->dev, "Unable to get event data\n");
747-
return;
748-
}
749-
750-
obj = (union acpi_object *)response.pointer;
751741
if (obj && obj->type == ACPI_TYPE_INTEGER)
752742
huawei_wmi_process_key(idev, obj->integer.value);
753743
else
754744
dev_err(&idev->dev, "Bad response type\n");
755-
756-
kfree(response.pointer);
757745
}
758746

759747
static int huawei_wmi_input_setup(struct device *dev, const char *guid)

drivers/platform/x86/lg-laptop.c

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -205,21 +205,11 @@ static union acpi_object *lg_wmbb(struct device *dev, u32 method_id, u32 arg1, u
205205
return (union acpi_object *)buffer.pointer;
206206
}
207207

208-
static void wmi_notify(u32 value, void *context)
208+
static void wmi_notify(union acpi_object *obj, void *context)
209209
{
210-
struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
211-
union acpi_object *obj;
212-
acpi_status status;
213210
long data = (long)context;
214211

215212
pr_debug("event guid %li\n", data);
216-
status = wmi_get_event_data(value, &response);
217-
if (ACPI_FAILURE(status)) {
218-
pr_err("Bad event status 0x%x\n", status);
219-
return;
220-
}
221-
222-
obj = (union acpi_object *)response.pointer;
223213
if (!obj)
224214
return;
225215

@@ -241,7 +231,6 @@ static void wmi_notify(u32 value, void *context)
241231

242232
pr_debug("Type: %i Eventcode: 0x%llx\n", obj->type,
243233
obj->integer.value);
244-
kfree(response.pointer);
245234
}
246235

247236
static void wmi_input_setup(void)

drivers/platform/x86/msi-wmi.c

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -170,20 +170,9 @@ static const struct backlight_ops msi_backlight_ops = {
170170
.update_status = bl_set_status,
171171
};
172172

173-
static void msi_wmi_notify(u32 value, void *context)
173+
static void msi_wmi_notify(union acpi_object *obj, void *context)
174174
{
175-
struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
176175
struct key_entry *key;
177-
union acpi_object *obj;
178-
acpi_status status;
179-
180-
status = wmi_get_event_data(value, &response);
181-
if (status != AE_OK) {
182-
pr_info("bad event status 0x%x\n", status);
183-
return;
184-
}
185-
186-
obj = (union acpi_object *)response.pointer;
187176

188177
if (obj && obj->type == ACPI_TYPE_INTEGER) {
189178
int eventcode = obj->integer.value;
@@ -192,7 +181,7 @@ static void msi_wmi_notify(u32 value, void *context)
192181
eventcode);
193182
if (!key) {
194183
pr_info("Unknown key pressed - %x\n", eventcode);
195-
goto msi_wmi_notify_exit;
184+
return;
196185
}
197186

198187
if (event_wmi->quirk_last_pressed) {
@@ -204,7 +193,7 @@ static void msi_wmi_notify(u32 value, void *context)
204193
pr_debug("Suppressed key event 0x%X - "
205194
"Last press was %lld us ago\n",
206195
key->code, ktime_to_us(diff));
207-
goto msi_wmi_notify_exit;
196+
return;
208197
}
209198
last_pressed = cur;
210199
}
@@ -221,9 +210,6 @@ static void msi_wmi_notify(u32 value, void *context)
221210
}
222211
} else
223212
pr_info("Unknown event received\n");
224-
225-
msi_wmi_notify_exit:
226-
kfree(response.pointer);
227213
}
228214

229215
static int __init msi_wmi_backlight_setup(void)

drivers/platform/x86/toshiba-wmi.c

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,26 +32,13 @@ static const struct key_entry toshiba_wmi_keymap[] __initconst = {
3232
{ KE_END, 0 }
3333
};
3434

35-
static void toshiba_wmi_notify(u32 value, void *context)
35+
static void toshiba_wmi_notify(union acpi_object *obj, void *context)
3636
{
37-
struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
38-
union acpi_object *obj;
39-
acpi_status status;
40-
41-
status = wmi_get_event_data(value, &response);
42-
if (ACPI_FAILURE(status)) {
43-
pr_err("Bad event status 0x%x\n", status);
44-
return;
45-
}
46-
47-
obj = (union acpi_object *)response.pointer;
4837
if (!obj)
4938
return;
5039

5140
/* TODO: Add proper checks once we have data */
5241
pr_debug("Unknown event received, obj type %x\n", obj->type);
53-
54-
kfree(response.pointer);
5542
}
5643

5744
static const struct dmi_system_id toshiba_wmi_dmi_table[] __initconst = {

0 commit comments

Comments
 (0)