Lines Matching +full:cpu +full:- +full:map
1 // SPDX-License-Identifier: GPL-2.0-only
3 * CPU/APIC topology
24 #define pr_fmt(fmt) "CPU topo: " fmt
25 #include <linux/cpu.h>
35 #include "cpu.h"
38 * Map cpu index to physical APIC ID
48 /* Used for CPU number allocation and parallel CPU bringup */
49 u32 cpuid_to_apicid[] __ro_after_init = { [0 ... NR_CPUS - 1] = BAD_APICID, };
52 static struct { DECLARE_BITMAP(map, MAX_LOCAL_APIC); } apic_maps[TOPO_MAX_DOMAIN] __ro_after_init;
56 * with 1 as CPU #0 is reserved for the boot CPU.
70 #define domain_weight(_dom) bitmap_weight(apic_maps[_dom].map, MAX_LOCAL_APIC)
72 bool arch_match_cpu_phys_id(int cpu, u64 phys_id) in arch_match_cpu_phys_id() argument
74 return phys_id == (u64)cpuid_to_apicid[cpu]; in arch_match_cpu_phys_id()
78 static void cpu_mark_primary_thread(unsigned int cpu, unsigned int apicid) in cpu_mark_primary_thread() argument
80 if (!(apicid & (__max_threads_per_core - 1))) in cpu_mark_primary_thread()
81 cpumask_set_cpu(cpu, &__cpu_primary_thread_mask); in cpu_mark_primary_thread()
84 static inline void cpu_mark_primary_thread(unsigned int cpu, unsigned int apicid) { } in cpu_mark_primary_thread() argument
95 return apicid & (UINT_MAX << x86_topo_system.dom_shifts[dom - 1]); in topo_apicid()
102 /* CPU# to APICID mapping is persistent once it is established */ in topo_lookup_cpuid()
107 return -ENODEV; in topo_lookup_cpuid()
112 int cpu = topo_lookup_cpuid(apic_id); in topo_get_cpunr() local
114 if (cpu >= 0) in topo_get_cpunr()
115 return cpu; in topo_get_cpunr()
120 static void topo_set_cpuids(unsigned int cpu, u32 apic_id, u32 acpi_id) in topo_set_cpuids() argument
123 early_per_cpu(x86_cpu_to_apicid, cpu) = apic_id; in topo_set_cpuids()
124 early_per_cpu(x86_cpu_to_acpiid, cpu) = acpi_id; in topo_set_cpuids()
126 set_cpu_present(cpu, true); in topo_set_cpuids()
139 * CPU is the real BSP. If it is not, then do not register the APIC in check_for_real_bsp()
144 * because the boot CPU APIC ID is registered before that without in check_for_real_bsp()
152 * BSP bit in the APICBASE MSR. If the CPU does not have the in check_for_real_bsp()
163 * If the boot CPU has the APIC BSP bit set then the in check_for_real_bsp()
164 * firmware enumeration is agreeing. If the CPU does not in check_for_real_bsp()
180 pr_warn("Assuming crash kernel. Limiting to one CPU to prevent machine INIT\n"); in check_for_real_bsp()
185 pr_warn("Boot CPU APIC ID not the first enumerated APIC ID: %x != %x\n", in check_for_real_bsp()
190 * The boot CPU has the APIC BSP bit set. Use it and complain in check_for_real_bsp()
208 unsigned long *map) in topo_unit_count() argument
216 for (id = find_next_bit(map, end, lvlid); id < end; id = find_next_bit(map, end, ++id)) in topo_unit_count()
223 int cpu, dom; in topo_register_apic() local
229 * Double registration is valid in case of the boot CPU in topo_register_apic()
235 cpu = 0; in topo_register_apic()
237 cpu = topo_get_cpunr(apic_id); in topo_register_apic()
239 cpuid_to_apicid[cpu] = apic_id; in topo_register_apic()
240 topo_set_cpuids(cpu, apic_id, acpi_id); in topo_register_apic()
250 pr_info_once("Ignoring hot-pluggable APIC ID %x in present package.\n", in topo_register_apic()
265 set_bit(topo_apicid(apic_id, dom), apic_maps[dom].map); in topo_register_apic()
269 * topology_register_apic - Register an APIC in early topology maps
272 * @present: True if the corresponding CPU is present
277 pr_err_once("APIC ID %x exceeds kernel limit of: %x\n", apic_id, MAX_LOCAL_APIC - 1); in topology_register_apic()
287 /* CPU numbers exhausted? */ in topology_register_apic()
289 pr_warn_once("CPU limit of %d reached. Ignoring further CPUs\n", nr_cpu_ids); in topology_register_apic()
298 * topology_register_boot_apic - Register the boot CPU APIC
301 * Separate so CPU #0 can be assigned
312 * topology_get_logical_id - Retrieve the logical ID at a given topology domain level
321 * - >= 0: The requested logical ID
322 * - -ERANGE: @apicid is out of range
323 * - -ENODEV: @apicid is not registered
331 return -ERANGE; in topology_get_logical_id()
332 if (!test_bit(lvlid, apic_maps[at_level].map)) in topology_get_logical_id()
333 return -ENODEV; in topology_get_logical_id()
335 return bitmap_weight(apic_maps[at_level].map, lvlid); in topology_get_logical_id()
340 * topology_unit_count - Retrieve the count of specified units at a given topology domain level
365 if (!test_bit(lvlid, apic_maps[at_level].map)) in topology_unit_count()
371 return topo_unit_count(lvlid, at_level, apic_maps[which_units].map); in topology_unit_count()
376 * topology_hotplug_apic - Handle a physical hotplugged APIC after boot
382 int cpu; in topology_hotplug_apic() local
385 return -EINVAL; in topology_hotplug_apic()
388 if (!test_bit(apic_id, apic_maps[TOPO_SMT_DOMAIN].map)) in topology_hotplug_apic()
389 return -ENODEV; in topology_hotplug_apic()
391 cpu = topo_lookup_cpuid(apic_id); in topology_hotplug_apic()
392 if (cpu < 0) in topology_hotplug_apic()
393 return -ENOSPC; in topology_hotplug_apic()
396 topo_set_cpuids(cpu, apic_id, acpi_id); in topology_hotplug_apic()
397 cpu_mark_primary_thread(cpu, apic_id); in topology_hotplug_apic()
398 return cpu; in topology_hotplug_apic()
402 * topology_hotunplug_apic - Remove a physical hotplugged APIC after boot
403 * @cpu: The CPU number for which the APIC ID is removed
405 void topology_hotunplug_apic(unsigned int cpu) in topology_hotunplug_apic() argument
407 u32 apic_id = cpuid_to_apicid[cpu]; in topology_hotunplug_apic()
412 per_cpu(x86_cpu_to_apicid, cpu) = BAD_APICID; in topology_hotunplug_apic()
414 set_cpu_present(cpu, false); in topology_hotunplug_apic()
422 * topology_apply_cmdline_limits_early - Apply topology command line limits early
464 unsigned int cnta, cntb, cpu, allowed = 1; in topology_init_possible_cpus() local
481 disabled += assigned - nr_cpu_ids; in topology_init_possible_cpus()
491 disabled = allowed - assigned; in topology_init_possible_cpus()
502 __max_dies_per_package = 1U << (get_count_order(cntb) - get_count_order(cnta)); in topology_init_possible_cpus()
517 firstid = find_first_bit(apic_maps[TOPO_SMT_DOMAIN].map, MAX_LOCAL_APIC); in topology_init_possible_cpus()
530 /* Assign CPU numbers to non-present CPUs */ in topology_init_possible_cpus()
531 for (apicid = 0; disabled; disabled--, apicid++) { in topology_init_possible_cpus()
532 apicid = find_next_andnot_bit(apic_maps[TOPO_SMT_DOMAIN].map, phys_cpu_present_map, in topology_init_possible_cpus()
539 for (cpu = 0; cpu < allowed; cpu++) { in topology_init_possible_cpus()
540 apicid = cpuid_to_apicid[cpu]; in topology_init_possible_cpus()
542 set_cpu_possible(cpu, true); in topology_init_possible_cpus()
547 cpu_mark_primary_thread(cpu, apicid); in topology_init_possible_cpus()
548 set_cpu_present(cpu, test_bit(apicid, phys_cpu_present_map)); in topology_init_possible_cpus()
553 * Late SMP disable after sizing CPU masks when APIC/IOAPIC setup failed.