Skip to content

Commit

Permalink
vsock: add memory related functionality...
Browse files Browse the repository at this point in the history
needed for the vhost-based vsock support.

Signed-off-by: Diana Popa <[email protected]>
  • Loading branch information
dianpopa authored and andreeaflorescu committed Nov 21, 2018
1 parent 967adc9 commit 32e074f
Showing 1 changed file with 51 additions and 0 deletions.
51 changes: 51 additions & 0 deletions memory_model/src/guest_memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,34 @@ impl GuestMemory {
})
}

/// Convert a GuestAddress into a pointer in the address space of this
/// process. This should only be necessary for giving addresses to the
/// kernel, as with vhost ioctls. Normal reads/writes to guest memory should
/// be done through `write_from_memory`, `read_obj_from_addr`, etc.
///
/// # Arguments
/// * `guest_addr` - Guest address to convert.
///
/// # Examples
///
/// ```
/// # use sys_util::{GuestAddress, GuestMemory};
/// # fn test_host_addr() -> Result<(), ()> {
/// let start_addr = GuestAddress(0x1000);
/// let mut gm = GuestMemory::new(&vec![(start_addr, 0x500)]).map_err(|_| ())?;
/// let addr = gm.get_host_address(GuestAddress(0x1200)).unwrap();
/// println!("Host address is {:p}", addr);
/// Ok(())
/// # }
/// ```
pub fn get_host_address(&self, guest_addr: GuestAddress) -> Result<*const u8> {
self.do_in_region(guest_addr, |mapping, offset| {
// This is safe; `do_in_region` already checks that offset is in
// bounds.
Ok(unsafe { mapping.as_ptr().offset(offset as isize) } as *const u8)
})
}

fn do_in_region<F, T>(&self, guest_addr: GuestAddress, cb: F) -> Result<T>
where
F: FnOnce(&MemoryMapping, usize) -> Result<T>,
Expand Down Expand Up @@ -466,4 +494,27 @@ mod tests {
assert_eq!(gm.clone().regions[1].guest_base, regions[1].0);
}

// Get the base address of the mapping for a GuestAddress.
fn get_mapping(mem: &GuestMemory, addr: GuestAddress) -> Result<*const u8> {
mem.do_in_region(addr, |mapping, _| Ok(mapping.as_ptr() as *const u8))
}

#[test]
fn guest_to_host() {
let start_addr1 = GuestAddress(0x0);
let start_addr2 = GuestAddress(0x100);
let mem = GuestMemory::new(&vec![(start_addr1, 0x100), (start_addr2, 0x400)]).unwrap();

// Verify the host addresses match what we expect from the mappings.
let addr1_base = get_mapping(&mem, start_addr1).unwrap();
let addr2_base = get_mapping(&mem, start_addr2).unwrap();
let host_addr1 = mem.get_host_address(start_addr1).unwrap();
let host_addr2 = mem.get_host_address(start_addr2).unwrap();
assert_eq!(host_addr1, addr1_base);
assert_eq!(host_addr2, addr2_base);

// Check that a bad address returns an error.
let bad_addr = GuestAddress(0x123456);
assert!(mem.get_host_address(bad_addr).is_err());
}
}

0 comments on commit 32e074f

Please sign in to comment.