linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3 v2] fs/proc: extend the PAGEMAP_SCAN ioctl to report guard regions
@ 2025-03-24  6:53 Andrei Vagin
  2025-03-24  6:53 ` [PATCH 1/3] " Andrei Vagin
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Andrei Vagin @ 2025-03-24  6:53 UTC (permalink / raw)
  To: Lorenzo Stoakes, Andrew Morton
  Cc: linux-kernel, linux-mm, linux-fsdevel, linux-doc,
	David Hildenbrand, Shuah Khan, Jonathan Corbet, criu,
	Andrei Vagin

Introduce the PAGE_IS_GUARD flag in the PAGEMAP_SCAN ioctl to expose
information about guard regions. This allows userspace tools, such as
CRIU, to detect and handle guard regions.

Currently, CRIU utilizes PAGEMAP_SCAN as a more efficient alternative to
parsing /proc/pid/pagemap. Without this change, guard regions are
incorrectly reported as swap-anon regions, leading CRIU to attempt
dumping them and subsequently failing.

This series should be applied on top of "[PATCH 0/2] fs/proc/task_mmu:
add guard region bit to pagemap":
https://lore.kernel.org/all/2025031926-engraved-footer-3e9b@gregkh/T/

The series includes updates to the documentation and selftests to
reflect the new functionality.

v2:
- sync linux/fs.h with the kernel sources
- address comments from Lorenzo and David.

Andrei Vagin (3):
  fs/proc: extend the PAGEMAP_SCAN ioctl to report guard regions
  tools headers UAPI: Sync linux/fs.h with the kernel sources
  selftests/mm: add PAGEMAP_SCAN guard region test

 Documentation/admin-guide/mm/pagemap.rst   |  1 +
 fs/proc/task_mmu.c                         | 17 ++++---
 include/uapi/linux/fs.h                    |  1 +
 tools/include/uapi/linux/fs.h              | 19 +++++++-
 tools/testing/selftests/mm/guard-regions.c | 57 ++++++++++++++++++++++
 5 files changed, 87 insertions(+), 8 deletions(-)

-- 
2.49.0.rc1.451.g8f38331e32-goog



^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/3] fs/proc: extend the PAGEMAP_SCAN ioctl to report guard regions
  2025-03-24  6:53 [PATCH 0/3 v2] fs/proc: extend the PAGEMAP_SCAN ioctl to report guard regions Andrei Vagin
@ 2025-03-24  6:53 ` Andrei Vagin
  2025-03-24  6:53 ` [PATCH 2/3] tools headers UAPI: Sync linux/fs.h with the kernel sources Andrei Vagin
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 8+ messages in thread
From: Andrei Vagin @ 2025-03-24  6:53 UTC (permalink / raw)
  To: Lorenzo Stoakes, Andrew Morton
  Cc: linux-kernel, linux-mm, linux-fsdevel, linux-doc,
	David Hildenbrand, Shuah Khan, Jonathan Corbet, criu,
	Andrei Vagin

From: Andrei Vagin <avagin@gmail.com>

Introduce the PAGE_IS_GUARD flag in the PAGEMAP_SCAN ioctl to expose
information about guard regions. This allows userspace tools, such as
CRIU, to detect and handle guard regions.

Acked-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Signed-off-by: Andrei Vagin <avagin@gmail.com>
---
 Documentation/admin-guide/mm/pagemap.rst |  1 +
 fs/proc/task_mmu.c                       | 17 ++++++++++-------
 include/uapi/linux/fs.h                  |  1 +
 3 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/Documentation/admin-guide/mm/pagemap.rst b/Documentation/admin-guide/mm/pagemap.rst
index a297e824f990..1f49762190eb 100644
--- a/Documentation/admin-guide/mm/pagemap.rst
+++ b/Documentation/admin-guide/mm/pagemap.rst
@@ -234,6 +234,7 @@ Following flags about pages are currently supported:
 - ``PAGE_IS_PFNZERO`` - Page has zero PFN
 - ``PAGE_IS_HUGE`` - Page is PMD-mapped THP or Hugetlb backed
 - ``PAGE_IS_SOFT_DIRTY`` - Page is soft-dirty
+- ``PAGE_IS_GUARD`` - Page is a part of a guard region
 
 The ``struct pm_scan_arg`` is used as the argument of the IOCTL.
 
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index c17615e21a5d..cc35d8990c54 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -2067,7 +2067,8 @@ static int pagemap_release(struct inode *inode, struct file *file)
 #define PM_SCAN_CATEGORIES	(PAGE_IS_WPALLOWED | PAGE_IS_WRITTEN |	\
 				 PAGE_IS_FILE |	PAGE_IS_PRESENT |	\
 				 PAGE_IS_SWAPPED | PAGE_IS_PFNZERO |	\
-				 PAGE_IS_HUGE | PAGE_IS_SOFT_DIRTY)
+				 PAGE_IS_HUGE | PAGE_IS_SOFT_DIRTY |	\
+				 PAGE_IS_GUARD)
 #define PM_SCAN_FLAGS		(PM_SCAN_WP_MATCHING | PM_SCAN_CHECK_WPASYNC)
 
 struct pagemap_scan_private {
@@ -2108,12 +2109,14 @@ static unsigned long pagemap_page_category(struct pagemap_scan_private *p,
 		if (!pte_swp_uffd_wp_any(pte))
 			categories |= PAGE_IS_WRITTEN;
 
-		if (p->masks_of_interest & PAGE_IS_FILE) {
-			swp = pte_to_swp_entry(pte);
-			if (is_pfn_swap_entry(swp) &&
-			    !folio_test_anon(pfn_swap_entry_folio(swp)))
-				categories |= PAGE_IS_FILE;
-		}
+		swp = pte_to_swp_entry(pte);
+		if (is_guard_swp_entry(swp))
+			categories |= PAGE_IS_GUARD;
+		else if ((p->masks_of_interest & PAGE_IS_FILE) &&
+			 is_pfn_swap_entry(swp) &&
+			 !folio_test_anon(pfn_swap_entry_folio(swp)))
+			categories |= PAGE_IS_FILE;
+
 		if (pte_swp_soft_dirty(pte))
 			categories |= PAGE_IS_SOFT_DIRTY;
 	}
diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h
index 2bbe00cf1248..8aa66c5f69b7 100644
--- a/include/uapi/linux/fs.h
+++ b/include/uapi/linux/fs.h
@@ -363,6 +363,7 @@ typedef int __bitwise __kernel_rwf_t;
 #define PAGE_IS_PFNZERO		(1 << 5)
 #define PAGE_IS_HUGE		(1 << 6)
 #define PAGE_IS_SOFT_DIRTY	(1 << 7)
+#define PAGE_IS_GUARD		(1 << 8)
 
 /*
  * struct page_region - Page region with flags
-- 
2.49.0.395.g12beb8f557-goog



^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 2/3] tools headers UAPI: Sync linux/fs.h with the kernel sources
  2025-03-24  6:53 [PATCH 0/3 v2] fs/proc: extend the PAGEMAP_SCAN ioctl to report guard regions Andrei Vagin
  2025-03-24  6:53 ` [PATCH 1/3] " Andrei Vagin
