mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-05 18:20:34 +00:00
guest_memory: make do_in_region(..) callback take memfd offset
Useful for the udmabuf use case. The current offset used by the callback is relative to the mapping, not the absolute memfd offset. BUG=chromium:892806, b:173630595 TEST=cargo test -p vm_memory Change-Id: I57d02d016888a2d974f1f9e359375cb0941dc949 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2786289 Tested-by: kokoro <noreply+kokoro@google.com> Tested-by: Gurchetan Singh <gurchetansingh@chromium.org> Commit-Queue: Gurchetan Singh <gurchetansingh@chromium.org> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
This commit is contained in:
parent
db17478125
commit
1e9e331799
1 changed files with 20 additions and 10 deletions
|
@ -252,7 +252,7 @@ impl GuestMemory {
|
|||
|
||||
/// Madvise away the address range in the host that is associated with the given guest range.
|
||||
pub fn remove_range(&self, addr: GuestAddress, count: u64) -> Result<()> {
|
||||
self.do_in_region(addr, move |mapping, offset| {
|
||||
self.do_in_region(addr, move |mapping, offset, _| {
|
||||
mapping
|
||||
.remove_range(offset, count as usize)
|
||||
.map_err(|e| Error::MemoryAccess(addr, e))
|
||||
|
@ -303,7 +303,7 @@ impl GuestMemory {
|
|||
/// # }
|
||||
/// ```
|
||||
pub fn write_at_addr(&self, buf: &[u8], guest_addr: GuestAddress) -> Result<usize> {
|
||||
self.do_in_region(guest_addr, move |mapping, offset| {
|
||||
self.do_in_region(guest_addr, move |mapping, offset, _| {
|
||||
mapping
|
||||
.write_slice(buf, offset)
|
||||
.map_err(|e| Error::MemoryAccess(guest_addr, e))
|
||||
|
@ -362,7 +362,7 @@ impl GuestMemory {
|
|||
/// # }
|
||||
/// ```
|
||||
pub fn read_at_addr(&self, buf: &mut [u8], guest_addr: GuestAddress) -> Result<usize> {
|
||||
self.do_in_region(guest_addr, move |mapping, offset| {
|
||||
self.do_in_region(guest_addr, move |mapping, offset, _| {
|
||||
mapping
|
||||
.read_slice(buf, offset)
|
||||
.map_err(|e| Error::MemoryAccess(guest_addr, e))
|
||||
|
@ -422,7 +422,7 @@ impl GuestMemory {
|
|||
/// # }
|
||||
/// ```
|
||||
pub fn read_obj_from_addr<T: DataInit>(&self, guest_addr: GuestAddress) -> Result<T> {
|
||||
self.do_in_region(guest_addr, |mapping, offset| {
|
||||
self.do_in_region(guest_addr, |mapping, offset, _| {
|
||||
mapping
|
||||
.read_obj(offset)
|
||||
.map_err(|e| Error::MemoryAccess(guest_addr, e))
|
||||
|
@ -446,7 +446,7 @@ impl GuestMemory {
|
|||
/// # }
|
||||
/// ```
|
||||
pub fn write_obj_at_addr<T: DataInit>(&self, val: T, guest_addr: GuestAddress) -> Result<()> {
|
||||
self.do_in_region(guest_addr, move |mapping, offset| {
|
||||
self.do_in_region(guest_addr, move |mapping, offset, _| {
|
||||
mapping
|
||||
.write_obj(val, offset)
|
||||
.map_err(|e| Error::MemoryAccess(guest_addr, e))
|
||||
|
@ -543,7 +543,7 @@ impl GuestMemory {
|
|||
src: &dyn AsRawDescriptor,
|
||||
count: usize,
|
||||
) -> Result<()> {
|
||||
self.do_in_region(guest_addr, move |mapping, offset| {
|
||||
self.do_in_region(guest_addr, move |mapping, offset, _| {
|
||||
mapping
|
||||
.read_to_memory(offset, src, count)
|
||||
.map_err(|e| Error::MemoryAccess(guest_addr, e))
|
||||
|
@ -581,7 +581,7 @@ impl GuestMemory {
|
|||
dst: &dyn AsRawDescriptor,
|
||||
count: usize,
|
||||
) -> Result<()> {
|
||||
self.do_in_region(guest_addr, move |mapping, offset| {
|
||||
self.do_in_region(guest_addr, move |mapping, offset, _| {
|
||||
mapping
|
||||
.write_from_memory(offset, dst, count)
|
||||
.map_err(|e| Error::MemoryAccess(guest_addr, e))
|
||||
|
@ -609,16 +609,25 @@ impl GuestMemory {
|
|||
/// # }
|
||||
/// ```
|
||||
pub fn get_host_address(&self, guest_addr: GuestAddress) -> Result<*const u8> {
|
||||
self.do_in_region(guest_addr, |mapping, offset| {
|
||||
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().add(offset) } as *const u8)
|
||||
})
|
||||
}
|
||||
|
||||
/// Loops over all guest memory regions of `self`, and performs the callback function `F` in
|
||||
/// the target region that contains `guest_addr`. The callback function `F` takes in:
|
||||
///
|
||||
/// (i) the memory mapping associated with the target region.
|
||||
/// (ii) the relative offset from the start of the target region to `guest_addr`.
|
||||
/// (iii) the absolute offset from the start of the memory mapping to the target region.
|
||||
///
|
||||
/// If no target region is found, an error is returned. The callback function `F` may return
|
||||
/// an Ok(`T`) on success or a `GuestMemoryError` on failure.
|
||||
pub fn do_in_region<F, T>(&self, guest_addr: GuestAddress, cb: F) -> Result<T>
|
||||
where
|
||||
F: FnOnce(&MemoryMapping, usize) -> Result<T>,
|
||||
F: FnOnce(&MemoryMapping, usize, u64) -> Result<T>,
|
||||
{
|
||||
self.regions
|
||||
.iter()
|
||||
|
@ -628,6 +637,7 @@ impl GuestMemory {
|
|||
cb(
|
||||
®ion.mapping,
|
||||
guest_addr.offset_from(region.start()) as usize,
|
||||
region.memfd_offset,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
@ -800,7 +810,7 @@ mod tests {
|
|||
|
||||
// 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))
|
||||
mem.do_in_region(addr, |mapping, _, _| Ok(mapping.as_ptr() as *const u8))
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Reference in a new issue