|
@@ -2021,7 +2021,53 @@ void disconnect_bsp_APIC(int virt_wire_setup)
|
|
|
apic_write(APIC_LVT1, value);
|
|
|
}
|
|
|
|
|
|
-static int __generic_processor_info(int apicid, int version, bool enabled)
|
|
|
+/*
|
|
|
+ * The number of allocated logical CPU IDs. Since logical CPU IDs are allocated
|
|
|
+ * contiguously, it equals to current allocated max logical CPU ID plus 1.
|
|
|
+ * All allocated CPU ID should be in [0, nr_logical_cpuidi), so the maximum of
|
|
|
+ * nr_logical_cpuids is nr_cpu_ids.
|
|
|
+ *
|
|
|
+ * NOTE: Reserve 0 for BSP.
|
|
|
+ */
|
|
|
+static int nr_logical_cpuids = 1;
|
|
|
+
|
|
|
+/*
|
|
|
+ * Used to store mapping between logical CPU IDs and APIC IDs.
|
|
|
+ */
|
|
|
+static int cpuid_to_apicid[] = {
|
|
|
+ [0 ... NR_CPUS - 1] = -1,
|
|
|
+};
|
|
|
+
|
|
|
+/*
|
|
|
+ * Should use this API to allocate logical CPU IDs to keep nr_logical_cpuids
|
|
|
+ * and cpuid_to_apicid[] synchronized.
|
|
|
+ */
|
|
|
+static int allocate_logical_cpuid(int apicid)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * cpuid <-> apicid mapping is persistent, so when a cpu is up,
|
|
|
+ * check if the kernel has allocated a cpuid for it.
|
|
|
+ */
|
|
|
+ for (i = 0; i < nr_logical_cpuids; i++) {
|
|
|
+ if (cpuid_to_apicid[i] == apicid)
|
|
|
+ return i;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Allocate a new cpuid. */
|
|
|
+ if (nr_logical_cpuids >= nr_cpu_ids) {
|
|
|
+ WARN_ONCE(1, "Only %d processors supported."
|
|
|
+ "Processor %d/0x%x and the rest are ignored.\n",
|
|
|
+ nr_cpu_ids - 1, nr_logical_cpuids, apicid);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ cpuid_to_apicid[nr_logical_cpuids] = apicid;
|
|
|
+ return nr_logical_cpuids++;
|
|
|
+}
|
|
|
+
|
|
|
+int __generic_processor_info(int apicid, int version, bool enabled)
|
|
|
{
|
|
|
int cpu, max = nr_cpu_ids;
|
|
|
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)
|
|
|
* for BSP.
|
|
|
*/
|
|
|
cpu = 0;
|
|
|
- } else
|
|
|
- cpu = cpumask_next_zero(-1, cpu_present_mask);
|
|
|
+
|
|
|
+ /* Logical cpuid 0 is reserved for BSP. */
|
|
|
+ cpuid_to_apicid[0] = apicid;
|
|
|
+ } else {
|
|
|
+ cpu = allocate_logical_cpuid(apicid);
|
|
|
+ if (cpu < 0) {
|
|
|
+ disabled_cpus++;
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
/*
|
|
|
* This can happen on physical hotplug. The sanity check at boot time
|