save_id() is called too early and uses xapic ops, which is fine up to 2566 cpus. However with that any CPU with APIC ID more than 255 will set wrong bit in online_cpus (since xapic ops only handle 8bit IDs, thus losing all higher bit x2apic might have). As result CPUs with id higher than 255 are not registered (they will trumple over elements in range 0-255 instead). To fix it move save_id() after the point where APs have switched to x2apic ops, to get non-truncated ID. Signed-off-by: Igor Mammedov --- lib/x86/setup.c | 2 +- x86/cstart.S | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/x86/setup.c b/lib/x86/setup.c index 122f0af3..c2f1c6d0 100644 --- a/lib/x86/setup.c +++ b/lib/x86/setup.c @@ -391,9 +391,9 @@ void ap_start64(void) setup_gdt_tss(); reset_apic(); load_idt(); - save_id(); enable_apic(); enable_x2apic(); + save_id(); ap_online(); } diff --git a/x86/cstart.S b/x86/cstart.S index 8fb7bdef..dafb330d 100644 --- a/x86/cstart.S +++ b/x86/cstart.S @@ -99,9 +99,9 @@ ap_start32: call load_idt call prepare_32 call reset_apic - call save_id call enable_apic call enable_x2apic + call save_id call ap_online /* ap_online() should never return */ -- 2.47.1