Skip to content

Commit

Permalink
KVM: selftests: Test Hyper-V invariant TSC control
Browse files Browse the repository at this point in the history
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: Vitaly Kuznetsov <vkuznets@redhat.com>
Reviewed-by: Sean Christopherson <seanjc@google.com>
Message-Id: <20221013095849.705943-8-vkuznets@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
  • Loading branch information
vittyvk authored and bonzini committed Dec 29, 2022
1 parent 91a0b54 commit bd827bd
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 0 deletions.
3 changes: 3 additions & 0 deletions tools/testing/selftests/kvm/include/x86_64/hyperv.h
Original file line number Diff line number Diff line change
Expand Up @@ -335,4 +335,7 @@ struct hyperv_test_pages {
struct hyperv_test_pages *vcpu_alloc_hyperv_test_pages(struct kvm_vm *vm,
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 */
1 change: 1 addition & 0 deletions tools/testing/selftests/kvm/include/x86_64/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ struct kvm_x86_cpu_feature {
#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_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_AMD_IBPB KVM_X86_CPU_FEATURE(0x80000008, 0, EBX, 12)
#define X86_FEATURE_NPT KVM_X86_CPU_FEATURE(0x8000000A, 0, EDX, 0)
Expand Down
47 changes: 47 additions & 0 deletions tools/testing/selftests/kvm/x86_64/hyperv_features.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,16 @@ static void guest_msr(struct msr_data *msr)
if (msr->write)
GUEST_ASSERT_3(msr_val == msr->write_val, msr->idx,
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:
GUEST_DONE();
}
Expand Down Expand Up @@ -118,6 +128,7 @@ static void guest_test_msrs_access(void)
int stage = 0;
vm_vaddr_t msr_gva;
struct msr_data *msr;
bool has_invtsc = kvm_cpu_has(X86_FEATURE_INVTSC);

while (true) {
vm = vm_create_with_one_vcpu(&vcpu, guest_msr);
Expand Down Expand Up @@ -435,6 +446,42 @@ static void guest_test_msrs_access(void)
break;

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);
return;
}
Expand Down

0 comments on commit bd827bd

Please sign in to comment.