feat: use i686 layout for nanvix-unstable guests and make snapshot RWX#1271
feat: use i686 layout for nanvix-unstable guests and make snapshot RWX#1271danbugs wants to merge 1 commit intohyperlight-dev:mainfrom
Conversation
9275564 to
b961eb1
Compare
ef6485a to
4b579d3
Compare
dblnz
left a comment
There was a problem hiding this comment.
LGTM!
However, I am not that well acquainted with this part of the codebase. Maybe @syntactically can take a look
|
I'm not clear on the need for a configurable region base for scratch. You can just set MAX_GPA/MAX_GVA based on target architecture + feature flags? (see src/hyperlight_common/src/arch/i686/layout.rs). Maybe the selection based on target_arch of which layout module to use is broken in the host for the i686 case where it's the guest arch that counts; maybe that needs to change to something like I'm not clear on how the idea of making snapshot pages writable is going to work with the snapshot-first lifecycle (#1268). This seems like it will break a lot of assumptions and make a lot of code more complex/rife with opportunities for vulnerabilities. If you really are unable to run on amd64 natively, would teaching hyperlight about i686 paging structures be a slightly smaller break of the conceptual model? |
This seems like something we could flush out in that discussion? With CoW changes we've broken some downstream consumers, so it makes sense give an escape hatch (maybe behind a feature flag) while we sort through what we want to do. As far as I understand, this isn't a breaking change and doesn't introduce issues now? or does it? To be clear I think we do need to reconcile this requirement and enabling this wouldn't be a long term solution |
ludfjig
left a comment
There was a problem hiding this comment.
does nanvix not use snapshotting? If we can do this without adding a config option, I think that would be good too.
|
Addressed the config option concern. Latest push removes
The Regarding the xsave commit that was on this branch — it's been dropped from the latest push since it's orthogonal to the scratch GPA changes. The writable snapshot commit remains, gated behind Note that Nanvix doesn't use Hyperlight's snapshotting mechanism. Instead, it has a kernel call that, being guest-aware, can VMExit at any time to snapshot. Nanvix does this because it doesn't execute like our purpose-built guest binaries (e.g., it doesn't use guest function calls). Instead, it just calls |
9546967 to
3b4760d
Compare
3b4760d to
8002243
Compare
When nanvix-unstable is enabled, select the i686 layout module on x86_64 hosts. This ensures MAX_GPA/MAX_GVA use 32-bit address space limits and the scratch region is placed at the top of 4 GiB. Also makes the snapshot region RWX for nanvix-unstable guests since they have no CoW page tables and need direct write access. Key changes: - Propagate nanvix-unstable from hyperlight-host to hyperlight-common - Use i686 layout when nanvix-unstable is enabled on x86_64 - Gate SNAPSHOT_PT_GVA_* exports behind not(nanvix-unstable) and target_arch = "x86_64" (i686 layout never defines these symbols) - Make snapshot writable for nanvix-unstable (no CoW means hardware needs direct write access) Signed-off-by: danbugs <danilochiarlone@gmail.com>
8002243 to
7bb7ab7
Compare
Summary
When
nanvix-unstableis enabled, selects the i686 hyperlight-common memory layout on x86_64 hosts and makes the snapshot memory region writable. Also propagates thenanvix-unstablefeature fromhyperlight-hosttohyperlight-commonso both crates share the same cfg gates.Motivation
Nanvix runs as a 32-bit (i386) guest without CoW guest paging. Two things need to change for this to work:
i686 layout: The amd64 layout defines
MAX_GPA/MAX_GVAfor a 36-bit/48-bit address space and includesSNAPSHOT_PT_GVA_*constants for the CoW page table region. A 32-bit guest needs 32-bit address limits (0xFFFF_FFFF) and has no snapshot page tables. Withnanvix-unstable, the i686 layout module is used even on x86_64 hosts.Snapshot RWX: Without CoW, the guest writes directly to snapshot pages —
.data,.bss, kernel page pool, and even GDT descriptors (the CPU sets the "Accessed" bit during segment loads). If the snapshot isn't writable, these writes cause EPT violations that KVM retries forever.Changes
hyperlight_host/Cargo.toml:nanvix-unstable = ["hyperlight-common/nanvix-unstable"]— propagates the featurehyperlight_common/src/layout.rs: Three-waycfg_attrselects i686 layout for native x86 OR x86_64 withnanvix-unstable; gatesSNAPSHOT_PT_GVA_*exports behindall(target_arch = "x86_64", not(nanvix-unstable))hyperlight_common/src/arch/i686/layout.rs: Removes staleSNAPSHOT_PT_GVA_*constants and fixesMAX_GVAto0xFFFF_FFFF; updatesmin_scratch_sizesignature to match the amd64 layouthyperlight_host/src/mem/shared_mem.rs: Snapshot region isREAD | EXECUTEby default (CoW handles writes),READ | WRITE | EXECUTEwithnanvix-unstablehyperlight_host/src/sandbox/snapshot.rs: Gates the snapshot page-table GVA filter behindnot(nanvix-unstable)