// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2021 ARM Limited.
 */
#include <errno.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/auxv.h>
#include <sys/prctl.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/wait.h>
#include <asm/sigcontext.h>
#include <asm/ptrace.h>

#include "../../kselftest.h"

/* <linux/elf.h> and <sys/auxv.h> don't like each other, so: */
#ifndef NT_ARM_ZA
#define NT_ARM_ZA 0x40c
#endif
#ifndef NT_ARM_ZT
#define NT_ARM_ZT 0x40d
#endif

#define EXPECTED_TESTS 3

static int sme_vl;

static void fill_buf(char *buf, size_t size)
{
	int i;

	for (i = 0; i < size; i++)
		buf[i] = random();
}

static int do_child(void)
{
	if (ptrace(PTRACE_TRACEME, -1, NULL, NULL))
		ksft_exit_fail_msg("ptrace(PTRACE_TRACEME) failed: %s (%d)\n",
				   strerror(errno), errno);

	if (raise(SIGSTOP))
		ksft_exit_fail_msg("raise(SIGSTOP) failed: %s (%d)\n",
				   strerror(errno), errno);

	return EXIT_SUCCESS;
}

static struct user_za_header *get_za(pid_t pid, void **buf, size_t *size)
{
	struct user_za_header *za;
	void *p;
	size_t sz = sizeof(*za);
	struct iovec iov;

	while (1) {
		if (*size < sz) {
			p = realloc(*buf, sz);
			if (!p) {
				errno = ENOMEM;
				goto error;
			}

			*buf = p;
			*size = sz;
		}

		iov.iov_base = *buf;
		iov.iov_len = sz;
		if (ptrace(PTRACE_GETREGSET, pid, NT_ARM_ZA, &iov))
			goto error;

		za = *buf;
		if (za->size <= sz)
			break;

		sz = za->size;
	}

	return za;

error:
	return NULL;
}

static int set_za(pid_t pid, const struct user_za_header *za)
{
	struct iovec iov;

	iov.iov_base = (void *)za;
	iov.iov_len = za->size;
	return ptrace(PTRACE_SETREGSET, pid, NT_ARM_ZA, &iov);
}

static int get_zt(pid_t pid, char zt[ZT_SIG_REG_BYTES])
{
	struct iovec iov;

	iov.iov_base = zt;
	iov.iov_len = ZT_SIG_REG_BYTES;
	return ptrace(PTRACE_GETREGSET, pid, NT_ARM_ZT, &iov);
}


static int set_zt(pid_t pid, const char zt[ZT_SIG_REG_BYTES])
{
	struct iovec iov;

	iov.iov_base = (void *)zt;
	iov.iov_len = ZT_SIG_REG_BYTES;
	return ptrace(PTRACE_SETREGSET, pid, NT_ARM_ZT, &iov);
}

/* Reading with ZA disabled returns all zeros */
static void ptrace_za_disabled_read_zt(pid_t child)
{
	struct user_za_header za;
	char zt[ZT_SIG_REG_BYTES];
	int ret, i;
	bool fail = false;

	/* Disable PSTATE.ZA using the ZA interface */
	memset(&za, 0, sizeof(za));
	za.vl = sme_vl;
	za.size = sizeof(za);

	ret = set_za(child, &za);
	if (ret != 0) {
		ksft_print_msg("Failed to disable ZA\n");
		fail = true;
	}

	/* Read back ZT */
	ret = get_zt(child, zt);
	if (ret != 0) {
		ksft_print_msg("Failed to read ZT\n");
		fail = true;
	}

	for (i = 0; i < ARRAY_SIZE(zt); i++) {
		if (zt[i]) {
			ksft_print_msg("zt[%d]: 0x%x != 0\n", i, zt[i]);
			fail = true;
		}
	}

	ksft_test_result(!fail, "ptrace_za_disabled_read_zt\n");
}

/* Writing then reading ZT should return the data written */
static void ptrace_set_get_zt(pid_t child)
{
	char zt_in[ZT_SIG_REG_BYTES];
	char zt_out[ZT_SIG_REG_BYTES];
	int ret, i;
	bool fail = false;

	fill_buf(zt_in, sizeof(zt_in));

	ret = set_zt(child, zt_in);
	if (ret != 0) {
		ksft_print_msg("Failed to set ZT\n");
		fail = true;
	}

	ret = get_zt(child, zt_out);
	if (ret != 0) {
		ksft_print_msg("Failed to read ZT\n");
		fail = true;
	}

	for (i = 0; i < ARRAY_SIZE(zt_in); i++) {
		if (zt_in[i] != zt_out[i]) {
			ksft_print_msg("zt[%d]: 0x%x != 0x%x\n", i, 
				       zt_in[i], zt_out[i]);
			fail = true;
		}
	}

	ksft_test_result(!fail, "ptrace_set_get_zt\n");
}

