diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2021-06-21 18:31:52 +0200 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2021-06-25 10:53:46 +0200 |
commit | 9ce8af4d92d4772cb33d4ea9cbd5ebdb970c5172 (patch) | |
tree | 3696e62d9bcb81b9d12320b1c989f08e26c1202d | |
parent | ecba223da6215d6f6ce2d343b70b2e9a19bfb90b (diff) | |
download | qemu-9ce8af4d92d4772cb33d4ea9cbd5ebdb970c5172.zip qemu-9ce8af4d92d4772cb33d4ea9cbd5ebdb970c5172.tar.gz qemu-9ce8af4d92d4772cb33d4ea9cbd5ebdb970c5172.tar.bz2 |
target/i386: kvm: add support for TSC scaling
Linux 5.14 will add support for nested TSC scaling. Add the
corresponding feature in QEMU; to keep support for existing kernels,
do not add it to any processor yet.
The handling of the VMCS enumeration MSR is ugly; once we have more than
one case, we may want to add a table to check VMX features against.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | target/i386/cpu.c | 2 | ||||
-rw-r--r-- | target/i386/cpu.h | 1 | ||||
-rw-r--r-- | target/i386/kvm/kvm.c | 12 |
3 files changed, 10 insertions, 5 deletions
diff --git a/target/i386/cpu.c b/target/i386/cpu.c index a9fe166..d8f3ab3 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -1031,7 +1031,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { "vmx-invpcid-exit", "vmx-vmfunc", "vmx-shadow-vmcs", "vmx-encls-exit", "vmx-rdseed-exit", "vmx-pml", NULL, NULL, "vmx-xsaves", NULL, NULL, NULL, - NULL, NULL, NULL, NULL, + NULL, "vmx-tsc-scaling", NULL, NULL, NULL, NULL, NULL, NULL, }, .msr = { diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 1e11071..f7fa587 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -972,6 +972,7 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS]; #define VMX_SECONDARY_EXEC_RDSEED_EXITING 0x00010000 #define VMX_SECONDARY_EXEC_ENABLE_PML 0x00020000 #define VMX_SECONDARY_EXEC_XSAVES 0x00100000 +#define VMX_SECONDARY_EXEC_TSC_SCALING 0x02000000 #define VMX_PIN_BASED_EXT_INTR_MASK 0x00000001 #define VMX_PIN_BASED_NMI_EXITING 0x00000008 diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index ad950c3..04e4ec0 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -2700,8 +2700,6 @@ static uint64_t make_vmx_msr_value(uint32_t index, uint32_t features) return must_be_one | (((uint64_t)can_be_one) << 32); } -#define VMCS12_MAX_FIELD_INDEX (0x17) - static void kvm_msr_entry_add_vmx(X86CPU *cpu, FeatureWordArray f) { uint64_t kvm_vmx_basic = @@ -2791,8 +2789,14 @@ static void kvm_msr_entry_add_vmx(X86CPU *cpu, FeatureWordArray f) CR0_PE_MASK | CR0_PG_MASK | CR0_NE_MASK); kvm_msr_entry_add(cpu, MSR_IA32_VMX_CR4_FIXED0, CR4_VMXE_MASK); - kvm_msr_entry_add(cpu, MSR_IA32_VMX_VMCS_ENUM, - VMCS12_MAX_FIELD_INDEX << 1); + + if (f[FEAT_VMX_SECONDARY_CTLS] & VMX_SECONDARY_EXEC_TSC_SCALING) { + /* TSC multiplier (0x2032). */ + kvm_msr_entry_add(cpu, MSR_IA32_VMX_VMCS_ENUM, 0x32); + } else { + /* Preemption timer (0x482E). */ + kvm_msr_entry_add(cpu, MSR_IA32_VMX_VMCS_ENUM, 0x2E); + } } static void kvm_msr_entry_add_perf(X86CPU *cpu, FeatureWordArray f) |