Skip to content

Commit e0ce7df

Browse files
committed
save restore inmemory nvram
1 parent 20df503 commit e0ce7df

File tree

18 files changed

+249
-84
lines changed

18 files changed

+249
-84
lines changed

Cargo.lock

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2788,13 +2788,15 @@ dependencies = [
27882788
"cvm_tracing",
27892789
"guid",
27902790
"inspect",
2791+
"mesh_protobuf",
27912792
"open_enum",
27922793
"pal_async",
27932794
"static_assertions",
27942795
"thiserror 2.0.12",
27952796
"tracing",
27962797
"ucs2 0.0.0",
27972798
"uefi_nvram_storage",
2799+
"vmcore",
27982800
"wchar",
27992801
"zerocopy 0.8.24",
28002802
]
@@ -7297,10 +7299,12 @@ dependencies = [
72977299
"async-trait",
72987300
"guid",
72997301
"inspect",
7302+
"mesh_protobuf",
73007303
"pal_async",
73017304
"thiserror 2.0.12",
73027305
"ucs2 0.0.0",
73037306
"uefi_specs",
7307+
"vmcore",
73047308
"wchar",
73057309
"zerocopy 0.8.24",
73067310
]

openhcl/underhill_core/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ hyperv_ic_resources.workspace = true
5656
hyperv_secure_boot_templates.workspace = true
5757
hyperv_uefi_custom_vars_json.workspace = true
5858
framebuffer.workspace = true
59-
hcl_compat_uefi_nvram_storage = { workspace = true, features = ["inspect"] }
59+
hcl_compat_uefi_nvram_storage = { workspace = true, features = ["inspect", "save_restore"] }
6060
get_helpers.workspace = true
6161
get_protocol.workspace = true
6262
guest_emulation_transport.workspace = true

