virtio-devices: mark Vdpa::dma_map as unsafe

I believe that its only caller used it safely, but it is still better to
mark the code as unsafe.  Also add additional validity checks.

Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
This commit is contained in:
Demi Marie Obenour
2025-06-27 18:07:56 -04:00
committed by Rob Bradford
parent 06b76972e2
commit 8f6a6a85e0

View File

@@ -326,17 +326,28 @@ impl Vdpa {
.map_err(Error::SetStatus)
}
fn dma_map(
/// # SAFETY
///
/// `host_vaddr` must point to `size` bytes of valid memory.
unsafe fn dma_map(
&mut self,
iova: u64,
size: u64,
host_vaddr: *const u8,
readonly: bool,
) -> Result<()> {
let iova_last = iova + size - 1;
let Some(iova_last) = iova.checked_add(size) else {
return Err(Error::InvalidIovaRange(iova, u64::MAX));
};
let Some(iova_last) = iova_last.checked_sub(1) else {
return Err(Error::InvalidIovaRange(0, 0));
};
if iova < self.iova_range.first || iova_last > self.iova_range.last {
return Err(Error::InvalidIovaRange(iova, iova_last));
}
if isize::try_from(size).is_err() {
return Err(Error::InvalidIovaRange(iova, iova_last));
}
assert!(self.vhost.is_some());
self.vhost
@@ -552,16 +563,20 @@ impl<M: GuestAddressSpace + Sync + Send> ExternalDmaMapping for VdpaDmaMapping<M
"DMA map iova 0x{:x}, gpa 0x{:x}, size 0x{:x}, host_addr 0x{:x}",
iova, gpa, size, user_addr as u64
);
self.device
.lock()
.unwrap()
.dma_map(iova, size, user_addr, false)
.map_err(|e| {
io::Error::other(format!(
"failed to map memory for vDPA device, \
// SAFETY: check_range() and get_host_address() guarantee that
// user_addr points to `size` bytes of memory.
unsafe {
self.device
.lock()
.unwrap()
.dma_map(iova, size, user_addr, false)
.map_err(|e| {
io::Error::other(format!(
"failed to map memory for vDPA device, \
iova 0x{iova:x}, gpa 0x{gpa:x}, size 0x{size:x}: {e:?}"
))
})
))
})
}
}
fn unmap(&self, iova: u64, size: u64) -> std::result::Result<(), std::io::Error> {