[RFC PATCH v2 0/16] x86/kexec: Add exception handling for relocate_kernel and further yak-shaving
David Woodhouse
dwmw2 at infradead.org
Fri Nov 22 14:38:09 PST 2024
Make it easier to pass information into relocate_kernel by allowing it to
have actual variables which are set from the real kernel. To do this, move
it into the kernel's .data section, keeping its data and code together
with linker script rules. Execute it from the *copy* instead of its
original in the kernel data section, and clean it up a bit.
Then do what I originally started with, which is add a GDT+IDT and some
exception handling so we can actually catch problems instead of just
suffering a triple fault and wondering why the world hates us.
The serial output of the debug mode can be cleaned up a little, and it's
even now possible to pass in information about which serial port to write
to.
I'll also work on resyncing with the i386 code and applying as many of
these cleanups there as possible. And probably also make the 64-bit one
use a separate image->arch.pgd instead of lumping it into a single 8KiB
"control page" as we do on x86_64 at the moment.
But the basic cleanups are probably ready for another round of bikeshedding.
Testing the preserve_context mode with the following test case:
#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;
}
David Woodhouse (16):
x86/kexec: Clean up and document register use in relocate_kernel_64.S
x86/kexec: Use named labels in swap_pages in relocate_kernel_64.S
x86/kexec: Restore GDT on return from preserve_context kexec
x86/kexec: Only swap pages for preserve_context mode
x86/kexec: Invoke copy of relocate_kernel() instead of the original
x86/kexec: Move relocate_kernel to kernel .data section
x86/kexec: Add data section to relocate_kernel
x86/kexec: Copy control page into place in machine_kexec_prepare()
x86/kexec: Drop page_list argument from relocate_kernel()
x86/kexec: Eliminate writes through kernel mapping of relocate_kernel page
x86/kexec: Clean up register usage in relocate_kernel()
x86/kexec: Mark relocate_kernel page as ROX instead of RWX
x86/kexec: Debugging support: load a GDT
x86/kexec: Debugging support: Load an IDT and basic exception entry points
x86/kexec: Debugging support: Dump registers on exception
[DO NOT MERGE] x86/kexec: enable DEBUG
arch/x86/include/asm/kexec.h | 13 +-
arch/x86/include/asm/sections.h | 1 +
arch/x86/kernel/machine_kexec_64.c | 55 +++--
arch/x86/kernel/relocate_kernel_64.S | 384 +++++++++++++++++++++++++++--------
arch/x86/kernel/vmlinux.lds.S | 12 +-
5 files changed, 358 insertions(+), 107 deletions(-)
More information about the kexec
mailing list