Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
ddd79b2
ci: add very_heavy test class, and write about test monikers in the g…
mattkur Oct 24, 2025
d415aa1
really? a space? okay.
mattkur Oct 24, 2025
88bc704
copilot feedback
mattkur Oct 24, 2025
f82d3e8
initial wip
mattkur Oct 20, 2025
de9459e
leverage hints
mattkur Oct 20, 2025
280a0e4
add release-only tests
mattkur Oct 24, 2025
d08dccd
self pr feedback
mattkur Oct 24, 2025
1f58b6a
pr feedback + tests
mattkur Oct 24, 2025
3c2b7d0
unit test fixups
mattkur Oct 25, 2025
e7da72a
clippy
mattkur Oct 25, 2025
bde3f51
Merge branch 'main' into private-pool
mattkur Oct 27, 2025
0e9007c
Merge branch 'main' into private-pool
mattkur Oct 28, 2025
1cc96c6
pr feedback: parameterize the lookup tables + other nits
mattkur Oct 28, 2025
f3074ab
clippy
mattkur Oct 28, 2025
a309359
Merge branch 'main' into private-pool
mattkur Oct 29, 2025
1feeac3
self cleanup + oops forgot json manifests
mattkur Oct 29, 2025
086b28a
openhcl_boot: write in-memory logger to serial when the serial port i…
mattkur Oct 29, 2025
21cd194
Merge branch 'boot-logger-memory-write' into private-pool
mattkur Oct 29, 2025
2ae5173
tweak the debug table
mattkur Oct 29, 2025
f606760
pr feedback
mattkur Oct 29, 2025
c8fa2c0
petri/hyperv: preserve more of the VMs artifacts if PETRI_PRESERVE_VM…
mattkur Oct 29, 2025
ce1baab
Merge branch 'preserve-vm' into private-pool
mattkur Oct 29, 2025
8abbe25
merge oops
mattkur Oct 29, 2025
ce9db8e
handle host-provided 0 dt
mattkur Oct 29, 2025
1cf53b4
adjust dev lookup table
mattkur Oct 29, 2025
ad64aec
update dev lookup table to rationalize around ~3 NVMe devices per spe…
mattkur Oct 29, 2025
fca8912
revert preserve vm stuff
mattkur Oct 29, 2025
c9ccd0a
revert more remnants of petri core
mattkur Oct 29, 2025
fd7f7df
Merge branch 'main' into private-pool
mattkur Oct 29, 2025
a470a37
fixup vtl2 ram counter test
mattkur Oct 30, 2025
db29ab4
Merge branch 'boot-logger-memory-write' into private-pool
mattkur Oct 30, 2025
39fa3c6
pr nit
mattkur Oct 30, 2025
5fef416
sigh, override override override
mattkur Oct 30, 2025
547f042
try this (release)
mattkur Oct 30, 2025
1ef840a
Merge branch 'main' into private-pool
mattkur Oct 30, 2025
473a8e4
pr feedback: don't reserve private pool for isolated VMs
mattkur Oct 30, 2025
4de0c81
oops
mattkur Oct 30, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5013,7 +5013,9 @@ dependencies = [
"sidecar_defs",
"string_page_buf",
"tdcall",
"test_with_tracing",
"thiserror 2.0.16",
"tracing",
"underhill_confidentiality",
"x86defs",
"zerocopy 0.8.25",
Expand Down
4 changes: 4 additions & 0 deletions openhcl/openhcl_boot/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ safe_intrinsics.workspace = true
tdcall.workspace = true
x86defs.workspace = true

[dev-dependencies]
test_with_tracing.workspace = true
tracing.workspace = true

[build-dependencies]
minimal_rt_build.workspace = true

Expand Down
175 changes: 131 additions & 44 deletions openhcl/openhcl_boot/src/cmdline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,23 @@

//! Command line arguments and parsing for openhcl_boot.

use crate::boot_logger::log;
use underhill_confidentiality::OPENHCL_CONFIDENTIAL_DEBUG_ENV_VAR_NAME;

/// Enable the private VTL2 GPA pool for page allocations. This is only enabled
/// via the command line, because in order to support the VTL2 GPA pool
/// generically, the boot shim must read serialized data from the previous
/// OpenHCL instance on a servicing boot in order to guarantee the same memory
/// layout is presented.
/// Enable the private VTL2 GPA pool for page allocations.
///
/// The value specified is the number of 4K pages to reserve for the pool.
/// Possible values:
/// * `release`: Use the release version of the lookup table (default), or device tree.
/// * `debug`: Use the debug version of the lookup table, or device tree.
/// * `off`: Disable the VTL2 GPA pool.
/// * `<num_pages>`: Explicitly specify the size of the VTL2 GPA pool.
///
/// TODO: Remove this commandline once support for reading saved state is
/// supported in openhcl_boot.
/// See `Vtl2GpaPoolConfig` for more details.
const IGVM_VTL2_GPA_POOL_CONFIG: &str = "OPENHCL_IGVM_VTL2_GPA_POOL_CONFIG=";

/// Test-legacy/test-compat override for `OPENHCL_IGVM_VTL2_GPA_POOL_CONFIG`.
/// (otherwise, tests cannot modify the VTL2 GPA pool config different from what
/// may be in the manifest).
const ENABLE_VTL2_GPA_POOL: &str = "OPENHCL_ENABLE_VTL2_GPA_POOL=";

/// Options controlling sidecar.
Expand All @@ -29,10 +34,59 @@ const SIDECAR: &str = "OPENHCL_SIDECAR=";
/// Disable NVME keep alive regardless if the host supports it.
const DISABLE_NVME_KEEP_ALIVE: &str = "OPENHCL_DISABLE_NVME_KEEP_ALIVE=";

/// Lookup table to use for VTL2 GPA pool size heuristics.
#[derive(Debug, PartialEq, Clone, Copy)]
pub enum Vtl2GpaPoolLookupTable {
Release,
Debug,
}

#[derive(Debug, PartialEq, Clone, Copy)]
pub enum Vtl2GpaPoolConfig {
/// Use heuristics to determine the VTL2 GPA pool size.
/// Reserve a default size based on the amount of VTL2 ram and
/// number of vCPUs. The point of this method is to account for cases where
/// we retrofit the private pool into existing deployments that do not
/// specify it explicitly.
///
/// If the host specifies a size via the device tree, that size will be used
/// instead.
///
/// The lookup table specifies whether to use the debug or release
/// heuristics (as the dev manifests provide different amounts of VTL2 RAM).
Heuristics(Vtl2GpaPoolLookupTable),

/// Explicitly disable the VTL2 private pool.
Off,

/// Explicitly specify the size of the VTL2 GPA pool in pages.
Pages(u64),
}

impl<S: AsRef<str>> From<S> for Vtl2GpaPoolConfig {
fn from(arg: S) -> Self {
match arg.as_ref() {
"debug" => Vtl2GpaPoolConfig::Heuristics(Vtl2GpaPoolLookupTable::Debug),
"release" => Vtl2GpaPoolConfig::Heuristics(Vtl2GpaPoolLookupTable::Release),
"off" => Vtl2GpaPoolConfig::Off,
_ => {
let num = arg.as_ref().parse::<u64>().unwrap_or(0);
// A size of 0 or failure to parse is treated as disabling
// the pool.
if num == 0 {
Vtl2GpaPoolConfig::Off
} else {
Vtl2GpaPoolConfig::Pages(num)
}
}
}
}
}

#[derive(Debug, PartialEq)]
pub struct BootCommandLineOptions {
pub confidential_debug: bool,
pub enable_vtl2_gpa_pool: Option<u64>,
pub enable_vtl2_gpa_pool: Vtl2GpaPoolConfig,
pub sidecar: bool,
pub sidecar_logging: bool,
pub disable_nvme_keep_alive: bool,
Expand All @@ -42,7 +96,7 @@ impl BootCommandLineOptions {
pub const fn new() -> Self {
BootCommandLineOptions {
confidential_debug: false,
enable_vtl2_gpa_pool: None,
enable_vtl2_gpa_pool: Vtl2GpaPoolConfig::Heuristics(Vtl2GpaPoolLookupTable::Release), // use the release config by default
sidecar: true, // sidecar is enabled by default
sidecar_logging: false,
disable_nvme_keep_alive: false,
Expand All @@ -53,19 +107,25 @@ impl BootCommandLineOptions {
impl BootCommandLineOptions {
/// Parse arguments from a command line.
pub fn parse(&mut self, cmdline: &str) {
let mut override_vtl2_gpa_pool: Option<Vtl2GpaPoolConfig> = None;
for arg in cmdline.split_whitespace() {
if arg.starts_with(OPENHCL_CONFIDENTIAL_DEBUG_ENV_VAR_NAME) {
let arg = arg.split_once('=').map(|(_, arg)| arg);
if arg.is_some_and(|a| a != "0") {
self.confidential_debug = true;
}
} else if arg.starts_with(IGVM_VTL2_GPA_POOL_CONFIG) {
if let Some((_, arg)) = arg.split_once('=') {
self.enable_vtl2_gpa_pool = Vtl2GpaPoolConfig::from(arg);
} else {
log!("WARNING: Missing value for IGVM_VTL2_GPA_POOL_CONFIG argument");
}
} else if arg.starts_with(ENABLE_VTL2_GPA_POOL) {
self.enable_vtl2_gpa_pool = arg.split_once('=').and_then(|(_, arg)| {
let num = arg.parse::<u64>().unwrap_or(0);
// A size of 0 or failure to parse is treated as disabling
// the pool.
if num == 0 { None } else { Some(num) }
});
if let Some((_, arg)) = arg.split_once('=') {
override_vtl2_gpa_pool = Some(Vtl2GpaPoolConfig::from(arg));
} else {
log!("WARNING: Missing value for ENABLE_VTL2_GPA_POOL argument");
}
} else if arg.starts_with(SIDECAR) {
if let Some((_, arg)) = arg.split_once('=') {
for arg in arg.split(',') {
Expand All @@ -84,6 +144,14 @@ impl BootCommandLineOptions {
}
}
}

if let Some(override_config) = override_vtl2_gpa_pool {
self.enable_vtl2_gpa_pool = override_config;
log!(
"INFO: Overriding VTL2 GPA pool config to {:?} from command line",
override_config
);
}
}
}

Expand All @@ -99,34 +167,53 @@ mod tests {

#[test]
fn test_vtl2_gpa_pool_parsing() {
assert_eq!(
parse_boot_command_line("OPENHCL_ENABLE_VTL2_GPA_POOL=1"),
BootCommandLineOptions {
enable_vtl2_gpa_pool: Some(1),
..BootCommandLineOptions::new()
}
);
assert_eq!(
parse_boot_command_line("OPENHCL_ENABLE_VTL2_GPA_POOL=0"),
BootCommandLineOptions {
enable_vtl2_gpa_pool: None,
..BootCommandLineOptions::new()
}
);
assert_eq!(
parse_boot_command_line("OPENHCL_ENABLE_VTL2_GPA_POOL=asdf"),
BootCommandLineOptions {
enable_vtl2_gpa_pool: None,
..BootCommandLineOptions::new()
}
);
assert_eq!(
parse_boot_command_line("OPENHCL_ENABLE_VTL2_GPA_POOL=512"),
BootCommandLineOptions {
enable_vtl2_gpa_pool: Some(512),
..BootCommandLineOptions::new()
}
);
for (cmdline, expected) in [
(
// default
"",
Vtl2GpaPoolConfig::Heuristics(Vtl2GpaPoolLookupTable::Release),
),
(
"OPENHCL_IGVM_VTL2_GPA_POOL_CONFIG=1",
Vtl2GpaPoolConfig::Pages(1),
),
(
"OPENHCL_IGVM_VTL2_GPA_POOL_CONFIG=0",
Vtl2GpaPoolConfig::Off,
),
(
"OPENHCL_IGVM_VTL2_GPA_POOL_CONFIG=asdf",
Vtl2GpaPoolConfig::Off,
),
(
"OPENHCL_IGVM_VTL2_GPA_POOL_CONFIG=512",
Vtl2GpaPoolConfig::Pages(512),
),
(
"OPENHCL_IGVM_VTL2_GPA_POOL_CONFIG=off",
Vtl2GpaPoolConfig::Off,
),
(
"OPENHCL_IGVM_VTL2_GPA_POOL_CONFIG=debug",
Vtl2GpaPoolConfig::Heuristics(Vtl2GpaPoolLookupTable::Debug),
),
(
"OPENHCL_IGVM_VTL2_GPA_POOL_CONFIG=release",
Vtl2GpaPoolConfig::Heuristics(Vtl2GpaPoolLookupTable::Release),
),
(
// OPENHCL_ENABLE_VTL2_GPA_POOL= takes precedence over OPENHCL_IGVM_VTL2_GPA_POOL_CONFIG=
"OPENHCL_IGVM_VTL2_GPA_POOL_CONFIG=release OPENHCL_ENABLE_VTL2_GPA_POOL=debug",
Vtl2GpaPoolConfig::Heuristics(Vtl2GpaPoolLookupTable::Debug),
),
] {
assert_eq!(
parse_boot_command_line(cmdline).enable_vtl2_gpa_pool,
expected,
"Failed parsing VTL2 GPA pool config from command line: {}",
cmdline
);
}
}

#[test]
Expand Down
Loading
Loading