Skip to content

Commit 0d4f86a

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 9f25a1b commit 0d4f86a

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
@@ -447,6 +447,8 @@ impl Snapshot {
447447
sregs: CommonSpecialRegisters,
448448
entrypoint: NextAction,
449449
) -> Result<Self> {
450+
use std::collections::HashMap;
451+
let mut phys_seen = HashMap::<u64, usize>::new();
450452
let memory = shared_mem.with_contents(|snap_c| {
451453
scratch_mem.with_contents(|scratch_c| {
452454
// Pass 1: count how many pages need to live
@@ -458,9 +460,6 @@ impl Snapshot {
458460
let pt_buf = GuestPageTableBuffer::new(layout.get_pt_base_gpa() as usize);
459461
let mut snapshot_memory: Vec<u8> = Vec::new();
460462
for (mapping, contents) in live_pages {
461-
let new_offset = snapshot_memory.len();
462-
snapshot_memory.extend(contents);
463-
let new_gpa = new_offset + SandboxMemoryLayout::BASE_ADDRESS;
464463
let kind = match mapping.kind {
465464
MappingKind::Cow(cm) => MappingKind::Cow(cm),
466465
MappingKind::Basic(bm) if bm.writable => MappingKind::Cow(CowMapping {
@@ -473,8 +472,13 @@ impl Snapshot {
473472
executable: bm.executable,
474473
}),
475474
};
475+
let new_gpa = phys_seen.entry(mapping.phys_base).or_insert_with(|| {
476+
let new_offset = snapshot_memory.len();
477+
snapshot_memory.extend(contents);
478+
new_offset + SandboxMemoryLayout::BASE_ADDRESS
479+
});
476480
let mapping = Mapping {
477-
phys_base: new_gpa as u64,
481+
phys_base: *new_gpa as u64,
478482
virt_base: mapping.virt_base,
479483
len: PAGE_SIZE as u64,
480484
kind,

0 commit comments

Comments
 (0)