// SPDX-License-Identifier: GPL-2.0
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <fcntl.h>
#include <stdint.h>
#include <malloc.h>
#include <sys/mman.h>
#include "../kselftest.h"
#include "vm_util.h"

#define PAGEMAP_FILE_PATH "/proc/self/pagemap"
#define TEST_ITERATIONS 10000

static void test_simple(int pagemap_fd, int pagesize)
{
	int i;
	char *map;

	map = aligned_alloc(pagesize, pagesize);
	if (!map)
		ksft_exit_fail_msg("mmap failed\n");

	clear_softdirty();

	for (i = 0 ; i < TEST_ITERATIONS; i++) {
		if (pagemap_is_softdirty(pagemap_fd, map) == 1) {
			ksft_print_msg("dirty bit was 1, but should be 0 (i=%d)\n", i);
			break;
		}

		clear_softdirty();
		// Write something to the page to get the dirty bit enabled on the page
		map[0]++;

		if (pagemap_is_softdirty(pagemap_fd, map) == 0) {
			ksft_print_msg("dirty bit was 0, but should be 1 (i=%d)\n", i);
			break;
		}

		clear_softdirty();
	}
	free(map);

	ksft_test_result(i == TEST_ITERATIONS, "Test %s\n", __func__);
}

static void test_vma_reuse(int pagemap_fd, int pagesize)
{
	char *map, *map2;

	map = mmap(NULL, pagesize, (PROT_READ | PROT_WRITE), (MAP_PRIVATE | MAP_ANON), -1, 0);
	if (map == MAP_FAILED)
		ksft_exit_fail_msg("mmap failed");

	// The kernel always marks new regions as soft dirty
	ksft_test_result(pagemap_is_softdirty(pagemap_fd, map) == 1,
			 "Test %s dirty bit of allocated page\n", __func__);

	clear_softdirty();
	munmap(map, pagesize);

	map2 = mmap(NULL, pagesize, (PROT_READ | PROT_WRITE), (MAP_PRIVATE | MAP_ANON), -1, 0);
	if (map2 == MAP_FAILED)
		ksft_exit_fail_msg("mmap failed");

	// Dirty bit is set for new regions even if they are reused
	if (map == map2)
		ksft_test_result(pagemap_is_softdirty(pagemap_fd, map2) == 1,
				 "Test %s dirty bit of reused address page\n", __func__);
	else
		ksft_test_result_skip("Test %s dirty bit of reused address page\n", __func__);

	munmap(map2, pagesize);
}

static void test_hugepage(int pagemap_fd, int pagesize)
{
	char *map;
	int i, ret;
	size_t hpage_len = read_pmd_pagesize();

	if (!hpage_len)
		ksft_exit_fail_msg("Reading PMD pagesize failed");

	map = memalign(hpage_len, hpage_len);
	if (!map)
		ksft_exit_fail_msg("memalign failed\n");

	ret = madvise(map, hpage_len, MADV_HUGEPAGE);
	if (ret)
		ksft_exit_fail_msg("madvise failed %d\n", ret);

	for (i = 0; i < hpage_len; i++)
		map[i] = (char)i;

	if (check_huge_anon(map, 1, hpage_len)) {
		ksft_test_result_pass("Test %s huge page allocation\n", __func__);

		clear_softdirty();
		for (i = 0 ; i < TEST_ITERATIONS ; i++) {
			if (pagemap_is_softdirty(pagemap_fd, map) == 1) {
				ksft_print_msg("dirty bit was 1, but should be 0 (i=%d)\n", i);
				break;
			}

			clear_softdirty();
			// Write something to the page to get the dirty bit enabled on the page
			map[0]++;

			if (pagemap_is_softdirty(pagemap_fd, map) == 0) {
				ksft_print_msg("dirty bit was 0, but should be 1 (i=%d)\n", i);
				break;
			}
			clear_softdirty();
		}

		ksft_test_result(i == TEST_ITERATIONS, "Test %s huge page dirty bit\n", __func__);
	} else {
		// hugepage allocation failed. skip these tests
		ksft_test_result_skip("Test %s huge page allocation\n", __func__);
		ksft_test_result_skip("Test %s huge page dirty bit\n", __func__);
	}
	free(map);
}

static void test_mprotect(int pagemap_fd, int pagesize, bool anon)
{
	const char *type[] = {"file", "anon"};
	const char *fname = "./soft-dirty-test-file";
	int test_fd;
	char *map;

	if (anon) {
		map = mmap(NULL, pagesize, PROT_READ|PROT_WRITE,
			   MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
		if (!map)
			ksft_exit_fail_msg("anon mmap failed\n");
	} else {
		test_fd = open(fname, O_RDWR | O_CREAT, 0664);
		if (test_fd < 0) {
			ksft_test_result_skip("Test %s open() file failed\n", __func__);
			return;
		}
		unlink(fname);
		ftruncate(test_fd, pagesize);
		map = mmap(NULL, pagesize, PROT_READ|PROT_WRITE,
			   MAP_SHARED, test_fd, 0);
		if (!map)
			ksft_exit_fail_msg("file mmap failed\n");
	}

	*map = 1;
	ksft_test_result(pagemap_is_softdirty(pagemap_fd, map) == 1,
			 "Test %s-%s dirty bit of new written page\n",
			 __func__, type[anon]);
	clear_softdirty();
	ksft_test_result(pagemap_is_softdirty(pagemap_fd, map) == 0,
			 "Test %s-%s soft-dirty clear after clear_refs\n",
			 __func__, type[anon]);
	mprotect(map, pagesize, PROT_READ);
	ksft_test_result(pagemap_is_softdirty(pagemap_fd, map) == 0,
			 "Test %s-%s soft-dirty clear after marking RO\n",
			 __func__, type[anon]);
	mprotect(map, pagesize, PROT_READ|PROT_WRITE);
	ksft_test_result(pagemap_is_softdirty(pagemap_fd, map) == 0,
			 "Test %s-%s soft-dirty clear after marking RW\n",
			 __func__, type[anon]);
	*map = 2;
	ksft_test_result(pagemap_is_softdirty(pagemap_fd, map) == 1,
			 "Test %s-%s soft-dirty after rewritten\n",
			 __func__, type[anon]);

	munmap(map, pagesize);

	if (!anon)
		close(test_fd);
}

static void test_mprotect_anon(int pagemap_fd, int pagesize)
{
	test_mprotect(pagemap_fd, pagesize, true);
}

static void test_mprotect_file(int pagemap_fd, int pagesize)
{
	test_mprotect(pagemap_fd, pagesize, false);
}

int main(int argc, char **argv)
{
	int pagemap_fd;
	int pagesize;

	ksft_print_header();
	ksft_set_plan(15);

	pagemap_fd = open(PAGEMAP_FILE_PATH, O_RDONLY);
	if (pagemap_fd < 0)
		ksft_exit_fail_msg("Failed to open %s\n", PAGEMAP_FILE_PATH);

	pagesize = getpagesize();

	test_simple(pagemap_fd, pagesize);
	test_vma_reuse(pagemap_fd, pagesize);
	test_hugepage(pagemap_fd, pagesize);
	test_mprotect_anon(pagemap_fd, pagesize);
	test_mprotect_file(pagemap_fd, pagesize);

	close(pagemap_fd);

	ksft_finished();
}
