/*
 * 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_STACK_SIZE)
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 = 0;
	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
	 * Starting from &val which is close enough to stack pointer
	 */
	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_thread_stack,
			 ztest_1cpu_unit_test(test_stack_buffer),
			 ztest_1cpu_unit_test(test_idle_stack)
			 );
	ztest_run_test_suite(userspace_thread_stack);
}
