vmm: export full setup-header area for x86_64 kernels

The Linux x86 boot protocol defines the setup area as
(setup_sects + 1) * 512 bytes. Previously we exported only the
boot_params buffer (4096 bytes), which is wrong for kernels with
setup_sects >= 8 where the actual setup area exceeds boot_params.

Truncate or extend the existing buffer to the correct setup_sects-
derived length, reading any extra bytes directly from the kernel file.
This avoids an extra allocation in the common case (setup_sects <= 7)
and matches QEMU's fw_cfg_add_kernel() behavior in
hw/i386/x86-common.c.

Signed-off-by: Dylan Reid <dgreid@fb.com>
This commit is contained in:
Dylan Reid
2026-04-03 16:10:20 -07:00
committed by Rob Bradford
parent 883ca3feb2
commit d48d1dcd3d

View File

@@ -649,6 +649,18 @@ impl FwCfg {
let kernel_start = bp.text_offset;
#[cfg(target_arch = "x86_64")]
let kernel_start = (bp.hdr.setup_sects as usize + 1) * 512;
#[cfg(target_arch = "x86_64")]
if kernel_start <= buffer.len() {
buffer.truncate(kernel_start);
} else {
buffer.resize(kernel_start, 0);
file.read_exact_at(
&mut buffer[size_of::<boot_params>()..],
size_of::<boot_params>() as u64,
)?;
}
self.known_items[FW_CFG_SETUP_SIZE as usize] = FwCfgContent::U32(buffer.len() as u32);
self.known_items[FW_CFG_SETUP_DATA as usize] = FwCfgContent::Bytes(buffer);
self.known_items[FW_CFG_KERNEL_SIZE as usize] =