1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2020, Red Hat, Inc. 4 */ 5 #include "guest_modes.h" 6 7 #if defined(__aarch64__) || defined(__riscv) || defined(__powerpc64__) 8 #include "processor.h" 9 enum vm_guest_mode vm_mode_default; 10 #endif 11 12 #if defined(__powerpc64__) 13 #include <unistd.h> 14 #endif 15 16 struct guest_mode guest_modes[NUM_VM_MODES]; 17 18 void guest_modes_append_default(void) 19 { 20 #if !defined(__aarch64__) && !defined(__riscv) && !defined(__powerpc64__) 21 guest_mode_append(VM_MODE_DEFAULT, true); 22 #endif 23 24 #ifdef __aarch64__ 25 { 26 unsigned int limit = kvm_check_cap(KVM_CAP_ARM_VM_IPA_SIZE); 27 u32 ipa4k, ipa16k, ipa64k; 28 int i; 29 30 aarch64_get_supported_page_sizes(limit, &ipa4k, &ipa16k, &ipa64k); 31 32 guest_mode_append(VM_MODE_P52V48_4K, ipa4k >= 52); 33 guest_mode_append(VM_MODE_P52V48_16K, ipa16k >= 52); 34 guest_mode_append(VM_MODE_P52V48_64K, ipa64k >= 52); 35 36 guest_mode_append(VM_MODE_P48V48_4K, ipa4k >= 48); 37 guest_mode_append(VM_MODE_P48V48_16K, ipa16k >= 48); 38 guest_mode_append(VM_MODE_P48V48_64K, ipa64k >= 48); 39 40 guest_mode_append(VM_MODE_P40V48_4K, ipa4k >= 40); 41 guest_mode_append(VM_MODE_P40V48_16K, ipa16k >= 40); 42 guest_mode_append(VM_MODE_P40V48_64K, ipa64k >= 40); 43 44 guest_mode_append(VM_MODE_P36V48_4K, ipa4k >= 36); 45 guest_mode_append(VM_MODE_P36V48_16K, ipa16k >= 36); 46 guest_mode_append(VM_MODE_P36V48_64K, ipa64k >= 36); 47 guest_mode_append(VM_MODE_P36V47_16K, ipa16k >= 36); 48 49 vm_mode_default = ipa4k >= 40 ? VM_MODE_P40V48_4K : NUM_VM_MODES; 50 51 /* 52 * Pick the first supported IPA size if the default 53 * isn't available. 54 */ 55 for (i = 0; vm_mode_default == NUM_VM_MODES && i < NUM_VM_MODES; i++) { 56 if (guest_modes[i].supported && guest_modes[i].enabled) 57 vm_mode_default = i; 58 } 59 60 TEST_ASSERT(vm_mode_default != NUM_VM_MODES, 61 "No supported mode!"); 62 } 63 #endif 64 #ifdef __s390x__ 65 { 66 int kvm_fd, vm_fd; 67 struct kvm_s390_vm_cpu_processor info; 68 69 kvm_fd = open_kvm_dev_path_or_exit(); 70 vm_fd = __kvm_ioctl(kvm_fd, KVM_CREATE_VM, NULL); 71 kvm_device_attr_get(vm_fd, KVM_S390_VM_CPU_MODEL, 72 KVM_S390_VM_CPU_PROCESSOR, &info); 73 close(vm_fd); 74 close(kvm_fd); 75 /* Starting with z13 we have 47bits of physical address */ 76 if (info.ibc >= 0x30) 77 guest_mode_append(VM_MODE_P47V64_4K, true); 78 } 79 #endif 80 #ifdef __riscv 81 { 82 unsigned int sz = kvm_check_cap(KVM_CAP_VM_GPA_BITS); 83 unsigned long satp_mode = riscv64_get_satp_mode() << SATP_MODE_SHIFT; 84 int i; 85 86 switch (sz) { 87 case 59: 88 guest_mode_append(VM_MODE_P56V57_4K, satp_mode >= SATP_MODE_57); 89 guest_mode_append(VM_MODE_P56V48_4K, satp_mode >= SATP_MODE_48); 90 guest_mode_append(VM_MODE_P56V39_4K, satp_mode >= SATP_MODE_39); 91 break; 92 case 50: 93 guest_mode_append(VM_MODE_P50V57_4K, satp_mode >= SATP_MODE_57); 94 guest_mode_append(VM_MODE_P50V48_4K, satp_mode >= SATP_MODE_48); 95 guest_mode_append(VM_MODE_P50V39_4K, satp_mode >= SATP_MODE_39); 96 break; 97 case 41: 98 guest_mode_append(VM_MODE_P41V57_4K, satp_mode >= SATP_MODE_57); 99 guest_mode_append(VM_MODE_P41V48_4K, satp_mode >= SATP_MODE_48); 100 guest_mode_append(VM_MODE_P41V39_4K, satp_mode >= SATP_MODE_39); 101 break; 102 default: 103 break; 104 } 105 106 /* set the first supported mode as default */ 107 vm_mode_default = NUM_VM_MODES; 108 for (i = 0; vm_mode_default == NUM_VM_MODES && i < NUM_VM_MODES; i++) { 109 if (guest_modes[i].supported && guest_modes[i].enabled) 110 vm_mode_default = i; 111 } 112 TEST_ASSERT(vm_mode_default != NUM_VM_MODES, "No supported mode!"); 113 } 114 #endif 115 #ifdef __powerpc64__ 116 { 117 TEST_REQUIRE(kvm_has_cap(KVM_CAP_PPC_MMU_RADIX)); 118 /* Radix guest EA and RA are 52-bit on POWER9 and POWER10 */ 119 if (sysconf(_SC_PAGESIZE) == 4096) 120 vm_mode_default = VM_MODE_P52V52_4K; 121 else 122 vm_mode_default = VM_MODE_P52V52_64K; 123 guest_mode_append(VM_MODE_P52V52_4K, true); 124 guest_mode_append(VM_MODE_P52V52_64K, true); 125 } 126 #endif 127 } 128 129 void for_each_guest_mode(void (*func)(enum vm_guest_mode, void *), void *arg) 130 { 131 int i; 132 133 for (i = 0; i < NUM_VM_MODES; ++i) { 134 if (!guest_modes[i].enabled) 135 continue; 136 TEST_ASSERT(guest_modes[i].supported, 137 "Guest mode ID %d (%s) not supported.", 138 i, vm_guest_mode_string(i)); 139 func(i, arg); 140 } 141 } 142 143 void guest_modes_help(void) 144 { 145 int i; 146 147 printf(" -m: specify the guest mode ID to test\n" 148 " (default: test all supported modes)\n" 149 " This option may be used multiple times.\n" 150 " Guest mode IDs:\n"); 151 for (i = 0; i < NUM_VM_MODES; ++i) { 152 printf(" %d: %s%s\n", i, vm_guest_mode_string(i), 153 guest_modes[i].supported ? " (supported)" : ""); 154 } 155 } 156 157 void guest_modes_cmdline(const char *arg) 158 { 159 static bool mode_selected; 160 unsigned int mode; 161 int i; 162 163 if (!mode_selected) { 164 for (i = 0; i < NUM_VM_MODES; ++i) 165 guest_modes[i].enabled = false; 166 mode_selected = true; 167 } 168 169 mode = atoi_non_negative("Guest mode ID", arg); 170 TEST_ASSERT(mode < NUM_VM_MODES, "Guest mode ID %d too big", mode); 171 guest_modes[mode].enabled = true; 172 } 173