linux/tools/testing/selftests/kvm/lib/guest_modes.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (C) 2020, Red Hat, Inc.
   4 */
   5#include "guest_modes.h"
   6
   7struct guest_mode guest_modes[NUM_VM_MODES];
   8
   9void guest_modes_append_default(void)
  10{
  11        guest_mode_append(VM_MODE_DEFAULT, true, true);
  12
  13#ifdef __aarch64__
  14        guest_mode_append(VM_MODE_P40V48_64K, true, true);
  15        {
  16                unsigned int limit = kvm_check_cap(KVM_CAP_ARM_VM_IPA_SIZE);
  17                if (limit >= 52)
  18                        guest_mode_append(VM_MODE_P52V48_64K, true, true);
  19                if (limit >= 48) {
  20                        guest_mode_append(VM_MODE_P48V48_4K, true, true);
  21                        guest_mode_append(VM_MODE_P48V48_64K, true, true);
  22                }
  23        }
  24#endif
  25#ifdef __s390x__
  26        {
  27                int kvm_fd, vm_fd;
  28                struct kvm_s390_vm_cpu_processor info;
  29
  30                kvm_fd = open_kvm_dev_path_or_exit();
  31                vm_fd = ioctl(kvm_fd, KVM_CREATE_VM, 0);
  32                kvm_device_access(vm_fd, KVM_S390_VM_CPU_MODEL,
  33                                  KVM_S390_VM_CPU_PROCESSOR, &info, false);
  34                close(vm_fd);
  35                close(kvm_fd);
  36                /* Starting with z13 we have 47bits of physical address */
  37                if (info.ibc >= 0x30)
  38                        guest_mode_append(VM_MODE_P47V64_4K, true, true);
  39        }
  40#endif
  41}
  42
  43void for_each_guest_mode(void (*func)(enum vm_guest_mode, void *), void *arg)
  44{
  45        int i;
  46
  47        for (i = 0; i < NUM_VM_MODES; ++i) {
  48                if (!guest_modes[i].enabled)
  49                        continue;
  50                TEST_ASSERT(guest_modes[i].supported,
  51                            "Guest mode ID %d (%s) not supported.",
  52                            i, vm_guest_mode_string(i));
  53                func(i, arg);
  54        }
  55}
  56
  57void guest_modes_help(void)
  58{
  59        int i;
  60
  61        printf(" -m: specify the guest mode ID to test\n"
  62               "     (default: test all supported modes)\n"
  63               "     This option may be used multiple times.\n"
  64               "     Guest mode IDs:\n");
  65        for (i = 0; i < NUM_VM_MODES; ++i) {
  66                printf("         %d:    %s%s\n", i, vm_guest_mode_string(i),
  67                       guest_modes[i].supported ? " (supported)" : "");
  68        }
  69}
  70
  71void guest_modes_cmdline(const char *arg)
  72{
  73        static bool mode_selected;
  74        unsigned int mode;
  75        int i;
  76
  77        if (!mode_selected) {
  78                for (i = 0; i < NUM_VM_MODES; ++i)
  79                        guest_modes[i].enabled = false;
  80                mode_selected = true;
  81        }
  82
  83        mode = strtoul(optarg, NULL, 10);
  84        TEST_ASSERT(mode < NUM_VM_MODES, "Guest mode ID %d too big", mode);
  85        guest_modes[mode].enabled = true;
  86}
  87