// SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2020 ARM Limited

#define _GNU_SOURCE

#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ucontext.h>
#include <sys/wait.h>

#include "kselftest.h"
#include "mte_common_util.h"
#include "mte_def.h"

#define BUFFER_SIZE		(5 * MT_GRANULE_SIZE)
#define RUNS			(MT_TAG_COUNT)
#define UNDERFLOW		MT_GRANULE_SIZE
#define OVERFLOW		MT_GRANULE_SIZE

static size_t page_size;
static int sizes[] = {
	1, 537, 989, 1269, MT_GRANULE_SIZE - 1, MT_GRANULE_SIZE,
	/* page size - 1*/ 0, /* page_size */ 0, /* page size + 1 */ 0
};

static int check_child_tag_inheritance(char *ptr, int size, int mode)
{
	int i, parent_tag, child_tag, fault, child_status;
	pid_t child;

	parent_tag = MT_FETCH_TAG((uintptr_t)ptr);
	fault = 0;

	child = fork();
	if (child == -1) {
		ksft_print_msg("FAIL: child process creation\n");
		return KSFT_FAIL;
	} else if (child == 0) {
		mte_initialize_current_context(mode, (uintptr_t)ptr, size);
		/* Do copy on write */
		memset(ptr, '1', size);
		mte_wait_after_trig();
		if (cur_mte_cxt.fault_valid == true) {
			fault = 1;
			goto check_child_tag_inheritance_err;
		}
		for (i = 0 ; i < size ; i += MT_GRANULE_SIZE) {
			child_tag = MT_FETCH_TAG((uintptr_t)(mte_get_tag_address(ptr + i)));
			if (parent_tag != child_tag) {
				ksft_print_msg("FAIL: child mte tag mismatch\n");
				fault = 1;
				goto check_child_tag_inheritance_err;
			}
		}
		mte_initialize_current_context(mode, (uintptr_t)ptr, -UNDERFLOW);
		memset(ptr - UNDERFLOW, '2', UNDERFLOW);
		mte_wait_after_trig();
		if (cur_mte_cxt.fault_valid == false) {
			fault = 1;
			goto check_child_tag_inheritance_err;
		}
		mte_initialize_current_context(mode, (uintptr_t)ptr, size + OVERFLOW);
		memset(ptr + size, '3', OVERFLOW);
		mte_wait_after_trig();
		if (cur_mte_cxt.fault_valid == false) {
			fault = 1;
			goto check_child_tag_inheritance_err;
		}
check_child_tag_inheritance_err:
		_exit(fault);
	}
	/* Wait for child process to terminate */
	wait(&child_status);
	if (WIFEXITED(child_status))
		fault = WEXITSTATUS(child_status);
	else
		fault = 1;
	return (fault) ? KSFT_FAIL : KSFT_PASS;
}

static int check_child_memory_mapping(int mem_type, int mode, int mapping)
{
	char *ptr;
	int run, result;
	int item = sizeof(sizes)/sizeof(int);

	item = sizeof(sizes)/sizeof(int);
	mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG);
	for (run = 0; run < item; run++) {
		ptr = (char *)mte_allocate_memory_tag_range(sizes[run], mem_type, mapping,
							    UNDERFLOW, OVERFLOW);
		if (check_allocated_memory_range(ptr, sizes[run], mem_type,
						 UNDERFLOW, OVERFLOW) != KSFT_PASS)
			return KSFT_FAIL;
		result = check_child_tag_inheritance(ptr, sizes[run], mode);
		mte_free_memory_tag_range((void *)ptr, sizes[run], mem_type, UNDERFLOW, OVERFLOW);
		if (result == KSFT_FAIL)
			return result;
	}
	return KSFT_PASS;
}

