From 31154ea0da7c7a716b388bccc3b08af58e9009bb Mon Sep 17 00:00:00 2001 From: Erik Schilling Date: Fri, 29 Sep 2023 09:26:47 +0200 Subject: [PATCH] Update vhost-user-backend to 0.11 series - Features were renamed from slave -> backend - Generics got simplified - Some write and read functions on Volatile slice got turned into standalone traits: ReadVolatile, WriteVolatile - handle_event no longer returns a bool Signed-off-by: Erik Schilling --- Cargo.lock | 24 ++++----- staging/Cargo.lock | 24 ++++----- staging/vhost-device-sound/Cargo.toml | 12 ++--- staging/vhost-device-sound/src/device.rs | 34 ++++++------ staging/vhost-device-video/Cargo.toml | 12 ++--- staging/vhost-device-video/src/vhu_video.rs | 10 ++-- .../src/vhu_video_thread.rs | 7 +-- vhost-device-gpio/Cargo.toml | 12 ++--- vhost-device-gpio/src/vhu_gpio.rs | 11 ++-- vhost-device-i2c/Cargo.toml | 12 ++--- vhost-device-i2c/src/vhu_i2c.rs | 11 ++-- vhost-device-rng/Cargo.toml | 12 ++--- vhost-device-rng/src/vhu_rng.rs | 38 ++++++++------ vhost-device-scmi/Cargo.toml | 10 ++-- vhost-device-scmi/src/vhu_scmi.rs | 9 ++-- vhost-device-scsi/Cargo.toml | 8 +-- vhost-device-scsi/src/vhu_scsi.rs | 9 ++-- vhost-device-vsock/Cargo.toml | 12 ++--- vhost-device-vsock/src/vhu_vsock.rs | 15 +++--- vhost-device-vsock/src/vhu_vsock_thread.rs | 5 +- vhost-device-vsock/src/vsock_conn.rs | 52 ++++++++++++++++--- 21 files changed, 196 insertions(+), 143 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7a18de0..1d39656 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -853,11 +853,11 @@ checksum = "1c18c859eead79d8b95d09e4678566e8d70105c4e7b251f707a03df32442661b" [[package]] name = "vhost" -version = "0.8.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61957aeb36daf0b00b87fff9c10dd28a161bd35ab157553d340d183b3d8756e6" +checksum = "289adfce099c71f8310f895932ccd978f352ca494ea47496dbe20d4241888b82" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.1", "libc", "vm-memory", "vmm-sys-util", @@ -985,9 +985,9 @@ dependencies = [ [[package]] name = "vhost-user-backend" -version = "0.10.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab069cdedaf18a0673766eb0a07a0f4ee3ed1b8e17fbfe4aafe5b988e2de1d01" +checksum = "61255322e3ebe93fb77d9f6d99577eca7089bbea4174076c5353a8024a463061" dependencies = [ "libc", "log", @@ -1006,9 +1006,9 @@ checksum = "878bcb1b2812a10c30d53b0ed054999de3d98f25ece91fc173973f9c57aaae86" [[package]] name = "virtio-queue" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35aca00da06841bd99162c381ec65893cace23ca0fb89254302cfe4bec4c300f" +checksum = "73a01db2cfb6c4b9bc20608b1336263d16714ea8db05de9fec2a254e076f9385" dependencies = [ "log", "virtio-bindings", @@ -1018,9 +1018,9 @@ dependencies = [ [[package]] name = "virtio-vsock" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c92d1d0c0db339e03dc275e86e5de2654ed94b351f02d405a3a0260dfc1b839f" +checksum = "22d55181677c3b7574a8e9f2f0f24b66912ffebd07953f42e42447aa0fd9b066" dependencies = [ "virtio-bindings", "virtio-queue", @@ -1029,12 +1029,12 @@ dependencies = [ [[package]] name = "vm-memory" -version = "0.12.2" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dc276f0d00c17b9aeb584da0f1e1c673df0d183cc2539e3636ec8cbc5eae99b" +checksum = "5376c9ee5ebe2103a310d8241936cfb93c946734b0479a4fa5bdf7a64abbacd8" dependencies = [ "arc-swap", - "bitflags 1.3.2", + "bitflags 2.4.1", "libc", "thiserror", "vmm-sys-util", diff --git a/staging/Cargo.lock b/staging/Cargo.lock index b44a82b..ee7af34 100644 --- a/staging/Cargo.lock +++ b/staging/Cargo.lock @@ -1012,11 +1012,11 @@ checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29" [[package]] name = "vhost" -version = "0.8.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61957aeb36daf0b00b87fff9c10dd28a161bd35ab157553d340d183b3d8756e6" +checksum = "289adfce099c71f8310f895932ccd978f352ca494ea47496dbe20d4241888b82" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.1", "libc", "vm-memory", "vmm-sys-util", @@ -1069,9 +1069,9 @@ dependencies = [ [[package]] name = "vhost-user-backend" -version = "0.10.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab069cdedaf18a0673766eb0a07a0f4ee3ed1b8e17fbfe4aafe5b988e2de1d01" +checksum = "61255322e3ebe93fb77d9f6d99577eca7089bbea4174076c5353a8024a463061" dependencies = [ "libc", "log", @@ -1084,15 +1084,15 @@ dependencies = [ [[package]] name = "virtio-bindings" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c18d7b74098a946470ea265b5bacbbf877abc3373021388454de0d47735a5b98" +checksum = "878bcb1b2812a10c30d53b0ed054999de3d98f25ece91fc173973f9c57aaae86" [[package]] name = "virtio-queue" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35aca00da06841bd99162c381ec65893cace23ca0fb89254302cfe4bec4c300f" +checksum = "73a01db2cfb6c4b9bc20608b1336263d16714ea8db05de9fec2a254e076f9385" dependencies = [ "log", "virtio-bindings", @@ -1102,12 +1102,12 @@ dependencies = [ [[package]] name = "vm-memory" -version = "0.12.2" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dc276f0d00c17b9aeb584da0f1e1c673df0d183cc2539e3636ec8cbc5eae99b" +checksum = "5376c9ee5ebe2103a310d8241936cfb93c946734b0479a4fa5bdf7a64abbacd8" dependencies = [ "arc-swap", - "bitflags 1.3.2", + "bitflags 2.4.1", "libc", "thiserror", "vmm-sys-util", diff --git a/staging/vhost-device-sound/Cargo.toml b/staging/vhost-device-sound/Cargo.toml index eb4c87e..02dcbf1 100644 --- a/staging/vhost-device-sound/Cargo.toml +++ b/staging/vhost-device-sound/Cargo.toml @@ -23,15 +23,15 @@ env_logger = "0.10" log = "0.4" pw = { package = "pipewire", git = "https://gitlab.freedesktop.org/pipewire/pipewire-rs.git", rev = "5fe090b3ac8f6fed756c4871ac18f26edda3ac89", optional = true } thiserror = "1.0" -vhost = { version = "0.8", features = ["vhost-user-slave"] } -vhost-user-backend = "0.10" +vhost = { version = "0.9", features = ["vhost-user-backend"] } +vhost-user-backend = "0.11" virtio-bindings = "0.2.1" -virtio-queue = "0.9" -vm-memory = "0.12" +virtio-queue = "0.10" +vm-memory = "0.13.1" vmm-sys-util = "0.11" [dev-dependencies] rstest = "0.18.2" tempfile = "3.5" -virtio-queue = { version = "0.9", features = ["test-utils"] } -vm-memory = { version = "0.12", features = ["backend-mmap", "backend-atomic"] } +virtio-queue = { version = "0.10", features = ["test-utils"] } +vm-memory = { version = "0.13.1", features = ["backend-mmap", "backend-atomic"] } diff --git a/staging/vhost-device-sound/src/device.rs b/staging/vhost-device-sound/src/device.rs index 0e3b609..5dff291 100644 --- a/staging/vhost-device-sound/src/device.rs +++ b/staging/vhost-device-sound/src/device.rs @@ -90,7 +90,7 @@ impl VhostUserSoundThread { device_event: u16, vrings: &[VringRwLock], audio_backend: &RwLock>, - ) -> IoResult { + ) -> IoResult<()> { let vring = &vrings[device_event as usize]; let queue_idx = self.queue_indexes[device_event as usize]; if self.event_idx { @@ -121,7 +121,7 @@ impl VhostUserSoundThread { _ => Err(Error::HandleUnknownEvent.into()), }?; } - Ok(false) + Ok(()) } #[allow(clippy::cognitive_complexity)] @@ -697,7 +697,10 @@ impl VhostUserSoundBackend { } } -impl VhostUserBackend for VhostUserSoundBackend { +impl VhostUserBackend for VhostUserSoundBackend { + type Vring = VringRwLock; + type Bitmap = (); + fn num_queues(&self) -> usize { NUM_QUEUES as usize } @@ -742,7 +745,7 @@ impl VhostUserBackend for VhostUserSoundBackend { evset: EventSet, vrings: &[VringRwLock], thread_id: usize, - ) -> IoResult { + ) -> IoResult<()> { if evset != EventSet::IN { return Err(Error::HandleEventNotEpollIn.into()); } @@ -1110,17 +1113,18 @@ mod tests { assert!(exit.is_some()); exit.unwrap().write(1).unwrap(); - let ret = backend.handle_event(CONTROL_QUEUE_IDX, EventSet::IN, &vrings, 0); - assert!(!ret.unwrap()); - - let ret = backend.handle_event(EVENT_QUEUE_IDX, EventSet::IN, &vrings, 0); - assert!(!ret.unwrap()); - - let ret = backend.handle_event(TX_QUEUE_IDX, EventSet::IN, &vrings, 0); - assert!(!ret.unwrap()); - - let ret = backend.handle_event(RX_QUEUE_IDX, EventSet::IN, &vrings, 0); - assert!(!ret.unwrap()); + backend + .handle_event(CONTROL_QUEUE_IDX, EventSet::IN, &vrings, 0) + .unwrap(); + backend + .handle_event(EVENT_QUEUE_IDX, EventSet::IN, &vrings, 0) + .unwrap(); + backend + .handle_event(TX_QUEUE_IDX, EventSet::IN, &vrings, 0) + .unwrap(); + backend + .handle_event(RX_QUEUE_IDX, EventSet::IN, &vrings, 0) + .unwrap(); test_dir.close().unwrap(); } diff --git a/staging/vhost-device-video/Cargo.toml b/staging/vhost-device-video/Cargo.toml index 80de152..df6d65e 100644 --- a/staging/vhost-device-video/Cargo.toml +++ b/staging/vhost-device-video/Cargo.toml @@ -26,11 +26,11 @@ log = "0.4" libc = "0.2.147" thiserror = "1.0" futures-executor = { version = "0.3", features = ["thread-pool"] } -vhost = { version = "0.8", features = ["vhost-user-slave"] } -vhost-user-backend = "0.10" +vhost = { version = "0.9", features = ["vhost-user-backend"] } +vhost-user-backend = "0.11" virtio-bindings = "0.2.1" -virtio-queue = "0.9" -vm-memory = "0.12" +virtio-queue = "0.10" +vm-memory = "0.13.1" vmm-sys-util = "0.11" v4l2r = { git = "https://github.com/Gnurou/v4l2r", rev = "110fd77", optional = true } @@ -38,5 +38,5 @@ v4l2r = { git = "https://github.com/Gnurou/v4l2r", rev = "110fd77", optional = assert_matches = "1.5" rstest = "0.18.2" tempfile = "3.8.0" -virtio-queue = { version = "0.9", features = ["test-utils"] } -vm-memory = { version = "0.12", features = ["backend-mmap", "backend-atomic"] } +virtio-queue = { version = "0.10", features = ["test-utils"] } +vm-memory = { version = "0.13.1", features = ["backend-mmap", "backend-atomic"] } diff --git a/staging/vhost-device-video/src/vhu_video.rs b/staging/vhost-device-video/src/vhu_video.rs index fbf2966..98903a2 100644 --- a/staging/vhost-device-video/src/vhu_video.rs +++ b/staging/vhost-device-video/src/vhu_video.rs @@ -151,7 +151,10 @@ impl VuVideoBackend { } /// VhostUserBackend trait methods -impl VhostUserBackendMut for VuVideoBackend { +impl VhostUserBackendMut for VuVideoBackend { + type Vring = VringRwLock; + type Bitmap = (); + fn num_queues(&self) -> usize { NUM_QUEUES } @@ -194,7 +197,7 @@ impl VhostUserBackendMut for VuVideoBackend { evset: EventSet, vrings: &[VringRwLock], thread_id: usize, - ) -> IoResult { + ) -> IoResult<()> { if evset != EventSet::IN { return Err(VuVideoError::HandleEventNotEpollIn.into()); } @@ -240,7 +243,7 @@ impl VhostUserBackendMut for VuVideoBackend { return Err(VuVideoError::HandleUnknownEvent.into()); } } - Ok(false) + Ok(()) } fn get_config(&self, _offset: u32, _size: u32) -> Vec { @@ -349,7 +352,6 @@ pub mod tests { } let ret = backend.handle_event(queue, EventSet::IN, &vrings, 0); assert!(ret.is_ok()); - assert!(!ret.unwrap()); } } diff --git a/staging/vhost-device-video/src/vhu_video_thread.rs b/staging/vhost-device-video/src/vhu_video_thread.rs index 3d321bd..96018d4 100644 --- a/staging/vhost-device-video/src/vhu_video_thread.rs +++ b/staging/vhost-device-video/src/vhu_video_thread.rs @@ -190,7 +190,7 @@ pub(crate) struct VhostUserVideoThread { /// VIRTIO_RING_F_EVENT_IDX. pub event_idx: bool, poller: VideoPoller, - vring_worker: Option>>, + vring_worker: Option>>, backend: Arc>>, /// Thread pool to handle async commands. pool: ThreadPool, @@ -233,10 +233,7 @@ impl VhostUserVideoThread { }) } - pub fn set_vring_workers( - &mut self, - vring_worker: Arc>, - ) { + pub fn set_vring_workers(&mut self, vring_worker: Arc>) { self.vring_worker = Some(vring_worker); self.vring_worker .as_ref() diff --git a/vhost-device-gpio/Cargo.toml b/vhost-device-gpio/Cargo.toml index ea0e4cd..d23bcb6 100644 --- a/vhost-device-gpio/Cargo.toml +++ b/vhost-device-gpio/Cargo.toml @@ -21,11 +21,11 @@ env_logger = "0.10" libc = "0.2" log = "0.4" thiserror = "1.0" -vhost = { version = "0.8", features = ["vhost-user-slave"] } -vhost-user-backend = "0.10" +vhost = { version = "0.9", features = ["vhost-user-backend"] } +vhost-user-backend = "0.11" virtio-bindings = "0.2.2" -virtio-queue = "0.9" -vm-memory = "0.12" +virtio-queue = "0.10" +vm-memory = "0.13.1" vmm-sys-util = "0.11" [target.'cfg(target_env = "gnu")'.dependencies] @@ -33,5 +33,5 @@ libgpiod = "0.2" [dev-dependencies] assert_matches = "1.5" -virtio-queue = { version = "0.9", features = ["test-utils"] } -vm-memory = { version = "0.12", features = ["backend-mmap", "backend-atomic"] } +virtio-queue = { version = "0.10", features = ["test-utils"] } +vm-memory = { version = "0.13.1", features = ["backend-mmap", "backend-atomic"] } diff --git a/vhost-device-gpio/src/vhu_gpio.rs b/vhost-device-gpio/src/vhu_gpio.rs index 3086b39..c294e6f 100644 --- a/vhost-device-gpio/src/vhu_gpio.rs +++ b/vhost-device-gpio/src/vhu_gpio.rs @@ -380,9 +380,10 @@ impl VhostUserGpioBackend { } /// VhostUserBackendMut trait methods -impl VhostUserBackendMut - for VhostUserGpioBackend -{ +impl VhostUserBackendMut for VhostUserGpioBackend { + type Vring = VringRwLock; + type Bitmap = (); + fn num_queues(&self) -> usize { NUM_QUEUES } @@ -438,7 +439,7 @@ impl VhostUserBackendMut evset: EventSet, vrings: &[VringRwLock], _thread_id: usize, - ) -> IoResult { + ) -> IoResult<()> { if evset != EventSet::IN { return Err(Error::HandleEventNotEpollIn.into()); } @@ -490,7 +491,7 @@ impl VhostUserBackendMut return Err(Error::HandleEventUnknown.into()); } } - Ok(false) + Ok(()) } fn exit_event(&self, _thread_index: usize) -> Option { diff --git a/vhost-device-i2c/Cargo.toml b/vhost-device-i2c/Cargo.toml index 599f217..0d03705 100644 --- a/vhost-device-i2c/Cargo.toml +++ b/vhost-device-i2c/Cargo.toml @@ -20,14 +20,14 @@ env_logger = "0.10" libc = "0.2" log = "0.4" thiserror = "1.0" -vhost = { version = "0.8", features = ["vhost-user-slave"] } -vhost-user-backend = "0.10" +vhost = { version = "0.9", features = ["vhost-user-backend"] } +vhost-user-backend = "0.11" virtio-bindings = "0.2.2" -virtio-queue = "0.9" -vm-memory = "0.12" +virtio-queue = "0.10" +vm-memory = "0.13.1" vmm-sys-util = "0.11" [dev-dependencies] assert_matches = "1.5" -virtio-queue = { version = "0.9", features = ["test-utils"] } -vm-memory = { version = "0.12", features = ["backend-mmap", "backend-atomic"] } +virtio-queue = { version = "0.10", features = ["test-utils"] } +vm-memory = { version = "0.13.1", features = ["backend-mmap", "backend-atomic"] } diff --git a/vhost-device-i2c/src/vhu_i2c.rs b/vhost-device-i2c/src/vhu_i2c.rs index 995c261..26dd013 100644 --- a/vhost-device-i2c/src/vhu_i2c.rs +++ b/vhost-device-i2c/src/vhu_i2c.rs @@ -277,9 +277,10 @@ impl VhostUserI2cBackend { } /// VhostUserBackendMut trait methods -impl VhostUserBackendMut - for VhostUserI2cBackend -{ +impl VhostUserBackendMut for VhostUserI2cBackend { + type Vring = VringRwLock; + type Bitmap = (); + fn num_queues(&self) -> usize { NUM_QUEUES } @@ -317,7 +318,7 @@ impl VhostUserBackendMut evset: EventSet, vrings: &[VringRwLock], _thread_id: usize, - ) -> IoResult { + ) -> IoResult<()> { if evset != EventSet::IN { return Err(Error::HandleEventNotEpollIn.into()); } @@ -349,7 +350,7 @@ impl VhostUserBackendMut return Err(Error::HandleEventUnknown.into()); } } - Ok(false) + Ok(()) } fn exit_event(&self, _thread_index: usize) -> Option { diff --git a/vhost-device-rng/Cargo.toml b/vhost-device-rng/Cargo.toml index 89ae4d9..2842318 100644 --- a/vhost-device-rng/Cargo.toml +++ b/vhost-device-rng/Cargo.toml @@ -21,14 +21,14 @@ log = "0.4" rand = "0.8.5" tempfile = "3.5" thiserror = "1.0" -vhost = { version = "0.8", features = ["vhost-user-slave"] } -vhost-user-backend = "0.10" +vhost = { version = "0.9", features = ["vhost-user-backend"] } +vhost-user-backend = "0.11" virtio-bindings = "0.2.2" -virtio-queue = "0.9" -vm-memory = "0.12" +virtio-queue = "0.10" +vm-memory = "0.13.1" vmm-sys-util = "0.11" [dev-dependencies] assert_matches = "1.5" -virtio-queue = { version = "0.9", features = ["test-utils"] } -vm-memory = { version = "0.12", features = ["backend-mmap", "backend-atomic"] } +virtio-queue = { version = "0.10", features = ["test-utils"] } +vm-memory = { version = "0.13", features = ["backend-mmap", "backend-atomic"] } diff --git a/vhost-device-rng/src/vhu_rng.rs b/vhost-device-rng/src/vhu_rng.rs index 66ba24e..afd9f5e 100644 --- a/vhost-device-rng/src/vhu_rng.rs +++ b/vhost-device-rng/src/vhu_rng.rs @@ -6,7 +6,6 @@ // SPDX-License-Identifier: Apache-2.0 or BSD-3-Clause use log::warn; -use std::io::Read; use std::sync::{Arc, Mutex}; use std::thread::sleep; use std::time::{Duration, Instant}; @@ -21,7 +20,8 @@ use virtio_bindings::bindings::virtio_ring::{ }; use virtio_queue::{DescriptorChain, QueueOwnedT}; use vm_memory::{ - Bytes, GuestAddressSpace, GuestMemoryAtomic, GuestMemoryLoadGuard, GuestMemoryMmap, + GuestAddressSpace, GuestMemory, GuestMemoryAtomic, GuestMemoryLoadGuard, GuestMemoryMmap, + ReadVolatile, }; use vmm_sys_util::epoll::EventSet; use vmm_sys_util::eventfd::{EventFd, EFD_NONBLOCK}; @@ -82,7 +82,7 @@ impl VuRngTimerConfig { } } -pub(crate) struct VuRngBackend { +pub(crate) struct VuRngBackend { event_idx: bool, timer: VuRngTimerConfig, rng_source: Arc>, @@ -90,7 +90,7 @@ pub(crate) struct VuRngBackend { mem: Option>, } -impl VuRngBackend { +impl VuRngBackend { /// Create a new virtio rng device that gets random data from /dev/urandom. pub fn new( rng_source: Arc>, @@ -169,7 +169,7 @@ impl VuRngBackend { let len = desc_chain .memory() - .read_from(descriptor.addr(), &mut *rng_source, to_read) + .read_volatile_from(descriptor.addr(), &mut *rng_source, to_read) .map_err(|_| VuRngError::UnexpectedRngSourceError)?; timer.quota_remaining -= len; @@ -202,7 +202,10 @@ impl VuRngBackend { } /// VhostUserBackend trait methods -impl VhostUserBackendMut for VuRngBackend { +impl VhostUserBackendMut for VuRngBackend { + type Vring = VringRwLock; + type Bitmap = (); + fn num_queues(&self) -> usize { NUM_QUEUES } @@ -242,7 +245,7 @@ impl VhostUserBackendMut for V evset: EventSet, vrings: &[VringRwLock], _thread_id: usize, - ) -> result::Result { + ) -> result::Result<(), io::Error> { if evset != EventSet::IN { return Err(VuRngError::HandleEventNotEpollIn.into()); } @@ -274,7 +277,7 @@ impl VhostUserBackendMut for V return Err(VuRngError::HandleEventUnknownEvent.into()); } } - Ok(false) + Ok(()) } fn exit_event(&self, _thread_index: usize) -> Option { @@ -285,14 +288,14 @@ impl VhostUserBackendMut for V #[cfg(test)] mod tests { use super::*; - use std::io::{ErrorKind, Read}; + use std::io::ErrorKind; 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 vm_memory::{Address, Bytes, GuestAddress, GuestMemoryAtomic, GuestMemoryMmap}; // Add VuRngBackend accessor to artificially manipulate internal fields - impl VuRngBackend { + impl VuRngBackend { // For testing purposes modify time synthetically pub(crate) fn time_add(&mut self, duration: Duration) { if let Some(t) = self.timer.period_start.checked_add(duration) { @@ -327,12 +330,17 @@ mod tests { } } - impl Read for MockRng { - fn read(&mut self, buf: &mut [u8]) -> std::io::Result { + impl ReadVolatile for MockRng { + fn read_volatile( + &mut self, + buf: &mut vm_memory::VolatileSlice, + ) -> result::Result { match self.permission_denied { - true => Err(std::io::Error::from(ErrorKind::PermissionDenied)), + true => Err(vm_memory::VolatileMemoryError::IOError( + std::io::Error::from(ErrorKind::PermissionDenied), + )), false => { - buf[0] = rand::random::(); + buf.write_obj(rand::random::(), 0)?; Ok(1) } } diff --git a/vhost-device-scmi/Cargo.toml b/vhost-device-scmi/Cargo.toml index 914ab14..8e6930b 100644 --- a/vhost-device-scmi/Cargo.toml +++ b/vhost-device-scmi/Cargo.toml @@ -15,13 +15,13 @@ env_logger = "0.10" itertools = "0.11" log = "0.4" thiserror = "1.0" -vhost = { version = "0.8", features = ["vhost-user-slave"] } -vhost-user-backend = "0.10" +vhost = { version = "0.9", features = ["vhost-user-backend"] } +vhost-user-backend = "0.11" virtio-bindings = "0.2" -virtio-queue = "0.9" -vm-memory = "0.12" +virtio-queue = "0.10" +vm-memory = "0.13.1" vmm-sys-util = "0.11" [dev-dependencies] assert_matches = "1.5" -virtio-queue = { version = "0.9", features = ["test-utils"] } +virtio-queue = { version = "0.10", features = ["test-utils"] } diff --git a/vhost-device-scmi/src/vhu_scmi.rs b/vhost-device-scmi/src/vhu_scmi.rs index 856a1b1..b2e674a 100644 --- a/vhost-device-scmi/src/vhu_scmi.rs +++ b/vhost-device-scmi/src/vhu_scmi.rs @@ -329,7 +329,10 @@ impl VuScmiBackend { } /// VhostUserBackend trait methods -impl VhostUserBackendMut for VuScmiBackend { +impl VhostUserBackendMut for VuScmiBackend { + type Vring = VringRwLock; + type Bitmap = (); + fn num_queues(&self) -> usize { debug!("Num queues called"); NUM_QUEUES @@ -372,7 +375,7 @@ impl VhostUserBackendMut for VuScmiBackend { evset: EventSet, vrings: &[VringRwLock], _thread_id: usize, - ) -> IoResult { + ) -> IoResult<()> { debug!("Handle event called"); if evset != EventSet::IN { warn!("Non-input event"); @@ -428,7 +431,7 @@ impl VhostUserBackendMut for VuScmiBackend { } } debug!("Handle event finished"); - Ok(false) + Ok(()) } fn exit_event(&self, _thread_index: usize) -> Option { diff --git a/vhost-device-scsi/Cargo.toml b/vhost-device-scsi/Cargo.toml index 4036429..8dad2b9 100644 --- a/vhost-device-scsi/Cargo.toml +++ b/vhost-device-scsi/Cargo.toml @@ -21,11 +21,11 @@ epoll = "4.3" log = "0.4" num_enum = "0.7" thiserror = "1.0" -vhost = { version = "0.8", features = ["vhost-user-slave"] } -vhost-user-backend = "0.10" +vhost = { version = "0.9", features = ["vhost-user-backend"] } +vhost-user-backend = "0.11" virtio-bindings = "0.2.2" -virtio-queue = "0.9" -vm-memory = "0.12" +virtio-queue = "0.10" +vm-memory = "0.13.1" vmm-sys-util = "0.11" [dev-dependencies] diff --git a/vhost-device-scsi/src/vhu_scsi.rs b/vhost-device-scsi/src/vhu_scsi.rs index 8567654..6693693 100644 --- a/vhost-device-scsi/src/vhu_scsi.rs +++ b/vhost-device-scsi/src/vhu_scsi.rs @@ -195,7 +195,10 @@ impl VhostUserScsiBackend { } } -impl VhostUserBackendMut for VhostUserScsiBackend { +impl VhostUserBackendMut for VhostUserScsiBackend { + type Vring = VringRwLock; + type Bitmap = (); + fn num_queues(&self) -> usize { // control + event + request queues let num_request_queues = 1; @@ -237,7 +240,7 @@ impl VhostUserBackendMut for VhostUserScsiBackend { evset: EventSet, vrings: &[VringRwLock], thread_id: usize, - ) -> io::Result { + ) -> io::Result<()> { assert!(evset == EventSet::IN); assert!(vrings.len() == 3); assert!((device_event as usize) < vrings.len()); @@ -268,7 +271,7 @@ impl VhostUserBackendMut for VhostUserScsiBackend { } } - Ok(false) + Ok(()) } fn get_config(&self, offset: u32, size: u32) -> Vec { diff --git a/vhost-device-vsock/Cargo.toml b/vhost-device-vsock/Cargo.toml index 244e6e5..1c873b7 100644 --- a/vhost-device-vsock/Cargo.toml +++ b/vhost-device-vsock/Cargo.toml @@ -19,12 +19,12 @@ env_logger = "0.10" epoll = "4.3.2" log = "0.4" thiserror = "1.0" -vhost = { version = "0.8", features = ["vhost-user-slave"] } -vhost-user-backend = "0.10" +vhost = { version = "0.9", features = ["vhost-user-backend"] } +vhost-user-backend = "0.11" virtio-bindings = "0.2.2" -virtio-queue = "0.9" -virtio-vsock = "0.3.1" -vm-memory = "0.12" +virtio-queue = "0.10" +virtio-vsock = "0.4" +vm-memory = "0.13.1" vmm-sys-util = "0.11" config = { version = "0.13", default-features = false, features = ["yaml"] } serde = { version = "1", features = ["derive"] } @@ -32,5 +32,5 @@ serde_yaml = "0.9" [dev-dependencies] assert_matches = "1.5" -virtio-queue = { version = "0.9", features = ["test-utils"] } +virtio-queue = { version = "0.10", features = ["test-utils"] } tempfile = "3.6.0" diff --git a/vhost-device-vsock/src/vhu_vsock.rs b/vhost-device-vsock/src/vhu_vsock.rs index 176fcd2..547fbbb 100644 --- a/vhost-device-vsock/src/vhu_vsock.rs +++ b/vhost-device-vsock/src/vhu_vsock.rs @@ -256,7 +256,10 @@ impl VhostUserVsockBackend { } } -impl VhostUserBackend for VhostUserVsockBackend { +impl VhostUserBackend for VhostUserVsockBackend { + type Vring = VringRwLock; + type Bitmap = (); + fn num_queues(&self) -> usize { NUM_QUEUES } @@ -295,7 +298,7 @@ impl VhostUserBackend for VhostUserVsockBackend { evset: EventSet, vrings: &[VringRwLock], thread_id: usize, - ) -> IoResult { + ) -> IoResult<()> { let vring_rx = &vrings[0]; let vring_tx = &vrings[1]; @@ -328,7 +331,7 @@ impl VhostUserBackend for VhostUserVsockBackend { SIBLING_VM_EVENT => { let _ = thread.sibling_event_fd.read(); thread.process_raw_pkts(vring_rx, evt_idx)?; - return Ok(false); + return Ok(()); } _ => { return Err(Error::HandleUnknownEvent.into()); @@ -339,7 +342,7 @@ impl VhostUserBackend for VhostUserVsockBackend { thread.process_rx(vring_rx, evt_idx)?; } - Ok(false) + Ok(()) } fn get_config(&self, offset: u32, size: u32) -> Vec { @@ -443,19 +446,15 @@ mod tests { let ret = backend.handle_event(RX_QUEUE_EVENT, EventSet::IN, &vrings, 0); assert!(ret.is_ok()); - assert!(!ret.unwrap()); let ret = backend.handle_event(TX_QUEUE_EVENT, EventSet::IN, &vrings, 0); assert!(ret.is_ok()); - assert!(!ret.unwrap()); let ret = backend.handle_event(EVT_QUEUE_EVENT, EventSet::IN, &vrings, 0); assert!(ret.is_ok()); - assert!(!ret.unwrap()); let ret = backend.handle_event(BACKEND_EVENT, EventSet::IN, &vrings, 0); assert!(ret.is_ok()); - assert!(!ret.unwrap()); // cleanup let _ = std::fs::remove_file(vhost_socket_path); diff --git a/vhost-device-vsock/src/vhu_vsock_thread.rs b/vhost-device-vsock/src/vhu_vsock_thread.rs index c0dba70..10dcc1c 100644 --- a/vhost-device-vsock/src/vhu_vsock_thread.rs +++ b/vhost-device-vsock/src/vhu_vsock_thread.rs @@ -240,10 +240,7 @@ impl VhostUserVsockThread { } /// Register our listeners in the VringEpollHandler - pub fn register_listeners( - &mut self, - epoll_handler: Arc>, - ) { + pub fn register_listeners(&mut self, epoll_handler: Arc>) { epoll_handler .register_listener(self.get_epoll_fd(), EventSet::IN, u64::from(BACKEND_EVENT)) .unwrap(); diff --git a/vhost-device-vsock/src/vsock_conn.rs b/vhost-device-vsock/src/vsock_conn.rs index 42f762b..a116593 100644 --- a/vhost-device-vsock/src/vsock_conn.rs +++ b/vhost-device-vsock/src/vsock_conn.rs @@ -1,14 +1,14 @@ // SPDX-License-Identifier: Apache-2.0 or BSD-3-Clause use std::{ - io::{ErrorKind, Read, Write}, + io::{ErrorKind, Write}, num::Wrapping, os::unix::prelude::{AsRawFd, RawFd}, }; use log::{error, info}; use virtio_vsock::packet::{VsockPacket, PKT_HEADER_SIZE}; -use vm_memory::{bitmap::BitmapSlice, Bytes, VolatileSlice}; +use vm_memory::{bitmap::BitmapSlice, ReadVolatile, VolatileSlice, WriteVolatile}; use crate::{ rxops::*, @@ -55,7 +55,7 @@ pub(crate) struct VsockConnection { tx_buffer_size: u32, } -impl VsockConnection { +impl VsockConnection { /// Create a new vsock connection object for locally i.e host-side /// inititated connections. pub fn new_local_init( @@ -158,9 +158,11 @@ impl VsockConnection { // data must fit inside a packet buffer and be within peer's // available buffer space let max_read_len = std::cmp::min(buf.len(), self.peer_avail_credit()); - + let mut buf = buf + .subslice(0, max_read_len) + .expect("subslicing should work since length was checked"); // Read data from the stream directly into the buffer - if let Ok(read_cnt) = buf.read_from(0, &mut self.stream, max_read_len) { + if let Ok(read_cnt) = self.stream.read_volatile(&mut buf) { if read_cnt == 0 { // If no data was read then the stream was closed down unexpectedly. // Send a shutdown packet to the guest-side application. @@ -305,7 +307,8 @@ impl VsockConnection { } // Write data to the stream - let written_count = match buf.write_to(0, &mut self.stream, buf.len()) { + + let written_count = match self.stream.write_volatile(buf) { Ok(cnt) => cnt, Err(vm_memory::VolatileMemoryError::IOError(e)) => { if e.kind() == ErrorKind::WouldBlock { @@ -382,7 +385,7 @@ mod tests { use super::*; use crate::vhu_vsock::{VSOCK_HOST_CID, VSOCK_OP_RW, VSOCK_TYPE_STREAM}; use std::collections::VecDeque; - use std::io::Result as IoResult; + use std::io::{Read, Result as IoResult}; use std::ops::Deref; use std::sync::{Arc, Mutex}; use virtio_bindings::bindings::virtio_ring::{VRING_DESC_F_NEXT, VRING_DESC_F_WRITE}; @@ -527,17 +530,52 @@ mod tests { fn write(&mut self, buf: &[u8]) -> std::result::Result { self.write_buffer.lock().unwrap().write(buf) } + fn flush(&mut self) -> IoResult<()> { Ok(()) } } + impl WriteVolatile for VsockDummySocket { + fn write_volatile( + &mut self, + buf: &VolatileSlice, + ) -> std::result::Result { + // VecDequeue has no fancy unsafe tricks that vm-memory can abstract. + // One could do fairly efficient stuff using the moving From imp... + // But this is just for tests, so lets clone, convert to Vec, append, convert back and replace. + let mut write_buffer = self.write_buffer.lock().unwrap(); + let mut vec = Vec::from(write_buffer.clone()); + let n = vec.write_volatile(buf)?; + *write_buffer = VecDeque::from(vec); + + Ok(n) + } + } + impl Read for VsockDummySocket { fn read(&mut self, buf: &mut [u8]) -> IoResult { self.read_buffer.lock().unwrap().read(buf) } } + impl ReadVolatile for VsockDummySocket { + fn read_volatile( + &mut self, + buf: &mut VolatileSlice, + ) -> std::result::Result { + // Similar to the std's Read impl, we only read on the head. Since + // we drain the head, successive reads will cover the rest of the + // queue. + let mut read_buffer = self.read_buffer.lock().unwrap(); + let (head, _) = read_buffer.as_slices(); + let n = ReadVolatile::read_volatile(&mut &head[..], buf)?; + read_buffer.drain(..n); + + Ok(n) + } + } + impl AsRawFd for VsockDummySocket { fn as_raw_fd(&self) -> RawFd { -1