From 9b48ee38cb384a8b7d41f6dab5b59794491616a3 Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Tue, 15 Sep 2020 16:15:50 +0100 Subject: [PATCH] hypervisor: Support enabling HyperV synthetic interrupt controller This adds a KVM HyperV synthetic interrupt controller in place of the emulated PIC. Signed-off-by: Rob Bradford --- hypervisor/src/cpu.rs | 10 ++++++++++ hypervisor/src/kvm/mod.rs | 13 ++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/hypervisor/src/cpu.rs b/hypervisor/src/cpu.rs index 16b5ed062..92de49362 100644 --- a/hypervisor/src/cpu.rs +++ b/hypervisor/src/cpu.rs @@ -148,6 +148,11 @@ pub enum HypervisorCpuError { /// #[error("Failed to notify guest its clock was paused: {0}")] NotifyGuestClockPaused(#[source] anyhow::Error), + /// + /// Enabling HyperV SynIC error + /// + #[error("Failed to enable HyperV SynIC")] + EnableHyperVSynIC(#[source] anyhow::Error), } #[derive(Debug)] @@ -210,6 +215,11 @@ pub trait Vcpu: Send + Sync { fn set_cpuid2(&self, cpuid: &CpuId) -> Result<()>; #[cfg(target_arch = "x86_64")] /// + /// X86 specific call to enable HyperV SynIC + /// + fn enable_hyperv_synic(&self) -> Result<()>; + #[cfg(target_arch = "x86_64")] + /// /// X86 specific call to retrieve the CPUID registers. /// fn get_cpuid2(&self, num_entries: usize) -> Result; diff --git a/hypervisor/src/kvm/mod.rs b/hypervisor/src/kvm/mod.rs index 40dc11837..2049459a0 100644 --- a/hypervisor/src/kvm/mod.rs +++ b/hypervisor/src/kvm/mod.rs @@ -38,7 +38,7 @@ pub use x86_64::{ }; #[cfg(target_arch = "x86_64")] -use kvm_bindings::{kvm_enable_cap, MsrList, KVM_CAP_SPLIT_IRQCHIP}; +use kvm_bindings::{kvm_enable_cap, MsrList, KVM_CAP_HYPERV_SYNIC, KVM_CAP_SPLIT_IRQCHIP}; #[cfg(target_arch = "x86_64")] use crate::arch::x86::NUM_IOAPIC_PINS; @@ -550,6 +550,17 @@ impl cpu::Vcpu for KvmVcpu { .set_cpuid2(cpuid) .map_err(|e| cpu::HypervisorCpuError::SetCpuid(e.into())) } + #[cfg(target_arch = "x86_64")] + /// + /// X86 specific call to enable HyperV SynIC + /// + fn enable_hyperv_synic(&self) -> cpu::Result<()> { + let mut cap: kvm_enable_cap = Default::default(); + cap.cap = KVM_CAP_HYPERV_SYNIC; + self.fd + .enable_cap(&cap) + .map_err(|e| cpu::HypervisorCpuError::EnableHyperVSynIC(e.into())) + } /// /// X86 specific call to retrieve the CPUID registers. ///