[PATCH 1/3] UBUNTU: SAUCE: Allow registration of handler to multiple WMI events with same GUID

Tim Gardner tim.gardner at canonical.com
Wed Nov 24 19:20:07 UTC 2010


On 11/24/2010 12:13 PM, Tim Gardner wrote:
> On 11/24/2010 11:53 AM, Colin Ian King wrote:
>> BugLink: http://bugs.launchpad.net/bugs/676997
>>
>> WMI data blocks can contain WMI events with the same GUID but with
>> different notifiy_ids.  This patch enables a single event handler
>> to be registered and unregistered against all events against with
>> the same GUID.  The event handler is passed the notify_id of these
>> events and hence can differentiate between the differen events. The
>> patch also ensures we only register and unregister a device per
>> unique GUID.
>>
>> The original registration implementation just matched on the first
>> event with the matching GUID and left the other events with out a
>> handler.
>>
>> Signed-off-by: Eric Miao<eric.miao at canonical.com>
>> Signed-off-by: Colin Ian King<colin.king at canonical.com>
>> ---
>>    drivers/platform/x86/wmi.c |  125 +++++++++++++++++++++++--------------------
>>    1 files changed, 67 insertions(+), 58 deletions(-)
>>
>> diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c
>> index e4eaa14..3312c35 100644
>> --- a/drivers/platform/x86/wmi.c
>> +++ b/drivers/platform/x86/wmi.c
>> @@ -68,6 +68,7 @@ struct wmi_block {
>>    	wmi_notify_handler handler;
>>    	void *handler_data;
>>    	struct device *dev;
>> +	bool first_instance;
>>    };
>>
>>    static struct wmi_block wmi_blocks;
>> @@ -241,13 +242,16 @@ static bool find_guid(const char *guid_string, struct wmi_block **out)
>>    	char tmp[16], guid_input[16];
>>    	struct wmi_block *wblock;
>>    	struct guid_block *block;
>> -	struct list_head *p;
>>
>>    	wmi_parse_guid(guid_string, tmp);
>>    	wmi_swap_bytes(tmp, guid_input);
>>
>> -	list_for_each(p,&wmi_blocks.list) {
>> -		wblock = list_entry(p, struct wmi_block, list);
>> +	if ((out == NULL) || (*out == NULL))
>> +		wblock = list_entry(&wmi_blocks.list, struct wmi_block, list);
>> +	else
>> +		wblock = *out;
>> +
>> +	list_for_each_entry_continue(wblock,&wmi_blocks.list, list) {
>>    		block =&wblock->gblock;
>>
>>    		if (memcmp(block->guid, guid_input, 16) == 0) {
>
> I think the code in this clause should be:
>
> 			if (out&&  *out)
> 				*out = wblock;
> 			return 1;
>
> Otherwise it is possible to GP fault on a NULL dereference.
>

On the other hand, I did check all of the call sites for this function, 
and all send correctly initialized 'out' pointers. So,

Acked-by: Tim Gardner <tim.gardner at canonical.com>

rtg
-- 
Tim Gardner tim.gardner at canonical.com




More information about the kernel-team mailing list