openhcl/underhill_core/src/worker.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2056,16 +2056,20 @@ async fn new_underhill_vm(
20562056
logger: Box::new(UnderhillLogger {
20572057
get: get_client.clone(),
20582058
}),
2059-
nvram_storage: Box::new(HclCompatNvram::new(
2060-
VmgsStorageBackendAdapter(
2061-
vmgs_client
2062-
.as_non_volatile_store(vmgs::FileId::BIOS_NVRAM, true)
2063-
.context("failed to instantiate UEFI NVRAM store")?,
2064-
),
2065-
Some(HclCompatNvramQuirks {
2066-
skip_corrupt_vars_with_missing_null_term: true,
2067-
}),
2068-
)),
2059+
nvram_storage: Box::new(
2060+
HclCompatNvram::new(
2061+
VmgsStorageBackendAdapter(
2062+
vmgs_client
2063+
.as_non_volatile_store(vmgs::FileId::BIOS_NVRAM, true)
2064+
.context("failed to instantiate UEFI NVRAM store")?,
2065+
),
2066+
Some(HclCompatNvramQuirks {
2067+
skip_corrupt_vars_with_missing_null_term: true,
2068+
}),
2069+
is_restoring,
2070+
)
2071+
.await?,
2072+
),
20692073
generation_id_recv: get_client
20702074
.take_generation_id_recv()
20712075
.await

openvmm/hvlite_core/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,10 @@ disk_backend.workspace = true
5252
firmware_pcat.workspace = true
5353
firmware_uefi_custom_vars.workspace = true
5454
firmware_uefi.workspace = true
55-
uefi_nvram_storage.workspace = true
55+
uefi_nvram_storage = { workspace = true, features = ["save_restore"] }
5656
framebuffer.workspace = true
5757
get_resources.workspace = true
58-
hcl_compat_uefi_nvram_storage = { workspace = true, features = ["inspect"] }
58+
hcl_compat_uefi_nvram_storage = { workspace = true, features = ["inspect", "save_restore"] }
5959
ide.workspace = true
6060
floppy.workspace = true
6161
input_core.workspace = true

openvmm/hvlite_core/src/worker/dispatch.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,13 +1067,17 @@ impl InitializedVm {
10671067
use vmm_core::emuplat::hcl_compat_uefi_nvram_storage::VmgsStorageBackendAdapter;
10681068

10691069
match vmgs_client {
1070-
Some(vmgs) => Box::new(HclCompatNvram::new(
1071-
VmgsStorageBackendAdapter(
1072-
vmgs.as_non_volatile_store(vmgs::FileId::BIOS_NVRAM, true)
1073-
.context("failed to instantiate UEFI NVRAM store")?,
1074-
),
1075-
None,
1076-
)),
1070+
Some(vmgs) => Box::new(
1071+
HclCompatNvram::new(
1072+
VmgsStorageBackendAdapter(
1073+
vmgs.as_non_volatile_store(vmgs::FileId::BIOS_NVRAM, true)
1074+
.context("failed to instantiate UEFI NVRAM store")?,
1075+
),
1076+
None,
1077+
false,
1078+
)
1079+
.await?,
1080+
),
10771081
None => Box::new(InMemoryNvram::new()),
10781082
}
10791083
},

vm/devices/firmware/firmware_uefi/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ fuzzing = []
2222

2323
[dependencies]
2424
firmware_uefi_custom_vars.workspace = true
25-
uefi_nvram_storage = { workspace = true, features = ["inspect"] }
25+
uefi_nvram_storage = { workspace = true, features = ["inspect", "save_restore"] }
2626
uefi_specs.workspace = true
2727
uefi_nvram_specvars.workspace = true
2828
generation_id.workspace = true

vm/devices/firmware/firmware_uefi/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ use std::convert::TryInto;
7474
use std::ops::RangeInclusive;
7575
use std::task::Context;
7676
use thiserror::Error;
77-
use uefi_nvram_storage::InspectableNvramStorage;
77+
use uefi_nvram_storage::VmmNvramStorage;
7878
use vmcore::device_state::ChangeDeviceState;
7979
use vmcore::vmtime::VmTimeSource;
8080
use watchdog_core::platform::WatchdogPlatform;
@@ -129,7 +129,7 @@ pub struct UefiConfig {
129129
/// Various runtime objects used by the UEFI device + underlying services.
130130
pub struct UefiRuntimeDeps<'a> {
131131
pub gm: GuestMemory,
132-
pub nvram_storage: Box<dyn InspectableNvramStorage>,
132+
pub nvram_storage: Box<dyn VmmNvramStorage>,
133133
pub logger: Box<dyn UefiLogger>,
134134
pub vmtime: &'a VmTimeSource,
135135
pub watchdog_platform: Box<dyn WatchdogPlatform>,

vm/devices/firmware/firmware_uefi/src/service/nvram/mod.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use inspect::Inspect;
2424
use std::borrow::Cow;
2525
use std::fmt::Debug;
2626
use thiserror::Error;
27-
use uefi_nvram_storage::InspectableNvramStorage;
27+
use uefi_nvram_storage::VmmNvramStorage;
2828
use uefi_specs::uefi::common::EfiStatus;
2929
use uefi_specs::uefi::nvram::EfiVariableAttributes;
3030
use zerocopy::IntoBytes;
@@ -67,12 +67,12 @@ pub struct NvramServices {
6767

6868
// Sub-emulators
6969
#[inspect(flatten)]
70-
services: NvramSpecServices<Box<dyn InspectableNvramStorage>>,
70+
services: NvramSpecServices<Box<dyn VmmNvramStorage>>,
7171
}
7272

7373
impl NvramServices {
7474
pub async fn new(
75-
nvram_storage: Box<dyn InspectableNvramStorage>,
75+
nvram_storage: Box<dyn VmmNvramStorage>,
7676
custom_vars: CustomVars,
7777
secure_boot_enabled: bool,
7878
vsm_config: Option<Box<dyn VsmConfig>>,
@@ -622,15 +622,14 @@ mod save_restore {
622622
mod state {
623623
use crate::service::nvram::NvramSpecServices;
624624
use mesh::payload::Protobuf;
625-
use uefi_nvram_storage::InspectableNvramStorage;
625+
use uefi_nvram_storage::VmmNvramStorage;
626626
use vmcore::save_restore::SaveRestore;
627627

628628
#[derive(Protobuf)]
629629
#[mesh(package = "firmware.uefi.nvram")]
630630
pub struct SavedState {
631631
#[mesh(1)]
632-
pub services:
633-
<NvramSpecServices<Box<dyn InspectableNvramStorage>> as SaveRestore>::SavedState,
632+
pub services: <NvramSpecServices<Box<dyn VmmNvramStorage>> as SaveRestore>::SavedState,
634633
}
635634
}
636635

vm/devices/firmware/firmware_uefi/src/service/nvram/spec_services/mod.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ use ucs2::Ucs2LeSlice;
2323
use ucs2::Ucs2ParseError;
2424
use uefi_nvram_specvars::signature_list;
2525
use uefi_nvram_specvars::signature_list::ParseSignatureLists;
26-
use uefi_nvram_storage::InspectableNvramStorage;
2726
use uefi_nvram_storage::NextVariable;
2827
use uefi_nvram_storage::NvramStorageError;
28+
use uefi_nvram_storage::VmmNvramStorage;
2929
use uefi_specs::uefi::common::EfiStatus;
3030
use uefi_specs::uefi::nvram::EfiVariableAttributes;
3131
use uefi_specs::uefi::time::EFI_TIME;
@@ -224,12 +224,12 @@ impl RuntimeState {
224224
/// `NvramError` type provides additional context as to what error occurred in
225225
/// OpenVMM (i.e: for logging purposes).
226226
#[derive(Debug, Inspect)]
227-
pub struct NvramSpecServices<S: InspectableNvramStorage> {
227+
pub struct NvramSpecServices<S: VmmNvramStorage> {
228228
storage: S,
229229
runtime_state: RuntimeState,
230230
}
231231

232-
impl<S: InspectableNvramStorage> NvramSpecServices<S> {
232+
impl<S: VmmNvramStorage> NvramSpecServices<S> {
233233
/// Construct a new NvramServices instance from an existing storage backend.
234234
pub fn new(storage: S) -> NvramSpecServices<S> {
235235
NvramSpecServices {
@@ -1453,6 +1453,7 @@ mod save_restore {
14531453

14541454
mod state {
14551455
use mesh::payload::Protobuf;
1456+
use vmcore::save_restore::SavedStateBlob;
14561457

14571458
#[derive(Protobuf)]
14581459
#[mesh(package = "firmware.uefi.nvram.spec")]
@@ -1470,10 +1471,12 @@ mod save_restore {
14701471
pub struct SavedState {
14711472
#[mesh(1)]
14721473
pub runtime_state: SavedRuntimeState,
1474+
#[mesh(2)]
1475+
pub storage: SavedStateBlob,
14731476
}
14741477
}
14751478

1476-
impl<S: InspectableNvramStorage> SaveRestore for NvramSpecServices<S> {
1479+
impl<S: VmmNvramStorage> SaveRestore for NvramSpecServices<S> {
14771480
type SavedState = state::SavedState;
14781481

14791482
fn save(&mut self) -> Result<Self::SavedState, SaveError> {
@@ -1483,17 +1486,22 @@ mod save_restore {
14831486
RuntimeState::Boot => state::SavedRuntimeState::Boot,
14841487
RuntimeState::Runtime => state::SavedRuntimeState::Runtime,
14851488
},
1489+
storage: self.storage.save()?,
14861490
})
14871491
}
14881492

14891493
fn restore(&mut self, state: Self::SavedState) -> Result<(), RestoreError> {
1490-
let state::SavedState { runtime_state } = state;
1494+
let state::SavedState {
1495+
runtime_state,
1496+
storage,
1497+
} = state;
14911498

14921499
self.runtime_state = match runtime_state {
14931500
state::SavedRuntimeState::PreBoot => RuntimeState::PreBoot,
14941501
state::SavedRuntimeState::Boot => RuntimeState::Boot,
14951502
state::SavedRuntimeState::Runtime => RuntimeState::Runtime,
14961503
};
1504+
self.storage.restore(storage)?;
14971505

14981506
Ok(())
14991507
}
@@ -1526,7 +1534,7 @@ mod test {
15261534
}
15271535

15281536
#[async_trait::async_trait]
1529-
impl<S: InspectableNvramStorage> NvramServicesTestExt for NvramSpecServices<S> {
1537+
impl<S: VmmNvramStorage> NvramServicesTestExt for NvramSpecServices<S> {
15301538
async fn set_test_var(&mut self, name: &[u8], attr: u32, data: &[u8]) -> NvramResult<()> {
15311539
let vendor = Guid::default();
15321540

vm/devices/firmware/firmware_uefi/src/service/nvram/spec_services/nvram_services_ext.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use super::NvramResult;
66
use super::NvramSpecServices;
77
use guid::Guid;
88
use ucs2::Ucs2LeSlice;
9-
use uefi_nvram_storage::InspectableNvramStorage;
9+
use uefi_nvram_storage::VmmNvramStorage;
1010
use uefi_specs::uefi::common::EfiStatus;
1111

1212
/// Extension trait around `NvramServices` that makes it easier to use the API
@@ -56,7 +56,7 @@ pub trait NvramServicesExt {
5656
}
5757

5858
#[async_trait::async_trait]
59-
impl<S: InspectableNvramStorage> NvramServicesExt for NvramSpecServices<S> {
59+
impl<S: VmmNvramStorage> NvramServicesExt for NvramSpecServices<S> {
6060
async fn get_variable(
6161
&mut self,
6262
vendor: Guid,

0 commit comments

Comments
 (0)