Skip to content

Commit e0f3f46

Browse files
dmatlackbonzini
authored andcommitted
KVM: selftests: Restrict test region to 48-bit physical addresses when using nested
The selftests nested code only supports 4-level paging at the moment. This means it cannot map nested guest physical addresses with more than 48 bits. Allow perf_test_util nested mode to work on hosts with more than 48 physical addresses by restricting the guest test region to 48-bits. While here, opportunistically fix an off-by-one error when dealing with vm_get_max_gfn(). perf_test_util.c was treating this as the maximum number of GFNs, rather than the maximum allowed GFN. This didn't result in any correctness issues, but it did end up shifting the test region down slightly when using huge pages. Suggested-by: Sean Christopherson <seanjc@google.com> Signed-off-by: David Matlack <dmatlack@google.com> Message-Id: <20220520233249.3776001-12-dmatlack@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent 71d4896 commit e0f3f46

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

tools/testing/selftests/kvm/lib/perf_test_util.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ struct kvm_vm *perf_test_create_vm(enum vm_guest_mode mode, int vcpus,
110110
struct kvm_vm *vm;
111111
uint64_t guest_num_pages, slot0_pages = DEFAULT_GUEST_PHY_PAGES;
112112
uint64_t backing_src_pagesz = get_backing_src_pagesz(backing_src);
113+
uint64_t region_end_gfn;
113114
int i;
114115

115116
pr_info("Testing guest mode: %s\n", vm_guest_mode_string(mode));
@@ -151,18 +152,29 @@ struct kvm_vm *perf_test_create_vm(enum vm_guest_mode mode, int vcpus,
151152

152153
pta->vm = vm;
153154

155+
/* Put the test region at the top guest physical memory. */
156+
region_end_gfn = vm_get_max_gfn(vm) + 1;
157+
158+
#ifdef __x86_64__
159+
/*
160+
* When running vCPUs in L2, restrict the test region to 48 bits to
161+
* avoid needing 5-level page tables to identity map L2.
162+
*/
163+
if (pta->nested)
164+
region_end_gfn = min(region_end_gfn, (1UL << 48) / pta->guest_page_size);
165+
#endif
154166
/*
155167
* If there should be more memory in the guest test region than there
156168
* can be pages in the guest, it will definitely cause problems.
157169
*/
158-
TEST_ASSERT(guest_num_pages < vm_get_max_gfn(vm),
170+
TEST_ASSERT(guest_num_pages < region_end_gfn,
159171
"Requested more guest memory than address space allows.\n"
160172
" guest pages: %" PRIx64 " max gfn: %" PRIx64
161173
" vcpus: %d wss: %" PRIx64 "]\n",
162-
guest_num_pages, vm_get_max_gfn(vm), vcpus,
174+
guest_num_pages, region_end_gfn - 1, vcpus,
163175
vcpu_memory_bytes);
164176

165-
pta->gpa = (vm_get_max_gfn(vm) - guest_num_pages) * pta->guest_page_size;
177+
pta->gpa = (region_end_gfn - guest_num_pages) * pta->guest_page_size;
166178
pta->gpa = align_down(pta->gpa, backing_src_pagesz);
167179
#ifdef __s390x__
168180
/* Align to 1M (segment size) */

0 commit comments

Comments
 (0)