/*
 * Copyright (c) 2020 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr.h>
#include <ztest.h>
#include <syscall_handler.h>
#include <kernel_internal.h>

#include "test_syscall.h"

/*
 * Stack testing
 */
struct k_thread test_thread;
#define NUM_STACKS	3
#define STEST_STACKSIZE	(512 + CONFIG_TEST_EXTRA_STACKSIZE)
K_THREAD_STACK_DEFINE(user_stack, STEST_STACKSIZE);
K_THREAD_STACK_ARRAY_DEFINE(user_stack_array, NUM_STACKS, STEST_STACKSIZE);
K_KERNEL_STACK_DEFINE(kern_stack, STEST_STACKSIZE);
K_KERNEL_STACK_ARRAY_DEFINE(kern_stack_array, NUM_STACKS, STEST_STACKSIZE);

struct foo {
	int bar;

	K_KERNEL_STACK_MEMBER(stack, STEST_STACKSIZE);
	int baz;
};

__kstackmem struct foo stest_member_stack;

void z_impl_stack_info_get(char **start_addr, size_t *size)
{
	*start_addr = (char *)k_current_get()->stack_info.start;
	*size = k_current_get()->stack_info.size;
}

#ifdef CONFIG_USERSPACE
static inline void z_vrfy_stack_info_get(char **start_addr,
					 size_t *size)
{
	Z_OOPS(Z_SYSCALL_MEMORY_WRITE(start_addr, sizeof(uintptr_t)));
	Z_OOPS(Z_SYSCALL_MEMORY_WRITE(size, sizeof(size_t)));

	z_impl_stack_info_get(start_addr, size);
}
#include <syscalls/stack_info_get_mrsh.c>

int z_impl_check_perms(void *addr, size_t size, int write)
{
	return arch_buffer_validate(addr, size, write);
}

static inline int z_vrfy_check_perms(void *addr, size_t size, int write)
{
	return z_impl_check_perms((void *)addr, size, write);
}
#include <syscalls/check_perms_mrsh.c>
#endif /* CONFIG_USERSPACE */

/* Global data structure with object information, used by
 * stack_buffer_scenarios
 */
ZTEST_BMEM struct scenario_data {
	k_thread_stack_t *stack;

	/* If this was declared with K_THREAD_STACK_DEFINE and not
	 * K_KERNEL_STACK_DEFINE
	 */
	bool is_user;

	/* Stack size stored in kernel object metadata if a user stack */
	size_t metadata_size;

	/* Return value of sizeof(stack) */
	size_t object_size;

	/* Return value of K_{THREAD|KERNEL}_STACK_SIZEOF(stack) */
	size_t reported_size;

	/* Original size argument passed to K_{THREAD|KERNEL}_STACK_DECLARE */
	size_t declared_size;

	/* Whether this stack is part of an array of thread stacks */
	bool is_array;
} scenario_data;

