mirror of
https://github.com/rust-vmm/vhost-device.git
synced 2025-12-29 00:41:19 +00:00
Merge pull request #184 from rust-vmm/dependabot/cargo/virtio-queue-0.5.0
build(deps): bump virtio-queue from 0.4.0 to 0.5.0
This commit is contained in:
commit
b90ec209a0
9
Cargo.lock
generated
9
Cargo.lock
generated
@ -492,9 +492,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "vhost-user-backend"
|
||||
version = "0.5.1"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ded8a9f15b09e61bb8a501d0a7a38056f4c1bd7f51cedcd41081c0e4233d5aa6"
|
||||
checksum = "558ac5ca9569fb03f518b2bdd17606809ffdc894b619b92d30df6c40c33d15f3"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
@ -513,11 +513,12 @@ checksum = "3ff512178285488516ed85f15b5d0113a7cdb89e9e8a760b269ae4f02b84bd6b"
|
||||
|
||||
[[package]]
|
||||
name = "virtio-queue"
|
||||
version = "0.4.0"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "519c0a333c871650269cba303bc108075d52a0c0d64f9b91fae61829b53725af"
|
||||
checksum = "b4f59652909f276e6edd8bf36e9f106480b2202f5f046717b3de14f1b4072a28"
|
||||
dependencies = [
|
||||
"log",
|
||||
"virtio-bindings",
|
||||
"vm-memory",
|
||||
"vmm-sys-util",
|
||||
]
|
||||
|
||||
@ -18,9 +18,9 @@ libc = ">=0.2.95"
|
||||
log = ">=0.4.6"
|
||||
thiserror = "1.0"
|
||||
vhost = { version = "0.4", features = ["vhost-user-slave"] }
|
||||
vhost-user-backend = "0.5.1"
|
||||
vhost-user-backend = "0.6.0"
|
||||
virtio-bindings = ">=0.1"
|
||||
virtio-queue = "0.4"
|
||||
virtio-queue = "0.5"
|
||||
vm-memory = ">=0.8"
|
||||
vmm-sys-util = "=0.10.0"
|
||||
|
||||
@ -28,5 +28,5 @@ vmm-sys-util = "=0.10.0"
|
||||
libgpiod = { git = "https://github.com/vireshk/libgpiod" }
|
||||
|
||||
[dev-dependencies]
|
||||
virtio-queue = { version = "0.4", features = ["test-utils"] }
|
||||
virtio-queue = { version = "0.5", features = ["test-utils"] }
|
||||
vm-memory = { version = ">=0.8.0", features = ["backend-mmap", "backend-atomic"] }
|
||||
|
||||
@ -19,10 +19,10 @@ use virtio_bindings::bindings::virtio_net::{VIRTIO_F_NOTIFY_ON_EMPTY, VIRTIO_F_V
|
||||
use virtio_bindings::bindings::virtio_ring::{
|
||||
VIRTIO_RING_F_EVENT_IDX, VIRTIO_RING_F_INDIRECT_DESC,
|
||||
};
|
||||
use virtio_queue::DescriptorChain;
|
||||
use virtio_queue::{DescriptorChain, QueueOwnedT};
|
||||
use vm_memory::{
|
||||
ByteValued, Bytes, GuestAddress, GuestMemoryAtomic, GuestMemoryLoadGuard, GuestMemoryMmap,
|
||||
Le16, Le32,
|
||||
ByteValued, Bytes, GuestAddress, GuestAddressSpace, GuestMemoryAtomic, GuestMemoryLoadGuard,
|
||||
GuestMemoryMmap, Le16, Le32,
|
||||
};
|
||||
use vmm_sys_util::epoll::EventSet;
|
||||
use vmm_sys_util::eventfd::{EventFd, EFD_NONBLOCK};
|
||||
@ -148,6 +148,7 @@ pub(crate) struct VhostUserGpioBackend<D: GpioDevice> {
|
||||
handles: Arc<RwLock<Vec<Option<JoinHandle<()>>>>>,
|
||||
event_idx: bool,
|
||||
pub(crate) exit_event: EventFd,
|
||||
mem: Option<GuestMemoryAtomic<GuestMemoryMmap>>,
|
||||
}
|
||||
|
||||
type GpioDescriptorChain = DescriptorChain<GuestMemoryLoadGuard<GuestMemoryMmap<()>>>;
|
||||
@ -163,6 +164,7 @@ impl<D: GpioDevice> VhostUserGpioBackend<D> {
|
||||
handles: Arc::new(RwLock::new(handles)),
|
||||
event_idx: false,
|
||||
exit_event: EventFd::new(EFD_NONBLOCK).map_err(|_| Error::EventFdFailed)?,
|
||||
mem: None,
|
||||
})
|
||||
}
|
||||
|
||||
@ -251,7 +253,7 @@ impl<D: GpioDevice> VhostUserGpioBackend<D> {
|
||||
let requests: Vec<_> = vring
|
||||
.get_mut()
|
||||
.get_queue_mut()
|
||||
.iter()
|
||||
.iter(self.mem.as_ref().unwrap().memory())
|
||||
.map_err(|_| Error::DescriptorNotFound)?
|
||||
.collect();
|
||||
|
||||
@ -359,7 +361,7 @@ impl<D: GpioDevice> VhostUserGpioBackend<D> {
|
||||
let requests: Vec<_> = vring
|
||||
.get_mut()
|
||||
.get_queue_mut()
|
||||
.iter()
|
||||
.iter(self.mem.as_ref().unwrap().memory())
|
||||
.map_err(|_| Error::DescriptorNotFound)?
|
||||
.collect();
|
||||
|
||||
@ -416,8 +418,9 @@ impl<D: 'static + GpioDevice + Sync + Send> VhostUserBackendMut<VringRwLock, ()>
|
||||
|
||||
fn update_memory(
|
||||
&mut self,
|
||||
_mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
||||
mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
||||
) -> VhostUserBackendResult<()> {
|
||||
self.mem = Some(mem);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -489,8 +492,8 @@ impl<D: 'static + GpioDevice + Sync + Send> VhostUserBackendMut<VringRwLock, ()>
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use virtio_queue::defs::{VIRTQ_DESC_F_NEXT, VIRTQ_DESC_F_WRITE};
|
||||
use virtio_queue::{mock::MockSplitQueue, Descriptor};
|
||||
use virtio_bindings::bindings::virtio_ring::{VRING_DESC_F_NEXT, VRING_DESC_F_WRITE};
|
||||
use virtio_queue::{mock::MockSplitQueue, Descriptor, Queue};
|
||||
use vm_memory::{Address, GuestAddress, GuestMemoryAtomic, GuestMemoryMmap};
|
||||
|
||||
use super::Error;
|
||||
@ -505,15 +508,15 @@ mod tests {
|
||||
out_hdr: R,
|
||||
response_len: u32,
|
||||
) -> GpioDescriptorChain {
|
||||
let mem = GuestMemoryMmap::<()>::from_ranges(&[(start_addr, 0x1000)]).unwrap();
|
||||
let vq = MockSplitQueue::new(&mem, 16);
|
||||
let mem = &GuestMemoryMmap::<()>::from_ranges(&[(start_addr, 0x1000)]).unwrap();
|
||||
let vq = MockSplitQueue::new(mem, 16);
|
||||
let mut next_addr = vq.desc_table().total_size() + 0x100;
|
||||
let mut index = 0;
|
||||
|
||||
let desc_out = Descriptor::new(
|
||||
next_addr,
|
||||
size_of::<R>() as u32,
|
||||
VIRTQ_DESC_F_NEXT,
|
||||
VRING_DESC_F_NEXT as u16,
|
||||
index + 1,
|
||||
);
|
||||
|
||||
@ -523,7 +526,7 @@ mod tests {
|
||||
index += 1;
|
||||
|
||||
// In response descriptor
|
||||
let desc_in = Descriptor::new(next_addr, response_len, VIRTQ_DESC_F_WRITE, 0);
|
||||
let desc_in = Descriptor::new(next_addr, response_len, VRING_DESC_F_WRITE as u16, 0);
|
||||
vq.desc_table().store(index, desc_in).unwrap();
|
||||
|
||||
// Put the descriptor index 0 in the first available ring position.
|
||||
@ -535,8 +538,9 @@ mod tests {
|
||||
.unwrap();
|
||||
|
||||
// Create descriptor chain from pre-filled memory
|
||||
vq.create_queue(GuestMemoryAtomic::<GuestMemoryMmap>::new(mem.clone()))
|
||||
.iter()
|
||||
vq.create_queue::<Queue>()
|
||||
.unwrap()
|
||||
.iter(GuestMemoryAtomic::new(mem.clone()).memory())
|
||||
.unwrap()
|
||||
.next()
|
||||
.unwrap()
|
||||
@ -580,14 +584,14 @@ mod tests {
|
||||
flags: Vec<u16>,
|
||||
len: Vec<u32>,
|
||||
) -> GpioDescriptorChain {
|
||||
let mem = GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x1000)]).unwrap();
|
||||
let vq = MockSplitQueue::new(&mem, 16);
|
||||
let mem = &GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x1000)]).unwrap();
|
||||
let vq = MockSplitQueue::new(mem, 16);
|
||||
|
||||
for (i, flag) in flags.iter().enumerate() {
|
||||
let mut f = if i == flags.len() - 1 {
|
||||
let mut f: u16 = if i == flags.len() - 1 {
|
||||
0
|
||||
} else {
|
||||
VIRTQ_DESC_F_NEXT
|
||||
VRING_DESC_F_NEXT as u16
|
||||
};
|
||||
f |= flag;
|
||||
|
||||
@ -609,8 +613,9 @@ mod tests {
|
||||
.unwrap();
|
||||
|
||||
// Create descriptor chain from pre-filled memory
|
||||
vq.create_queue(GuestMemoryAtomic::<GuestMemoryMmap>::new(mem.clone()))
|
||||
.iter()
|
||||
vq.create_queue::<Queue>()
|
||||
.unwrap()
|
||||
.iter(GuestMemoryAtomic::new(mem.clone()).memory())
|
||||
.unwrap()
|
||||
.next()
|
||||
.unwrap()
|
||||
@ -650,7 +655,7 @@ mod tests {
|
||||
let mem = GuestMemoryAtomic::new(
|
||||
GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x1000)]).unwrap(),
|
||||
);
|
||||
let vring = VringRwLock::new(mem, 0x1000);
|
||||
let vring = VringRwLock::new(mem, 0x1000).unwrap();
|
||||
|
||||
// Descriptor chain size zero, shouldn't fail
|
||||
backend
|
||||
@ -701,7 +706,7 @@ mod tests {
|
||||
let mem = GuestMemoryAtomic::new(
|
||||
GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x1000)]).unwrap(),
|
||||
);
|
||||
let vring = VringRwLock::new(mem, 0x1000);
|
||||
let vring = VringRwLock::new(mem, 0x1000).unwrap();
|
||||
|
||||
// Have only one descriptor, expected two.
|
||||
let flags: Vec<u16> = vec![0];
|
||||
@ -726,7 +731,7 @@ mod tests {
|
||||
);
|
||||
|
||||
// Write only out hdr.
|
||||
let flags: Vec<u16> = vec![VIRTQ_DESC_F_WRITE, VIRTQ_DESC_F_WRITE];
|
||||
let flags: Vec<u16> = vec![VRING_DESC_F_WRITE as u16, VRING_DESC_F_WRITE as u16];
|
||||
let len: Vec<u32> = vec![size_of::<VirtioGpioRequest>() as u32, 2];
|
||||
let desc_chain = prepare_desc_chain_dummy(None, flags, len);
|
||||
assert_eq!(
|
||||
@ -738,7 +743,7 @@ mod tests {
|
||||
|
||||
// Invalid out hdr address.
|
||||
let addr: Vec<u64> = vec![0x10000, 0];
|
||||
let flags: Vec<u16> = vec![0, VIRTQ_DESC_F_WRITE];
|
||||
let flags: Vec<u16> = vec![0, VRING_DESC_F_WRITE as u16];
|
||||
let len: Vec<u32> = vec![size_of::<VirtioGpioRequest>() as u32, 2];
|
||||
let desc_chain = prepare_desc_chain_dummy(Some(addr), flags, len);
|
||||
assert_eq!(
|
||||
@ -749,7 +754,7 @@ mod tests {
|
||||
);
|
||||
|
||||
// Invalid out hdr length.
|
||||
let flags: Vec<u16> = vec![0, VIRTQ_DESC_F_WRITE];
|
||||
let flags: Vec<u16> = vec![0, VRING_DESC_F_WRITE as u16];
|
||||
let len: Vec<u32> = vec![100, 2];
|
||||
let desc_chain = prepare_desc_chain_dummy(None, flags, len);
|
||||
assert_eq!(
|
||||
@ -772,7 +777,7 @@ mod tests {
|
||||
|
||||
// Invalid in hdr address.
|
||||
let addr: Vec<u64> = vec![0, 0x10000];
|
||||
let flags: Vec<u16> = vec![0, VIRTQ_DESC_F_WRITE];
|
||||
let flags: Vec<u16> = vec![0, VRING_DESC_F_WRITE as u16];
|
||||
let len: Vec<u32> = vec![size_of::<VirtioGpioRequest>() as u32, 2];
|
||||
let desc_chain = prepare_desc_chain_dummy(Some(addr), flags, len);
|
||||
assert_eq!(
|
||||
@ -802,7 +807,7 @@ mod tests {
|
||||
let mem = GuestMemoryAtomic::new(
|
||||
GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x1000)]).unwrap(),
|
||||
);
|
||||
let vring = VringRwLock::new(mem, 0x1000);
|
||||
let vring = VringRwLock::new(mem, 0x1000).unwrap();
|
||||
|
||||
// Descriptor chain size zero, shouldn't fail.
|
||||
backend
|
||||
@ -856,7 +861,7 @@ mod tests {
|
||||
let mem = GuestMemoryAtomic::new(
|
||||
GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x1000)]).unwrap(),
|
||||
);
|
||||
let vring = VringRwLock::new(mem, 0x1000);
|
||||
let vring = VringRwLock::new(mem, 0x1000).unwrap();
|
||||
|
||||
let desc_chains = vec![
|
||||
// Prepare line: GPIO
|
||||
@ -947,7 +952,7 @@ mod tests {
|
||||
let mem = GuestMemoryAtomic::new(
|
||||
GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x1000)]).unwrap(),
|
||||
);
|
||||
let vring = VringRwLock::new(mem, 0x1000);
|
||||
let vring = VringRwLock::new(mem, 0x1000).unwrap();
|
||||
|
||||
// Only one descriptor, expected two.
|
||||
let flags: Vec<u16> = vec![0];
|
||||
@ -972,7 +977,7 @@ mod tests {
|
||||
);
|
||||
|
||||
// Write only out hdr
|
||||
let flags: Vec<u16> = vec![VIRTQ_DESC_F_WRITE, VIRTQ_DESC_F_WRITE];
|
||||
let flags: Vec<u16> = vec![VRING_DESC_F_WRITE as u16, VRING_DESC_F_WRITE as u16];
|
||||
let len: Vec<u32> = vec![
|
||||
size_of::<VirtioGpioIrqRequest>() as u32,
|
||||
size_of::<VirtioGpioIrqResponse>() as u32,
|
||||
@ -987,7 +992,7 @@ mod tests {
|
||||
|
||||
// Invalid out hdr address
|
||||
let addr: Vec<u64> = vec![0x10000, 0];
|
||||
let flags: Vec<u16> = vec![0, VIRTQ_DESC_F_WRITE];
|
||||
let flags: Vec<u16> = vec![0, VRING_DESC_F_WRITE as u16];
|
||||
let len: Vec<u32> = vec![
|
||||
size_of::<VirtioGpioIrqRequest>() as u32,
|
||||
size_of::<VirtioGpioIrqResponse>() as u32,
|
||||
@ -1001,7 +1006,7 @@ mod tests {
|
||||
);
|
||||
|
||||
// Invalid out hdr length
|
||||
let flags: Vec<u16> = vec![0, VIRTQ_DESC_F_WRITE];
|
||||
let flags: Vec<u16> = vec![0, VRING_DESC_F_WRITE as u16];
|
||||
let len: Vec<u32> = vec![100, size_of::<VirtioGpioIrqResponse>() as u32];
|
||||
let desc_chain = prepare_desc_chain_dummy(None, flags, len);
|
||||
assert_eq!(
|
||||
@ -1026,7 +1031,7 @@ mod tests {
|
||||
);
|
||||
|
||||
// Invalid in hdr length
|
||||
let flags: Vec<u16> = vec![0, VIRTQ_DESC_F_WRITE];
|
||||
let flags: Vec<u16> = vec![0, VRING_DESC_F_WRITE as u16];
|
||||
let len: Vec<u32> = vec![size_of::<VirtioGpioIrqRequest>() as u32, 100];
|
||||
let desc_chain = prepare_desc_chain_dummy(None, flags, len);
|
||||
assert_eq!(
|
||||
@ -1037,7 +1042,7 @@ mod tests {
|
||||
);
|
||||
|
||||
// Wait for event without setting irq type first.
|
||||
let flags: Vec<u16> = vec![0, VIRTQ_DESC_F_WRITE];
|
||||
let flags: Vec<u16> = vec![0, VRING_DESC_F_WRITE as u16];
|
||||
let len: Vec<u32> = vec![
|
||||
size_of::<VirtioGpioIrqRequest>() as u32,
|
||||
size_of::<VirtioGpioIrqResponse>() as u32,
|
||||
@ -1134,8 +1139,8 @@ mod tests {
|
||||
);
|
||||
backend.update_memory(mem.clone()).unwrap();
|
||||
|
||||
let vring_request = VringRwLock::new(mem.clone(), 0x1000);
|
||||
let vring_event = VringRwLock::new(mem, 0x1000);
|
||||
let vring_request = VringRwLock::new(mem.clone(), 0x1000).unwrap();
|
||||
let vring_event = VringRwLock::new(mem, 0x1000).unwrap();
|
||||
assert_eq!(
|
||||
backend
|
||||
.handle_event(
|
||||
|
||||
@ -18,12 +18,12 @@ libc = ">=0.2.95"
|
||||
log = ">=0.4.6"
|
||||
thiserror = "1.0"
|
||||
vhost = { version = "0.4", features = ["vhost-user-slave"] }
|
||||
vhost-user-backend = "0.5.1"
|
||||
vhost-user-backend = "0.6.0"
|
||||
virtio-bindings = ">=0.1"
|
||||
virtio-queue = "0.4"
|
||||
virtio-queue = "0.5"
|
||||
vm-memory = ">=0.8"
|
||||
vmm-sys-util = "=0.10.0"
|
||||
|
||||
[dev-dependencies]
|
||||
virtio-queue = { version = "0.4", features = ["test-utils"] }
|
||||
virtio-queue = { version = "0.5", features = ["test-utils"] }
|
||||
vm-memory = { version = ">=0.8.0", features = ["backend-mmap", "backend-atomic"] }
|
||||
|
||||
@ -575,7 +575,7 @@ pub mod tests {
|
||||
use vmm_sys_util::tempfile::TempFile;
|
||||
|
||||
// Update read-buffer of each write-buffer with index + 1 value.
|
||||
pub fn update_rdwr_buf(buf: &mut Vec<u8>) {
|
||||
pub fn update_rdwr_buf(buf: &mut [u8]) {
|
||||
for (i, byte) in buf.iter_mut().enumerate() {
|
||||
*byte = i as u8 + 1;
|
||||
}
|
||||
|
||||
@ -17,9 +17,10 @@ use virtio_bindings::bindings::virtio_net::{VIRTIO_F_NOTIFY_ON_EMPTY, VIRTIO_F_V
|
||||
use virtio_bindings::bindings::virtio_ring::{
|
||||
VIRTIO_RING_F_EVENT_IDX, VIRTIO_RING_F_INDIRECT_DESC,
|
||||
};
|
||||
use virtio_queue::DescriptorChain;
|
||||
use virtio_queue::{DescriptorChain, QueueOwnedT};
|
||||
use vm_memory::{
|
||||
ByteValued, Bytes, GuestMemoryAtomic, GuestMemoryLoadGuard, GuestMemoryMmap, Le16, Le32,
|
||||
ByteValued, Bytes, GuestAddressSpace, GuestMemoryAtomic, GuestMemoryLoadGuard, GuestMemoryMmap,
|
||||
Le16, Le32,
|
||||
};
|
||||
use vmm_sys_util::epoll::EventSet;
|
||||
use vmm_sys_util::eventfd::{EventFd, EFD_NONBLOCK};
|
||||
@ -97,6 +98,7 @@ pub struct VhostUserI2cBackend<D: I2cDevice> {
|
||||
i2c_map: Arc<I2cMap<D>>,
|
||||
event_idx: bool,
|
||||
pub exit_event: EventFd,
|
||||
mem: Option<GuestMemoryAtomic<GuestMemoryMmap>>,
|
||||
}
|
||||
|
||||
type I2cDescriptorChain = DescriptorChain<GuestMemoryLoadGuard<GuestMemoryMmap<()>>>;
|
||||
@ -107,6 +109,7 @@ impl<D: I2cDevice> VhostUserI2cBackend<D> {
|
||||
i2c_map,
|
||||
event_idx: false,
|
||||
exit_event: EventFd::new(EFD_NONBLOCK).map_err(|_| Error::EventFdFailed)?,
|
||||
mem: None,
|
||||
})
|
||||
}
|
||||
|
||||
@ -252,7 +255,7 @@ impl<D: I2cDevice> VhostUserI2cBackend<D> {
|
||||
let requests: Vec<_> = vring
|
||||
.get_mut()
|
||||
.get_queue_mut()
|
||||
.iter()
|
||||
.iter(self.mem.as_ref().unwrap().memory())
|
||||
.map_err(|_| Error::DescriptorNotFound)?
|
||||
.collect();
|
||||
|
||||
@ -299,8 +302,9 @@ impl<D: 'static + I2cDevice + Sync + Send> VhostUserBackendMut<VringRwLock, ()>
|
||||
|
||||
fn update_memory(
|
||||
&mut self,
|
||||
_mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
||||
mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
||||
) -> VhostUserBackendResult<()> {
|
||||
self.mem = Some(mem);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -354,8 +358,8 @@ impl<D: 'static + I2cDevice + Sync + Send> VhostUserBackendMut<VringRwLock, ()>
|
||||
mod tests {
|
||||
use std::convert::TryFrom;
|
||||
|
||||
use virtio_queue::defs::{VIRTQ_DESC_F_NEXT, VIRTQ_DESC_F_WRITE};
|
||||
use virtio_queue::{mock::MockSplitQueue, Descriptor};
|
||||
use virtio_bindings::bindings::virtio_ring::{VRING_DESC_F_NEXT, VRING_DESC_F_WRITE};
|
||||
use virtio_queue::{mock::MockSplitQueue, Descriptor, Queue};
|
||||
use vm_memory::{Address, GuestAddress, GuestMemoryAtomic, GuestMemoryMmap};
|
||||
|
||||
use super::Error;
|
||||
@ -370,8 +374,8 @@ mod tests {
|
||||
flag: u32,
|
||||
client_addr: u16,
|
||||
) -> I2cDescriptorChain {
|
||||
let mem = GuestMemoryMmap::<()>::from_ranges(&[(start_addr, 0x1000)]).unwrap();
|
||||
let vq = MockSplitQueue::new(&mem, 16);
|
||||
let mem = &GuestMemoryMmap::<()>::from_ranges(&[(start_addr, 0x1000)]).unwrap();
|
||||
let vq = MockSplitQueue::new(mem, 16);
|
||||
let mut next_addr = vq.desc_table().total_size() + 0x100;
|
||||
let mut index = 0;
|
||||
|
||||
@ -385,7 +389,7 @@ mod tests {
|
||||
let desc_out = Descriptor::new(
|
||||
next_addr,
|
||||
size_of::<VirtioI2cOutHdr>() as u32,
|
||||
VIRTQ_DESC_F_NEXT,
|
||||
VRING_DESC_F_NEXT as u16,
|
||||
index + 1,
|
||||
);
|
||||
|
||||
@ -402,13 +406,13 @@ mod tests {
|
||||
update_rdwr_buf(buf);
|
||||
0
|
||||
} else {
|
||||
VIRTQ_DESC_F_WRITE
|
||||
VRING_DESC_F_WRITE
|
||||
};
|
||||
|
||||
let desc_buf = Descriptor::new(
|
||||
next_addr,
|
||||
buf.len() as u32,
|
||||
flag | VIRTQ_DESC_F_NEXT,
|
||||
(flag | VRING_DESC_F_NEXT) as u16,
|
||||
index + 1,
|
||||
);
|
||||
mem.write(buf, desc_buf.addr()).unwrap();
|
||||
@ -418,7 +422,12 @@ mod tests {
|
||||
}
|
||||
|
||||
// In response descriptor
|
||||
let desc_in = Descriptor::new(next_addr, size_of::<u8>() as u32, VIRTQ_DESC_F_WRITE, 0);
|
||||
let desc_in = Descriptor::new(
|
||||
next_addr,
|
||||
size_of::<u8>() as u32,
|
||||
VRING_DESC_F_WRITE as u16,
|
||||
0,
|
||||
);
|
||||
vq.desc_table().store(index, desc_in).unwrap();
|
||||
|
||||
// Put the descriptor index 0 in the first available ring position.
|
||||
@ -430,8 +439,9 @@ mod tests {
|
||||
.unwrap();
|
||||
|
||||
// Create descriptor chain from pre-filled memory
|
||||
vq.create_queue(GuestMemoryAtomic::<GuestMemoryMmap>::new(mem.clone()))
|
||||
.iter()
|
||||
vq.create_queue::<Queue>()
|
||||
.unwrap()
|
||||
.iter(GuestMemoryAtomic::new(mem.clone()).memory())
|
||||
.unwrap()
|
||||
.next()
|
||||
.unwrap()
|
||||
@ -475,14 +485,14 @@ mod tests {
|
||||
flags: Vec<u16>,
|
||||
len: Vec<u32>,
|
||||
) -> I2cDescriptorChain {
|
||||
let mem = GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x1000)]).unwrap();
|
||||
let vq = MockSplitQueue::new(&mem, 16);
|
||||
let mem = &GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x1000)]).unwrap();
|
||||
let vq = MockSplitQueue::new(mem, 16);
|
||||
|
||||
for (i, flag) in flags.iter().enumerate() {
|
||||
let mut f = if i == flags.len() - 1 {
|
||||
let mut f: u16 = if i == flags.len() - 1 {
|
||||
0
|
||||
} else {
|
||||
VIRTQ_DESC_F_NEXT
|
||||
VRING_DESC_F_NEXT as u16
|
||||
};
|
||||
f |= flag;
|
||||
|
||||
@ -491,7 +501,7 @@ mod tests {
|
||||
_ => 0x100,
|
||||
};
|
||||
|
||||
let desc = Descriptor::new(offset, len[i], f, (i + 1) as u16);
|
||||
let desc = Descriptor::new(offset, len[i], f as u16, (i + 1) as u16);
|
||||
vq.desc_table().store(i as u16, desc).unwrap();
|
||||
}
|
||||
|
||||
@ -504,8 +514,9 @@ mod tests {
|
||||
.unwrap();
|
||||
|
||||
// Create descriptor chain from pre-filled memory
|
||||
vq.create_queue(GuestMemoryAtomic::<GuestMemoryMmap>::new(mem.clone()))
|
||||
.iter()
|
||||
vq.create_queue::<Queue>()
|
||||
.unwrap()
|
||||
.iter(GuestMemoryAtomic::new(mem.clone()).memory())
|
||||
.unwrap()
|
||||
.next()
|
||||
.unwrap()
|
||||
@ -519,7 +530,7 @@ mod tests {
|
||||
let mem = GuestMemoryAtomic::new(
|
||||
GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x1000)]).unwrap(),
|
||||
);
|
||||
let vring = VringRwLock::new(mem, 0x1000);
|
||||
let vring = VringRwLock::new(mem, 0x1000).unwrap();
|
||||
|
||||
// Descriptor chain size zero, shouldn't fail
|
||||
backend
|
||||
@ -577,7 +588,7 @@ mod tests {
|
||||
let mem = GuestMemoryAtomic::new(
|
||||
GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x1000)]).unwrap(),
|
||||
);
|
||||
let vring = VringRwLock::new(mem, 0x1000);
|
||||
let vring = VringRwLock::new(mem, 0x1000).unwrap();
|
||||
|
||||
// One descriptors
|
||||
let flags: Vec<u16> = vec![0];
|
||||
@ -602,7 +613,7 @@ mod tests {
|
||||
);
|
||||
|
||||
// Write only out hdr
|
||||
let flags: Vec<u16> = vec![VIRTQ_DESC_F_WRITE, 0, VIRTQ_DESC_F_WRITE];
|
||||
let flags: Vec<u16> = vec![VRING_DESC_F_WRITE as u16, 0, VRING_DESC_F_WRITE as u16];
|
||||
let len: Vec<u32> = vec![
|
||||
size_of::<VirtioI2cOutHdr>() as u32,
|
||||
1,
|
||||
@ -617,7 +628,7 @@ mod tests {
|
||||
);
|
||||
|
||||
// Invalid out hdr length
|
||||
let flags: Vec<u16> = vec![0, 0, VIRTQ_DESC_F_WRITE];
|
||||
let flags: Vec<u16> = vec![0, 0, VRING_DESC_F_WRITE as u16];
|
||||
let len: Vec<u32> = vec![100, 1, size_of::<u8>() as u32];
|
||||
let desc_chain = prepare_desc_chain_dummy(None, flags, len);
|
||||
assert_eq!(
|
||||
@ -629,7 +640,7 @@ mod tests {
|
||||
|
||||
// Invalid out hdr address
|
||||
let addr: Vec<u64> = vec![0x10000, 0, 0];
|
||||
let flags: Vec<u16> = vec![0, 0, VIRTQ_DESC_F_WRITE];
|
||||
let flags: Vec<u16> = vec![0, 0, VRING_DESC_F_WRITE as u16];
|
||||
let len: Vec<u32> = vec![
|
||||
size_of::<VirtioI2cOutHdr>() as u32,
|
||||
1,
|
||||
@ -659,7 +670,7 @@ mod tests {
|
||||
);
|
||||
|
||||
// Invalid in hdr length
|
||||
let flags: Vec<u16> = vec![0, 0, VIRTQ_DESC_F_WRITE];
|
||||
let flags: Vec<u16> = vec![0, 0, VRING_DESC_F_WRITE as u16];
|
||||
let len: Vec<u32> = vec![size_of::<VirtioI2cOutHdr>() as u32, 1, 100];
|
||||
let desc_chain = prepare_desc_chain_dummy(None, flags, len);
|
||||
assert_eq!(
|
||||
@ -671,7 +682,7 @@ mod tests {
|
||||
|
||||
// Invalid in hdr address
|
||||
let addr: Vec<u64> = vec![0, 0, 0x10000];
|
||||
let flags: Vec<u16> = vec![0, 0, VIRTQ_DESC_F_WRITE];
|
||||
let flags: Vec<u16> = vec![0, 0, VRING_DESC_F_WRITE as u16];
|
||||
let len: Vec<u32> = vec![
|
||||
size_of::<VirtioI2cOutHdr>() as u32,
|
||||
1,
|
||||
@ -686,7 +697,7 @@ mod tests {
|
||||
);
|
||||
|
||||
// Invalid buf length
|
||||
let flags: Vec<u16> = vec![0, 0, VIRTQ_DESC_F_WRITE];
|
||||
let flags: Vec<u16> = vec![0, 0, VRING_DESC_F_WRITE as u16];
|
||||
let len: Vec<u32> = vec![
|
||||
size_of::<VirtioI2cOutHdr>() as u32,
|
||||
0,
|
||||
@ -702,7 +713,7 @@ mod tests {
|
||||
|
||||
// Invalid buf address
|
||||
let addr: Vec<u64> = vec![0, 0x10000, 0];
|
||||
let flags: Vec<u16> = vec![0, 0, VIRTQ_DESC_F_WRITE];
|
||||
let flags: Vec<u16> = vec![0, 0, VRING_DESC_F_WRITE as u16];
|
||||
let len: Vec<u32> = vec![
|
||||
size_of::<VirtioI2cOutHdr>() as u32,
|
||||
1,
|
||||
@ -717,7 +728,7 @@ mod tests {
|
||||
);
|
||||
|
||||
// Write only buf for write operation
|
||||
let flags: Vec<u16> = vec![0, VIRTQ_DESC_F_WRITE, VIRTQ_DESC_F_WRITE];
|
||||
let flags: Vec<u16> = vec![0, VRING_DESC_F_WRITE as u16, VRING_DESC_F_WRITE as u16];
|
||||
let len: Vec<u32> = vec![
|
||||
size_of::<VirtioI2cOutHdr>() as u32,
|
||||
10,
|
||||
@ -766,7 +777,7 @@ mod tests {
|
||||
);
|
||||
backend.update_memory(mem.clone()).unwrap();
|
||||
|
||||
let vring = VringRwLock::new(mem, 0x1000);
|
||||
let vring = VringRwLock::new(mem, 0x1000).unwrap();
|
||||
assert_eq!(
|
||||
backend
|
||||
.handle_event(0, EventSet::OUT, &[vring.clone()], 0)
|
||||
|
||||
@ -19,12 +19,12 @@ rand = ">=0.8.5"
|
||||
tempfile = "3.2.0"
|
||||
thiserror = "1.0"
|
||||
vhost = { version = "0.4", features = ["vhost-user-slave"] }
|
||||
vhost-user-backend = "0.5.1"
|
||||
vhost-user-backend = "0.6.0"
|
||||
virtio-bindings = ">=0.1"
|
||||
virtio-queue = "0.4"
|
||||
virtio-queue = "0.5"
|
||||
vm-memory = ">=0.8"
|
||||
vmm-sys-util = "=0.10.0"
|
||||
|
||||
[dev-dependencies]
|
||||
virtio-queue = { version = "0.4", features = ["test-utils"] }
|
||||
virtio-queue = { version = "0.5", features = ["test-utils"] }
|
||||
vm-memory = { version = ">=0.8.0", features = ["backend-mmap", "backend-atomic"] }
|
||||
|
||||
@ -19,8 +19,10 @@ use virtio_bindings::bindings::virtio_net::{VIRTIO_F_NOTIFY_ON_EMPTY, VIRTIO_F_V
|
||||
use virtio_bindings::bindings::virtio_ring::{
|
||||
VIRTIO_RING_F_EVENT_IDX, VIRTIO_RING_F_INDIRECT_DESC,
|
||||
};
|
||||
use virtio_queue::DescriptorChain;
|
||||
use vm_memory::{Bytes, GuestMemoryAtomic, GuestMemoryLoadGuard, GuestMemoryMmap};
|
||||
use virtio_queue::{DescriptorChain, QueueOwnedT};
|
||||
use vm_memory::{
|
||||
Bytes, GuestAddressSpace, GuestMemoryAtomic, GuestMemoryLoadGuard, GuestMemoryMmap,
|
||||
};
|
||||
use vmm_sys_util::epoll::EventSet;
|
||||
use vmm_sys_util::eventfd::{EventFd, EFD_NONBLOCK};
|
||||
|
||||
@ -87,6 +89,7 @@ pub struct VuRngBackend<T: Read> {
|
||||
timer: VuRngTimerConfig,
|
||||
rng_source: Arc<Mutex<T>>,
|
||||
pub exit_event: EventFd,
|
||||
mem: Option<GuestMemoryAtomic<GuestMemoryMmap>>,
|
||||
}
|
||||
|
||||
impl<T: Read> VuRngBackend<T> {
|
||||
@ -101,6 +104,7 @@ impl<T: Read> VuRngBackend<T> {
|
||||
rng_source,
|
||||
timer: VuRngTimerConfig::new(period_ms, max_bytes),
|
||||
exit_event: EventFd::new(EFD_NONBLOCK).map_err(|_| VuRngError::EventFdError)?,
|
||||
mem: None,
|
||||
})
|
||||
}
|
||||
|
||||
@ -184,7 +188,7 @@ impl<T: Read> VuRngBackend<T> {
|
||||
let requests: Vec<_> = vring
|
||||
.get_mut()
|
||||
.get_queue_mut()
|
||||
.iter()
|
||||
.iter(self.mem.as_ref().unwrap().memory())
|
||||
.map_err(|_| VuRngError::DescriptorNotFound)?
|
||||
.collect();
|
||||
|
||||
@ -228,8 +232,9 @@ impl<T: 'static + Read + Sync + Send> VhostUserBackendMut<VringRwLock, ()> for V
|
||||
|
||||
fn update_memory(
|
||||
&mut self,
|
||||
_mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
||||
mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
||||
) -> result::Result<(), io::Error> {
|
||||
self.mem = Some(mem);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -284,8 +289,8 @@ mod tests {
|
||||
use super::*;
|
||||
use std::io::{ErrorKind, Read};
|
||||
|
||||
use virtio_queue::defs::{VIRTQ_DESC_F_NEXT, VIRTQ_DESC_F_WRITE};
|
||||
use virtio_queue::{mock::MockSplitQueue, Descriptor};
|
||||
use virtio_bindings::bindings::virtio_ring::{VRING_DESC_F_NEXT, VRING_DESC_F_WRITE};
|
||||
use virtio_queue::{mock::MockSplitQueue, Descriptor, Queue};
|
||||
use vm_memory::{Address, GuestAddress, GuestMemoryAtomic, GuestMemoryMmap};
|
||||
|
||||
// Add VuRngBackend accessor to artificially manipulate internal fields
|
||||
@ -337,15 +342,15 @@ mod tests {
|
||||
}
|
||||
|
||||
fn build_desc_chain(count: u16, flags: u16) -> RngDescriptorChain {
|
||||
let mem = GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x1000)]).unwrap();
|
||||
let vq = MockSplitQueue::new(&mem, 16);
|
||||
let mem = &GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x1000)]).unwrap();
|
||||
let vq = MockSplitQueue::new(mem, 16);
|
||||
|
||||
//Create a descriptor chain with @count descriptors.
|
||||
for i in 0..count {
|
||||
let desc_flags = if i < count - 1 {
|
||||
flags | VIRTQ_DESC_F_NEXT
|
||||
flags | VRING_DESC_F_NEXT as u16
|
||||
} else {
|
||||
flags & !VIRTQ_DESC_F_NEXT
|
||||
flags & !VRING_DESC_F_NEXT as u16
|
||||
};
|
||||
|
||||
let desc = Descriptor::new((0x100 * (i + 1)) as u64, 0x200, desc_flags, i + 1);
|
||||
@ -361,8 +366,9 @@ mod tests {
|
||||
.unwrap();
|
||||
|
||||
// Create descriptor chain from pre-filled memory
|
||||
vq.create_queue(GuestMemoryAtomic::<GuestMemoryMmap>::new(mem.clone()))
|
||||
.iter()
|
||||
vq.create_queue::<Queue>()
|
||||
.unwrap()
|
||||
.iter(GuestMemoryAtomic::new(mem.clone()).memory())
|
||||
.unwrap()
|
||||
.next()
|
||||
.unwrap()
|
||||
@ -381,10 +387,10 @@ mod tests {
|
||||
);
|
||||
|
||||
// Artificial Vring
|
||||
let vring = VringRwLock::new(mem, 0x1000);
|
||||
let vring = VringRwLock::new(mem, 0x1000).unwrap();
|
||||
|
||||
// The guest driver is supposed to send us only unchained descriptors
|
||||
let desc_chain = build_desc_chain(count, VIRTQ_DESC_F_WRITE);
|
||||
let desc_chain = build_desc_chain(count, VRING_DESC_F_WRITE as u16);
|
||||
assert_eq!(
|
||||
backend
|
||||
.process_requests(vec![desc_chain], &vring)
|
||||
@ -413,7 +419,7 @@ mod tests {
|
||||
);
|
||||
|
||||
// Artificial Vring
|
||||
let vring = VringRwLock::new(mem, 0x1000);
|
||||
let vring = VringRwLock::new(mem, 0x1000).unwrap();
|
||||
|
||||
// Artificially set the period start time 5 seconds in the future
|
||||
backend.time_add(Duration::from_secs(5));
|
||||
@ -421,7 +427,7 @@ mod tests {
|
||||
// Checking for a start time in the future throws a VuRngError::UnexpectedTimerValue
|
||||
assert_eq!(
|
||||
backend
|
||||
.process_requests(vec![build_desc_chain(1, VIRTQ_DESC_F_WRITE)], &vring)
|
||||
.process_requests(vec![build_desc_chain(1, VRING_DESC_F_WRITE as u16)], &vring)
|
||||
.unwrap_err(),
|
||||
VuRngError::UnexpectedTimerValue
|
||||
);
|
||||
@ -431,7 +437,7 @@ mod tests {
|
||||
// to its maximum value.
|
||||
backend.time_sub(Duration::from_secs(10));
|
||||
assert!(backend
|
||||
.process_requests(vec![build_desc_chain(1, VIRTQ_DESC_F_WRITE)], &vring)
|
||||
.process_requests(vec![build_desc_chain(1, VRING_DESC_F_WRITE as u16)], &vring)
|
||||
.unwrap());
|
||||
|
||||
// Reset time to right now and set remaining quota to 0. This will simulate a
|
||||
@ -440,7 +446,7 @@ mod tests {
|
||||
backend.time_now();
|
||||
backend.set_quota(0);
|
||||
assert!(backend
|
||||
.process_requests(vec![build_desc_chain(1, VIRTQ_DESC_F_WRITE)], &vring)
|
||||
.process_requests(vec![build_desc_chain(1, VRING_DESC_F_WRITE as u16)], &vring)
|
||||
.unwrap());
|
||||
}
|
||||
|
||||
@ -456,12 +462,12 @@ mod tests {
|
||||
);
|
||||
|
||||
// Artificial Vring
|
||||
let vring = VringRwLock::new(mem, 0x1000);
|
||||
let vring = VringRwLock::new(mem, 0x1000).unwrap();
|
||||
|
||||
// Any type of error while reading an RNG source will throw a VuRngError::UnexpectedRngSourceError.
|
||||
assert_eq!(
|
||||
backend
|
||||
.process_requests(vec![build_desc_chain(1, VIRTQ_DESC_F_WRITE)], &vring)
|
||||
.process_requests(vec![build_desc_chain(1, VRING_DESC_F_WRITE as u16)], &vring)
|
||||
.unwrap_err(),
|
||||
VuRngError::UnexpectedRngSourceError
|
||||
);
|
||||
@ -477,8 +483,11 @@ mod tests {
|
||||
GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0), 0x1000)]).unwrap(),
|
||||
);
|
||||
|
||||
// Update memory
|
||||
backend.update_memory(mem.clone()).unwrap();
|
||||
|
||||
// Artificial Vring
|
||||
let vring = VringRwLock::new(mem, 0x1000);
|
||||
let vring = VringRwLock::new(mem, 0x1000).unwrap();
|
||||
|
||||
// Currently handles EventSet::IN only, otherwise an error is generated.
|
||||
assert_eq!(
|
||||
@ -522,7 +531,7 @@ mod tests {
|
||||
);
|
||||
|
||||
// Artificial Vring
|
||||
let vring = VringRwLock::new(mem.clone(), 0x1000);
|
||||
let vring = VringRwLock::new(mem.clone(), 0x1000).unwrap();
|
||||
|
||||
// Empty descriptor chain should be ignored
|
||||
assert!(backend
|
||||
@ -534,7 +543,7 @@ mod tests {
|
||||
// available than the capacity of the descriptor buffer.
|
||||
backend.set_quota(0x100);
|
||||
assert!(backend
|
||||
.process_requests(vec![build_desc_chain(1, VIRTQ_DESC_F_WRITE)], &vring)
|
||||
.process_requests(vec![build_desc_chain(1, VRING_DESC_F_WRITE as u16)], &vring)
|
||||
.unwrap());
|
||||
|
||||
assert_eq!(backend.num_queues(), NUM_QUEUES);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user