mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
virtio-devices: introduce ActivationContext for device activation
Signed-off-by: Peter Oskolkov <posk@google.com>
(cherry picked from commit f77c6ef78b)
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -89,11 +89,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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
@@ -998,12 +998,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;
|
||||||
|
|||||||
@@ -703,12 +703,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
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
@@ -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(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -291,12 +291,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() {
|
||||||
|
|||||||
@@ -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)?;
|
||||||
|
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
@@ -4477,7 +4477,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)?;
|
||||||
|
|||||||
Reference in New Issue
Block a user