MCPcopy Create free account
hub / github.com/cloud-hypervisor/cloud-hypervisor / find_user_address

Method find_user_address

pci/src/vfio.rs:324–357  ·  view source on GitHub ↗

Locate the user region address for a guest address within all mmio regions

(&self, guest_addr: u64, size: u64)

Source from the content-addressed store, hash-verified

322
323 // Locate the user region address for a guest address within all mmio regions
324 fn find_user_address(&self, guest_addr: u64, size: u64) -> Result<*mut u8, io::Error> {
325 for region in self.iter() {
326 for user_region in region.user_memory_regions.iter() {
327 let mapping: &MmapRegion = &user_region.mapping;
328 let start: u64 = user_region.start;
329 let len: u64 = mapping.len().try_into().unwrap();
330 // See if the guest address is inside the region.
331 let Some(offset_from_start) = guest_addr.checked_sub(start) else {
332 continue;
333 };
334 if offset_from_start >= len {
335 continue;
336 }
337 // Check that the size is in bounds.
338 // This enforces the invariant promised by implementing MmioRegionRange.
339 assert!(
340 size <= len - offset_from_start,
341 "Attempt to read {size} bytes at offset {offset_from_start} into \
342a region of size {len}"
343 );
344 // SAFETY: MmapRegion guarantees that mapping.addr points to at least
345 // mapping.len() bytes of valid memory. offset_from_start is equal
346 // to guest_addr - start, which was checked to be less than mapping.len().
347 // Therefore, the returned pointer is still in the range of valid memory.
348 // Also, since mapping.len() fit in usize, offset_from_start must as well,
349 // so the cast is safe.
350 return Ok(unsafe { mapping.addr().add(offset_from_start as usize) });
351 }
352 }
353
354 Err(io::Error::other(format!(
355 "unable to find user address: 0x{guest_addr:x}"
356 )))
357 }
358}
359
360#[derive(Debug, Error)]

Callers 1

mapMethod · 0.80

Calls 5

iterMethod · 0.80
try_intoMethod · 0.80
addMethod · 0.80
lenMethod · 0.45
addrMethod · 0.45

Tested by

no test coverage detected