hypervisor, vmm: Implement MsiInterruptOps for mshv

Co-Developed-by: Wei Liu <liuwe@microsoft.com>
Signed-off-by: Wei Liu <liuwe@microsoft.com>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
This commit is contained in:
Muminul Islam 2020-12-04 16:39:05 -08:00 committed by Samuel Ortiz
parent 7fe5d276a3
commit f4af668d76
3 changed files with 86 additions and 0 deletions

View File

@ -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;

View File

@ -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::{

View File

@ -396,6 +396,69 @@ pub mod kvm {
}
}
#[cfg(feature = "mshv")]
pub mod mshv {
use super::*;
use hypervisor::mshv::*;
type MshvMsiInterruptGroup = MsiInterruptGroup<MshvIrqRoutingEntry>;
type MshvRoutingEntry = RoutingEntry<MshvIrqRoutingEntry>;
pub type MshvMsiInterruptManager = MsiInterruptManager<MshvIrqRoutingEntry>;
impl RoutingEntryExt for MshvRoutingEntry {
fn make_entry(
_vm: &Arc<dyn hypervisor::Vm>,
gsi: u32,
config: &InterruptSourceConfig,
) -> Result<Box<Self>> {
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<MshvIrqRoutingEntry> for MshvMsiInterruptGroup {
fn set_gsi_routes(
&self,
routes: &HashMap<u32, RoutingEntry<MshvIrqRoutingEntry>>,
) -> Result<()> {
let mut entry_vec: Vec<MshvIrqRoutingEntry> = 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 {