@ 2025-03-24  6:53 ` Andrei Vagin
  2025-03-31 11:27   ` Lorenzo Stoakes
  2025-03-24  6:53 ` [PATCH 3/3] selftests/mm: add PAGEMAP_SCAN guard region test Andrei Vagin
  2025-03-31 11:26 ` [PATCH 0/3 v2] fs/proc: extend the PAGEMAP_SCAN ioctl to report guard regions Lorenzo Stoakes
  3 siblings, 1 reply; 8+ messages in thread
From: Andrei Vagin @ 2025-03-24  6:53 UTC (permalink / raw)
  To: Lorenzo Stoakes, Andrew Morton
  Cc: linux-kernel, linux-mm, linux-fsdevel, linux-doc,
	David Hildenbrand, Shuah Khan, Jonathan Corbet, criu,
	Andrei Vagin

From: Andrei Vagin <avagin@gmail.com>

Required for a new PAGEMAP_SCAN test to verify guard region reporting.

Signed-off-by: Andrei Vagin <avagin@gmail.com>
---
 tools/include/uapi/linux/fs.h | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/tools/include/uapi/linux/fs.h b/tools/include/uapi/linux/fs.h
index 8a27bc5c7a7f..24ddf7bc4f25 100644
--- a/tools/include/uapi/linux/fs.h
+++ b/tools/include/uapi/linux/fs.h
@@ -40,6 +40,15 @@
 #define BLOCK_SIZE_BITS 10
 #define BLOCK_SIZE (1<<BLOCK_SIZE_BITS)
 
