// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2021 ARM Limited.
 * Original author: Mark Brown <broonie@kernel.org>
 */
#include <assert.h>
#include <errno.h>
#include <fcntl.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/types.h>
#include <sys/wait.h>
#include <asm/sigcontext.h>
#include <asm/hwcap.h>

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

#define ARCH_MIN_VL SVE_VL_MIN

struct vec_data {
	const char *name;
	unsigned long hwcap_type;
	unsigned long hwcap;
	const char *rdvl_binary;
	int (*rdvl)(void);

	int prctl_get;
	int prctl_set;
	const char *default_vl_file;

	int default_vl;
	int min_vl;
	int max_vl;
};

#define VEC_SVE 0
#define VEC_SME 1

static struct vec_data vec_data[] = {
	[VEC_SVE] = {
		.name = "SVE",
		.hwcap_type = AT_HWCAP,
		.hwcap = HWCAP_SVE,
		.rdvl = rdvl_sve,
		.rdvl_binary = "./rdvl-sve",
		.prctl_get = PR_SVE_GET_VL,
		.prctl_set = PR_SVE_SET_VL,
		.default_vl_file = "/proc/sys/abi/sve_default_vector_length",
	},
	[VEC_SME] = {
		.name = "SME",
		.hwcap_type = AT_HWCAP2,
		.hwcap = HWCAP2_SME,
		.rdvl = rdvl_sme,
		.rdvl_binary = "./rdvl-sme",
		.prctl_get = PR_SME_GET_VL,
		.prctl_set = PR_SME_SET_VL,
		.default_vl_file = "/proc/sys/abi/sme_default_vector_length",
	},
};

static bool vec_type_supported(struct vec_data *data)
{
	return getauxval(data->hwcap_type) & data->hwcap;
}

static int stdio_read_integer(FILE *f, const char *what, int *val)
{
	int n = 0;
	int ret;

	ret = fscanf(f, "%d%*1[\n]%n", val, &n);
	if (ret < 1 || n < 1) {
		ksft_print_msg("failed to parse integer from %s\n", what);
		return -1;
	}

	return 0;
}

/* Start a new process and return the vector length it sees */
static int get_child_rdvl(struct vec_data *data)
{
	FILE *out;
	int pipefd[2];
	pid_t pid, child;
	int read_vl, ret;

	ret = pipe(pipefd);
	if (ret == -1) {
		ksft_print_msg("pipe() failed: %d (%s)\n",
			       errno, strerror(errno));
		return -1;
	}

	fflush(stdout);

	child = fork();
	if (child == -1) {
		ksft_print_msg("fork() failed: %d (%s)\n",
			       errno, strerror(errno));
		close(pipefd[0]);
		close(pipefd[1]);
		return -1;
	}

	/* Child: put vector length on the pipe */
	if (child == 0) {
		/*
		 * Replace stdout with the pipe, errors to stderr from
		 * here as kselftest prints to stdout.
		 */
		ret = dup2(pipefd[1], 1);
		if (ret == -1) {
			fprintf(stderr, "dup2() %d\n", errno);
			exit(EXIT_FAILURE);
		}

		/* exec() a new binary which puts the VL on stdout */
		ret = execl(data->rdvl_binary, data->rdvl_binary, NULL);
		fprintf(stderr, "execl(%s) failed: %d (%s)\n",
			data->rdvl_binary, errno, strerror(errno));

		exit(EXIT_FAILURE);
	}

	close(pipefd[1]);

	/* Parent; wait for the exit status from the child & verify it */
	do {
		pid = wait(&ret);
		if (pid == -1) {
			ksft_print_msg("wait() failed: %d (%s)\n",
				       errno, strerror(errno));
			close(pipefd[0]);
			return -1;
		}
	} while (pid != child);

	assert(pid == child);

	if (!WIFEXITED(ret)) {
		ksft_print_msg("child exited abnormally\n");
		close(pipefd[0]);
		return -1;
	}

	if (WEXITSTATUS(ret) != 0) {
		ksft_print_msg("child returned error %d\n",
			       WEXITSTATUS(ret));
		close(pipefd[0]);
		return -1;
	}

	out = fdopen(pipefd[0], "r");
	if (!out) {
		ksft_print_msg("failed to open child stdout\n");
		close(pipefd[0]);
		return -1;
	}

	ret = stdio_read_integer(out, "child", &read_vl);
	fclose(out);
	if (ret != 0)
		return ret;

	return read_vl;
}

