feat(whp): copy-on-write file mapping for snapshot load#1391
feat(whp): copy-on-write file mapping for snapshot load#1391danbugs wants to merge 5 commits intohyperlight-dev:mainfrom
Conversation
Signed-off-by: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com>
Signed-off-by: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com>
Save snapshots to disk via Snapshot::to_file(), load them back via Snapshot::from_file(). Create sandboxes directly from loaded snapshots via MultiUseSandbox::from_snapshot(), bypassing ELF parsing and guest init. Signed-off-by: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com>
from_snapshot() was constructing a fresh MultiUseSandbox via from_uninit(), which assigns a new monotonically-increasing sandbox id. The loaded snapshot still carries the id of the sandbox it was originally captured from, so the very first restore() call after from_snapshot trips SnapshotSandboxMismatch and aborts before any guest code runs. Conceptually the snapshot IS this sandbox's identity when loaded from disk — the sandbox it was captured from no longer exists. Inherit the snapshot's sandbox_id and register the loaded snapshot as this sandbox's active snapshot so subsequent restores match. Signed-off-by: danbugs <danilochiarlone@gmail.com>
The Windows path in ReadonlySharedMemory::from_file_windows was
created with PAGE_READONLY + FILE_MAP_READ. That matches the name
('ReadonlySharedMemory') but not the semantics the caller needs: a
sandbox loaded from a snapshot still has to be a writable view of
the guest's memory from the host's perspective, so WHP/MSHV can
service copy-on-write faults the guest takes on first write.
A read-only mapping triggers an access violation on the host thread
the moment the guest touches any page, before the VMM can vector
the fault into the in-kernel CoW path.
Switch to PAGE_WRITECOPY + FILE_MAP_COPY — the Windows equivalent
of Linux's mmap(MAP_PRIVATE) that Linux's from_file path already
uses. Reads still come from the backing file; writes transparently
allocate private copy-on-write pages.
Follow-up to hyperlight-dev#1373; depends on that PR
landing first.
Signed-off-by: danbugs <danilochiarlone@gmail.com>
b380323 to
daa1f7d
Compare
I didn't actually review any of the code in this PR yet, but I want to ask for some clarification from this line in the description. With FILE_MAP_COPY, the CoW will happen for the whole process when the host/guest writes into a page in the region, but that would mean the modification would be visible across all the sandboxes using the same The reason for the |
Summary
Stacked follow-up to #1373. The Windows path in
ReadonlySharedMemory::from_file_windowsis currently created withPAGE_READONLY+FILE_MAP_READ. That matches the type name (ReadonlySharedMemory) but not the semantics thefrom_snapshotcaller needs: the host-side view has to be writable so WHP (and MSHV) can service the copy-on-write faults the guest takes on first write. A read-only mapping triggers an access violation on the host thread the moment the guest touches any page.Switch to
PAGE_WRITECOPY+FILE_MAP_COPY— the Windows equivalent of Linux'smmap(MAP_PRIVATE)that the Linuxfrom_filepath already uses. Reads still come from the backing file; writes transparently allocate private copy-on-write pages.Relationship to #1373
disk_snapshot's tip, so the diff here will reduce to just the CoW change once Persist snapshot to disk #1373 is merged.shared_mem.rsdelta.Tested
On a Windows box with WHP enabled:
Snapshot::to_filethenMultiUseSandbox::from_snapshot→restore→callcompletes cleanly. Pre-fix, the same flow took an access violation on the first page fault the guest triggered after restore.Known follow-ups (not in this PR)
None for this change specifically. Separate PR will add
Registerable for MultiUseSandboxso host functions can be wired on sandboxes acquired viafrom_snapshot.