// SPDX-License-Identifier: GPL-2.0

/*
 * Test that MAP_FIXED_NOREPLACE works.
 *
 * Copyright 2018, Jann Horn <jannh@google.com>
 * Copyright 2018, Michael Ellerman, IBM Corporation.
 */

#include <sys/mman.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "../kselftest.h"

static void dump_maps(void)
{
	char cmd[32];

	snprintf(cmd, sizeof(cmd), "cat /proc/%d/maps", getpid());
	system(cmd);
}

static unsigned long find_base_addr(unsigned long size)
{
	void *addr;
	unsigned long flags;

	flags = MAP_PRIVATE | MAP_ANONYMOUS;
	addr = mmap(NULL, size, PROT_NONE, flags, -1, 0);
	if (addr == MAP_FAILED)
		ksft_exit_fail_msg("Error: couldn't map the space we need for the test\n");

	if (munmap(addr, size) != 0)
		ksft_exit_fail_msg("Error: munmap failed\n");

	return (unsigned long)addr;
}

int main(void)
{
	unsigned long base_addr;
	unsigned long flags, addr, size, page_size;
	char *p;

	ksft_print_header();
	ksft_set_plan(9);

	page_size = sysconf(_SC_PAGE_SIZE);

	/* let's find a base addr that is free before we start the tests */
	size = 5 * page_size;
	base_addr = find_base_addr(size);

	flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED_NOREPLACE;

	/* Check we can map all the areas we need below */
	addr = base_addr;
	size = 5 * page_size;
	p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
	if (p == MAP_FAILED) {
		dump_maps();
		ksft_exit_fail_msg("Error: couldn't map the space we need for the test\n");
	}
	if (munmap((void *)addr, 5 * page_size) != 0) {
		dump_maps();
		ksft_exit_fail_msg("Error: munmap failed!?\n");
	}
	ksft_print_msg("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
	ksft_test_result_pass("mmap() 5*PAGE_SIZE at base\n");

	addr = base_addr + page_size;
	size = 3 * page_size;
	p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
	if (p == MAP_FAILED) {
		dump_maps();
		ksft_exit_fail_msg("Error: first mmap() failed unexpectedly\n");
	}
	ksft_print_msg("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
	ksft_test_result_pass("mmap() 3*PAGE_SIZE at base+PAGE_SIZE\n");

	/*
	 * Exact same mapping again:
	 *   base |  free  | new
	 *     +1 | mapped | new
	 *     +2 | mapped | new
	 *     +3 | mapped | new
	 *     +4 |  free  | new
	 */
	addr = base_addr;
	size = 5 * page_size;
	p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
	if (p != MAP_FAILED) {
		dump_maps();
		ksft_exit_fail_msg("Error:1: mmap() succeeded when it shouldn't have\n");
	}
	ksft_print_msg("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
	ksft_test_result_pass("mmap() 5*PAGE_SIZE at base\n");

	/*
	 * Second mapping contained within first:
	 *
	 *   base |  free  |
	 *     +1 | mapped |
	 *     +2 | mapped | new
	 *     +3 | mapped |
	 *     +4 |  free  |
	 */
	addr = base_addr + (2 * page_size);
	size = page_size;
	p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
	if (p != MAP_FAILED) {
		dump_maps();
		ksft_exit_fail_msg("Error:2: mmap() succeeded when it shouldn't have\n");
	}
	ksft_print_msg("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
	ksft_test_result_pass("mmap() 2*PAGE_SIZE at base+PAGE_SIZE\n");

	/*
	 * Overlap end of existing mapping:
	 *   base |  free  |
	 *     +1 | mapped |
	 *     +2 | mapped |
	 *     +3 | mapped | new
	 *     +4 |  free  | new
	 */
	addr = base_addr + (3 * page_size);
	size = 2 * page_size;
	p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
	if (p != MAP_FAILED) {
		dump_maps();
		ksft_exit_fail_msg("Error:3: mmap() succeeded when it shouldn't have\n");
	}
	ksft_print_msg("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
	ksft_test_result_pass("mmap() 2*PAGE_SIZE  at base+(3*PAGE_SIZE)\n");

	/*
	 * Overlap start of existing mapping:
	 *   base |  free  | new
	 *     +1 | mapped | new
	 *     +2 | mapped |
	 *     +3 | mapped |
	 *     +4 |  free  |
	 */
	addr = base_addr;
	size = 2 * page_size;
	p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
	if (p != MAP_FAILED) {
		dump_maps();
		ksft_exit_fail_msg("Error:4: mmap() succeeded when it shouldn't have\n");
	}
	ksft_print_msg("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
	ksft_test_result_pass("mmap() 2*PAGE_SIZE bytes at base\n");

	/*
	 * Adjacent to start of existing mapping:
	 *   base |  free  | new
	 *     +1 | mapped |
	 *     +2 | mapped |
	 *     +3 | mapped |
	 *     +4 |  free  |
	 */
	addr = base_addr;
	size = page_size;
	p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
	if (p == MAP_FAILED) {
		dump_maps();
		ksft_exit_fail_msg("Error:5: mmap() failed when it shouldn't have\n");
	}
	ksft_print_msg("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
	ksft_test_result_pass("mmap() PAGE_SIZE at base\n");

	/*
	 * Adjacent to end of existing mapping:
	 *   base |  free  |
	 *     +1 | mapped |
	 *     +2 | mapped |
	 *     +3 | mapped |
	 *     +4 |  free  |  new
	 */
	addr = base_addr + (4 * page_size);
	size = page_size;
	p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
	if (p == MAP_FAILED) {
		dump_maps();
		ksft_exit_fail_msg("Error:6: mmap() failed when it shouldn't have\n");
	}
	ksft_print_msg("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
	ksft_test_result_pass("mmap() PAGE_SIZE at base+(4*PAGE_SIZE)\n");

	addr = base_addr;
	size = 5 * page_size;
	if (munmap((void *)addr, size) != 0) {
		dump_maps();
		ksft_exit_fail_msg("Error: munmap failed!?\n");
	}
	ksft_test_result_pass("Base Address unmap() successful\n");

	ksft_finished();
}
