Skip to content

Commit

Permalink
fix(mem): add private anonymous memory back
Browse files Browse the repository at this point in the history
Private anonymous memory is useful when a device does not want other
devices to access its memory.

Fixes: a536818 ("feat(mem)!: create anonymous mem with memfd_create")

Signed-off-by: Changyuan Lyu <[email protected]>
  • Loading branch information
Lencerf committed Jun 2, 2024
1 parent 0005413 commit dc0c8c6
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 21 deletions.
9 changes: 3 additions & 6 deletions alioth/src/board/x86_64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ where
let memory = &self.memory;

let low_mem_size = std::cmp::min(config.mem_size, RAM_32_SIZE);
let pages_low = ArcMemPages::from_anonymous(low_mem_size, None, Some(c"ram-low"))?;
let pages_low = ArcMemPages::from_memfd(low_mem_size, None, Some(c"ram-low"))?;
if self.config.coco.is_some() {
self.memory.ram_bus().register_encrypted_pages(&pages_low)?;
}
Expand Down Expand Up @@ -161,11 +161,8 @@ where
};
memory.add_region(AddrOpt::Fixed(0), Arc::new(region_low))?;
if config.mem_size > RAM_32_SIZE {
let mem_hi = ArcMemPages::from_anonymous(
config.mem_size - RAM_32_SIZE,
None,
Some(c"ram-high"),
)?;
let mem_hi =
ArcMemPages::from_memfd(config.mem_size - RAM_32_SIZE, None, Some(c"ram-high"))?;
if self.config.coco.is_some() {
self.memory.ram_bus().register_encrypted_pages(&mem_hi)?;
}
Expand Down
2 changes: 1 addition & 1 deletion alioth/src/loader/firmware/x86_64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub fn load<P: AsRef<Path>>(memory: &Memory, path: P) -> Result<(InitState, ArcM
let size = file.metadata()?.len() as usize;
assert_eq!(size & 0xfff, 0);

let mut rom = ArcMemPages::from_anonymous(size, None, Some(c"rom"))?;
let mut rom = ArcMemPages::from_memfd(size, None, Some(c"rom"))?;
file.read_exact(rom.as_slice_mut())?;

let gpa = MEM_64_START - size;
Expand Down
31 changes: 20 additions & 11 deletions alioth/src/mem/mapped.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ use std::sync::atomic::{AtomicU32, Ordering};
use std::sync::Arc;

use libc::{
c_void, mmap, msync, munmap, MAP_FAILED, MAP_SHARED, MFD_CLOEXEC, MS_ASYNC, PROT_EXEC,
PROT_READ, PROT_WRITE,
c_void, mmap, msync, munmap, MAP_ANONYMOUS, MAP_FAILED, MAP_PRIVATE, MAP_SHARED, MFD_CLOEXEC,
MS_ASYNC, PROT_EXEC, PROT_READ, PROT_WRITE,
};
use parking_lot::{RwLock, RwLockReadGuard};
use zerocopy::{AsBytes, FromBytes};
Expand All @@ -41,7 +41,7 @@ use super::{Error, Result};
struct MemPages {
addr: NonNull<c_void>,
len: usize,
fd: File,
fd: Option<File>,
}

unsafe impl Send for MemPages {}
Expand Down Expand Up @@ -83,16 +83,16 @@ impl ArcMemPages {
self.size
}

pub fn fd(&self) -> BorrowedFd {
self._inner.fd.as_fd()
pub fn fd(&self) -> Option<BorrowedFd> {
self._inner.fd.as_ref().map(|f| f.as_fd())
}

pub fn sync(&self) -> Result<()> {
ffi!(unsafe { msync(self.addr as *mut _, self.size, MS_ASYNC) })?;
Ok(())
}

fn from_raw(addr: *mut c_void, len: usize, fd: File) -> Self {
fn from_raw(addr: *mut c_void, len: usize, fd: Option<File>) -> Self {
let addr = NonNull::new(addr).expect("address from mmap() should not be null");
ArcMemPages {
addr: addr.as_ptr() as usize,
Expand All @@ -106,10 +106,10 @@ impl ArcMemPages {
unsafe { mmap(null_mut(), len, prot, MAP_SHARED, file.as_raw_fd(), offset) },
MAP_FAILED
)?;
Ok(Self::from_raw(addr, len, file))
Ok(Self::from_raw(addr, len, Some(file)))
}

pub fn from_anonymous(size: usize, prot: Option<i32>, name: Option<&CStr>) -> Result<Self> {
pub fn from_memfd(size: usize, prot: Option<i32>, name: Option<&CStr>) -> Result<Self> {
let name = name.unwrap_or(c"anon");
let fd = ffi!(unsafe { libc::memfd_create(name.as_ptr(), MFD_CLOEXEC) })?;
let prot = prot.unwrap_or(PROT_WRITE | PROT_READ | PROT_EXEC);
Expand All @@ -119,7 +119,16 @@ impl ArcMemPages {
)?;
let file = unsafe { File::from_raw_fd(fd) };
file.set_len(size as _)?;
Ok(Self::from_raw(addr, size, file))
Ok(Self::from_raw(addr, size, Some(file)))
}

pub fn from_anonymous(size: usize, prot: Option<i32>) -> Result<Self> {
let prot = prot.unwrap_or(PROT_WRITE | PROT_READ | PROT_EXEC);
let addr = ffi!(
unsafe { mmap(null_mut(), size, prot, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0) },
MAP_FAILED
)?;
Ok(Self::from_raw(addr, size, None))
}

/// Given offset and len, return the host virtual address and len;
Expand Down Expand Up @@ -581,8 +590,8 @@ mod test {
fn test_ram_bus_read() {
let bus = RamBus::new(FakeVmMemory);
let prot = PROT_READ | PROT_WRITE;
let mem1 = ArcMemPages::from_anonymous(PAGE_SIZE, Some(prot), None).unwrap();
let mem2 = ArcMemPages::from_anonymous(PAGE_SIZE, Some(prot), None).unwrap();
let mem1 = ArcMemPages::from_memfd(PAGE_SIZE, Some(prot), None).unwrap();
let mem2 = ArcMemPages::from_memfd(PAGE_SIZE, Some(prot), None).unwrap();

if mem1.addr > mem2.addr {
bus.add(0x0, mem1).unwrap();
Expand Down
7 changes: 4 additions & 3 deletions alioth/src/virtio/dev/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@ impl Virtio for VuFs {
.set_features(&(feature | VirtioFeature::VHOST_PROTOCOL.bits()))?;
let mem = memory.lock_layout();
for (gpa, slot) in mem.iter() {
let Some(fd) = slot.pages.fd() else {
continue;
};
let region = MemorySingleRegion {
_padding: 0,
region: MemoryRegion {
Expand All @@ -165,9 +168,7 @@ impl Virtio for VuFs {
mmap_offset: 0,
},
};
self.vu_dev
.add_mem_region(&region, slot.pages.fd().as_raw_fd())
.unwrap();
self.vu_dev.add_mem_region(&region, fd.as_raw_fd()).unwrap();
log::info!("region: {region:x?}");
self.regions.push(region.region);
}
Expand Down

0 comments on commit dc0c8c6

Please sign in to comment.