Commit 2128e30b authored by Sean Christopherson's avatar Sean Christopherson Committed by Paolo Bonzini

KVM: selftests: Dedup MSR index list helpers, simplify dedicated test

Consolidate the helper for retrieving the list of save/restore MSRs and
the list of feature MSRs, and use the common helpers in the related
get_msr_index_features test.  Switching to the common helpers eliminates
the testcase that KVM returns the same -E2BIG result if the input number
of MSRs is '1' versus '0', but considered that testcase isn't very
interesting, e.g. '0' and '1' are equally arbitrary, and certainly not
worth the additional code.
Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 0ce74180
...@@ -428,6 +428,7 @@ void vcpu_load_state(struct kvm_vm *vm, uint32_t vcpuid, ...@@ -428,6 +428,7 @@ void vcpu_load_state(struct kvm_vm *vm, uint32_t vcpuid,
void kvm_x86_state_cleanup(struct kvm_x86_state *state); void kvm_x86_state_cleanup(struct kvm_x86_state *state);
const struct kvm_msr_list *kvm_get_msr_index_list(void); const struct kvm_msr_list *kvm_get_msr_index_list(void);
const struct kvm_msr_list *kvm_get_feature_msr_index_list(void);
bool kvm_msr_is_in_save_restore_list(uint32_t msr_index); bool kvm_msr_is_in_save_restore_list(uint32_t msr_index);
uint64_t kvm_get_feature_msr(uint64_t msr_index); uint64_t kvm_get_feature_msr(uint64_t msr_index);
......
...@@ -891,19 +891,20 @@ void vcpu_dump(FILE *stream, struct kvm_vm *vm, uint32_t vcpuid, uint8_t indent) ...@@ -891,19 +891,20 @@ void vcpu_dump(FILE *stream, struct kvm_vm *vm, uint32_t vcpuid, uint8_t indent)
sregs_dump(stream, &sregs, indent + 4); sregs_dump(stream, &sregs, indent + 4);
} }
const struct kvm_msr_list *kvm_get_msr_index_list(void) static struct kvm_msr_list *__kvm_get_msr_index_list(bool feature_msrs)
{ {
static struct kvm_msr_list *list; struct kvm_msr_list *list;
struct kvm_msr_list nmsrs; struct kvm_msr_list nmsrs;
int kvm_fd, r; int kvm_fd, r;
if (list)
return list;
kvm_fd = open_kvm_dev_path_or_exit(); kvm_fd = open_kvm_dev_path_or_exit();
nmsrs.nmsrs = 0; nmsrs.nmsrs = 0;
if (!feature_msrs)
r = __kvm_ioctl(kvm_fd, KVM_GET_MSR_INDEX_LIST, &nmsrs); r = __kvm_ioctl(kvm_fd, KVM_GET_MSR_INDEX_LIST, &nmsrs);
else
r = __kvm_ioctl(kvm_fd, KVM_GET_MSR_FEATURE_INDEX_LIST, &nmsrs);
TEST_ASSERT(r == -1 && errno == E2BIG, TEST_ASSERT(r == -1 && errno == E2BIG,
"Expected -E2BIG, got rc: %i errno: %i (%s)", "Expected -E2BIG, got rc: %i errno: %i (%s)",
r, errno, strerror(errno)); r, errno, strerror(errno));
...@@ -912,15 +913,37 @@ const struct kvm_msr_list *kvm_get_msr_index_list(void) ...@@ -912,15 +913,37 @@ const struct kvm_msr_list *kvm_get_msr_index_list(void)
TEST_ASSERT(list, "-ENOMEM when allocating MSR index list"); TEST_ASSERT(list, "-ENOMEM when allocating MSR index list");
list->nmsrs = nmsrs.nmsrs; list->nmsrs = nmsrs.nmsrs;
if (!feature_msrs)
kvm_ioctl(kvm_fd, KVM_GET_MSR_INDEX_LIST, list); kvm_ioctl(kvm_fd, KVM_GET_MSR_INDEX_LIST, list);
else
kvm_ioctl(kvm_fd, KVM_GET_MSR_FEATURE_INDEX_LIST, list);
close(kvm_fd); close(kvm_fd);
TEST_ASSERT(list->nmsrs == nmsrs.nmsrs, TEST_ASSERT(list->nmsrs == nmsrs.nmsrs,
"Number of save/restore MSRs changed, was %d, now %d", "Number of MSRs in list changed, was %d, now %d",
nmsrs.nmsrs, list->nmsrs); nmsrs.nmsrs, list->nmsrs);
return list; return list;
} }
const struct kvm_msr_list *kvm_get_msr_index_list(void)
{
static const struct kvm_msr_list *list;
if (!list)
list = __kvm_get_msr_index_list(false);
return list;
}
const struct kvm_msr_list *kvm_get_feature_msr_index_list(void)
{
static const struct kvm_msr_list *list;
if (!list)
list = __kvm_get_msr_index_list(true);
return list;
}
bool kvm_msr_is_in_save_restore_list(uint32_t msr_index) bool kvm_msr_is_in_save_restore_list(uint32_t msr_index)
{ {
const struct kvm_msr_list *list = kvm_get_msr_index_list(); const struct kvm_msr_list *list = kvm_get_msr_index_list();
......
...@@ -15,108 +15,24 @@ ...@@ -15,108 +15,24 @@
#include "kvm_util.h" #include "kvm_util.h"
#include "processor.h" #include "processor.h"
static int kvm_num_index_msrs(int kvm_fd, int nmsrs) int main(int argc, char *argv[])
{
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;
struct kvm_msr_list *list;
kvm_fd = open_kvm_dev_path_or_exit();
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;
kvm_ioctl(kvm_fd, KVM_GET_MSR_INDEX_LIST, list);
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 = __kvm_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;
list = malloc(sizeof(*list) + nmsrs * sizeof(list->indices[0]));
list->nmsrs = nmsrs;
kvm_ioctl(kvm_fd, KVM_GET_MSR_FEATURE_INDEX_LIST, list);
return list;
}
static void test_get_msr_feature(void)
{ {
int res, old_res, i, kvm_fd; const struct kvm_msr_list *feature_list;
struct kvm_msr_list *feature_list; int i;
kvm_fd = open_kvm_dev_path_or_exit();
old_res = kvm_num_feature_msrs(kvm_fd, 0); /*
TEST_ASSERT(old_res != 0, "Expecting nmsrs to be > 0"); * Skip the entire test if MSR_FEATURES isn't supported, other tests
* will cover the "regular" list of MSRs, the coverage here is purely
if (old_res != 1) { * opportunistic and not interesting on its own.
res = kvm_num_feature_msrs(kvm_fd, 1); */
TEST_ASSERT(res > 1, "Expecting nmsrs to be > 1"); if (!kvm_check_cap(KVM_CAP_GET_MSR_FEATURES)) {
TEST_ASSERT(res == old_res, "Expecting nmsrs to be identical"); print_skip("KVM_CAP_GET_MSR_FEATURES not supported");
exit(KSFT_SKIP);
} }
feature_list = kvm_get_msr_feature_list(kvm_fd, old_res); (void)kvm_get_msr_index_list();
TEST_ASSERT(old_res == feature_list->nmsrs,
"Unmatching number of msr indexes");
feature_list = kvm_get_feature_msr_index_list();
for (i = 0; i < feature_list->nmsrs; i++) for (i = 0; i < feature_list->nmsrs; i++)
kvm_get_feature_msr(feature_list->indices[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();
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment