From: David Woodhouse Date: Mon, 16 Dec 2024 10:49:12 +0000 (+0000) Subject: x86/kexec: Invalidate GDT/IDT from relocate_kernel() instead of earlier X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=9500b0b9f7152444b9477af91a1574c016fd10bf;p=users%2Fdwmw2%2Flinux.git x86/kexec: Invalidate GDT/IDT from relocate_kernel() instead of earlier Commit 2114796ca041 ("x86/kexec: Mark machine_kexec() with __nocfi") marked the machine_kexec() function with __nocfi because I failed to make objtool happy when actually *providing* CFI information for the relocate_kernel() function that it calls, and __nocfi was the easy workaround. When that eventually gets fixed, the check on calling the relocate_kernel() function pointer may trap. Obviously that should never happen unless the function prototype gets messed up, but that's exactly what the CFI check is for. So it would be kind of helpful if the IDT was still in place and the trap could be *handled*. It can remain valid until the moment that %cr3 gets replaced, so shift the invalidation down into relocate_kernel() itself. This is a useful cleanup regardless of making CFI work, so do it now. Signed-off-by: David Woodhouse --- diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c index a2e00a814708a..7abc7aa0261b2 100644 --- a/arch/x86/kernel/machine_kexec_64.c +++ b/arch/x86/kernel/machine_kexec_64.c @@ -434,16 +434,10 @@ void __nocfi machine_kexec(struct kimage *image) * with from a table in memory. At no other time is the * descriptor table in memory accessed. * - * I take advantage of this here by force loading the - * segments, before I zap the gdt with an invalid value. + * Take advantage of this here by force loading the segments, + * before the GDT is zapped with an invalid value. */ load_segments(); - /* - * The gdt & idt are now invalid. - * If you want to load them you must set up your own idt & gdt. - */ - native_idt_invalidate(); - native_gdt_invalidate(); /* now call it */ image->start = relocate_kernel_ptr((unsigned long)image->head, diff --git a/arch/x86/kernel/relocate_kernel_64.S b/arch/x86/kernel/relocate_kernel_64.S index d58b4686645ce..17d41e6e1a4b8 100644 --- a/arch/x86/kernel/relocate_kernel_64.S +++ b/arch/x86/kernel/relocate_kernel_64.S @@ -79,8 +79,13 @@ SYM_CODE_START_NOALIGN(relocate_kernel) pushq %r15 pushf - /* zero out flags, and disable interrupts */ - pushq $0 + /* Invalidate GDT/IDT, zero out flags */ + pushq $0 + pushq $0 + + lidt (%rsp) + lgdt (%rsp) + addq $8, %rsp popfq /* Switch to the identity mapped page tables */