// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2018 Dmitry Safonov, Arista Networks
 *
 * MAP_POPULATE | MAP_PRIVATE should COW VMA pages.
 */

#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "kselftest.h"

#include "vm_util.h"

#define MMAP_SZ		4096

#define BUG_ON(condition, description)						\
	do {									\
		if (condition)							\
			ksft_exit_fail_msg("[FAIL]\t%s:%d\t%s:%s\n",		\
					   __func__, __LINE__, (description),	\
					   strerror(errno));			\
	} while (0)

#define TESTS_IN_CHILD 2

static void parent_f(int sock, unsigned long *smap, int child)
{
	int status, ret;

	ret = read(sock, &status, sizeof(int));
	BUG_ON(ret <= 0, "read(sock)");

	*smap = 0x22222BAD;
	ret = msync(smap, MMAP_SZ, MS_SYNC);
	BUG_ON(ret, "msync()");

	ret = write(sock, &status, sizeof(int));
	BUG_ON(ret <= 0, "write(sock)");

	waitpid(child, &status, 0);

	/* The ksft macros don't keep counters between processes */
	ksft_cnt.ksft_pass = WEXITSTATUS(status);
	ksft_cnt.ksft_fail = TESTS_IN_CHILD - WEXITSTATUS(status);
}

static int child_f(int sock, unsigned long *smap, int fd)
{
	int ret, buf = 0;

	smap = mmap(0, MMAP_SZ, PROT_READ | PROT_WRITE,
			MAP_PRIVATE | MAP_POPULATE, fd, 0);
	BUG_ON(smap == MAP_FAILED, "mmap()");

	BUG_ON(*smap != 0xdeadbabe, "MAP_PRIVATE | MAP_POPULATE changed file");

	ret = write(sock, &buf, sizeof(int));
	BUG_ON(ret <= 0, "write(sock)");

	ret = read(sock, &buf, sizeof(int));
	BUG_ON(ret <= 0, "read(sock)");

	ksft_test_result(*smap != 0x22222BAD, "MAP_POPULATE COW private page\n");
	ksft_test_result(*smap == 0xdeadbabe, "The mapping state\n");

	/* The ksft macros don't keep counters between processes */
	return ksft_cnt.ksft_pass;
}

int main(int argc, char **argv)
{
	int sock[2], child, ret;
	FILE *ftmp;
	unsigned long *smap;

	ksft_print_header();
	ksft_set_plan(TESTS_IN_CHILD);

	ftmp = tmpfile();
	BUG_ON(!ftmp, "tmpfile()");

	ret = ftruncate(fileno(ftmp), MMAP_SZ);
	if (ret < 0 && errno == ENOENT) {
		skip_test_dodgy_fs("ftruncate()");
	}
	BUG_ON(ret, "ftruncate()");

	smap = mmap(0, MMAP_SZ, PROT_READ | PROT_WRITE,
			MAP_SHARED, fileno(ftmp), 0);
	BUG_ON(smap == MAP_FAILED, "mmap()");

	*smap = 0xdeadbabe;
	/* Probably unnecessary, but let it be. */
	ret = msync(smap, MMAP_SZ, MS_SYNC);
	BUG_ON(ret, "msync()");

	ret = socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sock);
	BUG_ON(ret, "socketpair()");

	child = fork();
	BUG_ON(child == -1, "fork()");

	if (child) {
		ret = close(sock[0]);
		BUG_ON(ret, "close()");

		parent_f(sock[1], smap, child);

		ksft_finished();
	}

	ret = close(sock[1]);
	BUG_ON(ret, "close()");

	return child_f(sock[0], smap, fileno(ftmp));
}
