1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2020, Red Hat, Inc.
5 #include "guest_modes.h"
9 enum vm_guest_mode vm_mode_default
;
12 struct guest_mode guest_modes
[NUM_VM_MODES
];
14 void guest_modes_append_default(void)
17 guest_mode_append(VM_MODE_DEFAULT
, true);
20 unsigned int limit
= kvm_check_cap(KVM_CAP_ARM_VM_IPA_SIZE
);
21 uint32_t ipa4k
, ipa16k
, ipa64k
;
24 aarch64_get_supported_page_sizes(limit
, &ipa4k
, &ipa16k
, &ipa64k
);
26 guest_mode_append(VM_MODE_P52V48_4K
, ipa4k
>= 52);
27 guest_mode_append(VM_MODE_P52V48_16K
, ipa16k
>= 52);
28 guest_mode_append(VM_MODE_P52V48_64K
, ipa64k
>= 52);
30 guest_mode_append(VM_MODE_P48V48_4K
, ipa4k
>= 48);
31 guest_mode_append(VM_MODE_P48V48_16K
, ipa16k
>= 48);
32 guest_mode_append(VM_MODE_P48V48_64K
, ipa64k
>= 48);
34 guest_mode_append(VM_MODE_P40V48_4K
, ipa4k
>= 40);
35 guest_mode_append(VM_MODE_P40V48_16K
, ipa16k
>= 40);
36 guest_mode_append(VM_MODE_P40V48_64K
, ipa64k
>= 40);
38 guest_mode_append(VM_MODE_P36V48_4K
, ipa4k
>= 36);
39 guest_mode_append(VM_MODE_P36V48_16K
, ipa16k
>= 36);
40 guest_mode_append(VM_MODE_P36V48_64K
, ipa64k
>= 36);
41 guest_mode_append(VM_MODE_P36V47_16K
, ipa16k
>= 36);
43 vm_mode_default
= ipa4k
>= 40 ? VM_MODE_P40V48_4K
: NUM_VM_MODES
;
46 * Pick the first supported IPA size if the default
49 for (i
= 0; vm_mode_default
== NUM_VM_MODES
&& i
< NUM_VM_MODES
; i
++) {
50 if (guest_modes
[i
].supported
&& guest_modes
[i
].enabled
)
54 TEST_ASSERT(vm_mode_default
!= NUM_VM_MODES
,
55 "No supported mode!");
61 struct kvm_s390_vm_cpu_processor info
;
63 kvm_fd
= open_kvm_dev_path_or_exit();
64 vm_fd
= __kvm_ioctl(kvm_fd
, KVM_CREATE_VM
, NULL
);
65 kvm_device_attr_get(vm_fd
, KVM_S390_VM_CPU_MODEL
,
66 KVM_S390_VM_CPU_PROCESSOR
, &info
);
69 /* Starting with z13 we have 47bits of physical address */
71 guest_mode_append(VM_MODE_P47V64_4K
, true);
76 unsigned int sz
= kvm_check_cap(KVM_CAP_VM_GPA_BITS
);
79 guest_mode_append(VM_MODE_P52V48_4K
, true);
81 guest_mode_append(VM_MODE_P48V48_4K
, true);
86 void for_each_guest_mode(void (*func
)(enum vm_guest_mode
, void *), void *arg
)
90 for (i
= 0; i
< NUM_VM_MODES
; ++i
) {
91 if (!guest_modes
[i
].enabled
)
93 TEST_ASSERT(guest_modes
[i
].supported
,
94 "Guest mode ID %d (%s) not supported.",
95 i
, vm_guest_mode_string(i
));
100 void guest_modes_help(void)
104 printf(" -m: specify the guest mode ID to test\n"
105 " (default: test all supported modes)\n"
106 " This option may be used multiple times.\n"
107 " Guest mode IDs:\n");
108 for (i
= 0; i
< NUM_VM_MODES
; ++i
) {
109 printf(" %d: %s%s\n", i
, vm_guest_mode_string(i
),
110 guest_modes
[i
].supported
? " (supported)" : "");
114 void guest_modes_cmdline(const char *arg
)
116 static bool mode_selected
;
120 if (!mode_selected
) {
121 for (i
= 0; i
< NUM_VM_MODES
; ++i
)
122 guest_modes
[i
].enabled
= false;
123 mode_selected
= true;
126 mode
= atoi_non_negative("Guest mode ID", arg
);
127 TEST_ASSERT(mode
< NUM_VM_MODES
, "Guest mode ID %d too big", mode
);
128 guest_modes
[mode
].enabled
= true;