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

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#include <sys/auxv.h>
#include <linux/auxvec.h>
#include <ucontext.h>

#include <asm/unistd.h>

#include <kselftest.h>

#include "test_signals.h"
#include "test_signals_utils.h"
#include "testcases/testcases.h"


extern struct tdescr *current;

static int sig_copyctx = SIGTRAP;

static char const *const feats_names[FMAX_END] = {
	" SSBS ",
	" SVE ",
	" SME ",
	" FA64 ",
	" SME2 ",
	" GCS ",
};

#define MAX_FEATS_SZ	128
static char feats_string[MAX_FEATS_SZ];

static inline char *feats_to_string(unsigned long feats)
{
	size_t flen = MAX_FEATS_SZ - 1;

	feats_string[0] = '\0';

	for (int i = 0; i < FMAX_END; i++) {
		if (feats & (1UL << i)) {
			size_t tlen = strlen(feats_names[i]);

			assert(flen > tlen);
			flen -= tlen;
			strncat(feats_string, feats_names[i], flen);
		}
	}

	return feats_string;
}

static void unblock_signal(int signum)
{
	sigset_t sset;

	sigemptyset(&sset);
	sigaddset(&sset, signum);
	sigprocmask(SIG_UNBLOCK, &sset, NULL);
}

static void default_result(struct tdescr *td, bool force_exit)
{
	if (td->result == KSFT_SKIP) {
		fprintf(stderr, "==>> completed. SKIP.\n");
	} else if (td->pass) {
		fprintf(stderr, "==>> completed. PASS(1)\n");
		td->result = KSFT_PASS;
	} else {
		fprintf(stdout, "==>> completed. FAIL(0)\n");
		td->result = KSFT_FAIL;
	}

	if (force_exit)
		exit(td->result);
}

/*
 * The following handle_signal_* helpers are used by main default_handler
 * and are meant to return true when signal is handled successfully:
 * when false is returned instead, it means that the signal was somehow
 * unexpected in that context and it was NOT handled; default_handler will
 * take care of such unexpected situations.
 */

static bool handle_signal_unsupported(struct tdescr *td,
				      siginfo_t *si, void *uc)
{
	if (feats_ok(td))
		return false;

	/* Mangling PC to avoid loops on original SIGILL */
	((ucontext_t *)uc)->uc_mcontext.pc += 4;

	if (!td->initialized) {
		fprintf(stderr,
			"Got SIG_UNSUPP @test_init. Ignore.\n");
	} else {
		fprintf(stderr,
			"-- RX SIG_UNSUPP on unsupported feat...OK\n");
		td->pass = 1;
		default_result(current, 1);
	}

	return true;
}

static bool handle_signal_trigger(struct tdescr *td,
				  siginfo_t *si, void *uc)
{
	td->triggered = 1;
	/* ->run was asserted NON-NULL in test_setup() already */
	td->run(td, si, uc);

	return true;
}

static bool handle_signal_ok(struct tdescr *td,
			     siginfo_t *si, void *uc)
{
	/*
	 * it's a bug in the test code when this assert fail:
	 * if sig_trig was defined, it must have been used before getting here.
	 */
	assert(!td->sig_trig || td->triggered);
	fprintf(stderr,
		"SIG_OK -- SP:0x%llX  si_addr@:%p  si_code:%d  token@:%p  offset:%ld\n",
		((ucontext_t *)uc)->uc_mcontext.sp,
		si->si_addr, si->si_code, td->token, td->token - si->si_addr);
	/*
	 * fake_sigreturn tests, which have sanity_enabled=1, set, at the very
	 * last time, the token field to the SP address used to place the fake
	 * sigframe: so token==0 means we never made it to the end,
	 * segfaulting well-before, and the test is possibly broken.
	 */
	if (!td->sanity_disabled && !td->token) {
		fprintf(stdout,
			"current->token ZEROED...test is probably broken!\n");
		abort();
	}
	if (td->sig_ok_code) {
		if (si->si_code != td->sig_ok_code) {
			fprintf(stdout, "si_code is %d not %d\n",
				si->si_code, td->sig_ok_code);
			abort();
		}
	} else {
		/*
		 * Trying to narrow down the SEGV to the ones
		 * generated by Kernel itself via
		 * arm64_notify_segfault(). This is a best-effort
		 * check anyway, and the si_code check may need to
		 * change if this aspect of the kernel ABI changes.
		 */
		if (td->sig_ok == SIGSEGV && si->si_code != SEGV_ACCERR) {
			fprintf(stdout,
				"si_code != SEGV_ACCERR...test is probably broken!\n");
			abort();
		}
	}
	td->pass = 1;
	/*
	 * Some tests can lead to SEGV loops: in such a case we want to
	 * terminate immediately exiting straight away; some others are not
	 * supposed to outlive the signal handler code, due to the content of
	 * the fake sigframe which caused the signal itself.
	 */
	default_result(current, 1);

	return true;
}

