#include <fcntl.h>
 #include <linux/limits.h>
 #include <linux/userfaultfd.h>
+#include <linux/fs.h>
 #include <setjmp.h>
 #include <signal.h>
 #include <stdbool.h>
        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