Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ACPI: processor: fix acpi_get_cpuid for UP processor

For UP processor, it is likely that no _MAT method or MADT table defined.
So currently acpi_get_cpuid(...) always return -1 for UP processor.
This is wrong. It should return valid value for CPU0.

In the other hand, BIOS may define multiple CPU handles even for UP
processor, for example

Scope (_PR)
{
Processor (CPU0, 0x00, 0x00000410, 0x06) {}
Processor (CPU1, 0x01, 0x00000410, 0x06) {}
Processor (CPU2, 0x02, 0x00000410, 0x06) {}
Processor (CPU3, 0x03, 0x00000410, 0x06) {}
}

We should only return valid value for CPU0's acpi handle.
And return invalid value for others.

http://marc.info/?t=132329819900003&r=1&w=2

Cc: stable@vger.kernel.org
Reported-and-tested-by: wallak@free.fr
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>

authored by

Lin Ming and committed by
Len Brown
d640113f 805a6af8

+24 -2
+24 -2
drivers/acpi/processor_core.c
··· 173 173 apic_id = map_mat_entry(handle, type, acpi_id); 174 174 if (apic_id == -1) 175 175 apic_id = map_madt_entry(type, acpi_id); 176 - if (apic_id == -1) 177 - return apic_id; 176 + if (apic_id == -1) { 177 + /* 178 + * On UP processor, there is no _MAT or MADT table. 179 + * So above apic_id is always set to -1. 180 + * 181 + * BIOS may define multiple CPU handles even for UP processor. 182 + * For example, 183 + * 184 + * Scope (_PR) 185 + * { 186 + * Processor (CPU0, 0x00, 0x00000410, 0x06) {} 187 + * Processor (CPU1, 0x01, 0x00000410, 0x06) {} 188 + * Processor (CPU2, 0x02, 0x00000410, 0x06) {} 189 + * Processor (CPU3, 0x03, 0x00000410, 0x06) {} 190 + * } 191 + * 192 + * Ignores apic_id and always return 0 for CPU0's handle. 193 + * Return -1 for other CPU's handle. 194 + */ 195 + if (acpi_id == 0) 196 + return acpi_id; 197 + else 198 + return apic_id; 199 + } 178 200 179 201 #ifdef CONFIG_SMP 180 202 for_each_possible_cpu(i) {