virtio-devices: introduce ActivationContext for device activation

Signed-off-by: Peter Oskolkov <posk@google.com>
This commit is contained in:
Peter Oskolkov
2026-03-12 09:50:37 -07:00
committed by Bo Chen
parent ab8169c855
commit f77c6ef78b
30 changed files with 183 additions and 177 deletions

View File

@@ -95,15 +95,15 @@ fuzz_target!(|bytes: &[u8]| -> Corpus {
reporting_queue_evt.write(1).unwrap(); reporting_queue_evt.write(1).unwrap();
balloon balloon
.activate( .activate(virtio_devices::ActivationContext {
guest_memory, mem: guest_memory,
Arc::new(NoopVirtioInterrupt {}), interrupt_cb: Arc::new(NoopVirtioInterrupt {}),
vec![ queues: vec![
(0, inflate_q, inflate_evt), (0, inflate_q, inflate_evt),
(1, deflate_q, deflate_evt), (1, deflate_q, deflate_evt),
(2, reporting_q, reporting_evt), (2, reporting_q, reporting_evt),
], ],
) })
.ok(); .ok();
// Wait for the events to finish and balloon device worker thread to return // Wait for the events to finish and balloon device worker thread to return

View File

@@ -91,11 +91,11 @@ fuzz_target!(|bytes: &[u8]| -> Corpus {
queue_evt.write(1).unwrap(); queue_evt.write(1).unwrap();
block block
.activate( .activate(virtio_devices::ActivationContext {
guest_memory, mem: guest_memory,
Arc::new(NoopVirtioInterrupt {}), interrupt_cb: Arc::new(NoopVirtioInterrupt {}),
vec![(0, q, evt)], queues: vec![(0, q, evt)],
) })
.ok(); .ok();
// Wait for the events to finish and block device worker thread to return // Wait for the events to finish and block device worker thread to return

View File

@@ -128,11 +128,11 @@ fuzz_target!(|bytes: &[u8]| -> Corpus {
pipe_tx.write_all(console_input_bytes).unwrap(); // To use fuzzed data; pipe_tx.write_all(console_input_bytes).unwrap(); // To use fuzzed data;
console console
.activate( .activate(virtio_devices::ActivationContext {
guest_memory, mem: guest_memory,
Arc::new(NoopVirtioInterrupt {}), interrupt_cb: Arc::new(NoopVirtioInterrupt {}),
vec![(0, input_queue, input_evt), (1, output_queue, output_evt)], queues: vec![(0, input_queue, input_evt), (1, output_queue, output_evt)],
) })
.unwrap(); .unwrap();
// Wait for the events to finish and console device worker thread to return // Wait for the events to finish and console device worker thread to return

View File

@@ -107,14 +107,14 @@ fuzz_target!(|bytes: &[u8]| -> Corpus {
request_queue_evt.write(1).unwrap(); request_queue_evt.write(1).unwrap();
iommu iommu
.activate( .activate(virtio_devices::ActivationContext {
guest_memory, mem: guest_memory,
Arc::new(NoopVirtioInterrupt {}), interrupt_cb: Arc::new(NoopVirtioInterrupt {}),
vec![ queues: vec![
(0, request_queue, request_evt), (0, request_queue, request_evt),
(0, _event_queue, _event_evt), (0, _event_queue, _event_evt),
], ],
) })
.ok(); .ok();
// Wait for the events to finish and vIOMMU device worker thread to return // Wait for the events to finish and vIOMMU device worker thread to return

View File

@@ -105,11 +105,11 @@ fuzz_target!(|bytes: &[u8]| -> Corpus {
queue_evt.write(1).unwrap(); queue_evt.write(1).unwrap();
virtio_mem virtio_mem
.activate( .activate(virtio_devices::ActivationContext {
guest_memory, mem: guest_memory,
Arc::new(NoopVirtioInterrupt {}), interrupt_cb: Arc::new(NoopVirtioInterrupt {}),
vec![(0, q, evt)], queues: vec![(0, q, evt)],
) })
.ok(); .ok();
// Wait for the events to finish and virtio-mem device worker thread to return // Wait for the events to finish and virtio-mem device worker thread to return

View File

@@ -143,11 +143,11 @@ fuzz_target!(|bytes: &[u8]| -> Corpus {
input_queue_evt.write(1).unwrap(); input_queue_evt.write(1).unwrap();
output_queue_evt.write(1).unwrap(); output_queue_evt.write(1).unwrap();
net.activate( net.activate(virtio_devices::ActivationContext {
guest_memory, mem: guest_memory,
Arc::new(NoopVirtioInterrupt {}), interrupt_cb: Arc::new(NoopVirtioInterrupt {}),
vec![(0, input_queue, input_evt), (1, output_queue, output_evt)], queues: vec![(0, input_queue, input_evt), (1, output_queue, output_evt)],
) })
.unwrap(); .unwrap();
// Wait for the events to finish and net device worker thread to return // Wait for the events to finish and net device worker thread to return

View File

@@ -61,11 +61,11 @@ fuzz_target!(|bytes: &[u8]| -> Corpus {
// Kick the 'queue' event before activate the pmem device // Kick the 'queue' event before activate the pmem device
queue_evt.write(1).unwrap(); queue_evt.write(1).unwrap();
pmem.activate( pmem.activate(virtio_devices::ActivationContext {
guest_memory, mem: guest_memory,
Arc::new(NoopVirtioInterrupt {}), interrupt_cb: Arc::new(NoopVirtioInterrupt {}),
vec![(0, q, evt)], queues: vec![(0, q, evt)],
) })
.ok(); .ok();
// Wait for the events to finish and pmem device worker thread to return // Wait for the events to finish and pmem device worker thread to return

View File

@@ -99,11 +99,11 @@ fuzz_target!(|bytes: &[u8]| -> Corpus {
// Kick the 'queue' event before activate the rng device // Kick the 'queue' event before activate the rng device
queue_evt.write(1).unwrap(); queue_evt.write(1).unwrap();
rng.activate( rng.activate(virtio_devices::ActivationContext {
guest_memory, mem: guest_memory,
Arc::new(NoopVirtioInterrupt {}), interrupt_cb: Arc::new(NoopVirtioInterrupt {}),
vec![(0, q, evt)], queues: vec![(0, q, evt)],
) })
.ok(); .ok();
// Wait for the events to finish and rng device worker thread to return // Wait for the events to finish and rng device worker thread to return

View File

@@ -108,11 +108,11 @@ fuzz_target!(|bytes: &[u8]| -> Corpus {
.unwrap(); .unwrap();
vsock vsock
.activate( .activate(virtio_devices::ActivationContext {
guest_memory, mem: guest_memory,
Arc::new(NoopVirtioInterrupt {}), interrupt_cb: Arc::new(NoopVirtioInterrupt {}),
vec![(0, q, evt)], queues: vec![(0, q, evt)],
) })
.ok(); .ok();
// Wait for the events to finish and vsock device worker thread to return // Wait for the events to finish and vsock device worker thread to return

View File

@@ -64,11 +64,11 @@ fuzz_target!(|bytes: &[u8]| -> Corpus {
queue_evt.write(1).unwrap(); queue_evt.write(1).unwrap();
watchdog watchdog
.activate( .activate(virtio_devices::ActivationContext {
guest_memory, mem: guest_memory,
Arc::new(NoopVirtioInterrupt {}), interrupt_cb: Arc::new(NoopVirtioInterrupt {}),
vec![(0, q, evt)], queues: vec![(0, q, evt)],
) })
.ok(); .ok();
// Wait for the events to finish and watchdog device worker thread to return // Wait for the events to finish and watchdog device worker thread to return

View File

@@ -590,12 +590,13 @@ impl VirtioDevice for Balloon {
} }
} }
fn activate( fn activate(&mut self, context: crate::device::ActivationContext) -> ActivateResult {
&mut self, let crate::device::ActivationContext {
mem: GuestMemoryAtomic<GuestMemoryMmap>, mem,
interrupt_cb: Arc<dyn VirtioInterrupt>, interrupt_cb,
mut queues: Vec<(usize, Queue, EventFd)>, mut queues,
) -> ActivateResult { ..
} = context;
self.common.activate(&queues, interrupt_cb.clone())?; self.common.activate(&queues, interrupt_cb.clone())?;
let (kill_evt, pause_evt) = self.common.dup_eventfds(); let (kill_evt, pause_evt) = self.common.dup_eventfds();

View File

@@ -1008,12 +1008,12 @@ impl VirtioDevice for Block {
self.update_writeback(); self.update_writeback();
} }
fn activate( fn activate(&mut self, context: crate::device::ActivationContext) -> ActivateResult {
&mut self, let crate::device::ActivationContext {
mem: GuestMemoryAtomic<GuestMemoryMmap>, mem,
interrupt_cb: Arc<dyn VirtioInterrupt>, interrupt_cb,
mut queues: Vec<(usize, Queue, EventFd)>, mut queues,
) -> ActivateResult { } = context;
// See if the guest didn't ack the device being read-only. // See if the guest didn't ack the device being read-only.
// If so, warn and pretend it did. // If so, warn and pretend it did.
let original_acked_features = self.common.acked_features; let original_acked_features = self.common.acked_features;

View File

@@ -710,12 +710,13 @@ impl VirtioDevice for Console {
self.read_config_from_slice(self.config.lock().unwrap().as_slice(), offset, data); self.read_config_from_slice(self.config.lock().unwrap().as_slice(), offset, data);
} }
fn activate( fn activate(&mut self, context: crate::device::ActivationContext) -> ActivateResult {
&mut self, let crate::device::ActivationContext {
mem: GuestMemoryAtomic<GuestMemoryMmap>, mem,
interrupt_cb: Arc<dyn VirtioInterrupt>, interrupt_cb,
mut queues: Vec<(usize, Queue, EventFd)>, mut queues,
) -> ActivateResult { ..
} = context;
self.common.activate(&queues, interrupt_cb.clone())?; self.common.activate(&queues, interrupt_cb.clone())?;
self.resizer self.resizer
.acked_features .acked_features

View File

@@ -53,6 +53,12 @@ pub struct VirtioSharedMemoryList {
pub region_list: Vec<VirtioSharedMemory>, pub region_list: Vec<VirtioSharedMemory>,
} }
pub struct ActivationContext {
pub mem: GuestMemoryAtomic<GuestMemoryMmap>,
pub interrupt_cb: Arc<dyn VirtioInterrupt>,
pub queues: Vec<(usize, Queue, EventFd)>,
}
/// Trait for virtio devices to be driven by a virtio transport. /// Trait for virtio devices to be driven by a virtio transport.
/// ///
/// The lifecycle of a virtio device is to be moved to a virtio transport, which will then query the /// The lifecycle of a virtio device is to be moved to a virtio transport, which will then query the
@@ -94,12 +100,7 @@ pub trait VirtioDevice: Send {
} }
/// Activates this device for real usage. /// Activates this device for real usage.
fn activate( fn activate(&mut self, context: ActivationContext) -> ActivateResult;
&mut self,
mem: GuestMemoryAtomic<GuestMemoryMmap>,
interrupt_evt: Arc<dyn VirtioInterrupt>,
queues: Vec<(usize, Queue, EventFd)>,
) -> ActivateResult;
/// Optionally deactivates this device and returns ownership of the guest memory map, interrupt /// Optionally deactivates this device and returns ownership of the guest memory map, interrupt
/// event, and queue events. /// event, and queue events.

View File

@@ -1075,12 +1075,13 @@ impl VirtioDevice for Iommu {
self.update_bypass(); self.update_bypass();
} }
fn activate( fn activate(&mut self, context: crate::device::ActivationContext) -> ActivateResult {
&mut self, let crate::device::ActivationContext {
mem: GuestMemoryAtomic<GuestMemoryMmap>, mem,
interrupt_cb: Arc<dyn VirtioInterrupt>, interrupt_cb,
mut queues: Vec<(usize, Queue, EventFd)>, mut queues,
) -> ActivateResult { ..
} = context;
self.common.activate(&queues, interrupt_cb.clone())?; self.common.activate(&queues, interrupt_cb.clone())?;
let (kill_evt, pause_evt) = self.common.dup_eventfds(); let (kill_evt, pause_evt) = self.common.dup_eventfds();

View File

@@ -42,8 +42,8 @@ pub use self::balloon::Balloon;
pub use self::block::{Block, BlockState}; pub use self::block::{Block, BlockState};
pub use self::console::{Console, ConsoleResizer, Endpoint}; pub use self::console::{Console, ConsoleResizer, Endpoint};
pub use self::device::{ pub use self::device::{
DmaRemapping, VirtioCommon, VirtioDevice, VirtioInterrupt, VirtioInterruptType, ActivationContext, DmaRemapping, VirtioCommon, VirtioDevice, VirtioInterrupt,
VirtioSharedMemoryList, VirtioInterruptType, VirtioSharedMemoryList,
}; };
pub use self::epoll_helper::{ pub use self::epoll_helper::{
EPOLL_HELPER_EVENT_LAST, EpollHelper, EpollHelperError, EpollHelperHandler, EPOLL_HELPER_EVENT_LAST, EpollHelper, EpollHelperError, EpollHelperHandler,

View File

@@ -950,12 +950,13 @@ impl VirtioDevice for Mem {
self.read_config_from_slice(self.config.lock().unwrap().as_slice(), offset, data); self.read_config_from_slice(self.config.lock().unwrap().as_slice(), offset, data);
} }
fn activate( fn activate(&mut self, context: crate::device::ActivationContext) -> ActivateResult {
&mut self, let crate::device::ActivationContext {
mem: GuestMemoryAtomic<GuestMemoryMmap>, mem,
interrupt_cb: Arc<dyn VirtioInterrupt>, interrupt_cb,
mut queues: Vec<(usize, Queue, EventFd)>, mut queues,
) -> ActivateResult { ..
} = context;
self.common.activate(&queues, interrupt_cb.clone())?; self.common.activate(&queues, interrupt_cb.clone())?;
let (kill_evt, pause_evt) = self.common.dup_eventfds(); let (kill_evt, pause_evt) = self.common.dup_eventfds();

View File

@@ -693,12 +693,12 @@ impl VirtioDevice for Net {
self.read_config_from_slice(self.config.as_slice(), offset, data); self.read_config_from_slice(self.config.as_slice(), offset, data);
} }
fn activate( fn activate(&mut self, context: crate::device::ActivationContext) -> ActivateResult {
&mut self, let crate::device::ActivationContext {
mem: GuestMemoryAtomic<GuestMemoryMmap>, mem,
interrupt_cb: Arc<dyn VirtioInterrupt>, interrupt_cb,
mut queues: Vec<(usize, Queue, EventFd)>, mut queues,
) -> ActivateResult { } = context;
self.common.activate(&queues, interrupt_cb.clone())?; self.common.activate(&queues, interrupt_cb.clone())?;
let num_queues = queues.len(); let num_queues = queues.len();

View File

@@ -377,12 +377,13 @@ impl VirtioDevice for Pmem {
self.read_config_from_slice(self.config.as_slice(), offset, data); self.read_config_from_slice(self.config.as_slice(), offset, data);
} }
fn activate( fn activate(&mut self, context: crate::device::ActivationContext) -> ActivateResult {
&mut self, let crate::device::ActivationContext {
mem: GuestMemoryAtomic<GuestMemoryMmap>, mem,
interrupt_cb: Arc<dyn VirtioInterrupt>, interrupt_cb,
mut queues: Vec<(usize, Queue, EventFd)>, mut queues,
) -> ActivateResult { ..
} = context;
self.common.activate(&queues, interrupt_cb.clone())?; self.common.activate(&queues, interrupt_cb.clone())?;
let (kill_evt, pause_evt) = self.common.dup_eventfds(); let (kill_evt, pause_evt) = self.common.dup_eventfds();
if let Some(disk) = self.disk.as_ref() { if let Some(disk) = self.disk.as_ref() {

View File

@@ -244,12 +244,13 @@ impl VirtioDevice for Rng {
self.common.ack_features(value); self.common.ack_features(value);
} }
fn activate( fn activate(&mut self, context: crate::device::ActivationContext) -> ActivateResult {
&mut self, let crate::device::ActivationContext {
mem: GuestMemoryAtomic<GuestMemoryMmap>, mem,
interrupt_cb: Arc<dyn VirtioInterrupt>, interrupt_cb,
mut queues: Vec<(usize, Queue, EventFd)>, mut queues,
) -> ActivateResult { ..
} = context;
self.common.activate(&queues, interrupt_cb.clone())?; self.common.activate(&queues, interrupt_cb.clone())?;
let (kill_evt, pause_evt) = self.common.dup_eventfds(); let (kill_evt, pause_evt) = self.common.dup_eventfds();

View File

@@ -404,11 +404,8 @@ impl Snapshottable for VirtioPciCommonConfig {
#[cfg(test)] #[cfg(test)]
mod unit_tests { mod unit_tests {
use vm_memory::GuestMemoryAtomic;
use vmm_sys_util::eventfd::EventFd;
use super::*; use super::*;
use crate::{ActivateResult, GuestMemoryMmap, VirtioInterrupt}; use crate::{ActivateResult, ActivationContext};
struct DummyDevice(u32); struct DummyDevice(u32);
const QUEUE_SIZE: u16 = 256; const QUEUE_SIZE: u16 = 256;
@@ -421,12 +418,7 @@ mod unit_tests {
fn queue_max_sizes(&self) -> &[u16] { fn queue_max_sizes(&self) -> &[u16] {
QUEUE_SIZES QUEUE_SIZES
} }
fn activate( fn activate(&mut self, _context: ActivationContext) -> ActivateResult {
&mut self,
_mem: GuestMemoryAtomic<GuestMemoryMmap>,
_interrupt_evt: Arc<dyn VirtioInterrupt>,
_queues: Vec<(usize, Queue, EventFd)>,
) -> ActivateResult {
Ok(()) Ok(())
} }

View File

@@ -309,12 +309,13 @@ pub struct VirtioPciDeviceActivator {
} }
impl VirtioPciDeviceActivator { impl VirtioPciDeviceActivator {
pub fn activate(&mut self) -> ActivateResult { pub fn activate(mut self) -> ActivateResult {
self.device.lock().unwrap().activate( let mut locked_device = self.device.lock().unwrap();
self.memory.take().unwrap(), locked_device.activate(crate::device::ActivationContext {
self.interrupt.take().unwrap(), mem: self.memory.take().unwrap(),
self.queues.take().unwrap(), interrupt_cb: self.interrupt.take().unwrap(),
)?; queues: self.queues.take().unwrap(),
})?;
self.device_activated.store(true, Ordering::SeqCst); self.device_activated.store(true, Ordering::SeqCst);
if let Some(barrier) = self.barrier.take() { if let Some(barrier) = self.barrier.take() {

View File

@@ -428,12 +428,13 @@ impl VirtioDevice for Vdpa {
} }
} }
fn activate( fn activate(&mut self, context: crate::device::ActivationContext) -> ActivateResult {
&mut self, let crate::device::ActivationContext {
mem: GuestMemoryAtomic<GuestMemoryMmap>, mem,
virtio_interrupt: Arc<dyn VirtioInterrupt>, interrupt_cb: virtio_interrupt,
queues: Vec<(usize, Queue, EventFd)>, queues,
) -> ActivateResult { ..
} = context;
self.activate_vdpa(&mem.memory(), virtio_interrupt.as_ref(), &queues) self.activate_vdpa(&mem.memory(), virtio_interrupt.as_ref(), &queues)
.map_err(ActivateError::ActivateVdpa)?; .map_err(ActivateError::ActivateVdpa)?;

View File

@@ -19,7 +19,6 @@ use virtio_bindings::virtio_blk::{
VIRTIO_BLK_F_GEOMETRY, VIRTIO_BLK_F_MQ, VIRTIO_BLK_F_RO, VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_GEOMETRY, VIRTIO_BLK_F_MQ, VIRTIO_BLK_F_RO, VIRTIO_BLK_F_SEG_MAX,
VIRTIO_BLK_F_SIZE_MAX, VIRTIO_BLK_F_TOPOLOGY, VIRTIO_BLK_F_WRITE_ZEROES, VIRTIO_BLK_F_SIZE_MAX, VIRTIO_BLK_F_TOPOLOGY, VIRTIO_BLK_F_WRITE_ZEROES,
}; };
use virtio_queue::Queue;
use vm_memory::{ByteValued, GuestMemoryAtomic}; use vm_memory::{ByteValued, GuestMemoryAtomic};
use vm_migration::protocol::MemoryRangeTable; use vm_migration::protocol::MemoryRangeTable;
use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable}; use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable};
@@ -279,12 +278,13 @@ impl VirtioDevice for Blk {
} }
} }
fn activate( fn activate(&mut self, context: crate::device::ActivationContext) -> ActivateResult {
&mut self, let crate::device::ActivationContext {
mem: GuestMemoryAtomic<GuestMemoryMmap>, mem,
interrupt_cb: Arc<dyn VirtioInterrupt>, interrupt_cb,
queues: Vec<(usize, Queue, EventFd)>, queues,
) -> ActivateResult { ..
} = context;
self.common.activate(&queues, interrupt_cb.clone())?; self.common.activate(&queues, interrupt_cb.clone())?;
self.guest_memory = Some(mem.clone()); self.guest_memory = Some(mem.clone());

View File

@@ -12,7 +12,6 @@ use serde::{Deserialize, Serialize};
use serde_with::{Bytes, serde_as}; use serde_with::{Bytes, serde_as};
use vhost::vhost_user::message::{VhostUserProtocolFeatures, VhostUserVirtioFeatures}; use vhost::vhost_user::message::{VhostUserProtocolFeatures, VhostUserVirtioFeatures};
use vhost::vhost_user::{FrontendReqHandler, VhostUserFrontend, VhostUserFrontendReqHandler}; use vhost::vhost_user::{FrontendReqHandler, VhostUserFrontend, VhostUserFrontendReqHandler};
use virtio_queue::Queue;
use vm_device::UserspaceMapping; use vm_device::UserspaceMapping;
use vm_memory::{ByteValued, GuestMemoryAtomic}; use vm_memory::{ByteValued, GuestMemoryAtomic};
use vm_migration::protocol::MemoryRangeTable; use vm_migration::protocol::MemoryRangeTable;
@@ -261,12 +260,13 @@ impl VirtioDevice for Fs {
self.read_config_from_slice(self.config.as_slice(), offset, data); self.read_config_from_slice(self.config.as_slice(), offset, data);
} }
fn activate( fn activate(&mut self, context: crate::device::ActivationContext) -> ActivateResult {
&mut self, let crate::device::ActivationContext {
mem: GuestMemoryAtomic<GuestMemoryMmap>, mem,
interrupt_cb: Arc<dyn VirtioInterrupt>, interrupt_cb,
queues: Vec<(usize, Queue, EventFd)>, queues,
) -> ActivateResult { ..
} = context;
self.common.activate(&queues, interrupt_cb.clone())?; self.common.activate(&queues, interrupt_cb.clone())?;
self.guest_memory = Some(mem.clone()); self.guest_memory = Some(mem.clone());

View File

@@ -14,7 +14,6 @@ use vhost::vhost_user::message::{
VhostUserConfigFlags, VhostUserProtocolFeatures, VhostUserVirtioFeatures, VhostUserConfigFlags, VhostUserProtocolFeatures, VhostUserVirtioFeatures,
}; };
use vhost::vhost_user::{FrontendReqHandler, VhostUserFrontend, VhostUserFrontendReqHandler}; use vhost::vhost_user::{FrontendReqHandler, VhostUserFrontend, VhostUserFrontendReqHandler};
use virtio_queue::Queue;
use vm_device::UserspaceMapping; use vm_device::UserspaceMapping;
use vm_memory::GuestMemoryAtomic; use vm_memory::GuestMemoryAtomic;
use vm_migration::protocol::MemoryRangeTable; use vm_migration::protocol::MemoryRangeTable;
@@ -277,12 +276,13 @@ impl VirtioDevice for GenericVhostUser {
} }
} }
fn activate( fn activate(&mut self, context: crate::device::ActivationContext) -> ActivateResult {
&mut self, let crate::device::ActivationContext {
mem: GuestMemoryAtomic<GuestMemoryMmap>, mem,
interrupt_cb: Arc<dyn VirtioInterrupt>, interrupt_cb,
queues: Vec<(usize, Queue, EventFd)>, queues,
) -> ActivateResult { ..
} = context;
self.common.activate(&queues, interrupt_cb.clone())?; self.common.activate(&queues, interrupt_cb.clone())?;
self.guest_memory = Some(mem.clone()); self.guest_memory = Some(mem.clone());

View File

@@ -19,7 +19,7 @@ use virtio_bindings::virtio_net::{
VIRTIO_NET_F_MAC, VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_MTU, VIRTIO_NET_F_MAC, VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_MTU,
}; };
use virtio_bindings::virtio_ring::VIRTIO_RING_F_EVENT_IDX; use virtio_bindings::virtio_ring::VIRTIO_RING_F_EVENT_IDX;
use virtio_queue::{Queue, QueueT}; use virtio_queue::QueueT;
use vm_memory::{ByteValued, GuestMemoryAtomic}; use vm_memory::{ByteValued, GuestMemoryAtomic};
use vm_migration::protocol::MemoryRangeTable; use vm_migration::protocol::MemoryRangeTable;
use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable}; use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable};
@@ -288,12 +288,13 @@ impl VirtioDevice for Net {
self.read_config_from_slice(self.config.as_slice(), offset, data); self.read_config_from_slice(self.config.as_slice(), offset, data);
} }
fn activate( fn activate(&mut self, context: crate::device::ActivationContext) -> ActivateResult {
&mut self, let crate::device::ActivationContext {
mem: GuestMemoryAtomic<GuestMemoryMmap>, mem,
interrupt_cb: Arc<dyn VirtioInterrupt>, interrupt_cb,
mut queues: Vec<(usize, Queue, EventFd)>, mut queues,
) -> ActivateResult { ..
} = context;
self.common.activate(&queues, interrupt_cb.clone())?; self.common.activate(&queues, interrupt_cb.clone())?;
self.guest_memory = Some(mem.clone()); self.guest_memory = Some(mem.clone());

View File

@@ -435,12 +435,13 @@ where
} }
} }
fn activate( fn activate(&mut self, context: crate::device::ActivationContext) -> ActivateResult {
&mut self, let crate::device::ActivationContext {
mem: GuestMemoryAtomic<GuestMemoryMmap>, mem,
interrupt_cb: Arc<dyn VirtioInterrupt>, interrupt_cb,
queues: Vec<(usize, Queue, EventFd)>, queues,
) -> ActivateResult { ..
} = context;
self.common.activate(&queues, interrupt_cb.clone())?; self.common.activate(&queues, interrupt_cb.clone())?;
let (kill_evt, pause_evt) = self.common.dup_eventfds(); let (kill_evt, pause_evt) = self.common.dup_eventfds();
@@ -593,9 +594,11 @@ mod unit_tests {
let memory = GuestMemoryAtomic::new(ctx.mem.clone()); let memory = GuestMemoryAtomic::new(ctx.mem.clone());
// Test a bad activation. // Test a bad activation.
let bad_activate = let bad_activate = ctx.device.activate(crate::device::ActivationContext {
ctx.device mem: memory.clone(),
.activate(memory.clone(), Arc::new(NoopVirtioInterrupt {}), Vec::new()); interrupt_cb: Arc::new(NoopVirtioInterrupt {}),
queues: Vec::new(),
});
match bad_activate { match bad_activate {
Err(ActivateError::BadActivate) => (), Err(ActivateError::BadActivate) => (),
other => panic!("{other:?}"), other => panic!("{other:?}"),
@@ -603,10 +606,10 @@ mod unit_tests {
// Test a correct activation. // Test a correct activation.
ctx.device ctx.device
.activate( .activate(crate::device::ActivationContext {
memory, mem: memory,
Arc::new(NoopVirtioInterrupt {}), interrupt_cb: Arc::new(NoopVirtioInterrupt {}),
vec![ queues: vec![
( (
0, 0,
Queue::new(256).unwrap(), Queue::new(256).unwrap(),
@@ -623,7 +626,7 @@ mod unit_tests {
EventFd::new(EFD_NONBLOCK).unwrap(), EventFd::new(EFD_NONBLOCK).unwrap(),
), ),
], ],
) })
.unwrap(); .unwrap();
} }

View File

@@ -326,12 +326,13 @@ impl VirtioDevice for Watchdog {
self.common.ack_features(value); self.common.ack_features(value);
} }
fn activate( fn activate(&mut self, context: crate::device::ActivationContext) -> ActivateResult {
&mut self, let crate::device::ActivationContext {
mem: GuestMemoryAtomic<GuestMemoryMmap>, mem,
interrupt_cb: Arc<dyn VirtioInterrupt>, interrupt_cb,
mut queues: Vec<(usize, Queue, EventFd)>, mut queues,
) -> ActivateResult { ..
} = context;
self.common.activate(&queues, interrupt_cb.clone())?; self.common.activate(&queues, interrupt_cb.clone())?;
let (kill_evt, pause_evt) = self.common.dup_eventfds(); let (kill_evt, pause_evt) = self.common.dup_eventfds();

View File

@@ -4543,7 +4543,7 @@ impl DeviceManager {
} }
pub fn activate_virtio_devices(&self) -> DeviceManagerResult<()> { pub fn activate_virtio_devices(&self) -> DeviceManagerResult<()> {
for mut activator in self.pending_activations.lock().unwrap().drain(..) { for activator in self.pending_activations.lock().unwrap().drain(..) {
activator activator
.activate() .activate()
.map_err(DeviceManagerError::VirtioActivate)?; .map_err(DeviceManagerError::VirtioActivate)?;