linux/tools/testing/selftests/kvm/x86_64/get_msr_index_features.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Test that KVM_GET_MSR_INDEX_LIST and
   4 * KVM_GET_MSR_FEATURE_INDEX_LIST work as intended
   5 *
   6 * Copyright (C) 2020, Red Hat, Inc.
   7 */
   8#include <fcntl.h>
   9#include <stdio.h>
  10#include <stdlib.h>
  11#include <string.h>
  12#include <sys/ioctl.h>
  13
  14#include "test_util.h"
  15#include "kvm_util.h"
  16#include "processor.h"
  17
  18static int kvm_num_index_msrs(int kvm_fd, int nmsrs)
  19{
  20        struct kvm_msr_list *list;
  21        int r;
  22
  23        list = malloc(sizeof(*list) + nmsrs * sizeof(list->indices[0]));
  24        list->nmsrs = nmsrs;
  25        r = ioctl(kvm_fd, KVM_GET_MSR_INDEX_LIST, list);
  26        TEST_ASSERT(r == -1 && errno == E2BIG,
  27                                "Unexpected result from KVM_GET_MSR_INDEX_LIST probe, r: %i",
  28                                r);
  29
  30        r = list->nmsrs;
  31        free(list);
  32        return r;
  33}
  34
  35static void test_get_msr_index(void)
  36{
  37        int old_res, res, kvm_fd, r;
  38        struct kvm_msr_list *list;
  39
  40        kvm_fd = open_kvm_dev_path_or_exit();
  41
  42        old_res = kvm_num_index_msrs(kvm_fd, 0);
  43        TEST_ASSERT(old_res != 0, "Expecting nmsrs to be > 0");
  44
  45        if (old_res != 1) {
  46                res = kvm_num_index_msrs(kvm_fd, 1);
  47                TEST_ASSERT(res > 1, "Expecting nmsrs to be > 1");
  48                TEST_ASSERT(res == old_res, "Expecting nmsrs to be identical");
  49        }
  50
  51        list = malloc(sizeof(*list) + old_res * sizeof(list->indices[0]));
  52        list->nmsrs = old_res;
  53        r = ioctl(kvm_fd, KVM_GET_MSR_INDEX_LIST, list);
  54
  55        TEST_ASSERT(r == 0,
  56                    "Unexpected result from KVM_GET_MSR_FEATURE_INDEX_LIST, r: %i",
  57                    r);
  58        TEST_ASSERT(list->nmsrs == old_res, "Expecting nmsrs to be identical");
  59        free(list);
  60
  61        close(kvm_fd);
  62}
  63
  64static int kvm_num_feature_msrs(int kvm_fd, int nmsrs)
  65{
  66        struct kvm_msr_list *list;
  67        int r;
  68
  69        list = malloc(sizeof(*list) + nmsrs * sizeof(list->indices[0]));
  70        list->nmsrs = nmsrs;
  71        r = ioctl(kvm_fd, KVM_GET_MSR_FEATURE_INDEX_LIST, list);
  72        TEST_ASSERT(r == -1 && errno == E2BIG,
  73                "Unexpected result from KVM_GET_MSR_FEATURE_INDEX_LIST probe, r: %i",
  74                                r);
  75
  76        r = list->nmsrs;
  77        free(list);
  78        return r;
  79}
  80
  81struct kvm_msr_list *kvm_get_msr_feature_list(int kvm_fd, int nmsrs)
  82{
  83        struct kvm_msr_list *list;
  84        int r;
  85
  86        list = malloc(sizeof(*list) + nmsrs * sizeof(list->indices[0]));
  87        list->nmsrs = nmsrs;
  88        r = ioctl(kvm_fd, KVM_GET_MSR_FEATURE_INDEX_LIST, list);
  89
  90        TEST_ASSERT(r == 0,
  91                "Unexpected result from KVM_GET_MSR_FEATURE_INDEX_LIST, r: %i",
  92                r);
  93
  94        return list;
  95}
  96
  97static void test_get_msr_feature(void)
  98{
  99        int res, old_res, i, kvm_fd;
 100        struct kvm_msr_list *feature_list;
 101
 102        kvm_fd = open_kvm_dev_path_or_exit();
 103
 104        old_res = kvm_num_feature_msrs(kvm_fd, 0);
 105        TEST_ASSERT(old_res != 0, "Expecting nmsrs to be > 0");
 106
 107        if (old_res != 1) {
 108                res = kvm_num_feature_msrs(kvm_fd, 1);
 109                TEST_ASSERT(res > 1, "Expecting nmsrs to be > 1");
 110                TEST_ASSERT(res == old_res, "Expecting nmsrs to be identical");
 111        }
 112
 113        feature_list = kvm_get_msr_feature_list(kvm_fd, old_res);
 114        TEST_ASSERT(old_res == feature_list->nmsrs,
 115                                "Unmatching number of msr indexes");
 116
 117        for (i = 0; i < feature_list->nmsrs; i++)
 118                kvm_get_feature_msr(feature_list->indices[i]);
 119
 120        free(feature_list);
 121        close(kvm_fd);
 122}
 123
 124int main(int argc, char *argv[])
 125{
 126        if (kvm_check_cap(KVM_CAP_GET_MSR_FEATURES))
 127                test_get_msr_feature();
 128
 129        test_get_msr_index();
 130}
 131