selftests: kvm: add get_msr_index_features
Test the KVM_GET_MSR_FEATURE_INDEX_LIST and KVM_GET_MSR_INDEX_LIST ioctls. Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> Message-Id: <20210318145629.486450-1-eesposit@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
2c7f76b4c4
commit
77a3aa26a0
|
@ -8,6 +8,7 @@
|
|||
/x86_64/debug_regs
|
||||
/x86_64/evmcs_test
|
||||
/x86_64/get_cpuid_test
|
||||
/x86_64/get_msr_index_features
|
||||
/x86_64/kvm_pv_test
|
||||
/x86_64/hyperv_clock
|
||||
/x86_64/hyperv_cpuid
|
||||
|
|
|
@ -39,6 +39,7 @@ LIBKVM_aarch64 = lib/aarch64/processor.c lib/aarch64/ucall.c
|
|||
LIBKVM_s390x = lib/s390x/processor.c lib/s390x/ucall.c lib/s390x/diag318_test_handler.c
|
||||
|
||||
TEST_GEN_PROGS_x86_64 = x86_64/cr4_cpuid_sync_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/get_msr_index_features
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/evmcs_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/get_cpuid_test
|
||||
TEST_GEN_PROGS_x86_64 += x86_64/hyperv_clock
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "sparsebit.h"
|
||||
|
||||
#define KVM_DEV_PATH "/dev/kvm"
|
||||
#define KVM_MAX_VCPUS 512
|
||||
|
||||
/*
|
||||
|
|
|
@ -10,8 +10,6 @@
|
|||
|
||||
#include "sparsebit.h"
|
||||
|
||||
#define KVM_DEV_PATH "/dev/kvm"
|
||||
|
||||
struct userspace_mem_region {
|
||||
struct kvm_userspace_memory_region region;
|
||||
struct sparsebit *unused_phy_pages;
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Test that KVM_GET_MSR_INDEX_LIST and
|
||||
* KVM_GET_MSR_FEATURE_INDEX_LIST work as intended
|
||||
*
|
||||
* 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 int kvm_num_index_msrs(int kvm_fd, int nmsrs)
|
||||
{
|
||||
struct kvm_msr_list *list;
|
||||
int r;
|
||||
|
||||
list = malloc(sizeof(*list) + nmsrs * sizeof(list->indices[0]));
|
||||
list->nmsrs = nmsrs;
|
||||
r = ioctl(kvm_fd, KVM_GET_MSR_INDEX_LIST, list);
|
||||
TEST_ASSERT(r == -1 && errno == E2BIG,
|
||||
"Unexpected result from KVM_GET_MSR_INDEX_LIST probe, r: %i",
|
||||
r);
|
||||
|
||||
r = list->nmsrs;
|
||||
free(list);
|
||||
return r;
|
||||
}
|
||||
|
||||
static void test_get_msr_index(void)
|
||||
{
|
||||
int old_res, res, kvm_fd, r;
|
||||
struct kvm_msr_list *list;
|
||||
|
||||
kvm_fd = open(KVM_DEV_PATH, O_RDONLY);
|
||||
if (kvm_fd < 0)
|
||||
exit(KSFT_SKIP);
|
||||
|
||||
old_res = kvm_num_index_msrs(kvm_fd, 0);
|
||||
TEST_ASSERT(old_res != 0, "Expecting nmsrs to be > 0");
|
||||
|
||||
if (old_res != 1) {
|
||||
res = kvm_num_index_msrs(kvm_fd, 1);
|
||||
TEST_ASSERT(res > 1, "Expecting nmsrs to be > 1");
|
||||
TEST_ASSERT(res == old_res, "Expecting nmsrs to be identical");
|
||||
}
|
||||
|
||||
list = malloc(sizeof(*list) + old_res * sizeof(list->indices[0]));
|
||||
list->nmsrs = old_res;
|
||||
r = ioctl(kvm_fd, KVM_GET_MSR_INDEX_LIST, list);
|
||||
|
||||
TEST_ASSERT(r == 0,
|
||||
"Unexpected result from KVM_GET_MSR_FEATURE_INDEX_LIST, r: %i",
|
||||
r);
|
||||
TEST_ASSERT(list->nmsrs == old_res, "Expecting nmsrs to be identical");
|
||||
free(list);
|
||||
|
||||
close(kvm_fd);
|
||||
}
|
||||
|
||||
static int kvm_num_feature_msrs(int kvm_fd, int nmsrs)
|
||||
{
|
||||
struct kvm_msr_list *list;
|
||||
int r;
|
||||
|
||||
list = malloc(sizeof(*list) + nmsrs * sizeof(list->indices[0]));
|
||||
list->nmsrs = nmsrs;
|
||||
r = ioctl(kvm_fd, KVM_GET_MSR_FEATURE_INDEX_LIST, list);
|
||||
TEST_ASSERT(r == -1 && errno == E2BIG,
|
||||
"Unexpected result from KVM_GET_MSR_FEATURE_INDEX_LIST probe, r: %i",
|
||||
r);
|
||||
|
||||
r = list->nmsrs;
|
||||
free(list);
|
||||
return r;
|
||||
}
|
||||
|
||||
struct kvm_msr_list *kvm_get_msr_feature_list(int kvm_fd, int nmsrs)
|
||||
{
|
||||
struct kvm_msr_list *list;
|
||||
int r;
|
||||
|
||||
list = malloc(sizeof(*list) + nmsrs * sizeof(list->indices[0]));
|
||||
list->nmsrs = nmsrs;
|
||||
r = ioctl(kvm_fd, KVM_GET_MSR_FEATURE_INDEX_LIST, list);
|
||||
|
||||
TEST_ASSERT(r == 0,
|
||||
"Unexpected result from KVM_GET_MSR_FEATURE_INDEX_LIST, r: %i",
|
||||
r);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
static void test_get_msr_feature(void)
|
||||
{
|
||||
int res, old_res, i, kvm_fd;
|
||||
struct kvm_msr_list *feature_list;
|
||||
|
||||
kvm_fd = open(KVM_DEV_PATH, O_RDONLY);
|
||||
if (kvm_fd < 0)
|
||||
exit(KSFT_SKIP);
|
||||
|
||||
old_res = kvm_num_feature_msrs(kvm_fd, 0);
|
||||
TEST_ASSERT(old_res != 0, "Expecting nmsrs to be > 0");
|
||||
|
||||
if (old_res != 1) {
|
||||
res = kvm_num_feature_msrs(kvm_fd, 1);
|
||||
TEST_ASSERT(res > 1, "Expecting nmsrs to be > 1");
|
||||
TEST_ASSERT(res == old_res, "Expecting nmsrs to be identical");
|
||||
}
|
||||
|
||||
feature_list = kvm_get_msr_feature_list(kvm_fd, old_res);
|
||||
TEST_ASSERT(old_res == feature_list->nmsrs,
|
||||
"Unmatching number of msr indexes");
|
||||
|
||||
for (i = 0; i < feature_list->nmsrs; i++)
|
||||
kvm_get_feature_msr(feature_list->indices[i]);
|
||||
|
||||
free(feature_list);
|
||||
close(kvm_fd);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (kvm_check_cap(KVM_CAP_GET_MSR_FEATURES))
|
||||
test_get_msr_feature();
|
||||
|
||||
test_get_msr_index();
|
||||
}
|
Loading…
Reference in New Issue