Skip to content

Commit 744b6fb

Browse files
Salil Mehtajongwu
Salil Mehta
authored andcommitted
arm64: kernel: Arch specific ACPI hooks(like logical cpuid<->hwid etc.)
To support virtual cpu hotplug, some arch specific 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 8d06116 commit 744b6fb

File tree

1 file changed

+80
-0
lines changed

1 file changed

+80
-0
lines changed

arch/arm64/kernel/smp.c

+80
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,86 @@ struct acpi_madt_generic_interrupt *acpi_cpu_get_madt_gicc(int cpu)
543543
return &cpu_madt_gicc[cpu];
544544
}
545545

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

0 commit comments

Comments
 (0)