1 From 9778c14b4ca2c81e437fc2fd2b1f3d676937db27 Mon Sep 17 00:00:00 2001
2 From: Taku Izumi <izumi.taku@jp.fujitsu.com>
3 Date: Fri, 17 Oct 2008 13:48:36 +0900
4 Subject: ACPI/PCI: Fix possible race condition on _OSC evaluation
8 Fix possible race condition on _OSC evaluation.
10 Current _OSC evaluation code has possible race condition because it
11 maniputes osc_data linked list or its contents without any lock
14 Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
15 Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com>
16 Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
17 Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
20 drivers/pci/pci-acpi.c | 28 ++++++++++++++++++++--------
21 1 file changed, 20 insertions(+), 8 deletions(-)
23 --- a/drivers/pci/pci-acpi.c
24 +++ b/drivers/pci/pci-acpi.c
25 @@ -35,6 +35,8 @@ struct acpi_osc_args {
29 +static DEFINE_MUTEX(pci_acpi_lock);
31 static struct acpi_osc_data *acpi_get_osc_data(acpi_handle handle)
33 struct acpi_osc_data *data;
34 @@ -131,10 +133,12 @@ static acpi_status acpi_query_osc(acpi_h
35 if (ACPI_FAILURE(status))
38 + mutex_lock(&pci_acpi_lock);
39 osc_data = acpi_get_osc_data(handle);
41 printk(KERN_ERR "acpi osc data array is full\n");
47 /* do _OSC query for all possible controls */
48 @@ -149,7 +153,8 @@ static acpi_status acpi_query_osc(acpi_h
49 osc_data->query_result = osc_args.query_result;
50 osc_data->is_queried = 1;
54 + mutex_unlock(&pci_acpi_lock);
58 @@ -190,19 +195,25 @@ acpi_status pci_osc_control_set(acpi_han
59 if (ACPI_FAILURE(status))
62 + mutex_lock(&pci_acpi_lock);
63 osc_data = acpi_get_osc_data(handle);
65 printk(KERN_ERR "acpi osc data array is full\n");
71 ctrlset = (flags & OSC_CONTROL_MASKS);
79 if (osc_data->is_queried &&
80 - ((osc_data->query_result & ctrlset) != ctrlset))
82 + ((osc_data->query_result & ctrlset) != ctrlset)) {
83 + status = AE_SUPPORT;
87 control_set = osc_data->control_set | ctrlset;
88 osc_args.capbuf[OSC_QUERY_TYPE] = 0;
89 @@ -211,7 +222,8 @@ acpi_status pci_osc_control_set(acpi_han
90 status = acpi_run_osc(handle, &osc_args);
91 if (ACPI_SUCCESS(status))
92 osc_data->control_set = control_set;
95 + mutex_unlock(&pci_acpi_lock);
98 EXPORT_SYMBOL(pci_osc_control_set);