static int check_child_file_mapping(int mem_type, int mode, int mapping)
{
	char *ptr, *map_ptr;
	int run, fd, map_size, result = KSFT_PASS;
	int total = sizeof(sizes)/sizeof(int);

	mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG);
	for (run = 0; run < total; run++) {
		fd = create_temp_file();
		if (fd == -1)
			return KSFT_FAIL;

		map_size = sizes[run] + OVERFLOW + UNDERFLOW;
		map_ptr = (char *)mte_allocate_file_memory(map_size, mem_type, mapping, false, fd);
		if (check_allocated_memory(map_ptr, map_size, mem_type, false) != KSFT_PASS) {
			close(fd);
			return KSFT_FAIL;
		}
		ptr = map_ptr + UNDERFLOW;
		mte_initialize_current_context(mode, (uintptr_t)ptr, sizes[run]);
		/* Only mte enabled memory will allow tag insertion */
		ptr = mte_insert_tags((void *)ptr, sizes[run]);
		if (!ptr || cur_mte_cxt.fault_valid == true) {
			ksft_print_msg("FAIL: Insert tags on file based memory\n");
			munmap((void *)map_ptr, map_size);
			close(fd);
			return KSFT_FAIL;
		}
		result = check_child_tag_inheritance(ptr, sizes[run], mode);
		mte_clear_tags((void *)ptr, sizes[run]);
		munmap((void *)map_ptr, map_size);
		close(fd);
		if (result != KSFT_PASS)
			return KSFT_FAIL;
	}
	return KSFT_PASS;
}

int main(int argc, char *argv[])
{
	int err;
	int item = sizeof(sizes)/sizeof(int);

	page_size = getpagesize();
	if (!page_size) {
		ksft_print_msg("ERR: Unable to get page size\n");
		return KSFT_FAIL;
	}
	sizes[item - 3] = page_size - 1;
	sizes[item - 2] = page_size;
	sizes[item - 1] = page_size + 1;

	err = mte_default_setup();
	if (err)
		return err;

	/* Register SIGSEGV handler */
	mte_register_signal(SIGSEGV, mte_default_handler);
	mte_register_signal(SIGBUS, mte_default_handler);

	/* Set test plan */
	ksft_set_plan(12);

	evaluate_test(check_child_memory_mapping(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE),
		"Check child anonymous memory with private mapping, precise mode and mmap memory\n");
	evaluate_test(check_child_memory_mapping(USE_MMAP, MTE_SYNC_ERR, MAP_SHARED),
		"Check child anonymous memory with shared mapping, precise mode and mmap memory\n");
	evaluate_test(check_child_memory_mapping(USE_MMAP, MTE_ASYNC_ERR, MAP_PRIVATE),
		"Check child anonymous memory with private mapping, imprecise mode and mmap memory\n");
	evaluate_test(check_child_memory_mapping(USE_MMAP, MTE_ASYNC_ERR, MAP_SHARED),
		"Check child anonymous memory with shared mapping, imprecise mode and mmap memory\n");
	evaluate_test(check_child_memory_mapping(USE_MPROTECT, MTE_SYNC_ERR, MAP_PRIVATE),
		"Check child anonymous memory with private mapping, precise mode and mmap/mprotect memory\n");
	evaluate_test(check_child_memory_mapping(USE_MPROTECT, MTE_SYNC_ERR, MAP_SHARED),
		"Check child anonymous memory with shared mapping, precise mode and mmap/mprotect memory\n");

	evaluate_test(check_child_file_mapping(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE),
		"Check child file memory with private mapping, precise mode and mmap memory\n");
	evaluate_test(check_child_file_mapping(USE_MMAP, MTE_SYNC_ERR, MAP_SHARED),
		"Check child file memory with shared mapping, precise mode and mmap memory\n");
	evaluate_test(check_child_memory_mapping(USE_MMAP, MTE_ASYNC_ERR, MAP_PRIVATE),
		"Check child file memory with private mapping, imprecise mode and mmap memory\n");
	evaluate_test(check_child_memory_mapping(USE_MMAP, MTE_ASYNC_ERR, MAP_SHARED),
		"Check child file memory with shared mapping, imprecise mode and mmap memory\n");
	evaluate_test(check_child_memory_mapping(USE_MPROTECT, MTE_SYNC_ERR, MAP_PRIVATE),
		"Check child file memory with private mapping, precise mode and mmap/mprotect memory\n");
	evaluate_test(check_child_memory_mapping(USE_MPROTECT, MTE_SYNC_ERR, MAP_SHARED),
		"Check child file memory with shared mapping, precise mode and mmap/mprotect memory\n");

	mte_restore_setup();
	ksft_print_cnts();
	return ksft_get_fail_cnt() == 0 ? KSFT_PASS : KSFT_FAIL;
}
