Skip to content

Commit

Permalink
KVM: selftests: Restrict test region to 48-bit physical addresses whe…
Browse files Browse the repository at this point in the history
…n 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>
  • Loading branch information
David Matlack authored and Paolo Bonzini committed Jun 9, 2022
1 parent 71d4896 commit e0f3f46
Showing 1 changed file with 15 additions and 3 deletions.
18 changes: 15 additions & 3 deletions tools/testing/selftests/kvm/lib/perf_test_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ struct kvm_vm *perf_test_create_vm(enum vm_guest_mode mode, int vcpus,
struct kvm_vm *vm;
uint64_t guest_num_pages, slot0_pages = DEFAULT_GUEST_PHY_PAGES;
uint64_t backing_src_pagesz = get_backing_src_pagesz(backing_src);
uint64_t region_end_gfn;
int i;

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

pta->vm = vm;

/* Put the test region at the top guest physical memory. */
region_end_gfn = vm_get_max_gfn(vm) + 1;

#ifdef __x86_64__
/*
* When running vCPUs in L2, restrict the test region to 48 bits to
* avoid needing 5-level page tables to identity map L2.
*/
if (pta->nested)
region_end_gfn = min(region_end_gfn, (1UL << 48) / pta->guest_page_size);
#endif
/*
* If there should be more memory in the guest test region than there
* can be pages in the guest, it will definitely cause problems.
*/
TEST_ASSERT(guest_num_pages < vm_get_max_gfn(vm),
TEST_ASSERT(guest_num_pages < region_end_gfn,
"Requested more guest memory than address space allows.\n"
" guest pages: %" PRIx64 " max gfn: %" PRIx64
" vcpus: %d wss: %" PRIx64 "]\n",
guest_num_pages, vm_get_max_gfn(vm), vcpus,
guest_num_pages, region_end_gfn - 1, vcpus,
vcpu_memory_bytes);

pta->gpa = (vm_get_max_gfn(vm) - guest_num_pages) * pta->guest_page_size;
pta->gpa = (region_end_gfn - guest_num_pages) * pta->guest_page_size;
pta->gpa = align_down(pta->gpa, backing_src_pagesz);
#ifdef __s390x__
/* Align to 1M (segment size) */
Expand Down

0 comments on commit e0f3f46

Please sign in to comment.