Skip to content

Commit ab8f7a4

Browse files
committed
snapshot: avoid duplicating pages mapped multiple times
Previously, if a sandbox mapped one physical page to multiple virtual addresses, taking a snapshot would duplicate the page. This commit changes the logic around snapshots to keep track of the physical pages that have been encountered during the virtual memory traversal so far, and ensure that the same page is not copied multiple times. Note that this does not (yet) track the contents of pages to allow de-duplicating them---it merely ensures that two mappings of the same physical address do not result in needless duplication. Signed-off-by: Lucy Menon <168595099+syntactically@users.noreply.github.com>
1 parent 5d45136 commit ab8f7a4

File tree

1 file changed

+8
-4
lines changed

1 file changed

+8
-4
lines changed

src/hyperlight_host/src/sandbox/snapshot.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,8 @@ impl Snapshot {
444444
sregs: CommonSpecialRegisters,
445445
entrypoint: NextAction,
446446
) -> Result<Self> {
447+
use std::collections::HashMap;
448+
let mut phys_seen = HashMap::<u64, usize>::new();
447449
let memory = shared_mem.with_contents(|snap_c| {
448450
scratch_mem.with_contents(|scratch_c| {
449451
// Pass 1: count how many pages need to live
@@ -455,9 +457,6 @@ impl Snapshot {
455457
let pt_buf = GuestPageTableBuffer::new(layout.get_pt_base_gpa() as usize);
456458
let mut snapshot_memory: Vec<u8> = Vec::new();
457459
for (mapping, contents) in live_pages {
458-
let new_offset = snapshot_memory.len();
459-
snapshot_memory.extend(contents);
460-
let new_gpa = new_offset + SandboxMemoryLayout::BASE_ADDRESS;
461460
let kind = match mapping.kind {
462461
MappingKind::Cow(cm) => MappingKind::Cow(cm),
463462
MappingKind::Basic(bm) if bm.writable => MappingKind::Cow(CowMapping {
@@ -470,8 +469,13 @@ impl Snapshot {
470469
executable: bm.executable,
471470
}),
472471
};
472+
let new_gpa = phys_seen.entry(mapping.phys_base).or_insert_with(|| {
473+
let new_offset = snapshot_memory.len();
474+
snapshot_memory.extend(contents);
475+
new_offset + SandboxMemoryLayout::BASE_ADDRESS
476+
});
473477
let mapping = Mapping {
474-
phys_base: new_gpa as u64,
478+
phys_base: *new_gpa as u64,
475479
virt_base: mapping.virt_base,
476480
len: PAGE_SIZE as u64,
477481
kind,

0 commit comments

Comments
 (0)