Skip to content

ged: load overload UEFI images for LoadFirmware - #5064

Open
Mike Ebersol (mebersol) wants to merge 2 commits into
microsoft:mainfrom
mebersol:user/mebersol/openvmm-uefi-overload
Open

Mike Ebersol (mebersol) wants to merge 2 commits into
microsoft:mainfrom
mebersol:user/mebersol/openvmm-uefi-overload

Conversation

@mebersol

@mebersol Mike Ebersol (mebersol) commented Nov 12, 2026 •

Copy link
Copy Markdown
Collaborator

OpenHCL asks the host to overload VTL0 firmware (LoadFirmware) when resuming a hibernated guest whose hibernate token doesn't match the current UEFI. Until now OpenVMM's GED acknowledged every request with a zero offset without loading anything. This makes OpenVMM act like a real host.

  • GED: carries a catalog of VTL0 UEFI images keyed by LoadFirmware token (uefi_overload_images). For a matching token it writes the image into guest memory and returns the image's entry point offset. Unknown tokens get INVALID_TOKEN; a failed guest-memory write gets FAILED.
  • Loader: new loader::uefi::image_layout returns where load places an image and its entry point (x64: 0x100000 plus the SEC entry offset; aarch64: 0 plus 0x1000). The aarch64 loader now uses the same constants.
  • Protocol: entry_point_image_offset is now documented for aarch64 (0x1000), and zero is documented as "leave the entry point unchanged".
  • openvmm_helpers: uefi_overload builds the catalog from a mu_msvm image: one entry under the token from the image's version record (major.minor), plus OpenHCL 1.8's legacy token 0x0108. 1.8 shipped a 26.0 UEFI, which the default image supersedes. 1.7 (0x0107) has no entry.
  • OpenVMM: fills the catalog from the default UEFI firmware (OPENVMM_UEFI_FIRMWARE). If that file can't be read, it logs a warning and overload requests are rejected.
  • Petri: new with_uefi_overload_firmware builder method fills the GED catalog from a UEFI firmware artifact. Tests opt in; the catalog is empty by default.

Tests:

  • GED transport unit tests check that the image bytes are written and the entry offset is returned, and cover the INVALID_TOKEN and FAILED cases.
  • hibernate_token_overload (VMM test) seeds 0x0108, so OpenHCL requests an overload on resume, and expects 0x0108 to be kept. It no longer has a skip path.
  • hibernate_token_overload_rejected (VMM test) seeds 0x0107; the host has no image for it, so the test expects OpenHCL to fall back to the current token.

The GED now carries a catalog of VTL0 UEFI images keyed by LoadFirmware token. On a matching request it writes the image into guest memory at the loader's base GPA and returns the image's entry point offset; unknown tokens get INVALID_TOKEN and write failures get FAILED. The loader exposes uefi::image_layout for the per-architecture base and entry offset. OpenVMM populates the catalog from the default UEFI firmware (OPENVMM_UEFI_FIRMWARE), keyed by the token from its mu_msvm version record. Petri passes an empty catalog for now.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved critical issues can leave guest memory partially overwritten after failure, accept incompatible firmware, and panic during startup on malformed images.

4 open issues
What changed in this PR

This PR enables OpenVMM’s Guest Emulation Device to load token-selected UEFI firmware for OpenHCL hibernation resume, replacing the previous acknowledgement-only behavior.

Changes:

  • Adds a firmware catalog and writes matching images into guest memory, returning an entry offset or failure status.
  • Adds image-layout and version-token helpers, and populates OpenVMM’s catalog from the default firmware.
  • Tests successful loading, unknown tokens, and write failures; leaves Petri’s catalog empty.
File Description
vm/​loader/​src/​uefi/​mod.rs Exposes image layouts and shares ARM64 load constants.
vm/​devices/​get/​guest_emulation_transport/​src/​lib.rs Tests firmware writes, entry offsets, and failure statuses.
vm/​devices/​get/​guest_emulation_device/​src/​test_utilities.rs Provides a test firmware catalog entry.
vm/​devices/​get/​guest_emulation_device/​src/​resolver.rs Converts resource catalog entries into device configuration.
vm/​devices/​get/​guest_emulation_device/​src/​lib.rs Implements token lookup, image writes, and status responses.
vm/​devices/​get/​get_resources/​src/​lib.rs Adds serializable firmware catalog resources.
petri/​src/​vm/​openvmm/​construct.rs Initializes an empty firmware catalog.
openvmm/​openvmm_helpers/​src/​uefi_overload.rs Builds catalog entries from firmware layouts and version tokens.
openvmm/​openvmm_helpers/​src/​lib.rs Exports the overload helper module.
openvmm/​openvmm_helpers/​Cargo.toml Adds the loader dependency.
openvmm/​openvmm_entry/​src/​lib.rs Loads the default firmware into the catalog.
Cargo.lock Records the helper’s loader dependency.

Review effort: Balanced


/// Builds the GED overload image that loads `image` for `token`.
pub fn uefi_overload_image(token: u64, image: Vec<u8>) -> anyhow::Result<UefiOverloadImage> {
let layout = loader::uefi::image_layout(&image).context("invalid uefi image")?;
.find(|image| image.token == firmware_token);
let (status, entry_offset) = match image {
None => (get_protocol::LoadFirmwareStatus::INVALID_TOKEN, 0),
Some(image) => match self.gm.write_at(image.base_gpa, &image.image) {
Comment thread vm/loader/src/uefi/mod.rs
if image.len() != IMAGE_SIZE as usize {
return Err(Error::InvalidImageSize);
}
let entry_offset = get_sec_entry_point_offset(image).ok_or(Error::NoSecEntryPoint)?;
Ok(UefiOverloadImage {
token,
base_gpa: layout.base_gpa,
entry_offset: layout.entry_offset,
Also document the aarch64 entry offset (0x1000) and that a zero offset leaves the entry point unchanged. Petri gains with_uefi_overload_firmware, and the hibernate overload tests now cover both outcomes deterministically: 1.8 overloads end to end, 1.7 is rejected and falls back to the current token.
@github-actions

Copy link
Copy Markdown

Copilot AI balanced review requested due to automatic review settings November 12, 2026 21:43

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

A failed firmware write can permit fallback to a partially overwritten image, while the aarch64 consumer warns on and ignores newly documented nonzero offsets.

5 open issues

Review effort: Balanced

Comment on lines +1970 to +1973
/// entry on x64, `0x1000` on aarch64), computed by the host. Valid only
/// when `status` is [`LoadFirmwareStatus::SUCCESS`]; the guest/paravisor
/// programs VTL0's entry point to `image_base + entry_point_image_offset`.
/// Zero leaves the entry point unchanged.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants