From f4af668d765577d4567fd19a70c226c1b2161a4a Mon Sep 17 00:00:00 2001 From: Muminul Islam Date: Fri, 4 Dec 2020 16:39:05 -0800 Subject: [PATCH] hypervisor, vmm: Implement MsiInterruptOps for mshv Co-Developed-by: Wei Liu Signed-off-by: Wei Liu Signed-off-by: Muminul Islam --- hypervisor/src/mshv/mod.rs | 19 ++++++++++++ vmm/src/device_manager.rs | 4 +++ vmm/src/interrupt.rs | 63 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+) diff --git a/hypervisor/src/mshv/mod.rs b/hypervisor/src/mshv/mod.rs index 490f6f030..5049a0aca 100644 --- a/hypervisor/src/mshv/mod.rs +++ b/hypervisor/src/mshv/mod.rs @@ -12,3 +12,22 @@ // x86_64 dependencies #[cfg(target_arch = "x86_64")] pub mod x86_64; + +#[derive(Copy, Clone, Debug)] +pub struct MshvIrqRoutingMsi { + pub address_lo: u32, + pub address_hi: u32, + pub data: u32, +} + +#[derive(Copy, Clone, Debug)] +pub enum MshvIrqRouting { + Msi(MshvIrqRoutingMsi), +} + +#[derive(Copy, Clone, Debug)] +pub struct MshvIrqRoutingEntry { + pub gsi: u32, + pub route: MshvIrqRouting, +} +pub type IrqRoutingEntry = MshvIrqRoutingEntry; diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index e58898465..681a9d83f 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -15,6 +15,8 @@ use crate::config::{DiskConfig, FsConfig, NetConfig, PmemConfig, VmConfig, Vsock use crate::device_tree::{DeviceNode, DeviceTree}; #[cfg(feature = "kvm")] use crate::interrupt::kvm::KvmMsiInterruptManager as MsiInterruptManager; +#[cfg(feature = "mshv")] +use crate::interrupt::mshv::MshvMsiInterruptManager as MsiInterruptManager; use crate::interrupt::LegacyUserspaceInterruptManager; use crate::memory_manager::{Error as MemoryManagerError, MemoryManager}; #[cfg(feature = "acpi")] @@ -47,6 +49,8 @@ use devices::{ use hypervisor::kvm_ioctls::*; #[cfg(target_arch = "aarch64")] use hypervisor::CpuState; +#[cfg(feature = "mshv")] +use hypervisor::IoEventAddress; use libc::TIOCGWINSZ; use libc::{MAP_NORESERVE, MAP_PRIVATE, MAP_SHARED, O_TMPFILE, PROT_READ, PROT_WRITE}; use pci::{ diff --git a/vmm/src/interrupt.rs b/vmm/src/interrupt.rs index 380891d1a..0c4756cb2 100644 --- a/vmm/src/interrupt.rs +++ b/vmm/src/interrupt.rs @@ -396,6 +396,69 @@ pub mod kvm { } } +#[cfg(feature = "mshv")] +pub mod mshv { + use super::*; + use hypervisor::mshv::*; + + type MshvMsiInterruptGroup = MsiInterruptGroup; + type MshvRoutingEntry = RoutingEntry; + pub type MshvMsiInterruptManager = MsiInterruptManager; + + impl RoutingEntryExt for MshvRoutingEntry { + fn make_entry( + _vm: &Arc, + gsi: u32, + config: &InterruptSourceConfig, + ) -> Result> { + if let InterruptSourceConfig::MsiIrq(cfg) = &config { + let route = MshvIrqRoutingEntry { + gsi, + route: MshvIrqRouting::Msi(MshvIrqRoutingMsi { + address_lo: cfg.low_addr, + address_hi: cfg.high_addr, + data: cfg.data, + }), + }; + let entry = MshvRoutingEntry { + route, + masked: false, + }; + + return Ok(Box::new(entry)); + } + + Err(io::Error::new( + io::ErrorKind::Other, + "Interrupt config type not supported", + )) + } + } + + impl MsiInterruptGroupOps for MshvMsiInterruptGroup { + fn set_gsi_routes( + &self, + routes: &HashMap>, + ) -> Result<()> { + let mut entry_vec: Vec = Vec::new(); + for (_, entry) in routes.iter() { + if entry.masked { + continue; + } + + entry_vec.push(entry.route); + } + + self.vm.set_gsi_routing(&entry_vec).map_err(|e| { + io::Error::new( + io::ErrorKind::Other, + format!("Failed setting GSI routing: {}", e), + ) + }) + } + } +} + #[cfg(target_arch = "aarch64")] #[cfg(test)] mod tests {