Skip to content

Commit fda35d2

Browse files
syntacticallysimongdavies
authored andcommitted
[hyperlight_host/snapshot] Reorganise structures
This moves `mem::shared_mem_snapshot::SharedMemorySNapshot` into `sandbox::snapshot::Snapshot`, because that structure has always contained more than /just/ a snapshot of a shared memory. It also removes the Arc reference counting wrapper from the new structure, and shifts the Arc wrapper into `sandbox::initialized_multi_use::MultiUseSandbox`, which is where it was actually needed. Signed-off-by: Simon Davies <simongdavies@users.noreply.github.com>
1 parent b82cf78 commit fda35d2

File tree

7 files changed

+147
-172
lines changed

7 files changed

+147
-172
lines changed

src/hyperlight_host/benches/benchmarks.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ fn bench_guest_call_with_restore(b: &mut criterion::Bencher, size: SandboxSize)
172172

173173
b.iter(|| {
174174
sbox.call::<String>("Echo", "hello\n".to_string()).unwrap();
175-
sbox.restore(&snapshot).unwrap();
175+
sbox.restore(snapshot.clone()).unwrap();
176176
});
177177
}
178178

@@ -340,7 +340,7 @@ fn bench_snapshot_restore(b: &mut criterion::Bencher, size: SandboxSize) {
340340

341341
// Measure only the restore time
342342
let start = Instant::now();
343-
sbox.restore(&snapshot).unwrap();
343+
sbox.restore(snapshot.clone()).unwrap();
344344
total_duration += start.elapsed();
345345
}
346346

src/hyperlight_host/src/mem/mgr.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ use super::memory_region::{DEFAULT_GUEST_BLOB_MEM_FLAGS, MemoryRegionType};
3333
use super::ptr::{GuestPtr, RawPtr};
3434
use super::ptr_offset::Offset;
3535
use super::shared_mem::{ExclusiveSharedMemory, GuestSharedMemory, HostSharedMemory, SharedMemory};
36-
use super::shared_mem_snapshot::SharedMemorySnapshot;
3736
use crate::sandbox::SandboxConfiguration;
37+
use crate::sandbox::snapshot::Snapshot;
3838
use crate::sandbox::uninitialized::GuestBlob;
3939
use crate::{Result, log_then_return, new_error};
4040

@@ -285,20 +285,20 @@ where
285285
&mut self,
286286
sandbox_id: u64,
287287
mapped_regions: Vec<MemoryRegion>,
288-
) -> Result<SharedMemorySnapshot> {
289-
SharedMemorySnapshot::new(&mut self.shared_mem, sandbox_id, mapped_regions)
288+
) -> Result<Snapshot> {
289+
Snapshot::new(&mut self.shared_mem, sandbox_id, mapped_regions)
290290
}
291291

292292
/// This function restores a memory snapshot from a given snapshot.
293-
pub(crate) fn restore_snapshot(&mut self, snapshot: &SharedMemorySnapshot) -> Result<()> {
293+
pub(crate) fn restore_snapshot(&mut self, snapshot: &Snapshot) -> Result<()> {
294294
if self.shared_mem.mem_size() != snapshot.mem_size() {
295295
return Err(new_error!(
296296
"Snapshot size does not match current memory size: {} != {}",
297297
self.shared_mem.raw_mem_size(),
298298
snapshot.mem_size()
299299
));
300300
}
301-
snapshot.restore_from_snapshot(&mut self.shared_mem)?;
301+
self.shared_mem.restore_from_snapshot(snapshot)?;
302302
Ok(())
303303
}
304304
}

src/hyperlight_host/src/mem/mod.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,6 @@ pub mod ptr_offset;
3535
/// A wrapper around unsafe functionality to create and initialize
3636
/// a memory region for a guest running in a sandbox.
3737
pub mod shared_mem;
38-
/// A wrapper around a `SharedMemory` and a snapshot in time
39-
/// of the memory therein
40-
pub mod shared_mem_snapshot;
4138
/// Utilities for writing shared memory tests
4239
#[cfg(test)]
4340
pub(crate) mod shared_mem_tests;

