Skip to content

Commit 82d1a3c

Browse files
stefano-garzarellajiangliu
authored andcommitted
vdpa: add dma_map/dma_unmap functions
Add dma_map/dma_unmap functions in VhostVdpa trait and implement them in VhostKernVdpa using the IOTLB messages support provided by VhostIotlbBackend. Add also a specific test in vhost_kern/vdpa.rs. Signed-off-by: Stefano Garzarella <[email protected]>
1 parent 866932e commit 82d1a3c

File tree

2 files changed

+87
-1
lines changed

2 files changed

+87
-1
lines changed

src/vdpa.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,20 @@ pub trait VhostVdpa: VhostBackend {
6565

6666
/// Get the valid I/O virtual addresses range supported by the device.
6767
fn get_iova_range(&self) -> Result<VhostVdpaIovaRange>;
68+
69+
/// Map DMA region.
70+
///
71+
/// # Arguments
72+
/// * `iova` - I/O virtual address.
73+
/// * `size` - Size of the I/O mapping.
74+
/// * `vaddr` - Virtual address in the current process.
75+
/// * `readonly` - true if the region is read-only, false if reads and writes are allowed.
76+
fn dma_map(&self, iova: u64, size: u64, vaddr: *const u8, readonly: bool) -> Result<()>;
77+
78+
/// Unmap DMA region.
79+
///
80+
/// # Arguments
81+
/// * `iova` - I/O virtual address.
82+
/// * `size` - Size of the I/O mapping.
83+
fn dma_unmap(&self, iova: u64, size: u64) -> Result<()>;
6884
}

src/vhost_kern/vdpa.rs

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,15 @@ use std::alloc::{alloc, dealloc, Layout};
1616
use std::mem;
1717

1818
use super::vhost_binding::*;
19-
use super::{ioctl_result, Error, Result, VhostKernBackend};
19+
use super::{ioctl_result, Error, Result, VhostKernBackend, VhostKernFeatures};
2020
use crate::vdpa::*;
21+
use crate::{VhostAccess, VhostIotlbBackend, VhostIotlbMsg, VhostIotlbType};
2122

2223
/// Handle for running VHOST_VDPA ioctls.
2324
pub struct VhostKernVdpa<AS: GuestAddressSpace> {
2425
fd: File,
2526
mem: AS,
27+
backend_features_acked: u64,
2628
}
2729

2830
impl<AS: GuestAddressSpace> VhostKernVdpa<AS> {
@@ -36,6 +38,7 @@ impl<AS: GuestAddressSpace> VhostKernVdpa<AS> {
3638
.open(path)
3739
.map_err(Error::VhostOpen)?,
3840
mem,
41+
backend_features_acked: 0,
3942
})
4043
}
4144
}
@@ -140,6 +143,32 @@ impl<AS: GuestAddressSpace> VhostVdpa for VhostKernVdpa<AS> {
140143

141144
ioctl_result(ret, iova_range)
142145
}
146+
147+
fn dma_map(&self, iova: u64, size: u64, vaddr: *const u8, readonly: bool) -> Result<()> {
148+
let iotlb = VhostIotlbMsg {
149+
iova,
150+
size,
151+
userspace_addr: vaddr as u64,
152+
perm: match readonly {
153+
true => VhostAccess::ReadOnly,
154+
false => VhostAccess::ReadWrite,
155+
},
156+
msg_type: VhostIotlbType::Update,
157+
};
158+
159+
self.send_iotlb_msg(&iotlb)
160+
}
161+
162+
fn dma_unmap(&self, iova: u64, size: u64) -> Result<()> {
163+
let iotlb = VhostIotlbMsg {
164+
iova,
165+
size,
166+
msg_type: VhostIotlbType::Invalidate,
167+
..Default::default()
168+
};
169+
170+
self.send_iotlb_msg(&iotlb)
171+
}
143172
}
144173

145174
impl<AS: GuestAddressSpace> VhostKernBackend for VhostKernVdpa<AS> {
@@ -156,6 +185,16 @@ impl<AS: GuestAddressSpace> AsRawFd for VhostKernVdpa<AS> {
156185
}
157186
}
158187

188+
impl<AS: GuestAddressSpace> VhostKernFeatures for VhostKernVdpa<AS> {
189+
fn get_backend_features_acked(&self) -> u64 {
190+
self.backend_features_acked
191+
}
192+
193+
fn set_backend_features_acked(&mut self, features: u64) {
194+
self.backend_features_acked = features;
195+
}
196+
}
197+
159198
#[cfg(test)]
160199
mod tests {
161200
const VHOST_VDPA_PATH: &str = "/dev/vhost-vdpa-0";
@@ -281,4 +320,35 @@ mod tests {
281320
vdpa.set_vring_enable(0, true).unwrap();
282321
vdpa.set_vring_enable(0, false).unwrap();
283322
}
323+
324+
#[test]
325+
#[serial]
326+
fn test_vdpa_kern_dma() {
327+
let m = GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x10_0000)]).unwrap();
328+
let mut vdpa = VhostKernVdpa::new(VHOST_VDPA_PATH, &m).unwrap();
329+
330+
let features = vdpa.get_features().unwrap();
331+
// VIRTIO_F_VERSION_1 (bit 32) should be set
332+
assert_ne!(features & (1 << 32), 0);
333+
vdpa.set_features(features).unwrap();
334+
335+
let backend_features = vdpa.get_backend_features().unwrap();
336+
assert_ne!(backend_features & (1 << VHOST_BACKEND_F_IOTLB_MSG_V2), 0);
337+
vdpa.set_backend_features(backend_features).unwrap();
338+
339+
vdpa.set_owner().unwrap();
340+
341+
vdpa.dma_map(0xFFFF_0000, 0xFFFF, std::ptr::null::<u8>(), false)
342+
.unwrap_err();
343+
344+
unsafe {
345+
let layout = Layout::from_size_align(0xFFFF, 1).unwrap();
346+
let ptr = alloc(layout);
347+
348+
vdpa.dma_map(0xFFFF_0000, 0xFFFF, ptr, false).unwrap();
349+
vdpa.dma_unmap(0xFFFF_0000, 0xFFFF).unwrap();
350+
351+
dealloc(ptr, layout);
352+
};
353+
}
284354
}

0 commit comments

Comments
 (0)