vm-virtio: mmio: Expect an identifier upon device creation

This identifier is chosen from the DeviceManager so that it will manage
all identifiers across the VM, which will ensure uniqueness.

It is based off the name from the virtio device attached to this
transport layer.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2020-04-27 16:05:04 +02:00 committed by Rob Bradford
parent 9d84ef5073
commit eeb7e10d1f
2 changed files with 19 additions and 19 deletions

View File

@ -4,9 +4,9 @@
use crate::transport::{VirtioTransport, NOTIFY_REG_OFFSET}; use crate::transport::{VirtioTransport, NOTIFY_REG_OFFSET};
use crate::{ use crate::{
Queue, VirtioDevice, VirtioDeviceType, VirtioInterrupt, VirtioInterruptType, Queue, VirtioDevice, VirtioInterrupt, VirtioInterruptType, DEVICE_ACKNOWLEDGE, DEVICE_DRIVER,
DEVICE_ACKNOWLEDGE, DEVICE_DRIVER, DEVICE_DRIVER_OK, DEVICE_FAILED, DEVICE_FEATURES_OK, DEVICE_DRIVER_OK, DEVICE_FAILED, DEVICE_FEATURES_OK, DEVICE_INIT,
DEVICE_INIT, INTERRUPT_STATUS_CONFIG_CHANGED, INTERRUPT_STATUS_USED_RING, INTERRUPT_STATUS_CONFIG_CHANGED, INTERRUPT_STATUS_USED_RING,
}; };
use anyhow::anyhow; use anyhow::anyhow;
use byteorder::{ByteOrder, LittleEndian}; use byteorder::{ByteOrder, LittleEndian};
@ -96,6 +96,7 @@ struct VirtioMmioDeviceState {
/// Typically one page (4096 bytes) of MMIO address space is sufficient to handle this transport /// Typically one page (4096 bytes) of MMIO address space is sufficient to handle this transport
/// and inner virtio device. /// and inner virtio device.
pub struct MmioDevice { pub struct MmioDevice {
id: String,
device: Arc<Mutex<dyn VirtioDevice>>, device: Arc<Mutex<dyn VirtioDevice>>,
device_activated: bool, device_activated: bool,
@ -115,6 +116,7 @@ pub struct MmioDevice {
impl MmioDevice { impl MmioDevice {
/// Constructs a new MMIO transport for the given virtio device. /// Constructs a new MMIO transport for the given virtio device.
pub fn new( pub fn new(
id: String,
mem: GuestMemoryAtomic<GuestMemoryMmap>, mem: GuestMemoryAtomic<GuestMemoryMmap>,
device: Arc<Mutex<dyn VirtioDevice>>, device: Arc<Mutex<dyn VirtioDevice>>,
) -> Result<MmioDevice> { ) -> Result<MmioDevice> {
@ -130,6 +132,7 @@ impl MmioDevice {
.map(|&s| Queue::new(s)) .map(|&s| Queue::new(s))
.collect(); .collect();
Ok(MmioDevice { Ok(MmioDevice {
id,
device, device,
device_activated: false, device_activated: false,
features_select: 0, features_select: 0,
@ -422,24 +425,18 @@ impl Pausable for MmioDevice {
} }
} }
const VIRTIO_MMIO_DEV_SNAPSHOT_ID: &str = "virtio_mmio_device";
impl Snapshottable for MmioDevice { impl Snapshottable for MmioDevice {
fn id(&self) -> String { fn id(&self) -> String {
format!( self.id.clone()
"{}-{}",
VIRTIO_MMIO_DEV_SNAPSHOT_ID,
VirtioDeviceType::from(self.device.lock().unwrap().device_type())
)
} }
fn snapshot(&self) -> std::result::Result<Snapshot, MigratableError> { fn snapshot(&self) -> std::result::Result<Snapshot, MigratableError> {
let snapshot = let snapshot =
serde_json::to_vec(&self.state()).map_err(|e| MigratableError::Snapshot(e.into()))?; serde_json::to_vec(&self.state()).map_err(|e| MigratableError::Snapshot(e.into()))?;
let snapshot_id = self.id(); let mut virtio_mmio_dev_snapshot = Snapshot::new(self.id.as_str());
let mut virtio_mmio_dev_snapshot = Snapshot::new(&snapshot_id);
virtio_mmio_dev_snapshot.add_data_section(SnapshotDataSection { virtio_mmio_dev_snapshot.add_data_section(SnapshotDataSection {
id: format!("{}-section", snapshot_id), id: format!("{}-section", self.id),
snapshot, snapshot,
}); });
@ -447,10 +444,8 @@ impl Snapshottable for MmioDevice {
} }
fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> { fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> {
let snapshot_id = self.id(); if let Some(virtio_mmio_dev_section) =
if let Some(virtio_mmio_dev_section) = snapshot snapshot.snapshot_data.get(&format!("{}-section", self.id))
.snapshot_data
.get(&format!("{}-section", snapshot_id))
{ {
let virtio_mmio_dev_state = let virtio_mmio_dev_state =
match serde_json::from_slice(&virtio_mmio_dev_section.snapshot) { match serde_json::from_slice(&virtio_mmio_dev_section.snapshot) {

View File

@ -86,6 +86,9 @@ const VSOCK_DEVICE_NAME_PREFIX: &str = "vsock";
#[cfg(feature = "pci_support")] #[cfg(feature = "pci_support")]
const IOMMU_DEVICE_NAME: &str = "iommu"; const IOMMU_DEVICE_NAME: &str = "iommu";
#[cfg(feature = "mmio_support")]
const VIRTIO_MMIO_DEVICE_NAME_PREFIX: &str = "virtio-mmio";
/// Errors associated with device manager /// Errors associated with device manager
#[derive(Debug)] #[derive(Debug)]
pub enum DeviceManagerError { pub enum DeviceManagerError {
@ -881,7 +884,7 @@ impl DeviceManager {
) -> DeviceManagerResult<()> { ) -> DeviceManagerResult<()> {
#[cfg(feature = "mmio_support")] #[cfg(feature = "mmio_support")]
{ {
for (device, _, _) in virtio_devices { for (device, _, id) in virtio_devices {
let mmio_addr = self let mmio_addr = self
.address_manager .address_manager
.allocator .allocator
@ -889,7 +892,7 @@ impl DeviceManager {
.unwrap() .unwrap()
.allocate_mmio_addresses(None, MMIO_LEN, Some(MMIO_LEN)); .allocate_mmio_addresses(None, MMIO_LEN, Some(MMIO_LEN));
if let Some(addr) = mmio_addr { if let Some(addr) = mmio_addr {
self.add_virtio_mmio_device(device, interrupt_manager, addr)?; self.add_virtio_mmio_device(id, device, interrupt_manager, addr)?;
} else { } else {
error!("Unable to allocate MMIO address!"); error!("Unable to allocate MMIO address!");
} }
@ -2025,12 +2028,14 @@ impl DeviceManager {
#[cfg(feature = "mmio_support")] #[cfg(feature = "mmio_support")]
fn add_virtio_mmio_device( fn add_virtio_mmio_device(
&mut self, &mut self,
virtio_device_id: String,
virtio_device: VirtioDeviceArc, virtio_device: VirtioDeviceArc,
interrupt_manager: &Arc<dyn InterruptManager<GroupConfig = LegacyIrqGroupConfig>>, interrupt_manager: &Arc<dyn InterruptManager<GroupConfig = LegacyIrqGroupConfig>>,
mmio_base: GuestAddress, mmio_base: GuestAddress,
) -> DeviceManagerResult<()> { ) -> DeviceManagerResult<()> {
let id = format!("{}-{}", VIRTIO_MMIO_DEVICE_NAME_PREFIX, virtio_device_id);
let memory = self.memory_manager.lock().unwrap().guest_memory(); let memory = self.memory_manager.lock().unwrap().guest_memory();
let mut mmio_device = vm_virtio::transport::MmioDevice::new(memory, virtio_device) let mut mmio_device = vm_virtio::transport::MmioDevice::new(id, memory, virtio_device)
.map_err(DeviceManagerError::VirtioDevice)?; .map_err(DeviceManagerError::VirtioDevice)?;
for (i, (event, addr)) in mmio_device.ioeventfds(mmio_base.0).iter().enumerate() { for (i, (event, addr)) in mmio_device.ioeventfds(mmio_base.0).iter().enumerate() {