mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-05 18:20:34 +00:00
x86_64: add tsc_deadline_timer support
Support TSC deadline mode of LAPIC timer, this can potentially increase the precision of guest timer. BUG=None TEST=launch linux guest and run `lscpu`, tsc_deadline_timer is present in the output. Change-Id: I7adc87827a51ba8d1866ebee201759f2769ba664 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1951429 Reviewed-by: Daniel Verkamp <dverkamp@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Zhuocheng Ding <zhuocheng.ding@intel.corp-partner.google.com>
This commit is contained in:
parent
eaff194759
commit
1918627791
1 changed files with 13 additions and 3 deletions
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue