On Mon, 2024-11-18 at 09:54 +0800, Dave Young wrote: > Hi David, > > I did not see anyone around me test this. The kexec jump feature > was > introduced by Ying [cced him] in below kernel comment, probably you > can try the steps mentioned in the commit log: > commit 3ab83521378268044a448113c6aa9a9e245f4d2f > Author: Huang Ying <ying.huang@xxxxxxxxx> > Date: Fri Jul 25 19:45:07 2008 -0700 > > kexec jump Thanks. I built an object which contains only a single 'ret' instruction, but I couldn't get kexec-tools to load that without loading a bunch of its own purgatory too, which breaks things. So I did it manually: #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <linux/kexec.h> #include <linux/reboot.h> #include <sys/reboot.h> #include <sys/syscall.h> int main (void) { struct kexec_segment segment = {}; unsigned char purgatory[] = { 0x66, 0xba, 0xf8, 0x03, // mov $0x3f8, %dx 0xb0, 0x42, // mov $0x42, %al 0xee, // outb %al, (%dx) 0xc3, // ret }; int ret; segment.buf = &purgatory; segment.bufsz = sizeof(purgatory); segment.mem = (void *)0x400000; segment.memsz = 0x1000; ret = syscall(__NR_kexec_load, 0x400000, 1, &segment, KEXEC_PRESERVE_CONTEXT); if (ret) { perror("kexec_load"); exit(1); } return 0; } That works, prints a 'B' to the serial port, then returns to the kernel... which immediately crashes. Fixed thus, and now I can actually test that my own changes are breaking it any *more*... From: David Woodhouse <dwmw@xxxxxxxxxxxx> Subject: [PATCH] x86/kexec: Restore GDT on return from preserve_context kexec The restore_processor_state() function explicitly states that "the asm code that gets us here will have restored a usable GDT". That wasn't true in the case of returning from a preserve_context kexec. Make it so. Without this, the kernel was depending on the called function to reload an appropriate GDT. Signed-off-by: David Woodhouse <dwmw@xxxxxxxxxxxx> --- arch/x86/kernel/relocate_kernel_64.S | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/x86/kernel/relocate_kernel_64.S b/arch/x86/kernel/relocate_kernel_64.S index ca01e3e2f097..ed2ae50535dd 100644 --- a/arch/x86/kernel/relocate_kernel_64.S +++ b/arch/x86/kernel/relocate_kernel_64.S @@ -252,6 +252,11 @@ SYM_CODE_START_LOCAL_NOALIGN(virtual_mapped) movq CR0(%r8), %r8 movq %rax, %cr3 movq %r8, %cr0 + + /* Saved in save_processor_state. */ + movq $saved_context, %rax + lgdt saved_context_gdt_desc(%rax) + movq %rbp, %rax popf -- 2.47.0
<<attachment: smime.p7s>>