From: David Woodhouse <dwmw@xxxxxxxxxxxx> There are some failure modes which lead to triple-faults in the relocate_kernel function, which is fairly much undebuggable for normal mortals. Adding a GDT in the relocate_kernel environment is step 1 towards being able to catch faults and do something more useful. Signed-off-by: David Woodhouse <dwmw@xxxxxxxxxxxx> --- arch/x86/kernel/relocate_kernel_64.S | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/arch/x86/kernel/relocate_kernel_64.S b/arch/x86/kernel/relocate_kernel_64.S index 9b6ed08e00ea..2af4ce593645 100644 --- a/arch/x86/kernel/relocate_kernel_64.S +++ b/arch/x86/kernel/relocate_kernel_64.S @@ -131,6 +131,21 @@ SYM_CODE_START_LOCAL_NOALIGN(identity_mapped) /* store the start address on the stack */ pushq %rdx +#ifdef DEBUG + /* Create a GDTR (16 bits limit, 64 bits addr) on stack */ + leaq .Lreloc_kernel_gdt(%rip), %r8 + pushq %r8 + pushw (%r8) + + /* Load the GDT, put the stack back */ + lgdt (%rsp) + addq $10, %rsp + + /* Test that we can load segments */ + movq %ds, %rax + movq %rax, %ds +#endif /* DEBUG */ + /* * Clear X86_CR4_CET (if it was set) such that we can clear CR0_WP * below. @@ -331,5 +346,16 @@ SYM_CODE_START_LOCAL_NOALIGN(swap_pages) int3 SYM_CODE_END(swap_pages) +#ifdef DEBUG +.Lreloc_kernel_gdt: + .word 1f - .Lreloc_kernel_gdt - 1 + .long 0 + .word 0 + .quad 0x00cf9a000000ffff /* __KERNEL32_CS */ + .quad 0x00af9a000000ffff /* __KERNEL_CS */ + .quad 0x00cf92000000ffff /* __KERNEL_DS */ +1: +#endif /* DEBUG */ + .skip KEXEC_CONTROL_CODE_MAX_SIZE - (. - relocate_kernel), 0xcc SYM_CODE_END(relocate_range); -- 2.44.0 _______________________________________________ kexec mailing list kexec@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/kexec