// SPDX-License-Identifier: GPL-2.0
#define _GNU_SOURCE
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <sys/mman.h>
#include <errno.h>
#include <malloc.h>
#include "vm_util.h"
#include "../kselftest.h"
#include <linux/types.h>
#include <linux/memfd.h>
#include <linux/userfaultfd.h>
#include <linux/fs.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <math.h>
#include <asm-generic/unistd.h>
#include <pthread.h>
#include <sys/resource.h>
#include <assert.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define PAGEMAP_BITS_ALL (PAGE_IS_WPALLOWED | PAGE_IS_WRITTEN | \
PAGE_IS_FILE | PAGE_IS_PRESENT | \
PAGE_IS_SWAPPED | PAGE_IS_PFNZERO | \
PAGE_IS_HUGE)
#define PAGEMAP_NON_WRITTEN_BITS (PAGE_IS_WPALLOWED | PAGE_IS_FILE | \
PAGE_IS_PRESENT | PAGE_IS_SWAPPED | \
PAGE_IS_PFNZERO | PAGE_IS_HUGE)
#define TEST_ITERATIONS 100
#define PAGEMAP "/proc/self/pagemap"
int pagemap_fd;
int uffd;
int page_size;
int hpage_size;
const char *progname;
#define LEN(region) ((region.end - region.start)/page_size)
static long pagemap_ioctl(void *start, int len, void *vec, int vec_len, int flag,
int max_pages, long required_mask, long anyof_mask, long excluded_mask,
long return_mask)
{
struct pm_scan_arg arg;
arg.start = (uintptr_t)start;
arg.end = (uintptr_t)(start + len);
arg.vec = (uintptr_t)vec;
arg.vec_len = vec_len;
arg.flags = flag;
arg.size = sizeof(struct pm_scan_arg);
arg.max_pages = max_pages;
arg.category_mask = required_mask;
arg.category_anyof_mask = anyof_mask;
arg.category_inverted = excluded_mask;
arg.return_mask = return_mask;
return ioctl(pagemap_fd, PAGEMAP_SCAN, &arg);
}
static long pagemap_ioc(void *start, int len, void *vec, int vec_len, int flag,
int max_pages, long required_mask, long anyof_mask, long excluded_mask,
long return_mask, long *walk_end)
{
struct pm_scan_arg arg;
int ret;
arg.start = (uintptr_t)start;
arg.end = (uintptr_t)(start + len);
arg.vec = (uintptr_t)vec;
arg.vec_len = vec_len;
arg.flags = flag;
arg.size = sizeof(s
|