ACPI / scan: bail out early if failed to parse APIC ID for CPU
authorJiang Liu <jiang.liu@linux.intel.com>
Thu, 9 Jan 2014 08:15:19 +0000 (16:15 +0800)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Sat, 11 Jan 2014 00:31:38 +0000 (01:31 +0100)
Enhance ACPI CPU hotplug driver to print clear error message and
bail out early if BIOS returns wrong value in ACPI MADT table or
_MAT method. Otherwise it will add the CPU device even if failed
to get APIC ID and fails any operations against sysfs interface:
/sys/devices/system/cpu/cpux/online

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/acpi/acpi_processor.c

index 3c1d6b0c09a4b7d1eeeb9347a7c743d1c7487988..6ce71b07c197000eeb56dc699a35a3168e41fca4 100644 (file)
@@ -212,7 +212,7 @@ static int acpi_processor_get_info(struct acpi_device *device)
        union acpi_object object = { 0 };
        struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
        struct acpi_processor *pr = acpi_driver_data(device);
-       int cpu_index, device_declaration = 0;
+       int apic_id, cpu_index, device_declaration = 0;
        acpi_status status = AE_OK;
        static int cpu0_initialized;
        unsigned long long value;
@@ -258,18 +258,21 @@ static int acpi_processor_get_info(struct acpi_device *device)
                device_declaration = 1;
                pr->acpi_id = value;
        }
-       pr->apic_id = acpi_get_apicid(pr->handle, device_declaration,
-                                       pr->acpi_id);
-       cpu_index = acpi_map_cpuid(pr->apic_id, pr->acpi_id);
 
-       /* Handle UP system running SMP kernel, with no LAPIC in MADT */
-       if (!cpu0_initialized && (cpu_index == -1) &&
-           (num_online_cpus() == 1)) {
-               cpu_index = 0;
+       apic_id = acpi_get_apicid(pr->handle, device_declaration, pr->acpi_id);
+       if (apic_id < 0) {
+               acpi_handle_err(pr->handle, "failed to get CPU APIC ID.\n");
+               return -ENODEV;
        }
+       pr->apic_id = apic_id;
 
-       cpu0_initialized = 1;
-
+       cpu_index = acpi_map_cpuid(pr->apic_id, pr->acpi_id);
+       if (!cpu0_initialized) {
+               cpu0_initialized = 1;
+               /* Handle UP system running SMP kernel, with no LAPIC in MADT */
+               if ((cpu_index == -1) && (num_online_cpus() == 1))
+                       cpu_index = 0;
+       }
        pr->id = cpu_index;
 
        /*
@@ -282,6 +285,7 @@ static int acpi_processor_get_info(struct acpi_device *device)
                if (ret)
                        return ret;
        }
+
        /*
         * On some boxes several processors use the same processor bus id.
         * But they are located in different scope. For example: