Skip to content

Commit d911b9b

Browse files
Salil Mehtajongwu
authored andcommitted
arm64: kernel: Arch specific ACPI hooks(like logical cpuid<->hwid etc.)
To support virtual cpu hotplug, some arch specifc hooks must be facilitated. These hooks are called by the generic ACPI cpu hotplug framework during a vcpu hot-(un)plug event handling. The changes required involve: 1. Allocation of the logical cpuid corresponding to the hwid/mpidr 2. Mapping of logical cpuid to hwid/mpidr and marking present 3. Removing vcpu from present mask during hot-unplug 4. For arm64, all possible cpus are registered within topology_init() Hence, we need to override the weak ACPI call of arch_register_cpu() (which returns -ENODEV) and return success. 5. NUMA node mapping set for this vcpu using SRAT Table info during init time will be discarded as the logical cpu-ids used at that time might not be correct. This mapping will be set again using the proximity/node info obtained by evaluating _PXM ACPI method. Note, during hot unplug of vcpu, we do not unmap the association between the logical cpuid and hwid/mpidr. This remains persistent. Signed-off-by: Salil Mehta <[email protected]> Signed-off-by: Xiongfeng Wang <[email protected]>
1 parent cc3595c commit d911b9b

File tree

1 file changed

+80
-0
lines changed

1 file changed

+80
-0
lines changed

arch/arm64/kernel/smp.c

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,86 @@ struct acpi_madt_generic_interrupt *acpi_cpu_get_madt_gicc(int cpu)
545545
return &cpu_madt_gicc[cpu];
546546
}
547547

548+
#ifdef CONFIG_ACPI_HOTPLUG_CPU
549+
int arch_register_cpu(int num)
550+
{
551+
return 0;
552+
}
553+
554+
static int set_numa_node_for_cpu(acpi_handle handle, int cpu)
555+
{
556+
#ifdef CONFIG_ACPI_NUMA
557+
int node_id;
558+
559+
/* will evaluate _PXM */
560+
node_id = acpi_get_node(handle);
561+
if (node_id != NUMA_NO_NODE)
562+
set_cpu_numa_node(cpu, node_id);
563+
#endif
564+
return 0;
565+
}
566+
567+
static void unset_numa_node_for_cpu(int cpu)
568+
{
569+
#ifdef CONFIG_ACPI_NUMA
570+
set_cpu_numa_node(cpu, NUMA_NO_NODE);
571+
#endif
572+
}
573+
574+
static int allocate_logical_cpuid(u64 physid)
575+
{
576+
int first_invalid_idx = -1;
577+
bool first = true;
578+
int i;
579+
580+
for_each_possible_cpu(i) {
581+
/*
582+
* logical cpuid<->hwid association remains persistent once
583+
* established
584+
*/
585+
if (cpu_logical_map(i) == physid)
586+
return i;
587+
588+
if ((cpu_logical_map(i) == INVALID_HWID) && first) {
589+
first_invalid_idx = i;
590+
first = false;
591+
}
592+
}
593+
594+
return first_invalid_idx;
595+
}
596+
597+
int acpi_unmap_cpu(int cpu)
598+
{
599+
set_cpu_present(cpu, false);
600+
unset_numa_node_for_cpu(cpu);
601+
602+
return 0;
603+
}
604+
605+
int acpi_map_cpu(acpi_handle handle, phys_cpuid_t physid, u32 acpi_id,
606+
int *cpuid)
607+
{
608+
int cpu;
609+
610+
cpu = allocate_logical_cpuid(physid);
611+
if (cpu < 0) {
612+
pr_warn("Unable to map logical cpuid to physid 0x%llx\n",
613+
physid);
614+
return -ENOSPC;
615+
}
616+
617+
/* map the logical cpu id to cpu MPIDR */
618+
__cpu_logical_map[cpu] = physid;
619+
set_numa_node_for_cpu(handle, cpu);
620+
621+
set_cpu_present(cpu, true);
622+
*cpuid = cpu;
623+
624+
return 0;
625+
}
626+
#endif
627+
548628
/*
549629
* acpi_map_gic_cpu_interface - parse processor MADT entry
550630
*

0 commit comments

Comments
 (0)