Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 113 lines 3.1 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) 2020, Red Hat, Inc. 4 */ 5#include <fcntl.h> 6#include <stdio.h> 7#include <stdlib.h> 8#include <string.h> 9#include <sys/ioctl.h> 10 11#include "test_util.h" 12#include "kvm_util.h" 13#include "processor.h" 14 15static bool is_kvm_controlled_msr(u32 msr) 16{ 17 return msr == MSR_IA32_VMX_CR0_FIXED1 || msr == MSR_IA32_VMX_CR4_FIXED1; 18} 19 20/* 21 * For VMX MSRs with a "true" variant, KVM requires userspace to set the "true" 22 * MSR, and doesn't allow setting the hidden version. 23 */ 24static bool is_hidden_vmx_msr(u32 msr) 25{ 26 switch (msr) { 27 case MSR_IA32_VMX_PINBASED_CTLS: 28 case MSR_IA32_VMX_PROCBASED_CTLS: 29 case MSR_IA32_VMX_EXIT_CTLS: 30 case MSR_IA32_VMX_ENTRY_CTLS: 31 return true; 32 default: 33 return false; 34 } 35} 36 37static bool is_quirked_msr(u32 msr) 38{ 39 return msr != MSR_AMD64_DE_CFG; 40} 41 42static void test_feature_msr(u32 msr) 43{ 44 const u64 supported_mask = kvm_get_feature_msr(msr); 45 u64 reset_value = is_quirked_msr(msr) ? supported_mask : 0; 46 struct kvm_vcpu *vcpu; 47 struct kvm_vm *vm; 48 49 /* 50 * Don't bother testing KVM-controlled MSRs beyond verifying that the 51 * MSR can be read from userspace. Any value is effectively legal, as 52 * KVM is bound by x86 architecture, not by ABI. 53 */ 54 if (is_kvm_controlled_msr(msr)) 55 return; 56 57 /* 58 * More goofy behavior. KVM reports the host CPU's actual revision ID, 59 * but initializes the vCPU's revision ID to an arbitrary value. 60 */ 61 if (msr == MSR_IA32_UCODE_REV) 62 reset_value = host_cpu_is_intel ? 0x100000000ULL : 0x01000065; 63 64 /* 65 * For quirked MSRs, KVM's ABI is to initialize the vCPU's value to the 66 * full set of features supported by KVM. For non-quirked MSRs, and 67 * when the quirk is disabled, KVM must zero-initialize the MSR and let 68 * userspace do the configuration. 69 */ 70 vm = vm_create_with_one_vcpu(&vcpu, NULL); 71 TEST_ASSERT(vcpu_get_msr(vcpu, msr) == reset_value, 72 "Wanted 0x%lx for %squirked MSR 0x%x, got 0x%lx", 73 reset_value, is_quirked_msr(msr) ? "" : "non-", msr, 74 vcpu_get_msr(vcpu, msr)); 75 if (!is_hidden_vmx_msr(msr)) 76 vcpu_set_msr(vcpu, msr, supported_mask); 77 kvm_vm_free(vm); 78 79 if (is_hidden_vmx_msr(msr)) 80 return; 81 82 if (!kvm_has_cap(KVM_CAP_DISABLE_QUIRKS2) || 83 !(kvm_check_cap(KVM_CAP_DISABLE_QUIRKS2) & KVM_X86_QUIRK_STUFF_FEATURE_MSRS)) 84 return; 85 86 vm = vm_create(1); 87 vm_enable_cap(vm, KVM_CAP_DISABLE_QUIRKS2, KVM_X86_QUIRK_STUFF_FEATURE_MSRS); 88 89 vcpu = vm_vcpu_add(vm, 0, NULL); 90 TEST_ASSERT(!vcpu_get_msr(vcpu, msr), 91 "Quirk disabled, wanted '0' for MSR 0x%x, got 0x%lx", 92 msr, vcpu_get_msr(vcpu, msr)); 93 kvm_vm_free(vm); 94} 95 96int main(int argc, char *argv[]) 97{ 98 const struct kvm_msr_list *feature_list; 99 int i; 100 101 /* 102 * Skip the entire test if MSR_FEATURES isn't supported, other tests 103 * will cover the "regular" list of MSRs, the coverage here is purely 104 * opportunistic and not interesting on its own. 105 */ 106 TEST_REQUIRE(kvm_has_cap(KVM_CAP_GET_MSR_FEATURES)); 107 108 (void)kvm_get_msr_index_list(); 109 110 feature_list = kvm_get_feature_msr_index_list(); 111 for (i = 0; i < feature_list->nmsrs; i++) 112 test_feature_msr(feature_list->indices[i]); 113}