On 08/02/2023 05:09, Brian Gerst wrote:
On Tue, Feb 7, 2023 at 6:10 PM Usama Arif <usama.arif@xxxxxxxxxxxxx> wrote:
From: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
Rework the real-mode startup code to allow for APs to be brought up in
parallel. This is in two parts:
1. Introduce a bit-spinlock to prevent them from all using the real
mode stack at the same time.
2. Avoid the use of global variables for passing per-CPU information to
the APs.
To achieve the latter, export the cpuid_to_apicid[] array so that each
AP can find its own per_cpu data (and thus initial_gs, initial_stack and
early_gdt_descr) by searching therein based on its APIC ID.
Introduce a global variable 'smpboot_control' indicating to the AP how
it should find its APIC ID. For a serialized bringup, the APIC ID is
explicitly passed in the low bits of smpboot_control, while for parallel
mode there are flags directing the AP to find its APIC ID in CPUID leaf
0x0b (for X2APIC mode) or CPUID leaf 0x01 where 8 bits are sufficient.
For the serialized bringup case, it would be simpler to just put the
cpu number in the lower bits instead of the APIC id, skipping the
lookup.
--
Brian Gerst
I guess we could do something like below, it would save a few loops
through find_cpunr in serial case, but probably is as simple as just
using setup_AP and find_cpunr for all cases? Happy with either but if
there is a strong preference for below, can change in next revision?
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
index 656e6018b9d4..30aa543a0114 100644
--- a/arch/x86/kernel/head_64.S
+++ b/arch/x86/kernel/head_64.S
@@ -265,7 +265,10 @@ SYM_INNER_LABEL(secondary_startup_64_no_verify,
SYM_L_GLOBAL)
testl $STARTUP_APICID_CPUID_01, %edx
jnz .Luse_cpuid_01
andl $0x0FFFFFFF, %edx
- jmp .Lsetup_AP
+ mov $8, %eax
+ mul %edx
+ movq %rax, %rcx
+ jmp .Linit_cpu_data
.Luse_cpuid_01:
mov $0x01, %eax
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 8ffec5de2e2e..73dd87bf2f29 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1141,7 +1141,7 @@ static int do_boot_cpu(int apicid, int cpu, struct
task_struct *idle,
early_gdt_descr.address = (unsigned
long)get_cpu_gdt_rw(cpu);
initial_stack = idle->thread.sp;
} else if (!do_parallel_bringup) {
- smpboot_control = STARTUP_SECONDARY | apicid;
+ smpboot_control = STARTUP_SECONDARY | cpu;
}
/* Enable the espfix hack for this CPU */