Skip to content

Commit 6e81fcf

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 e335f54 commit 6e81fcf

File tree

4 files changed

+34
-10
lines changed

4 files changed

+34
-10
lines changed

src/hyperlight_host/src/mem/elf.rs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use goblin::elf32::program_header::PT_LOAD;
2424
#[cfg(feature = "init-paging")]
2525
use goblin::elf64::program_header::PT_LOAD;
2626

27+
use super::shared_mem::ExclusiveSharedMemory;
2728
use crate::{Result, log_then_return, new_error};
2829

2930
pub(crate) struct ElfInfo {
@@ -73,15 +74,26 @@ impl ElfInfo {
7374
.unwrap();
7475
(max_phdr.p_vaddr + max_phdr.p_memsz - self.get_base_va()) as usize
7576
}
76-
pub(crate) fn load_at(&self, load_addr: usize, target: &mut [u8]) -> Result<()> {
77+
pub(crate) fn load_at(
78+
&self,
79+
load_addr: usize,
80+
guest_code_offset: usize,
81+
excl: &mut ExclusiveSharedMemory,
82+
) -> Result<()> {
7783
let base_va = self.get_base_va();
7884
for phdr in self.phdrs.iter().filter(|phdr| phdr.p_type == PT_LOAD) {
7985
let start_va = (phdr.p_vaddr - base_va) as usize;
8086
let payload_offset = phdr.p_offset as usize;
8187
let payload_len = phdr.p_filesz as usize;
82-
target[start_va..start_va + payload_len]
83-
.copy_from_slice(&self.payload[payload_offset..payload_offset + payload_len]);
84-
target[start_va + payload_len..start_va + phdr.p_memsz as usize].fill(0);
88+
excl.copy_from_slice(
89+
&self.payload[payload_offset..payload_offset + payload_len],
90+
guest_code_offset + start_va,
91+
)?;
92+
93+
excl.zero_fill(
94+
guest_code_offset + start_va + payload_len,
95+
phdr.p_memsz as usize - payload_len,
96+
)?;
8597
}
8698
let get_addend = |name, r: &Reloc| {
8799
r.r_addend
@@ -104,8 +116,10 @@ impl ElfInfo {
104116
match r.r_type {
105117
R_X86_64_RELATIVE => {
106118
let addend = get_addend("R_X86_64_RELATIVE", r)?;
107-
target[r.r_offset as usize..r.r_offset as usize + 8]
108-
.copy_from_slice(&(load_addr as i64 + addend).to_le_bytes());
119+
excl.copy_from_slice(
120+
&(load_addr as i64 + addend).to_le_bytes(),
121+
guest_code_offset + r.r_offset as usize,
122+
)?;
109123
}
110124
R_X86_64_NONE => {}
111125
_ => {

src/hyperlight_host/src/mem/exe.rs

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

2121
use super::elf::ElfInfo;
2222
use super::ptr_offset::Offset;
23+
use super::shared_mem::ExclusiveSharedMemory;
2324
use crate::Result;
2425

2526
// This is used extremely infrequently, so being unusually large for PE
@@ -71,10 +72,15 @@ impl ExeInfo {
7172
// copying into target, but the PE loader chooses to apply
7273
// relocations in its owned representation of the PE contents,
7374
// which requires it to be &mut.
74-
pub fn load(&mut self, load_addr: usize, target: &mut [u8]) -> Result<()> {
75+
pub fn load(
76+
&mut self,
77+
load_addr: usize,
78+
guest_code_offset: usize,
79+
target: &mut ExclusiveSharedMemory,
80+
) -> Result<()> {
7581
match self {
7682
ExeInfo::Elf(elf) => {
77-
elf.load_at(load_addr, target)?;
83+
elf.load_at(load_addr, guest_code_offset, target)?;
7884
}
7985
}
8086
Ok(())

src/hyperlight_host/src/mem/mgr.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,8 @@ impl SandboxMemoryManager<ExclusiveSharedMemory> {
341341

342342
exe_info.load(
343343
load_addr.clone().try_into()?,
344-
&mut shared_mem.as_mut_slice()[layout.get_guest_code_offset()..],
344+
layout.get_guest_code_offset(),
345+
&mut shared_mem,
345346
)?;
346347

347348
Ok(Self::new(layout, shared_mem, load_addr, entrypoint_offset))

src/hyperlight_host/src/mem/shared_mem.rs

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

0 commit comments

Comments
 (0)