static bool handle_signal_copyctx(struct tdescr *td,
				  siginfo_t *si, void *uc_in)
{
	ucontext_t *uc = uc_in;
	struct _aarch64_ctx *head;
	struct extra_context *extra, *copied_extra;
	size_t offset = 0;
	size_t to_copy;

	ASSERT_GOOD_CONTEXT(uc);

	/* Mangling PC to avoid loops on original BRK instr */
	uc->uc_mcontext.pc += 4;

	/*
	 * Check for an preserve any extra data too with fixups.
	 */
	head = (struct _aarch64_ctx *)uc->uc_mcontext.__reserved;
	head = get_header(head, EXTRA_MAGIC, td->live_sz, &offset);
	if (head) {
		extra = (struct extra_context *)head;

		/*
		 * The extra buffer must be immediately after the
		 * extra_context and a 16 byte terminator. Include it
		 * in the copy, this was previously validated in
		 * ASSERT_GOOD_CONTEXT().
		 */
		to_copy = __builtin_offsetof(ucontext_t,
					     uc_mcontext.__reserved);
		to_copy += offset + sizeof(struct extra_context) + 16;
		to_copy += extra->size;
		copied_extra = (struct extra_context *)&(td->live_uc->uc_mcontext.__reserved[offset]);
	} else {
		copied_extra = NULL;
		to_copy = sizeof(ucontext_t);
	}

	if (to_copy > td->live_sz) {
		fprintf(stderr,
			"Not enough space to grab context, %lu/%lu bytes\n",
			td->live_sz, to_copy);
		return false;
	}

	memcpy(td->live_uc, uc, to_copy);

	/*
	 * If there was any EXTRA_CONTEXT fix up the size to be the
	 * struct extra_context and the following terminator record,
	 * this means that the rest of the code does not need to have
	 * special handling for the record and we don't need to fix up
	 * datap for the new location.
	 */
	if (copied_extra)
		copied_extra->head.size = sizeof(*copied_extra) + 16;

	td->live_uc_valid = 1;
	fprintf(stderr,
		"%lu byte GOOD CONTEXT grabbed from sig_copyctx handler\n",
		to_copy);

	return true;
}

static void default_handler(int signum, siginfo_t *si, void *uc)
{
	if (current->sig_unsupp && signum == current->sig_unsupp &&
	    handle_signal_unsupported(current, si, uc)) {
		fprintf(stderr, "Handled SIG_UNSUPP\n");
	} else if (current->sig_trig && signum == current->sig_trig &&
		   handle_signal_trigger(current, si, uc)) {
		fprintf(stderr, "Handled SIG_TRIG\n");
	} else if (current->sig_ok && signum == current->sig_ok &&
		   handle_signal_ok(current, si, uc)) {
		fprintf(stderr, "Handled SIG_OK\n");
	} else if (signum == sig_copyctx && current->live_uc &&
		   handle_signal_copyctx(current, si, uc)) {
		fprintf(stderr, "Handled SIG_COPYCTX\n");
	} else {
		if (signum == SIGALRM && current->timeout) {
			fprintf(stderr, "-- Timeout !\n");
		} else {
			fprintf(stderr,
				"-- RX UNEXPECTED SIGNAL: %d code %d address %p\n",
				signum, si->si_code, si->si_addr);
		}
		default_result(current, 1);
	}
}