static int file_read_integer(const char *name, int *val)
{
	FILE *f;
	int ret;

	f = fopen(name, "r");
	if (!f) {
		ksft_test_result_fail("Unable to open %s: %d (%s)\n",
				      name, errno,
				      strerror(errno));
		return -1;
	}

	ret = stdio_read_integer(f, name, val);
	fclose(f);

	return ret;
}

static int file_write_integer(const char *name, int val)
{
	FILE *f;

	f = fopen(name, "w");
	if (!f) {
		ksft_test_result_fail("Unable to open %s: %d (%s)\n",
				      name, errno,
				      strerror(errno));
		return -1;
	}

	fprintf(f, "%d", val);
	fclose(f);

	return 0;
}

/*
 * Verify that we can read the default VL via proc, checking that it
 * is set in a freshly spawned child.
 */
static void proc_read_default(struct vec_data *data)
{
	int default_vl, child_vl, ret;

	ret = file_read_integer(data->default_vl_file, &default_vl);
	if (ret != 0)
		return;

	/* Is this the actual default seen by new processes? */
	child_vl = get_child_rdvl(data);
	if (child_vl != default_vl) {
		ksft_test_result_fail("%s is %d but child VL is %d\n",
				      data->default_vl_file,
				      default_vl, child_vl);
		return;
	}

	ksft_test_result_pass("%s default vector length %d\n", data->name,
			      default_vl);
	data->default_vl = default_vl;
}

/* Verify that we can write a minimum value and have it take effect */
static void proc_write_min(struct vec_data *data)
{
	int ret, new_default, child_vl;

	if (geteuid() != 0) {
		ksft_test_result_skip("Need to be root to write to /proc\n");
		return;
	}

	ret = file_write_integer(data->default_vl_file, ARCH_MIN_VL);
	if (ret != 0)
		return;

	/* What was the new value? */
	ret = file_read_integer(data->default_vl_file, &new_default);
	if (ret != 0)
		return;

	/* Did it take effect in a new process? */
	child_vl = get_child_rdvl(data);
	if (child_vl != new_default) {
		ksft_test_result_fail("%s is %d but child VL is %d\n",
				      data->default_vl_file,
				      new_default, child_vl);
		return;
	}

	ksft_test_result_pass("%s minimum vector length %d\n", data->name,
			      new_default);
	data->min_vl = new_default;

	file_write_integer(data->default_vl_file, data->default_vl);
}

/* Verify that we can write a maximum value and have it take effect */
static void proc_write_max(struct vec_data *data)
{
	int ret, new_default, child_vl;

	if (geteuid() != 0) {
		ksft_test_result_skip("Need to be root to write to /proc\n");
		return;
	}

	/* -1 is accepted by the /proc interface as the maximum VL */
	ret = file_write_integer(data->default_vl_file, -1);
	if (ret != 0)
		return;

	/* What was the new value? */
	ret = file_read_integer(data->default_vl_file, &new_default);
	if (ret != 0)
		return;

	/* Did it take effect in a new process? */
	child_vl = get_child_rdvl(data);
	if (child_vl != new_default) {
		ksft_test_result_fail("%s is %d but child VL is %d\n",
				      data->default_vl_file,
				      new_default, child_vl);
		return;
	}

	ksft_test_result_pass("%s maximum vector length %d\n", data->name,
			      new_default);
	data->max_vl = new_default;

	file_write_integer(data->default_vl_file, data->default_vl);
}

/* Can we read back a VL from prctl? */
static void prctl_get(struct vec_data *data)
{
	int ret;

	ret = prctl(data->prctl_get);
	if (ret == -1) {
		ksft_test_result_fail("%s prctl() read failed: %d (%s)\n",
				      data->name, errno, strerror(errno));
		return;
	}

	/* Mask out any flags */
	ret &= PR_SVE_VL_LEN_MASK;

	/* Is that what we can read back directly? */
	if (ret == data->rdvl())
		ksft_test_result_pass("%s current VL is %d\n",
				      data->name, ret);
	else
		ksft_test_result_fail("%s prctl() VL %d but RDVL is %d\n",
				      data->name, ret, data->rdvl());
}

/* Does the prctl let us set the VL we already have? */
static void prctl_set_same(struct vec_data *data)
{
	int cur_vl = data->rdvl();
	int ret;

	ret = prctl(data->prctl_set, cur_vl);
	if (ret < 0) {
		ksft_test_result_fail("%s prctl set failed: %d (%s)\n",
				      data->name, errno, strerror(errno));
		return;
	}

	ksft_test_result(cur_vl == data->rdvl(),
			 "%s set VL %d and have VL %d\n",
			 data->name, cur_vl, data->rdvl());
}

