Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

KVM: riscv: selftests: Add riscv vm satp modes

Current vm modes cannot represent riscv guest modes precisely, here add
all 9 combinations of P(56,40,41) x V(57,48,39). Also the default vm
mode is detected on runtime instead of hardcoded one, which might not be
supported on specific machine.

Signed-off-by: Wu Fei <wu.fei9@sanechips.com.cn>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Nutty Liu <nutty.liu@hotmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20251105151442.28767-1-wu.fei9@sanechips.com.cn
Signed-off-by: Anup Patel <anup@brainfault.org>

authored by

Wu Fei and committed by
Anup Patel
39ad809d ab2a7b7b

+142 -14
+14 -3
tools/testing/selftests/kvm/include/kvm_util.h
··· 186 186 VM_MODE_P36V48_64K, 187 187 VM_MODE_P47V47_16K, 188 188 VM_MODE_P36V47_16K, 189 + 190 + VM_MODE_P56V57_4K, /* For riscv64 */ 191 + VM_MODE_P56V48_4K, 192 + VM_MODE_P56V39_4K, 193 + VM_MODE_P50V57_4K, 194 + VM_MODE_P50V48_4K, 195 + VM_MODE_P50V39_4K, 196 + VM_MODE_P41V57_4K, 197 + VM_MODE_P41V48_4K, 198 + VM_MODE_P41V39_4K, 199 + 189 200 NUM_VM_MODES, 190 201 }; 191 202 ··· 221 210 shape; \ 222 211 }) 223 212 224 - #if defined(__aarch64__) 225 - 226 213 extern enum vm_guest_mode vm_mode_default; 214 + 215 + #if defined(__aarch64__) 227 216 228 217 #define VM_MODE_DEFAULT vm_mode_default 229 218 #define MIN_PAGE_SHIFT 12U ··· 247 236 #error "RISC-V 32-bit kvm selftests not supported" 248 237 #endif 249 238 250 - #define VM_MODE_DEFAULT VM_MODE_P40V48_4K 239 + #define VM_MODE_DEFAULT vm_mode_default 251 240 #define MIN_PAGE_SHIFT 12U 252 241 #define ptes_per_page(page_size) ((page_size) / 8) 253 242
+2
tools/testing/selftests/kvm/include/riscv/processor.h
··· 192 192 csr_clear(CSR_SSTATUS, SR_SIE); 193 193 } 194 194 195 + unsigned long riscv64_get_satp_mode(void); 196 + 195 197 #endif /* SELFTEST_KVM_PROCESSOR_H */
+34 -7
tools/testing/selftests/kvm/lib/guest_modes.c
··· 4 4 */ 5 5 #include "guest_modes.h" 6 6 7 - #ifdef __aarch64__ 7 + #if defined(__aarch64__) || defined(__riscv) 8 8 #include "processor.h" 9 9 enum vm_guest_mode vm_mode_default; 10 10 #endif ··· 13 13 14 14 void guest_modes_append_default(void) 15 15 { 16 - #ifndef __aarch64__ 16 + #if !defined(__aarch64__) && !defined(__riscv) 17 17 guest_mode_append(VM_MODE_DEFAULT, true); 18 - #else 18 + #endif 19 + 20 + #ifdef __aarch64__ 19 21 { 20 22 unsigned int limit = kvm_check_cap(KVM_CAP_ARM_VM_IPA_SIZE); 21 23 uint32_t ipa4k, ipa16k, ipa64k; ··· 76 74 #ifdef __riscv 77 75 { 78 76 unsigned int sz = kvm_check_cap(KVM_CAP_VM_GPA_BITS); 77 + unsigned long satp_mode = riscv64_get_satp_mode() << SATP_MODE_SHIFT; 78 + int i; 79 79 80 - if (sz >= 52) 81 - guest_mode_append(VM_MODE_P52V48_4K, true); 82 - if (sz >= 48) 83 - guest_mode_append(VM_MODE_P48V48_4K, true); 80 + switch (sz) { 81 + case 59: 82 + guest_mode_append(VM_MODE_P56V57_4K, satp_mode >= SATP_MODE_57); 83 + guest_mode_append(VM_MODE_P56V48_4K, satp_mode >= SATP_MODE_48); 84 + guest_mode_append(VM_MODE_P56V39_4K, satp_mode >= SATP_MODE_39); 85 + break; 86 + case 50: 87 + guest_mode_append(VM_MODE_P50V57_4K, satp_mode >= SATP_MODE_57); 88 + guest_mode_append(VM_MODE_P50V48_4K, satp_mode >= SATP_MODE_48); 89 + guest_mode_append(VM_MODE_P50V39_4K, satp_mode >= SATP_MODE_39); 90 + break; 91 + case 41: 92 + guest_mode_append(VM_MODE_P41V57_4K, satp_mode >= SATP_MODE_57); 93 + guest_mode_append(VM_MODE_P41V48_4K, satp_mode >= SATP_MODE_48); 94 + guest_mode_append(VM_MODE_P41V39_4K, satp_mode >= SATP_MODE_39); 95 + break; 96 + default: 97 + break; 98 + } 99 + 100 + /* set the first supported mode as default */ 101 + vm_mode_default = NUM_VM_MODES; 102 + for (i = 0; vm_mode_default == NUM_VM_MODES && i < NUM_VM_MODES; i++) { 103 + if (guest_modes[i].supported && guest_modes[i].enabled) 104 + vm_mode_default = i; 105 + } 106 + TEST_ASSERT(vm_mode_default != NUM_VM_MODES, "No supported mode!"); 84 107 } 85 108 #endif 86 109 }
+33
tools/testing/selftests/kvm/lib/kvm_util.c
··· 209 209 [VM_MODE_P36V48_64K] = "PA-bits:36, VA-bits:48, 64K pages", 210 210 [VM_MODE_P47V47_16K] = "PA-bits:47, VA-bits:47, 16K pages", 211 211 [VM_MODE_P36V47_16K] = "PA-bits:36, VA-bits:47, 16K pages", 212 + [VM_MODE_P56V57_4K] = "PA-bits:56, VA-bits:57, 4K pages", 213 + [VM_MODE_P56V48_4K] = "PA-bits:56, VA-bits:48, 4K pages", 214 + [VM_MODE_P56V39_4K] = "PA-bits:56, VA-bits:39, 4K pages", 215 + [VM_MODE_P50V57_4K] = "PA-bits:50, VA-bits:57, 4K pages", 216 + [VM_MODE_P50V48_4K] = "PA-bits:50, VA-bits:48, 4K pages", 217 + [VM_MODE_P50V39_4K] = "PA-bits:50, VA-bits:39, 4K pages", 218 + [VM_MODE_P41V57_4K] = "PA-bits:41, VA-bits:57, 4K pages", 219 + [VM_MODE_P41V48_4K] = "PA-bits:41, VA-bits:48, 4K pages", 220 + [VM_MODE_P41V39_4K] = "PA-bits:41, VA-bits:39, 4K pages", 212 221 }; 213 222 _Static_assert(sizeof(strings)/sizeof(char *) == NUM_VM_MODES, 214 223 "Missing new mode strings?"); ··· 245 236 [VM_MODE_P36V48_64K] = { 36, 48, 0x10000, 16 }, 246 237 [VM_MODE_P47V47_16K] = { 47, 47, 0x4000, 14 }, 247 238 [VM_MODE_P36V47_16K] = { 36, 47, 0x4000, 14 }, 239 + [VM_MODE_P56V57_4K] = { 56, 57, 0x1000, 12 }, 240 + [VM_MODE_P56V48_4K] = { 56, 48, 0x1000, 12 }, 241 + [VM_MODE_P56V39_4K] = { 56, 39, 0x1000, 12 }, 242 + [VM_MODE_P50V57_4K] = { 50, 57, 0x1000, 12 }, 243 + [VM_MODE_P50V48_4K] = { 50, 48, 0x1000, 12 }, 244 + [VM_MODE_P50V39_4K] = { 50, 39, 0x1000, 12 }, 245 + [VM_MODE_P41V57_4K] = { 41, 57, 0x1000, 12 }, 246 + [VM_MODE_P41V48_4K] = { 41, 48, 0x1000, 12 }, 247 + [VM_MODE_P41V39_4K] = { 41, 39, 0x1000, 12 }, 248 248 }; 249 249 _Static_assert(sizeof(vm_guest_mode_params)/sizeof(struct vm_guest_mode_params) == NUM_VM_MODES, 250 250 "Missing new mode params?"); ··· 355 337 break; 356 338 case VM_MODE_P44V64_4K: 357 339 vm->pgtable_levels = 5; 340 + break; 341 + case VM_MODE_P56V57_4K: 342 + case VM_MODE_P50V57_4K: 343 + case VM_MODE_P41V57_4K: 344 + vm->pgtable_levels = 5; 345 + break; 346 + case VM_MODE_P56V48_4K: 347 + case VM_MODE_P50V48_4K: 348 + case VM_MODE_P41V48_4K: 349 + vm->pgtable_levels = 4; 350 + break; 351 + case VM_MODE_P56V39_4K: 352 + case VM_MODE_P50V39_4K: 353 + case VM_MODE_P41V39_4K: 354 + vm->pgtable_levels = 3; 358 355 break; 359 356 default: 360 357 TEST_FAIL("Unknown guest mode: 0x%x", vm->mode);
+59 -4
tools/testing/selftests/kvm/lib/riscv/processor.c
··· 8 8 #include <linux/compiler.h> 9 9 #include <assert.h> 10 10 11 + #include "guest_modes.h" 11 12 #include "kvm_util.h" 12 13 #include "processor.h" 13 14 #include "ucall_common.h" ··· 198 197 { 199 198 struct kvm_vm *vm = vcpu->vm; 200 199 unsigned long satp; 200 + unsigned long satp_mode; 201 + unsigned long max_satp_mode; 201 202 202 203 /* 203 204 * The RISC-V Sv48 MMU mode supports 56-bit physical address 204 205 * for 48-bit virtual address with 4KB last level page size. 205 206 */ 206 207 switch (vm->mode) { 207 - case VM_MODE_P52V48_4K: 208 - case VM_MODE_P48V48_4K: 209 - case VM_MODE_P40V48_4K: 208 + case VM_MODE_P56V57_4K: 209 + case VM_MODE_P50V57_4K: 210 + case VM_MODE_P41V57_4K: 211 + satp_mode = SATP_MODE_57; 212 + break; 213 + case VM_MODE_P56V48_4K: 214 + case VM_MODE_P50V48_4K: 215 + case VM_MODE_P41V48_4K: 216 + satp_mode = SATP_MODE_48; 217 + break; 218 + case VM_MODE_P56V39_4K: 219 + case VM_MODE_P50V39_4K: 220 + case VM_MODE_P41V39_4K: 221 + satp_mode = SATP_MODE_39; 210 222 break; 211 223 default: 212 224 TEST_FAIL("Unknown guest mode, mode: 0x%x", vm->mode); 213 225 } 214 226 227 + max_satp_mode = vcpu_get_reg(vcpu, RISCV_CONFIG_REG(satp_mode)); 228 + 229 + if ((satp_mode >> SATP_MODE_SHIFT) > max_satp_mode) 230 + TEST_FAIL("Unable to set satp mode 0x%lx, max mode 0x%lx\n", 231 + satp_mode >> SATP_MODE_SHIFT, max_satp_mode); 232 + 215 233 satp = (vm->pgd >> PGTBL_PAGE_SIZE_SHIFT) & SATP_PPN; 216 - satp |= SATP_MODE_48; 234 + satp |= satp_mode; 217 235 218 236 vcpu_set_reg(vcpu, RISCV_GENERAL_CSR_REG(satp), satp); 219 237 } ··· 534 514 GUEST_ASSERT(!ret.error); 535 515 536 516 return ret.value; 517 + } 518 + 519 + void kvm_selftest_arch_init(void) 520 + { 521 + /* 522 + * riscv64 doesn't have a true default mode, so start by detecting the 523 + * supported vm mode. 524 + */ 525 + guest_modes_append_default(); 526 + } 527 + 528 + unsigned long riscv64_get_satp_mode(void) 529 + { 530 + int kvm_fd, vm_fd, vcpu_fd, err; 531 + uint64_t val; 532 + struct kvm_one_reg reg = { 533 + .id = RISCV_CONFIG_REG(satp_mode), 534 + .addr = (uint64_t)&val, 535 + }; 536 + 537 + kvm_fd = open_kvm_dev_path_or_exit(); 538 + vm_fd = __kvm_ioctl(kvm_fd, KVM_CREATE_VM, NULL); 539 + TEST_ASSERT(vm_fd >= 0, KVM_IOCTL_ERROR(KVM_CREATE_VM, vm_fd)); 540 + 541 + vcpu_fd = ioctl(vm_fd, KVM_CREATE_VCPU, 0); 542 + TEST_ASSERT(vcpu_fd >= 0, KVM_IOCTL_ERROR(KVM_CREATE_VCPU, vcpu_fd)); 543 + 544 + err = ioctl(vcpu_fd, KVM_GET_ONE_REG, &reg); 545 + TEST_ASSERT(err == 0, KVM_IOCTL_ERROR(KVM_GET_ONE_REG, vcpu_fd)); 546 + 547 + close(vcpu_fd); 548 + close(vm_fd); 549 + close(kvm_fd); 550 + 551 + return val; 537 552 }