void stack_buffer_scenarios(void)
{
	k_thread_stack_t *stack_obj = scenario_data.stack;
	size_t obj_size = scenario_data.object_size;
	size_t stack_size, unused, carveout, reserved, alignment, adjusted;
	uint8_t val;
	char *stack_start, *stack_ptr, *stack_end, *obj_start, *obj_end;
	char *stack_buf;
	volatile char *pos;
	int ret, expected;
	uintptr_t base = (uintptr_t)stack_obj;
	bool is_usermode;
	long int end_space;

#ifdef CONFIG_USERSPACE
	is_usermode = arch_is_user_context();
#else
	is_usermode = false;
#endif
	/* Dump interesting information */
	stack_info_get(&stack_start, &stack_size);
	printk("   - Thread reports buffer %p size %zu\n", stack_start,
	       stack_size);

#ifdef CONFIG_USERSPACE
	if (scenario_data.is_user) {
		reserved = K_THREAD_STACK_RESERVED;
		stack_buf = Z_THREAD_STACK_BUFFER(stack_obj);
		alignment = Z_THREAD_STACK_OBJ_ALIGN(stack_size);
	} else
#endif
	{
		reserved = K_KERNEL_STACK_RESERVED;
		stack_buf = Z_KERNEL_STACK_BUFFER(stack_obj);
		alignment = Z_KERNEL_STACK_OBJ_ALIGN;
	}

	stack_end = stack_start + stack_size;
	obj_end = (char *)stack_obj + obj_size;
	obj_start = (char *)stack_obj;



	/* Assert that the created stack object, with the reserved data
	 * removed, can hold a thread buffer of STEST_STACKSIZE
	 */
	zassert_true(STEST_STACKSIZE <= (obj_size - reserved),
		      "bad stack size in object");

	/* Check that the stack info in the thread marks a region
	 * completely contained within the stack object
	 */
	zassert_true(stack_end <= obj_end,
		     "stack size in thread struct out of bounds (overflow)");
	zassert_true(stack_start >= obj_start,
		     "stack size in thread struct out of bounds (underflow)");

	/* Check that the base of the stack is aligned properly. */
	zassert_true(base % alignment == 0,
		     "stack base address %p not aligned to %zu",
		     stack_obj, alignment);

	/* Check that the entire stack buffer is read/writable */
	printk("   - check read/write to stack buffer\n");

	/* Address of this stack variable is guaranteed to part of
	 * the active stack, and close to the actual stack pointer.
	 * Some CPUs have hardware stack overflow detection which
	 * faults on memory access within the stack buffer but below
	 * the stack pointer.
	 *
	 * First test does direct read & write starting at the estimated
	 * stack pointer up to the highest addresses in the buffer
	 */
	stack_ptr = &val;
	for (pos = stack_ptr; pos < stack_end; pos++) {
		/* pos is volatile so this doesn't get optimized out */
		val = *pos;
		*pos = val;
	}

#ifdef CONFIG_USERSPACE
	if (is_usermode) {
		/* If we're in user mode, check every byte in the stack buffer
		 * to ensure that the thread has permissions on it.
		 */
		for (pos = stack_start; pos < stack_end; pos++) {
			zassert_false(check_perms((void *)pos, 1, 1),
				      "bad MPU/MMU permission on stack buffer at address %p",
				      pos);
		}

		/* Bounds check the user accessible area, it shouldn't extend
		 * before or after the stack. Because of memory protection HW
		 * alignment constraints, we test the end of the stack object
		 * and not the buffer.
		 */
		zassert_true(check_perms(stack_start - 1, 1, 0),
			     "user mode access to memory %p before start of stack object",
			     obj_start - 1);
		zassert_true(check_perms(stack_end, 1, 0),
			     "user mode access to memory %p past end of stack object",
			     obj_end);
		zassert_true(stack_size <= obj_size - reserved,
			      "bad stack size %zu in thread struct",
			      stack_size);
	}
#endif
	carveout = stack_start - stack_buf;
	printk("   - Carved-out space in buffer: %zu\n", carveout);
	zassert_true(carveout < stack_size,
		     "Suspicious carve-out space reported");
	/* 0 unless this is a stack array */
	end_space = obj_end - stack_end;
	printk("   - Unused objects space: %ld\n", end_space);

	/* For all stacks, when k_thread_create() is called with a stack object,
	 * it is equivalent to pass either the original requested stack size, or
	 * the return value of K_*_STACK_SIZEOF() for that stack object.
	 *
	 * When the stack is actually instantiated, both expand to fill any space
	 * rounded up, except rounding space for array members.
	 */
	if (!scenario_data.is_array) {
		/* These should be exactly the same. We have an equivalence relation:
		 * For some stack declared with:
		 *
		 * K_THREAD_STACK_DEFINE(my_stack, X);
		 * Z_THREAD_STACK_SIZE_ADJUST(X) - K_THREAD_STACK_RESERVED ==
		 * 	K_THREAD_STACK_SIZEOF(my_stack)
		 *
		 * K_KERNEL_STACK_DEFINE(my_kern_stack, Y):
		 * Z_KERNEL_STACK_SIZE_ADJUST(Y) - K_KERNEL_STACK_RESERVED ==
		 *	K_KERNEL_STACK_SIZEOF(my_stack)
		 */
#ifdef CONFIG_USERSPACE
		/* Not defined if user mode disabled, all stacks are kernel stacks */
		if (scenario_data.is_user) {
			adjusted = Z_THREAD_STACK_SIZE_ADJUST(scenario_data.declared_size);
		} else
#endif
		{
			adjusted = Z_KERNEL_STACK_SIZE_ADJUST(scenario_data.declared_size);
		}
		adjusted -= reserved;

		zassert_equal(end_space, 0, "unexpected unused space\n");
	} else {
		/* For arrays there may be unused space per-object. This is because
		 * every single array member must be aligned to the value returned
		 * by Z_{KERNEL|THREAD}_STACK_OBJ_ALIGN.
		 *
		 * If we define:
		 *
		 * K_{THREAD|KERNEL}_STACK_ARRAY_DEFINE(my_stack_array, num_stacks, X);
		 *
		 * We do not auto-expand usable space to cover this unused area. Doing
		 * this would require some way for the kernel to know that a stack object
		 * pointer passed in is an array member, which is currently not possible.
		 *
		 * The equivalence here is computable with:
		 * K_THREAD_STACK_SIZEOF(my_stack_array[0]) ==
		 * 	K_THREAD_STACK_LEN(X) - K_THREAD_STACK_RESERVED;
		 */

		if (scenario_data.is_user) {
			adjusted = K_THREAD_STACK_LEN(scenario_data.declared_size);
		} else {
			adjusted = Z_KERNEL_STACK_LEN(scenario_data.declared_size);
		}
		adjusted -= reserved;

		/* At least make sure it's not negative, that means stack_info isn't set
		 * right
		 */
		zassert_true(end_space >= 0, "bad stack bounds in stack_info");
	}

	zassert_true(adjusted == scenario_data.reported_size,
		     "size mismatch: adjusted %zu vs. reported %zu",
		     adjusted, scenario_data.reported_size);

	ret = k_thread_stack_space_get(k_current_get(), &unused);
	if (!is_usermode && IS_ENABLED(CONFIG_NO_UNUSED_STACK_INSPECTION)) {
		expected = -ENOTSUP;
	} else {
		expected = 0;
	}

	zassert_equal(ret, expected, "unexpected return value %d", ret);
	if (ret == 0) {
		printk("self-reported unused stack space: %zu\n", unused);
	}
}