/* Can we set a new VL for this process? */
static void prctl_set(struct vec_data *data)
{
	int ret;

	if (data->min_vl == data->max_vl) {
		ksft_test_result_skip("%s only one VL supported\n",
				      data->name);
		return;
	}

	/* Try to set the minimum VL */
	ret = prctl(data->prctl_set, data->min_vl);
	if (ret < 0) {
		ksft_test_result_fail("%s prctl set failed for %d: %d (%s)\n",
				      data->name, data->min_vl,
				      errno, strerror(errno));
		return;
	}

	if ((ret & PR_SVE_VL_LEN_MASK) != data->min_vl) {
		ksft_test_result_fail("%s prctl set %d but return value is %d\n",
				      data->name, data->min_vl, data->rdvl());
		return;
	}

	if (data->rdvl() != data->min_vl) {
		ksft_test_result_fail("%s set %d but RDVL is %d\n",
				      data->name, data->min_vl, data->rdvl());
		return;
	}

	/* Try to set the maximum VL */
	ret = prctl(data->prctl_set, data->max_vl);
	if (ret < 0) {
		ksft_test_result_fail("%s prctl set failed for %d: %d (%s)\n",
				      data->name, data->max_vl,
				      errno, strerror(errno));
		return;
	}

	if ((ret & PR_SVE_VL_LEN_MASK) != data->max_vl) {
		ksft_test_result_fail("%s prctl() set %d but return value is %d\n",
				      data->name, data->max_vl, data->rdvl());
		return;
	}

	/* The _INHERIT flag should not be present when we read the VL */
	ret = prctl(data->prctl_get);
	if (ret == -1) {
		ksft_test_result_fail("%s prctl() read failed: %d (%s)\n",
				      data->name, errno, strerror(errno));
		return;
	}

	if (ret & PR_SVE_VL_INHERIT) {
		ksft_test_result_fail("%s prctl() reports _INHERIT\n",
				      data->name);
		return;
	}

	ksft_test_result_pass("%s prctl() set min/max\n", data->name);
}

/* If we didn't request it a new VL shouldn't affect the child */
static void prctl_set_no_child(struct vec_data *data)
{
	int ret, child_vl;

	if (data->min_vl == data->max_vl) {
		ksft_test_result_skip("%s only one VL supported\n",
				      data->name);
		return;
	}

	ret = prctl(data->prctl_set, data->min_vl);
	if (ret < 0) {
		ksft_test_result_fail("%s prctl set failed for %d: %d (%s)\n",
				      data->name, data->min_vl,
				      errno, strerror(errno));
		return;
	}

	/* Ensure the default VL is different */
	ret = file_write_integer(data->default_vl_file, data->max_vl);
	if (ret != 0)
		return;

	/* Check that the child has the default we just set */
	child_vl = get_child_rdvl(data);
	if (child_vl != data->max_vl) {
		ksft_test_result_fail("%s is %d but child VL is %d\n",
				      data->default_vl_file,
				      data->max_vl, child_vl);
		return;
	}

	ksft_test_result_pass("%s vector length used default\n", data->name);

	file_write_integer(data->default_vl_file, data->default_vl);
}

/* If we didn't request it a new VL shouldn't affect the child */
static void prctl_set_for_child(struct vec_data *data)
{
	int ret, child_vl;

	if (data->min_vl == data->max_vl) {
		ksft_test_result_skip("%s only one VL supported\n",
				      data->name);
		return;
	}

	ret = prctl(data->prctl_set, data->min_vl | PR_SVE_VL_INHERIT);
	if (ret < 0) {
		ksft_test_result_fail("%s prctl set failed for %d: %d (%s)\n",
				      data->name, data->min_vl,
				      errno, strerror(errno));
		return;
	}

	/* The _INHERIT flag should be present when we read the VL */
	ret = prctl(data->prctl_get);
	if (ret == -1) {
		ksft_test_result_fail("%s prctl() read failed: %d (%s)\n",
				      data->name, errno, strerror(errno));
		return;
	}
	if (!(ret & PR_SVE_VL_INHERIT)) {
		ksft_test_result_fail("%s prctl() does not report _INHERIT\n",
				      data->name);
		return;
	}

	/* Ensure the default VL is different */
	ret = file_write_integer(data->default_vl_file, data->max_vl);
	if (ret != 0)
		return;

	/* Check that the child inherited our VL */
	child_vl = get_child_rdvl(data);
	if (child_vl != data->min_vl) {
		ksft_test_result_fail("%s is %d but child VL is %d\n",
				      data->default_vl_file,
				      data->min_vl, child_vl);
		return;
	}

	ksft_test_result_pass("%s vector length was inherited\n", data->name);

	file_write_integer(data->default_vl_file, data->default_vl);
}

