Skip to content

Commit 2889e61

Browse files
committed
feat: use i686 layout for non-init-paging guests on x86_64
When the init-paging feature is disabled (e.g., 32-bit guests that manage their own paging), select the i686 layout module instead of amd64 on x86_64 hosts. This ensures MAX_GPA/MAX_GVA use 32-bit address space limits, and the scratch region is placed correctly at the top of 4 GiB physical memory. Key changes: - Set MAX_GVA = MAX_GPA (0xffff_ffff) in i686 layout so that identity-mapped guests get correct virtual addresses - Remove SNAPSHOT_PT_GVA_* from i686 layout (no page tables) - Gate SNAPSHOT_PT_GVA_* exports/usage behind init-paging feature - Propagate init-paging feature from hyperlight-host to hyperlight-common via Cargo feature forwarding - Make snapshot region writable for non-init-paging guests (no CoW page tables means the hardware needs direct write access) - Fix min_scratch_size signature to match amd64 layout Signed-off-by: danbugs <danilochiarlone@gmail.com>
1 parent 64aa448 commit 2889e61

5 files changed

Lines changed: 33 additions & 10 deletions

File tree

src/hyperlight_common/src/arch/i686/layout.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,9 @@ limitations under the License.
1717
// This file is just dummy definitions at the moment, in order to
1818
// allow compiling the guest for real mode boot scenarios.
1919

20-
pub const MAX_GVA: usize = 0xffff_efff;
21-
pub const SNAPSHOT_PT_GVA_MIN: usize = 0xef00_0000;
22-
pub const SNAPSHOT_PT_GVA_MAX: usize = 0xefff_efff;
20+
pub const MAX_GVA: usize = 0xffff_ffff;
2321
pub const MAX_GPA: usize = 0xffff_ffff;
2422

25-
pub fn min_scratch_size() -> usize {
26-
1 * crate::vmem::PAGE_SIZE
23+
pub fn min_scratch_size(_input_data_size: usize, _output_data_size: usize) -> usize {
24+
crate::vmem::PAGE_SIZE
2725
}

src/hyperlight_common/src/layout.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,20 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
#[cfg_attr(target_arch = "x86_64", path = "arch/amd64/layout.rs")]
1817
#[cfg_attr(target_arch = "x86", path = "arch/i686/layout.rs")]
18+
#[cfg_attr(
19+
all(target_arch = "x86_64", feature = "init-paging"),
20+
path = "arch/amd64/layout.rs"
21+
)]
22+
#[cfg_attr(
23+
all(target_arch = "x86_64", not(feature = "init-paging")),
24+
path = "arch/i686/layout.rs"
25+
)]
1926
mod arch;
2027

21-
pub use arch::{MAX_GPA, MAX_GVA, SNAPSHOT_PT_GVA_MAX, SNAPSHOT_PT_GVA_MIN};
28+
pub use arch::{MAX_GPA, MAX_GVA};
29+
#[cfg(feature = "init-paging")]
30+
pub use arch::{SNAPSHOT_PT_GVA_MAX, SNAPSHOT_PT_GVA_MIN};
2231

2332
// offsets down from the top of scratch memory for various things
2433
pub const SCRATCH_TOP_SIZE_OFFSET: u64 = 0x08;

src/hyperlight_host/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ tracing = { version = "0.1.44", features = ["log"] }
4040
tracing-log = "0.2.0"
4141
tracing-core = "0.1.36"
4242
tracing-opentelemetry = { version = "0.32.1", optional = true }
43-
hyperlight-common = { workspace = true, default-features = true, features = [ "std", "init-paging" ] }
43+
hyperlight-common = { workspace = true, default-features = true, features = [ "std" ] }
4444
hyperlight-guest-tracing = { workspace = true, default-features = true, optional = true }
4545
vmm-sys-util = "0.15.0"
4646
crossbeam-channel = "0.5.15"
@@ -137,7 +137,7 @@ mshv3 = ["dep:mshv-bindings", "dep:mshv-ioctls"]
137137
gdb = ["dep:gdbstub", "dep:gdbstub_arch"]
138138
fuzzing = ["hyperlight-common/fuzzing"]
139139
build-metadata = ["dep:built"]
140-
init-paging = []
140+
init-paging = ["hyperlight-common/init-paging"]
141141

142142
[[bench]]
143143
name = "benchmarks"

src/hyperlight_host/src/mem/shared_mem.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,22 @@ impl GuestSharedMemory {
679679
MemoryRegionType::Scratch => {
680680
MemoryRegionFlags::READ | MemoryRegionFlags::WRITE | MemoryRegionFlags::EXECUTE
681681
}
682-
MemoryRegionType::Snapshot => MemoryRegionFlags::READ | MemoryRegionFlags::EXECUTE,
682+
// For init-paging, the snapshot is read-only because guest page
683+
// tables provide CoW semantics for writable pages. For
684+
// non-init-paging there are no guest page tables, so the snapshot
685+
// must be writable — otherwise writes (including the CPU setting
686+
// the "Accessed" bit in GDT descriptors during segment loads)
687+
// cause EPT violations that KVM retries forever.
688+
MemoryRegionType::Snapshot => {
689+
#[cfg(feature = "init-paging")]
690+
{
691+
MemoryRegionFlags::READ | MemoryRegionFlags::EXECUTE
692+
}
693+
#[cfg(not(feature = "init-paging"))]
694+
{
695+
MemoryRegionFlags::READ | MemoryRegionFlags::WRITE | MemoryRegionFlags::EXECUTE
696+
}
697+
}
683698
#[allow(clippy::panic)]
684699
// In the future, all the host side knowledge about memory
685700
// region types should collapse down to Snapshot vs

src/hyperlight_host/src/sandbox/snapshot.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ fn filtered_mappings<'a>(
263263
return None;
264264
}
265265
// neither does the mapping of the snapshot's own page tables
266+
#[cfg(feature = "init-paging")]
266267
if mapping.virt_base >= hyperlight_common::layout::SNAPSHOT_PT_GVA_MIN as u64
267268
&& mapping.virt_base <= hyperlight_common::layout::SNAPSHOT_PT_GVA_MAX as u64
268269
{

0 commit comments

Comments
 (0)