diff options
author | Sean Christopherson <seanjc@google.com> | 2022-06-14 23:06:43 +0300 |
---|---|---|
committer | Sean Christopherson <seanjc@google.com> | 2022-07-14 04:14:15 +0300 |
commit | 7fbc6038acbaa4c0c0b374aac635038881143e84 (patch) | |
tree | 118191569d5b5115ff1d6714413382eae069e36b /tools/testing/selftests/kvm/x86_64 | |
parent | fc66963d7b01e00ef0482bd7adbc8918343f81d9 (diff) | |
download | linux-7fbc6038acbaa4c0c0b374aac635038881143e84.tar.xz |
KVM: selftests: Cache CPUID in struct kvm_vcpu
Cache a vCPU's CPUID information in "struct kvm_vcpu" to allow fixing the
mess where tests, often unknowingly, modify the global/static "cpuid"
allocated by kvm_get_supported_cpuid().
Add vcpu_init_cpuid() to handle stuffing an entirely different CPUID
model, e.g. during vCPU creation or when switching to the Hyper-V enabled
CPUID model. Automatically refresh the cache on vcpu_set_cpuid() so that
any adjustments made by KVM are always reflected in the cache. Drop
vcpu_get_cpuid() entirely to force tests to use the cache, and to allow
adding e.g. vcpu_get_cpuid_entry() in the future without creating a
conflicting set of APIs where vcpu_get_cpuid() does KVM_GET_CPUID2, but
vcpu_get_cpuid_entry() does not.
Opportunistically convert the VMX nested state test and KVM PV test to
manipulating the vCPU's CPUID (because it's easy), but use
vcpu_init_cpuid() for the Hyper-V features test and "emulator error" test
to effectively retain their current behavior as they're less trivial to
convert.
Signed-off-by: Sean Christopherson <seanjc@google.com>
Link: https://lore.kernel.org/r/20220614200707.3315957-19-seanjc@google.com
Diffstat (limited to 'tools/testing/selftests/kvm/x86_64')
7 files changed, 19 insertions, 21 deletions
diff --git a/tools/testing/selftests/kvm/x86_64/cpuid_test.c b/tools/testing/selftests/kvm/x86_64/cpuid_test.c index 59dcdf5a1220..96f141a758ca 100644 --- a/tools/testing/selftests/kvm/x86_64/cpuid_test.c +++ b/tools/testing/selftests/kvm/x86_64/cpuid_test.c @@ -144,21 +144,22 @@ struct kvm_cpuid2 *vcpu_alloc_cpuid(struct kvm_vm *vm, vm_vaddr_t *p_gva, struct return guest_cpuids; } -static void set_cpuid_after_run(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid) +static void set_cpuid_after_run(struct kvm_vcpu *vcpu) { + struct kvm_cpuid2 *cpuid = vcpu->cpuid; struct kvm_cpuid_entry2 *ent; int rc; u32 eax, ebx, x; /* Setting unmodified CPUID is allowed */ - rc = __vcpu_set_cpuid(vcpu, cpuid); + rc = __vcpu_set_cpuid(vcpu); TEST_ASSERT(!rc, "Setting unmodified CPUID after KVM_RUN failed: %d", rc); /* Changing CPU features is forbidden */ ent = get_cpuid(cpuid, 0x7, 0); ebx = ent->ebx; ent->ebx--; - rc = __vcpu_set_cpuid(vcpu, cpuid); + rc = __vcpu_set_cpuid(vcpu); TEST_ASSERT(rc, "Changing CPU features should fail"); ent->ebx = ebx; @@ -167,14 +168,14 @@ static void set_cpuid_after_run(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid) eax = ent->eax; x = eax & 0xff; ent->eax = (eax & ~0xffu) | (x - 1); - rc = __vcpu_set_cpuid(vcpu, cpuid); + rc = __vcpu_set_cpuid(vcpu); TEST_ASSERT(rc, "Changing MAXPHYADDR should fail"); ent->eax = eax; } int main(void) { - struct kvm_cpuid2 *supp_cpuid, *cpuid2; + struct kvm_cpuid2 *supp_cpuid; struct kvm_vcpu *vcpu; vm_vaddr_t cpuid_gva; struct kvm_vm *vm; @@ -183,18 +184,17 @@ int main(void) vm = vm_create_with_one_vcpu(&vcpu, guest_main); supp_cpuid = kvm_get_supported_cpuid(); - cpuid2 = vcpu_get_cpuid(vcpu); - compare_cpuids(supp_cpuid, cpuid2); + compare_cpuids(supp_cpuid, vcpu->cpuid); - vcpu_alloc_cpuid(vm, &cpuid_gva, cpuid2); + vcpu_alloc_cpuid(vm, &cpuid_gva, vcpu->cpuid); vcpu_args_set(vcpu, 1, cpuid_gva); for (stage = 0; stage < 3; stage++) run_vcpu(vcpu, stage); - set_cpuid_after_run(vcpu, cpuid2); + set_cpuid_after_run(vcpu); kvm_vm_free(vm); } diff --git a/tools/testing/selftests/kvm/x86_64/emulator_error_test.c b/tools/testing/selftests/kvm/x86_64/emulator_error_test.c index 3aa3d17f230f..d8dbed419638 100644 --- a/tools/testing/selftests/kvm/x86_64/emulator_error_test.c +++ b/tools/testing/selftests/kvm/x86_64/emulator_error_test.c @@ -171,7 +171,7 @@ int main(int argc, char *argv[]) entry->eax = (entry->eax & 0xffffff00) | MAXPHYADDR; set_cpuid(cpuid, entry); - vcpu_set_cpuid(vcpu, cpuid); + vcpu_init_cpuid(vcpu, cpuid); rc = kvm_check_cap(KVM_CAP_EXIT_ON_EMULATION_FAILURE); TEST_ASSERT(rc, "KVM_CAP_EXIT_ON_EMULATION_FAILURE is unavailable"); diff --git a/tools/testing/selftests/kvm/x86_64/hyperv_features.c b/tools/testing/selftests/kvm/x86_64/hyperv_features.c index 2070ba0d6392..86ce1f1e98ee 100644 --- a/tools/testing/selftests/kvm/x86_64/hyperv_features.c +++ b/tools/testing/selftests/kvm/x86_64/hyperv_features.c @@ -102,7 +102,7 @@ static void hv_set_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid, "failed to set HYPERV_CPUID_ENLIGHTMENT_INFO leaf"); TEST_ASSERT(set_cpuid(cpuid, dbg), "failed to set HYPERV_CPUID_SYNDBG_PLATFORM_CAPABILITIES leaf"); - vcpu_set_cpuid(vcpu, cpuid); + vcpu_init_cpuid(vcpu, cpuid); } static void guest_test_msrs_access(void) diff --git a/tools/testing/selftests/kvm/x86_64/kvm_pv_test.c b/tools/testing/selftests/kvm/x86_64/kvm_pv_test.c index ea452444f4af..986ca7282a09 100644 --- a/tools/testing/selftests/kvm/x86_64/kvm_pv_test.c +++ b/tools/testing/selftests/kvm/x86_64/kvm_pv_test.c @@ -147,7 +147,6 @@ static void enter_guest(struct kvm_vcpu *vcpu) int main(void) { - struct kvm_cpuid2 *best; struct kvm_vcpu *vcpu; struct kvm_vm *vm; @@ -157,9 +156,8 @@ int main(void) vcpu_enable_cap(vcpu, KVM_CAP_ENFORCE_PV_FEATURE_CPUID, 1); - best = kvm_get_supported_cpuid(); - clear_kvm_cpuid_features(best); - vcpu_set_cpuid(vcpu, best); + clear_kvm_cpuid_features(vcpu->cpuid); + vcpu_set_cpuid(vcpu); vm_init_descriptor_tables(vm); vcpu_init_descriptor_tables(vcpu); diff --git a/tools/testing/selftests/kvm/x86_64/monitor_mwait_test.c b/tools/testing/selftests/kvm/x86_64/monitor_mwait_test.c index c804f6f04134..0ac5bec1e3b7 100644 --- a/tools/testing/selftests/kvm/x86_64/monitor_mwait_test.c +++ b/tools/testing/selftests/kvm/x86_64/monitor_mwait_test.c @@ -80,7 +80,7 @@ int main(int argc, char *argv[]) set_cpuid(cpuid, entry); vm = vm_create_with_one_vcpu(&vcpu, guest_code); - vcpu_set_cpuid(vcpu, cpuid); + vcpu_set_cpuid(vcpu); run = vcpu->run; diff --git a/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c b/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c index 66cb2d0054e6..1cf78ec007f2 100644 --- a/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c +++ b/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c @@ -121,7 +121,7 @@ void test_vmx_nested_state(struct kvm_vcpu *vcpu) test_nested_state(vcpu, state); /* Enable VMX in the guest CPUID. */ - vcpu_set_cpuid(vcpu, kvm_get_supported_cpuid()); + vcpu_set_cpuid(vcpu); /* * Setting vmxon_pa == -1ull and vmcs_pa == -1ull exits early without @@ -245,7 +245,7 @@ void test_vmx_nested_state(struct kvm_vcpu *vcpu) void disable_vmx(struct kvm_vcpu *vcpu) { - struct kvm_cpuid2 *cpuid = kvm_get_supported_cpuid(); + struct kvm_cpuid2 *cpuid = vcpu->cpuid; int i; for (i = 0; i < cpuid->nent; ++i) @@ -255,7 +255,7 @@ void disable_vmx(struct kvm_vcpu *vcpu) TEST_ASSERT(i != cpuid->nent, "CPUID function 1 not found"); cpuid->entries[i].ecx &= ~CPUID_VMX; - vcpu_set_cpuid(vcpu, cpuid); + vcpu_set_cpuid(vcpu); cpuid->entries[i].ecx |= CPUID_VMX; } diff --git a/tools/testing/selftests/kvm/x86_64/xapic_state_test.c b/tools/testing/selftests/kvm/x86_64/xapic_state_test.c index 87531623064f..52133bb4d85a 100644 --- a/tools/testing/selftests/kvm/x86_64/xapic_state_test.c +++ b/tools/testing/selftests/kvm/x86_64/xapic_state_test.c @@ -152,13 +152,13 @@ int main(int argc, char *argv[]) vm = vm_create_with_one_vcpu(&x.vcpu, xapic_guest_code); x.is_x2apic = false; - cpuid = vcpu_get_cpuid(x.vcpu); + cpuid = x.vcpu->cpuid; for (i = 0; i < cpuid->nent; i++) { if (cpuid->entries[i].function == 1) break; } cpuid->entries[i].ecx &= ~BIT(21); - vcpu_set_cpuid(x.vcpu, cpuid); + vcpu_set_cpuid(x.vcpu); virt_pg_map(vm, APIC_DEFAULT_GPA, APIC_DEFAULT_GPA); test_icr(&x); |