All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mike Rapoport <rppt@kernel.org>
To: "Lorenzo Stoakes (Oracle)" <ljs@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>,
	"Liam R . Howlett" <Liam.Howlett@oracle.com>,
	Vlastimil Babka <vbabka@kernel.org>, Jann Horn <jannh@google.com>,
	Pedro Falcato <pfalcato@suse.de>,
	David Hildenbrand <david@kernel.org>,
	Suren Baghdasaryan <surenb@google.com>,
	Michal Hocko <mhocko@suse.com>,
	linux-mm@kvack.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2] tools/testing/selftests: add merge test for partial msealed range
Date: Fri, 3 Apr 2026 19:08:40 +0300	[thread overview]
Message-ID: <ac_mCIUQWRAbuH8F@kernel.org> (raw)
In-Reply-To: <20260331073627.50010-1-ljs@kernel.org>

On Tue, Mar 31, 2026 at 08:36:27AM +0100, Lorenzo Stoakes (Oracle) wrote:
> Commit 2697dd8ae721 ("mm/mseal: update VMA end correctly on merge") fixed
> an issue in the loop which iterates through VMAs applying mseal, which was
> triggered by mseal()'ing a range of VMAs where the second was mseal()'d and
> the first mergeable with it, once mseal()'d.
> 
> Add a regression test to assert that this behaviour is correct. We place it
> in the merge selftests as this is strictly an issue with merging (via a
> vma_modify() invocation).
> 
> It also assert that mseal()'d ranges are correctly merged as you'd expect.
> 
> The test is implemented such that it is skipped if mseal() is not
> available on the system.
> 
> Signed-off-by: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
> ---
> v2:
> * Added tools/ based header so __NR_mseal should always be available.
> * However, for completeness, also check to see if defined, and assume ENOSYS if
>   not.
> * Thanks to Mike for reporting issues in his build on this test!

Unfortunately it's not the only one :)

The header inclusion actually causes handle_uprobe_upon_merged_vma() to
fail because of mismatch in definition of__NR_perf_event_open in
<asm-generic/unistd.h> and the correct definition from
/usr/include/unistd.h

With the patch below handle_uprobe_upon_merged_vma() passes again and I
think it's not needed for mseal tests as well.

diff --git a/tools/testing/selftests/mm/merge.c b/tools/testing/selftests/mm/merge.c
index efcb100fd865..519e5ac02db7 100644
--- a/tools/testing/selftests/mm/merge.c
+++ b/tools/testing/selftests/mm/merge.c
@@ -2,7 +2,6 @@
 
 #define _GNU_SOURCE
 #include "kselftest_harness.h"
-#include <asm-generic/unistd.h>
 #include <linux/prctl.h>
 #include <fcntl.h>
 #include <stdio.h>

