Re: [PATCH v4 08/20] tools/testing/vma: add tests for copy_vma() self-merge

From: David Hildenbrand (Arm)

Date: Tue Aug 11 2026 - 13:08:57 EST


On 8/6/26 22:21, Lorenzo Stoakes (ARM) wrote:
> Assert that a VMA can be moved backwards, forwards and between a preceding
> VMA and its old self.
>
> In the cases in which the VMA merges only with itself expect that to be
> achieved by expanding its old self, so assert that these function
> correctly.
>
> However in the case of a merge between a preceding VMA and itself the
> original VMA is removed, so assert that the preceding VMA replaces the one
> passed in as vmap and the merge is as expected.
>
> Signed-off-by: Lorenzo Stoakes (ARM) <ljs@xxxxxxxxxx>
> ---
> tools/testing/vma/tests/vma.c | 46 ++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 45 insertions(+), 1 deletion(-)
>
> diff --git a/tools/testing/vma/tests/vma.c b/tools/testing/vma/tests/vma.c
> index 754a2da06321..0d40d7ba2181 100644
> --- a/tools/testing/vma/tests/vma.c
> +++ b/tools/testing/vma/tests/vma.c
> @@ -33,7 +33,51 @@ static bool test_copy_vma(void)
> struct mm_struct mm = {};
> bool need_locks = false;
> VMA_ITERATOR(vmi, &mm, 0);
> - struct vm_area_struct *vma, *vma_new, *vma_next;
> + struct vm_area_struct *vma, *vma_prev, *vma_new, *vma_next, *vma_orig;
> +
> + /* Move forwards, adjacent to old self - self-merge. */
> +
> + vma = alloc_and_link_vma(&mm, 0x1000, 0x2000, 1, vma_flags);
> + vma_set_anonymous(vma);
> + vma_orig = vma;
> + vma_new = copy_vma(&vma, 0x2000, 0x1000, 1, &need_locks);
> + ASSERT_EQ(vma_new, vma_orig);
> + ASSERT_EQ(vma, vma_orig);
> + ASSERT_EQ(vma_new->vm_start, 0x1000);
> + ASSERT_EQ(vma_new->vm_end, 0x3000);
> +
> + cleanup_mm(&mm, &vmi);
> +
> + /* Move backwards, adjacent to old self - self-merge. */
> +
> + vma = alloc_and_link_vma(&mm, 0x2000, 0x3000, 2, vma_flags);
> + vma_set_anonymous(vma);
> + vma_orig = vma;
> + vma_new = copy_vma(&vma, 0x1000, 0x1000, 2, &need_locks);
> + ASSERT_EQ(vma_new, vma_orig);
> + ASSERT_EQ(vma, vma_orig);
> + ASSERT_EQ(vma_new->vm_start, 0x1000);
> + ASSERT_EQ(vma_new->vm_end, 0x3000);
> +
> + cleanup_mm(&mm, &vmi);
> +
> + /*
> + * Move backwards between prior VMA and old self - self-merge and vma
> + * updated to a new VMA.
> + */
> +
> + vma_prev = alloc_and_link_vma(&mm, 0x1000, 0x2000, 1, vma_flags);
> + vma_set_anonymous(vma_prev);
> + vma = alloc_and_link_vma(&mm, 0x3000, 0x4000, 3, vma_flags);
> + vma_set_anonymous(vma);
> + vma_orig = vma;
> + vma_new = copy_vma(&vma, 0x2000, 0x1000, 3, &need_locks);
> + ASSERT_NE(vma_new, vma_orig);
> + ASSERT_EQ(vma_new, vma);
> + ASSERT_EQ(vma_new->vm_start, 0x1000);
> + ASSERT_EQ(vma_new->vm_end, 0x4000);
> +
> + cleanup_mm(&mm, &vmi);

Okay, these examples were pretty useful to understand the original problem.

Acked-by: David Hildenbrand (Arm) <david@xxxxxxxxxx>

--
Cheers,

David