+/* flags for integrity meta */
+#define IO_INTEGRITY_CHK_GUARD		(1U << 0) /* enforce guard check */
+#define IO_INTEGRITY_CHK_REFTAG		(1U << 1) /* enforce ref check */
+#define IO_INTEGRITY_CHK_APPTAG		(1U << 2) /* enforce app check */
+
+#define IO_INTEGRITY_VALID_FLAGS (IO_INTEGRITY_CHK_GUARD | \
+				  IO_INTEGRITY_CHK_REFTAG | \
+				  IO_INTEGRITY_CHK_APPTAG)
+
 #define SEEK_SET	0	/* seek relative to beginning of file */
 #define SEEK_CUR	1	/* seek relative to current file position */
 #define SEEK_END	2	/* seek relative to end of file */
@@ -329,9 +338,16 @@ typedef int __bitwise __kernel_rwf_t;
 /* per-IO negation of O_APPEND */
 #define RWF_NOAPPEND	((__force __kernel_rwf_t)0x00000020)
 
+/* Atomic Write */
+#define RWF_ATOMIC	((__force __kernel_rwf_t)0x00000040)
+
+/* buffered IO that drops the cache after reading or writing data */
+#define RWF_DONTCACHE	((__force __kernel_rwf_t)0x00000080)
+
 /* mask of flags supported by the kernel */
 #define RWF_SUPPORTED	(RWF_HIPRI | RWF_DSYNC | RWF_SYNC | RWF_NOWAIT |\
-			 RWF_APPEND | RWF_NOAPPEND)
+			 RWF_APPEND | RWF_NOAPPEND | RWF_ATOMIC |\
+			 RWF_DONTCACHE)
 
 #define PROCFS_IOCTL_MAGIC 'f'
 
@@ -347,6 +363,7 @@ typedef int __bitwise __kernel_rwf_t;
 #define PAGE_IS_PFNZERO		(1 << 5)
 #define PAGE_IS_HUGE		(1 << 6)
 #define PAGE_IS_SOFT_DIRTY	(1 << 7)
