linux/tools/testing/selftests/kvm/x86/feature_msrs_test.c
David Matlack 0c3a877469 KVM: selftests: Use u32 instead of uint32_t
Use u32 instead of uint32_t to make the KVM selftests code more concise
and more similar to the kernel (since selftests are primarily developed
by kernel developers).

This commit was generated with the following command:

  git ls-files tools/testing/selftests/kvm | xargs sed -i 's/uint32_t/u32/g'

Then by manually adjusting whitespace to make checkpatch.pl happy.

No functional change intended.

Signed-off-by: David Matlack <dmatlack@google.com>
Link: https://patch.msgid.link/20260420212004.3938325-7-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
2026-04-20 14:54:16 -07:00

114 lines
3.0 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2020, Red Hat, Inc.
*/
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include "test_util.h"
#include "kvm_util.h"
#include "processor.h"
static bool is_kvm_controlled_msr(u32 msr)
{
return msr == MSR_IA32_VMX_CR0_FIXED1 || msr == MSR_IA32_VMX_CR4_FIXED1;
}
/*
* For VMX MSRs with a "true" variant, KVM requires userspace to set the "true"
* MSR, and doesn't allow setting the hidden version.
*/
static bool is_hidden_vmx_msr(u32 msr)
{
switch (msr) {
case MSR_IA32_VMX_PINBASED_CTLS:
case MSR_IA32_VMX_PROCBASED_CTLS:
case MSR_IA32_VMX_EXIT_CTLS:
case MSR_IA32_VMX_ENTRY_CTLS:
return true;
default:
return false;
}
}
static bool is_quirked_msr(u32 msr)
{
return msr != MSR_AMD64_DE_CFG;
}
static void test_feature_msr(u32 msr)
{
const u64 supported_mask = kvm_get_feature_msr(msr);
u64 reset_value = is_quirked_msr(msr) ? supported_mask : 0;
struct kvm_vcpu *vcpu;
struct kvm_vm *vm;
/*
* Don't bother testing KVM-controlled MSRs beyond verifying that the
* MSR can be read from userspace. Any value is effectively legal, as
* KVM is bound by x86 architecture, not by ABI.
*/
if (is_kvm_controlled_msr(msr))
return;
/*
* More goofy behavior. KVM reports the host CPU's actual revision ID,
* but initializes the vCPU's revision ID to an arbitrary value.
*/
if (msr == MSR_IA32_UCODE_REV)
reset_value = host_cpu_is_intel ? 0x100000000ULL : 0x01000065;
/*
* For quirked MSRs, KVM's ABI is to initialize the vCPU's value to the
* full set of features supported by KVM. For non-quirked MSRs, and
* when the quirk is disabled, KVM must zero-initialize the MSR and let
* userspace do the configuration.
*/
vm = vm_create_with_one_vcpu(&vcpu, NULL);
TEST_ASSERT(vcpu_get_msr(vcpu, msr) == reset_value,
"Wanted 0x%lx for %squirked MSR 0x%x, got 0x%lx",
reset_value, is_quirked_msr(msr) ? "" : "non-", msr,
vcpu_get_msr(vcpu, msr));
if (!is_hidden_vmx_msr(msr))
vcpu_set_msr(vcpu, msr, supported_mask);
kvm_vm_free(vm);
if (is_hidden_vmx_msr(msr))
return;
if (!kvm_has_cap(KVM_CAP_DISABLE_QUIRKS2) ||
!(kvm_check_cap(KVM_CAP_DISABLE_QUIRKS2) & KVM_X86_QUIRK_STUFF_FEATURE_MSRS))
return;
vm = vm_create(1);
vm_enable_cap(vm, KVM_CAP_DISABLE_QUIRKS2, KVM_X86_QUIRK_STUFF_FEATURE_MSRS);
vcpu = vm_vcpu_add(vm, 0, NULL);
TEST_ASSERT(!vcpu_get_msr(vcpu, msr),
"Quirk disabled, wanted '0' for MSR 0x%x, got 0x%lx",
msr, vcpu_get_msr(vcpu, msr));
kvm_vm_free(vm);
}
int main(int argc, char *argv[])
{
const struct kvm_msr_list *feature_list;
int i;
/*
* Skip the entire test if MSR_FEATURES isn't supported, other tests
* will cover the "regular" list of MSRs, the coverage here is purely
* opportunistic and not interesting on its own.
*/
TEST_REQUIRE(kvm_has_cap(KVM_CAP_GET_MSR_FEATURES));
(void)kvm_get_msr_index_list();
feature_list = kvm_get_feature_msr_index_list();
for (i = 0; i < feature_list->nmsrs; i++)
test_feature_msr(feature_list->indices[i]);
}