[PATCH v2 2/2] KVM: selftests: Add a hugetlb memslot alignment test mode
Anup Patel
apatel at ventanamicro.com
Sat Jun 6 22:54:40 PDT 2026
On Thu, Jun 4, 2026 at 7:58 PM Jinyu Tang <tjytimi at 163.com> wrote:
>
> 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 at 163.com>
LGTM.
Reviewed-by: Anup Patel <anup at brainfault.org>
I did not observe any impact on the default usage without "-u"
option hence queueing it for Linux-7.2
Thanks
Anup
> ---
> v1 -> v2:
> - Keep the selftest change unchanged from v1
>
> .../selftests/kvm/kvm_page_table_test.c | 28 +++++++++++++++----
> 1 file 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 fc5242fb9..a910e3abb 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]);
> --
> 2.43.0
>
More information about the linux-riscv
mailing list