+#define PAGE_IS_GUARD		(1 << 8)
 
 /*
  * struct page_region - Page region with flags
-- 
2.49.0.395.g12beb8f557-goog



^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 3/3] selftests/mm: add PAGEMAP_SCAN guard region test
  2025-03-24  6:53 [PATCH 0/3 v2] fs/proc: extend the PAGEMAP_SCAN ioctl to report guard regions Andrei Vagin
  2025-03-24  6:53 ` [PATCH 1/3] " Andrei Vagin
  2025-03-24  6:53 ` [PATCH 2/3] tools headers UAPI: Sync linux/fs.h with the kernel sources Andrei Vagin
@ 2025-03-24  6:53 ` Andrei Vagin
  2025-03-31 11:27   ` Lorenzo Stoakes
  2025-03-31 11:26 ` [PATCH 0/3 v2] fs/proc: extend the PAGEMAP_SCAN ioctl to report guard regions Lorenzo Stoakes
  3 siblings, 1 reply; 8+ messages in thread
From: Andrei Vagin @ 2025-03-24  6:53 UTC (permalink / raw)
  To: Lorenzo Stoakes, Andrew Morton
  Cc: linux-kernel, linux-mm, linux-fsdevel, linux-doc,
	David Hildenbrand, Shuah Khan, Jonathan Corbet, criu,
	Andrei Vagin

From: Andrei Vagin <avagin@gmail.com>

Add a selftest to verify the PAGEMAP_SCAN ioctl correctly reports guard
regions using the newly introduced PAGE_IS_GUARD flag.

Signed-off-by: Andrei Vagin <avagin@gmail.com>
---
 tools/testing/selftests/mm/guard-regions.c | 57 ++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/tools/testing/selftests/mm/guard-regions.c b/tools/testing/selftests/mm/guard-regions.c
index 0c7183e8b661..c99f3da8bfb7 100644
--- a/tools/testing/selftests/mm/guard-regions.c
+++ b/tools/testing/selftests/mm/guard-regions.c
@@ -8,6 +8,7 @@
 #include <fcntl.h>
 #include <linux/limits.h>
 #include <linux/userfaultfd.h>
+#include <linux/fs.h>
 #include <setjmp.h>
 #include <signal.h>
 #include <stdbool.h>
@@ -2079,4 +2080,60 @@ TEST_F(guard_regions, pagemap)
 	ASSERT_EQ(munmap(ptr, 10 * page_size), 0);
 }
 
+/*
+ * Assert that PAGEMAP_SCAN correctly reports guard region ranges.
+ */
+TEST_F(guard_regions, pagemap_scan)
+{
+	const unsigned long page_size = self->page_size;
+	struct page_region pm_regs[10];
+	struct pm_scan_arg pm_scan_args = {
+		.size = sizeof(struct pm_scan_arg),
+		.category_anyof_mask = PAGE_IS_GUARD,
+		.return_mask = PAGE_IS_GUARD,
+		.vec = (long)&pm_regs,
+		.vec_len = ARRAY_SIZE(pm_regs),
+	};
+	int proc_fd, i;
+	char *ptr;
+
+	proc_fd = open("/proc/self/pagemap", O_RDONLY);
+	ASSERT_NE(proc_fd, -1);
+
+	ptr = mmap_(self, variant, NULL, 10 * page_size,
+		    PROT_READ | PROT_WRITE, 0, 0);
+	ASSERT_NE(ptr, MAP_FAILED);
+
+	pm_scan_args.start = (long)ptr;
+	pm_scan_args.end = (long)ptr + 10 * page_size;
+	ASSERT_EQ(ioctl(proc_fd, PAGEMAP_SCAN, &pm_scan_args), 0);
+	ASSERT_EQ(pm_scan_args.walk_end, (long)ptr + 10 * page_size);
+
+	/* Install a guard region in every other page. */
+	for (i = 0; i < 10; i += 2) {
+		char *ptr_p = &ptr[i * page_size];
+
+		ASSERT_EQ(syscall(__NR_madvise, ptr_p, page_size, MADV_GUARD_INSTALL), 0);
+	}
+
+	/*
+	 * Assert ioctl() returns the count of located regions, where each
+	 * region spans every other page within the range of 10 pages.
+	 */
+	ASSERT_EQ(ioctl(proc_fd, PAGEMAP_SCAN, &pm_scan_args), 5);
+	ASSERT_EQ(pm_scan_args.walk_end, (long)ptr + 10 * page_size);
+
+	/* Re-read from pagemap, and assert guard regions are detected. */
+	for (i = 0; i < 5; i++) {
+		long ptr_p = (long)&ptr[2 * i * page_size];
+
+		ASSERT_EQ(pm_regs[i].start, ptr_p);
+		ASSERT_EQ(pm_regs[i].end, ptr_p + page_size);
+		ASSERT_EQ(pm_regs[i].categories, PAGE_IS_GUARD);
+	}
+
+	ASSERT_EQ(close(proc_fd), 0);
+	ASSERT_EQ(munmap(ptr, 10 * page_size), 0);
+}
+
 TEST_HARNESS_MAIN
-- 
2.49.0.395.g12beb8f557-goog



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 0/3 v2] fs/proc: extend the PAGEMAP_SCAN ioctl to report guard regions
  2025-03-24  6:53 [PATCH 0/3 v2] fs/proc: extend the PAGEMAP_SCAN ioctl to report guard regions Andrei Vagin
                   ` (2 preceding siblings ...)
  2025-03-24  6:53 ` [PATCH 3/3] selftests/mm: add PAGEMAP_SCAN guard region test Andrei Vagin
@ 2025-03-31 11:26 ` Lorenzo Stoakes
  2025-03-31 16:12   ` Andrei Vagin
  3 siblings, 1 reply; 8+ messages in thread
From: Lorenzo Stoakes @ 2025-03-31 11:26 UTC (permalink / raw)
  To: Andrei Vagin
  Cc: Andrew Morton, linux-kernel, linux-mm, linux-fsdevel, linux-doc,
	David Hildenbrand, Shuah Khan, Jonathan Corbet, criu

On Mon, Mar 24, 2025 at 06:53:25AM +0000, Andrei Vagin wrote:
> Introduce the PAGE_IS_GUARD flag in the PAGEMAP_SCAN ioctl to expose
> information about guard regions. This allows userspace tools, such as
> CRIU, to detect and handle guard regions.
>
> Currently, CRIU utilizes PAGEMAP_SCAN as a more efficient alternative to
> parsing /proc/pid/pagemap. Without this change, guard regions are
> incorrectly reported as swap-anon regions, leading CRIU to attempt
> dumping them and subsequently failing.
>
> This series should be applied on top of "[PATCH 0/2] fs/proc/task_mmu:
> add guard region bit to pagemap":
> https://lore.kernel.org/all/2025031926-engraved-footer-3e9b@gregkh/T/
>
> The series includes updates to the documentation and selftests to
> reflect the new functionality.
>
> v2:
> - sync linux/fs.h with the kernel sources
> - address comments from Lorenzo and David.

