(&self, iova: u64, gpa: u64, size: u64)
| 557 | |
| 558 | impl<M: GuestAddressSpace + Sync + Send> ExternalDmaMapping for VfioUserDmaMapping<M> { |
| 559 | fn map(&self, iova: u64, gpa: u64, size: u64) -> std::result::Result<(), std::io::Error> { |
| 560 | let mem = self.memory.memory(); |
| 561 | let guest_addr = GuestAddress(gpa); |
| 562 | let Some(region) = mem.find_region(guest_addr) else { |
| 563 | return Err(std::io::Error::other(format!( |
| 564 | "Region not found for 0x{gpa:x}" |
| 565 | ))); |
| 566 | }; |
| 567 | |
| 568 | // Check that the range fits in the region. |
| 569 | let region_offset = guest_addr |
| 570 | .checked_offset_from(region.start_addr()) |
| 571 | .ok_or_else(|| std::io::Error::other(format!("gpa 0x{gpa:x} below region start")))?; |
| 572 | let region_remaining = (region.len()) |
| 573 | .checked_sub(region_offset) |
| 574 | .ok_or_else(|| std::io::Error::other(format!("gpa 0x{gpa:x} past region end")))?; |
| 575 | if size > region_remaining { |
| 576 | return Err(std::io::Error::other(format!( |
| 577 | "DMA map (gpa 0x{gpa:x}, size 0x{size:x}) extends past region end" |
| 578 | ))); |
| 579 | } |
| 580 | |
| 581 | // Unwrap is safe as we only do vfio with shared mem with a backing file. |
| 582 | let file_offset = region.file_offset().unwrap(); |
| 583 | let offset = region_offset + file_offset.start(); |
| 584 | |
| 585 | self.client |
| 586 | .lock() |
| 587 | .unwrap() |
| 588 | .dma_map(offset, iova, size, file_offset.file().as_raw_fd()) |
| 589 | .map_err(|e| std::io::Error::other(format!("Error mapping region: {e}"))) |
| 590 | } |
| 591 | |
| 592 | fn unmap(&self, iova: u64, size: u64) -> std::result::Result<(), std::io::Error> { |
| 593 | self.client |
no test coverage detected