Skip to content

Commit 0086a01

Browse files
committed
Don't use shared_mem.as_mut_slice() since it doesn't dirty touched pages in the host
Signed-off-by: Ludvig Liljenberg <[email protected]>
1 parent 466df5b commit 0086a01

File tree

4 files changed

+30
-10
lines changed

4 files changed

+30
-10
lines changed

src/hyperlight_host/src/mem/elf.rs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use goblin::elf32::program_header::PT_LOAD;
2727
#[cfg(feature = "init-paging")]
2828
use goblin::elf64::program_header::PT_LOAD;
2929

30+
use super::shared_mem::ExclusiveSharedMemory;
3031
use crate::{Result, log_then_return, new_error};
3132

3233
#[cfg(feature = "unwind_guest")]
@@ -164,16 +165,23 @@ impl ElfInfo {
164165
pub(crate) fn load_at(
165166
self,
166167
load_addr: usize,
167-
target: &mut [u8],
168+
guest_code_offset: usize,
169+
excl: &mut ExclusiveSharedMemory,
168170
) -> Result<super::exe::LoadInfo> {
169171
let base_va = self.get_base_va();
170172
for phdr in self.phdrs.iter().filter(|phdr| phdr.p_type == PT_LOAD) {
171173
let start_va = (phdr.p_vaddr - base_va) as usize;
172174
let payload_offset = phdr.p_offset as usize;
173175
let payload_len = phdr.p_filesz as usize;
174-
target[start_va..start_va + payload_len]
175-
.copy_from_slice(&self.payload[payload_offset..payload_offset + payload_len]);
176-
target[start_va + payload_len..start_va + phdr.p_memsz as usize].fill(0);
176+
excl.copy_from_slice(
177+
&self.payload[payload_offset..payload_offset + payload_len],
178+
guest_code_offset + start_va,
179+
)?;
180+
181+
excl.zero_fill(
182+
guest_code_offset + start_va + payload_len,
183+
phdr.p_memsz as usize - payload_len,
184+
)?;
177185
}
178186
let get_addend = |name, r: &Reloc| {
179187
r.r_addend
@@ -196,8 +204,10 @@ impl ElfInfo {
196204
match r.r_type {
197205
R_X86_64_RELATIVE => {
198206
let addend = get_addend("R_X86_64_RELATIVE", r)?;
199-
target[r.r_offset as usize..r.r_offset as usize + 8]
200-
.copy_from_slice(&(load_addr as i64 + addend).to_le_bytes());
207+
excl.copy_from_slice(
208+
&(load_addr as i64 + addend).to_le_bytes(),
209+
guest_code_offset + r.r_offset as usize,
210+
)?;
201211
}
202212
R_X86_64_NONE => {}
203213
_ => {

src/hyperlight_host/src/mem/exe.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use std::vec::Vec;
2222

2323
use super::elf::ElfInfo;
2424
use super::ptr_offset::Offset;
25+
use super::shared_mem::ExclusiveSharedMemory;
2526
use crate::Result;
2627

2728
// This is used extremely infrequently, so being unusually large for PE
@@ -108,9 +109,14 @@ impl ExeInfo {
108109
// copying into target, but the PE loader chooses to apply
109110
// relocations in its owned representation of the PE contents,
110111
// which requires it to be &mut.
111-
pub fn load(self, load_addr: usize, target: &mut [u8]) -> Result<LoadInfo> {
112+
pub fn load(
113+
self,
114+
load_addr: usize,
115+
guest_code_offset: usize,
116+
target: &mut ExclusiveSharedMemory,
117+
) -> Result<LoadInfo> {
112118
match self {
113-
ExeInfo::Elf(elf) => elf.load_at(load_addr, target),
119+
ExeInfo::Elf(elf) => elf.load_at(load_addr, guest_code_offset, target),
114120
}
115121
}
116122
}

src/hyperlight_host/src/mem/mgr.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,8 @@ impl SandboxMemoryManager<ExclusiveSharedMemory> {
346346
#[allow(clippy::let_unit_value)]
347347
let load_info = exe_info.load(
348348
load_addr.clone().try_into()?,
349-
&mut shared_mem.as_mut_slice()[layout.get_guest_code_offset()..],
349+
layout.get_guest_code_offset(),
350+
&mut shared_mem,
350351
)?;
351352

352353
Ok((

src/hyperlight_host/src/mem/shared_mem.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -577,7 +577,10 @@ impl ExclusiveSharedMemory {
577577
/// the safety documentation of pointer::offset.
578578
///
579579
/// This is ensured by a check in ::new()
580-
pub(super) fn as_mut_slice(&mut self) -> &mut [u8] {
580+
///
581+
/// Additionally, writes to the returned slice will not mark pages as dirty.
582+
/// User must call `mark_pages_dirty` manually to mark pages as dirty.
583+
fn as_mut_slice(&mut self) -> &mut [u8] {
581584
unsafe { std::slice::from_raw_parts_mut(self.base_ptr(), self.mem_size()) }
582585
}
583586

0 commit comments

Comments
 (0)