diff --git a/x86_64/src/cpuid.rs b/x86_64/src/cpuid.rs index 5710120995..a42b6622da 100644 --- a/x86_64/src/cpuid.rs +++ b/x86_64/src/cpuid.rs @@ -47,10 +47,16 @@ const EBX_CLFLUSH_SIZE_SHIFT: u32 = 8; // Bytes flushed when executing CLFLUSH. const EBX_CPU_COUNT_SHIFT: u32 = 16; // Index of this CPU. const EBX_CPUID_SHIFT: u32 = 24; // Index of this CPU. const ECX_EPB_SHIFT: u32 = 3; // "Energy Performance Bias" bit. +const ECX_TSC_DEADLINE_TIMER_SHIFT: u32 = 24; // TSC deadline mode of APIC timer const ECX_HYPERVISOR_SHIFT: u32 = 31; // Flag to be set when the cpu is running on a hypervisor. const EDX_HTT_SHIFT: u32 = 28; // Hyper Threading Enabled. -fn filter_cpuid(cpu_id: u64, cpu_count: u64, kvm_cpuid: &mut kvm::CpuId) -> Result<()> { +fn filter_cpuid( + cpu_id: u64, + cpu_count: u64, + kvm_cpuid: &mut kvm::CpuId, + kvm: &kvm::Kvm, +) -> Result<()> { let entries = kvm_cpuid.mut_entries_slice(); for entry in entries { @@ -60,6 +66,9 @@ fn filter_cpuid(cpu_id: u64, cpu_count: u64, kvm_cpuid: &mut kvm::CpuId) -> Resu if entry.index == 0 { entry.ecx |= 1 << ECX_HYPERVISOR_SHIFT; } + if kvm.check_extension(kvm::Cap::TscDeadlineTimer) { + entry.ecx |= 1 << ECX_TSC_DEADLINE_TIMER_SHIFT; + } entry.ebx = (cpu_id << EBX_CPUID_SHIFT) as u32 | (EBX_CLFLUSH_CACHELINE << EBX_CLFLUSH_SIZE_SHIFT); if cpu_count > 1 { @@ -115,7 +124,7 @@ pub fn setup_cpuid(kvm: &kvm::Kvm, vcpu: &kvm::Vcpu, cpu_id: u64, nrcpus: u64) - .get_supported_cpuid() .map_err(Error::GetSupportedCpusFailed)?; - filter_cpuid(cpu_id, nrcpus, &mut kvm_cpuid)?; + filter_cpuid(cpu_id, nrcpus, &mut kvm_cpuid, kvm)?; vcpu.set_cpuid2(&kvm_cpuid) .map_err(Error::SetSupportedCpusFailed) @@ -163,13 +172,14 @@ mod tests { #[test] fn feature_and_vendor_name() { let mut cpuid = kvm::CpuId::new(2); + let kvm = kvm::Kvm::new().unwrap(); let entries = cpuid.mut_entries_slice(); entries[0].function = 0; entries[1].function = 1; entries[1].ecx = 0x10; entries[1].edx = 0; - assert_eq!(Ok(()), filter_cpuid(1, 2, &mut cpuid)); + assert_eq!(Ok(()), filter_cpuid(1, 2, &mut cpuid, &kvm)); let entries = cpuid.mut_entries_slice(); assert_eq!(entries[0].function, 0);