Thanks, sorry for delay, LSF/MM/BPF is why :)
>
> Andrei Vagin (3):
>   fs/proc: extend the PAGEMAP_SCAN ioctl to report guard regions
>   tools headers UAPI: Sync linux/fs.h with the kernel sources
>   selftests/mm: add PAGEMAP_SCAN guard region test
>
>  Documentation/admin-guide/mm/pagemap.rst   |  1 +
>  fs/proc/task_mmu.c                         | 17 ++++---
>  include/uapi/linux/fs.h                    |  1 +
>  tools/include/uapi/linux/fs.h              | 19 +++++++-
>  tools/testing/selftests/mm/guard-regions.c | 57 ++++++++++++++++++++++
>  5 files changed, 87 insertions(+), 8 deletions(-)
>
> --
> 2.49.0.rc1.451.g8f38331e32-goog
>


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/3] tools headers UAPI: Sync linux/fs.h with the kernel sources
  2025-03-24  6:53 ` [PATCH 2/3] tools headers UAPI: Sync linux/fs.h with the kernel sources Andrei Vagin
@ 2025-03-31 11:27   ` Lorenzo Stoakes
  0 siblings, 0 replies; 8+ messages in thread
From: Lorenzo Stoakes @ 2025-03-31 11:27 UTC (permalink / raw)
  To: Andrei Vagin
  Cc: Andrew Morton, linux-kernel, linux-mm, linux-fsdevel, linux-doc,
	David Hildenbrand, Shuah Khan, Jonathan Corbet, criu,
	Andrei Vagin

On Mon, Mar 24, 2025 at 06:53:27AM +0000, Andrei Vagin wrote:
> From: Andrei Vagin <avagin@gmail.com>
>
> Required for a new PAGEMAP_SCAN test to verify guard region reporting.
>
> Signed-off-by: Andrei Vagin <avagin@gmail.com>

Reviewed-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>