/* _ONEXEC takes effect only in the child process */
static void prctl_set_onexec(struct vec_data *data)
{
	int ret, child_vl;

	if (data->min_vl == data->max_vl) {
		ksft_test_result_skip("%s only one VL supported\n",
				      data->name);
		return;
	}

	/* Set a known value for the default and our current VL */
	ret = file_write_integer(data->default_vl_file, data->max_vl);
	if (ret != 0)
		return;

	ret = prctl(data->prctl_set, data->max_vl);
	if (ret < 0) {
		ksft_test_result_fail("%s prctl set failed for %d: %d (%s)\n",
				      data->name, data->min_vl,
				      errno, strerror(errno));
		return;
	}

	/* Set a different value for the child to have on exec */
	ret = prctl(data->prctl_set, data->min_vl | PR_SVE_SET_VL_ONEXEC);
	if (ret < 0) {
		ksft_test_result_fail("%s prctl set failed for %d: %d (%s)\n",
				      data->name, data->min_vl,
				      errno, strerror(errno));
		return;
	}

	/* Our current VL should stay the same */
	if (data->rdvl() != data->max_vl) {
		ksft_test_result_fail("%s VL changed by _ONEXEC prctl()\n",
				      data->name);
		return;
	}

	/* Check that the child inherited our VL */
	child_vl = get_child_rdvl(data);
	if (child_vl != data->min_vl) {
		ksft_test_result_fail("Set %d _ONEXEC but child VL is %d\n",
				      data->min_vl, child_vl);
		return;
	}

	ksft_test_result_pass("%s vector length set on exec\n", data->name);

	file_write_integer(data->default_vl_file, data->default_vl);
}

/* For each VQ verify that setting via prctl() does the right thing */
static void prctl_set_all_vqs(struct vec_data *data)
{
	int ret, vq, vl, new_vl, i;
	int orig_vls[ARRAY_SIZE(vec_data)];
	int errors = 0;

	if (!data->min_vl || !data->max_vl) {
		ksft_test_result_skip("%s Failed to enumerate VLs, not testing VL setting\n",
				      data->name);
		return;
	}

	for (i = 0; i < ARRAY_SIZE(vec_data); i++) {
		if (!vec_type_supported(&vec_data[i]))
			continue;
		orig_vls[i] = vec_data[i].rdvl();
	}

	for (vq = SVE_VQ_MIN; vq <= SVE_VQ_MAX; vq++) {
		vl = sve_vl_from_vq(vq);

		/* Attempt to set the VL */
		ret = prctl(data->prctl_set, vl);
		if (ret < 0) {
			errors++;
			ksft_print_msg("%s prctl set failed for %d: %d (%s)\n",
				       data->name, vl,
				       errno, strerror(errno));
			continue;
		}

		new_vl = ret & PR_SVE_VL_LEN_MASK;

		/* Check that we actually have the reported new VL */
		if (data->rdvl() != new_vl) {
			ksft_print_msg("Set %s VL %d but RDVL reports %d\n",
				       data->name, new_vl, data->rdvl());
			errors++;
		}

		/* Did any other VLs change? */
		for (i = 0; i < ARRAY_SIZE(vec_data); i++) {
			if (&vec_data[i] == data)
				continue;

			if (!vec_type_supported(&vec_data[i]))
				continue;

			if (vec_data[i].rdvl() != orig_vls[i]) {
				ksft_print_msg("%s VL changed from %d to %d\n",
					       vec_data[i].name, orig_vls[i],
					       vec_data[i].rdvl());
				errors++;
			}
		}

		/* Was that the VL we asked for? */
		if (new_vl == vl)
			continue;

		/* Should round up to the minimum VL if below it */
		if (vl < data->min_vl) {
			if (new_vl != data->min_vl) {
				ksft_print_msg("%s VL %d returned %d not minimum %d\n",
					       data->name, vl, new_vl,
					       data->min_vl);
				errors++;
			}

			continue;
		}

		/* Should round down to maximum VL if above it */
		if (vl > data->max_vl) {
			if (new_vl != data->max_vl) {
				ksft_print_msg("%s VL %d returned %d not maximum %d\n",
					       data->name, vl, new_vl,
					       data->max_vl);
				errors++;
			}

			continue;
		}

		/* Otherwise we should've rounded down */
		if (!(new_vl < vl)) {
			ksft_print_msg("%s VL %d returned %d, did not round down\n",
				       data->name, vl, new_vl);
			errors++;

			continue;
		}
	}

	ksft_test_result(errors == 0, "%s prctl() set all VLs, %d errors\n",
			 data->name, errors);
}

