Skip to content

Commit 83bccbf

Browse files
authored
petri: allow test to override default VTL2 allocation scheme (#2224)
Promote the settings that change how VTL2 memory is allocated to the Petri VM objects, rather than being hidden in the depths of the OpenVMM config. This is a convenience for additional tests coming as part of #2215 .
1 parent 9a4e9aa commit 83bccbf

File tree

5 files changed

+64
-37
lines changed

5 files changed

+64
-37
lines changed

petri/src/vm/hyperv/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,9 +467,14 @@ impl PetriVmmBackend for HyperVPetriBackend {
467467
vmbus_redirect,
468468
command_line: _,
469469
log_levels: _,
470+
vtl2_base_address_type,
470471
},
471472
)) = &openhcl_config
472473
{
474+
if vtl2_base_address_type.is_some() {
475+
todo!("custom VTL2 base address type not yet supported for Hyper-V")
476+
}
477+
473478
// Copy the IGVM file locally, since it may not be accessible by
474479
// Hyper-V (e.g., if it is in a WSL filesystem).
475480
let igvm_file = temp_dir.path().join("igvm.bin");

petri/src/vm/mod.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use crate::disk_image::AgentImage;
1515
use crate::openhcl_diag::OpenHclDiagHandler;
1616
use async_trait::async_trait;
1717
use get_resources::ged::FirmwareEvent;
18+
use hvlite_defs::config::Vtl2BaseAddressType;
1819
use mesh::CancelContext;
1920
use pal_async::DefaultDriver;
2021
use pal_async::task::Spawn;
@@ -477,6 +478,19 @@ impl<T: PetriVmmBackend> PetriVmBuilder<T> {
477478
self
478479
}
479480

481+
/// Sets a custom OpenHCL IGVM VTL2 address type. This controls the behavior
482+
/// of where VTL2 is placed in address space, and also the total size of memory
483+
/// allocated for VTL2. VTL2 start will fail if `address_type` is specified
484+
/// and leads to the loader allocating less memory than what is in the IGVM file.
485+
pub fn with_vtl2_base_address_type(mut self, address_type: Vtl2BaseAddressType) -> Self {
486+
self.config
487+
.firmware
488+
.openhcl_config_mut()
489+
.expect("OpenHCL firmware is required to set custom VTL2 address type.")
490+
.vtl2_base_address_type = Some(address_type);
491+
self
492+
}
493+
480494
/// Sets a custom OpenHCL IGVM file to use.
481495
pub fn with_custom_openhcl(mut self, artifact: ResolvedArtifact<impl IsOpenhclIgvm>) -> Self {
482496
match &mut self.config.firmware {
@@ -1193,6 +1207,9 @@ pub struct OpenHclConfig {
11931207
/// from `command_line` so that petri can decide to use default log
11941208
/// levels.
11951209
pub log_levels: OpenHclLogConfig,
1210+
/// How to place VTL2 in address space. If `None`, the backend VMM
1211+
/// will decide on default behavior.
1212+
pub vtl2_base_address_type: Option<Vtl2BaseAddressType>,
11961213
}
11971214

11981215
impl OpenHclConfig {
@@ -1239,6 +1256,7 @@ impl Default for OpenHclConfig {
12391256
vmbus_redirect: false,
12401257
command_line: None,
12411258
log_levels: OpenHclLogConfig::TestDefault,
1259+
vtl2_base_address_type: None,
12421260
}
12431261
}
12441262
}

petri/src/vm/openvmm/construct.rs

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -184,11 +184,23 @@ impl PetriVmConfigOpenVmm {
184184
framebuffer.is_some(),
185185
tpm_state_persistence,
186186
)?;
187+
188+
let late_map_vtl0_memory = match load_mode {
189+
LoadMode::Igvm {
190+
vtl2_base_address: Vtl2BaseAddressType::Vtl2Allocate { .. },
191+
..
192+
} => {
193+
// Late Map VTL0 memory not supported when test supplies Vtl2Allocate
194+
None
195+
}
196+
_ => Some(LateMapVtl0MemoryPolicy::InjectException),
197+
};
198+
187199
let (vtl2_vsock_listener, vtl2_vsock_path) = make_vsock_listener()?;
188200
(
189201
Some(Vtl2Config {
190202
vtl0_alias_map: false, // TODO: enable when OpenVMM supports it for DMA
191-
late_map_vtl0_memory: Some(LateMapVtl0MemoryPolicy::InjectException),
203+
late_map_vtl0_memory,
192204
}),
193205
Some(VmbusConfig {
194206
vsock_listener: Some(vtl2_vsock_listener),
@@ -686,6 +698,7 @@ impl PetriVmConfigSetupCore<'_> {
686698
vmbus_redirect: _, // config_openhcl_vmbus_devices
687699
command_line: _,
688700
log_levels: _,
701+
vtl2_base_address_type,
689702
} = openhcl_config;
690703

691704
let mut cmdline = Some(openhcl_config.command_line());
@@ -706,23 +719,28 @@ impl PetriVmConfigSetupCore<'_> {
706719
Firmware::OpenhclUefi { isolation, .. } if isolation.is_some() => true,
707720
_ => false,
708721
};
709-
let file = File::open(igvm_path.clone())
710-
.context("failed to open openhcl firmware file")?
711-
.into();
712-
LoadMode::Igvm {
713-
file,
714-
cmdline: cmdline.unwrap_or_default(),
715-
vtl2_base_address: if isolated {
722+
723+
let vtl2_base_address = vtl2_base_address_type.unwrap_or_else(|| {
724+
if isolated {
716725
// Isolated VMs must load at the location specified by
717726
// the file, as they do not support relocation.
718727
Vtl2BaseAddressType::File
719728
} else {
720-
// By default, utilize IGVM relocation and tell hvlite
729+
// By default, utilize IGVM relocation and tell OpenVMM
721730
// to place VTL2 at 2GB. This tests both relocation
722-
// support in hvlite, and relocation support within
723-
// underhill.
731+
// support in OpenVMM, and relocation support within
732+
// OpenHCL.
724733
Vtl2BaseAddressType::Absolute(2 * SIZE_1_GB)
725-
},
734+
}
735+
});
736+
737+
let file = File::open(igvm_path.clone())
738+
.context("failed to open openhcl firmware file")?
739+
.into();
740+
LoadMode::Igvm {
741+
file,
742+
cmdline: cmdline.unwrap_or_default(),
743+
vtl2_base_address,
726744
com_serial: Some(SerialInformation {
727745
io_port: ComPort::Com3.io_port(),
728746
irq: ComPort::Com3.irq().into(),

vmm_tests/vmm_tests/tests/tests/x86_64/openhcl_linux_direct.rs

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use crate::x86_64::storage::new_test_vtl2_nvme_device;
77
use guid::Guid;
88
use hvlite_defs::config::Vtl2BaseAddressType;
9+
use petri::MemoryConfig;
910
use petri::OpenHclServicingFlags;
1011
use petri::PetriVmBuilder;
1112
use petri::ResolvedArtifact;
@@ -206,30 +207,12 @@ async fn openhcl_linux_vtl2_ram_self_allocate(
206207
let vtl2_ram_size = 1024 * 1024 * 1024; // 1GB
207208
let vm_ram_size = 6 * 1024 * 1024 * 1024; // 6GB
208209
let (mut vm, agent) = config
209-
.modify_backend(move |b| {
210-
b.with_custom_config(|cfg| {
211-
if let hvlite_defs::config::LoadMode::Igvm {
212-
ref mut vtl2_base_address,
213-
..
214-
} = cfg.load_mode
215-
{
216-
*vtl2_base_address = Vtl2BaseAddressType::Vtl2Allocate {
217-
size: Some(vtl2_ram_size),
218-
}
219-
} else {
220-
panic!("unexpected load mode, must be igvm");
221-
}
222-
223-
// Disable late map vtl0 memory when vtl2 allocation mode is used.
224-
cfg.hypervisor
225-
.with_vtl2
226-
.as_mut()
227-
.unwrap()
228-
.late_map_vtl0_memory = None;
229-
230-
// Set overall VM ram.
231-
cfg.memory.mem_size = vm_ram_size;
232-
})
210+
.with_memory(MemoryConfig {
211+
startup_bytes: vm_ram_size,
212+
..Default::default()
213+
})
214+
.with_vtl2_base_address_type(Vtl2BaseAddressType::Vtl2Allocate {
215+
size: Some(vtl2_ram_size),
233216
})
234217
.run()
235218
.await?;

vmm_tests/vmm_tests/tests/tests/x86_64/openhcl_uefi.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,12 @@ async fn nvme_relay_test_core(
3838
.with_openhcl_command_line(openhcl_cmdline)
3939
.with_vmbus_redirect(true)
4040
.with_processor_topology(ProcessorTopology {
41-
vp_count: 1,
41+
vp_count: 4, // Ideally, with 16GB RAM to match D4v5
4242
..Default::default()
4343
})
44+
.with_vtl2_base_address_type(hvlite_defs::config::Vtl2BaseAddressType::Vtl2Allocate {
45+
size: Some(512 * 1024 * 1024), // 512MB to be more than what is defined in the dev manifest json
46+
})
4447
.run()
4548
.await?;
4649

0 commit comments

Comments
 (0)