aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/mpspec.h1
-rw-r--r--arch/x86/kernel/acpi/boot.c7
-rw-r--r--arch/x86/kernel/apic/apic.c60
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
88int generic_processor_info(int apicid, int version); 88int generic_processor_info(int apicid, int version);
89int __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
2024static 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 */
2032static int nr_logical_cpuids = 1;
2033
2034/*
2035 * Used to store mapping between logical CPU IDs and APIC IDs.
2036 */
2037static 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 */
2045static 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
2070int __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