void stest_thread_entry(void *p1, void *p2, void *p3)
{
	bool drop = (bool)p1;

	if (drop) {
		k_thread_user_mode_enter(stest_thread_entry, (void *)false,
					 p2, p3);
	} else {
		stack_buffer_scenarios();
	}
}

void stest_thread_launch(uint32_t flags, bool drop)
{
	int ret;
	size_t unused;

	k_thread_create(&test_thread, scenario_data.stack, STEST_STACKSIZE,
			stest_thread_entry,
			(void *)drop, NULL, NULL,
			-1, flags, K_NO_WAIT);
	k_thread_join(&test_thread, K_FOREVER);

	ret = k_thread_stack_space_get(&test_thread, &unused);
	zassert_equal(ret, 0, "failed to calculate unused stack space\n");
	printk("target thread unused stack space: %zu\n", unused);
}

void scenario_entry(void *stack_obj, size_t obj_size, size_t reported_size,
		    size_t declared_size, bool is_array)
{
	bool is_user;
	size_t metadata_size;

#ifdef CONFIG_USERSPACE
	struct z_object *zo;

	zo = z_object_find(stack_obj);
	if (zo != NULL) {
		is_user = true;
#ifdef CONFIG_GEN_PRIV_STACKS
		metadata_size = zo->data.stack_data->size;
#else
		metadata_size = zo->data.stack_size;
#endif /* CONFIG_GEN_PRIV_STACKS */
		printk("stack may host user thread, size in metadata is %zu\n",
		       metadata_size);
	} else
#endif /* CONFIG_USERSPACE */
	{
		metadata_size = 0;
		is_user = false;
	}

	scenario_data.stack = stack_obj;
	scenario_data.object_size = obj_size;
	scenario_data.is_user = is_user;
	scenario_data.metadata_size = metadata_size;
	scenario_data.reported_size = reported_size;
	scenario_data.declared_size = declared_size;
	scenario_data.is_array = is_array;

	printk("Stack object %p[%zu]\n", stack_obj, obj_size);
	printk(" - Testing supervisor mode\n");
	stest_thread_launch(0, false);

#ifdef CONFIG_USERSPACE
	if (is_user) {
		printk(" - Testing user mode (direct launch)\n");
		stest_thread_launch(K_USER | K_INHERIT_PERMS, false);
		printk(" - Testing user mode (drop)\n");
		stest_thread_launch(K_INHERIT_PERMS, true);
	}
#endif /* CONFIG_USERSPACE */
}

/**
 * @brief Test kernel provides user thread read/write access to its own stack
 * memory buffer
 *
 * @details Thread can access its own stack memory buffer and perform
 * read/write operations.
 *
 * @ingroup kernel_memprotect_tests
 */
