[PATCH v5 13/20] x86/kexec: Mark relocate_kernel page as ROX instead of RWX
David Woodhouse
dwmw2 at infradead.org
Thu Dec 12 02:30:10 PST 2024
On Wed, 2024-12-11 at 18:44 -0700, Nathan Chancellor wrote:
> Hi David,
>
> On Thu, Dec 05, 2024 at 03:05:19PM +0000, David Woodhouse wrote:
> > From: David Woodhouse <dwmw at amazon.co.uk>
> >
> > All writes to the page now happen before it gets marked as executable
> > (or after it's already switched to the identmap page tables where it's
> > OK to be RWX).
> >
> > Signed-off-by: David Woodhouse <dwmw at amazon.co.uk>
> > ---
> > arch/x86/kernel/machine_kexec_64.c | 3 ++-
> > 1 file changed, 2 insertions(+), 1 deletion(-)
> >
> > diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c
> > index c9fd60f8f806..9232ad1562c8 100644
> > --- a/arch/x86/kernel/machine_kexec_64.c
> > +++ b/arch/x86/kernel/machine_kexec_64.c
> > @@ -323,7 +323,7 @@ int machine_kexec_prepare(struct kimage *image)
> >
> > __memcpy(control_page, __relocate_kernel_start, reloc_end - reloc_start);
> >
> > - set_memory_x((unsigned long)control_page, 1);
> > + set_memory_rox((unsigned long)control_page, 1);
> >
> > return 0;
> > }
> > @@ -333,6 +333,7 @@ void machine_kexec_cleanup(struct kimage *image)
> > void *control_page = page_address(image->control_code_page);
> >
> > set_memory_nx((unsigned long)control_page, 1);
> > + set_memory_rw((unsigned long)control_page, 1);
> >
> > free_transition_pgtable(image);
> > }
> > --
> > 2.47.0
> >
>
> I just bisected a change in behavior that I see in to this change in
> -next as commit 5a82223e0743 ("x86/kexec: Mark relocate_kernel page as
> ROX instead of RWX"). I usually kexec my machines by running:
>
> # kexec --load /boot/vmlinuz-linux --initrd /boot/initramfs-linux.img --reuse-cmdline
>
> # systemctl kexec
>
> to cleanly shutdown userspace then kexec into the new kernel after
> installing it via the package manager. After this change, I get sent to
> systemd-boot after running 'systemctl kexec', which selects the default
> entry, my distribution kernel.
>
> I just see:
>
> [ OK ] Reached target Reboot via kexec.
> BdsDxe: loading Boot0007 "Linux Boot Manager" from HD(1,GPT,4B5AFD80-5EC7-47FC-83EA-7EC88ACB15A7,0x800,0x200000)/\EFI\systemd\systemd-bootx64.efi
> BdsDxe: starting Boot0007 "Linux Boot Manager" from HD(1,GPT,4B5AFD80-5EC7-47FC-83EA-7EC88ACB15A7,0x800,0x200000)/\EFI\systemd\systemd-bootx64.efi
>
> then the systemd-boot menu in QEMU when reproducing this there.
>
> Is this expected? If not, I am happy to provide any information or test
> patches as necessary.
No, definitely not expected. Thanks for the report. I'll see if I can
reproduce it; please could you share your kernel .config?
Please could you also confirm that it still occurs if you don't use
systemctl; for speed of testing I have mostly been booting my test
kernel with no actual root file system; just an initrd which does
'kexec -f' immediately.
Since you are running in QEMU, if you can reproduce with this patch to
QEMU itself which should dump the CPU state on a triple-fault, it would
be very useful please:
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -3133,6 +3133,7 @@ int kvm_cpu_exec(CPUState *cpu)
ret = EXCP_INTERRUPT;
break;
case KVM_EXIT_SHUTDOWN:
+ cpu_dump_state(cpu, stderr, CPU_DUMP_CODE);
qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
ret = EXCP_INTERRUPT;
break;
If you get output from that, please also send the output of 'objdump -S
arch/x86/kernel/relocate_kernel_64.o' to help interpret it.
Thanks.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 5965 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/kexec/attachments/20241212/13cbcbe0/attachment.p7s>
More information about the kexec
mailing list