x86/kexec: Invalidate GDT/IDT from relocate_kernel() instead of earlier
authorDavid Woodhouse <dwmw@amazon.co.uk>
Wed, 26 Mar 2025 14:16:03 +0000 (14:16 +0000)
committerIngo Molnar <mingo@kernel.org>
Thu, 10 Apr 2025 10:17:14 +0000 (12:17 +0200)
Reduce the window during which exceptions are unhandled, by leaving the
GDT/IDT in place all the way into the relocate_kernel() function, until
the moment that %cr3 gets replaced.

Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Ard Biesheuvel <ardb@kernel.org>
Link: https://lore.kernel.org/r/20250326142404.256980-4-dwmw2@infradead.org
arch/x86/kernel/machine_kexec_64.c
arch/x86/kernel/relocate_kernel_64.S

index ecb0da54abd12dac37f49a3ecbfcb072eebc4ec5..949c9e4bfad22a7d609a2ec070067c9e9c07e7b0 100644 (file)
@@ -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,
index 8808cfca6322187dd56de019235103aaa396759e..3062cb3efc443516c83ff16b7d8f3d122216c995 100644 (file)
@@ -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 */