// SPDX-License-Identifier: GPL-2.0
/*
 * hugepage-mremap:
 *
 * Example of remapping huge page memory in a user application using the
 * mremap system call.  The path to a file in a hugetlbfs filesystem must
 * be passed as the last argument to this test.  The amount of memory used
 * by this test in MBs can optionally be passed as an argument.  If no memory
 * amount is passed, the default amount is 10MB.
 *
 * To make sure the test triggers pmd sharing and goes through the 'unshare'
 * path in the mremap code use 1GB (1024) or more.
 */

#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
#include <errno.h>
#include <fcntl.h> /* Definition of O_* constants */
#include <sys/syscall.h> /* Definition of SYS_* constants */
#include <linux/userfaultfd.h>
#include <sys/ioctl.h>

#define DEFAULT_LENGTH_MB 10UL
#define MB_TO_BYTES(x) (x * 1024 * 1024)

#define PROTECTION (PROT_READ | PROT_WRITE | PROT_EXEC)
#define FLAGS (MAP_SHARED | MAP_ANONYMOUS)

static void check_bytes(char *addr)
{
	printf("First hex is %x\n", *((unsigned int *)addr));
}

static void write_bytes(char *addr, size_t len)
{
	unsigned long i;

	for (i = 0; i < len; i++)
		*(addr + i) = (char)i;
}

static int read_bytes(char *addr, size_t len)
{
	unsigned long i;

	check_bytes(addr);
	for (i = 0; i < len; i++)
		if (*(addr + i) != (char)i) {
			printf("Mismatch at %lu\n", i);
			return 1;
		}
	return 0;
}

static void register_region_with_uffd(char *addr, size_t len)
{
	long uffd; /* userfaultfd file descriptor */
	struct uffdio_api uffdio_api;
	struct uffdio_register uffdio_register;

	/* Create and enable userfaultfd object. */

	uffd = syscall(__NR_userfaultfd, O_CLOEXEC | O_NONBLOCK);
	if (uffd == -1) {
		perror("userfaultfd");
		exit(1);
	}

	uffdio_api.api = UFFD_API;
	uffdio_api.features = 0;
	if (ioctl(uffd, UFFDIO_API, &uffdio_api) == -1) {
		perror("ioctl-UFFDIO_API");
		exit(1);
	}

	/* Create a private anonymous mapping. The memory will be
	 * demand-zero paged--that is, not yet allocated. When we
	 * actually touch the memory, it will be allocated via
	 * the userfaultfd.
	 */

	addr = mmap(NULL, len, PROT_READ | PROT_WRITE,
		    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
	if (addr == MAP_FAILED) {
		perror("mmap");
		exit(1);
	}

	printf("Address returned by mmap() = %p\n", addr);

	/* Register the memory range of the mapping we just created for
	 * handling by the userfaultfd object. In mode, we request to track
	 * missing pages (i.e., pages that have not yet been faulted in).
	 */

	uffdio_register.range.start = (unsigned long)addr;
	uffdio_register.range.len = len;
	uffdio_register.mode = UFFDIO_REGISTER_MODE_MISSING;
	if (ioctl(uffd, UFFDIO_REGISTER, &uffdio_register) == -1) {
		perror("ioctl-UFFDIO_REGISTER");
		exit(1);
	}
}

int main(int argc, char *argv[])
{
	size_t length = 0;

	if (argc != 2 && argc != 3) {
		printf("Usage: %s [length_in_MB] <hugetlb_file>\n", argv[0]);
		exit(1);
	}

	/* Read memory length as the first arg if valid, otherwise fallback to
	 * the default length.
	 */
	if (argc == 3)
		length = argc > 2 ? (size_t)atoi(argv[1]) : 0UL;

	length = length > 0 ? length : DEFAULT_LENGTH_MB;
	length = MB_TO_BYTES(length);

	int ret = 0;

	/* last arg is the hugetlb file name */
	int fd = open(argv[argc-1], O_CREAT | O_RDWR, 0755);

	if (fd < 0) {
		perror("Open failed");
		exit(1);
	}

	/* mmap to a PUD aligned address to hopefully trigger pmd sharing. */
	unsigned long suggested_addr = 0x7eaa40000000;
	void *haddr = mmap((void *)suggested_addr, length, PROTECTION,
			   MAP_HUGETLB | MAP_SHARED | MAP_POPULATE, fd, 0);
	printf("Map haddr: Returned address is %p\n", haddr);
	if (haddr == MAP_FAILED) {
		perror("mmap1");
		exit(1);
	}

	/* mmap again to a dummy address to hopefully trigger pmd sharing. */
	suggested_addr = 0x7daa40000000;
	void *daddr = mmap((void *)suggested_addr, length, PROTECTION,
			   MAP_HUGETLB | MAP_SHARED | MAP_POPULATE, fd, 0);
	printf("Map daddr: Returned address is %p\n", daddr);
	if (daddr == MAP_FAILED) {
		perror("mmap3");
		exit(1);
	}

	suggested_addr = 0x7faa40000000;
	void *vaddr =
		mmap((void *)suggested_addr, length, PROTECTION, FLAGS, -1, 0);
	printf("Map vaddr: Returned address is %p\n", vaddr);
	if (vaddr == MAP_FAILED) {
		perror("mmap2");
		exit(1);
	}

	register_region_with_uffd(haddr, length);

	void *addr = mremap(haddr, length, length,
			    MREMAP_MAYMOVE | MREMAP_FIXED, vaddr);
	if (addr == MAP_FAILED) {
		perror("mremap");
		exit(1);
	}

	printf("Mremap: Returned address is %p\n", addr);
	check_bytes(addr);
	write_bytes(addr, length);
	ret = read_bytes(addr, length);

	munmap(addr, length);

	addr = mremap(addr, length, length, 0);
	if (addr != MAP_FAILED) {
		printf("mremap: Expected failure, but call succeeded\n");
		exit(1);
	}

	close(fd);
	unlink(argv[argc-1]);

	return ret;
}
