0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/bitmap.h>
0012 #include "kvm_util.h"
0013 #include "vmx.h"
0014
0015 static void vmx_fixed1_msr_test(struct kvm_vcpu *vcpu, uint32_t msr_index,
0016 uint64_t mask)
0017 {
0018 uint64_t val = vcpu_get_msr(vcpu, msr_index);
0019 uint64_t bit;
0020
0021 mask &= val;
0022
0023 for_each_set_bit(bit, &mask, 64) {
0024 vcpu_set_msr(vcpu, msr_index, val & ~BIT_ULL(bit));
0025 vcpu_set_msr(vcpu, msr_index, val);
0026 }
0027 }
0028
0029 static void vmx_fixed0_msr_test(struct kvm_vcpu *vcpu, uint32_t msr_index,
0030 uint64_t mask)
0031 {
0032 uint64_t val = vcpu_get_msr(vcpu, msr_index);
0033 uint64_t bit;
0034
0035 mask = ~mask | val;
0036
0037 for_each_clear_bit(bit, &mask, 64) {
0038 vcpu_set_msr(vcpu, msr_index, val | BIT_ULL(bit));
0039 vcpu_set_msr(vcpu, msr_index, val);
0040 }
0041 }
0042
0043 static void vmx_fixed0and1_msr_test(struct kvm_vcpu *vcpu, uint32_t msr_index)
0044 {
0045 vmx_fixed0_msr_test(vcpu, msr_index, GENMASK_ULL(31, 0));
0046 vmx_fixed1_msr_test(vcpu, msr_index, GENMASK_ULL(63, 32));
0047 }
0048
0049 static void vmx_save_restore_msrs_test(struct kvm_vcpu *vcpu)
0050 {
0051 vcpu_set_msr(vcpu, MSR_IA32_VMX_VMCS_ENUM, 0);
0052 vcpu_set_msr(vcpu, MSR_IA32_VMX_VMCS_ENUM, -1ull);
0053
0054 vmx_fixed1_msr_test(vcpu, MSR_IA32_VMX_BASIC,
0055 BIT_ULL(49) | BIT_ULL(54) | BIT_ULL(55));
0056
0057 vmx_fixed1_msr_test(vcpu, MSR_IA32_VMX_MISC,
0058 BIT_ULL(5) | GENMASK_ULL(8, 6) | BIT_ULL(14) |
0059 BIT_ULL(15) | BIT_ULL(28) | BIT_ULL(29) | BIT_ULL(30));
0060
0061 vmx_fixed0and1_msr_test(vcpu, MSR_IA32_VMX_PROCBASED_CTLS2);
0062 vmx_fixed1_msr_test(vcpu, MSR_IA32_VMX_EPT_VPID_CAP, -1ull);
0063 vmx_fixed0and1_msr_test(vcpu, MSR_IA32_VMX_TRUE_PINBASED_CTLS);
0064 vmx_fixed0and1_msr_test(vcpu, MSR_IA32_VMX_TRUE_PROCBASED_CTLS);
0065 vmx_fixed0and1_msr_test(vcpu, MSR_IA32_VMX_TRUE_EXIT_CTLS);
0066 vmx_fixed0and1_msr_test(vcpu, MSR_IA32_VMX_TRUE_ENTRY_CTLS);
0067 vmx_fixed1_msr_test(vcpu, MSR_IA32_VMX_VMFUNC, -1ull);
0068 }
0069
0070 int main(void)
0071 {
0072 struct kvm_vcpu *vcpu;
0073 struct kvm_vm *vm;
0074
0075 TEST_REQUIRE(kvm_has_cap(KVM_CAP_DISABLE_QUIRKS2));
0076 TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_VMX));
0077
0078
0079 vm = vm_create_with_one_vcpu(&vcpu, NULL);
0080
0081 vmx_save_restore_msrs_test(vcpu);
0082
0083 kvm_vm_free(vm);
0084 }