> v1:
> https://lore.kernel.org/all/20260330135011.107036-1-ljs@kernel.org/
> 
>  tools/testing/selftests/mm/merge.c | 89 ++++++++++++++++++++++++++++++
>  1 file changed, 89 insertions(+)
> 
> diff --git a/tools/testing/selftests/mm/merge.c b/tools/testing/selftests/mm/merge.c
> index 10b686102b79..f73803b3679a 100644
> --- a/tools/testing/selftests/mm/merge.c
> +++ b/tools/testing/selftests/mm/merge.c
> @@ -2,6 +2,7 @@
> 
>  #define _GNU_SOURCE
>  #include "kselftest_harness.h"
> +#include <asm-generic/unistd.h>
>  #include <linux/prctl.h>
>  #include <fcntl.h>
>  #include <stdio.h>
> @@ -48,6 +49,19 @@ static pid_t do_fork(struct procmap_fd *procmap)
>  	return 0;
>  }
> 
> +#ifdef __NR_mseal
> +static int sys_mseal(void *ptr, size_t len, unsigned long flags)
> +{
> +	return syscall(__NR_mseal, (unsigned long)ptr, len, flags);
> +}
> +#else
> +static int sys_mseal(void *ptr, size_t len, unsigned long flags)
> +{
> +	errno = ENOSYS;
> +	return -1;
> +}
> +#endif
> +
>  FIXTURE_SETUP(merge)
>  {
>  	self->page_size = psize();
> @@ -1217,6 +1231,81 @@ TEST_F(merge, mremap_correct_placed_faulted)
>  	ASSERT_EQ(procmap->query.vma_end, (unsigned long)ptr + 15 * page_size);
>  }
> 
> +TEST_F(merge, merge_vmas_with_mseal)
> +{
> +	unsigned int page_size = self->page_size;
> +	struct procmap_fd *procmap = &self->procmap;
> +	char *ptr, *ptr2, *ptr3;
> +	/* We need our own as cannot munmap() once sealed. */
> +	char *carveout;
> +
> +	/* Invalid mseal() call to see if implemented. */
> +	ASSERT_EQ(sys_mseal(NULL, 0, ~0UL), -1);
> +	if (errno == ENOSYS)
> +		SKIP(return, "mseal not supported, skipping.");
> +
> +	/* Map carveout. */
> +	carveout = mmap(NULL, 17 * page_size, PROT_NONE,
> +			MAP_PRIVATE | MAP_ANON, -1, 0);
> +	ASSERT_NE(carveout, MAP_FAILED);
> +
> +	/*
> +	 * Map 3 separate VMAs:
> +	 *
> +	 * |-----------|-----------|-----------|
> +	 * |    RW     |    RWE    |    RO     |
> +	 * |-----------|-----------|-----------|
> +	 *      ptr         ptr2        ptr3
> +	 */
> +	ptr = mmap(&carveout[page_size], 5 * page_size, PROT_READ | PROT_WRITE,
> +		   MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0);
> +	ASSERT_NE(ptr, MAP_FAILED);
> +	ptr2 = mmap(&carveout[page_size * 6], 5 * page_size,
> +		    PROT_READ | PROT_WRITE | PROT_EXEC,
> +		   MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0);
> +	ASSERT_NE(ptr2, MAP_FAILED);
> +	ptr3 = mmap(&carveout[page_size * 11], 5 * page_size, PROT_READ,
> +		   MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0);
> +	ASSERT_NE(ptr3, MAP_FAILED);
> +
> +	/*
> +	 * mseal the second VMA:
> +	 *
> +	 * |-----------|-----------|-----------|
> +	 * |    RW     |    RWES   |    RO     |
> +	 * |-----------|-----------|-----------|
> +	 *      ptr         ptr2        ptr3
> +	 */
> +	ASSERT_EQ(sys_mseal(ptr2, 5 * page_size, 0), 0);
> +
> +	/* Make first VMA mergeable upon mseal. */
> +	ASSERT_EQ(mprotect(ptr, 5 * page_size,
> +			   PROT_READ | PROT_WRITE | PROT_EXEC), 0);
> +	/*
> +	 * At this point we have:
> +	 *
> +	 * |-----------|-----------|-----------|
> +	 * |    RWE    |    RWES   |    RO     |
> +	 * |-----------|-----------|-----------|
> +	 *      ptr         ptr2        ptr3
> +	 *
> +	 * Now mseal all of the VMAs.
> +	 */
> +	ASSERT_EQ(sys_mseal(ptr, 15 * page_size, 0), 0);
> +
> +	/*
> +	 * We should end up with:
> +	 *
> +	 * |-----------------------|-----------|
> +	 * |          RWES         |    ROS    |
> +	 * |-----------------------|-----------|
> +	 *            ptr               ptr3
> +	 */
> +	ASSERT_TRUE(find_vma_procmap(procmap, ptr));
> +	ASSERT_EQ(procmap->query.vma_start, (unsigned long)ptr);
> +	ASSERT_EQ(procmap->query.vma_end, (unsigned long)ptr + 10 * page_size);
> +}
> +
>  TEST_F(merge_with_fork, mremap_faulted_to_unfaulted_prev)
>  {
>  	struct procmap_fd *procmap = &self->procmap;
> --
> 2.53.0
> 

-- 
Sincerely yours,
Mike.


  parent reply	other threads:[~2026-04-03 16:08 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-31  7:36 [PATCH v2] tools/testing/selftests: add merge test for partial msealed range Lorenzo Stoakes (Oracle)
2026-03-31  9:35 ` Pedro Falcato
2026-03-31  9:56   ` Lorenzo Stoakes (Oracle)
2026-03-31 10:08   ` Lorenzo Stoakes (Oracle)
2026-03-31 13:54     ` Pedro Falcato
2026-04-01  0:58     ` Andrew Morton
2026-04-01  8:32       ` Lorenzo Stoakes (Oracle)
2026-04-03 16:08 ` Mike Rapoport [this message]
2026-04-03 16:33   ` Lorenzo Stoakes (Oracle)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ac_mCIUQWRAbuH8F@kernel.org \
    --to=rppt@kernel.org \
    --cc=Liam.Howlett@oracle.com \
    --cc=akpm@linux-foundation.org \
    --cc=david@kernel.org \
    --cc=jannh@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=ljs@kernel.org \
    --cc=mhocko@suse.com \
    --cc=pfalcato@suse.de \
    --cc=surenb@google.com \
    --cc=vbabka@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.