From a6f090ea0b904ba702d355425b20c331f1887de5 Mon Sep 17 00:00:00 2001 From: Kyle Moorhead Date: Thu, 28 May 2026 18:04:56 +0000 Subject: [PATCH 1/6] feat(vmm-tests): add per-test Linux kernel version selection Add infrastructure for individual VMM tests to specify which Linux kernel version to use via the test macro syntax: #[openvmm_test(linux_direct_x64)] // default kernel #[openvmm_test(linux_direct_x64(kernel_6_1))] // explicit 6.1 #[openvmm_test(linux_direct_x64(kernel_6_18))]// explicit 6.18 Changes across all layers: - petri_artifacts_vmm_test: Add LinuxDirectKernelVersion enum and version-specific artifact IDs (LINUX_DIRECT_TEST_KERNEL_X64_6_1, _6_18, etc.) with IsLoadable impls - petri_artifact_resolver_openvmm_known_paths: Map versioned artifact IDs to versioned paths (e.g. x64/6.1/vmlinux, x64/6.18/vmlinux) - petri (Firmware): Add linux_direct_with_version() and linux_direct_bzimage_with_version() constructors that select version-specific kernel artifacts - vmm_test_macros: Parse optional (kernel_6_1)/(kernel_6_18) after linux_direct_x64, linux_direct_aarch64, linux_direct_bzimage_x64, and openhcl_linux_direct_x64 tokens. Generate appropriate Firmware constructor calls in codegen. - flowey (init_vmm_tests_env): Download all supported kernel versions and place them at both legacy paths and versioned subdirectories - flowey (resolve_openvmm_test_linux_kernel): Add Linux6_18 variant to LinuxTestKernelVersion with ALL constant for iteration Existing tests without a kernel version specifier continue to use the default (unversioned) artifact IDs, preserving full backward compatibility. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../src/init_vmm_tests_env.rs | 44 +++++++ .../src/resolve_openvmm_test_linux_kernel.rs | 5 + petri/src/vm/mod.rs | 52 ++++++++ .../src/lib.rs | 31 +++++ vmm_tests/petri_artifacts_vmm_test/src/lib.rs | 58 ++++++++- vmm_tests/vmm_test_macros/src/lib.rs | 121 +++++++++++++++--- 6 files changed, 289 insertions(+), 22 deletions(-) diff --git a/flowey/flowey_lib_hvlite/src/init_vmm_tests_env.rs b/flowey/flowey_lib_hvlite/src/init_vmm_tests_env.rs index bc12fdea4e..505de6934b 100644 --- a/flowey/flowey_lib_hvlite/src/init_vmm_tests_env.rs +++ b/flowey/flowey_lib_hvlite/src/init_vmm_tests_env.rs @@ -140,6 +140,36 @@ impl SimpleFlowNode for Node { }) }); + // Request all supported kernel versions for version-specific paths + let versioned_kernels: Vec<_> = + crate::resolve_openvmm_test_linux_kernel::LinuxTestKernelVersion::ALL + .iter() + .map(|&kver| { + let kernel = ctx.reqv(|v| { + crate::resolve_openvmm_test_linux_kernel::Request::Get( + crate::resolve_openvmm_test_linux_kernel::OpenvmmTestKernelFile::Kernel, + arch, + kver, + v, + ) + }); + let bzimage = + crate::resolve_openvmm_test_linux_kernel::OpenvmmTestKernelFile::BzImage + .is_available_for(arch) + .then(|| { + ctx.reqv(|v| { + crate::resolve_openvmm_test_linux_kernel::Request::Get( + crate::resolve_openvmm_test_linux_kernel::OpenvmmTestKernelFile::BzImage, + arch, + kver, + v, + ) + }) + }); + (kver, kernel, bzimage) + }) + .collect(); + let uefi = ctx.reqv(|v| crate::download_uefi_mu_msvm::Request::GetMsvmFd { arch, msvm_fd: v }); @@ -164,6 +194,10 @@ impl SimpleFlowNode for Node { let test_linux_initrd = test_linux_initrd.claim(ctx); let test_linux_kernel = test_linux_kernel.claim(ctx); let test_linux_bzimage = test_linux_bzimage.claim(ctx); + let versioned_kernels: Vec<_> = versioned_kernels + .into_iter() + .map(|(kver, kernel, bzimage)| (kver, kernel.claim(ctx), bzimage.claim(ctx))) + .collect(); let uefi = uefi.claim(ctx); let release_igvm_files_dir = release_igvm_files.claim(ctx); move |rt| { @@ -455,6 +489,16 @@ impl SimpleFlowNode for Node { )?; } + // Place version-specific kernels at versioned paths + for (kver, kernel_var, bzimage_var) in versioned_kernels { + let version_dir = test_content_dir.join(arch_dir).join(kver.artifact_tag()); + fs_err::create_dir_all(&version_dir)?; + fs_err::copy(rt.read(kernel_var), version_dir.join(kernel_file_name))?; + if let Some(bz_var) = bzimage_var { + fs_err::copy(rt.read(bz_var), version_dir.join("bzImage"))?; + } + } + let uefi_dir = test_content_dir.join(match arch { CommonArch::Aarch64 => { "hyperv.uefi.mscoreuefi.AARCH64.RELEASE/MsvmAARCH64/RELEASE_CLANGPDB/FV" diff --git a/flowey/flowey_lib_hvlite/src/resolve_openvmm_test_linux_kernel.rs b/flowey/flowey_lib_hvlite/src/resolve_openvmm_test_linux_kernel.rs index 501ba742df..f32dad9092 100644 --- a/flowey/flowey_lib_hvlite/src/resolve_openvmm_test_linux_kernel.rs +++ b/flowey/flowey_lib_hvlite/src/resolve_openvmm_test_linux_kernel.rs @@ -28,6 +28,7 @@ use std::collections::BTreeSet; #[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub enum LinuxTestKernelVersion { Linux6_1, + Linux6_18, } impl LinuxTestKernelVersion { @@ -36,8 +37,12 @@ impl LinuxTestKernelVersion { pub fn artifact_tag(self) -> &'static str { match self { Self::Linux6_1 => "6.1", + Self::Linux6_18 => "6.18", } } + + /// All supported kernel versions. + pub const ALL: &'static [LinuxTestKernelVersion] = &[Self::Linux6_1, Self::Linux6_18]; } /// Which file to extract from a per-(arch, kver) `openvmm-test-linux` archive. diff --git a/petri/src/vm/mod.rs b/petri/src/vm/mod.rs index 11cbb8797f..16e663ef50 100644 --- a/petri/src/vm/mod.rs +++ b/petri/src/vm/mod.rs @@ -2484,6 +2484,36 @@ impl Firmware { } } + /// Constructs a [`Firmware::LinuxDirect`] configuration with a specific + /// kernel version. + pub fn linux_direct_with_version( + resolver: &ArtifactResolver<'_>, + arch: MachineArch, + version: petri_artifacts_vmm_test::LinuxDirectKernelVersion, + ) -> Self { + use petri_artifacts_vmm_test::LinuxDirectKernelVersion; + use petri_artifacts_vmm_test::artifacts::loadable::*; + let kernel = match (arch, version) { + (MachineArch::X86_64, LinuxDirectKernelVersion::V6_1) => { + resolver.require(LINUX_DIRECT_TEST_KERNEL_X64_6_1).erase() + } + (MachineArch::X86_64, LinuxDirectKernelVersion::V6_18) => { + resolver.require(LINUX_DIRECT_TEST_KERNEL_X64_6_18).erase() + } + (MachineArch::Aarch64, LinuxDirectKernelVersion::V6_1) => resolver + .require(LINUX_DIRECT_TEST_KERNEL_AARCH64_6_1) + .erase(), + (MachineArch::Aarch64, LinuxDirectKernelVersion::V6_18) => resolver + .require(LINUX_DIRECT_TEST_KERNEL_AARCH64_6_18) + .erase(), + }; + let initrd = match arch { + MachineArch::X86_64 => resolver.require(LINUX_DIRECT_TEST_INITRD_X64).erase(), + MachineArch::Aarch64 => resolver.require(LINUX_DIRECT_TEST_INITRD_AARCH64).erase(), + }; + Firmware::LinuxDirect { kernel, initrd } + } + /// Constructs a [`Firmware::LinuxDirect`] configuration that uses a /// compressed bzImage kernel instead of an uncompressed ELF. /// @@ -2496,6 +2526,28 @@ impl Firmware { } } + /// Constructs a [`Firmware::LinuxDirect`] bzImage configuration with a + /// specific kernel version. + pub fn linux_direct_bzimage_with_version( + resolver: &ArtifactResolver<'_>, + version: petri_artifacts_vmm_test::LinuxDirectKernelVersion, + ) -> Self { + use petri_artifacts_vmm_test::LinuxDirectKernelVersion; + use petri_artifacts_vmm_test::artifacts::loadable::*; + let kernel = match version { + LinuxDirectKernelVersion::V6_1 => { + resolver.require(LINUX_DIRECT_TEST_BZIMAGE_X64_6_1).erase() + } + LinuxDirectKernelVersion::V6_18 => { + resolver.require(LINUX_DIRECT_TEST_BZIMAGE_X64_6_18).erase() + } + }; + Firmware::LinuxDirect { + kernel, + initrd: resolver.require(LINUX_DIRECT_TEST_INITRD_X64).erase(), + } + } + /// Constructs a standard [`Firmware::OpenhclLinuxDirect`] configuration. pub fn openhcl_linux_direct(resolver: &ArtifactResolver<'_>, arch: MachineArch) -> Self { use petri_artifacts_vmm_test::artifacts::openhcl_igvm::*; diff --git a/vmm_tests/petri_artifact_resolver_openvmm_known_paths/src/lib.rs b/vmm_tests/petri_artifact_resolver_openvmm_known_paths/src/lib.rs index 3b392cc672..f77c983516 100644 --- a/vmm_tests/petri_artifact_resolver_openvmm_known_paths/src/lib.rs +++ b/vmm_tests/petri_artifact_resolver_openvmm_known_paths/src/lib.rs @@ -71,6 +71,14 @@ impl petri_artifacts_core::ResolveTestArtifact for OpenvmmKnownPathsTestArtifact _ if id == loadable::LINUX_DIRECT_TEST_INITRD_X64 => linux_direct_test_initrd_path(MachineArch::X86_64), _ if id == loadable::LINUX_DIRECT_TEST_INITRD_AARCH64 => linux_direct_test_initrd_path(MachineArch::Aarch64), + // Version-specific kernel artifacts + _ if id == loadable::LINUX_DIRECT_TEST_KERNEL_X64_6_1 => linux_direct_versioned_kernel_path("x64", "6.1", "vmlinux"), + _ if id == loadable::LINUX_DIRECT_TEST_KERNEL_X64_6_18 => linux_direct_versioned_kernel_path("x64", "6.18", "vmlinux"), + _ if id == loadable::LINUX_DIRECT_TEST_KERNEL_AARCH64_6_1 => linux_direct_versioned_kernel_path("aarch64", "6.1", "Image"), + _ if id == loadable::LINUX_DIRECT_TEST_KERNEL_AARCH64_6_18 => linux_direct_versioned_kernel_path("aarch64", "6.18", "Image"), + _ if id == loadable::LINUX_DIRECT_TEST_BZIMAGE_X64_6_1 => linux_direct_versioned_kernel_path("x64", "6.1", "bzImage"), + _ if id == loadable::LINUX_DIRECT_TEST_BZIMAGE_X64_6_18 => linux_direct_versioned_kernel_path("x64", "6.18", "bzImage"), + _ if id == petritools::PETRITOOLS_EROFS_X64 => petritools_erofs_path(MachineArch::X86_64), _ if id == petritools::PETRITOOLS_EROFS_AARCH64 => petritools_erofs_path(MachineArch::Aarch64), @@ -192,6 +200,13 @@ pub fn resolve_bundle_name(id: ErasedArtifactHandle) -> Option<&'static str> { _ if id == loadable::LINUX_DIRECT_TEST_KERNEL_AARCH64 => Some("aarch64/Image"), _ if id == loadable::LINUX_DIRECT_TEST_INITRD_X64 => Some("x64/initrd"), _ if id == loadable::LINUX_DIRECT_TEST_INITRD_AARCH64 => Some("aarch64/initrd"), + // Version-specific kernel bundle names + _ if id == loadable::LINUX_DIRECT_TEST_KERNEL_X64_6_1 => Some("x64/6.1/vmlinux"), + _ if id == loadable::LINUX_DIRECT_TEST_KERNEL_X64_6_18 => Some("x64/6.18/vmlinux"), + _ if id == loadable::LINUX_DIRECT_TEST_KERNEL_AARCH64_6_1 => Some("aarch64/6.1/Image"), + _ if id == loadable::LINUX_DIRECT_TEST_KERNEL_AARCH64_6_18 => Some("aarch64/6.18/Image"), + _ if id == loadable::LINUX_DIRECT_TEST_BZIMAGE_X64_6_1 => Some("x64/6.1/bzImage"), + _ if id == loadable::LINUX_DIRECT_TEST_BZIMAGE_X64_6_18 => Some("x64/6.18/bzImage"), _ if id == petritools::PETRITOOLS_EROFS_X64 => Some("x64/petritools.erofs"), _ if id == petritools::PETRITOOLS_EROFS_AARCH64 => Some("aarch64/petritools.erofs"), _ if id == loadable::UEFI_FIRMWARE_X64 => { @@ -495,6 +510,22 @@ fn linux_direct_arm_image_path() -> anyhow::Result { ) } +/// Path to a version-specific linux direct kernel or bzImage file. +fn linux_direct_versioned_kernel_path( + arch_dir: &str, + version: &str, + filename: &str, +) -> anyhow::Result { + let bundle_name = format!("{arch_dir}/{version}/{filename}"); + get_path( + ".packages/underhill-deps-private", + bundle_name, + MissingCommand::Restore { + description: "version-specific linux direct test kernel", + }, + ) +} + /// Path to our packaged PCAT firmware. fn pcat_firmware_path() -> anyhow::Result { get_path( diff --git a/vmm_tests/petri_artifacts_vmm_test/src/lib.rs b/vmm_tests/petri_artifacts_vmm_test/src/lib.rs index 5b9d1b1382..6717519ab6 100644 --- a/vmm_tests/petri_artifacts_vmm_test/src/lib.rs +++ b/vmm_tests/petri_artifacts_vmm_test/src/lib.rs @@ -5,6 +5,18 @@ #![forbid(unsafe_code)] +/// Which Linux kernel version to use for linux-direct tests. +/// +/// Used by test macros and petri firmware selection to pick +/// version-specific kernel artifacts. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum LinuxDirectKernelVersion { + /// Linux 6.1 + V6_1, + /// Linux 6.18 + V6_18, +} + /// Artifact declarations pub mod artifacts { use petri_artifacts_common::tags::IsVmgsTool; @@ -123,16 +135,31 @@ pub mod artifacts { > = petri_artifacts_core::ArtifactHandle::new(); declare_artifacts! { - /// Test linux direct kernel (from OpenVMM deps) + /// Test linux direct kernel (from OpenVMM deps) — default version LINUX_DIRECT_TEST_KERNEL_X64, /// Test linux direct initrd (from OpenVMM deps) LINUX_DIRECT_TEST_INITRD_X64, - /// Test linux direct kernel (from OpenVMM deps) + /// Test linux direct kernel (from OpenVMM deps) — default version LINUX_DIRECT_TEST_KERNEL_AARCH64, /// Test linux direct initrd (from OpenVMM deps) LINUX_DIRECT_TEST_INITRD_AARCH64, - /// Test linux direct bzImage kernel (from OpenVMM deps) + /// Test linux direct bzImage kernel (from OpenVMM deps) — default version LINUX_DIRECT_TEST_BZIMAGE_X64, + + // Version-specific kernel artifacts + /// Test linux direct kernel 6.1 (from OpenVMM deps) + LINUX_DIRECT_TEST_KERNEL_X64_6_1, + /// Test linux direct kernel 6.18 (from OpenVMM deps) + LINUX_DIRECT_TEST_KERNEL_X64_6_18, + /// Test linux direct kernel 6.1 (from OpenVMM deps) + LINUX_DIRECT_TEST_KERNEL_AARCH64_6_1, + /// Test linux direct kernel 6.18 (from OpenVMM deps) + LINUX_DIRECT_TEST_KERNEL_AARCH64_6_18, + /// Test linux direct bzImage kernel 6.1 (from OpenVMM deps) + LINUX_DIRECT_TEST_BZIMAGE_X64_6_1, + /// Test linux direct bzImage kernel 6.18 (from OpenVMM deps) + LINUX_DIRECT_TEST_BZIMAGE_X64_6_18, + /// PCAT firmware DLL PCAT_FIRMWARE_X64, /// SVGA firmware DLL @@ -163,6 +190,31 @@ pub mod artifacts { const ARCH: MachineArch = MachineArch::X86_64; } + // Version-specific IsLoadable impls + impl IsLoadable for LINUX_DIRECT_TEST_KERNEL_X64_6_1 { + const ARCH: MachineArch = MachineArch::X86_64; + } + + impl IsLoadable for LINUX_DIRECT_TEST_KERNEL_X64_6_18 { + const ARCH: MachineArch = MachineArch::X86_64; + } + + impl IsLoadable for LINUX_DIRECT_TEST_KERNEL_AARCH64_6_1 { + const ARCH: MachineArch = MachineArch::Aarch64; + } + + impl IsLoadable for LINUX_DIRECT_TEST_KERNEL_AARCH64_6_18 { + const ARCH: MachineArch = MachineArch::Aarch64; + } + + impl IsLoadable for LINUX_DIRECT_TEST_BZIMAGE_X64_6_1 { + const ARCH: MachineArch = MachineArch::X86_64; + } + + impl IsLoadable for LINUX_DIRECT_TEST_BZIMAGE_X64_6_18 { + const ARCH: MachineArch = MachineArch::X86_64; + } + impl IsLoadable for PCAT_FIRMWARE_X64 { const ARCH: MachineArch = MachineArch::X86_64; } diff --git a/vmm_tests/vmm_test_macros/src/lib.rs b/vmm_tests/vmm_test_macros/src/lib.rs index 552bb9ea5f..c41ba87843 100644 --- a/vmm_tests/vmm_test_macros/src/lib.rs +++ b/vmm_tests/vmm_test_macros/src/lib.rs @@ -46,15 +46,31 @@ enum Vmm { } enum Firmware { - LinuxDirect, - LinuxDirectBzImage, + LinuxDirect(Option), + LinuxDirectBzImage(Option), Pcat(PcatGuest), Uefi(UefiGuest), - OpenhclLinuxDirect, + OpenhclLinuxDirect(Option), OpenhclPcat(PcatGuest), OpenhclUefi(OpenhclUefiOptions, UefiGuest), } +/// Kernel version selection for linux-direct tests (macro-internal). +#[derive(Clone, Copy)] +enum LinuxKernelVersion { + V6_1, + V6_18, +} + +impl LinuxKernelVersion { + fn name_prefix(self) -> String { + match self { + LinuxKernelVersion::V6_1 => "kernel_6_1".to_string(), + LinuxKernelVersion::V6_18 => "kernel_6_18".to_string(), + } + } +} + #[derive(Default)] struct OpenhclUefiOptions { isolation: Option, @@ -114,6 +130,17 @@ fn arch_to_tokens(arch: MachineArch) -> TokenStream { } } +fn kernel_version_to_tokens(version: LinuxKernelVersion) -> TokenStream { + match version { + LinuxKernelVersion::V6_1 => { + quote!(::petri_artifacts_vmm_test::LinuxDirectKernelVersion::V6_1) + } + LinuxKernelVersion::V6_18 => { + quote!(::petri_artifacts_vmm_test::LinuxDirectKernelVersion::V6_18) + } + } +} + impl ResolvedConfig { fn name_prefix(&self) -> String { let arch_prefix = arch_to_str(self.arch); @@ -124,30 +151,33 @@ impl ResolvedConfig { }; let firmware_prefix = match &self.firmware { - Firmware::LinuxDirect => "linux", - Firmware::LinuxDirectBzImage => "linux_bzimage", + Firmware::LinuxDirect(_) => "linux", + Firmware::LinuxDirectBzImage(_) => "linux_bzimage", Firmware::Pcat(_) => "pcat", Firmware::Uefi(_) => "uefi", - Firmware::OpenhclLinuxDirect => "openhcl_linux", + Firmware::OpenhclLinuxDirect(_) => "openhcl_linux", Firmware::OpenhclPcat(..) => "openhcl_pcat", Firmware::OpenhclUefi(..) => "openhcl_uefi", }; let guest_prefix = match &self.firmware { - Firmware::LinuxDirect | Firmware::LinuxDirectBzImage | Firmware::OpenhclLinuxDirect => { - None - } + Firmware::LinuxDirect(_) + | Firmware::LinuxDirectBzImage(_) + | Firmware::OpenhclLinuxDirect(_) => None, Firmware::Pcat(guest) | Firmware::OpenhclPcat(guest) => Some(guest.name_prefix()), Firmware::Uefi(guest) | Firmware::OpenhclUefi(_, guest) => guest.name_prefix(), }; let options_prefix = match &self.firmware { - Firmware::LinuxDirect - | Firmware::LinuxDirectBzImage + Firmware::LinuxDirect(None) + | Firmware::LinuxDirectBzImage(None) | Firmware::Pcat(_) | Firmware::Uefi(_) - | Firmware::OpenhclLinuxDirect + | Firmware::OpenhclLinuxDirect(None) | Firmware::OpenhclPcat(_) => None, + Firmware::LinuxDirect(Some(v)) + | Firmware::LinuxDirectBzImage(Some(v)) + | Firmware::OpenhclLinuxDirect(Some(v)) => Some(v.name_prefix()), Firmware::OpenhclUefi(opt, _) => opt.name_prefix(), }; @@ -224,19 +254,34 @@ impl ToTokens for FirmwareAndArch { fn to_tokens(&self, tokens: &mut TokenStream) { let arch = arch_to_tokens(self.arch); tokens.extend(match &self.firmware { - Firmware::LinuxDirect => { + Firmware::LinuxDirect(None) => { quote!(::petri::Firmware::linux_direct(resolver, #arch)) } - Firmware::LinuxDirectBzImage => { + Firmware::LinuxDirect(Some(v)) => { + let version = kernel_version_to_tokens(*v); + quote!(::petri::Firmware::linux_direct_with_version(resolver, #arch, #version)) + } + Firmware::LinuxDirectBzImage(None) => { quote!(::petri::Firmware::linux_direct_bzimage(resolver)) } + Firmware::LinuxDirectBzImage(Some(v)) => { + let version = kernel_version_to_tokens(*v); + quote!(::petri::Firmware::linux_direct_bzimage_with_version(resolver, #version)) + } Firmware::Pcat(guest) => { quote!(::petri::Firmware::pcat(resolver, #guest)) } Firmware::Uefi(guest) => { quote!(::petri::Firmware::uefi(resolver, #arch, #guest)) } - Firmware::OpenhclLinuxDirect => { + Firmware::OpenhclLinuxDirect(None) => { + quote!(::petri::Firmware::openhcl_linux_direct(resolver, #arch)) + } + Firmware::OpenhclLinuxDirect(Some(v)) => { + // OpenhclLinuxDirect uses IGVM files and doesn't directly select kernel version. + // For now, kernel version selection for openhcl_linux_direct is a no-op — the + // IGVM file embeds the kernel. Pass through as the default. + let _ = v; quote!(::petri::Firmware::openhcl_linux_direct(resolver, #arch)) } Firmware::OpenhclPcat(guest) => { @@ -405,10 +450,22 @@ impl Parse for Config { }; let (arch, firmware) = match remainder { - "linux_direct_x64" => (MachineArch::X86_64, Firmware::LinuxDirect), - "linux_direct_bzimage_x64" => (MachineArch::X86_64, Firmware::LinuxDirectBzImage), - "linux_direct_aarch64" => (MachineArch::Aarch64, Firmware::LinuxDirect), - "openhcl_linux_direct_x64" => (MachineArch::X86_64, Firmware::OpenhclLinuxDirect), + "linux_direct_x64" => { + let kver = parse_linux_kernel_version(input)?; + (MachineArch::X86_64, Firmware::LinuxDirect(kver)) + } + "linux_direct_bzimage_x64" => { + let kver = parse_linux_kernel_version(input)?; + (MachineArch::X86_64, Firmware::LinuxDirectBzImage(kver)) + } + "linux_direct_aarch64" => { + let kver = parse_linux_kernel_version(input)?; + (MachineArch::Aarch64, Firmware::LinuxDirect(kver)) + } + "openhcl_linux_direct_x64" => { + let kver = parse_linux_kernel_version(input)?; + (MachineArch::X86_64, Firmware::OpenhclLinuxDirect(kver)) + } "pcat_x64" => ( MachineArch::X86_64, Firmware::Pcat(parse_pcat_guest(input)?), @@ -467,6 +524,25 @@ fn parse_uefi_guest(input: ParseStream<'_>) -> syn::Result { parens.parse::() } +/// Parse an optional parenthesized kernel version, e.g. `(kernel_6_1)`. +/// +/// Returns `None` if no parenthesized group follows, allowing the default +/// kernel to be used. +fn parse_linux_kernel_version(input: ParseStream<'_>) -> syn::Result> { + if input.peek(syn::token::Paren) { + let content; + syn::parenthesized!(content in input); + let word = content.parse::()?; + match &*word.to_string() { + "kernel_6_1" => Ok(Some(LinuxKernelVersion::V6_1)), + "kernel_6_18" => Ok(Some(LinuxKernelVersion::V6_18)), + _ => Err(Error::new(word.span(), "unrecognized kernel version")), + } + } else { + Ok(None) + } +} + impl Parse for PcatGuest { fn parse(input: ParseStream<'_>) -> syn::Result { let word = input.parse::()?; @@ -691,8 +767,11 @@ fn parse_extra_deps(input: ParseStream<'_>) -> syn::Result> { /// /// Valid configuration options are: /// - `{vmm}_linux_direct_{arch}`: Our provided Linux direct image +/// - `{vmm}_linux_direct_{arch}()`: Linux direct with a specific kernel version /// - `{vmm}_linux_direct_bzimage_x64`: Our provided Linux direct bzImage (compressed kernel, x86_64 only) +/// - `{vmm}_linux_direct_bzimage_x64()`: bzImage with a specific kernel version /// - `{vmm}_openhcl_linux_direct_{arch}`: Our provided Linux direct image with OpenHCL +/// - `{vmm}_openhcl_linux_direct_{arch}()`: OpenHCL Linux direct with a specific kernel version /// - `{vmm}_pcat_{arch}()`: A Gen 1 configuration /// - `{vmm}_uefi_{arch}()`: A Gen 2 configuration /// - `{vmm}_openhcl_pcat_{arch}()`: A Gen 1 configuration with OpenHCL @@ -739,6 +818,10 @@ fn parse_extra_deps(input: ParseStream<'_>) -> syn::Result> { /// - `snp`: Use SNP isolation. /// - `tdx`: Use TDX isolation. /// +/// Valid kernel version options are: +/// - `kernel_6_1`: Linux 6.1 kernel +/// - `kernel_6_18`: Linux 6.18 kernel +/// /// Each configuration can be optionally followed by a square-bracketed, comma-separated /// list of additional artifacts required for that particular configuration. #[proc_macro_attribute] From 145739f01772132f915c6c2224f3de8770caafe7 Mon Sep 17 00:00:00 2001 From: Kyle Moorhead Date: Tue, 19 May 2026 17:32:32 +0000 Subject: [PATCH 2/6] flowey: split openvmm-deps into separate archives and add Linux 6.18 kernel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update resolve_openvmm_deps to download separate archives per dep type: - openvmm-deps.{arch}.{ver}.tar.gz (SDK: dbgrd, shell, sysroot, petritools) - openvmm-test-initrd.{arch}.{ver}.tar.gz (shared test initrd) - openvmm-test-linux-{kernel_ver}.{arch}.{ver}.tar.gz (test kernel) This matches the new openvmm-deps release structure (0.3.0-29+). Archive format changed from .tar.bz2 to .tar.gz. Add test_kernel_version field to Config and OPENVMM_TEST_LINUX_KERNEL constant ("6.18") to cfg_versions.rs. The Request::Get API is unchanged — consumers are unaffected. Version set to TODO-PLACEHOLDER-PENDING-RELEASE until the openvmm-deps release with 6.18 kernel artifacts is cut. --- .github/workflows/openvmm-ci.yaml | 24 +-- .github/workflows/openvmm-pr-release.yaml | 24 +-- .github/workflows/openvmm-pr.yaml | 48 +++--- ci-flowey/openvmm-pr.yaml | 8 +- .../src/resolve_openvmm_deps.rs | 141 +++++++++++------- 5 files changed, 140 insertions(+), 105 deletions(-) diff --git a/.github/workflows/openvmm-ci.yaml b/.github/workflows/openvmm-ci.yaml index 062534d926..cf2f6c109e 100644 --- a/.github/workflows/openvmm-ci.yaml +++ b/.github/workflows/openvmm-ci.yaml @@ -2163,6 +2163,12 @@ jobs: flowey e 15 flowey_lib_hvlite::git_checkout_openvmm_repo 0 flowey e 15 flowey_lib_hvlite::cfg_openvmm_magicpath 0 shell: bash + - name: checking if packages need to be installed + run: flowey e 15 flowey_lib_common::install_dist_pkg 0 + shell: bash + - name: installing packages + run: flowey e 15 flowey_lib_common::install_dist_pkg 1 + shell: bash - name: create gh-release-download cache dir run: flowey e 15 flowey_lib_common::download_gh_release 0 shell: bash @@ -2192,12 +2198,6 @@ jobs: - name: extract X86_64 sysroot.tar.gz run: flowey e 15 flowey_lib_hvlite::init_openvmm_magicpath_openhcl_sysroot 0 shell: bash - - name: checking if packages need to be installed - run: flowey e 15 flowey_lib_common::install_dist_pkg 0 - shell: bash - - name: installing packages - run: flowey e 15 flowey_lib_common::install_dist_pkg 1 - shell: bash - name: set '-Dwarnings' in .cargo/config.toml run: flowey e 15 flowey_lib_hvlite::init_openvmm_cargo_config_deny_warnings 0 shell: bash @@ -3198,6 +3198,12 @@ jobs: flowey e 18 flowey_lib_hvlite::git_checkout_openvmm_repo 0 flowey e 18 flowey_lib_hvlite::cfg_openvmm_magicpath 0 shell: bash + - name: checking if packages need to be installed + run: flowey e 18 flowey_lib_common::install_dist_pkg 0 + shell: bash + - name: installing packages + run: flowey e 18 flowey_lib_common::install_dist_pkg 1 + shell: bash - name: create gh-release-download cache dir run: flowey e 18 flowey_lib_common::download_gh_release 0 shell: bash @@ -3227,12 +3233,6 @@ jobs: - name: extract Aarch64 sysroot.tar.gz run: flowey e 18 flowey_lib_hvlite::init_openvmm_magicpath_openhcl_sysroot 0 shell: bash - - name: checking if packages need to be installed - run: flowey e 18 flowey_lib_common::install_dist_pkg 0 - shell: bash - - name: installing packages - run: flowey e 18 flowey_lib_common::install_dist_pkg 1 - shell: bash - name: set '-Dwarnings' in .cargo/config.toml run: flowey e 18 flowey_lib_hvlite::init_openvmm_cargo_config_deny_warnings 0 shell: bash diff --git a/.github/workflows/openvmm-pr-release.yaml b/.github/workflows/openvmm-pr-release.yaml index 6fefff41ed..7255880004 100644 --- a/.github/workflows/openvmm-pr-release.yaml +++ b/.github/workflows/openvmm-pr-release.yaml @@ -1926,6 +1926,12 @@ jobs: flowey e 15 flowey_lib_hvlite::git_checkout_openvmm_repo 0 flowey e 15 flowey_lib_hvlite::cfg_openvmm_magicpath 0 shell: bash + - name: checking if packages need to be installed + run: flowey e 15 flowey_lib_common::install_dist_pkg 0 + shell: bash + - name: installing packages + run: flowey e 15 flowey_lib_common::install_dist_pkg 1 + shell: bash - name: create gh-release-download cache dir run: flowey e 15 flowey_lib_common::download_gh_release 0 shell: bash @@ -1955,12 +1961,6 @@ jobs: - name: extract X86_64 sysroot.tar.gz run: flowey e 15 flowey_lib_hvlite::init_openvmm_magicpath_openhcl_sysroot 0 shell: bash - - name: checking if packages need to be installed - run: flowey e 15 flowey_lib_common::install_dist_pkg 0 - shell: bash - - name: installing packages - run: flowey e 15 flowey_lib_common::install_dist_pkg 1 - shell: bash - name: set '-Dwarnings' in .cargo/config.toml run: flowey e 15 flowey_lib_hvlite::init_openvmm_cargo_config_deny_warnings 0 shell: bash @@ -2967,6 +2967,12 @@ jobs: flowey e 18 flowey_lib_hvlite::git_checkout_openvmm_repo 0 flowey e 18 flowey_lib_hvlite::cfg_openvmm_magicpath 0 shell: bash + - name: checking if packages need to be installed + run: flowey e 18 flowey_lib_common::install_dist_pkg 0 + shell: bash + - name: installing packages + run: flowey e 18 flowey_lib_common::install_dist_pkg 1 + shell: bash - name: create gh-release-download cache dir run: flowey e 18 flowey_lib_common::download_gh_release 0 shell: bash @@ -2996,12 +3002,6 @@ jobs: - name: extract Aarch64 sysroot.tar.gz run: flowey e 18 flowey_lib_hvlite::init_openvmm_magicpath_openhcl_sysroot 0 shell: bash - - name: checking if packages need to be installed - run: flowey e 18 flowey_lib_common::install_dist_pkg 0 - shell: bash - - name: installing packages - run: flowey e 18 flowey_lib_common::install_dist_pkg 1 - shell: bash - name: set '-Dwarnings' in .cargo/config.toml run: flowey e 18 flowey_lib_hvlite::init_openvmm_cargo_config_deny_warnings 0 shell: bash diff --git a/.github/workflows/openvmm-pr.yaml b/.github/workflows/openvmm-pr.yaml index fc7791378c..4bea8ccc29 100644 --- a/.github/workflows/openvmm-pr.yaml +++ b/.github/workflows/openvmm-pr.yaml @@ -701,6 +701,12 @@ jobs: flowey e 11 flowey_lib_hvlite::git_checkout_openvmm_repo 0 flowey e 11 flowey_lib_hvlite::cfg_openvmm_magicpath 0 shell: bash + - name: checking if packages need to be installed + run: flowey e 11 flowey_lib_common::install_dist_pkg 0 + shell: bash + - name: installing packages + run: flowey e 11 flowey_lib_common::install_dist_pkg 1 + shell: bash - name: create gh-release-download cache dir run: flowey e 11 flowey_lib_common::download_gh_release 0 shell: bash @@ -733,12 +739,6 @@ jobs: - name: set '-Dwarnings' in .cargo/config.toml run: flowey e 11 flowey_lib_hvlite::init_openvmm_cargo_config_deny_warnings 0 shell: bash - - name: checking if packages need to be installed - run: flowey e 11 flowey_lib_common::install_dist_pkg 0 - shell: bash - - name: installing packages - run: flowey e 11 flowey_lib_common::install_dist_pkg 1 - shell: bash - name: unpack protoc run: flowey e 11 flowey_lib_common::resolve_protoc 0 shell: bash @@ -1235,6 +1235,12 @@ jobs: flowey e 13 flowey_lib_hvlite::git_checkout_openvmm_repo 0 flowey e 13 flowey_lib_hvlite::cfg_openvmm_magicpath 0 shell: bash + - name: checking if packages need to be installed + run: flowey e 13 flowey_lib_common::install_dist_pkg 0 + shell: bash + - name: installing packages + run: flowey e 13 flowey_lib_common::install_dist_pkg 1 + shell: bash - name: create gh-release-download cache dir run: flowey e 13 flowey_lib_common::download_gh_release 0 shell: bash @@ -1267,12 +1273,6 @@ jobs: - name: set '-Dwarnings' in .cargo/config.toml run: flowey e 13 flowey_lib_hvlite::init_openvmm_cargo_config_deny_warnings 0 shell: bash - - name: checking if packages need to be installed - run: flowey e 13 flowey_lib_common::install_dist_pkg 0 - shell: bash - - name: installing packages - run: flowey e 13 flowey_lib_common::install_dist_pkg 1 - shell: bash - name: unpack protoc run: flowey e 13 flowey_lib_common::resolve_protoc 0 shell: bash @@ -2317,6 +2317,12 @@ jobs: flowey e 17 flowey_lib_hvlite::git_checkout_openvmm_repo 0 flowey e 17 flowey_lib_hvlite::cfg_openvmm_magicpath 0 shell: bash + - name: checking if packages need to be installed + run: flowey e 17 flowey_lib_common::install_dist_pkg 0 + shell: bash + - name: installing packages + run: flowey e 17 flowey_lib_common::install_dist_pkg 1 + shell: bash - name: create gh-release-download cache dir run: flowey e 17 flowey_lib_common::download_gh_release 0 shell: bash @@ -2346,12 +2352,6 @@ jobs: - name: extract X86_64 sysroot.tar.gz run: flowey e 17 flowey_lib_hvlite::init_openvmm_magicpath_openhcl_sysroot 0 shell: bash - - name: checking if packages need to be installed - run: flowey e 17 flowey_lib_common::install_dist_pkg 0 - shell: bash - - name: installing packages - run: flowey e 17 flowey_lib_common::install_dist_pkg 1 - shell: bash - name: set '-Dwarnings' in .cargo/config.toml run: flowey e 17 flowey_lib_hvlite::init_openvmm_cargo_config_deny_warnings 0 shell: bash @@ -3542,6 +3542,12 @@ jobs: flowey e 20 flowey_lib_hvlite::git_checkout_openvmm_repo 0 flowey e 20 flowey_lib_hvlite::cfg_openvmm_magicpath 0 shell: bash + - name: checking if packages need to be installed + run: flowey e 20 flowey_lib_common::install_dist_pkg 0 + shell: bash + - name: installing packages + run: flowey e 20 flowey_lib_common::install_dist_pkg 1 + shell: bash - name: create gh-release-download cache dir run: flowey e 20 flowey_lib_common::download_gh_release 0 shell: bash @@ -3571,12 +3577,6 @@ jobs: - name: extract Aarch64 sysroot.tar.gz run: flowey e 20 flowey_lib_hvlite::init_openvmm_magicpath_openhcl_sysroot 0 shell: bash - - name: checking if packages need to be installed - run: flowey e 20 flowey_lib_common::install_dist_pkg 0 - shell: bash - - name: installing packages - run: flowey e 20 flowey_lib_common::install_dist_pkg 1 - shell: bash - name: set '-Dwarnings' in .cargo/config.toml run: flowey e 20 flowey_lib_hvlite::init_openvmm_cargo_config_deny_warnings 0 shell: bash diff --git a/ci-flowey/openvmm-pr.yaml b/ci-flowey/openvmm-pr.yaml index 5dd82e462f..8f911ed662 100644 --- a/ci-flowey/openvmm-pr.yaml +++ b/ci-flowey/openvmm-pr.yaml @@ -280,6 +280,10 @@ jobs: $(FLOWEY_BIN) e 15 flowey_lib_hvlite::git_checkout_openvmm_repo 0 $(FLOWEY_BIN) e 15 flowey_lib_hvlite::cfg_openvmm_magicpath 0 displayName: report cloned repo directories + - bash: $(FLOWEY_BIN) e 15 flowey_lib_common::install_dist_pkg 0 + displayName: checking if packages need to be installed + - bash: $(FLOWEY_BIN) e 15 flowey_lib_common::install_dist_pkg 1 + displayName: installing packages - bash: $(FLOWEY_BIN) e 15 flowey_lib_common::download_gh_release 0 displayName: create gh-release-download cache dir - bash: |- @@ -307,10 +311,6 @@ jobs: displayName: unpack openvmm-deps archive - bash: $(FLOWEY_BIN) e 15 flowey_lib_hvlite::init_openvmm_magicpath_openhcl_sysroot 0 displayName: extract X86_64 sysroot.tar.gz - - bash: $(FLOWEY_BIN) e 15 flowey_lib_common::install_dist_pkg 0 - displayName: checking if packages need to be installed - - bash: $(FLOWEY_BIN) e 15 flowey_lib_common::install_dist_pkg 1 - displayName: installing packages - bash: $(FLOWEY_BIN) e 15 flowey_lib_hvlite::init_openvmm_cargo_config_deny_warnings 0 displayName: set '-Dwarnings' in .cargo/config.toml - bash: $(FLOWEY_BIN) e 15 flowey_lib_common::resolve_protoc 0 diff --git a/flowey/flowey_lib_hvlite/src/resolve_openvmm_deps.rs b/flowey/flowey_lib_hvlite/src/resolve_openvmm_deps.rs index bbafb2f36c..16dff43c63 100644 --- a/flowey/flowey_lib_hvlite/src/resolve_openvmm_deps.rs +++ b/flowey/flowey_lib_hvlite/src/resolve_openvmm_deps.rs @@ -2,10 +2,16 @@ // Licensed under the MIT License. //! Download various pre-built `openvmm-deps` dependencies, or use a local path if specified. +//! +//! The openvmm-deps release publishes separate archives: +//! - `openvmm-deps.{arch}.{ver}.tar.gz` — SDK tools (dbgrd, shell, sysroot, petritools) +//! - `openvmm-test-initrd.{arch}.{ver}.tar.gz` — shared test initrd +//! - `openvmm-test-linux-{kernel_ver}.{arch}.{ver}.tar.gz` — test kernel use crate::common::CommonArch; use flowey::node::prelude::*; use std::collections::BTreeMap; +use std::collections::BTreeSet; /// Which file to extract from the openvmm-deps archive. #[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] @@ -27,6 +33,37 @@ impl OpenvmmDepFile { } } +/// Which source archive a dep file comes from. +/// +/// Test kernel and initrd archives are handled by their own dedicated nodes +/// ([`crate::resolve_openvmm_test_linux_kernel`] and +/// [`crate::resolve_openvmm_test_initrd`]). +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] +enum SourceArchive { + /// `openvmm-deps.{arch}.{ver}.tar.gz` + OpenvmmDeps, +} + +impl OpenvmmDepFile { + fn source_archive(self) -> SourceArchive { + match self { + Self::OpenhclCpioDbgrd + | Self::OpenhclCpioShell + | Self::OpenhclSysroot + | Self::PetritoolsErofs => SourceArchive::OpenvmmDeps, + } + } +} + +impl SourceArchive { + /// Returns the archive filename for the given architecture and version. + fn archive_filename(self, arch_str: &str, version: &str) -> String { + match self { + Self::OpenvmmDeps => format!("openvmm-deps.{arch_str}.{version}.tar.gz"), + } + } +} + flowey_config! { /// Config for the resolve_openvmm_deps node. pub struct Config { @@ -87,9 +124,6 @@ impl FlowNodeWithConfig for Node { return Ok(()); } - // Which architectures have at least one dep requested? - let needs_arch = |arch: CommonArch| deps.keys().any(|(_, a)| *a == arch); - if !local_paths.is_empty() { ctx.emit_rust_step("use local openvmm-deps", |ctx| { let deps = deps.claim(ctx); @@ -118,67 +152,68 @@ impl FlowNodeWithConfig for Node { return Ok(()); } - let extract_tar_gz_persistent_dir = ctx.persistent_dir(); - - let download_archive = |arch: CommonArch, ctx: &mut NodeCtx<'_>| { - let version = version.clone().expect("local requests handled above"); - let arch_str = match arch { - CommonArch::X86_64 => "x86_64", - CommonArch::Aarch64 => "aarch64", - }; - ctx.reqv(|v| flowey_lib_common::download_gh_release::Request { - repo_owner: "microsoft".into(), - repo_name: "openvmm-deps".into(), - needs_auth: false, - tag: version.clone(), - file_name: format!("openvmm-deps.{arch_str}.{version}.tar.gz"), - path: v, - }) - }; + let version = version.expect("local requests handled above"); - let openvmm_deps_tar_gz_x64 = - needs_arch(CommonArch::X86_64).then(|| download_archive(CommonArch::X86_64, ctx)); - let openvmm_deps_tar_gz_aarch64 = - needs_arch(CommonArch::Aarch64).then(|| download_archive(CommonArch::Aarch64, ctx)); + // Determine which (source_archive, arch) pairs we need to download. + let needed_archives: BTreeSet<(SourceArchive, CommonArch)> = deps + .keys() + .map(|(dep, arch)| (dep.source_archive(), *arch)) + .collect(); + + let extract_tar_bz2_deps = + flowey_lib_common::_util::extract::extract_tar_bz2_if_new_deps(ctx); + + // Download each unique (source_archive, arch) pair. + let downloads: BTreeMap<(SourceArchive, CommonArch), ReadVar> = needed_archives + .into_iter() + .map(|(source, arch)| { + let arch_str = match arch { + CommonArch::X86_64 => "x86_64", + CommonArch::Aarch64 => "aarch64", + }; + let file_name = source.archive_filename(arch_str, &version); + let path = ctx.reqv(|v| flowey_lib_common::download_gh_release::Request { + repo_owner: "microsoft".into(), + repo_name: "openvmm-deps".into(), + needs_auth: false, + tag: version.clone(), + file_name, + path: v, + }); + ((source, arch), path) + }) + .collect(); ctx.emit_rust_step("unpack openvmm-deps archive", |ctx| { - let extract_tar_gz_persistent_dir = extract_tar_gz_persistent_dir.claim(ctx); - let openvmm_deps_tar_gz_x64 = openvmm_deps_tar_gz_x64.claim(ctx); - let openvmm_deps_tar_gz_aarch64 = openvmm_deps_tar_gz_aarch64.claim(ctx); + let extract_tar_bz2_deps = extract_tar_bz2_deps.claim(ctx); + let downloads: BTreeMap<_, _> = downloads + .into_iter() + .map(|(key, var)| (key, var.claim(ctx))) + .collect(); let deps = deps.claim(ctx); - let version = version.clone().expect("local requests handled above"); + let version = version.clone(); move |rt| { - let persistent_dir = extract_tar_gz_persistent_dir.map(|d| rt.read(d)); - let extract_dir_x64 = openvmm_deps_tar_gz_x64 - .map(|file| { - let file = rt.read(file); - flowey_lib_common::_util::extract::extract_tar_gz_if_new( - rt, - persistent_dir.as_deref(), - &file, - &version, - ) - }) - .transpose()?; - let extract_dir_aarch64 = openvmm_deps_tar_gz_aarch64 - .map(|file| { - let file = rt.read(file); - flowey_lib_common::_util::extract::extract_tar_gz_if_new( + // Extract each downloaded archive, keyed by (source, arch). + let extract_dirs: BTreeMap<(SourceArchive, CommonArch), PathBuf> = downloads + .into_iter() + .map(|(key, var)| { + let file = rt.read(var); + let dir = flowey_lib_common::_util::extract::extract_tar_bz2_if_new( rt, - persistent_dir.as_deref(), + extract_tar_bz2_deps.clone(), &file, &version, - ) + )?; + Ok((key, dir)) }) - .transpose()?; - - let base_dir = |arch| match arch { - CommonArch::X86_64 => extract_dir_x64.clone().unwrap(), - CommonArch::Aarch64 => extract_dir_aarch64.clone().unwrap(), - }; + .collect::>()?; for ((dep, arch), vars) in deps { - let path = base_dir(arch).join(dep.filename()); + let source = dep.source_archive(); + let extract_dir = extract_dirs + .get(&(source, arch)) + .expect("archive was downloaded for this dep"); + let path = extract_dir.join(dep.filename()); rt.write_all(vars, &path) } From 200dc9e67d1b6fef334e7f7d208645190e7876a4 Mon Sep 17 00:00:00 2001 From: Kyle Moorhead Date: Wed, 20 May 2026 16:26:53 +0000 Subject: [PATCH 3/6] flowey: add Linux 6.18 test kernel and set as default - Add Linux6_18 variant to LinuxTestKernelVersion enum - Update DEFAULT_LINUX_TEST_KERNEL_VERSION to Linux6_18 - Remove unused OPENVMM_TEST_LINUX_KERNEL constant from cfg_versions Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../src/resolve_openvmm_test_linux_kernel.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/flowey/flowey_lib_hvlite/src/resolve_openvmm_test_linux_kernel.rs b/flowey/flowey_lib_hvlite/src/resolve_openvmm_test_linux_kernel.rs index f32dad9092..b98741d2e2 100644 --- a/flowey/flowey_lib_hvlite/src/resolve_openvmm_test_linux_kernel.rs +++ b/flowey/flowey_lib_hvlite/src/resolve_openvmm_test_linux_kernel.rs @@ -21,10 +21,6 @@ use std::collections::BTreeSet; /// Which Linux test kernel version to fetch from the openvmm-deps GitHub /// release. -/// -/// The `openvmm-deps` release currently only ships the 6.1 kernel; additional -/// kernel lines (e.g. 6.6, 6.12) are intended to be added as purely additive -/// follow-ups, both upstream and as new variants of this enum. #[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub enum LinuxTestKernelVersion { Linux6_1, @@ -78,7 +74,7 @@ impl OpenvmmTestKernelFile { /// The default Linux test kernel version. Call sites that don't otherwise care /// which kernel they're using should pass this. pub const DEFAULT_LINUX_TEST_KERNEL_VERSION: LinuxTestKernelVersion = - LinuxTestKernelVersion::Linux6_1; + LinuxTestKernelVersion::Linux6_18; flowey_config! { /// Config for the resolve_openvmm_test_linux_kernel node. From 8ecc95b807db92c26d53c003127a660cbc413958 Mon Sep 17 00:00:00 2001 From: Kyle Moorhead Date: Wed, 20 May 2026 20:00:22 +0000 Subject: [PATCH 4/6] fix(flowey): use tar.gz extraction for openvmm-deps archives The rewrite incorrectly used extract_tar_bz2_if_new which unnecessarily installs the bzip2 package. Switch to extract_tar_gz_if_new consistent with the sibling test kernel and initrd resolver modules. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/openvmm-ci.yaml | 24 +++++----- .github/workflows/openvmm-pr-release.yaml | 24 +++++----- .github/workflows/openvmm-pr.yaml | 48 +++++++++---------- ci-flowey/openvmm-pr.yaml | 8 ++-- .../src/resolve_openvmm_deps.rs | 11 +++-- 5 files changed, 58 insertions(+), 57 deletions(-) diff --git a/.github/workflows/openvmm-ci.yaml b/.github/workflows/openvmm-ci.yaml index cf2f6c109e..062534d926 100644 --- a/.github/workflows/openvmm-ci.yaml +++ b/.github/workflows/openvmm-ci.yaml @@ -2163,12 +2163,6 @@ jobs: flowey e 15 flowey_lib_hvlite::git_checkout_openvmm_repo 0 flowey e 15 flowey_lib_hvlite::cfg_openvmm_magicpath 0 shell: bash - - name: checking if packages need to be installed - run: flowey e 15 flowey_lib_common::install_dist_pkg 0 - shell: bash - - name: installing packages - run: flowey e 15 flowey_lib_common::install_dist_pkg 1 - shell: bash - name: create gh-release-download cache dir run: flowey e 15 flowey_lib_common::download_gh_release 0 shell: bash @@ -2198,6 +2192,12 @@ jobs: - name: extract X86_64 sysroot.tar.gz run: flowey e 15 flowey_lib_hvlite::init_openvmm_magicpath_openhcl_sysroot 0 shell: bash + - name: checking if packages need to be installed + run: flowey e 15 flowey_lib_common::install_dist_pkg 0 + shell: bash + - name: installing packages + run: flowey e 15 flowey_lib_common::install_dist_pkg 1 + shell: bash - name: set '-Dwarnings' in .cargo/config.toml run: flowey e 15 flowey_lib_hvlite::init_openvmm_cargo_config_deny_warnings 0 shell: bash @@ -3198,12 +3198,6 @@ jobs: flowey e 18 flowey_lib_hvlite::git_checkout_openvmm_repo 0 flowey e 18 flowey_lib_hvlite::cfg_openvmm_magicpath 0 shell: bash - - name: checking if packages need to be installed - run: flowey e 18 flowey_lib_common::install_dist_pkg 0 - shell: bash - - name: installing packages - run: flowey e 18 flowey_lib_common::install_dist_pkg 1 - shell: bash - name: create gh-release-download cache dir run: flowey e 18 flowey_lib_common::download_gh_release 0 shell: bash @@ -3233,6 +3227,12 @@ jobs: - name: extract Aarch64 sysroot.tar.gz run: flowey e 18 flowey_lib_hvlite::init_openvmm_magicpath_openhcl_sysroot 0 shell: bash + - name: checking if packages need to be installed + run: flowey e 18 flowey_lib_common::install_dist_pkg 0 + shell: bash + - name: installing packages + run: flowey e 18 flowey_lib_common::install_dist_pkg 1 + shell: bash - name: set '-Dwarnings' in .cargo/config.toml run: flowey e 18 flowey_lib_hvlite::init_openvmm_cargo_config_deny_warnings 0 shell: bash diff --git a/.github/workflows/openvmm-pr-release.yaml b/.github/workflows/openvmm-pr-release.yaml index 7255880004..6fefff41ed 100644 --- a/.github/workflows/openvmm-pr-release.yaml +++ b/.github/workflows/openvmm-pr-release.yaml @@ -1926,12 +1926,6 @@ jobs: flowey e 15 flowey_lib_hvlite::git_checkout_openvmm_repo 0 flowey e 15 flowey_lib_hvlite::cfg_openvmm_magicpath 0 shell: bash - - name: checking if packages need to be installed - run: flowey e 15 flowey_lib_common::install_dist_pkg 0 - shell: bash - - name: installing packages - run: flowey e 15 flowey_lib_common::install_dist_pkg 1 - shell: bash - name: create gh-release-download cache dir run: flowey e 15 flowey_lib_common::download_gh_release 0 shell: bash @@ -1961,6 +1955,12 @@ jobs: - name: extract X86_64 sysroot.tar.gz run: flowey e 15 flowey_lib_hvlite::init_openvmm_magicpath_openhcl_sysroot 0 shell: bash + - name: checking if packages need to be installed + run: flowey e 15 flowey_lib_common::install_dist_pkg 0 + shell: bash + - name: installing packages + run: flowey e 15 flowey_lib_common::install_dist_pkg 1 + shell: bash - name: set '-Dwarnings' in .cargo/config.toml run: flowey e 15 flowey_lib_hvlite::init_openvmm_cargo_config_deny_warnings 0 shell: bash @@ -2967,12 +2967,6 @@ jobs: flowey e 18 flowey_lib_hvlite::git_checkout_openvmm_repo 0 flowey e 18 flowey_lib_hvlite::cfg_openvmm_magicpath 0 shell: bash - - name: checking if packages need to be installed - run: flowey e 18 flowey_lib_common::install_dist_pkg 0 - shell: bash - - name: installing packages - run: flowey e 18 flowey_lib_common::install_dist_pkg 1 - shell: bash - name: create gh-release-download cache dir run: flowey e 18 flowey_lib_common::download_gh_release 0 shell: bash @@ -3002,6 +2996,12 @@ jobs: - name: extract Aarch64 sysroot.tar.gz run: flowey e 18 flowey_lib_hvlite::init_openvmm_magicpath_openhcl_sysroot 0 shell: bash + - name: checking if packages need to be installed + run: flowey e 18 flowey_lib_common::install_dist_pkg 0 + shell: bash + - name: installing packages + run: flowey e 18 flowey_lib_common::install_dist_pkg 1 + shell: bash - name: set '-Dwarnings' in .cargo/config.toml run: flowey e 18 flowey_lib_hvlite::init_openvmm_cargo_config_deny_warnings 0 shell: bash diff --git a/.github/workflows/openvmm-pr.yaml b/.github/workflows/openvmm-pr.yaml index 4bea8ccc29..fc7791378c 100644 --- a/.github/workflows/openvmm-pr.yaml +++ b/.github/workflows/openvmm-pr.yaml @@ -701,12 +701,6 @@ jobs: flowey e 11 flowey_lib_hvlite::git_checkout_openvmm_repo 0 flowey e 11 flowey_lib_hvlite::cfg_openvmm_magicpath 0 shell: bash - - name: checking if packages need to be installed - run: flowey e 11 flowey_lib_common::install_dist_pkg 0 - shell: bash - - name: installing packages - run: flowey e 11 flowey_lib_common::install_dist_pkg 1 - shell: bash - name: create gh-release-download cache dir run: flowey e 11 flowey_lib_common::download_gh_release 0 shell: bash @@ -739,6 +733,12 @@ jobs: - name: set '-Dwarnings' in .cargo/config.toml run: flowey e 11 flowey_lib_hvlite::init_openvmm_cargo_config_deny_warnings 0 shell: bash + - name: checking if packages need to be installed + run: flowey e 11 flowey_lib_common::install_dist_pkg 0 + shell: bash + - name: installing packages + run: flowey e 11 flowey_lib_common::install_dist_pkg 1 + shell: bash - name: unpack protoc run: flowey e 11 flowey_lib_common::resolve_protoc 0 shell: bash @@ -1235,12 +1235,6 @@ jobs: flowey e 13 flowey_lib_hvlite::git_checkout_openvmm_repo 0 flowey e 13 flowey_lib_hvlite::cfg_openvmm_magicpath 0 shell: bash - - name: checking if packages need to be installed - run: flowey e 13 flowey_lib_common::install_dist_pkg 0 - shell: bash - - name: installing packages - run: flowey e 13 flowey_lib_common::install_dist_pkg 1 - shell: bash - name: create gh-release-download cache dir run: flowey e 13 flowey_lib_common::download_gh_release 0 shell: bash @@ -1273,6 +1267,12 @@ jobs: - name: set '-Dwarnings' in .cargo/config.toml run: flowey e 13 flowey_lib_hvlite::init_openvmm_cargo_config_deny_warnings 0 shell: bash + - name: checking if packages need to be installed + run: flowey e 13 flowey_lib_common::install_dist_pkg 0 + shell: bash + - name: installing packages + run: flowey e 13 flowey_lib_common::install_dist_pkg 1 + shell: bash - name: unpack protoc run: flowey e 13 flowey_lib_common::resolve_protoc 0 shell: bash @@ -2317,12 +2317,6 @@ jobs: flowey e 17 flowey_lib_hvlite::git_checkout_openvmm_repo 0 flowey e 17 flowey_lib_hvlite::cfg_openvmm_magicpath 0 shell: bash - - name: checking if packages need to be installed - run: flowey e 17 flowey_lib_common::install_dist_pkg 0 - shell: bash - - name: installing packages - run: flowey e 17 flowey_lib_common::install_dist_pkg 1 - shell: bash - name: create gh-release-download cache dir run: flowey e 17 flowey_lib_common::download_gh_release 0 shell: bash @@ -2352,6 +2346,12 @@ jobs: - name: extract X86_64 sysroot.tar.gz run: flowey e 17 flowey_lib_hvlite::init_openvmm_magicpath_openhcl_sysroot 0 shell: bash + - name: checking if packages need to be installed + run: flowey e 17 flowey_lib_common::install_dist_pkg 0 + shell: bash + - name: installing packages + run: flowey e 17 flowey_lib_common::install_dist_pkg 1 + shell: bash - name: set '-Dwarnings' in .cargo/config.toml run: flowey e 17 flowey_lib_hvlite::init_openvmm_cargo_config_deny_warnings 0 shell: bash @@ -3542,12 +3542,6 @@ jobs: flowey e 20 flowey_lib_hvlite::git_checkout_openvmm_repo 0 flowey e 20 flowey_lib_hvlite::cfg_openvmm_magicpath 0 shell: bash - - name: checking if packages need to be installed - run: flowey e 20 flowey_lib_common::install_dist_pkg 0 - shell: bash - - name: installing packages - run: flowey e 20 flowey_lib_common::install_dist_pkg 1 - shell: bash - name: create gh-release-download cache dir run: flowey e 20 flowey_lib_common::download_gh_release 0 shell: bash @@ -3577,6 +3571,12 @@ jobs: - name: extract Aarch64 sysroot.tar.gz run: flowey e 20 flowey_lib_hvlite::init_openvmm_magicpath_openhcl_sysroot 0 shell: bash + - name: checking if packages need to be installed + run: flowey e 20 flowey_lib_common::install_dist_pkg 0 + shell: bash + - name: installing packages + run: flowey e 20 flowey_lib_common::install_dist_pkg 1 + shell: bash - name: set '-Dwarnings' in .cargo/config.toml run: flowey e 20 flowey_lib_hvlite::init_openvmm_cargo_config_deny_warnings 0 shell: bash diff --git a/ci-flowey/openvmm-pr.yaml b/ci-flowey/openvmm-pr.yaml index 8f911ed662..5dd82e462f 100644 --- a/ci-flowey/openvmm-pr.yaml +++ b/ci-flowey/openvmm-pr.yaml @@ -280,10 +280,6 @@ jobs: $(FLOWEY_BIN) e 15 flowey_lib_hvlite::git_checkout_openvmm_repo 0 $(FLOWEY_BIN) e 15 flowey_lib_hvlite::cfg_openvmm_magicpath 0 displayName: report cloned repo directories - - bash: $(FLOWEY_BIN) e 15 flowey_lib_common::install_dist_pkg 0 - displayName: checking if packages need to be installed - - bash: $(FLOWEY_BIN) e 15 flowey_lib_common::install_dist_pkg 1 - displayName: installing packages - bash: $(FLOWEY_BIN) e 15 flowey_lib_common::download_gh_release 0 displayName: create gh-release-download cache dir - bash: |- @@ -311,6 +307,10 @@ jobs: displayName: unpack openvmm-deps archive - bash: $(FLOWEY_BIN) e 15 flowey_lib_hvlite::init_openvmm_magicpath_openhcl_sysroot 0 displayName: extract X86_64 sysroot.tar.gz + - bash: $(FLOWEY_BIN) e 15 flowey_lib_common::install_dist_pkg 0 + displayName: checking if packages need to be installed + - bash: $(FLOWEY_BIN) e 15 flowey_lib_common::install_dist_pkg 1 + displayName: installing packages - bash: $(FLOWEY_BIN) e 15 flowey_lib_hvlite::init_openvmm_cargo_config_deny_warnings 0 displayName: set '-Dwarnings' in .cargo/config.toml - bash: $(FLOWEY_BIN) e 15 flowey_lib_common::resolve_protoc 0 diff --git a/flowey/flowey_lib_hvlite/src/resolve_openvmm_deps.rs b/flowey/flowey_lib_hvlite/src/resolve_openvmm_deps.rs index 16dff43c63..31a39f054f 100644 --- a/flowey/flowey_lib_hvlite/src/resolve_openvmm_deps.rs +++ b/flowey/flowey_lib_hvlite/src/resolve_openvmm_deps.rs @@ -160,8 +160,7 @@ impl FlowNodeWithConfig for Node { .map(|(dep, arch)| (dep.source_archive(), *arch)) .collect(); - let extract_tar_bz2_deps = - flowey_lib_common::_util::extract::extract_tar_bz2_if_new_deps(ctx); + let persistent_dir = ctx.persistent_dir(); // Download each unique (source_archive, arch) pair. let downloads: BTreeMap<(SourceArchive, CommonArch), ReadVar> = needed_archives @@ -185,7 +184,7 @@ impl FlowNodeWithConfig for Node { .collect(); ctx.emit_rust_step("unpack openvmm-deps archive", |ctx| { - let extract_tar_bz2_deps = extract_tar_bz2_deps.claim(ctx); + let persistent_dir = persistent_dir.claim(ctx); let downloads: BTreeMap<_, _> = downloads .into_iter() .map(|(key, var)| (key, var.claim(ctx))) @@ -193,14 +192,16 @@ impl FlowNodeWithConfig for Node { let deps = deps.claim(ctx); let version = version.clone(); move |rt| { + let persistent_dir = persistent_dir.map(|d| rt.read(d)); + // Extract each downloaded archive, keyed by (source, arch). let extract_dirs: BTreeMap<(SourceArchive, CommonArch), PathBuf> = downloads .into_iter() .map(|(key, var)| { let file = rt.read(var); - let dir = flowey_lib_common::_util::extract::extract_tar_bz2_if_new( + let dir = flowey_lib_common::_util::extract::extract_tar_gz_if_new( rt, - extract_tar_bz2_deps.clone(), + persistent_dir.as_deref(), &file, &version, )?; From 2e942520261235f2188b5c37baad573f3288d624 Mon Sep 17 00:00:00 2001 From: Kyle Moorhead Date: Wed, 20 May 2026 20:05:04 +0000 Subject: [PATCH 5/6] refactor(flowey): remove single-variant SourceArchive enum Inline the archive filename logic directly since there is only one archive type (openvmm-deps). The kernel and initrd archives are handled by their own dedicated resolver modules. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../src/resolve_openvmm_deps.rs | 61 ++++--------------- 1 file changed, 13 insertions(+), 48 deletions(-) diff --git a/flowey/flowey_lib_hvlite/src/resolve_openvmm_deps.rs b/flowey/flowey_lib_hvlite/src/resolve_openvmm_deps.rs index 31a39f054f..f1feae3d43 100644 --- a/flowey/flowey_lib_hvlite/src/resolve_openvmm_deps.rs +++ b/flowey/flowey_lib_hvlite/src/resolve_openvmm_deps.rs @@ -33,37 +33,6 @@ impl OpenvmmDepFile { } } -/// Which source archive a dep file comes from. -/// -/// Test kernel and initrd archives are handled by their own dedicated nodes -/// ([`crate::resolve_openvmm_test_linux_kernel`] and -/// [`crate::resolve_openvmm_test_initrd`]). -#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] -enum SourceArchive { - /// `openvmm-deps.{arch}.{ver}.tar.gz` - OpenvmmDeps, -} - -impl OpenvmmDepFile { - fn source_archive(self) -> SourceArchive { - match self { - Self::OpenhclCpioDbgrd - | Self::OpenhclCpioShell - | Self::OpenhclSysroot - | Self::PetritoolsErofs => SourceArchive::OpenvmmDeps, - } - } -} - -impl SourceArchive { - /// Returns the archive filename for the given architecture and version. - fn archive_filename(self, arch_str: &str, version: &str) -> String { - match self { - Self::OpenvmmDeps => format!("openvmm-deps.{arch_str}.{version}.tar.gz"), - } - } -} - flowey_config! { /// Config for the resolve_openvmm_deps node. pub struct Config { @@ -154,23 +123,20 @@ impl FlowNodeWithConfig for Node { let version = version.expect("local requests handled above"); - // Determine which (source_archive, arch) pairs we need to download. - let needed_archives: BTreeSet<(SourceArchive, CommonArch)> = deps - .keys() - .map(|(dep, arch)| (dep.source_archive(), *arch)) - .collect(); + // Determine which architectures we need to download. + let needed_archs: BTreeSet = deps.keys().map(|(_, arch)| *arch).collect(); let persistent_dir = ctx.persistent_dir(); - // Download each unique (source_archive, arch) pair. - let downloads: BTreeMap<(SourceArchive, CommonArch), ReadVar> = needed_archives + // Download each unique architecture. + let downloads: BTreeMap> = needed_archs .into_iter() - .map(|(source, arch)| { + .map(|arch| { let arch_str = match arch { CommonArch::X86_64 => "x86_64", CommonArch::Aarch64 => "aarch64", }; - let file_name = source.archive_filename(arch_str, &version); + let file_name = format!("openvmm-deps.{arch_str}.{version}.tar.gz"); let path = ctx.reqv(|v| flowey_lib_common::download_gh_release::Request { repo_owner: "microsoft".into(), repo_name: "openvmm-deps".into(), @@ -179,7 +145,7 @@ impl FlowNodeWithConfig for Node { file_name, path: v, }); - ((source, arch), path) + (arch, path) }) .collect(); @@ -194,10 +160,10 @@ impl FlowNodeWithConfig for Node { move |rt| { let persistent_dir = persistent_dir.map(|d| rt.read(d)); - // Extract each downloaded archive, keyed by (source, arch). - let extract_dirs: BTreeMap<(SourceArchive, CommonArch), PathBuf> = downloads + // Extract each downloaded archive, keyed by architecture. + let extract_dirs: BTreeMap = downloads .into_iter() - .map(|(key, var)| { + .map(|(arch, var)| { let file = rt.read(var); let dir = flowey_lib_common::_util::extract::extract_tar_gz_if_new( rt, @@ -205,15 +171,14 @@ impl FlowNodeWithConfig for Node { &file, &version, )?; - Ok((key, dir)) + Ok((arch, dir)) }) .collect::>()?; for ((dep, arch), vars) in deps { - let source = dep.source_archive(); let extract_dir = extract_dirs - .get(&(source, arch)) - .expect("archive was downloaded for this dep"); + .get(&arch) + .expect("archive was downloaded for this arch"); let path = extract_dir.join(dep.filename()); rt.write_all(vars, &path) } From e90f1e407ebdfda3cb7687f80e339654c91ecf86 Mon Sep 17 00:00:00 2001 From: Kyle Moorhead Date: Thu, 28 May 2026 20:04:11 +0000 Subject: [PATCH 6/6] fix(vmm-tests): pin pcie_devices test to kernel 6.1 The pcie_devices test crashes on Linux 6.18 due to a known kernel bug in mana_gd_probe where debugfs_create_dir dereferences a NULL pdev->slot pointer. Pin to 6.1 until the upstream fix is available. --- vmm_tests/vmm_tests/tests/tests/multiarch/pcie.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vmm_tests/vmm_tests/tests/tests/multiarch/pcie.rs b/vmm_tests/vmm_tests/tests/tests/multiarch/pcie.rs index fa90a937ca..634a2249b6 100644 --- a/vmm_tests/vmm_tests/tests/tests/multiarch/pcie.rs +++ b/vmm_tests/vmm_tests/tests/tests/multiarch/pcie.rs @@ -275,7 +275,7 @@ async fn pcie_switches(config: PetriVmBuilder) -> anyhow::R /// /// NOTE: This test relies on device specific software (drivers, /// tooling) within the guest OS to perform the validation. -#[openvmm_test(unstable_linux_direct_x64)] +#[openvmm_test(unstable_linux_direct_x64(kernel_6_1))] async fn pcie_devices(config: PetriVmBuilder) -> anyhow::Result<()> { let os_flavor = config.os_flavor(); let (vm, agent) = config