mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
vmm: interrupt: put KVM code into a kvm module
Signed-off-by: Wei Liu <liuwe@microsoft.com>
This commit is contained in:
@@ -14,7 +14,7 @@ use crate::config::ConsoleOutputMode;
|
|||||||
use crate::config::DeviceConfig;
|
use crate::config::DeviceConfig;
|
||||||
use crate::config::{DiskConfig, FsConfig, NetConfig, PmemConfig, VmConfig, VsockConfig};
|
use crate::config::{DiskConfig, FsConfig, NetConfig, PmemConfig, VmConfig, VsockConfig};
|
||||||
use crate::device_tree::{DeviceNode, DeviceTree};
|
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};
|
use crate::memory_manager::{Error as MemoryManagerError, MemoryManager};
|
||||||
#[cfg(feature = "pci_support")]
|
#[cfg(feature = "pci_support")]
|
||||||
use crate::PciDeviceInfo;
|
use crate::PciDeviceInfo;
|
||||||
|
|||||||
+69
-67
@@ -4,7 +4,6 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
use devices::interrupt_controller::InterruptController;
|
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::collections::HashMap;
|
||||||
use std::io;
|
use std::io;
|
||||||
@@ -108,8 +107,6 @@ pub struct RoutingEntry<E> {
|
|||||||
masked: bool,
|
masked: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
type KvmRoutingEntry = RoutingEntry<kvm_irq_routing_entry>;
|
|
||||||
|
|
||||||
pub struct MsiInterruptGroup<E> {
|
pub struct MsiInterruptGroup<E> {
|
||||||
vm_fd: Arc<dyn hypervisor::Vm>,
|
vm_fd: Arc<dyn hypervisor::Vm>,
|
||||||
gsi_msi_routes: Arc<Mutex<HashMap<u32, RoutingEntry<E>>>>,
|
gsi_msi_routes: Arc<Mutex<HashMap<u32, RoutingEntry<E>>>>,
|
||||||
@@ -124,34 +121,6 @@ pub trait RoutingEntryExt {
|
|||||||
fn make_entry(gsi: u32, config: &InterruptSourceConfig) -> Result<Box<Self>>;
|
fn make_entry(gsi: u32, config: &InterruptSourceConfig) -> Result<Box<Self>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RoutingEntryExt for KvmRoutingEntry {
|
|
||||||
fn make_entry(gsi: u32, config: &InterruptSourceConfig) -> Result<Box<Self>> {
|
|
||||||
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<E> MsiInterruptGroup<E> {
|
impl<E> MsiInterruptGroup<E> {
|
||||||
fn new(
|
fn new(
|
||||||
vm_fd: Arc<dyn hypervisor::Vm>,
|
vm_fd: Arc<dyn hypervisor::Vm>,
|
||||||
@@ -166,40 +135,6 @@ impl<E> MsiInterruptGroup<E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type KvmMsiInterruptGroup = MsiInterruptGroup<kvm_irq_routing_entry>;
|
|
||||||
|
|
||||||
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<kvm_irq_routing_entry> = 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::<kvm_irq_routing, kvm_irq_routing_entry>(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<E> InterruptSourceGroup for MsiInterruptGroup<E>
|
impl<E> InterruptSourceGroup for MsiInterruptGroup<E>
|
||||||
where
|
where
|
||||||
E: Send + Sync,
|
E: Send + Sync,
|
||||||
@@ -345,8 +280,6 @@ pub struct MsiInterruptManager<E> {
|
|||||||
gsi_msi_routes: Arc<Mutex<HashMap<u32, RoutingEntry<E>>>>,
|
gsi_msi_routes: Arc<Mutex<HashMap<u32, RoutingEntry<E>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type KvmMsiInterruptManager = MsiInterruptManager<kvm_irq_routing_entry>;
|
|
||||||
|
|
||||||
impl LegacyUserspaceInterruptManager {
|
impl LegacyUserspaceInterruptManager {
|
||||||
pub fn new(ioapic: Arc<Mutex<dyn InterruptController>>) -> Self {
|
pub fn new(ioapic: Arc<Mutex<dyn InterruptController>>) -> Self {
|
||||||
LegacyUserspaceInterruptManager { ioapic }
|
LegacyUserspaceInterruptManager { ioapic }
|
||||||
@@ -417,3 +350,72 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub mod kvm {
|
||||||
|
use super::*;
|
||||||
|
use hypervisor::kvm::{kvm_irq_routing, kvm_irq_routing_entry, KVM_IRQ_ROUTING_MSI};
|
||||||
|
|
||||||
|
type KvmMsiInterruptGroup = MsiInterruptGroup<kvm_irq_routing_entry>;
|
||||||
|
type KvmRoutingEntry = RoutingEntry<kvm_irq_routing_entry>;
|
||||||
|
pub type KvmMsiInterruptManager = MsiInterruptManager<kvm_irq_routing_entry>;
|
||||||
|
|
||||||
|
impl RoutingEntryExt for KvmRoutingEntry {
|
||||||
|
fn make_entry(gsi: u32, config: &InterruptSourceConfig) -> Result<Box<Self>> {
|
||||||
|
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<kvm_irq_routing_entry> = 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::<kvm_irq_routing, kvm_irq_routing_entry>(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),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user