From d99c0c0d1d7ea1e12b7bcbc3f1dd439a479d7fec Mon Sep 17 00:00:00 2001 From: Yi Wang Date: Thu, 15 Jun 2023 12:02:45 +0800 Subject: [PATCH] devices: pvpanic: add method for DeviceManager Add method for DeviceManager to invoke. Signed-off-by: Yi Wang Signed-off-by: Rob Bradford --- devices/src/lib.rs | 1 + devices/src/pvpanic.rs | 4 ++++ src/main.rs | 9 +++++++ vmm/src/config.rs | 3 +++ vmm/src/device_manager.rs | 49 +++++++++++++++++++++++++++++++++++++++ vmm/src/lib.rs | 1 + vmm/src/vm_config.rs | 2 ++ 7 files changed, 69 insertions(+) diff --git a/devices/src/lib.rs b/devices/src/lib.rs index 4f49682be..79e262020 100644 --- a/devices/src/lib.rs +++ b/devices/src/lib.rs @@ -25,6 +25,7 @@ pub mod pvpanic; pub mod tpm; pub use self::acpi::{AcpiGedDevice, AcpiPmTimerDevice, AcpiShutdownDevice}; +pub use self::pvpanic::{PvPanicDevice, PVPANIC_DEVICE_MMIO_SIZE}; bitflags! { pub struct AcpiNotificationFlags: u8 { diff --git a/devices/src/pvpanic.rs b/devices/src/pvpanic.rs index 5484bb85f..a52eed285 100644 --- a/devices/src/pvpanic.rs +++ b/devices/src/pvpanic.rs @@ -136,6 +136,10 @@ impl PvPanicDevice { events: self.events, } } + + pub fn config_bar_addr(&self) -> u64 { + self.configuration.get_bar_addr(0) + } } impl BusDevice for PvPanicDevice { diff --git a/src/main.rs b/src/main.rs index 08780a2b5..ae9a62f40 100644 --- a/src/main.rs +++ b/src/main.rs @@ -225,6 +225,10 @@ pub struct TopLevel { /// cid=, socket=, iommu=on|off, id=, pci_segment= vsock: Option, + #[argh(switch, long = "pvpanic")] + /// enable pvpanic device + pvpanic: bool, + #[argh(option, long = "numa")] /// guest_numa_id=, cpus=, distances=, memory_zones=, sgx_epc_sections= numa: Vec, @@ -349,6 +353,9 @@ impl TopLevel { }; let vsock = self.vsock.as_deref(); + + let pvpanic = self.pvpanic; + #[cfg(target_arch = "x86_64")] let sgx_epc = if !self.sgx_epc.is_empty() { Some(self.sgx_epc.iter().map(|x| x.as_str()).collect()) @@ -387,6 +394,7 @@ impl TopLevel { user_devices, vdpa, vsock, + pvpanic, #[cfg(target_arch = "x86_64")] sgx_epc, numa, @@ -773,6 +781,7 @@ mod unit_tests { user_devices: None, vdpa: None, vsock: None, + pvpanic: false, iommu: false, #[cfg(target_arch = "x86_64")] sgx_epc: None, diff --git a/vmm/src/config.rs b/vmm/src/config.rs index d43653a77..9506fed99 100644 --- a/vmm/src/config.rs +++ b/vmm/src/config.rs @@ -370,6 +370,7 @@ pub struct VmParams<'a> { pub user_devices: Option>, pub vdpa: Option>, pub vsock: Option<&'a str>, + pub pvpanic: bool, #[cfg(target_arch = "x86_64")] pub sgx_epc: Option>, pub numa: Option>, @@ -2084,6 +2085,7 @@ impl VmConfig { user_devices, vdpa, vsock, + pvpanic: vm_params.pvpanic, iommu: false, // updated in VmConfig::validate() #[cfg(target_arch = "x86_64")] sgx_epc, @@ -2767,6 +2769,7 @@ mod tests { user_devices: None, vdpa: None, vsock: None, + pvpanic: false, iommu: false, #[cfg(target_arch = "x86_64")] sgx_epc: None, diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index 4ba4ff8b4..4b1568999 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -114,6 +114,7 @@ const RNG_DEVICE_NAME: &str = "__rng"; const IOMMU_DEVICE_NAME: &str = "__iommu"; const BALLOON_DEVICE_NAME: &str = "__balloon"; const CONSOLE_DEVICE_NAME: &str = "__console"; +const PVPANIC_DEVICE_NAME: &str = "__pvpanic"; // Devices that the user may name and for which we generate // identifiers if the user doesn't give one @@ -470,6 +471,9 @@ pub enum DeviceManagerError { /// Failed retrieving device state from snapshot RestoreGetState(MigratableError), + + /// Cannot create a PvPanic device + PvPanicCreate(devices::pvpanic::PvPanicError), } pub type DeviceManagerResult = result::Result; @@ -931,6 +935,9 @@ pub struct DeviceManager { // GPIO device for AArch64 gpio_device: Option>>, + // pvpanic device + pvpanic_device: Option>>, + // Flag to force setting the iommu on virtio devices force_iommu: bool, @@ -1122,6 +1129,7 @@ impl DeviceManager { virtio_mem_devices: Vec::new(), #[cfg(target_arch = "aarch64")] gpio_device: None, + pvpanic_device: None, force_iommu, io_uring_supported: None, boot_id_list, @@ -1245,6 +1253,10 @@ impl DeviceManager { self.virtio_devices = virtio_devices; + if self.config.clone().lock().unwrap().pvpanic { + self.pvpanic_device = self.add_pvpanic_device()?; + } + Ok(()) } @@ -3604,6 +3616,43 @@ impl DeviceManager { Ok(pci_device_bdf) } + fn add_pvpanic_device( + &mut self, + ) -> DeviceManagerResult>>> { + let id = String::from(PVPANIC_DEVICE_NAME); + let pci_segment_id = 0x0_u16; + + info!("Creating pvpanic device {}", id); + + let (pci_segment_id, pci_device_bdf, resources) = + self.pci_resources(&id, pci_segment_id)?; + + let snapshot = snapshot_from_id(self.snapshot.as_ref(), id.as_str()); + + let pvpanic_device = devices::PvPanicDevice::new(id.clone(), snapshot) + .map_err(DeviceManagerError::PvPanicCreate)?; + + let pvpanic_device = Arc::new(Mutex::new(pvpanic_device)); + + let new_resources = self.add_pci_device( + pvpanic_device.clone(), + pvpanic_device.clone(), + pci_segment_id, + pci_device_bdf, + resources, + )?; + + let mut node = device_node!(id, pvpanic_device); + + node.resources = new_resources; + node.pci_bdf = Some(pci_device_bdf); + node.pci_device_handle = None; + + self.device_tree.lock().unwrap().insert(id, node); + + Ok(Some(pvpanic_device)) + } + fn pci_resources( &self, id: &str, diff --git a/vmm/src/lib.rs b/vmm/src/lib.rs index f885b7893..407e590fd 100644 --- a/vmm/src/lib.rs +++ b/vmm/src/lib.rs @@ -2197,6 +2197,7 @@ mod unit_tests { user_devices: None, vdpa: None, vsock: None, + pvpanic: false, iommu: false, #[cfg(target_arch = "x86_64")] sgx_epc: None, diff --git a/vmm/src/vm_config.rs b/vmm/src/vm_config.rs index 56add7ac8..b034ef1fd 100644 --- a/vmm/src/vm_config.rs +++ b/vmm/src/vm_config.rs @@ -586,6 +586,8 @@ pub struct VmConfig { pub vdpa: Option>, pub vsock: Option, #[serde(default)] + pub pvpanic: bool, + #[serde(default)] pub iommu: bool, #[cfg(target_arch = "x86_64")] pub sgx_epc: Option>,