static int default_setup(struct tdescr *td)
{
	struct sigaction sa;

	sa.sa_sigaction = default_handler;
	sa.sa_flags = SA_SIGINFO | SA_RESTART;
	sa.sa_flags |= td->sa_flags;
	sigemptyset(&sa.sa_mask);
	/* uncatchable signals naturally skipped ... */
	for (int sig = 1; sig < 32; sig++)
		sigaction(sig, &sa, NULL);
	/*
	 * RT Signals default disposition is Term but they cannot be
	 * generated by the Kernel in response to our tests; so just catch
	 * them all and report them as UNEXPECTED signals.
	 */
	for (int sig = SIGRTMIN; sig <= SIGRTMAX; sig++)
		sigaction(sig, &sa, NULL);

	/* just in case...unblock explicitly all we need */
	if (td->sig_trig)
		unblock_signal(td->sig_trig);
	if (td->sig_ok)
		unblock_signal(td->sig_ok);
	if (td->sig_unsupp)
		unblock_signal(td->sig_unsupp);

	if (td->timeout) {
		unblock_signal(SIGALRM);
		alarm(td->timeout);
	}
	fprintf(stderr, "Registered handlers for all signals.\n");

	return 1;
}

static inline int default_trigger(struct tdescr *td)
{
	return !raise(td->sig_trig);
}

int test_init(struct tdescr *td)
{
	if (td->sig_trig == sig_copyctx) {
		fprintf(stdout,
			"Signal %d is RESERVED, cannot be used as a trigger. Aborting\n",
			sig_copyctx);
		return 0;
	}
	/* just in case */
	unblock_signal(sig_copyctx);

	td->minsigstksz = getauxval(AT_MINSIGSTKSZ);
	if (!td->minsigstksz)
		td->minsigstksz = MINSIGSTKSZ;
	fprintf(stderr, "Detected MINSTKSIGSZ:%d\n", td->minsigstksz);

	if (td->feats_required || td->feats_incompatible) {
		td->feats_supported = 0;
		/*
		 * Checking for CPU required features using both the
		 * auxval and the arm64 MRS Emulation to read sysregs.
		 */
		if (getauxval(AT_HWCAP) & HWCAP_SSBS)
			td->feats_supported |= FEAT_SSBS;
		if (getauxval(AT_HWCAP) & HWCAP_SVE)
			td->feats_supported |= FEAT_SVE;
		if (getauxval(AT_HWCAP2) & HWCAP2_SME)
			td->feats_supported |= FEAT_SME;
		if (getauxval(AT_HWCAP2) & HWCAP2_SME_FA64)
			td->feats_supported |= FEAT_SME_FA64;
		if (getauxval(AT_HWCAP2) & HWCAP2_SME2)
			td->feats_supported |= FEAT_SME2;
		if (getauxval(AT_HWCAP) & HWCAP_GCS)
			td->feats_supported |= FEAT_GCS;
		if (feats_ok(td)) {
			if (td->feats_required & td->feats_supported)
				fprintf(stderr,
					"Required Features: [%s] supported\n",
					feats_to_string(td->feats_required &
							td->feats_supported));
			if (!(td->feats_incompatible & td->feats_supported))
				fprintf(stderr,
					"Incompatible Features: [%s] absent\n",
					feats_to_string(td->feats_incompatible));
		} else {
			if ((td->feats_required & td->feats_supported) !=
			    td->feats_supported)
				fprintf(stderr,
					"Required Features: [%s] NOT supported\n",
					feats_to_string(td->feats_required &
							~td->feats_supported));
			if (td->feats_incompatible & td->feats_supported)
				fprintf(stderr,
					"Incompatible Features: [%s] supported\n",
					feats_to_string(td->feats_incompatible &
							~td->feats_supported));


			td->result = KSFT_SKIP;
			return 0;
		}
	}

	/* Perform test specific additional initialization */
	if (td->init && !td->init(td)) {
		fprintf(stderr, "FAILED Testcase initialization.\n");
		return 0;
	}
	td->initialized = 1;
	fprintf(stderr, "Testcase initialized.\n");

	return 1;
}

int test_setup(struct tdescr *td)
{
	/* assert core invariants symptom of a rotten testcase */
	assert(current);
	assert(td);
	assert(td->name);
	assert(td->run);

	/* Default result is FAIL if test setup fails */
	td->result = KSFT_FAIL;
	if (td->setup)
		return td->setup(td);
	else
		return default_setup(td);
}

int test_run(struct tdescr *td)
{
	if (td->trigger)
		return td->trigger(td);
	else if (td->sig_trig)
		return default_trigger(td);
	else
		return td->run(td, NULL, NULL);
}

void test_result(struct tdescr *td)
{
	if (td->initialized && td->result != KSFT_SKIP && td->check_result)
		td->check_result(td);
	default_result(td, 0);
}

void test_cleanup(struct tdescr *td)
{
	if (td->cleanup)
		td->cleanup(td);
}
