diff options
| -rw-r--r-- | arch/x86/include/asm/mpspec.h | 1 | ||||
| -rw-r--r-- | arch/x86/kernel/acpi/boot.c | 7 | ||||
| -rw-r--r-- | arch/x86/kernel/apic/apic.c | 60 |
3 files changed, 59 insertions, 9 deletions
diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h index c2f94dcc92ce..32007041ef8c 100644 --- a/arch/x86/include/asm/mpspec.h +++ b/arch/x86/include/asm/mpspec.h | |||
| @@ -86,6 +86,7 @@ static inline void early_reserve_e820_mpc_new(void) { } | |||
| 86 | #endif | 86 | #endif |
| 87 | 87 | ||
| 88 | int generic_processor_info(int apicid, int version); | 88 | int generic_processor_info(int apicid, int version); |
| 89 | int __generic_processor_info(int apicid, int version, bool enabled); | ||
| 89 | 90 | ||
| 90 | #define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_LOCAL_APIC) | 91 | #define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_LOCAL_APIC) |
| 91 | 92 | ||
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 0447e314e7f5..7d668d172fce 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c | |||
| @@ -176,15 +176,10 @@ static int acpi_register_lapic(int id, u32 acpiid, u8 enabled) | |||
| 176 | return -EINVAL; | 176 | return -EINVAL; |
| 177 | } | 177 | } |
| 178 | 178 | ||
| 179 | if (!enabled) { | ||
| 180 | ++disabled_cpus; | ||
| 181 | return -EINVAL; | ||
| 182 | } | ||
| 183 | |||
| 184 | if (boot_cpu_physical_apicid != -1U) | 179 | if (boot_cpu_physical_apicid != -1U) |
| 185 | ver = boot_cpu_apic_version; | 180 | ver = boot_cpu_apic_version; |
| 186 | 181 | ||
| 187 | cpu = generic_processor_info(id, ver); | 182 | cpu = __generic_processor_info(id, ver, enabled); |
| 188 | if (cpu >= 0) | 183 | if (cpu >= 0) |
| 189 | early_per_cpu(x86_cpu_to_acpiid, cpu) = acpiid; | 184 | early_per_cpu(x86_cpu_to_acpiid, cpu) = acpiid; |
| 190 | 185 | ||
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index a8c94bb6b528..2dc01c38ad8e 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
| @@ -2021,7 +2021,53 @@ void disconnect_bsp_APIC(int virt_wire_setup) | |||
| 2021 | apic_write(APIC_LVT1, value); | 2021 | apic_write(APIC_LVT1, value); |
| 2022 | } | 2022 | } |
| 2023 | 2023 | ||
| 2024 | static int __generic_processor_info(int apicid, int version, bool enabled) | 2024 | /* |
| 2025 | * The number of allocated logical CPU IDs. Since logical CPU IDs are allocated | ||
| 2026 | * contiguously, it equals to current allocated max logical CPU ID plus 1. | ||
| 2027 | * All allocated CPU ID should be in [0, nr_logical_cpuidi), so the maximum of | ||
| 2028 | * nr_logical_cpuids is nr_cpu_ids. | ||
| 2029 | * | ||
| 2030 | * NOTE: Reserve 0 for BSP. | ||
| 2031 | */ | ||
| 2032 | static int nr_logical_cpuids = 1; | ||
| 2033 | |||
| 2034 | /* | ||
| 2035 | * Used to store mapping between logical CPU IDs and APIC IDs. | ||
| 2036 | */ | ||
| 2037 | static int cpuid_to_apicid[] = { | ||
| 2038 | [0 ... NR_CPUS - 1] = -1, | ||
| 2039 | }; | ||
| 2040 | |||
| 2041 | /* | ||
| 2042 | * Should use this API to allocate logical CPU IDs to keep nr_logical_cpuids | ||
| 2043 | * and cpuid_to_apicid[] synchronized. | ||
| 2044 | */ | ||
| 2045 | static int allocate_logical_cpuid(int apicid) | ||
| 2046 | { | ||
| 2047 | int i; | ||
| 2048 | |||
| 2049 | /* | ||
| 2050 | * cpuid <-> apicid mapping is persistent, so when a cpu is up, | ||
| 2051 | * check if the kernel has allocated a cpuid for it. | ||
| 2052 | */ | ||
| 2053 | for (i = 0; i < nr_logical_cpuids; i++) { | ||
| 2054 | if (cpuid_to_apicid[i] == apicid) | ||
| 2055 | return i; | ||
| 2056 | } | ||
| 2057 | |||
| 2058 | /* Allocate a new cpuid. */ | ||
| 2059 | if (nr_logical_cpuids >= nr_cpu_ids) { | ||
| 2060 | WARN_ONCE(1, "Only %d processors supported." | ||
| 2061 | "Processor %d/0x%x and the rest are ignored.\n", | ||
| 2062 | nr_cpu_ids - 1, nr_logical_cpuids, apicid); | ||
| 2063 | return -1; | ||
| 2064 | } | ||
| 2065 | |||
| 2066 | cpuid_to_apicid[nr_logical_cpuids] = apicid; | ||
| 2067 | return nr_logical_cpuids++; | ||
| 2068 | } | ||
| 2069 | |||
| 2070 | int __generic_processor_info(int apicid, int version, bool enabled) | ||
| 2025 | { | 2071 | { |
| 2026 | int cpu, max = nr_cpu_ids; | 2072 | int cpu, max = nr_cpu_ids; |
| 2027 | bool boot_cpu_detected = physid_isset(boot_cpu_physical_apicid, | 2073 | bool boot_cpu_detected = physid_isset(boot_cpu_physical_apicid, |
| @@ -2096,8 +2142,16 @@ static int __generic_processor_info(int apicid, int version, bool enabled) | |||
| 2096 | * for BSP. | 2142 | * for BSP. |
| 2097 | */ | 2143 | */ |
| 2098 | cpu = 0; | 2144 | cpu = 0; |
| 2099 | } else | 2145 | |
| 2100 | cpu = cpumask_next_zero(-1, cpu_present_mask); | 2146 | /* Logical cpuid 0 is reserved for BSP. */ |
| 2147 | cpuid_to_apicid[0] = apicid; | ||
| 2148 | } else { | ||
| 2149 | cpu = allocate_logical_cpuid(apicid); | ||
| 2150 | if (cpu < 0) { | ||
| 2151 | disabled_cpus++; | ||
| 2152 | return -EINVAL; | ||
| 2153 | } | ||
| 2154 | } | ||
| 2101 | 2155 | ||
| 2102 | /* | 2156 | /* |
| 2103 | * This can happen on physical hotplug. The sanity check at boot time | 2157 | * This can happen on physical hotplug. The sanity check at boot time |
