Re: Regression in module wmi since 2.6.32 (bisected to commit 1caab3c)

Carlos Corbacho
2009-12-26T01:18:33Z

On Friday 25 December 2009 22:09:28 Larry Finger wrote:
> On 12/25/2009 03:58 PM, Carlos Corbacho wrote:
> > On Friday 25 December 2009 21:35:49 Larry Finger wrote:
> >> Should I attach the files DSDT.dat, acpidump.out, or DSDT?
> >
> > DSDT from /proc/acpi/dsdt will do fine for my purposes.
>
> Attached.

This is the same as bugzilla #14846 - in both cases, the GUID 05901221-D566-11D1-B2F0-00A0C9062910 (a data block query) is duplicated in two different devices, although both look like they are nVidia related hooks.

Since we don't currently have any in kernel drivers that use that stuff, and the query in question just returns a binary MOF, the simplest solution (for now) seems to be to just ignore these duplicates - if and when someone wants to support these hooks, they can clean the mess up properly when they figure out how WMI is supposed to cope with conflicting GUID's.

Matthew, you looked at NVIF for your sins, can you see a better solution? We could just blacklist the offending GUID, rather than trying to catch all duplicates? Although just ignoring all duplicates strikes me as a better solution to catch the next time that J Random BIOS Developer decides to duplicate GUIDs in WMI.

Initial patch below which takes the "ignore all duplicate GUIDs" approach.

-Carlos
--
E-Mail: carlos@strangeworlds.co.uk
Web: strangeworlds.co.uk
GPG Key ID: 0x23EE722D
---
ACPI: WMI: Handle duplicate GUIDs

From: Carlos Corbacho <carlos@strangeworlds.co.uk>

It would appear that in BIOS's with nVidia hooks, the GUID
05901221-D566-11D1-B2F0-00A0C9062910 is duplicated. For now, the simplest
solution is to just ignore any duplicate GUIDs. These particular hooks are not
currently supported/ used in the kernel, so whoever does that can figure out
what the 'right' solution should be (if there's a better one).
---
drivers/platform/x86/wmi.c | 26 ++++++++++++++++++++++++++
1 files changed, 26 insertions(+), 0 deletions(-)

diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c
index 9f93d6c..483827f 100644
--- a/drivers/platform/x86/wmi.c
+++ b/drivers/platform/x86/wmi.c
@@ -716,6 +716,22 @@ static int wmi_class_init(void)
return ret;
}

+static bool guid_already_parsed(const char *guid_string) {
+ struct guid_block *gblock;
+ struct wmi_block *wblock;
+ struct list_head *p;
+
+ list_for_each(p, &wmi_blocks.list) {
+ wblock = list_entry(p, struct wmi_block, list);
+ gblock = &wblock->gblock;
+
+ if (strncmp(gblock->guid, guid_string, 16) != 0) {
+ return true;
+ }
+ }
+ return false;
+}
+
/*
* Parse the _WDG method for the GUID data blocks
*/
@@ -747,6 +763,16 @@ static __init acpi_status parse_wdg(acpi_handle handle)
memcpy(gblock, obj->buffer.pointer, obj->buffer.length);

for (i = 0; i < total; i++) {
+ /*
+ Some WMI devices, like those for nVidia hooks, have a
+ duplicate GUID. It's not clear what we should do in this
+ case yet, so for now, we'll just ignore the duplicate.
+ Anyone who wants to add support for that device can come
+ up with a better workaround for the mess then.
+ */
+ if (guid_already_parsed(gblock[i].guid) == true) {
+ continue;
+ }
wblock = kzalloc(sizeof(struct wmi_block), GFP_KERNEL);
if (!wblock)
return AE_NO_MEMORY;