> ---
>  tools/include/uapi/linux/fs.h | 19 ++++++++++++++++++-
>  1 file changed, 18 insertions(+), 1 deletion(-)
>
> diff --git a/tools/include/uapi/linux/fs.h b/tools/include/uapi/linux/fs.h
> index 8a27bc5c7a7f..24ddf7bc4f25 100644
> --- a/tools/include/uapi/linux/fs.h
> +++ b/tools/include/uapi/linux/fs.h
> @@ -40,6 +40,15 @@
>  #define BLOCK_SIZE_BITS 10
>  #define BLOCK_SIZE (1<<BLOCK_SIZE_BITS)
>
> +/* flags for integrity meta */
> +#define IO_INTEGRITY_CHK_GUARD		(1U << 0) /* enforce guard check */
> +#define IO_INTEGRITY_CHK_REFTAG		(1U << 1) /* enforce ref check */
> +#define IO_INTEGRITY_CHK_APPTAG		(1U << 2) /* enforce app check */
> +
> +#define IO_INTEGRITY_VALID_FLAGS (IO_INTEGRITY_CHK_GUARD | \
> +				  IO_INTEGRITY_CHK_REFTAG | \
> +				  IO_INTEGRITY_CHK_APPTAG)
> +
>  #define SEEK_SET	0	/* seek relative to beginning of file */
>  #define SEEK_CUR	1	/* seek relative to current file position */
>  #define SEEK_END	2	/* seek relative to end of file */
> @@ -329,9 +338,16 @@ typedef int __bitwise __kernel_rwf_t;
>  /* per-IO negation of O_APPEND */
>  #define RWF_NOAPPEND	((__force __kernel_rwf_t)0x00000020)
>
> +/* Atomic Write */
> +#define RWF_ATOMIC	((__force __kernel_rwf_t)0x00000040)
> +
> +/* buffered IO that drops the cache after reading or writing data */
> +#define RWF_DONTCACHE	((__force __kernel_rwf_t)0x00000080)
> +
>  /* mask of flags supported by the kernel */
>  #define RWF_SUPPORTED	(RWF_HIPRI | RWF_DSYNC | RWF_SYNC | RWF_NOWAIT |\
> -			 RWF_APPEND | RWF_NOAPPEND)
> +			 RWF_APPEND | RWF_NOAPPEND | RWF_ATOMIC |\
> +			 RWF_DONTCACHE)
>
>  #define PROCFS_IOCTL_MAGIC 'f'
>
> @@ -347,6 +363,7 @@ typedef int __bitwise __kernel_rwf_t;
>  #define PAGE_IS_PFNZERO		(1 << 5)
>  #define PAGE_IS_HUGE		(1 << 6)
>  #define PAGE_IS_SOFT_DIRTY	(1 << 7)
> +#define PAGE_IS_GUARD		(1 << 8)
>
>  /*
>   * struct page_region - Page region with flags
> --
> 2.49.0.395.g12beb8f557-goog
>


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 3/3] selftests/mm: add PAGEMAP_SCAN guard region test
  2025-03-24  6:53 ` [PATCH 3/3] selftests/mm: add PAGEMAP_SCAN guard region test Andrei Vagin
@ 2025-03-31 11:27   ` Lorenzo Stoakes
  0 siblings, 0 replies; 8+ messages in thread
From: Lorenzo Stoakes @ 2025-03-31 11:27 UTC (permalink / raw)
  To: Andrei Vagin
  Cc: Andrew Morton, linux-kernel, linux-mm, linux-fsdevel, linux-doc,
	David Hildenbrand, Shuah Khan, Jonathan Corbet, criu,
	Andrei Vagin

On Mon, Mar 24, 2025 at 06:53:28AM +0000, Andrei Vagin wrote:
> From: Andrei Vagin <avagin@gmail.com>
>
> Add a selftest to verify the PAGEMAP_SCAN ioctl correctly reports guard
> regions using the newly introduced PAGE_IS_GUARD flag.
>
> Signed-off-by: Andrei Vagin <avagin@gmail.com>

Reviewed-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>

> ---
>  tools/testing/selftests/mm/guard-regions.c | 57 ++++++++++++++++++++++
>  1 file changed, 57 insertions(+)
>
> diff --git a/tools/testing/selftests/mm/guard-regions.c b/tools/testing/selftests/mm/guard-regions.c
> index 0c7183e8b661..c99f3da8bfb7 100644
> --- a/tools/testing/selftests/mm/guard-regions.c
> +++ b/tools/testing/selftests/mm/guard-regions.c
> @@ -8,6 +8,7 @@
>  #include <fcntl.h>
>  #include <linux/limits.h>
>  #include <linux/userfaultfd.h>
> +#include <linux/fs.h>
>  #include <setjmp.h>
>  #include <signal.h>
>  #include <stdbool.h>
> @@ -2079,4 +2080,60 @@ TEST_F(guard_regions, pagemap)
>  	ASSERT_EQ(munmap(ptr, 10 * page_size), 0);
>  }
>
> +/*
> + * Assert that PAGEMAP_SCAN correctly reports guard region ranges.
> + */
> +TEST_F(guard_regions, pagemap_scan)
> +{
> +	const unsigned long page_size = self->page_size;
> +	struct page_region pm_regs[10];
> +	struct pm_scan_arg pm_scan_args = {
> +		.size = sizeof(struct pm_scan_arg),
> +		.category_anyof_mask = PAGE_IS_GUARD,
> +		.return_mask = PAGE_IS_GUARD,
> +		.vec = (long)&pm_regs,
> +		.vec_len = ARRAY_SIZE(pm_regs),
> +	};
> +	int proc_fd, i;
> +	char *ptr;
> +
> +	proc_fd = open("/proc/self/pagemap", O_RDONLY);
> +	ASSERT_NE(proc_fd, -1);
> +
> +	ptr = mmap_(self, variant, NULL, 10 * page_size,
> +		    PROT_READ | PROT_WRITE, 0, 0);
> +	ASSERT_NE(ptr, MAP_FAILED);
> +
> +	pm_scan_args.start = (long)ptr;
> +	pm_scan_args.end = (long)ptr + 10 * page_size;
> +	ASSERT_EQ(ioctl(proc_fd, PAGEMAP_SCAN, &pm_scan_args), 0);
> +	ASSERT_EQ(pm_scan_args.walk_end, (long)ptr + 10 * page_size);
> +
> +	/* Install a guard region in every other page. */
> +	for (i = 0; i < 10; i += 2) {
> +		char *ptr_p = &ptr[i * page_size];
> +
> +		ASSERT_EQ(syscall(__NR_madvise, ptr_p, page_size, MADV_GUARD_INSTALL), 0);
> +	}
> +
> +	/*
> +	 * Assert ioctl() returns the count of located regions, where each
> +	 * region spans every other page within the range of 10 pages.
> +	 */
> +	ASSERT_EQ(ioctl(proc_fd, PAGEMAP_SCAN, &pm_scan_args), 5);
> +	ASSERT_EQ(pm_scan_args.walk_end, (long)ptr + 10 * page_size);
> +
> +	/* Re-read from pagemap, and assert guard regions are detected. */
> +	for (i = 0; i < 5; i++) {
> +		long ptr_p = (long)&ptr[2 * i * page_size];
> +
> +		ASSERT_EQ(pm_regs[i].start, ptr_p);
> +		ASSERT_EQ(pm_regs[i].end, ptr_p + page_size);
> +		ASSERT_EQ(pm_regs[i].categories, PAGE_IS_GUARD);
> +	}
> +
> +	ASSERT_EQ(close(proc_fd), 0);
> +	ASSERT_EQ(munmap(ptr, 10 * page_size), 0);
> +}
> +
>  TEST_HARNESS_MAIN
> --
> 2.49.0.395.g12beb8f557-goog
>


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 0/3 v2] fs/proc: extend the PAGEMAP_SCAN ioctl to report guard regions
  2025-03-31 11:26 ` [PATCH 0/3 v2] fs/proc: extend the PAGEMAP_SCAN ioctl to report guard regions Lorenzo Stoakes
@ 2025-03-31 16:12   ` Andrei Vagin
  0 siblings, 0 replies; 8+ messages in thread
