/*
 * Copyright (C) 2012 Linux Test Project, Inc.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of version 2 of the GNU General Public
 * License as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it would be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * Further, this software is distributed without any warranty that it
 * is free of the rightful claim of any third person regarding
 * infringement or the like.  Any license provided herein, whether
 * implied or otherwise, applies only to this software file.  Patent
 * licenses, if any, provided herein do not apply to combinations of
 * this program with other software, or any other product whatsoever.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 */
/*
 * Test Name: mremap05
 *
 * Test Description:
 *  Verify that MREMAP_FIXED fails without MREMAP_MAYMOVE.
 *  Verify that MREMAP_FIXED|MREMAP_MAYMOVE fails if target address
 *    is not page aligned.
 *  Verify that MREMAP_FIXED|MREMAP_MAYMOVE fails if old range
 *    overlaps with new range.
 *  Verify that MREMAP_FIXED|MREMAP_MAYMOVE can move mapping to new address.
 *  Verify that MREMAP_FIXED|MREMAP_MAYMOVE unmaps previous mapping
 *    at the address range specified by new_address and new_size.
 */

#define _GNU_SOURCE
#include "config.h"
#include <sys/mman.h>
#include <errno.h>
#include <unistd.h>
#include "test.h"

char *TCID = "mremap05";

#ifdef HAVE_MREMAP_FIXED

struct test_case_t {
	char *old_address;
	char *new_address;
	size_t old_size;	/* in pages */
	size_t new_size;	/* in pages */
	int flags;
	const const char *msg;
	void *exp_ret;
	int exp_errno;
	char *ret;
	void (*setup) (struct test_case_t *);
	void (*cleanup) (struct test_case_t *);
};

static void setup(void);
static void cleanup(void);
static void setup0(struct test_case_t *);
static void setup1(struct test_case_t *);
static void setup2(struct test_case_t *);
static void setup3(struct test_case_t *);
static void setup4(struct test_case_t *);
static void cleanup0(struct test_case_t *);
static void cleanup1(struct test_case_t *);

struct test_case_t tdat[] = {
	{
	 .old_size = 1,
	 .new_size = 1,
	 .flags = MREMAP_FIXED,
	 .msg = "MREMAP_FIXED requires MREMAP_MAYMOVE",
	 .exp_ret = MAP_FAILED,
	 .exp_errno = EINVAL,
	 .setup = setup0,
	 .cleanup = cleanup0},
	{
	 .old_size = 1,
	 .new_size = 1,
	 .flags = MREMAP_FIXED | MREMAP_MAYMOVE,
	 .msg = "new_addr has to be page aligned",
	 .exp_ret = MAP_FAILED,
	 .exp_errno = EINVAL,
	 .setup = setup1,
	 .cleanup = cleanup0},
	{
	 .old_size = 2,
	 .new_size = 1,
	 .flags = MREMAP_FIXED | MREMAP_MAYMOVE,
	 .msg = "old/new area must not overlap",
	 .exp_ret = MAP_FAILED,
	 .exp_errno = EINVAL,
	 .setup = setup2,
	 .cleanup = cleanup0},
	{
	 .old_size = 1,
	 .new_size = 1,
	 .flags = MREMAP_FIXED | MREMAP_MAYMOVE,
	 .msg = "mremap #1",
	 .setup = setup3,
	 .cleanup = cleanup0},
	{
	 .old_size = 1,
	 .new_size = 1,
	 .flags = MREMAP_FIXED | MREMAP_MAYMOVE,
	 .msg = "mremap #2",
	 .setup = setup4,
	 .cleanup = cleanup1},
};

static int pagesize;
static int TST_TOTAL = sizeof(tdat) / sizeof(tdat[0]);

static void free_test_area(void *p, int size)
{
	if (munmap(p, size) < 0)
		tst_brkm(TBROK | TERRNO, cleanup, "free_test_area munmap");
}

static void *get_test_area(int size, int free_area)
{
	void *p;
	p = mmap(NULL, size, PROT_READ | PROT_WRITE,
		 MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
	if (p == MAP_FAILED)
		tst_brkm(TBROK | TERRNO, cleanup, "get_test_area mmap");
	if (free_area)
		free_test_area(p, size);
	return p;
}

static void test_mremap(struct test_case_t *t)
{
	t->ret = mremap(t->old_address, t->old_size, t->new_size, t->flags,
			t->new_address);

	if (t->ret == t->exp_ret) {
		if (t->ret != MAP_FAILED) {
			tst_resm(TPASS, "%s", t->msg);
			if (*(t->ret) == 0x1)
				tst_resm(TPASS, "%s value OK", t->msg);
			else
				tst_resm(TPASS, "%s value failed", t->msg);
		} else {
			if (errno == t->exp_errno)
				tst_resm(TPASS, "%s", t->msg);
			else
				tst_resm(TFAIL | TERRNO, "%s", t->msg);
		}
	} else {
		tst_resm(TFAIL, "%s ret: %p, expected: %p", t->msg,
			 t->ret, t->exp_ret);
	}
}

static void setup0(struct test_case_t *t)
{
	t->old_address = get_test_area(t->old_size * pagesize, 0);
	t->new_address = get_test_area(t->new_size * pagesize, 1);
}

static void setup1(struct test_case_t *t)
{
	t->old_address = get_test_area(t->old_size * pagesize, 0);
	t->new_address = get_test_area((t->new_size + 1) * pagesize, 1) + 1;
}

static void setup2(struct test_case_t *t)
{
	t->old_address = get_test_area(t->old_size * pagesize, 0);
	t->new_address = t->old_address;
}

static void setup3(struct test_case_t *t)
{
	t->old_address = get_test_area(t->old_size * pagesize, 0);
	t->new_address = get_test_area(t->new_size * pagesize, 1);
	t->exp_ret = t->new_address;
	*(t->old_address) = 0x1;
}

static void setup4(struct test_case_t *t)
{
	t->old_address = get_test_area(t->old_size * pagesize, 0);
	t->new_address = get_test_area(t->new_size * pagesize, 0);
	t->exp_ret = t->new_address;
	*(t->old_address) = 0x1;
	*(t->new_address) = 0x2;
}

static void cleanup0(struct test_case_t *t)
{
	if (t->ret == MAP_FAILED)
		free_test_area(t->old_address, t->old_size * pagesize);
	else
		free_test_area(t->ret, t->new_size * pagesize);
}

static void cleanup1(struct test_case_t *t)
{
	if (t->ret == MAP_FAILED) {
		free_test_area(t->old_address, t->old_size * pagesize);
		free_test_area(t->new_address, t->new_size * pagesize);
	} else {
		free_test_area(t->ret, t->new_size * pagesize);
	}
}

int main(int ac, char **av)
{
	const char *msg;
	int lc, testno;

	msg = parse_opts(ac, av, NULL, NULL);
	if (msg != NULL)
		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);

	setup();
	for (lc = 0; TEST_LOOPING(lc); lc++) {
		tst_count = 0;
		for (testno = 0; testno < TST_TOTAL; testno++) {
			tdat[testno].setup(&tdat[testno]);
			test_mremap(&tdat[testno]);
			tdat[testno].cleanup(&tdat[testno]);
		}
	}
	cleanup();
	tst_exit();
}

static void setup(void)
{
	pagesize = getpagesize();
}

static void cleanup(void)
{
}

#else

int main(void)
{
	tst_brkm(TCONF, NULL, "MREMAP_FIXED not present in <sys/mman.h>");
}

#endif /* HAVE_MREMAP_FIXED */
