KVM: selftests: Manage CPUID array in Hyper-V CPUID test's core helper
Allocate, get, and free the CPUID array in the Hyper-V CPUID test in the test's core helper, instead of copy+pasting code at each call site. In addition to deduplicating a small amount of code, restricting visibility of the array to a single invocation of the core test prevents "leaking" an array across test cases. Passing in @vcpu to the helper will also allow pivoting on VM-scoped information without needing to pass more booleans, e.g. to conditionally assert on features that require an in-kernel APIC. To avoid use-after-free bugs due to overzealous and careless developers, opportunstically add a comment to explain that the system-scoped helper caches the Hyper-V CPUID entries, i.e. that the caller is not responsible for freeing the memory. Cc: Vitaly Kuznetsov <vkuznets@redhat.com> Reviewed-by: Vitaly Kuznetsov <vkuznets@redhat.com> Link: https://lore.kernel.org/r/20250118003454.2619573-4-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
This commit is contained in:
parent
0b6db0dc43
commit
cd5a0c2f0f
1 changed files with 17 additions and 13 deletions
|
@ -41,13 +41,18 @@ static bool smt_possible(void)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_hv_cpuid(const struct kvm_cpuid2 *hv_cpuid_entries,
|
static void test_hv_cpuid(struct kvm_vcpu *vcpu, bool evmcs_expected)
|
||||||
bool evmcs_expected)
|
|
||||||
{
|
{
|
||||||
|
const struct kvm_cpuid2 *hv_cpuid_entries;
|
||||||
int i;
|
int i;
|
||||||
int nent_expected = 10;
|
int nent_expected = 10;
|
||||||
u32 test_val;
|
u32 test_val;
|
||||||
|
|
||||||
|
if (vcpu)
|
||||||
|
hv_cpuid_entries = vcpu_get_supported_hv_cpuid(vcpu);
|
||||||
|
else
|
||||||
|
hv_cpuid_entries = kvm_get_supported_hv_cpuid();
|
||||||
|
|
||||||
TEST_ASSERT(hv_cpuid_entries->nent == nent_expected,
|
TEST_ASSERT(hv_cpuid_entries->nent == nent_expected,
|
||||||
"KVM_GET_SUPPORTED_HV_CPUID should return %d entries"
|
"KVM_GET_SUPPORTED_HV_CPUID should return %d entries"
|
||||||
" (returned %d)",
|
" (returned %d)",
|
||||||
|
@ -109,6 +114,13 @@ static void test_hv_cpuid(const struct kvm_cpuid2 *hv_cpuid_entries,
|
||||||
* entry->edx);
|
* entry->edx);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note, the CPUID array returned by the system-scoped helper is a one-
|
||||||
|
* time allocation, i.e. must not be freed.
|
||||||
|
*/
|
||||||
|
if (vcpu)
|
||||||
|
free((void *)hv_cpuid_entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_hv_cpuid_e2big(struct kvm_vm *vm, struct kvm_vcpu *vcpu)
|
static void test_hv_cpuid_e2big(struct kvm_vm *vm, struct kvm_vcpu *vcpu)
|
||||||
|
@ -129,7 +141,6 @@ static void test_hv_cpuid_e2big(struct kvm_vm *vm, struct kvm_vcpu *vcpu)
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
struct kvm_vm *vm;
|
struct kvm_vm *vm;
|
||||||
const struct kvm_cpuid2 *hv_cpuid_entries;
|
|
||||||
struct kvm_vcpu *vcpu;
|
struct kvm_vcpu *vcpu;
|
||||||
|
|
||||||
TEST_REQUIRE(kvm_has_cap(KVM_CAP_HYPERV_CPUID));
|
TEST_REQUIRE(kvm_has_cap(KVM_CAP_HYPERV_CPUID));
|
||||||
|
@ -138,10 +149,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
/* Test vCPU ioctl version */
|
/* Test vCPU ioctl version */
|
||||||
test_hv_cpuid_e2big(vm, vcpu);
|
test_hv_cpuid_e2big(vm, vcpu);
|
||||||
|
test_hv_cpuid(vcpu, false);
|
||||||
hv_cpuid_entries = vcpu_get_supported_hv_cpuid(vcpu);
|
|
||||||
test_hv_cpuid(hv_cpuid_entries, false);
|
|
||||||
free((void *)hv_cpuid_entries);
|
|
||||||
|
|
||||||
if (!kvm_cpu_has(X86_FEATURE_VMX) ||
|
if (!kvm_cpu_has(X86_FEATURE_VMX) ||
|
||||||
!kvm_has_cap(KVM_CAP_HYPERV_ENLIGHTENED_VMCS)) {
|
!kvm_has_cap(KVM_CAP_HYPERV_ENLIGHTENED_VMCS)) {
|
||||||
|
@ -149,9 +157,7 @@ int main(int argc, char *argv[])
|
||||||
goto do_sys;
|
goto do_sys;
|
||||||
}
|
}
|
||||||
vcpu_enable_evmcs(vcpu);
|
vcpu_enable_evmcs(vcpu);
|
||||||
hv_cpuid_entries = vcpu_get_supported_hv_cpuid(vcpu);
|
test_hv_cpuid(vcpu, true);
|
||||||
test_hv_cpuid(hv_cpuid_entries, true);
|
|
||||||
free((void *)hv_cpuid_entries);
|
|
||||||
|
|
||||||
do_sys:
|
do_sys:
|
||||||
/* Test system ioctl version */
|
/* Test system ioctl version */
|
||||||
|
@ -161,9 +167,7 @@ do_sys:
|
||||||
}
|
}
|
||||||
|
|
||||||
test_hv_cpuid_e2big(vm, NULL);
|
test_hv_cpuid_e2big(vm, NULL);
|
||||||
|
test_hv_cpuid(NULL, kvm_cpu_has(X86_FEATURE_VMX));
|
||||||
hv_cpuid_entries = kvm_get_supported_hv_cpuid();
|
|
||||||
test_hv_cpuid(hv_cpuid_entries, kvm_cpu_has(X86_FEATURE_VMX));
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
kvm_vm_free(vm);
|
kvm_vm_free(vm);
|
||||||
|
|
Loading…
Add table
Reference in a new issue