src/hyperlight_host/src/mem/shared_mem.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ use windows::core::PCSTR;
3939
use crate::HyperlightError::MemoryAllocationFailed;
4040
#[cfg(target_os = "windows")]
4141
use crate::HyperlightError::{MemoryRequestTooBig, WindowsAPIError};
42+
use crate::sandbox::snapshot::Snapshot;
4243
use crate::{Result, log_then_return, new_error};
4344

4445
/// Makes sure that the given `offset` and `size` are within the bounds of the memory with size `mem_size`.
@@ -675,6 +676,12 @@ pub trait SharedMemory {
675676
&mut self,
676677
f: F,
677678
) -> Result<T>;
679+
680+
/// Restore a SharedMemory from a snapshot with matching size
681+
fn restore_from_snapshot(&mut self, snapshot: &Snapshot) -> Result<()> {
682+
assert!(self.mem_size() == snapshot.mem_size());
683+
self.with_exclusivity(|e| e.copy_from_slice(snapshot.memory(), 0))?
684+
}
678685
}
679686

680687
impl SharedMemory for ExclusiveSharedMemory {

src/hyperlight_host/src/mem/shared_mem_snapshot.rs

Lines changed: 0 additions & 139 deletions
This file was deleted.

src/hyperlight_host/src/sandbox/initialized_multi_use.rs

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ pub struct MultiUseSandbox {
104104
dbg_mem_access_fn: Arc<Mutex<SandboxMemoryManager<HostSharedMemory>>>,
105105
/// If the current state of the sandbox has been captured in a snapshot,
106106
/// that snapshot is stored here.
107-
snapshot: Option<Snapshot>,
107+
snapshot: Option<Arc<Snapshot>>,
108108
}
109109

110110
impl MultiUseSandbox {
@@ -163,7 +163,7 @@ impl MultiUseSandbox {
163163
/// # }
164164
/// ```
165165
#[instrument(err(Debug), skip_all, parent = Span::current())]
166-
pub fn snapshot(&mut self) -> Result<Snapshot> {
166+
pub fn snapshot(&mut self) -> Result<Arc<Snapshot>> {
167167
if self.poisoned {
168168
return Err(crate::HyperlightError::PoisonedSandbox);
169169
}
@@ -174,8 +174,7 @@ impl MultiUseSandbox {
174174
let mapped_regions_iter = self.vm.get_mapped_regions();
175175
let mapped_regions_vec: Vec<MemoryRegion> = mapped_regions_iter.cloned().collect();
176176
let memory_snapshot = self.mem_mgr.snapshot(self.id, mapped_regions_vec)?;
177-
let inner = Arc::new(memory_snapshot);
178-
let snapshot = Snapshot { inner };
177+
let snapshot = Arc::new(memory_snapshot);
179178
self.snapshot = Some(snapshot.clone());
180179
Ok(snapshot)
181180
}
@@ -221,7 +220,7 @@ impl MultiUseSandbox {
221220
/// assert_eq!(value, 100);
222221
///
223222
/// // Restore to previous state (same sandbox)
224-
/// sandbox.restore(&snapshot)?;
223+
/// sandbox.restore(snapshot)?;
225224
/// let restored_value: i32 = sandbox.call_guest_function_by_name("GetValue", ())?;
226225
/// assert_eq!(restored_value, 0); // Back to initial state
227226
/// # Ok(())
@@ -257,22 +256,22 @@ impl MultiUseSandbox {
257256
/// # }
258257
/// ```
259258
#[instrument(err(Debug), skip_all, parent = Span::current())]
260-
pub fn restore(&mut self, snapshot: &Snapshot) -> Result<()> {
259+
pub fn restore(&mut self, snapshot: Arc<Snapshot>) -> Result<()> {
261260
if let Some(snap) = &self.snapshot
262-
&& Arc::ptr_eq(&snap.inner, &snapshot.inner)
261+
&& Arc::ptr_eq(&snap, &snapshot)
263262
{
264263
// If the snapshot is already the current one, no need to restore
265264
return Ok(());
266265
}
267266

268-
if self.id != snapshot.inner.sandbox_id() {
267+
if self.id != snapshot.sandbox_id() {
269268
return Err(SnapshotSandboxMismatch);
270269
}
271270

272-
self.mem_mgr.restore_snapshot(&snapshot.inner)?;
271+
self.mem_mgr.restore_snapshot(&snapshot)?;
273272

274273
let current_regions: HashSet<_> = self.vm.get_mapped_regions().cloned().collect();
275-
let snapshot_regions: HashSet<_> = snapshot.inner.regions().iter().cloned().collect();
274+
let snapshot_regions: HashSet<_> = snapshot.regions().iter().cloned().collect();
276275

277276
let regions_to_unmap = current_regions.difference(&snapshot_regions);
278277
let regions_to_map = snapshot_regions.difference(&current_regions);
@@ -356,7 +355,7 @@ impl MultiUseSandbox {
356355
}
357356
let snapshot = self.snapshot()?;
358357
let res = self.call(func_name, args);
359-
self.restore(&snapshot)?;
358+
self.restore(snapshot)?;
360359
res
361360
}
362361

@@ -963,7 +962,7 @@ mod tests {
963962
let res: i32 = sbox.call("GetStatic", ()).unwrap();
964963
assert_eq!(res, 5);
965964

966-
sbox.restore(&snapshot).unwrap();
965+
sbox.restore(snapshot).unwrap();
967966
#[allow(deprecated)]
968967
let _ = sbox
969968
.call_guest_function_by_name::<i32>("AddToStatic", 5i32)
@@ -1027,7 +1026,7 @@ mod tests {
10271026
let res: i32 = sbox.call("GetStatic", ()).unwrap();
10281027
assert_eq!(res, 5);
10291028

1030-
sbox.restore(&snapshot).unwrap();
1029+
sbox.restore(snapshot).unwrap();
10311030
let res: i32 = sbox.call("GetStatic", ()).unwrap();
10321031
assert_eq!(res, 0);
10331032
}
@@ -1244,12 +1243,12 @@ mod tests {
12441243
assert_eq!(sbox.vm.get_mapped_regions().count(), 1);
12451244

12461245
// 4. Restore to snapshot 1 (should unmap the region)
1247-
sbox.restore(&snapshot1).unwrap();
1248-
assert_eq!(sbox.vm.get_mapped_regions().count(), 0);
1246+
sbox.restore(snapshot1).unwrap();
1247+
assert_eq!(sbox.vm.get_mapped_regions().len(), 0);
12491248

12501249
// 5. Restore forward to snapshot 2 (should remap the region)
1251-
sbox.restore(&snapshot2).unwrap();
1252-
assert_eq!(sbox.vm.get_mapped_regions().count(), 1);
1250+
sbox.restore(snapshot2).unwrap();
1251+
assert_eq!(sbox.vm.get_mapped_regions().len(), 1);
12531252

12541253
// Verify the region is the same
12551254
let mut restored_regions = sbox.vm.get_mapped_regions();
@@ -1282,7 +1281,7 @@ mod tests {
12821281
assert_ne!(sandbox.id, sandbox2.id);
12831282

12841283
let snapshot = sandbox.snapshot().unwrap();
1285-
let err = sandbox2.restore(&snapshot);
1284+
let err = sandbox2.restore(snapshot.clone());
12861285
assert!(matches!(err, Err(HyperlightError::SnapshotSandboxMismatch)));
12871286

12881287
let sandbox_id = sandbox.id;

0 commit comments

Comments
 (0)