diff --git a/Justfile b/Justfile index 59c095c52..66b06a587 100644 --- a/Justfile +++ b/Justfile @@ -75,8 +75,8 @@ test-like-ci config=default-target hypervisor="kvm": @# with default features just test {{config}} {{ if hypervisor == "mshv3" {"mshv3"} else {""} }} - @# with only one driver enabled + seccomp - just test {{config}} seccomp,build-metadata,{{ if hypervisor == "mshv" {"mshv2"} else if hypervisor == "mshv3" {"mshv3"} else {"kvm"} }} + @# with only one driver enabled + seccomp + build-metadata + init-paging + just test {{config}} seccomp,build-metadata,init-paging,{{ if hypervisor == "mshv" {"mshv2"} else if hypervisor == "mshv3" {"mshv3"} else {"kvm"} }} @# make sure certain cargo features compile cargo check -p hyperlight-host --features crashdump @@ -94,18 +94,18 @@ test target=default-target features="": (test-unit target features) (test-isolat # runs unit tests test-unit target=default-target features="": - cargo test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F " + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} --lib + cargo test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F init-paging," + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} --lib # runs tests that requires being run separately, for example due to global state test-isolated target=default-target features="": - cargo test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F " + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} -p hyperlight-host --lib -- sandbox::uninitialized::tests::test_trace_trace --exact --ignored - cargo test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F " + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} -p hyperlight-host --lib -- sandbox::uninitialized::tests::test_log_trace --exact --ignored - cargo test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F " + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} -p hyperlight-host --lib -- sandbox::initialized_multi_use::tests::create_1000_sandboxes --exact --ignored - cargo test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F " + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} -p hyperlight-host --lib -- sandbox::outb::tests::test_log_outb_log --exact --ignored - cargo test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F " + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} -p hyperlight-host --lib -- mem::shared_mem::tests::test_drop --exact --ignored - cargo test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F " + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} -p hyperlight-host --test integration_test -- log_message --exact --ignored + cargo test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F init-paging," + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} -p hyperlight-host --lib -- sandbox::uninitialized::tests::test_trace_trace --exact --ignored + cargo test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F init-paging," + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} -p hyperlight-host --lib -- sandbox::uninitialized::tests::test_log_trace --exact --ignored + cargo test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F init-paging," + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} -p hyperlight-host --lib -- sandbox::initialized_multi_use::tests::create_1000_sandboxes --exact --ignored + cargo test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F init-paging," + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} -p hyperlight-host --lib -- sandbox::outb::tests::test_log_outb_log --exact --ignored + cargo test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F init-paging," + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} -p hyperlight-host --lib -- mem::shared_mem::tests::test_drop --exact --ignored + cargo test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F init-paging," + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} -p hyperlight-host --test integration_test -- log_message --exact --ignored @# metrics tests - cargo test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F function_call_metrics," + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} -p hyperlight-host --lib -- metrics::tests::test_metrics_are_emitted --exact + cargo test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F function_call_metrics,init-paging," + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} -p hyperlight-host --lib -- metrics::tests::test_metrics_are_emitted --exact # runs integration tests. Guest can either be "rust" or "c" test-integration guest target=default-target features="": @# run execute_on_heap test with feature "executable_heap" on and off @@ -113,13 +113,13 @@ test-integration guest target=default-target features="": {{if os() == "windows" { "$env:" } else { "" } }}GUEST="{{guest}}"{{if os() == "windows" { ";" } else { "" } }} cargo test --profile={{ if target == "debug" { "dev" } else { target } }} --test integration_test execute_on_heap {{ if features =="" {""} else {"--features " + features} }} -- --ignored @# run the rest of the integration tests - {{if os() == "windows" { "$env:" } else { "" } }}GUEST="{{guest}}"{{if os() == "windows" { ";" } else { "" } }} cargo test -p hyperlight-host {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F " + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} --test '*' + {{if os() == "windows" { "$env:" } else { "" } }}GUEST="{{guest}}"{{if os() == "windows" { ";" } else { "" } }} cargo test -p hyperlight-host {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F init-paging," + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} --test '*' # runs seccomp tests test-seccomp target=default-target features="": @# run seccomp test with feature "seccomp" on and off cargo test --profile={{ if target == "debug" { "dev" } else { target } }} -p hyperlight-host test_violate_seccomp_filters --lib {{ if features =="" {''} else { "--features " + features } }} -- --ignored - cargo test --profile={{ if target == "debug" { "dev" } else { target } }} -p hyperlight-host test_violate_seccomp_filters --no-default-features {{ if features =~"mshv3" {"--features mshv3"} else {"--features mshv2,kvm" } }} --lib -- --ignored + cargo test --profile={{ if target == "debug" { "dev" } else { target } }} -p hyperlight-host test_violate_seccomp_filters --no-default-features {{ if features =~"mshv3" {"--features init-paging,mshv3"} else {"--features mshv2,init-paging,kvm" } }} --lib -- --ignored # runs tests that ensure compilation fails when it should test-compilation-fail target=default-target: diff --git a/src/hyperlight_host/Cargo.toml b/src/hyperlight_host/Cargo.toml index 3ebd772f3..047f1fc3b 100644 --- a/src/hyperlight_host/Cargo.toml +++ b/src/hyperlight_host/Cargo.toml @@ -119,7 +119,7 @@ cfg_aliases = "0.2.1" built = { version = "0.8.0", optional = true, features = ["chrono", "git2"] } [features] -default = ["kvm", "mshv2", "seccomp", "build-metadata"] +default = ["kvm", "mshv2", "seccomp", "build-metadata", "init-paging"] seccomp = ["dep:seccompiler"] function_call_metrics = [] executable_heap = [] @@ -134,6 +134,7 @@ mshv3 = ["dep:mshv-bindings3", "dep:mshv-ioctls3"] gdb = ["dep:gdbstub", "dep:gdbstub_arch"] fuzzing = ["hyperlight-common/fuzzing"] build-metadata = ["dep:built"] +init-paging = [] [[bench]] name = "benchmarks" diff --git a/src/hyperlight_host/src/hypervisor/hyperv_linux.rs b/src/hyperlight_host/src/hypervisor/hyperv_linux.rs index 3919e37b8..bd52996d6 100644 --- a/src/hyperlight_host/src/hypervisor/hyperv_linux.rs +++ b/src/hyperlight_host/src/hypervisor/hyperv_linux.rs @@ -61,14 +61,14 @@ use super::gdb::{ #[cfg(gdb)] use super::handlers::DbgMemAccessHandlerWrapper; use super::handlers::{MemAccessHandlerWrapper, OutBHandlerWrapper}; +#[cfg(feature = "init-paging")] use super::{ CR0_AM, CR0_ET, CR0_MP, CR0_NE, CR0_PE, CR0_PG, CR0_WP, CR4_OSFXSR, CR4_OSXMMEXCPT, CR4_PAE, - EFER_LMA, EFER_LME, EFER_NX, EFER_SCE, Hypervisor, InterruptHandle, LinuxInterruptHandle, - VirtualCPU, + EFER_LMA, EFER_LME, EFER_NX, EFER_SCE, }; +use super::{HyperlightExit, Hypervisor, InterruptHandle, LinuxInterruptHandle, VirtualCPU}; #[cfg(gdb)] use crate::HyperlightError; -use crate::hypervisor::HyperlightExit; use crate::mem::memory_region::{MemoryRegion, MemoryRegionFlags}; use crate::mem::ptr::{GuestPtr, RawPtr}; use crate::sandbox::SandboxConfiguration; @@ -436,11 +436,12 @@ impl HypervLinuxDriver { } #[instrument(err(Debug), skip_all, parent = Span::current(), level = "Trace")] - fn setup_initial_sregs(vcpu: &mut VcpuFd, pml4_addr: u64) -> Result<()> { + fn setup_initial_sregs(vcpu: &mut VcpuFd, _pml4_addr: u64) -> Result<()> { + #[cfg(feature = "init-paging")] let sregs = SpecialRegisters { cr0: CR0_PE | CR0_MP | CR0_ET | CR0_NE | CR0_AM | CR0_PG | CR0_WP, cr4: CR4_PAE | CR4_OSFXSR | CR4_OSXMMEXCPT, - cr3: pml4_addr, + cr3: _pml4_addr, efer: EFER_LME | EFER_LMA | EFER_SCE | EFER_NX, cs: SegmentRegister { type_: 11, @@ -457,6 +458,16 @@ impl HypervLinuxDriver { }, ..Default::default() }; + + #[cfg(not(feature = "init-paging"))] + let sregs = SpecialRegisters { + cs: SegmentRegister { + base: 0, + selector: 0, + ..Default::default() + }, + ..Default::default() + }; vcpu.set_sregs(&sregs)?; Ok(()) } diff --git a/src/hyperlight_host/src/hypervisor/hyperv_windows.rs b/src/hyperlight_host/src/hypervisor/hyperv_windows.rs index 0bc7886ad..f0b28e75f 100644 --- a/src/hyperlight_host/src/hypervisor/hyperv_windows.rs +++ b/src/hyperlight_host/src/hypervisor/hyperv_windows.rs @@ -41,10 +41,12 @@ use super::surrogate_process::SurrogateProcess; use super::surrogate_process_manager::*; use super::windows_hypervisor_platform::{VMPartition, VMProcessor}; use super::wrappers::{HandleWrapper, WHvFPURegisters}; +#[cfg(feature = "init-paging")] use super::{ CR0_AM, CR0_ET, CR0_MP, CR0_NE, CR0_PE, CR0_PG, CR0_WP, CR4_OSFXSR, CR4_OSXMMEXCPT, CR4_PAE, - EFER_LMA, EFER_LME, EFER_NX, EFER_SCE, HyperlightExit, Hypervisor, InterruptHandle, VirtualCPU, + EFER_LMA, EFER_LME, EFER_NX, EFER_SCE, }; +use super::{HyperlightExit, Hypervisor, InterruptHandle, VirtualCPU}; use crate::hypervisor::fpu::FP_CONTROL_WORD_DEFAULT; use crate::hypervisor::wrappers::WHvGeneralRegisters; use crate::mem::memory_region::{MemoryRegion, MemoryRegionFlags}; @@ -125,9 +127,10 @@ impl HypervWindowsDriver { }) } - fn setup_initial_sregs(proc: &mut VMProcessor, pml4_addr: u64) -> Result<()> { + fn setup_initial_sregs(proc: &mut VMProcessor, _pml4_addr: u64) -> Result<()> { + #[cfg(feature = "init-paging")] proc.set_registers(&[ - (WHvX64RegisterCr3, WHV_REGISTER_VALUE { Reg64: pml4_addr }), + (WHvX64RegisterCr3, WHV_REGISTER_VALUE { Reg64: _pml4_addr }), ( WHvX64RegisterCr4, WHV_REGISTER_VALUE { @@ -158,6 +161,19 @@ impl HypervWindowsDriver { }, ), ])?; + + #[cfg(not(feature = "init-paging"))] + proc.set_registers(&[( + WHvX64RegisterCs, + WHV_REGISTER_VALUE { + Segment: WHV_X64_SEGMENT_REGISTER { + Base: 0, + Selector: 0, + ..Default::default() + }, + }, + )])?; + Ok(()) } diff --git a/src/hyperlight_host/src/hypervisor/kvm.rs b/src/hyperlight_host/src/hypervisor/kvm.rs index 1e8ce1eee..4bc17035b 100644 --- a/src/hyperlight_host/src/hypervisor/kvm.rs +++ b/src/hyperlight_host/src/hypervisor/kvm.rs @@ -35,11 +35,12 @@ use super::gdb::{DebugCommChannel, DebugMsg, DebugResponse, GuestDebug, KvmDebug #[cfg(gdb)] use super::handlers::DbgMemAccessHandlerWrapper; use super::handlers::{MemAccessHandlerWrapper, OutBHandlerWrapper}; +#[cfg(feature = "init-paging")] use super::{ CR0_AM, CR0_ET, CR0_MP, CR0_NE, CR0_PE, CR0_PG, CR0_WP, CR4_OSFXSR, CR4_OSXMMEXCPT, CR4_PAE, - EFER_LMA, EFER_LME, EFER_NX, EFER_SCE, HyperlightExit, Hypervisor, InterruptHandle, - LinuxInterruptHandle, VirtualCPU, + EFER_LMA, EFER_LME, EFER_NX, EFER_SCE, }; +use super::{HyperlightExit, Hypervisor, InterruptHandle, LinuxInterruptHandle, VirtualCPU}; #[cfg(gdb)] use crate::HyperlightError; use crate::mem::memory_region::{MemoryRegion, MemoryRegionFlags}; @@ -390,14 +391,21 @@ impl KVMDriver { } #[instrument(err(Debug), skip_all, parent = Span::current(), level = "Trace")] - fn setup_initial_sregs(vcpu_fd: &mut VcpuFd, pml4_addr: u64) -> Result<()> { + fn setup_initial_sregs(vcpu_fd: &mut VcpuFd, _pml4_addr: u64) -> Result<()> { // setup paging and IA-32e (64-bit) mode let mut sregs = vcpu_fd.get_sregs()?; - sregs.cr3 = pml4_addr; - sregs.cr4 = CR4_PAE | CR4_OSFXSR | CR4_OSXMMEXCPT; - sregs.cr0 = CR0_PE | CR0_MP | CR0_ET | CR0_NE | CR0_AM | CR0_PG | CR0_WP; - sregs.efer = EFER_LME | EFER_LMA | EFER_SCE | EFER_NX; - sregs.cs.l = 1; // required for 64-bit mode + cfg_if::cfg_if! { + if #[cfg(feature = "init-paging")] { + sregs.cr3 = _pml4_addr; + sregs.cr4 = CR4_PAE | CR4_OSFXSR | CR4_OSXMMEXCPT; + sregs.cr0 = CR0_PE | CR0_MP | CR0_ET | CR0_NE | CR0_AM | CR0_PG | CR0_WP; + sregs.efer = EFER_LME | EFER_LMA | EFER_SCE | EFER_NX; + sregs.cs.l = 1; // required for 64-bit mode + } else { + sregs.cs.base = 0; + sregs.cs.selector = 0; + } + } vcpu_fd.set_sregs(&sregs)?; Ok(()) } diff --git a/src/hyperlight_host/src/hypervisor/mod.rs b/src/hyperlight_host/src/hypervisor/mod.rs index 6eed878fa..f8fa29f51 100644 --- a/src/hyperlight_host/src/hypervisor/mod.rs +++ b/src/hyperlight_host/src/hypervisor/mod.rs @@ -75,20 +75,24 @@ use self::handlers::{ }; use crate::mem::ptr::RawPtr; -pub(crate) const CR4_PAE: u64 = 1 << 5; -pub(crate) const CR4_OSFXSR: u64 = 1 << 9; -pub(crate) const CR4_OSXMMEXCPT: u64 = 1 << 10; -pub(crate) const CR0_PE: u64 = 1; -pub(crate) const CR0_MP: u64 = 1 << 1; -pub(crate) const CR0_ET: u64 = 1 << 4; -pub(crate) const CR0_NE: u64 = 1 << 5; -pub(crate) const CR0_WP: u64 = 1 << 16; -pub(crate) const CR0_AM: u64 = 1 << 18; -pub(crate) const CR0_PG: u64 = 1 << 31; -pub(crate) const EFER_LME: u64 = 1 << 8; -pub(crate) const EFER_LMA: u64 = 1 << 10; -pub(crate) const EFER_SCE: u64 = 1; -pub(crate) const EFER_NX: u64 = 1 << 11; +cfg_if::cfg_if! { + if #[cfg(feature = "init-paging")] { + pub(crate) const CR4_PAE: u64 = 1 << 5; + pub(crate) const CR4_OSFXSR: u64 = 1 << 9; + pub(crate) const CR4_OSXMMEXCPT: u64 = 1 << 10; + pub(crate) const CR0_PE: u64 = 1; + pub(crate) const CR0_MP: u64 = 1 << 1; + pub(crate) const CR0_ET: u64 = 1 << 4; + pub(crate) const CR0_NE: u64 = 1 << 5; + pub(crate) const CR0_WP: u64 = 1 << 16; + pub(crate) const CR0_AM: u64 = 1 << 18; + pub(crate) const CR0_PG: u64 = 1 << 31; + pub(crate) const EFER_LME: u64 = 1 << 8; + pub(crate) const EFER_LMA: u64 = 1 << 10; + pub(crate) const EFER_SCE: u64 = 1; + pub(crate) const EFER_NX: u64 = 1 << 11; + } +} /// These are the generic exit reasons that we can handle from a Hypervisor the Hypervisors run method is responsible for mapping from /// the hypervisor specific exit reasons to these generic ones diff --git a/src/hyperlight_host/src/mem/elf.rs b/src/hyperlight_host/src/mem/elf.rs index 5daffc35c..3efe09b4f 100644 --- a/src/hyperlight_host/src/mem/elf.rs +++ b/src/hyperlight_host/src/mem/elf.rs @@ -19,6 +19,9 @@ use goblin::elf::reloc::{R_AARCH64_NONE, R_AARCH64_RELATIVE}; #[cfg(target_arch = "x86_64")] use goblin::elf::reloc::{R_X86_64_NONE, R_X86_64_RELATIVE}; use goblin::elf::{Elf, ProgramHeaders, Reloc}; +#[cfg(not(feature = "init-paging"))] +use goblin::elf32::program_header::PT_LOAD; +#[cfg(feature = "init-paging")] use goblin::elf64::program_header::PT_LOAD; use crate::{Result, log_then_return, new_error}; diff --git a/src/hyperlight_host/src/mem/layout.rs b/src/hyperlight_host/src/mem/layout.rs index 345aa3401..04edc9bcc 100644 --- a/src/hyperlight_host/src/mem/layout.rs +++ b/src/hyperlight_host/src/mem/layout.rs @@ -20,13 +20,15 @@ use hyperlight_common::mem::{GuestMemoryRegion, HyperlightPEB, PAGE_SIZE_USIZE}; use rand::{RngCore, rng}; use tracing::{Span, instrument}; +#[cfg(feature = "init-paging")] +use super::memory_region::MemoryRegionType::PageTables; use super::memory_region::MemoryRegionType::{ - Code, GuardPage, Heap, HostFunctionDefinitions, InitData, InputData, OutputData, PageTables, - Peb, Stack, + Code, GuardPage, Heap, HostFunctionDefinitions, InitData, InputData, OutputData, Peb, Stack, }; use super::memory_region::{ DEFAULT_GUEST_BLOB_MEM_FLAGS, MemoryRegion, MemoryRegionFlags, MemoryRegionVecBuilder, }; +#[cfg(feature = "init-paging")] use super::mgr::AMOUNT_OF_MEMORY_PER_PT; use super::shared_mem::{ExclusiveSharedMemory, GuestSharedMemory, SharedMemory}; use crate::error::HyperlightError::{GuestOffsetIsInvalid, MemoryRequestTooBig}; @@ -257,11 +259,13 @@ impl SandboxMemoryLayout { init_data_size: usize, init_data_permissions: Option, ) -> Result { - let total_page_table_size = - Self::get_total_page_table_size(cfg, code_size, stack_size, heap_size); - let guest_code_offset = total_page_table_size; + #[cfg(feature = "init-paging")] + let base = Self::get_total_page_table_size(cfg, code_size, stack_size, heap_size); + #[cfg(not(feature = "init-paging"))] + let base = Self::BASE_ADDRESS; + let guest_code_offset = base; // The following offsets are to the fields of the PEB struct itself! - let peb_offset = total_page_table_size + round_up_to(code_size, PAGE_SIZE_USIZE); + let peb_offset = base + round_up_to(code_size, PAGE_SIZE_USIZE); let peb_security_cookie_seed_offset = peb_offset + offset_of!(HyperlightPEB, security_cookie_seed); let peb_guest_dispatch_function_ptr_offset = @@ -325,7 +329,7 @@ impl SandboxMemoryLayout { guest_user_stack_buffer_offset, peb_address, guard_page_offset, - total_page_table_size, + total_page_table_size: base, guest_code_offset, init_data_offset, init_data_size, @@ -507,6 +511,7 @@ impl SandboxMemoryLayout { } #[cfg(test)] + #[cfg(feature = "init-paging")] /// Get the page table size fn get_page_table_size(&self) -> usize { self.total_page_table_size @@ -523,6 +528,7 @@ impl SandboxMemoryLayout { // then divide that by 0x200_000 (as we can map 2MB in each PT). // This will give us the total size of the PTs required for the sandbox to which we can add the size of the PML4, PDPT and PD. #[instrument(skip_all, parent = Span::current(), level= "Trace")] + #[cfg(feature = "init-paging")] fn get_total_page_table_size( cfg: SandboxConfiguration, code_size: usize, @@ -582,19 +588,23 @@ impl SandboxMemoryLayout { pub fn get_memory_regions(&self, shared_mem: &GuestSharedMemory) -> Result> { let mut builder = MemoryRegionVecBuilder::new(Self::BASE_ADDRESS, shared_mem.base_addr()); - // PML4, PDPT, PD - let code_offset = builder.push_page_aligned( - self.total_page_table_size, - MemoryRegionFlags::READ | MemoryRegionFlags::WRITE, - PageTables, - ); - - if code_offset != self.guest_code_offset { - return Err(new_error!( - "Code offset does not match expected code offset expected: {}, actual: {}", - self.guest_code_offset, - code_offset - )); + cfg_if::cfg_if! { + if #[cfg(feature = "init-paging")] { + // PML4, PDPT, PD + let code_offset = builder.push_page_aligned( + self.total_page_table_size, + MemoryRegionFlags::READ | MemoryRegionFlags::WRITE, + PageTables, + ); + + if code_offset != self.guest_code_offset { + return Err(new_error!( + "Code offset does not match expected code offset expected: {}, actual: {}", + self.guest_code_offset, + code_offset + )); + } + } } // code @@ -929,7 +939,10 @@ mod tests { let cfg = layout.sandbox_memory_config; let mut expected_size = 0; // in order of layout - expected_size += layout.get_page_table_size(); + #[cfg(feature = "init-paging")] + { + expected_size += layout.get_page_table_size(); + } expected_size += layout.code_size; expected_size += round_up_to(size_of::(), PAGE_SIZE_USIZE); diff --git a/src/hyperlight_host/src/mem/memory_region.rs b/src/hyperlight_host/src/mem/memory_region.rs index 7db8f31c4..a7e22255b 100644 --- a/src/hyperlight_host/src/mem/memory_region.rs +++ b/src/hyperlight_host/src/mem/memory_region.rs @@ -43,6 +43,7 @@ use mshv_bindings::{hv_x64_memory_intercept_message, mshv_user_mem_region}; #[cfg(target_os = "windows")] use windows::Win32::System::Hypervisor::{self, WHV_MEMORY_ACCESS_TYPE}; +#[cfg(feature = "init-paging")] use super::mgr::{PAGE_NX, PAGE_PRESENT, PAGE_RW, PAGE_USER}; pub(crate) const DEFAULT_GUEST_BLOB_MEM_FLAGS: MemoryRegionFlags = MemoryRegionFlags::READ; @@ -65,6 +66,7 @@ bitflags! { } impl MemoryRegionFlags { + #[cfg(feature = "init-paging")] pub(crate) fn translate_flags(&self) -> u64 { let mut page_flags = 0; diff --git a/src/hyperlight_host/src/mem/mgr.rs b/src/hyperlight_host/src/mem/mgr.rs index 39154e2a8..239e9edef 100644 --- a/src/hyperlight_host/src/mem/mgr.rs +++ b/src/hyperlight_host/src/mem/mgr.rs @@ -28,6 +28,7 @@ use tracing::{Span, instrument}; use super::exe::ExeInfo; use super::layout::SandboxMemoryLayout; +#[cfg(feature = "init-paging")] use super::memory_region::{DEFAULT_GUEST_BLOB_MEM_FLAGS, MemoryRegion, MemoryRegionType}; use super::ptr::{GuestPtr, RawPtr}; use super::ptr_offset::Offset; @@ -36,21 +37,25 @@ use super::shared_mem_snapshot::SharedMemorySnapshot; use crate::HyperlightError::NoMemorySnapshot; use crate::sandbox::SandboxConfiguration; use crate::sandbox::uninitialized::GuestBlob; -use crate::{HyperlightError, Result, log_then_return, new_error}; - -/// Paging Flags -/// -/// See the following links explaining paging, also see paging-development-notes.md in docs: -/// -/// * Very basic description: https://stackoverflow.com/a/26945892 -/// * More in-depth descriptions: https://wiki.osdev.org/Paging -pub(crate) const PAGE_PRESENT: u64 = 1; // Page is Present -pub(crate) const PAGE_RW: u64 = 1 << 1; // Page is Read/Write (if not set page is read only so long as the WP bit in CR0 is set to 1 - which it is in Hyperlight) -pub(crate) const PAGE_USER: u64 = 1 << 2; // User/Supervisor (if this bit is set then the page is accessible by user mode code) -pub(crate) const PAGE_NX: u64 = 1 << 63; // Execute Disable (if this bit is set then data in the page cannot be executed) - -// The amount of memory that can be mapped per page table -pub(super) const AMOUNT_OF_MEMORY_PER_PT: usize = 0x200_000; +use crate::{Result, log_then_return, new_error}; + +cfg_if::cfg_if! { + if #[cfg(feature = "init-paging")] { + /// Paging Flags + /// + /// See the following links explaining paging, also see paging-development-notes.md in docs: + /// + /// * Very basic description: https://stackoverflow.com/a/26945892 + /// * More in-depth descriptions: https://wiki.osdev.org/Paging + pub(crate) const PAGE_PRESENT: u64 = 1; // Page is Present + pub(crate) const PAGE_RW: u64 = 1 << 1; // Page is Read/Write (if not set page is read only so long as the WP bit in CR0 is set to 1 - which it is in Hyperlight) + pub(crate) const PAGE_USER: u64 = 1 << 2; // User/Supervisor (if this bit is set then the page is accessible by user mode code) + pub(crate) const PAGE_NX: u64 = 1 << 63; // Execute Disable (if this bit is set then data in the page cannot be executed)` + // The amount of memory that can be mapped per page table + pub(super) const AMOUNT_OF_MEMORY_PER_PT: usize = 0x200_000; + } +} + /// Read/write permissions flag for the 64-bit PDE /// The page size for the 64-bit PDE /// The size of stack guard cookies @@ -104,6 +109,7 @@ where // TODO: This should perhaps happen earlier and use an // ExclusiveSharedMemory from the beginning. #[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")] + #[cfg(feature = "init-paging")] pub(crate) fn set_up_shared_memory( &mut self, mem_size: u64, @@ -202,13 +208,14 @@ where std::slice::from_raw_parts(pte_buffer.as_ptr() as *const u8, pte_buffer.len() * 8) }; shared_mem.copy_from_slice(pte_bytes, SandboxMemoryLayout::PT_OFFSET)?; - Ok::<(), HyperlightError>(()) + Ok::<(), crate::HyperlightError>(()) })??; Ok(rsp) } /// Optimized page flags getter that maintains state for sequential access patterns + #[cfg(feature = "init-paging")] fn get_page_flags( p: usize, i: usize, diff --git a/src/hyperlight_host/src/sandbox/uninitialized_evolve.rs b/src/hyperlight_host/src/sandbox/uninitialized_evolve.rs index 9bda0cb73..7cdd7d74d 100644 --- a/src/hyperlight_host/src/sandbox/uninitialized_evolve.rs +++ b/src/hyperlight_host/src/sandbox/uninitialized_evolve.rs @@ -32,7 +32,9 @@ use crate::mem::layout::SandboxMemoryLayout; use crate::mem::mgr::SandboxMemoryManager; use crate::mem::ptr::{GuestPtr, RawPtr}; use crate::mem::ptr_offset::Offset; -use crate::mem::shared_mem::{GuestSharedMemory, SharedMemory}; +use crate::mem::shared_mem::GuestSharedMemory; +#[cfg(feature = "init-paging")] +use crate::mem::shared_mem::SharedMemory; #[cfg(gdb)] use crate::sandbox::config::DebugInfo; use crate::sandbox::host_funcs::FunctionRegistry; @@ -150,13 +152,17 @@ pub(crate) fn set_up_hypervisor_partition( #[cfg_attr(target_os = "windows", allow(unused_variables))] config: &SandboxConfiguration, #[cfg(any(crashdump, gdb))] rt_cfg: &SandboxRuntimeConfig, ) -> Result> { - let mem_size = u64::try_from(mgr.shared_mem.mem_size())?; - let mut regions = mgr.layout.get_memory_regions(&mgr.shared_mem)?; + #[cfg(feature = "init-paging")] let rsp_ptr = { + let mut regions = mgr.layout.get_memory_regions(&mgr.shared_mem)?; + let mem_size = u64::try_from(mgr.shared_mem.mem_size())?; let rsp_u64 = mgr.set_up_shared_memory(mem_size, &mut regions)?; let rsp_raw = RawPtr::from(rsp_u64); GuestPtr::try_from(rsp_raw) }?; + #[cfg(not(feature = "init-paging"))] + let rsp_ptr = GuestPtr::try_from(Offset::from(0))?; + let regions = mgr.layout.get_memory_regions(&mgr.shared_mem)?; let base_ptr = GuestPtr::try_from(Offset::from(0))?; let pml4_ptr = { let pml4_offset_u64 = u64::try_from(SandboxMemoryLayout::PML4_OFFSET)?;