mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-15 00:04:15 +08:00
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: 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>
This commit is contained in:
parent
91a0b5478a
commit
bd827bd775
@ -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 */
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
}
|
||||
@ -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);
|
||||
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user