mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-02-21 19:02:30 +00:00
vmm: interrupt: put KVM code into a kvm module
Signed-off-by: Wei Liu <liuwe@microsoft.com>
This commit is contained in:
parent
c31e747005
commit
2b8accf49a
@ -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;
|
||||
|
@ -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<E> {
|
||||
masked: bool,
|
||||
}
|
||||
|
||||
type KvmRoutingEntry = RoutingEntry<kvm_irq_routing_entry>;
|
||||
|
||||
pub struct MsiInterruptGroup<E> {
|
||||
vm_fd: Arc<dyn hypervisor::Vm>,
|
||||
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>>;
|
||||
}
|
||||
|
||||
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> {
|
||||
fn new(
|
||||
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>
|
||||
where
|
||||
E: Send + Sync,
|
||||
@ -345,8 +280,6 @@ pub struct MsiInterruptManager<E> {
|
||||
gsi_msi_routes: Arc<Mutex<HashMap<u32, RoutingEntry<E>>>>,
|
||||
}
|
||||
|
||||
pub type KvmMsiInterruptManager = MsiInterruptManager<kvm_irq_routing_entry>;
|
||||
|
||||
impl LegacyUserspaceInterruptManager {
|
||||
pub fn new(ioapic: Arc<Mutex<dyn InterruptController>>) -> 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<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),
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user