From 4c1b3312ea0104a5163820b5392e4e72712eb34d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= Date: Sun, 24 May 2026 14:58:14 +0200 Subject: [PATCH 1/2] runtime-rs: nvidia-gpu: use _NV firmware substitutions in config template MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `configuration-qemu-nvidia-gpu-runtime-rs.toml.in` template was using the generic `@FIRMWAREPATH@` / `@FIRMWAREVOLUMEPATH@` placeholders, which are left empty for the qemu hypervisor in the runtime-rs Makefile. As a result, no firmware (BIOS) was actually passed to qemu when launching a VM with the nvidia-gpu configuration, breaking OVMF based boot. Switch the placeholders to `@FIRMWAREPATH_NV@` / `@FIRMWAREVOLUMEPATH_NV@`, matching the runtime-go nvidia-gpu template and the substitutions exported by the runtime-rs Makefile, so the OVMF firmware path is properly plumbed through to qemu. Signed-off-by: Fabiano FidĂȘncio --- .../config/configuration-qemu-nvidia-gpu-runtime-rs.toml.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/runtime-rs/config/configuration-qemu-nvidia-gpu-runtime-rs.toml.in b/src/runtime-rs/config/configuration-qemu-nvidia-gpu-runtime-rs.toml.in index 8c056f3b09..0edc10ba5e 100644 --- a/src/runtime-rs/config/configuration-qemu-nvidia-gpu-runtime-rs.toml.in +++ b/src/runtime-rs/config/configuration-qemu-nvidia-gpu-runtime-rs.toml.in @@ -65,13 +65,13 @@ kernel_verity_params = "@KERNELVERITYPARAMS_NV@" # Path to the firmware. # If you want that qemu uses the default firmware leave this option empty -firmware = "@FIRMWAREPATH@" +firmware = "@FIRMWAREPATH_NV@" # Path to the firmware volume. # firmware TDVF or OVMF can be split into FIRMWARE_VARS.fd (UEFI variables # as configuration) and FIRMWARE_CODE.fd (UEFI program image). UEFI variables # can be customized per each user while UEFI code is kept same. -firmware_volume = "@FIRMWAREVOLUMEPATH@" +firmware_volume = "@FIRMWAREVOLUMEPATH_NV@" # Machine accelerators # comma-separated list of machine accelerators to pass to the hypervisor. From ed4d0fb51f8b36c9d6f70be1348e388a3d662923 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= Date: Sun, 24 May 2026 15:04:54 +0200 Subject: [PATCH 2/2] runtime-rs: qemu: pass `-bios` for non-confidential guests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `boot_info.firmware` field from the hypervisor configuration is loaded by kata-types and surfaces in the TOML as `firmware = "..."`, but the qemu cmdline generator never consumed it for non-CC guests. Today, `-bios ` is only appended via the `Bios` device pushed by `add_{sev,sev_snp,tdx}_protection_device()` in `QemuInner::start_vm()`, which use the firmware copied into the `ProtectionDeviceConfig`. That path is taken only when `confidential_guest = true` and a SEV/SEV-SNP/TDX protection device is configured. For plain Q35 profiles (notably the nvidia-gpu one, which needs OVMF to boot the GPU passthrough VM), the `firmware` set in the TOML was silently dropped and qemu fell back to its default BIOS. Wire `boot_info.firmware` directly in `QemuCmdLine::new()` when no protection device path is going to emit `-bios` (i.e. for non-CC guests). CC paths are left untouched so we don't end up with a duplicated `-bios` argument. Signed-off-by: Fabiano FidĂȘncio --- .../hypervisor/src/qemu/cmdline_generator.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/runtime-rs/crates/hypervisor/src/qemu/cmdline_generator.rs b/src/runtime-rs/crates/hypervisor/src/qemu/cmdline_generator.rs index ef6326e030..e7d59ea317 100644 --- a/src/runtime-rs/crates/hypervisor/src/qemu/cmdline_generator.rs +++ b/src/runtime-rs/crates/hypervisor/src/qemu/cmdline_generator.rs @@ -2603,9 +2603,26 @@ impl<'a> QemuCmdLine<'a> { { qemu_cmd_line.add_seccomp_sandbox(seccomp_sandbox); } + + // For confidential guests (SEV/SEV-SNP/TDX), `-bios` is appended later + // by `add_{sev,sev_snp,tdx}_protection_device()` via the + // ProtectionDevice handling in QemuInner::start_vm(), using the + // firmware copied into the ProtectionDeviceConfig. For non-CC guests + // there is no such code path, so wire `boot_info.firmware` directly + // here. Otherwise the firmware configured in the TOML (e.g. OVMF.fd + // for the nvidia-gpu profile) would silently never reach qemu's + // command line. + if !config.security_info.confidential_guest && !config.boot_info.firmware.is_empty() { + qemu_cmd_line.add_bios(&config.boot_info.firmware); + } + Ok(qemu_cmd_line) } + fn add_bios(&mut self, firmware: &str) { + self.devices.push(Box::new(Bios::new(firmware.to_owned()))); + } + /// Takes ownership of the CCW subchannel, leaving `None` in its place. /// Used to transfer boot-time CCW state to Qmp for hotplug allocation. pub fn take_ccw_subchannel(&mut self) -> Option {