mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 01:53:29 +02:00
Use u32 instead of uint32_t to make the KVM selftests code more concise and more similar to the kernel (since selftests are primarily developed by kernel developers). This commit was generated with the following command: git ls-files tools/testing/selftests/kvm | xargs sed -i 's/uint32_t/u32/g' Then by manually adjusting whitespace to make checkpatch.pl happy. No functional change intended. Signed-off-by: David Matlack <dmatlack@google.com> Link: https://patch.msgid.link/20260420212004.3938325-7-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
157 lines
4.3 KiB
C
157 lines
4.3 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Copyright (C) 2020, Red Hat, Inc.
|
|
*/
|
|
#include "guest_modes.h"
|
|
|
|
#if defined(__aarch64__) || defined(__riscv)
|
|
#include "processor.h"
|
|
enum vm_guest_mode vm_mode_default;
|
|
#endif
|
|
|
|
struct guest_mode guest_modes[NUM_VM_MODES];
|
|
|
|
void guest_modes_append_default(void)
|
|
{
|
|
#if !defined(__aarch64__) && !defined(__riscv)
|
|
guest_mode_append(VM_MODE_DEFAULT, true);
|
|
#endif
|
|
|
|
#ifdef __aarch64__
|
|
{
|
|
unsigned int limit = kvm_check_cap(KVM_CAP_ARM_VM_IPA_SIZE);
|
|
u32 ipa4k, ipa16k, ipa64k;
|
|
int i;
|
|
|
|
aarch64_get_supported_page_sizes(limit, &ipa4k, &ipa16k, &ipa64k);
|
|
|
|
guest_mode_append(VM_MODE_P52V48_4K, ipa4k >= 52);
|
|
guest_mode_append(VM_MODE_P52V48_16K, ipa16k >= 52);
|
|
guest_mode_append(VM_MODE_P52V48_64K, ipa64k >= 52);
|
|
|
|
guest_mode_append(VM_MODE_P48V48_4K, ipa4k >= 48);
|
|
guest_mode_append(VM_MODE_P48V48_16K, ipa16k >= 48);
|
|
guest_mode_append(VM_MODE_P48V48_64K, ipa64k >= 48);
|
|
|
|
guest_mode_append(VM_MODE_P40V48_4K, ipa4k >= 40);
|
|
guest_mode_append(VM_MODE_P40V48_16K, ipa16k >= 40);
|
|
guest_mode_append(VM_MODE_P40V48_64K, ipa64k >= 40);
|
|
|
|
guest_mode_append(VM_MODE_P36V48_4K, ipa4k >= 36);
|
|
guest_mode_append(VM_MODE_P36V48_16K, ipa16k >= 36);
|
|
guest_mode_append(VM_MODE_P36V48_64K, ipa64k >= 36);
|
|
guest_mode_append(VM_MODE_P36V47_16K, ipa16k >= 36);
|
|
|
|
vm_mode_default = ipa4k >= 40 ? VM_MODE_P40V48_4K : NUM_VM_MODES;
|
|
|
|
/*
|
|
* Pick the first supported IPA size if the default
|
|
* isn't available.
|
|
*/
|
|
for (i = 0; vm_mode_default == NUM_VM_MODES && i < NUM_VM_MODES; i++) {
|
|
if (guest_modes[i].supported && guest_modes[i].enabled)
|
|
vm_mode_default = i;
|
|
}
|
|
|
|
TEST_ASSERT(vm_mode_default != NUM_VM_MODES,
|
|
"No supported mode!");
|
|
}
|
|
#endif
|
|
#ifdef __s390x__
|
|
{
|
|
int kvm_fd, vm_fd;
|
|
struct kvm_s390_vm_cpu_processor info;
|
|
|
|
kvm_fd = open_kvm_dev_path_or_exit();
|
|
vm_fd = __kvm_ioctl(kvm_fd, KVM_CREATE_VM, NULL);
|
|
kvm_device_attr_get(vm_fd, KVM_S390_VM_CPU_MODEL,
|
|
KVM_S390_VM_CPU_PROCESSOR, &info);
|
|
close(vm_fd);
|
|
close(kvm_fd);
|
|
/* Starting with z13 we have 47bits of physical address */
|
|
if (info.ibc >= 0x30)
|
|
guest_mode_append(VM_MODE_P47V64_4K, true);
|
|
}
|
|
#endif
|
|
#ifdef __riscv
|
|
{
|
|
unsigned int sz = kvm_check_cap(KVM_CAP_VM_GPA_BITS);
|
|
unsigned long satp_mode = riscv64_get_satp_mode() << SATP_MODE_SHIFT;
|
|
int i;
|
|
|
|
switch (sz) {
|
|
case 59:
|
|
guest_mode_append(VM_MODE_P56V57_4K, satp_mode >= SATP_MODE_57);
|
|
guest_mode_append(VM_MODE_P56V48_4K, satp_mode >= SATP_MODE_48);
|
|
guest_mode_append(VM_MODE_P56V39_4K, satp_mode >= SATP_MODE_39);
|
|
break;
|
|
case 50:
|
|
guest_mode_append(VM_MODE_P50V57_4K, satp_mode >= SATP_MODE_57);
|
|
guest_mode_append(VM_MODE_P50V48_4K, satp_mode >= SATP_MODE_48);
|
|
guest_mode_append(VM_MODE_P50V39_4K, satp_mode >= SATP_MODE_39);
|
|
break;
|
|
case 41:
|
|
guest_mode_append(VM_MODE_P41V57_4K, satp_mode >= SATP_MODE_57);
|
|
guest_mode_append(VM_MODE_P41V48_4K, satp_mode >= SATP_MODE_48);
|
|
guest_mode_append(VM_MODE_P41V39_4K, satp_mode >= SATP_MODE_39);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
/* set the first supported mode as default */
|
|
vm_mode_default = NUM_VM_MODES;
|
|
for (i = 0; vm_mode_default == NUM_VM_MODES && i < NUM_VM_MODES; i++) {
|
|
if (guest_modes[i].supported && guest_modes[i].enabled)
|
|
vm_mode_default = i;
|
|
}
|
|
TEST_ASSERT(vm_mode_default != NUM_VM_MODES, "No supported mode!");
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void for_each_guest_mode(void (*func)(enum vm_guest_mode, void *), void *arg)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < NUM_VM_MODES; ++i) {
|
|
if (!guest_modes[i].enabled)
|
|
continue;
|
|
TEST_ASSERT(guest_modes[i].supported,
|
|
"Guest mode ID %d (%s) not supported.",
|
|
i, vm_guest_mode_string(i));
|
|
func(i, arg);
|
|
}
|
|
}
|
|
|
|
void guest_modes_help(void)
|
|
{
|
|
int i;
|
|
|
|
printf(" -m: specify the guest mode ID to test\n"
|
|
" (default: test all supported modes)\n"
|
|
" This option may be used multiple times.\n"
|
|
" Guest mode IDs:\n");
|
|
for (i = 0; i < NUM_VM_MODES; ++i) {
|
|
printf(" %d: %s%s\n", i, vm_guest_mode_string(i),
|
|
guest_modes[i].supported ? " (supported)" : "");
|
|
}
|
|
}
|
|
|
|
void guest_modes_cmdline(const char *arg)
|
|
{
|
|
static bool mode_selected;
|
|
unsigned int mode;
|
|
int i;
|
|
|
|
if (!mode_selected) {
|
|
for (i = 0; i < NUM_VM_MODES; ++i)
|
|
guest_modes[i].enabled = false;
|
|
mode_selected = true;
|
|
}
|
|
|
|
mode = atoi_non_negative("Guest mode ID", arg);
|
|
TEST_ASSERT(mode < NUM_VM_MODES, "Guest mode ID %d too big", mode);
|
|
guest_modes[mode].enabled = true;
|
|
}
|