typedef void (*test_type)(struct vec_data *);

static const test_type tests[] = {
	/*
	 * The default/min/max tests must be first and in this order
	 * to provide data for other tests.
	 */
	proc_read_default,
	proc_write_min,
	proc_write_max,

	prctl_get,
	prctl_set_same,
	prctl_set,
	prctl_set_no_child,
	prctl_set_for_child,
	prctl_set_onexec,
	prctl_set_all_vqs,
};

static inline void smstart(void)
{
	asm volatile("msr S0_3_C4_C7_3, xzr");
}

static inline void smstart_sm(void)
{
	asm volatile("msr S0_3_C4_C3_3, xzr");
}

static inline void smstop(void)
{
	asm volatile("msr S0_3_C4_C6_3, xzr");
}


/*
 * Verify we can change the SVE vector length while SME is active and
 * continue to use SME afterwards.
 */
static void change_sve_with_za(void)
{
	struct vec_data *sve_data = &vec_data[VEC_SVE];
	bool pass = true;
	int ret, i;

	if (sve_data->min_vl == sve_data->max_vl) {
		ksft_print_msg("Only one SVE VL supported, can't change\n");
		ksft_test_result_skip("change_sve_while_sme\n");
		return;
	}

	/* Ensure we will trigger a change when we set the maximum */
	ret = prctl(sve_data->prctl_set, sve_data->min_vl);
	if (ret != sve_data->min_vl) {
		ksft_print_msg("Failed to set SVE VL %d: %d\n",
			       sve_data->min_vl, ret);
		pass = false;
	}

	/* Enable SM and ZA */
	smstart();

	/* Trigger another VL change */
	ret = prctl(sve_data->prctl_set, sve_data->max_vl);
	if (ret != sve_data->max_vl) {
		ksft_print_msg("Failed to set SVE VL %d: %d\n",
			       sve_data->max_vl, ret);
		pass = false;
	}

	/*
	 * Spin for a bit with SM enabled to try to trigger another
	 * save/restore.  We can't use syscalls without exiting
	 * streaming mode.
	 */
	for (i = 0; i < 100000000; i++)
		smstart_sm();

	/*
	 * TODO: Verify that ZA was preserved over the VL change and
	 * spin.
	 */

	/* Clean up after ourselves */
	smstop();
	ret = prctl(sve_data->prctl_set, sve_data->default_vl);
	if (ret != sve_data->default_vl) {
	        ksft_print_msg("Failed to restore SVE VL %d: %d\n",
			       sve_data->default_vl, ret);
		pass = false;
	}

	ksft_test_result(pass, "change_sve_with_za\n");
}

typedef void (*test_all_type)(void);

static const struct {
	const char *name;
	test_all_type test;
}  all_types_tests[] = {
	{ "change_sve_with_za", change_sve_with_za },
};

int main(void)
{
	bool all_supported = true;
	int i, j;

	ksft_print_header();
	ksft_set_plan(ARRAY_SIZE(tests) * ARRAY_SIZE(vec_data) +
		      ARRAY_SIZE(all_types_tests));

	for (i = 0; i < ARRAY_SIZE(vec_data); i++) {
		struct vec_data *data = &vec_data[i];
		unsigned long supported;

		supported = vec_type_supported(data);
		if (!supported)
			all_supported = false;

		for (j = 0; j < ARRAY_SIZE(tests); j++) {
			if (supported)
				tests[j](data);
			else
				ksft_test_result_skip("%s not supported\n",
						      data->name);
		}
	}

	for (i = 0; i < ARRAY_SIZE(all_types_tests); i++) {
		if (all_supported)
			all_types_tests[i].test();
		else
			ksft_test_result_skip("%s\n", all_types_tests[i].name);
	}

	ksft_exit_pass();
}
