On Thu, Jun 4, 2026 at 7:58 PM Jinyu Tang <[email protected]> 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 <[email protected]>

LGTM.

Reviewed-by: Anup Patel <[email protected]>

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
>

Reply via email to