/*
 * Copyright IBM Corp.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2.1 of the GNU Lesser 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.
 *
 */

#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/ptrace.h>
#include <sys/syscall.h>
#include <ucontext.h>
#include <unistd.h>

#include "utils.h"

char *file_name;

int in_test;
volatile int faulted;
volatile void *dar;
int errors;

static void segv(int signum, siginfo_t *info, void *ctxt_v)
{
	ucontext_t *ctxt = (ucontext_t *)ctxt_v;
	struct pt_regs *regs = ctxt->uc_mcontext.regs;

	if (!in_test) {
		fprintf(stderr, "Segfault outside of test !\n");
		exit(1);
	}

	faulted = 1;
	dar = (void *)regs->dar;
	regs->nip += 4;
}

static inline void do_read(const volatile void *addr)
{
	int ret;

	asm volatile("lwz %0,0(%1); twi 0,%0,0; isync;\n"
		     : "=r" (ret) : "r" (addr) : "memory");
}

static inline void do_write(const volatile void *addr)
{
	int val = 0x1234567;

	asm volatile("stw %0,0(%1); sync; \n"
		     : : "r" (val), "r" (addr) : "memory");
}

static inline void check_faulted(void *addr, long page, long subpage, int write)
{
	int want_fault = (subpage == ((page + 3) % 16));

	if (write)
		want_fault |= (subpage == ((page + 1) % 16));

	if (faulted != want_fault) {
		printf("Failed at 0x%p (p=%ld,sp=%ld,w=%d), want=%s, got=%s !\n",
		       addr, page, subpage, write,
		       want_fault ? "fault" : "pass",
		       faulted ? "fault" : "pass");
		++errors;
	}

	if (faulted) {
		if (dar != addr) {
			printf("Fault expected at 0x%p and happened at 0x%p !\n",
			       addr, dar);
		}
		faulted = 0;
		asm volatile("sync" : : : "memory");
	}
}

static int run_test(void *addr, unsigned long size)
{
	unsigned int *map;
	long i, j, pages, err;

	pages = size / 0x10000;
	map = malloc(pages * 4);
	assert(map);

	/*
	 * for each page, mark subpage i % 16 read only and subpage
	 * (i + 3) % 16 inaccessible
	 */
	for (i = 0; i < pages; i++) {
		map[i] = (0x40000000 >> (((i + 1) * 2) % 32)) |
			(0xc0000000 >> (((i + 3) * 2) % 32));
	}

	err = syscall(__NR_subpage_prot, addr, size, map);
	if (err) {
		perror("subpage_perm");
		return 1;
	}
	free(map);

	in_test = 1;
	errors = 0;
	for (i = 0; i < pages; i++) {
		for (j = 0; j < 16; j++, addr += 0x1000) {
			do_read(addr);
			check_faulted(addr, i, j, 0);
			do_write(addr);
			check_faulted(addr, i, j, 1);
		}
	}

	in_test = 0;
	if (errors) {
		printf("%d errors detected\n", errors);
		return 1;
	}

	return 0;
}

int test_anon(void)
{
	unsigned long align;
	struct sigaction act = {
		.sa_sigaction = segv,
		.sa_flags = SA_SIGINFO
	};
	void *mallocblock;
	unsigned long mallocsize;

	if (getpagesize() != 0x10000) {
		fprintf(stderr, "Kernel page size must be 64K!\n");
		return 1;
	}

	sigaction(SIGSEGV, &act, NULL);

	mallocsize = 4 * 16 * 1024 * 1024;

	FAIL_IF(posix_memalign(&mallocblock, 64 * 1024, mallocsize));

	align = (unsigned long)mallocblock;
	if (align & 0xffff)
		align = (align | 0xffff) + 1;

	mallocblock = (void *)align;

	printf("allocated malloc block of 0x%lx bytes at 0x%p\n",
	       mallocsize, mallocblock);

	printf("testing malloc block...\n");

	return run_test(mallocblock, mallocsize);
}

int test_file(void)
{
	struct sigaction act = {
		.sa_sigaction = segv,
		.sa_flags = SA_SIGINFO
	};
	void *fileblock;
	off_t filesize;
	int fd;

	fd = open(file_name, O_RDWR);
	if (fd == -1) {
		perror("failed to open file");
		return 1;
	}
	sigaction(SIGSEGV, &act, NULL);

	filesize = lseek(fd, 0, SEEK_END);
	if (filesize & 0xffff)
		filesize &= ~0xfffful;

	fileblock = mmap(NULL, filesize, PROT_READ | PROT_WRITE,
			 MAP_SHARED, fd, 0);
	if (fileblock == MAP_FAILED) {
		perror("failed to map file");
		return 1;
	}
	printf("allocated %s for 0x%lx bytes at 0x%p\n",
	       file_name, filesize, fileblock);

	printf("testing file map...\n");

	return run_test(fileblock, filesize);
}

int main(int argc, char *argv[])
{
	test_harness(test_anon, "subpage_prot_anon");

	if (argc > 1)
		file_name = argv[1];
	else
		file_name = "tempfile";

	test_harness(test_file, "subpage_prot_file");

	return 0;
}
