From ccdea0274c6ebb60375ca1197b3d0043d1afb46a Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Tue, 9 Feb 2021 14:39:50 +0000 Subject: [PATCH] vmm, arch: Move KVM HyperV emulation handling to shared CPUID code Move the code for populating the CPUID with KVM HyperV emulation details from the per-vCPU CPUID handling code to the shared CPUID handling code. Signed-off-by: Rob Bradford --- arch/src/x86_64/mod.rs | 52 ------------------------------------ vmm/src/cpu.rs | 60 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 59 insertions(+), 53 deletions(-) diff --git a/arch/src/x86_64/mod.rs b/arch/src/x86_64/mod.rs index de8e86c08..fa0a54c7c 100644 --- a/arch/src/x86_64/mod.rs +++ b/arch/src/x86_64/mod.rs @@ -341,58 +341,6 @@ pub fn configure_vcpu( CpuidPatch::set_cpuid_reg(&mut cpuid, 0xb, None, CpuidReg::EDX, u32::from(id)); CpuidPatch::set_cpuid_reg(&mut cpuid, 0x1f, None, CpuidReg::EDX, u32::from(id)); - if kvm_hyperv { - // Remove conflicting entries - cpuid.retain(|c| c.function != 0x4000_0000); - cpuid.retain(|c| c.function != 0x4000_0001); - - // See "Hypervisor Top Level Functional Specification" for details - // Compliance with "Hv#1" requires leaves up to 0x4000_000a - cpuid - .push(CpuIdEntry { - function: 0x40000000, - eax: 0x4000000a, // Maximum cpuid leaf - ebx: 0x756e694c, // "Linu" - ecx: 0x564b2078, // "x KV" - edx: 0x7648204d, // "M Hv" - ..Default::default() - }) - .map_err(|_| Error::PopulatingCpuid)?; - cpuid - .push(CpuIdEntry { - function: 0x40000001, - eax: 0x31237648, // "Hv#1" - ..Default::default() - }) - .map_err(|_| Error::PopulatingCpuid)?; - cpuid - .push(CpuIdEntry { - function: 0x40000002, - eax: 0x3839, // "Build number" - ebx: 0xa0000, // "Version" - ..Default::default() - }) - .map_err(|_| Error::PopulatingCpuid)?; - cpuid - .push(CpuIdEntry { - function: 0x4000_0003, - eax: 1 << 1 // AccessPartitionReferenceCounter - | 1 << 2 // AccessSynicRegs - | 1 << 3 // AccessSyntheticTimerRegs - | 1 << 9, // AccessPartitionReferenceTsc - ..Default::default() - }) - .map_err(|_| Error::PopulatingCpuid)?; - for i in 0x4000_0004..=0x4000_000a { - cpuid - .push(CpuIdEntry { - function: i, - ..Default::default() - }) - .map_err(|_| Error::PopulatingCpuid)?; - } - } - fd.set_cpuid2(&cpuid) .map_err(|e| Error::SetSupportedCpusFailed(e.into()))?; diff --git a/vmm/src/cpu.rs b/vmm/src/cpu.rs index 1de8e6065..dac4c2288 100644 --- a/vmm/src/cpu.rs +++ b/vmm/src/cpu.rs @@ -554,7 +554,13 @@ impl CpuManager { #[cfg(target_arch = "x86_64")] let cpuid = { let phys_bits = physical_bits(config.max_phys_bits); - CpuManager::patch_cpuid(hypervisor, &config.topology, sgx_epc_sections, phys_bits)? + CpuManager::patch_cpuid( + hypervisor, + &config.topology, + sgx_epc_sections, + phys_bits, + config.kvm_hyperv, + )? }; let device_manager = device_manager.lock().unwrap(); @@ -604,6 +610,7 @@ impl CpuManager { topology: &Option, sgx_epc_sections: Option>, phys_bits: u8, + kvm_hyperv: bool, ) -> Result { let mut cpuid_patches = Vec::new(); @@ -683,6 +690,57 @@ impl CpuManager { .unwrap(); } + if kvm_hyperv { + // Remove conflicting entries + cpuid.retain(|c| c.function != 0x4000_0000); + cpuid.retain(|c| c.function != 0x4000_0001); + // See "Hypervisor Top Level Functional Specification" for details + // Compliance with "Hv#1" requires leaves up to 0x4000_000a + cpuid + .push(CpuIdEntry { + function: 0x40000000, + eax: 0x4000000a, // Maximum cpuid leaf + ebx: 0x756e694c, // "Linu" + ecx: 0x564b2078, // "x KV" + edx: 0x7648204d, // "M Hv" + ..Default::default() + }) + .unwrap(); + cpuid + .push(CpuIdEntry { + function: 0x40000001, + eax: 0x31237648, // "Hv#1" + ..Default::default() + }) + .unwrap(); + cpuid + .push(CpuIdEntry { + function: 0x40000002, + eax: 0x3839, // "Build number" + ebx: 0xa0000, // "Version" + ..Default::default() + }) + .unwrap(); + cpuid + .push(CpuIdEntry { + function: 0x4000_0003, + eax: 1 << 1 // AccessPartitionReferenceCounter + | 1 << 2 // AccessSynicRegs + | 1 << 3 // AccessSyntheticTimerRegs + | 1 << 9, // AccessPartitionReferenceTsc + ..Default::default() + }) + .unwrap(); + for i in 0x4000_0004..=0x4000_000a { + cpuid + .push(CpuIdEntry { + function: i, + ..Default::default() + }) + .unwrap(); + } + } + Ok(cpuid) }