summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJinyu Tang <tjytimi@163.com>2026-06-04 17:26:02 +0300
committerAnup Patel <anup@brainfault.org>2026-06-07 08:46:18 +0300
commitc8aafbebfc95d9b65b9b86573dc47723fa621358 (patch)
treef01bac5652e2fcf2df416cc4d17cae522dd70ba6
parent49476d58f2171afc2e899da8040710d2c37760af (diff)
downloadlinux-c8aafbebfc95d9b65b9b86573dc47723fa621358.tar.xz
KVM: selftests: Add a hugetlb memslot alignment test mode
kvm_page_table_test can already exercise hugetlb-backed guest memory, but it always creates the test memslot with GPA alignment matching the hugetlb backing size. That misses the case where a valid hugetlb memslot is later moved so that the memslot GPA and HVA no longer have the same offset within the backing huge page. Add a -u option that moves the test memslot GPA by one guest page after creating the hugetlb memslot. The memslot is created through the normal helper first, so the backing allocation remains valid and hugetlb aligned. Moving the memslot then creates a deliberate HVA/GPA offset mismatch before the guest mapping is installed. This mode is useful for checking that architecture MMUs do not install a block mapping when the block would map the wrong host pages or cover memory outside the memslot. The option is restricted to hugetlb-backed test memory because it's specifically about hugetlb block mapping eligibility. Signed-off-by: Jinyu Tang <tjytimi@163.com> Reviewed-by: Anup Patel <anup@brainfault.org> Link: https://lore.kernel.org/r/20260604142602.3582602-3-tjytimi@163.com Signed-off-by: Anup Patel <anup@brainfault.org>
-rw-r--r--tools/testing/selftests/kvm/kvm_page_table_test.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/tools/testing/selftests/kvm/kvm_page_table_test.c b/tools/testing/selftests/kvm/kvm_page_table_test.c
index fc5242fb956f..a910e3abb8c7 100644
--- a/tools/testing/selftests/kvm/kvm_page_table_test.c
+++ b/tools/testing/selftests/kvm/kvm_page_table_test.c
@@ -230,6 +230,7 @@ struct test_params {
u64 phys_offset;
u64 test_mem_size;
enum vm_mem_backing_src_type src_type;
+ bool misalign_slot_gpa;
};
static struct kvm_vm *pre_init_before_test(enum vm_guest_mode mode, void *arg)
@@ -244,6 +245,7 @@ static struct kvm_vm *pre_init_before_test(enum vm_guest_mode mode, void *arg)
u64 guest_num_pages;
u64 alignment;
void *host_test_mem;
+ struct userspace_mem_region *region;
struct kvm_vm *vm;
/* Align up the test memory size */
@@ -276,13 +278,22 @@ static struct kvm_vm *pre_init_before_test(enum vm_guest_mode mode, void *arg)
/* Add an extra memory slot with specified backing src type */
vm_userspace_mem_region_add(vm, src_type, guest_test_phys_mem,
TEST_MEM_SLOT_INDEX, guest_num_pages, 0);
+ region = memslot2region(vm, TEST_MEM_SLOT_INDEX);
+ host_test_mem = region->host_mem;
+
+ if (p->misalign_slot_gpa) {
+ TEST_ASSERT(is_backing_src_hugetlb(src_type),
+ "Memslot GPA misalignment requires hugetlb backing");
+ TEST_ASSERT(guest_num_pages > 1,
+ "Need at least two guest pages to misalign memslot GPA");
+
+ guest_test_phys_mem += guest_page_size;
+ vm_mem_region_move(vm, TEST_MEM_SLOT_INDEX, guest_test_phys_mem);
+ }
/* Do mapping(GVA->GPA) for the testing memory slot */
virt_map(vm, guest_test_virt_mem, guest_test_phys_mem, guest_num_pages);
- /* Cache the HVA pointer of the region */
- host_test_mem = addr_gpa2hva(vm, (gpa_t)guest_test_phys_mem);
-
/* Export shared structure test_args to guest */
sync_global_to_guest(vm, test_args);
@@ -417,8 +428,8 @@ static void run_test(enum vm_guest_mode mode, void *arg)
static void help(char *name)
{
puts("");
- printf("usage: %s [-h] [-p offset] [-m mode] "
- "[-b mem-size] [-v vcpus] [-s mem-type]\n", name);
+ printf("usage: %s [-h] [-p offset] [-m mode] [-b mem-size]\n", name);
+ printf(" [-v vcpus] [-s mem-type] [-u]\n");
puts("");
printf(" -p: specify guest physical test memory offset\n"
" Warning: a low offset can conflict with the loaded test code.\n");
@@ -428,6 +439,8 @@ static void help(char *name)
printf(" -v: specify the number of vCPUs to run\n"
" (default: 1)\n");
backing_src_help("-s");
+ printf(" -u: move the test memslot GPA by one guest page after creating\n"
+ " the memslot, forcing a hugetlb HVA/GPA offset mismatch\n");
puts("");
}
@@ -442,7 +455,7 @@ int main(int argc, char *argv[])
guest_modes_append_default();
- while ((opt = getopt(argc, argv, "hp:m:b:v:s:")) != -1) {
+ while ((opt = getopt(argc, argv, "hp:m:b:v:s:u")) != -1) {
switch (opt) {
case 'p':
p.phys_offset = strtoull(optarg, NULL, 0);
@@ -461,6 +474,9 @@ int main(int argc, char *argv[])
case 's':
p.src_type = parse_backing_src_type(optarg);
break;
+ case 'u':
+ p.misalign_slot_gpa = true;
+ break;
case 'h':
default:
help(argv[0]);