/* Writing ZT should set PSTATE.ZA */
static void ptrace_enable_za_via_zt(pid_t child)
{
	struct user_za_header za_in;
	struct user_za_header *za_out;
	char zt[ZT_SIG_REG_BYTES];
	char *za_data;
	size_t za_out_size;
	int ret, i, vq;
	bool fail = false;

	/* Disable PSTATE.ZA using the ZA interface */
	memset(&za_in, 0, sizeof(za_in));
	za_in.vl = sme_vl;
	za_in.size = sizeof(za_in);

	ret = set_za(child, &za_in);
	if (ret != 0) {
		ksft_print_msg("Failed to disable ZA\n");
		fail = true;
	}

	/* Write ZT */
	fill_buf(zt, sizeof(zt));
	ret = set_zt(child, zt);
	if (ret != 0) {
		ksft_print_msg("Failed to set ZT\n");
		fail = true;
	}

	/* Read back ZA and check for register data */
	za_out = NULL;
	za_out_size = 0;
	if (get_za(child, (void **)&za_out, &za_out_size)) {
		/* Should have an unchanged VL */
		if (za_out->vl != sme_vl) {
			ksft_print_msg("VL changed from %d to %d\n",
				       sme_vl, za_out->vl);
			fail = true;
		}
		vq = __sve_vq_from_vl(za_out->vl);
		za_data = (char *)za_out + ZA_PT_ZA_OFFSET;

		/* Should have register data */
		if (za_out->size < ZA_PT_SIZE(vq)) {
			ksft_print_msg("ZA data less than expected: %u < %u\n",
				       za_out->size, (unsigned int)ZA_PT_SIZE(vq));
			fail = true;
			vq = 0;
		}

		/* That register data should be non-zero */
		for (i = 0; i < ZA_PT_ZA_SIZE(vq); i++) {
			if (za_data[i]) {
				ksft_print_msg("ZA byte %d is %x\n",
					       i, za_data[i]);
				fail = true;
			}
		}
	} else {
		ksft_print_msg("Failed to read ZA\n");
		fail = true;
	}

	ksft_test_result(!fail, "ptrace_enable_za_via_zt\n");
}

static int do_parent(pid_t child)
{
	int ret = EXIT_FAILURE;
	pid_t pid;
	int status;
	siginfo_t si;

	/* Attach to the child */
	while (1) {
		int sig;

		pid = wait(&status);
		if (pid == -1) {
			perror("wait");
			goto error;
		}

		/*
		 * This should never happen but it's hard to flag in
		 * the framework.
		 */
		if (pid != child)
			continue;

		if (WIFEXITED(status) || WIFSIGNALED(status))
			ksft_exit_fail_msg("Child died unexpectedly\n");

		if (!WIFSTOPPED(status))
			goto error;

		sig = WSTOPSIG(status);

		if (ptrace(PTRACE_GETSIGINFO, pid, NULL, &si)) {
			if (errno == ESRCH)
				goto disappeared;

			if (errno == EINVAL) {
				sig = 0; /* bust group-stop */
				goto cont;
			}

			ksft_test_result_fail("PTRACE_GETSIGINFO: %s\n",
					      strerror(errno));
			goto error;
		}

		if (sig == SIGSTOP && si.si_code == SI_TKILL &&
		    si.si_pid == pid)
			break;

	cont:
		if (ptrace(PTRACE_CONT, pid, NULL, sig)) {
			if (errno == ESRCH)
				goto disappeared;

			ksft_test_result_fail("PTRACE_CONT: %s\n",
					      strerror(errno));
			goto error;
		}
	}

	ksft_print_msg("Parent is %d, child is %d\n", getpid(), child);

	ptrace_za_disabled_read_zt(child);
	ptrace_set_get_zt(child);
	ptrace_enable_za_via_zt(child);

	ret = EXIT_SUCCESS;

error:
	kill(child, SIGKILL);

disappeared:
	return ret;
}

int main(void)
{
	int ret = EXIT_SUCCESS;
	pid_t child;

	srandom(getpid());

	ksft_print_header();

	if (!(getauxval(AT_HWCAP2) & HWCAP2_SME2)) {
		ksft_set_plan(1);
		ksft_exit_skip("SME2 not available\n");
	}

	/* We need a valid SME VL to enable/disable ZA */
	sme_vl = prctl(PR_SME_GET_VL);
	if (sme_vl == -1) {
		ksft_set_plan(1);
		ksft_exit_skip("Failed to read SME VL: %d (%s)\n",
			       errno, strerror(errno));
	}

	ksft_set_plan(EXPECTED_TESTS);

	child = fork();
	if (!child)
		return do_child();

	if (do_parent(child))
		ret = EXIT_FAILURE;

	ksft_print_cnts();

	return ret;
}
