On Sun, Feb 26 2023 at 11:07, Usama Arif wrote: > @@ -265,7 +265,12 @@ SYM_INNER_LABEL(secondary_startup_64_no_verify, SYM_L_GLOBAL) > * addresses where we're currently running on. We have to do that here > * because in 32bit we couldn't load a 64bit linear address. > */ > - lgdt early_gdt_descr(%rip) > + subq $16, %rsp > + movw $(GDT_SIZE-1), (%rsp) > + leaq gdt_page(%rdx), %rax Even on !SMP gdt_page is in the 0...__per_cpu_end range. Which means that on !SMP this results in: leaq 0xb000(%rdx),%rax and RDX is 0. That's not really a valid GDT pointer, right? > + movq %rax, 2(%rsp) > + lgdt (%rsp) and obviously that's equally broken for the task stack part: > movq pcpu_hot + X86_current_task(%rdx), %rax This needs: --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S @@ -239,7 +239,7 @@ SYM_INNER_LABEL(secondary_startup_64_no_ /* Get the per cpu offset for the given CPU# which is in ECX */ movq __per_cpu_offset(,%rcx,8), %rdx #else - xorl %edx, %edx + leaq INIT_PER_CPU_VAR(fixed_percpu_data)(%rip), %rdx #endif /* CONFIG_SMP */ /* in the initial_stack patch, which then allows to remove this hunk in the initial_gs patch: @@ -286,9 +286,6 @@ SYM_INNER_LABEL(secondary_startup_64_no_ * the per cpu areas are set up. */ movl $MSR_GS_BASE,%ecx -#ifndef CONFIG_SMP - leaq INIT_PER_CPU_VAR(fixed_percpu_data)(%rip), %rdx -#endif movl %edx, %eax shrq $32, %rdx wrmsr Maybe we should enforce CONFIG_SMP=y first :) Thanks, tglx