From: Andrei Vagin @ 2025-03-31 16:12 UTC (permalink / raw)
  To: Lorenzo Stoakes
  Cc: Andrew Morton, linux-kernel, linux-mm, linux-fsdevel, linux-doc,
	David Hildenbrand, Shuah Khan, Jonathan Corbet, criu

On Mon, Mar 31, 2025 at 4:26 AM Lorenzo Stoakes
<lorenzo.stoakes@oracle.com> wrote:
>
> On Mon, Mar 24, 2025 at 06:53:25AM +0000, Andrei Vagin wrote:
> > Introduce the PAGE_IS_GUARD flag in the PAGEMAP_SCAN ioctl to expose
> > information about guard regions. This allows userspace tools, such as
> > CRIU, to detect and handle guard regions.
> >
> > Currently, CRIU utilizes PAGEMAP_SCAN as a more efficient alternative to
> > parsing /proc/pid/pagemap. Without this change, guard regions are
> > incorrectly reported as swap-anon regions, leading CRIU to attempt
> > dumping them and subsequently failing.
> >
> > This series should be applied on top of "[PATCH 0/2] fs/proc/task_mmu:
> > add guard region bit to pagemap":
> > https://lore.kernel.org/all/2025031926-engraved-footer-3e9b@gregkh/T/
> >
> > The series includes updates to the documentation and selftests to
> > reflect the new functionality.
> >
> > v2:
> > - sync linux/fs.h with the kernel sources
> > - address comments from Lorenzo and David.
>
> Thanks, sorry for delay, LSF/MM/BPF is why :)

Yep, I know. I hope it was productive. You mentioned in another thread that
you are going to handle compatibility for the older kernel. Let me know if I can
help with anything.

Thanks for your cooperation.


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2025-03-31 16:16 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-03-24  6:53 [PATCH 0/3 v2] fs/proc: extend the PAGEMAP_SCAN ioctl to report guard regions Andrei Vagin
2025-03-24  6:53 ` [PATCH 1/3] " Andrei Vagin
2025-03-24  6:53 ` [PATCH 2/3] tools headers UAPI: Sync linux/fs.h with the kernel sources Andrei Vagin
2025-03-31 11:27   ` Lorenzo Stoakes
2025-03-24  6:53 ` [PATCH 3/3] selftests/mm: add PAGEMAP_SCAN guard region test Andrei Vagin
2025-03-31 11:27   ` Lorenzo Stoakes
2025-03-31 11:26 ` [PATCH 0/3 v2] fs/proc: extend the PAGEMAP_SCAN ioctl to report guard regions Lorenzo Stoakes
2025-03-31 16:12   ` Andrei Vagin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox