-
Notifications
You must be signed in to change notification settings - Fork 55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Setting load address doesn't work for PVH loader #12
Comments
My guess is you need to patch the |
Hey @rbradford, I can't seem to get this to repro with Firecracker, can you please check if it got accidentally fixed in the meantime or detail some repro steps if it's still valid? To fiddle with Firecracker and move the load address around:
Or: git checkout -b firecracker-aghecenco-loader
git pull https://github.com/aghecenco/firecracker.git loader
# change kernel_start in src/vmm/src/builder.rs...
tools/devtool shell -p
cargo test test_build_microvm |
Fiddled with cloud-hypervisor too, trying out various addresses here |
I think @rbradford might have been trying this with the However, that's not a bug in |
My mistake, the issue is seen with the PVH loader rather than the "vanilla" ELF loader. If you apply the following patch to CH: https://github.com/rbradford/cloud-hypervisor/tree/2020-05-26-kernel-loading-debugging And ensure
But without PVH:
It's quite possible that the way i'm testing using a different load address is wrong or it could in fact be a Cloud Hypervisor issue. |
I'm all in favour of closing this if we decide it's a Cloud Hypervisor issue. But the point i'm trying to make is that that |
I'm taking a look. |
The short answer is that this is not a Cloud Hypervisor issue, and for the PVH entry point to work correctly the kernel must be initially loaded in guest memory at the default location. I am not sure yet if it is possible to make the PVH entry point work when the kernel is loaded at a different location than the one specified at build time, but it would require Linux kernel changes. For quickly fixing this issue I propose a patch that simply does not return a PVH entry point as an option if a diff --git a/src/loader/x86_64/elf/mod.rs b/src/loader/x86_64/elf/mod.rs
index 1b319d7..d89217e 100644
--- a/src/loader/x86_64/elf/mod.rs
+++ b/src/loader/x86_64/elf/mod.rs
@@ -212,8 +212,10 @@ impl KernelLoader for Elf {
// Read in each section pointed to by the program headers.
for phdr in phdrs {
if phdr.p_type != elf::PT_LOAD || phdr.p_filesz == 0 {
- if phdr.p_type == elf::PT_NOTE {
+ if phdr.p_type == elf::PT_NOTE && kernel_start.is_none() {
// This segment describes a Note, check if PVH entry point is encoded.
+ // This is only useful if an offset from the default kernel load address
+ // has not been requested using the kernel_start parameter.
loader_result.pvh_entry_addr = parse_elf_note(&phdr, kernel_image)?;
}
continue; |
That being said we should discuss the One detail I noticed is that the description of the
Following from the above, it is not clear to me what this functionality buys us in a real use case scenario. I'd appreciate if someone with more experience in this area could give an example of when a VMM would need to use this functionality of loading the guest kernel at a non-default location in guest memory. |
Ping? I can fix the issue by defaulting to use the Linux boot protocol when This functionality might have been needed by crosvm (how/why?), but with my limited experience I cannot think of a current use case or need for it. If we can't or don't want to have that discussion right now, then please let me know and I'll just fix the bug. |
Hi, this is a good question and an interesting conversation. You are right about |
Thank you for the ack, and for looking into this. I'm completely unfamiliar with aarch64, so perhaps there is a good reason there. |
According to https://www.kernel.org/doc/Documentation/arm64/booting.txt:
@crab2313 @michael2012z could you confirm/infirm? In the meantime @aljimenezb would you submit a PR with the patch and explanation? |
If I correctly understand your comment and the So our I suppose it does not hurt to use Linux boot protocol instead of PVH if we want to keep
Will do soon. |
@aghecenco , I share the same understanding with @aljimenezb on |
The load() method in the KernelLoader trait takes a kernel_start argument that has different behavior in the Elf, BzImage, and PE implementations. Elf: kernel_start provides an offset to be added to the default kernel load address encoded in the phdr.p_paddr field of the Elf header. A VMM using kernel_start requests that the kernel is loaded in guest memory at phdr.p_paddr + kernel_start. BzImage: kernel_start allows to specify an absolute address at which to load the kernel in guest memory, replacing the default address taken from the code32_start field of the bzImage header. PE: kernel_start specifies a 2MB-aligned base address in guest memory. The kernel must be loaded at kernel_start + text_offset, where text_offset value is read from the Image header. Change the name from kernel_start to kernel_offset, and change the argument description on each implementation to clarify its use. Related to rust-vmm#12 Signed-off-by: Alejandro Jimenez <alejandro.j.jimenez@oracle.com>
According to https://www.kernel.org/doc/Documentation/arm64/booting.txt: "The Image must be placed text_offset bytes from a 2MB aligned base address anywhere in usable system RAM and called there." For the aarch64 case, the kernel_offset parameter allows a VMM to specify the desired base address at which to load the image in guest memory, while text_offset is contained in the Image header. Ensure that the base address requested by the VMM meets the 2 MB alignment requirement. Related to rust-vmm#12 Signed-off-by: Alejandro Jimenez <alejandro.j.jimenez@oracle.com>
Refactor the PVH code to return a field in KernelLoaderResult that specifies whether the PVH capability is present or not, or if it is being purposedly ignored. The only current reason for ignoring the PVH capability is when a kernel_offset is requested. Since PVH boot protocol expects the kernel to be loaded at the default load address, it cannot be used when a specific load offset has been requested by the VMM using the kernel_offset parameter. Related to rust-vmm#12 Signed-off-by: Alejandro Jimenez <alejandro.j.jimenez@oracle.com>
The load() method in the KernelLoader trait takes a kernel_start argument that has different behavior in the Elf, BzImage, and PE implementations. Elf: kernel_start provides an offset to be added to the default kernel load address encoded in the phdr.p_paddr field of the Elf header. A VMM using kernel_start requests that the kernel is loaded in guest memory at phdr.p_paddr + kernel_start. BzImage: kernel_start allows to specify an absolute address at which to load the kernel in guest memory, replacing the default address taken from the code32_start field of the bzImage header. PE: kernel_start specifies a 2MB-aligned base address in guest memory. The kernel must be loaded at kernel_start + text_offset, where text_offset value is read from the Image header. Change the name from kernel_start to kernel_offset, and change the argument description on each implementation to clarify its use. Related to #12 Signed-off-by: Alejandro Jimenez <alejandro.j.jimenez@oracle.com>
According to https://www.kernel.org/doc/Documentation/arm64/booting.txt: "The Image must be placed text_offset bytes from a 2MB aligned base address anywhere in usable system RAM and called there." For the aarch64 case, the kernel_offset parameter allows a VMM to specify the desired base address at which to load the image in guest memory, while text_offset is contained in the Image header. Ensure that the base address requested by the VMM meets the 2 MB alignment requirement. Related to #12 Signed-off-by: Alejandro Jimenez <alejandro.j.jimenez@oracle.com>
Refactor the PVH code to return a field in KernelLoaderResult that specifies whether the PVH capability is present or not, or if it is being purposedly ignored. The only current reason for ignoring the PVH capability is when a kernel_offset is requested. Since PVH boot protocol expects the kernel to be loaded at the default load address, it cannot be used when a specific load offset has been requested by the VMM using the kernel_offset parameter. Related to #12 Signed-off-by: Alejandro Jimenez <alejandro.j.jimenez@oracle.com>
Setting the kernel load address doesn't result in the kernel booting (tested with Cloud Hypervisor and setting it to 1MiB.) bzImage loader works fine with the specified load address.
The text was updated successfully, but these errors were encountered: