virtio: Port codebase to the latest virtio-queue version

The new virtio-queue version introduced some breaking changes which need
to be addressed so that Cloud Hypervisor can still work with this
version.

The most important change is about removing a handle to the guest memory
from the Queue, meaning the caller has to provide the guest memory
handle for multiple methods from the QueueT trait.

One interesting aspect is that QueueT has been widely extended to
provide every getter and setter we need to access and update the Queue
structure without having direct access to its internal fields.

This patch ports all the virtio and vhost-user devices to this new crate
definition. It also updates both vhost-user-block and vhost-user-net
backends based on the updated vhost-user-backend crate. It also updates
the fuzz directory.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf
2022-07-06 16:08:08 +02:00
committed by Rob Bradford
parent 7199119bb2
commit a423bf13ad
41 changed files with 414 additions and 354 deletions

View File

@@ -292,7 +292,7 @@ impl VirtioDevice for Blk {
&mut self,
mem: GuestMemoryAtomic<GuestMemoryMmap>,
interrupt_cb: Arc<dyn VirtioInterrupt>,
queues: Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>,
queues: Vec<(usize, Queue, EventFd)>,
) -> ActivateResult {
self.common.activate(&queues, &interrupt_cb)?;
self.guest_memory = Some(mem.clone());

View File

@@ -504,7 +504,7 @@ impl VirtioDevice for Fs {
&mut self,
mem: GuestMemoryAtomic<GuestMemoryMmap>,
interrupt_cb: Arc<dyn VirtioInterrupt>,
queues: Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>,
queues: Vec<(usize, Queue, EventFd)>,
) -> ActivateResult {
self.common.activate(&queues, &interrupt_cb)?;
self.guest_memory = Some(mem.clone());

View File

@@ -167,7 +167,7 @@ pub struct VhostUserEpollHandler<S: VhostUserMasterReqHandler> {
pub mem: GuestMemoryAtomic<GuestMemoryMmap>,
pub kill_evt: EventFd,
pub pause_evt: EventFd,
pub queues: Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>,
pub queues: Vec<(usize, Queue, EventFd)>,
pub virtio_interrupt: Arc<dyn VirtioInterrupt>,
pub acked_features: u64,
pub acked_protocol_features: u64,
@@ -297,7 +297,7 @@ impl VhostUserCommon {
pub fn activate<T: VhostUserMasterReqHandler>(
&mut self,
mem: GuestMemoryAtomic<GuestMemoryMmap>,
queues: Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>,
queues: Vec<(usize, Queue, EventFd)>,
interrupt_cb: Arc<dyn VirtioInterrupt>,
acked_features: u64,
slave_req_handler: Option<MasterReqHandler<T>>,

View File

@@ -27,7 +27,7 @@ use virtio_bindings::bindings::virtio_net::{
VIRTIO_NET_F_MAC, VIRTIO_NET_F_MRG_RXBUF,
};
use virtio_bindings::bindings::virtio_ring::VIRTIO_RING_F_EVENT_IDX;
use virtio_queue::Queue;
use virtio_queue::{Queue, QueueT};
use vm_memory::{ByteValued, GuestMemoryAtomic};
use vm_migration::{
protocol::MemoryRangeTable, Migratable, MigratableError, Pausable, Snapshot, Snapshottable,
@@ -272,7 +272,7 @@ impl VirtioDevice for Net {
&mut self,
mem: GuestMemoryAtomic<GuestMemoryMmap>,
interrupt_cb: Arc<dyn VirtioInterrupt>,
mut queues: Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>,
mut queues: Vec<(usize, Queue, EventFd)>,
) -> ActivateResult {
self.common.activate(&queues, &interrupt_cb)?;
self.guest_memory = Some(mem.clone());
@@ -288,6 +288,7 @@ impl VirtioDevice for Net {
let (kill_evt, pause_evt) = self.common.dup_eventfds();
let mut ctrl_handler = NetCtrlEpollHandler {
mem: mem.clone(),
kill_evt,
pause_evt,
ctrl_q: CtrlQueue::new(Vec::new()),

View File

@@ -23,9 +23,9 @@ use vhost::vhost_user::message::{
};
use vhost::vhost_user::{Master, MasterReqHandler, VhostUserMaster, VhostUserMasterReqHandler};
use vhost::{VhostBackend, VhostUserDirtyLogRegion, VhostUserMemoryRegionInfo, VringConfigData};
use virtio_queue::{Descriptor, Queue};
use virtio_queue::{Descriptor, Queue, QueueT};
use vm_memory::{
Address, Error as MmapError, FileOffset, GuestMemory, GuestMemoryAtomic, GuestMemoryRegion,
Address, Error as MmapError, FileOffset, GuestAddress, GuestMemory, GuestMemoryRegion,
};
use vm_migration::protocol::MemoryRangeTable;
use vmm_sys_util::eventfd::EventFd;
@@ -152,7 +152,7 @@ impl VhostUserHandle {
pub fn setup_vhost_user<S: VhostUserMasterReqHandler>(
&mut self,
mem: &GuestMemoryMmap,
queues: Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>,
queues: Vec<(usize, Queue, EventFd)>,
virtio_interrupt: &Arc<dyn VirtioInterrupt>,
acked_features: u64,
slave_req_handler: &Option<MasterReqHandler<S>>,
@@ -173,7 +173,7 @@ impl VhostUserHandle {
// at early stage.
for (queue_index, queue, _) in queues.iter() {
self.vu
.set_vring_num(*queue_index, queue.state.size)
.set_vring_num(*queue_index, queue.size())
.map_err(Error::VhostUserSetVringNum)?;
}
@@ -184,7 +184,7 @@ impl VhostUserHandle {
mmap_size: 0,
mmap_offset: 0,
num_queues: queues.len() as u16,
queue_size: queues[0].1.state.size,
queue_size: queues[0].1.size(),
};
let (info, fd) = self
.vu
@@ -201,15 +201,15 @@ impl VhostUserHandle {
let mut vrings_info = Vec::new();
for (queue_index, queue, queue_evt) in queues.iter() {
let actual_size: usize = queue.state.size.try_into().unwrap();
let actual_size: usize = queue.size().try_into().unwrap();
let config_data = VringConfigData {
queue_max_size: queue.max_size(),
queue_size: queue.state.size,
queue_size: queue.size(),
flags: 0u32,
desc_table_addr: get_host_address_range(
mem,
queue.state.desc_table,
GuestAddress(queue.desc_table()),
actual_size * std::mem::size_of::<Descriptor>(),
)
.ok_or(Error::DescriptorTableAddress)? as u64,
@@ -217,7 +217,7 @@ impl VhostUserHandle {
// i.e. 4 + (4 + 4) * actual_size.
used_ring_addr: get_host_address_range(
mem,
queue.state.used_ring,
GuestAddress(queue.used_ring()),
4 + actual_size * 8,
)
.ok_or(Error::UsedAddress)? as u64,
@@ -225,7 +225,7 @@ impl VhostUserHandle {
// i.e. 4 + (2) * actual_size.
avail_ring_addr: get_host_address_range(
mem,
queue.state.avail_ring,
GuestAddress(queue.avail_ring()),
4 + actual_size * 2,
)
.ok_or(Error::AvailAddress)? as u64,
@@ -234,7 +234,7 @@ impl VhostUserHandle {
vrings_info.push(VringInfo {
config_data,
used_guest_addr: queue.state.used_ring.raw_value(),
used_guest_addr: queue.used_ring(),
});
self.vu
@@ -244,7 +244,7 @@ impl VhostUserHandle {
.set_vring_base(
*queue_index,
queue
.avail_idx(Ordering::Acquire)
.avail_idx(mem, Ordering::Acquire)
.map_err(Error::GetAvailableIndex)?
.0,
)
@@ -337,7 +337,7 @@ impl VhostUserHandle {
pub fn reinitialize_vhost_user<S: VhostUserMasterReqHandler>(
&mut self,
mem: &GuestMemoryMmap,
queues: Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>,
queues: Vec<(usize, Queue, EventFd)>,
virtio_interrupt: &Arc<dyn VirtioInterrupt>,
acked_features: u64,
acked_protocol_features: u64,