From 2b8accf49a6c891023aebc8381a56c0dff1f9a6d Mon Sep 17 00:00:00 2001 From: Wei Liu Date: Sat, 27 Jun 2020 16:32:51 +0000 Subject: [PATCH] vmm: interrupt: put KVM code into a kvm module Signed-off-by: Wei Liu --- vmm/src/device_manager.rs | 2 +- vmm/src/interrupt.rs | 136 +++++++++++++++++++------------------- 2 files changed, 70 insertions(+), 68 deletions(-) diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index becd2a98c..9a958646e 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -14,7 +14,7 @@ use crate::config::ConsoleOutputMode; use crate::config::DeviceConfig; use crate::config::{DiskConfig, FsConfig, NetConfig, PmemConfig, VmConfig, VsockConfig}; use crate::device_tree::{DeviceNode, DeviceTree}; -use crate::interrupt::{KvmMsiInterruptManager, LegacyUserspaceInterruptManager}; +use crate::interrupt::{kvm::KvmMsiInterruptManager, LegacyUserspaceInterruptManager}; use crate::memory_manager::{Error as MemoryManagerError, MemoryManager}; #[cfg(feature = "pci_support")] use crate::PciDeviceInfo; diff --git a/vmm/src/interrupt.rs b/vmm/src/interrupt.rs index 960b79c7a..8b7f5f87f 100644 --- a/vmm/src/interrupt.rs +++ b/vmm/src/interrupt.rs @@ -4,7 +4,6 @@ // use devices::interrupt_controller::InterruptController; -use hypervisor::kvm::{kvm_irq_routing, kvm_irq_routing_entry, KVM_IRQ_ROUTING_MSI}; use std::collections::HashMap; use std::io; @@ -108,8 +107,6 @@ pub struct RoutingEntry { masked: bool, } -type KvmRoutingEntry = RoutingEntry; - pub struct MsiInterruptGroup { vm_fd: Arc, gsi_msi_routes: Arc>>>, @@ -124,34 +121,6 @@ pub trait RoutingEntryExt { fn make_entry(gsi: u32, config: &InterruptSourceConfig) -> Result>; } -impl RoutingEntryExt for KvmRoutingEntry { - fn make_entry(gsi: u32, config: &InterruptSourceConfig) -> Result> { - if let InterruptSourceConfig::MsiIrq(cfg) = &config { - let mut kvm_route = kvm_irq_routing_entry { - gsi, - type_: KVM_IRQ_ROUTING_MSI, - ..Default::default() - }; - - kvm_route.u.msi.address_lo = cfg.low_addr; - kvm_route.u.msi.address_hi = cfg.high_addr; - kvm_route.u.msi.data = cfg.data; - - let kvm_entry = KvmRoutingEntry { - route: kvm_route, - masked: false, - }; - - return Ok(Box::new(kvm_entry)); - } - - Err(io::Error::new( - io::ErrorKind::Other, - "Interrupt config type not supported", - )) - } -} - impl MsiInterruptGroup { fn new( vm_fd: Arc, @@ -166,40 +135,6 @@ impl MsiInterruptGroup { } } -type KvmMsiInterruptGroup = MsiInterruptGroup; - -impl MsiInterruptGroupOps for KvmMsiInterruptGroup { - fn set_gsi_routes(&self) -> Result<()> { - let gsi_msi_routes = self.gsi_msi_routes.lock().unwrap(); - let mut entry_vec: Vec = Vec::new(); - for (_, entry) in gsi_msi_routes.iter() { - if entry.masked { - continue; - } - - entry_vec.push(entry.route); - } - - let mut irq_routing = - vec_with_array_field::(entry_vec.len()); - irq_routing[0].nr = entry_vec.len() as u32; - irq_routing[0].flags = 0; - - unsafe { - let entries: &mut [kvm_irq_routing_entry] = - irq_routing[0].entries.as_mut_slice(entry_vec.len()); - entries.copy_from_slice(&entry_vec); - } - - self.vm_fd.set_gsi_routing(&irq_routing[0]).map_err(|e| { - io::Error::new( - io::ErrorKind::Other, - format!("Failed setting GSI routing: {}", e), - ) - }) - } -} - impl InterruptSourceGroup for MsiInterruptGroup where E: Send + Sync, @@ -345,8 +280,6 @@ pub struct MsiInterruptManager { gsi_msi_routes: Arc>>>, } -pub type KvmMsiInterruptManager = MsiInterruptManager; - impl LegacyUserspaceInterruptManager { pub fn new(ioapic: Arc>) -> Self { LegacyUserspaceInterruptManager { ioapic } @@ -417,3 +350,72 @@ where Ok(()) } } + +pub mod kvm { + use super::*; + use hypervisor::kvm::{kvm_irq_routing, kvm_irq_routing_entry, KVM_IRQ_ROUTING_MSI}; + + type KvmMsiInterruptGroup = MsiInterruptGroup; + type KvmRoutingEntry = RoutingEntry; + pub type KvmMsiInterruptManager = MsiInterruptManager; + + impl RoutingEntryExt for KvmRoutingEntry { + fn make_entry(gsi: u32, config: &InterruptSourceConfig) -> Result> { + if let InterruptSourceConfig::MsiIrq(cfg) = &config { + let mut kvm_route = kvm_irq_routing_entry { + gsi, + type_: KVM_IRQ_ROUTING_MSI, + ..Default::default() + }; + + kvm_route.u.msi.address_lo = cfg.low_addr; + kvm_route.u.msi.address_hi = cfg.high_addr; + kvm_route.u.msi.data = cfg.data; + + let kvm_entry = KvmRoutingEntry { + route: kvm_route, + masked: false, + }; + + return Ok(Box::new(kvm_entry)); + } + + Err(io::Error::new( + io::ErrorKind::Other, + "Interrupt config type not supported", + )) + } + } + + impl MsiInterruptGroupOps for KvmMsiInterruptGroup { + fn set_gsi_routes(&self) -> Result<()> { + let gsi_msi_routes = self.gsi_msi_routes.lock().unwrap(); + let mut entry_vec: Vec = Vec::new(); + for (_, entry) in gsi_msi_routes.iter() { + if entry.masked { + continue; + } + + entry_vec.push(entry.route); + } + + let mut irq_routing = + vec_with_array_field::(entry_vec.len()); + irq_routing[0].nr = entry_vec.len() as u32; + irq_routing[0].flags = 0; + + unsafe { + let entries: &mut [kvm_irq_routing_entry] = + irq_routing[0].entries.as_mut_slice(entry_vec.len()); + entries.copy_from_slice(&entry_vec); + } + + self.vm_fd.set_gsi_routing(&irq_routing[0]).map_err(|e| { + io::Error::new( + io::ErrorKind::Other, + format!("Failed setting GSI routing: {}", e), + ) + }) + } + } +}