void test_stack_buffer(void)
{
	printk("Reserved space (thread stacks): %zu\n",
	       K_THREAD_STACK_RESERVED);
	printk("Reserved space (kernel stacks): %zu\n",
	       K_KERNEL_STACK_RESERVED);

	printk("CONFIG_ISR_STACK_SIZE %zu\n", (size_t)CONFIG_ISR_STACK_SIZE);
	for (int i = 0; i < CONFIG_MP_NUM_CPUS; i++) {
		printk("irq stack %d: %p size %zu\n",
		       i, &z_interrupt_stacks[i],
		       sizeof(z_interrupt_stacks[i]));
	}

	printk("Provided stack size: %u\n", STEST_STACKSIZE);

	printk("\ntesting user_stack\n");
	scenario_entry(user_stack, sizeof(user_stack), K_THREAD_STACK_SIZEOF(user_stack),
		       STEST_STACKSIZE, false);

	for (int i = 0; i < NUM_STACKS; i++) {
		printk("\ntesting user_stack_array[%d]\n", i);
		scenario_entry(user_stack_array[i],
			       sizeof(user_stack_array[i]),
			       K_THREAD_STACK_SIZEOF(user_stack_array[i]),
			       STEST_STACKSIZE, true);
	}

	printk("\ntesting kern_stack\n");
	scenario_entry(kern_stack, sizeof(kern_stack), K_KERNEL_STACK_SIZEOF(kern_stack),
		       STEST_STACKSIZE, false);

	for (int i = 0; i < NUM_STACKS; i++) {
		printk("\ntesting kern_stack_array[%d]\n", i);
		scenario_entry(kern_stack_array[i],
			       sizeof(kern_stack_array[i]),
			       K_KERNEL_STACK_SIZEOF(kern_stack_array[i]),
			       STEST_STACKSIZE, true);
	}

	printk("\ntesting stest_member_stack\n");
	scenario_entry(&stest_member_stack.stack,
		       sizeof(stest_member_stack.stack),
		       K_KERNEL_STACK_SIZEOF(stest_member_stack.stack),
		       STEST_STACKSIZE, false);
}

void no_op_entry(void *p1, void *p2, void *p3)
{

	printk("hi! bye!\n");

#ifdef CONFIG_DYNAMIC_OBJECTS
	/* Allocate a dynamic kernel object, which gets freed on thread
	 * cleanup since this thread has the only reference.
	 */
	struct k_sem *dyn_sem = k_object_alloc(K_OBJ_SEM);
	k_sem_init(dyn_sem, 1, 1);
	printk("allocated semaphore %p\n", dyn_sem);
#endif
	/* thread self-aborts, triggering idle thread cleanup */
}

/**
 * @brief Show that the idle thread stack size is correct
 *
 * The idle thread has to occasionally clean up self-exiting threads.
 * Exercise this and show that we didn't overflow, reporting out stack
 * usage.
 *
 * @ingroup kernel_memprotect_tests
 */
void test_idle_stack(void)
{
	if (IS_ENABLED(CONFIG_KERNEL_COHERENCE)) {
		/* Stacks on coherence platforms aren't coherent, and
		 * the idle stack may have been initialized on a
		 * different CPU!
		 */
		ztest_test_skip();
	}

	int ret;
#ifdef CONFIG_SMP
	/* 1cpu test case, so all other CPUs are spinning with co-op
	 * threads blocking them. _current_cpu triggers an assertion.
	 */
	struct k_thread *idle = arch_curr_cpu()->idle_thread;
#else
	struct k_thread *idle = _current_cpu->idle_thread;
#endif
	size_t unused_bytes;

	/* Spwawn a child thread which self-exits */
	k_thread_create(&test_thread, kern_stack, STEST_STACKSIZE,
			no_op_entry,
			NULL, NULL, NULL,
			-1, 0, K_NO_WAIT);

	k_thread_join(&test_thread, K_FOREVER);

	/* Also sleep for a bit, which also exercises the idle thread
	 * in case some PM hooks will run
	 */
	k_sleep(K_MSEC(1));

	/* Now measure idle thread stack usage */
	ret = k_thread_stack_space_get(idle, &unused_bytes);
	zassert_true(ret == 0, "failed to obtain stack space");
	zassert_true(unused_bytes > 0, "idle thread stack size %d too low",
		     CONFIG_IDLE_STACK_SIZE);
	printk("unused idle thread stack size: %zu/%d (%zu used)\n",
	       unused_bytes, CONFIG_IDLE_STACK_SIZE,
	       CONFIG_IDLE_STACK_SIZE - unused_bytes);

}

void test_main(void)
{
	k_thread_system_pool_assign(k_current_get());

	/* Run a thread that self-exits, triggering idle cleanup */
	ztest_test_suite(userspace,
			 ztest_1cpu_unit_test(test_stack_buffer),
			 ztest_1cpu_unit_test(test_idle_stack)
			 );
	ztest_run_test_suite(userspace);
}
