crosvm/kernel_loader
Daniel Verkamp b4244d3952 kernel_loader: load ELF kernels at the right paddr
Previously, we were loading ELF kernels at the provided kernel_start
address plus the p_paddr (physical address) field of each program
header. This resulted in the kernel being loaded after a big gap of
zero bytes, which accidentally worked on x86_64 because 0x00 0x00
encodes a valid instruction, and the entry point was at the beginning of
the first section, so execution would effectively "nop slide" its way
from the supposed entry point all the way to the actual beginning of the
correct code. In addition, the Linux kernel entry point is compiled as
position-independent code, so the mismatched address did not matter.

Fix this by loading ELF kernels at whatever physical address they
specify, without adding any extra offset. The load_kernel() function
still accepts a start address, but this is now used simply to verify
that the ELF file does not try to load any sections outside of the
desired kernel region.

As a demonstration, we can look at the instructions at the kernel's
declared entry point (0x1000000 for a normal x86-64 Linux kernel in ELF
format) by attaching to the gdb stub and running:

   (gdb) disas 0x1000000,+8

With the old behavior, we get purely 0x00 0x00 opcodes, decoding as:
   0x0000000001000000:  add    BYTE PTR [rax],al
   0x0000000001000002:  add    BYTE PTR [rax],al
   0x0000000001000004:  add    BYTE PTR [rax],al
   0x0000000001000006:  add    BYTE PTR [rax],al

With the new behavior, we get the correct entry point instructions:
   0x0000000001000000:  lea    rsp,[rip+0x1203f51]        # 0x2203f58
   0x0000000001000007:  lea    rdi,[rip+0xfffffffffffffff2] # 0x1000000

BUG=b:234155022
TEST=cargo test -p kernel_loader
TEST=Boot x86-64 ELF vmlinux kernel

Change-Id: Iae4c8db022674e6311e54dffe479a1ed430a1ef4
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/3673612
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Anton Romanov <romanton@google.com>
Commit-Queue: Daniel Verkamp <dverkamp@chromium.org>
Reviewed-by: Alexandre Courbot <acourbot@chromium.org>
2022-06-23 22:30:37 +00:00
..
src kernel_loader: load ELF kernels at the right paddr 2022-06-23 22:30:37 +00:00
bindgen.sh kernel_loader: regenerate ELF bindings 2022-03-07 21:52:26 +00:00
Cargo.toml kernel_loader: load ELF kernels at the right paddr 2022-06-23 22:30:37 +00:00