diff --git a/virtio-devices/src/vhost_user/blk.rs b/virtio-devices/src/vhost_user/blk.rs index 9b2cd061a..804265c2a 100644 --- a/virtio-devices/src/vhost_user/blk.rs +++ b/virtio-devices/src/vhost_user/blk.rs @@ -23,7 +23,7 @@ use std::vec::Vec; use vhost::vhost_user::message::VhostUserConfigFlags; use vhost::vhost_user::message::VHOST_USER_CONFIG_OFFSET; use vhost::vhost_user::message::{VhostUserProtocolFeatures, VhostUserVirtioFeatures}; -use vhost::vhost_user::{Master, VhostUserMaster, VhostUserMasterReqHandler}; +use vhost::vhost_user::{Master, MasterReqHandler, VhostUserMaster, VhostUserMasterReqHandler}; use vhost::VhostBackend; use virtio_bindings::bindings::virtio_blk::{ VIRTIO_BLK_F_BLK_SIZE, VIRTIO_BLK_F_CONFIG_WCE, VIRTIO_BLK_F_DISCARD, VIRTIO_BLK_F_FLUSH, @@ -215,6 +215,8 @@ impl VirtioDevice for Blk { self.guest_memory = Some(mem.clone()); + let slave_req_handler: Option> = None; + // The backend acknowledged features must contain the protocol feature // bit in case it was initially set but lost through the features // negotiation with the guest. @@ -228,6 +230,7 @@ impl VirtioDevice for Blk { queue_evts.iter().map(|q| q.try_clone().unwrap()).collect(), &interrupt_cb, backend_acked_features, + &slave_req_handler, ) .map_err(ActivateError::VhostUserBlkSetup)?; diff --git a/virtio-devices/src/vhost_user/fs.rs b/virtio-devices/src/vhost_user/fs.rs index bb8fb57e4..9d27e12fc 100644 --- a/virtio-devices/src/vhost_user/fs.rs +++ b/virtio-devices/src/vhost_user/fs.rs @@ -415,22 +415,6 @@ impl VirtioDevice for Fs { self.common.activate(&queues, &queue_evts, &interrupt_cb)?; self.guest_memory = Some(mem.clone()); - // The backend acknowledged features must contain the protocol feature - // bit in case it was initially set but lost through the features - // negotiation with the guest. - let backend_acked_features = self.common.acked_features - | (self.common.avail_features & VhostUserVirtioFeatures::PROTOCOL_FEATURES.bits()); - - setup_vhost_user( - &mut self.vu.lock().unwrap(), - &mem.memory(), - queues.clone(), - queue_evts.iter().map(|q| q.try_clone().unwrap()).collect(), - &interrupt_cb, - backend_acked_features, - ) - .map_err(ActivateError::VhostUserFsSetup)?; - // Initialize slave communication. let slave_req_handler = if self.slave_req_support { if let Some(cache) = self.cache.as_ref() { @@ -446,13 +430,6 @@ impl VirtioDevice for Fs { ActivateError::VhostUserFsSetup(Error::MasterReqHandlerCreation(e)) })?; req_handler.set_reply_ack_flag(true); - self.vu - .lock() - .unwrap() - .set_slave_request_fd(req_handler.get_tx_raw_fd()) - .map_err(|e| { - ActivateError::VhostUserFsSetup(Error::VhostUserSetSlaveRequestFd(e)) - })?; Some(req_handler) } else { None @@ -461,6 +438,23 @@ impl VirtioDevice for Fs { None }; + // The backend acknowledged features must contain the protocol feature + // bit in case it was initially set but lost through the features + // negotiation with the guest. + let backend_acked_features = self.common.acked_features + | (self.common.avail_features & VhostUserVirtioFeatures::PROTOCOL_FEATURES.bits()); + + setup_vhost_user( + &mut self.vu.lock().unwrap(), + &mem.memory(), + queues.clone(), + queue_evts.iter().map(|q| q.try_clone().unwrap()).collect(), + &interrupt_cb, + backend_acked_features, + &slave_req_handler, + ) + .map_err(ActivateError::VhostUserFsSetup)?; + // Run a dedicated thread for handling potential reconnections with // the backend as well as requests initiated by the backend. let (kill_evt, pause_evt) = self.common.dup_eventfds(); diff --git a/virtio-devices/src/vhost_user/mod.rs b/virtio-devices/src/vhost_user/mod.rs index 46e996d41..dca7b2fe1 100644 --- a/virtio-devices/src/vhost_user/mod.rs +++ b/virtio-devices/src/vhost_user/mod.rs @@ -197,6 +197,7 @@ impl VhostUserEpollHandler { &self.virtio_interrupt, self.acked_features, self.acked_protocol_features, + &self.slave_req_handler, ) .map_err(|e| { EpollHelperError::IoError(std::io::Error::new( diff --git a/virtio-devices/src/vhost_user/net.rs b/virtio-devices/src/vhost_user/net.rs index d4557320a..cc023a659 100644 --- a/virtio-devices/src/vhost_user/net.rs +++ b/virtio-devices/src/vhost_user/net.rs @@ -23,7 +23,7 @@ use std::sync::{Arc, Barrier, Mutex}; use std::thread; use std::vec::Vec; use vhost::vhost_user::message::{VhostUserProtocolFeatures, VhostUserVirtioFeatures}; -use vhost::vhost_user::{Master, VhostUserMaster, VhostUserMasterReqHandler}; +use vhost::vhost_user::{Master, MasterReqHandler, VhostUserMaster, VhostUserMasterReqHandler}; use virtio_bindings::bindings::virtio_net::{ VIRTIO_NET_F_CSUM, VIRTIO_NET_F_CTRL_VQ, VIRTIO_NET_F_GUEST_CSUM, VIRTIO_NET_F_GUEST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6, VIRTIO_NET_F_GUEST_UFO, @@ -283,6 +283,8 @@ impl VirtioDevice for Net { })?; } + let slave_req_handler: Option> = None; + // The backend acknowledged features must contain the protocol feature // bit in case it was initially set but lost through the features // negotiation with the guest. Additionally, it must not contain @@ -297,6 +299,7 @@ impl VirtioDevice for Net { queue_evts.iter().map(|q| q.try_clone().unwrap()).collect(), &interrupt_cb, backend_acked_features, + &slave_req_handler, ) .map_err(ActivateError::VhostUserNetSetup)?; diff --git a/virtio-devices/src/vhost_user/vu_common_ctrl.rs b/virtio-devices/src/vhost_user/vu_common_ctrl.rs index 834685add..08d6e4c02 100644 --- a/virtio-devices/src/vhost_user/vu_common_ctrl.rs +++ b/virtio-devices/src/vhost_user/vu_common_ctrl.rs @@ -13,7 +13,7 @@ use std::thread::sleep; use std::time::{Duration, Instant}; use std::vec::Vec; use vhost::vhost_user::message::{VhostUserProtocolFeatures, VhostUserVirtioFeatures}; -use vhost::vhost_user::{Master, VhostUserMaster}; +use vhost::vhost_user::{Master, MasterReqHandler, VhostUserMaster, VhostUserMasterReqHandler}; use vhost::{VhostBackend, VhostUserMemoryRegionInfo, VringConfigData}; use vm_memory::{Address, Error as MmapError, GuestMemory, GuestMemoryRegion}; use vmm_sys_util::eventfd::EventFd; @@ -100,13 +100,14 @@ pub fn negotiate_features_vhost_user( Ok((acked_features, acked_protocol_features)) } -pub fn setup_vhost_user( +pub fn setup_vhost_user( vu: &mut Master, mem: &GuestMemoryMmap, queues: Vec, queue_evts: Vec, virtio_interrupt: &Arc, acked_features: u64, + slave_req_handler: &Option>, ) -> Result<()> { vu.set_features(acked_features) .map_err(Error::VhostUserSetFeatures)?; @@ -164,7 +165,12 @@ pub fn setup_vhost_user( .map_err(Error::VhostUserSetVringEnable)?; } - Ok(()) + if let Some(slave_req_handler) = slave_req_handler { + vu.set_slave_request_fd(slave_req_handler.get_tx_raw_fd()) + .map_err(Error::VhostUserSetSlaveRequestFd) + } else { + Ok(()) + } } pub fn reset_vhost_user(vu: &mut Master, num_queues: usize) -> Result<()> { @@ -178,7 +184,8 @@ pub fn reset_vhost_user(vu: &mut Master, num_queues: usize) -> Result<()> { vu.reset_owner().map_err(Error::VhostUserResetOwner) } -pub fn reinitialize_vhost_user( +#[allow(clippy::too_many_arguments)] +pub fn reinitialize_vhost_user( vu: &mut Master, mem: &GuestMemoryMmap, queues: Vec, @@ -186,6 +193,7 @@ pub fn reinitialize_vhost_user( virtio_interrupt: &Arc, acked_features: u64, acked_protocol_features: u64, + slave_req_handler: &Option>, ) -> Result<()> { vu.set_owner().map_err(Error::VhostUserSetOwner)?; vu.get_features().map_err(Error::VhostUserGetFeatures)?; @@ -206,6 +214,7 @@ pub fn reinitialize_vhost_user( queue_evts, virtio_interrupt, acked_features, + slave_req_handler, ) }