Commit bd827bd7 authored by Vitaly Kuznetsov's avatar Vitaly Kuznetsov Committed by Paolo Bonzini

KVM: selftests: Test Hyper-V invariant TSC control

Add a test for the newly introduced Hyper-V invariant TSC control feature:
- HV_X64_MSR_TSC_INVARIANT_CONTROL is not available without
 HV_ACCESS_TSC_INVARIANT CPUID bit set and available with it.
- BIT(0) of HV_X64_MSR_TSC_INVARIANT_CONTROL controls the filtering of
architectural invariant TSC (CPUID.80000007H:EDX[8]) bit.
Signed-off-by: default avatarVitaly Kuznetsov <vkuznets@redhat.com>
Reviewed-by: default avatarSean Christopherson <seanjc@google.com>
Message-Id: <20221013095849.705943-8-vkuznets@redhat.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 91a0b547
...@@ -335,4 +335,7 @@ struct hyperv_test_pages { ...@@ -335,4 +335,7 @@ struct hyperv_test_pages {
struct hyperv_test_pages *vcpu_alloc_hyperv_test_pages(struct kvm_vm *vm, struct hyperv_test_pages *vcpu_alloc_hyperv_test_pages(struct kvm_vm *vm,
vm_vaddr_t *p_hv_pages_gva); vm_vaddr_t *p_hv_pages_gva);
/* HV_X64_MSR_TSC_INVARIANT_CONTROL bits */
#define HV_INVARIANT_TSC_EXPOSED BIT_ULL(0)
#endif /* !SELFTEST_KVM_HYPERV_H */ #endif /* !SELFTEST_KVM_HYPERV_H */
...@@ -137,6 +137,7 @@ struct kvm_x86_cpu_feature { ...@@ -137,6 +137,7 @@ struct kvm_x86_cpu_feature {
#define X86_FEATURE_GBPAGES KVM_X86_CPU_FEATURE(0x80000001, 0, EDX, 26) #define X86_FEATURE_GBPAGES KVM_X86_CPU_FEATURE(0x80000001, 0, EDX, 26)
#define X86_FEATURE_RDTSCP KVM_X86_CPU_FEATURE(0x80000001, 0, EDX, 27) #define X86_FEATURE_RDTSCP KVM_X86_CPU_FEATURE(0x80000001, 0, EDX, 27)
#define X86_FEATURE_LM KVM_X86_CPU_FEATURE(0x80000001, 0, EDX, 29) #define X86_FEATURE_LM KVM_X86_CPU_FEATURE(0x80000001, 0, EDX, 29)
#define X86_FEATURE_INVTSC KVM_X86_CPU_FEATURE(0x80000007, 0, EDX, 8)
#define X86_FEATURE_RDPRU KVM_X86_CPU_FEATURE(0x80000008, 0, EBX, 4) #define X86_FEATURE_RDPRU KVM_X86_CPU_FEATURE(0x80000008, 0, EBX, 4)
#define X86_FEATURE_AMD_IBPB KVM_X86_CPU_FEATURE(0x80000008, 0, EBX, 12) #define X86_FEATURE_AMD_IBPB KVM_X86_CPU_FEATURE(0x80000008, 0, EBX, 12)
#define X86_FEATURE_NPT KVM_X86_CPU_FEATURE(0x8000000A, 0, EDX, 0) #define X86_FEATURE_NPT KVM_X86_CPU_FEATURE(0x8000000A, 0, EDX, 0)
......
...@@ -63,6 +63,16 @@ static void guest_msr(struct msr_data *msr) ...@@ -63,6 +63,16 @@ static void guest_msr(struct msr_data *msr)
if (msr->write) if (msr->write)
GUEST_ASSERT_3(msr_val == msr->write_val, msr->idx, GUEST_ASSERT_3(msr_val == msr->write_val, msr->idx,
msr_val, msr->write_val); msr_val, msr->write_val);
/* Invariant TSC bit appears when TSC invariant control MSR is written to */
if (msr->idx == HV_X64_MSR_TSC_INVARIANT_CONTROL) {
if (!this_cpu_has(HV_ACCESS_TSC_INVARIANT))
GUEST_ASSERT(this_cpu_has(X86_FEATURE_INVTSC));
else
GUEST_ASSERT(this_cpu_has(X86_FEATURE_INVTSC) ==
!!(msr_val & HV_INVARIANT_TSC_EXPOSED));
}
done: done:
GUEST_DONE(); GUEST_DONE();
} }
...@@ -118,6 +128,7 @@ static void guest_test_msrs_access(void) ...@@ -118,6 +128,7 @@ static void guest_test_msrs_access(void)
int stage = 0; int stage = 0;
vm_vaddr_t msr_gva; vm_vaddr_t msr_gva;
struct msr_data *msr; struct msr_data *msr;
bool has_invtsc = kvm_cpu_has(X86_FEATURE_INVTSC);
while (true) { while (true) {
vm = vm_create_with_one_vcpu(&vcpu, guest_msr); vm = vm_create_with_one_vcpu(&vcpu, guest_msr);
...@@ -435,6 +446,42 @@ static void guest_test_msrs_access(void) ...@@ -435,6 +446,42 @@ static void guest_test_msrs_access(void)
break; break;
case 44: case 44:
/* MSR is not available when CPUID feature bit is unset */
if (!has_invtsc)
continue;
msr->idx = HV_X64_MSR_TSC_INVARIANT_CONTROL;
msr->write = false;
msr->fault_expected = true;
break;
case 45:
/* MSR is vailable when CPUID feature bit is set */
if (!has_invtsc)
continue;
vcpu_set_cpuid_feature(vcpu, HV_ACCESS_TSC_INVARIANT);
msr->idx = HV_X64_MSR_TSC_INVARIANT_CONTROL;
msr->write = false;
msr->fault_expected = false;
break;
case 46:
/* Writing bits other than 0 is forbidden */
if (!has_invtsc)
continue;
msr->idx = HV_X64_MSR_TSC_INVARIANT_CONTROL;
msr->write = true;
msr->write_val = 0xdeadbeef;
msr->fault_expected = true;
break;
case 47:
/* Setting bit 0 enables the feature */
if (!has_invtsc)
continue;
msr->idx = HV_X64_MSR_TSC_INVARIANT_CONTROL;
msr->write = true;
msr->write_val = 1;
msr->fault_expected = false;
break;
default:
kvm_vm_free(vm); kvm_vm_free(vm);
return; return;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment