// SPDX-License-Identifier: GPL-2.0-only
/*
 * FP/SIMD context switching and fault handling
 *
 * Copyright (C) 2012 ARM Ltd.
 * Author: Catalin Marinas <catalin.marinas@arm.com>
 */

#include <linux/bitmap.h>
#include <linux/bitops.h>
#include <linux/bottom_half.h>
#include <linux/bug.h>
#include <linux/cache.h>
#include <linux/compat.h>
#include <linux/compiler.h>
#include <linux/cpu.h>
#include <linux/cpu_pm.h>
#include <linux/cpumask.h>
#include <linux/ctype.h>
#include <linux/kernel.h>
#include <linux/linkage.h>
#include <linux/irqflags.h>
#include <linux/init.h>
#include <linux/percpu.h>
#include <linux/prctl.h>
#include <linux/preempt.h>
#include <linux/ptrace.h>
#include <linux/sched/signal.h>
#include <linux/sched/task_stack.h>
#include <linux/signal.h>
#include <linux/slab.h>
#include <linux/smp.h>
#include <linux/stddef.h>
#include <linux/sysctl.h>
#include <linux/swab.h>

#include <asm/esr.h>
#include <asm/exception.h>
#include <asm/fpsimd.h>
#include <asm/cpufeature.h>
#include <asm/cputype.h>
#include <asm/neon.h>
#include <asm/processor.h>
#include <asm/simd.h>
#include <asm/sigcontext.h>
#include <asm/sysreg.h>
#include <asm/traps.h>
#include <asm/virt.h>

#define FPEXC_IOF	(1 << 0)
#define FPEXC_DZF	(1 << 1)
#define FPEXC_OFF	(1 << 2)
#define FPEXC_UFF	(1 << 3)
#define FPEXC_IXF	(1 << 4)
#define FPEXC_IDF	(1 << 7)

/*
 * (Note: in this discussion, statements about FPSIMD apply equally to SVE.)
 *
 * In order to reduce the number of times the FPSIMD state is needlessly saved
 * and restored, we need to keep track of two things:
 * (a) for each task, we need to remember which CPU was the last one to have
 *     the task's FPSIMD state loaded into its FPSIMD registers;
 * (b) for each CPU, we need to remember which task's userland FPSIMD state has
 *     been loaded into its FPSIMD registers most recently, or whether it has
 *     been used to perform kernel mode NEON in the meantime.
 *
 * For (a), we add a fpsimd_cpu field to thread_struct, which gets updated to
 * the id of the current CPU every time the state is loaded onto a CPU. For (b),
 * we add the per-cpu variable 'fpsimd_last_state' (below), which contains the
 * address of the userland FPSIMD state of the task that was loaded onto the CPU
 * the most recently, or NULL if kernel mode NEON has been performed after that.
 *
 * With this in place, we no longer have to restore the next FPSIMD state right
 * when switching between tasks. Instead, we can defer this check to userland
 * resume, at which time we verify whether the CPU's fpsimd_last_state and the
 * task's fpsimd_cpu are still mutually in sync. If this is the case, we
 * can omit the FPSIMD restore.
 *
 * As an optimization, we use the thread_info flag TIF_FOREIGN_FPSTATE to
 * indicate whether or not the userland FPSIMD state of the current task is
 * present in the registers. The flag is set unless the FPSIMD registers of this
 * CPU currently contain the most recent userland FPSIMD state of the current
 * task. If the task is behaving as a VMM, then this is will be managed by
 * KVM which will clear it to indicate that the vcpu FPSIMD state is currently
 * loaded on the CPU, allowing the state to be saved if a FPSIMD-aware
 * softirq kicks in. Upon vcpu_put(), KVM will save the vcpu FP state and
 * flag the register state as invalid.
 *
 * In order to allow softirq handlers to use FPSIMD, kernel_neon_begin() may be
 * called from softirq context, which will save the task's FPSIMD context back
 * to task_struct. To prevent this from racing with the manipulation of the
 * task's FPSIMD state from task context and thereby corrupting the state, it
 * is necessary to protect any manipulation of a task's fpsimd_state or
 * TIF_FOREIGN_FPSTATE flag with get_cpu_fpsimd_context(), which will suspend
 * softirq servicing entirely until put_cpu_fpsimd_context() is called.
 *
 * For a certain task, the sequence may look something like this:
 * - the task gets scheduled in; if both the task's fpsimd_cpu field
 *   contains the id of the current CPU, and the CPU's fpsimd_last_state per-cpu
 *   variable points to the task's fpsimd_state, the TIF_FOREIGN_FPSTATE flag is
 *   cleared, otherwise it is set;
 *
 * - the task returns to userland; if TIF_FOREIGN_FPSTATE is set, the task's
 *   userland FPSIMD state is copied from memory to the registers, the task's
 *   fpsimd_cpu field is set to the id of the current CPU, the current
 *   CPU's fpsimd_last_state pointer is set to this task's fpsimd_state and the
 *   TIF_FOREIGN_FPSTATE flag is cleared;
 *
 * - the task executes an ordinary syscall; upon return to userland, the
 *   TIF_FOREIGN_FPSTATE flag will still be cleared, so no FPSIMD state is
 *   restored;
 *
 * - the task executes a syscall which executes some NEON instructions; this is
 *   preceded by a call to kernel_neon_begin(), which copies the task's FPSIMD
 *   register contents to memory, clears the fpsimd_last_state per-cpu variable
 *   and sets the TIF_FOREIGN_FPSTATE flag;
 *
 * - the task gets preempted after kernel_neon_end() is called; as we have not
 *   returned from the 2nd syscall yet, TIF_FOREIGN_FPSTATE is still set so
 *   whatever is in the FPSIMD registers is not saved to memory, but discarded.
 */

DEFINE_PER_CPU(struct cpu_fp_state, fpsimd_last_state);

__ro_after_init struct vl_info vl_info[ARM64_VEC_MAX] = {
#ifdef CONFIG_ARM64_SVE
	[ARM64_VEC_SVE] = {
		.type			= ARM64_VEC_SVE,
		.name			= "SVE",
		.min_vl			= SVE_VL_MIN,
		.max_vl			= SVE_VL_MIN,
		.max_virtualisable_vl	= SVE_VL_MIN,
	},
#endif
#ifdef CONFIG_ARM64_SME
	[ARM64_VEC_SME] = {
		.type			= ARM64_VEC_SME,
		.name			= "SME",
	},
#endif
};

static unsigned int vec_vl_inherit_flag(enum vec_type type)
{
	switch (type) {
	case ARM64_VEC_SVE:
		return TIF_SVE_VL_INHERIT;
	case ARM64_VEC_SME:
		return TIF_SME_VL_INHERIT;
	default:
		WARN_ON_ONCE(1);
		return 0;
	}
}

struct vl_config {
	int __default_vl;		/* Default VL for tasks */
};

static struct vl_config vl_config[ARM64_VEC_MAX];

static inline int get_default_vl(enum vec_type type)
{
	return READ_ONCE(vl_config[type].__default_vl);
}

#ifdef CONFIG_ARM64_SVE

static inline int get_sve_default_vl(void)
{
	return get_default_vl(ARM64_VEC_SVE);
}

static inline void set_default_vl(enum vec_type type, int val)
{
	WRITE_ONCE(vl_config[type].__default_vl, val);
}

static inline void set_sve_default_vl(int val)
{
	set_default_vl(ARM64_VEC_SVE, val);
}

#endif /* ! CONFIG_ARM64_SVE */

#ifdef CONFIG_ARM64_SME

static int get_sme_default_vl(void)
{
	return get_default_vl(ARM64_VEC_SME);
}

static void set_sme_default_vl(int val)
{
	set_default_vl(ARM64_VEC_SME, val);
}

static void sme_free(struct task_struct *);

#else

static inline void sme_free(struct task_struct *t) { }

#endif

static void fpsimd_bind_task_to_cpu(void);

/*
 * Claim ownership of the CPU FPSIMD context for use by the calling context.
 *
 * The caller may freely manipulate the FPSIMD context metadata until
 * put_cpu_fpsimd_context() is called.
 *
 * On RT kernels local_bh_disable() is not sufficient because it only
 * serializes soft interrupt related sections via a local lock, but stays
 * preemptible. Disabling preemption is the right choice here as bottom
 * half processing is always in thread context on RT kernels so it
 * implicitly prevents bottom half processing as well.
 */
static void get_cpu_fpsimd_context(void)
{
	if (!IS_ENABLED(CONFIG_PREEMPT_RT)) {
		/*
		 * The softirq subsystem lacks a true unmask/mask API, and
		 * re-enabling softirq processing using local_bh_enable() will
		 * not only unmask softirqs, it will also result in immediate
		 * delivery of any pending softirqs.
		 * This is undesirable when running with IRQs disabled, but in
		 * that case, there is no need to mask softirqs in the first
		 * place, so only bother doing so when IRQs are enabled.
		 */
		if (!irqs_disabled())
			local_bh_disable();
	} else {
		preempt_disable();
	}
}

/*
 * Release the CPU FPSIMD context.
 *
 * Must be called from a context in which get_cpu_fpsimd_context() was
 * previously called, with no call to put_cpu_fpsimd_context() in the
 * meantime.
 */
static void put_cpu_fpsimd_context(void)
{
	if (!IS_ENABLED(CONFIG_PREEMPT_RT)) {
		if (!irqs_disabled())
			local_bh_enable();
	} else {
		preempt_enable();
	}
}

unsigned int task_get_vl(const struct task_struct *task, enum vec_type type)
{
	return task->thread.vl[type];
}

void task_set_vl(struct task_struct *task, enum vec_type type,
		 unsigned long vl)
{
	task->thread.vl[type] = vl;
}

unsigned int task_get_vl_onexec(const struct task_struct *task,
				enum vec_type type)
{
	return task->thread.vl_onexec[type];
}

void task_set_vl_onexec(struct task_struct *task, enum vec_type type,
			unsigned long vl)
{
	task->thread.vl_onexec[type] = vl;
}

/*
 * TIF_SME controls whether a task can use SME without trapping while
 * in userspace, when TIF_SME is set then we must have storage
 * allocated in sve_state and sme_state to store the contents of both ZA
 * and the SVE registers for both streaming and non-streaming modes.
 *
 * If both SVCR.ZA and SVCR.SM are disabled then at any point we
 * may disable TIF_SME and reenable traps.
 */


/*
 * TIF_SVE controls whether a task can use SVE without trapping while
 * in userspace, and also (together with TIF_SME) the way a task's
 * FPSIMD/SVE state is stored in thread_struct.
 *
 * The kernel uses this flag to track whether a user task is actively
 * using SVE, and therefore whether full SVE register state needs to
 * be tracked.  If not, the cheaper FPSIMD context handling code can
 * be used instead of the more costly SVE equivalents.
 *
 *  * TIF_SVE or SVCR.SM set:
 *
 *    The task can execute SVE instructions while in userspace without
 *    trapping to the kernel.
 *
 *    During any syscall, the kernel may optionally clear TIF_SVE and
 *    discard the vector state except for the FPSIMD subset.
 *
 *  * TIF_SVE clear:
 *
 *    An attempt by the user task to execute an SVE instruction causes
 *    do_sve_acc() to be called, which does some preparation and then
 *    sets TIF_SVE.
 *
 * During any syscall, the kernel may optionally clear TIF_SVE and
 * discard the vector state except for the FPSIMD subset.
 *
 * The data will be stored in one of two formats:
 *
 *  * FPSIMD only - FP_STATE_FPSIMD:
 *
 *    When the FPSIMD only state stored task->thread.fp_type is set to
 *    FP_STATE_FPSIMD, the FPSIMD registers V0-V31 are encoded in
 *    task->thread.uw.fpsimd_state; bits [max : 128] for each of Z0-Z31 are
 *    logically zero but not stored anywhere; P0-P15 and FFR are not
 *    stored and have unspecified values from userspace's point of
 *    view.  For hygiene purposes, the kernel zeroes them on next use,
 *    but userspace is discouraged from relying on this.
 *
 *    task->thread.sve_state does not need to be non-NULL, valid or any
 *    particular size: it must not be dereferenced and any data stored
 *    there should be considered stale and not referenced.
 *
 *  * SVE state - FP_STATE_SVE:
 *
 *    When the full SVE state is stored task->thread.fp_type is set to
 *    FP_STATE_SVE and Z0-Z31 (incorporating Vn in bits[127:0] or the
 *    corresponding Zn), P0-P15 and FFR are encoded in in
 *    task->thread.sve_state, formatted appropriately for vector
 *    length task->thread.sve_vl or, if SVCR.SM is set,
 *    task->thread.sme_vl. The storage for the vector registers in
 *    task->thread.uw.fpsimd_state should be ignored.
 *
 *    task->thread.sve_state must point to a valid buffer at least
 *    sve_state_size(task) bytes in size. The data stored in
 *    task->thread.uw.fpsimd_state.vregs should be considered stale
 *    and not referenced.
 *
 *  * FPSR and FPCR are always stored in task->thread.uw.fpsimd_state
 *    irrespective of whether TIF_SVE is clear or set, since these are
 *    not vector length dependent.
 */

/*
 * Update current's FPSIMD/SVE registers from thread_struct.
 *
 * This function should be called only when the FPSIMD/SVE state in
 * thread_struct is known to be up to date, when preparing to enter
 * userspace.
 */
static void task_fpsimd_load(void)
{
	bool restore_sve_regs = false;
	bool restore_ffr;

	WARN_ON(!system_supports_fpsimd());
	WARN_ON(preemptible());
	WARN_ON(test_thread_flag(TIF_KERNEL_FPSTATE));

	if (system_supports_sve() || system_supports_sme()) {
		switch (current->thread.fp_type) {
		case FP_STATE_FPSIMD:
			/* Stop tracking SVE for this task until next use. */
			clear_thread_flag(TIF_SVE);
			break;
		case FP_STATE_SVE:
			if (!thread_sm_enabled(&current->thread))
				WARN_ON_ONCE(!test_and_set_thread_flag(TIF_SVE));

			if (test_thread_flag(TIF_SVE))
				sve_set_vq(sve_vq_from_vl(task_get_sve_vl(current)) - 1);

			restore_sve_regs = true;
			restore_ffr = true;
			break;
		default:
			/*
			 * This indicates either a bug in
			 * fpsimd_save_user_state() or memory corruption, we
			 * should always record an explicit format
			 * when we save. We always at least have the
			 * memory allocated for FPSIMD registers so
			 * try that and hope for the best.
			 */
			WARN_ON_ONCE(1);
			clear_thread_flag(TIF_SVE);
			break;
		}
	}

	/* Restore SME, override SVE register configuration if needed */
	if (system_supports_sme()) {
		unsigned long sme_vl = task_get_sme_vl(current);

		/* Ensure VL is set up for restoring data */
		if (test_thread_flag(TIF_SME))
			sme_set_vq(sve_vq_from_vl(sme_vl) - 1);

		write_sysreg_s(current->thread.svcr, SYS_SVCR);

		if (thread_za_enabled(&current->thread))
			sme_load_state(current->thread.sme_state,
				       system_supports_sme2());

		if (thread_sm_enabled(&current->thread))
			restore_ffr = system_supports_fa64();
	}

	if (system_supports_fpmr())
		write_sysreg_s(current->thread.uw.fpmr, SYS_FPMR);

	if (restore_sve_regs) {
		WARN_ON_ONCE(current->thread.fp_type != FP_STATE_SVE);
		sve_load_state(sve_pffr(&current->thread),
			       &current->thread.uw.fpsimd_state.fpsr,
			       restore_ffr);
	} else {
		WARN_ON_ONCE(current->thread.fp_type != FP_STATE_FPSIMD);
		fpsimd_load_state(&current->thread.uw.fpsimd_state);
	}
}

/*
 * Ensure FPSIMD/SVE storage in memory for the loaded context is up to
 * date with respect to the CPU registers. Note carefully that the
 * current context is the context last bound to the CPU stored in
 * last, if KVM is involved this may be the guest VM context rather
 * than the host thread for the VM pointed to by current. This means
 * that we must always reference the state storage via last rather
 * than via current, if we are saving KVM state then it will have
 * ensured that the type of registers to save is set in last->to_save.
 */
static void fpsimd_save_user_state(void)
{
	struct cpu_fp_state const *last =
		this_cpu_ptr(&fpsimd_last_state);
	/* set by fpsimd_bind_task_to_cpu() or fpsimd_bind_state_to_cpu() */
	bool save_sve_regs = false;
	bool save_ffr;
	unsigned int vl;

	WARN_ON(!system_supports_fpsimd());
	WARN_ON(preemptible());

	if (test_thread_flag(TIF_FOREIGN_FPSTATE))
		return;

	if (system_supports_fpmr())
		*(last->fpmr) = read_sysreg_s(SYS_FPMR);

	/*
	 * Save SVE state if it is live.
	 *
	 * The syscall ABI discards live SVE state at syscall entry. When
	 * entering a syscall, fpsimd_syscall_enter() sets to_save to
	 * FP_STATE_FPSIMD to allow the SVE state to be lazily discarded until
	 * either new SVE state is loaded+bound or fpsimd_syscall_exit() is
	 * called prior to a return to userspace.
	 */
	if ((last->to_save == FP_STATE_CURRENT && test_thread_flag(TIF_SVE)) ||
	    last->to_save == FP_STATE_SVE) {
		save_sve_regs = true;
		save_ffr = true;
		vl = last->sve_vl;
	}

	if (system_supports_sme()) {
		u64 *svcr = last->svcr;

		*svcr = read_sysreg_s(SYS_SVCR);

		if (*svcr & SVCR_ZA_MASK)
			sme_save_state(last->sme_state,
				       system_supports_sme2());

		/* If we are in streaming mode override regular SVE. */
		if (*svcr & SVCR_SM_MASK) {
			save_sve_regs = true;
			save_ffr = system_supports_fa64();
			vl = last->sme_vl;
		}
	}

	if (IS_ENABLED(CONFIG_ARM64_SVE) && save_sve_regs) {
		/* Get the configured VL from RDVL, will account for SM */
		if (WARN_ON(sve_get_vl() != vl)) {
			/*
			 * Can't save the user regs, so current would
			 * re-enter user with corrupt state.
			 * There's no way to recover, so kill it:
			 */
			force_signal_inject(SIGKILL, SI_KERNEL, 0, 0);
			return;
		}

		sve_save_state((char *)last->sve_state +
					sve_ffr_offset(vl),
			       &last->st->fpsr, save_ffr);
		*last->fp_type = FP_STATE_SVE;
	} else {
		fpsimd_save_state(last->st);
		*last->fp_type = FP_STATE_FPSIMD;
	}
}

/*
 * All vector length selection from userspace comes through here.
 * We're on a slow path, so some sanity-checks are included.
 * If things go wrong there's a bug somewhere, but try to fall back to a
 * safe choice.
 */
static unsigned int find_supported_vector_length(enum vec_type type,
						 unsigned int vl)
{
	struct vl_info *info = &vl_info[type];
	int bit;
	int max_vl = info->max_vl;

	if (WARN_ON(!sve_vl_valid(vl)))
		vl = info->min_vl;

	if (WARN_ON(!sve_vl_valid(max_vl)))
		max_vl = info->min_vl;

	if (vl > max_vl)
		vl = max_vl;
	if (vl < info->min_vl)
		vl = info->min_vl;

	bit = find_next_bit(info->vq_map, SVE_VQ_MAX,
			    __vq_to_bit(sve_vq_from_vl(vl)));
	return sve_vl_from_vq(__bit_to_vq(bit));
}

#if defined(CONFIG_ARM64_SVE) && defined(CONFIG_SYSCTL)

static int vec_proc_do_default_vl(const struct ctl_table *table, int write,
				  void *buffer, size_t *lenp, loff_t *ppos)
{
	struct vl_info *info = table->extra1;
	enum vec_type type = info->type;
	int ret;
	int vl = get_default_vl(type);
	struct ctl_table tmp_table = {
		.data = &vl,
		.maxlen = sizeof(vl),
	};

	ret = proc_dointvec(&tmp_table, write, buffer, lenp, ppos);
	if (ret || !write)
		return ret;

	/* Writing -1 has the special meaning "set to max": */
	if (vl == -1)
		vl = info->max_vl;

	if (!sve_vl_valid(vl))
		return -EINVAL;

	set_default_vl(type, find_supported_vector_length(type, vl));
	return 0;
}

static const struct ctl_table sve_default_vl_table[] = {
	{
		.procname	= "sve_default_vector_length",
		.mode		= 0644,
		.proc_handler	= vec_proc_do_default_vl,
		.extra1		= &vl_info[ARM64_VEC_SVE],
	},
};

static int __init sve_sysctl_init(void)
{
	if (system_supports_sve())
		if (!register_sysctl("abi", sve_default_vl_table))
			return -EINVAL;

	return 0;
}

#else /* ! (CONFIG_ARM64_SVE && CONFIG_SYSCTL) */
static int __init sve_sysctl_init(void) { return 0; }
#endif /* ! (CONFIG_ARM64_SVE && CONFIG_SYSCTL) */

#if defined(CONFIG_ARM64_SME) && defined(CONFIG_SYSCTL)
static const struct ctl_table sme_default_vl_table[] = {
	{
		.procname	= "sme_default_vector_length",
		.mode		= 0644,
		.proc_handler	= vec_proc_do_default_vl,
		.extra1		= &vl_info[ARM64_VEC_SME],
	},
};

static int __init sme_sysctl_init(void)
{
	if (system_supports_sme())
		if (!register_sysctl("abi", sme_default_vl_table))
			return -EINVAL;

	return 0;
}

#else /* ! (CONFIG_ARM64_SME && CONFIG_SYSCTL) */
static int __init sme_sysctl_init(void) { return 0; }
#endif /* ! (CONFIG_ARM64_SME && CONFIG_SYSCTL) */

#define ZREG(sve_state, vq, n) ((char *)(sve_state) +		\
	(SVE_SIG_ZREG_OFFSET(vq, n) - SVE_SIG_REGS_OFFSET))

#ifdef CONFIG_CPU_BIG_ENDIAN
static __uint128_t arm64_cpu_to_le128(__uint128_t x)
{
	u64 a = swab64(x);
	u64 b = swab64(x >> 64);

	return ((__uint128_t)a << 64) | b;
}
#else
static __uint128_t arm64_cpu_to_le128(__uint128_t x)
{
	return x;
}
#endif

#define arm64_le128_to_cpu(x) arm64_cpu_to_le128(x)

static void __fpsimd_to_sve(void *sst, struct user_fpsimd_state const *fst,
			    unsigned int vq)
{
	unsigned int i;
	__uint128_t *p;

	for (i = 0; i < SVE_NUM_ZREGS; ++i) {
		p = (__uint128_t *)ZREG(sst, vq, i);
		*p = arm64_cpu_to_le128(fst->vregs[i]);
	}
}

/*
 * Transfer the FPSIMD state in task->thread.uw.fpsimd_state to
 * task->thread.sve_state.
 *
 * Task can be a non-runnable task, or current.  In the latter case,
 * the caller must have ownership of the cpu FPSIMD context before calling
 * this function.
 * task->thread.sve_state must point to at least sve_state_size(task)
 * bytes of allocated kernel memory.
 * task->thread.uw.fpsimd_state must be up to date before calling this
 * function.
 */
static inline void fpsimd_to_sve(struct task_struct *task)
{
	unsigned int vq;
	void *sst = task->thread.sve_state;
	struct user_fpsimd_state const *fst = &task->thread.uw.fpsimd_state;

	if (!system_supports_sve() && !system_supports_sme())
		return;

	vq = sve_vq_from_vl(thread_get_cur_vl(&task->thread));
	__fpsimd_to_sve(sst, fst, vq);
}

/*
 * Transfer the SVE state in task->thread.sve_state to
 * task->thread.uw.fpsimd_state.
 *
 * Task can be a non-runnable task, or current.  In the latter case,
 * the caller must have ownership of the cpu FPSIMD context before calling
 * this function.
 * task->thread.sve_state must point to at least sve_state_size(task)
 * bytes of allocated kernel memory.
 * task->thread.sve_state must be up to date before calling this function.
 */
static inline void sve_to_fpsimd(struct task_struct *task)
{
	unsigned int vq, vl;
	void const *sst = task->thread.sve_state;
	struct user_fpsimd_state *fst = &task->thread.uw.fpsimd_state;
	unsigned int i;
	__uint128_t const *p;

	if (!system_supports_sve() && !system_supports_sme())
		return;

	vl = thread_get_cur_vl(&task->thread);
	vq = sve_vq_from_vl(vl);
	for (i = 0; i < SVE_NUM_ZREGS; ++i) {
		p = (__uint128_t const *)ZREG(sst, vq, i);
		fst->vregs[i] = arm64_le128_to_cpu(*p);
	}
}

static inline void __fpsimd_zero_vregs(struct user_fpsimd_state *fpsimd)
{
	memset(&fpsimd->vregs, 0, sizeof(fpsimd->vregs));
}

/*
 * Simulate the effects of an SMSTOP SM instruction.
 */
void task_smstop_sm(struct task_struct *task)
{
	if (!thread_sm_enabled(&task->thread))
		return;

	__fpsimd_zero_vregs(&task->thread.uw.fpsimd_state);
	task->thread.uw.fpsimd_state.fpsr = 0x0800009f;
	if (system_supports_fpmr())
		task->thread.uw.fpmr = 0;

	task->thread.svcr &= ~SVCR_SM_MASK;
	task->thread.fp_type = FP_STATE_FPSIMD;
}

void cpu_enable_fpmr(const struct arm64_cpu_capabilities *__always_unused p)
{
	write_sysreg_s(read_sysreg_s(SYS_SCTLR_EL1) | SCTLR_EL1_EnFPM_MASK,
		       SYS_SCTLR_EL1);
}

#ifdef CONFIG_ARM64_SVE
static void sve_free(struct task_struct *task)
{
	kfree(task->thread.sve_state);
	task->thread.sve_state = NULL;
}

/*
 * Ensure that task->thread.sve_state is allocated and sufficiently large.
 *
 * This function should be used only in preparation for replacing
 * task->thread.sve_state with new data.  The memory is always zeroed
 * here to prevent stale data from showing through: this is done in
 * the interest of testability and predictability: except in the
 * do_sve_acc() case, there is no ABI requirement to hide stale data
 * written previously be task.
 */
void sve_alloc(struct task_struct *task, bool flush)
{
	if (task->thread.sve_state) {
		if (flush)
			memset(task->thread.sve_state, 0,
			       sve_state_size(task));
		return;
	}

	/* This is a small allocation (maximum ~8KB) and Should Not Fail. */
	task->thread.sve_state =
		kzalloc(sve_state_size(task), GFP_KERNEL);
}

/*
 * Ensure that task->thread.uw.fpsimd_state is up to date with respect to the
 * task's currently effective FPSIMD/SVE state.
 *
 * The task's FPSIMD/SVE/SME state must not be subject to concurrent
 * manipulation.
 */
void fpsimd_sync_from_effective_state(struct task_struct *task)
{
	if (task->thread.fp_type == FP_STATE_SVE)
		sve_to_fpsimd(task);
}

/*
 * Ensure that the task's currently effective FPSIMD/SVE state is up to date
 * with respect to task->thread.uw.fpsimd_state, zeroing any effective
 * non-FPSIMD (S)SVE state.
 *
 * The task's FPSIMD/SVE/SME state must not be subject to concurrent
 * manipulation.
 */
void fpsimd_sync_to_effective_state_zeropad(struct task_struct *task)
{
	unsigned int vq;
	void *sst = task->thread.sve_state;
	struct user_fpsimd_state const *fst = &task->thread.uw.fpsimd_state;

	if (task->thread.fp_type != FP_STATE_SVE)
		return;

	vq = sve_vq_from_vl(thread_get_cur_vl(&task->thread));

	memset(sst, 0, SVE_SIG_REGS_SIZE(vq));
	__fpsimd_to_sve(sst, fst, vq);
}

static int change_live_vector_length(struct task_struct *task,
				     enum vec_type type,
				     unsigned long vl)
{
	unsigned int sve_vl = task_get_sve_vl(task);
	unsigned int sme_vl = task_get_sme_vl(task);
	void *sve_state = NULL, *sme_state = NULL;

	if (type == ARM64_VEC_SME)
		sme_vl = vl;
	else
		sve_vl = vl;

	/*
	 * Allocate the new sve_state and sme_state before freeing the old
	 * copies so that allocation failure can be handled without needing to
	 * mutate the task's state in any way.
	 *
	 * Changes to the SVE vector length must not discard live ZA state or
	 * clear PSTATE.ZA, as userspace code which is unaware of the AAPCS64
	 * ZA lazy saving scheme may attempt to change the SVE vector length
	 * while unsaved/dormant ZA state exists.
	 */
	sve_state = kzalloc(__sve_state_size(sve_vl, sme_vl), GFP_KERNEL);
	if (!sve_state)
		goto out_mem;

	if (type == ARM64_VEC_SME) {
		sme_state = kzalloc(__sme_state_size(sme_vl), GFP_KERNEL);
		if (!sme_state)
			goto out_mem;
	}

	if (task == current)
		fpsimd_save_and_flush_current_state();
	else
		fpsimd_flush_task_state(task);

	/*
	 * Always preserve PSTATE.SM and the effective FPSIMD state, zeroing
	 * other SVE state.
	 */
	fpsimd_sync_from_effective_state(task);
	task_set_vl(task, type, vl);
	kfree(task->thread.sve_state);
	task->thread.sve_state = sve_state;
	fpsimd_sync_to_effective_state_zeropad(task);

	if (type == ARM64_VEC_SME) {
		task->thread.svcr &= ~SVCR_ZA_MASK;
		kfree(task->thread.sme_state);
		task->thread.sme_state = sme_state;
	}

	return 0;

out_mem:
	kfree(sve_state);
	kfree(sme_state);
	return -ENOMEM;
}

int vec_set_vector_length(struct task_struct *task, enum vec_type type,
			  unsigned long vl, unsigned long flags)
{
	bool onexec = flags & PR_SVE_SET_VL_ONEXEC;
	bool inherit = flags & PR_SVE_VL_INHERIT;

	if (flags & ~(unsigned long)(PR_SVE_VL_INHERIT |
				     PR_SVE_SET_VL_ONEXEC))
		return -EINVAL;

	if (!sve_vl_valid(vl))
		return -EINVAL;

	/*
	 * Clamp to the maximum vector length that VL-agnostic code
	 * can work with.  A flag may be assigned in the future to
	 * allow setting of larger vector lengths without confusing
	 * older software.
	 */
	if (vl > VL_ARCH_MAX)
		vl = VL_ARCH_MAX;

	vl = find_supported_vector_length(type, vl);

	if (!onexec && vl != task_get_vl(task, type)) {
		if (change_live_vector_length(task, type, vl))
			return -ENOMEM;
	}

	if (onexec || inherit)
		task_set_vl_onexec(task, type, vl);
	else
		/* Reset VL to system default on next exec: */
		task_set_vl_onexec(task, type, 0);

	update_tsk_thread_flag(task, vec_vl_inherit_flag(type),
			       flags & PR_SVE_VL_INHERIT);

	return 0;
}

/*
 * Encode the current vector length and flags for return.
 * This is only required for prctl(): ptrace has separate fields.
 * SVE and SME use the same bits for _ONEXEC and _INHERIT.
 *
 * flags are as for vec_set_vector_length().
 */
static int vec_prctl_status(enum vec_type type, unsigned long flags)
{
	int ret;

	if (flags & PR_SVE_SET_VL_ONEXEC)
		ret = task_get_vl_onexec(current, type);
	else
		ret = task_get_vl(current, type);

	if (test_thread_flag(vec_vl_inherit_flag(type)))
		ret |= PR_SVE_VL_INHERIT;

	return ret;
}

/* PR_SVE_SET_VL */
int sve_set_current_vl(unsigned long arg)
{
	unsigned long vl, flags;
	int ret;

	vl = arg & PR_SVE_VL_LEN_MASK;
	flags = arg & ~vl;

	if (!system_supports_sve() || is_compat_task())
		return -EINVAL;

	ret = vec_set_vector_length(current, ARM64_VEC_SVE, vl, flags);
	if (ret)
		return ret;

	return vec_prctl_status(ARM64_VEC_SVE, flags);
}

/* PR_SVE_GET_VL */
int sve_get_current_vl(void)
{
	if (!system_supports_sve() || is_compat_task())
		return -EINVAL;

	return vec_prctl_status(ARM64_VEC_SVE, 0);
}

#ifdef CONFIG_ARM64_SME
/* PR_SME_SET_VL */
int sme_set_current_vl(unsigned long arg)
{
	unsigned long vl, flags;
	int ret;

	vl = arg & PR_SME_VL_LEN_MASK;
	flags = arg & ~vl;

	if (!system_supports_sme() || is_compat_task())
		return -EINVAL;

	ret = vec_set_vector_length(current, ARM64_VEC_SME, vl, flags);
	if (ret)
		return ret;

	return vec_prctl_status(ARM64_VEC_SME, flags);
}

/* PR_SME_GET_VL */
int sme_get_current_vl(void)
{
	if (!system_supports_sme() || is_compat_task())
		return -EINVAL;

	return vec_prctl_status(ARM64_VEC_SME, 0);
}
#endif /* CONFIG_ARM64_SME */

static void vec_probe_vqs(struct vl_info *info,
			  DECLARE_BITMAP(map, SVE_VQ_MAX))
{
	unsigned int vq, vl;

	bitmap_zero(map, SVE_VQ_MAX);

	for (vq = SVE_VQ_MAX; vq >= SVE_VQ_MIN; --vq) {
		write_vl(info->type, vq - 1); /* self-syncing */

		switch (info->type) {
		case ARM64_VEC_SVE:
			vl = sve_get_vl();
			break;
		case ARM64_VEC_SME:
			vl = sme_get_vl();
			break;
		default:
			vl = 0;
			break;
		}

		/* Minimum VL identified? */
		if (sve_vq_from_vl(vl) > vq)
			break;

		vq = sve_vq_from_vl(vl); /* skip intervening lengths */
		set_bit(__vq_to_bit(vq), map);
	}
}

/*
 * Initialise the set of known supported VQs for the boot CPU.
 * This is called during kernel boot, before secondary CPUs are brought up.
 */
void __init vec_init_vq_map(enum vec_type type)
{
	struct vl_info *info = &vl_info[type];
	vec_probe_vqs(info, info->vq_map);
	bitmap_copy(info->vq_partial_map, info->vq_map, SVE_VQ_MAX);
}

/*
 * If we haven't committed to the set of supported VQs yet, filter out
 * those not supported by the current CPU.
 * This function is called during the bring-up of early secondary CPUs only.
 */
void vec_update_vq_map(enum vec_type type)
{
	struct vl_info *info = &vl_info[type];
	DECLARE_BITMAP(tmp_map, SVE_VQ_MAX);

	vec_probe_vqs(info, tmp_map);
	bitmap_and(info->vq_map, info->vq_map, tmp_map, SVE_VQ_MAX);
	bitmap_or(info->vq_partial_map, info->vq_partial_map, tmp_map,
		  SVE_VQ_MAX);
}

/*
 * Check whether the current CPU supports all VQs in the committed set.
 * This function is called during the bring-up of late secondary CPUs only.
 */
int vec_verify_vq_map(enum vec_type type)
{
	struct vl_info *info = &vl_info[type];
	DECLARE_BITMAP(tmp_map, SVE_VQ_MAX);
	unsigned long b;

	vec_probe_vqs(info, tmp_map);

	bitmap_complement(tmp_map, tmp_map, SVE_VQ_MAX);
	if (bitmap_intersects(tmp_map, info->vq_map, SVE_VQ_MAX)) {
		pr_warn("%s: cpu%d: Required vector length(s) missing\n",
			info->name, smp_processor_id());
		return -EINVAL;
	}

	if (!IS_ENABLED(CONFIG_KVM) || !is_hyp_mode_available())
		return 0;

	/*
	 * For KVM, it is necessary to ensure that this CPU doesn't
	 * support any vector length that guests may have probed as
	 * unsupported.
	 */

	/* Recover the set of supported VQs: */
	bitmap_complement(tmp_map, tmp_map, SVE_VQ_MAX);
	/* Find VQs supported that are not globally supported: */
	bitmap_andnot(tmp_map, tmp_map, info->vq_map, SVE_VQ_MAX);

	/* Find the lowest such VQ, if any: */
	b = find_last_bit(tmp_map, SVE_VQ_MAX);
	if (b >= SVE_VQ_MAX)
		return 0; /* no mismatches */

	/*
	 * Mismatches above sve_max_virtualisable_vl are fine, since
	 * no guest is allowed to configure ZCR_EL2.LEN to exceed this:
	 */
	if (sve_vl_from_vq(__bit_to_vq(b)) <= info->max_virtualisable_vl) {
		pr_warn("%s: cpu%d: Unsupported vector length(s) present\n",
			info->name, smp_processor_id());
		return -EINVAL;
	}

	return 0;
}

void cpu_enable_sve(const struct arm64_cpu_capabilities *__always_unused p)
{
	write_sysreg(read_sysreg(CPACR_EL1) | CPACR_EL1_ZEN_EL1EN, CPACR_EL1);
	isb();

	write_sysreg_s(0, SYS_ZCR_EL1);
}

void __init sve_setup(void)
{
	struct vl_info *info = &vl_info[ARM64_VEC_SVE];
	DECLARE_BITMAP(tmp_map, SVE_VQ_MAX);
	unsigned long b;
	int max_bit;

	if (!system_supports_sve())
		return;

	/*
	 * The SVE architecture mandates support for 128-bit vectors,
	 * so sve_vq_map must have at least SVE_VQ_MIN set.
	 * If something went wrong, at least try to patch it up:
	 */
	if (WARN_ON(!test_bit(__vq_to_bit(SVE_VQ_MIN), info->vq_map)))
		set_bit(__vq_to_bit(SVE_VQ_MIN), info->vq_map);

	max_bit = find_first_bit(info->vq_map, SVE_VQ_MAX);
	info->max_vl = sve_vl_from_vq(__bit_to_vq(max_bit));

	/*
	 * For the default VL, pick the maximum supported value <= 64.
	 * VL == 64 is guaranteed not to grow the signal frame.
	 */
	set_sve_default_vl(find_supported_vector_length(ARM64_VEC_SVE, 64));

	bitmap_andnot(tmp_map, info->vq_partial_map, info->vq_map,
		      SVE_VQ_MAX);

	b = find_last_bit(tmp_map, SVE_VQ_MAX);
	if (b >= SVE_VQ_MAX)
		/* No non-virtualisable VLs found */
		info->max_virtualisable_vl = SVE_VQ_MAX;
	else if (WARN_ON(b == SVE_VQ_MAX - 1))
		/* No virtualisable VLs?  This is architecturally forbidden. */
		info->max_virtualisable_vl = SVE_VQ_MIN;
	else /* b + 1 < SVE_VQ_MAX */
		info->max_virtualisable_vl = sve_vl_from_vq(__bit_to_vq(b + 1));

	if (info->max_virtualisable_vl > info->max_vl)
		info->max_virtualisable_vl = info->max_vl;

	pr_info("%s: maximum available vector length %u bytes per vector\n",
		info->name, info->max_vl);
	pr_info("%s: default vector length %u bytes per vector\n",
		info->name, get_sve_default_vl());

	/* KVM decides whether to support mismatched systems. Just warn here: */
	if (sve_max_virtualisable_vl() < sve_max_vl())
		pr_warn("%s: unvirtualisable vector lengths present\n",
			info->name);
}

/*
 * Called from the put_task_struct() path, which cannot get here
 * unless dead_task is really dead and not schedulable.
 */
void fpsimd_release_task(struct task_struct *dead_task)
{
	sve_free(dead_task);
	sme_free(dead_task);
}

#endif /* CONFIG_ARM64_SVE */

#ifdef CONFIG_ARM64_SME

/*
 * Ensure that task->thread.sme_state is allocated and sufficiently large.
 *
 * This function should be used only in preparation for replacing
 * task->thread.sme_state with new data.  The memory is always zeroed
 * here to prevent stale data from showing through: this is done in
 * the interest of testability and predictability, the architecture
 * guarantees that when ZA is enabled it will be zeroed.
 */
void sme_alloc(struct task_struct *task, bool flush)
{
	if (task->thread.sme_state) {
		if (flush)
			memset(task->thread.sme_state, 0,
			       sme_state_size(task));
		return;
	}

	/* This could potentially be up to 64K. */
	task->thread.sme_state =
		kzalloc(sme_state_size(task), GFP_KERNEL);
}

static void sme_free(struct task_struct *task)
{
	kfree(task->thread.sme_state);
	task->thread.sme_state = NULL;
}

void cpu_enable_sme(const struct arm64_cpu_capabilities *__always_unused p)
{
	/* Set priority for all PEs to architecturally defined minimum */
	write_sysreg_s(read_sysreg_s(SYS_SMPRI_EL1) & ~SMPRI_EL1_PRIORITY_MASK,
		       SYS_SMPRI_EL1);

	/* Allow SME in kernel */
	write_sysreg(read_sysreg(CPACR_EL1) | CPACR_EL1_SMEN_EL1EN, CPACR_EL1);
	isb();

	/* Ensure all bits in SMCR are set to known values */
	write_sysreg_s(0, SYS_SMCR_EL1);

	/* Allow EL0 to access TPIDR2 */
	write_sysreg(read_sysreg(SCTLR_EL1) | SCTLR_ELx_ENTP2, SCTLR_EL1);
	isb();
}

void cpu_enable_sme2(const struct arm64_cpu_capabilities *__always_unused p)
{
	/* This must be enabled after SME */
	BUILD_BUG_ON(ARM64_SME2 <= ARM64_SME);

	/* Allow use of ZT0 */
	write_sysreg_s(read_sysreg_s(SYS_SMCR_EL1) | SMCR_ELx_EZT0_MASK,
		       SYS_SMCR_EL1);
}

void cpu_enable_fa64(const struct arm64_cpu_capabilities *__always_unused p)
{
	/* This must be enabled after SME */
	BUILD_BUG_ON(ARM64_SME_FA64 <= ARM64_SME);

	/* Allow use of FA64 */
	write_sysreg_s(read_sysreg_s(SYS_SMCR_EL1) | SMCR_ELx_FA64_MASK,
		       SYS_SMCR_EL1);
}

void __init sme_setup(void)
{
	struct vl_info *info = &vl_info[ARM64_VEC_SME];
	int min_bit, max_bit;

	if (!system_supports_sme())
		return;

	min_bit = find_last_bit(info->vq_map, SVE_VQ_MAX);

	/*
	 * SME doesn't require any particular vector length be
	 * supported but it does require at least one.  We should have
	 * disabled the feature entirely while bringing up CPUs but
	 * let's double check here.  The bitmap is SVE_VQ_MAP sized for
	 * sharing with SVE.
	 */
	WARN_ON(min_bit >= SVE_VQ_MAX);

	info->min_vl = sve_vl_from_vq(__bit_to_vq(min_bit));

	max_bit = find_first_bit(info->vq_map, SVE_VQ_MAX);
	info->max_vl = sve_vl_from_vq(__bit_to_vq(max_bit));

	WARN_ON(info->min_vl > info->max_vl);

	/*
	 * For the default VL, pick the maximum supported value <= 32
	 * (256 bits) if there is one since this is guaranteed not to
	 * grow the signal frame when in streaming mode, otherwise the
	 * minimum available VL will be used.
	 */
	set_sme_default_vl(find_supported_vector_length(ARM64_VEC_SME, 32));

	pr_info("SME: minimum available vector length %u bytes per vector\n",
		info->min_vl);
	pr_info("SME: maximum available vector length %u bytes per vector\n",
		info->max_vl);
	pr_info("SME: default vector length %u bytes per vector\n",
		get_sme_default_vl());
}

void sme_suspend_exit(void)
{
	u64 smcr = 0;

	if (!system_supports_sme())
		return;

	if (system_supports_fa64())
		smcr |= SMCR_ELx_FA64;
	if (system_supports_sme2())
		smcr |= SMCR_ELx_EZT0;

	write_sysreg_s(smcr, SYS_SMCR_EL1);
	write_sysreg_s(0, SYS_SMPRI_EL1);
}

#endif /* CONFIG_ARM64_SME */

static void sve_init_regs(void)
{
	/*
	 * Convert the FPSIMD state to SVE, zeroing all the state that
	 * is not shared with FPSIMD. If (as is likely) the current
	 * state is live in the registers then do this there and
	 * update our metadata for the current task including
	 * disabling the trap, otherwise update our in-memory copy.
	 * We are guaranteed to not be in streaming mode, we can only
	 * take a SVE trap when not in streaming mode and we can't be
	 * in streaming mode when taking a SME trap.
	 */
	if (!test_thread_flag(TIF_FOREIGN_FPSTATE)) {
		unsigned long vq_minus_one =
			sve_vq_from_vl(task_get_sve_vl(current)) - 1;
		sve_set_vq(vq_minus_one);
		sve_flush_live(true, vq_minus_one);
		fpsimd_bind_task_to_cpu();
	} else {
		fpsimd_to_sve(current);
		current->thread.fp_type = FP_STATE_SVE;
		fpsimd_flush_task_state(current);
	}
}

/*
 * Trapped SVE access
 *
 * Storage is allocated for the full SVE state, the current FPSIMD
 * register contents are migrated across, and the access trap is
 * disabled.
 *
 * TIF_SVE should be clear on entry: otherwise, fpsimd_restore_current_state()
 * would have disabled the SVE access trap for userspace during
 * ret_to_user, making an SVE access trap impossible in that case.
 */
void do_sve_acc(unsigned long esr, struct pt_regs *regs)
{
	/* Even if we chose not to use SVE, the hardware could still trap: */
	if (unlikely(!system_supports_sve()) || WARN_ON(is_compat_task())) {
		force_signal_inject(SIGILL, ILL_ILLOPC, regs->pc, 0);
		return;
	}

	sve_alloc(current, true);
	if (!current->thread.sve_state) {
		force_sig(SIGKILL);
		return;
	}

	get_cpu_fpsimd_context();

	if (test_and_set_thread_flag(TIF_SVE))
		WARN_ON(1); /* SVE access shouldn't have trapped */

	/*
	 * Even if the task can have used streaming mode we can only
	 * generate SVE access traps in normal SVE mode and
	 * transitioning out of streaming mode may discard any
	 * streaming mode state.  Always clear the high bits to avoid
	 * any potential errors tracking what is properly initialised.
	 */
	sve_init_regs();

	put_cpu_fpsimd_context();
}

#ifdef CONFIG_ARM64_ERRATUM_4193714

/*
 * SME/CME erratum handling.
 */
static cpumask_t sme_dvmsync_cpus;

/*
 * These helpers are only called from non-preemptible contexts, so
 * smp_processor_id() is safe here.
 */
void sme_set_active(void)
{
	unsigned int cpu = smp_processor_id();

	if (!cpumask_test_cpu(cpu, &sme_dvmsync_cpus))
		return;

	cpumask_set_cpu(cpu, mm_cpumask(current->mm));

	/*
	 * A subsequent (post ERET) SME access may use a stale address
	 * translation. On C1-Pro, a TLBI+DSB on a different CPU will wait for
	 * the completion of cpumask_set_cpu() above as it appears in program
	 * order before the SME access. The post-TLBI+DSB read of mm_cpumask()
	 * will lead to the IPI being issued.
	 *
	 * https://lore.kernel.org/r/ablEXwhfKyJW1i7l@J2N7QTR9R3
	 */
}

void sme_clear_active(void)
{
	unsigned int cpu = smp_processor_id();

	if (!cpumask_test_cpu(cpu, &sme_dvmsync_cpus))
		return;

	/*
	 * With SCTLR_EL1.IESB enabled, the SME memory transactions are
	 * completed on entering EL1.
	 */
	cpumask_clear_cpu(cpu, mm_cpumask(current->mm));
}

static void sme_dvmsync_ipi(void *unused)
{
	/*
	 * With SCTLR_EL1.IESB on, taking an exception is sufficient to ensure
	 * the completion of the SME memory accesses, so no need for an
	 * explicit DSB.
	 */
}

void sme_do_dvmsync(const struct cpumask *mask)
{
	/*
	 * This is called from the TLB maintenance functions after the DSB ISH
	 * to send the hardware DVMSync message. If this CPU sees the mask as
	 * empty, the remote CPU executing sme_set_active() would have seen
	 * the DVMSync and no IPI required.
	 */
	if (cpumask_empty(mask))
		return;

	preempt_disable();
	smp_call_function_many(mask, sme_dvmsync_ipi, NULL, true);
	preempt_enable();
}

void sme_enable_dvmsync(void)
{
	cpumask_set_cpu(smp_processor_id(), &sme_dvmsync_cpus);
}

#endif /* CONFIG_ARM64_ERRATUM_4193714 */

/*
 * Trapped SME access
 *
 * Storage is allocated for the full SVE and SME state, the current
 * FPSIMD register contents are migrated to SVE if SVE is not already
 * active, and the access trap is disabled.
 *
 * TIF_SME should be clear on entry: otherwise, fpsimd_restore_current_state()
 * would have disabled the SME access trap for userspace during
 * ret_to_user, making an SME access trap impossible in that case.
 */
void do_sme_acc(unsigned long esr, struct pt_regs *regs)
{
	/* Even if we chose not to use SME, the hardware could still trap: */
	if (unlikely(!system_supports_sme()) || WARN_ON(is_compat_task())) {
		force_signal_inject(SIGILL, ILL_ILLOPC, regs->pc, 0);
		return;
	}

	/*
	 * If this not a trap due to SME being disabled then something
	 * is being used in the wrong mode, report as SIGILL.
	 */
	if (ESR_ELx_SME_ISS_SMTC(esr) != ESR_ELx_SME_ISS_SMTC_SME_DISABLED) {
		force_signal_inject(SIGILL, ILL_ILLOPC, regs->pc, 0);
		return;
	}

	sve_alloc(current, false);
	sme_alloc(current, true);
	if (!current->thread.sve_state || !current->thread.sme_state) {
		force_sig(SIGKILL);
		return;
	}

	get_cpu_fpsimd_context();

	/* With TIF_SME userspace shouldn't generate any traps */
	if (test_and_set_thread_flag(TIF_SME))
		WARN_ON(1);

	if (!test_thread_flag(TIF_FOREIGN_FPSTATE)) {
		unsigned long vq_minus_one =
			sve_vq_from_vl(task_get_sme_vl(current)) - 1;
		sme_set_vq(vq_minus_one);

		fpsimd_bind_task_to_cpu();
	} else {
		fpsimd_flush_task_state(current);
	}

	put_cpu_fpsimd_context();
}

/*
 * Trapped FP/ASIMD access.
 */
void do_fpsimd_acc(unsigned long esr, struct pt_regs *regs)
{
	/* Even if we chose not to use FPSIMD, the hardware could still trap: */
	if (!system_supports_fpsimd()) {
		force_signal_inject(SIGILL, ILL_ILLOPC, regs->pc, 0);
		return;
	}

	/*
	 * When FPSIMD is enabled, we should never take a trap unless something
	 * has gone very wrong.
	 */
	BUG();
}

/*
 * Raise a SIGFPE for the current process.
 */
void do_fpsimd_exc(unsigned long esr, struct pt_regs *regs)
{
	unsigned int si_code = FPE_FLTUNK;

	if (esr & ESR_ELx_FP_EXC_TFV) {
		if (esr & FPEXC_IOF)
			si_code = FPE_FLTINV;
		else if (esr & FPEXC_DZF)
			si_code = FPE_FLTDIV;
		else if (esr & FPEXC_OFF)
			si_code = FPE_FLTOVF;
		else if (esr & FPEXC_UFF)
			si_code = FPE_FLTUND;
		else if (esr & FPEXC_IXF)
			si_code = FPE_FLTRES;
	}

	send_sig_fault(SIGFPE, si_code,
		       (void __user *)instruction_pointer(regs),
		       current);
}

static void fpsimd_load_kernel_state(struct task_struct *task)
{
	struct cpu_fp_state *last = this_cpu_ptr(&fpsimd_last_state);

	/*
	 * Elide the load if this CPU holds the most recent kernel mode
	 * FPSIMD context of the current task.
	 */
	if (last->st == task->thread.kernel_fpsimd_state &&
	    task->thread.kernel_fpsimd_cpu == smp_processor_id())
		return;

	fpsimd_load_state(task->thread.kernel_fpsimd_state);
}

static void fpsimd_save_kernel_state(struct task_struct *task)
{
	struct cpu_fp_state cpu_fp_state = {
		.st		= task->thread.kernel_fpsimd_state,
		.to_save	= FP_STATE_FPSIMD,
	};

	BUG_ON(!cpu_fp_state.st);

	fpsimd_save_state(task->thread.kernel_fpsimd_state);
	fpsimd_bind_state_to_cpu(&cpu_fp_state);

	task->thread.kernel_fpsimd_cpu = smp_processor_id();
}

/*
 * Invalidate any task's FPSIMD state that is present on this cpu.
 * The FPSIMD context should be acquired with get_cpu_fpsimd_context()
 * before calling this function.
 */
static void fpsimd_flush_cpu_state(void)
{
	WARN_ON(!system_supports_fpsimd());
	__this_cpu_write(fpsimd_last_state.st, NULL);

	/*
	 * Leaving streaming mode enabled will cause issues for any kernel
	 * NEON and leaving streaming mode or ZA enabled may increase power
	 * consumption.
	 */
	if (system_supports_sme())
		sme_smstop();

	set_thread_flag(TIF_FOREIGN_FPSTATE);
}

void fpsimd_thread_switch(struct task_struct *next)
{
	bool wrong_task, wrong_cpu;

	if (!system_supports_fpsimd())
		return;

	WARN_ON_ONCE(!irqs_disabled());

	/* Save unsaved fpsimd state, if any: */
	if (test_thread_flag(TIF_KERNEL_FPSTATE))
		fpsimd_save_kernel_state(current);
	else
		fpsimd_save_user_state();

	if (test_tsk_thread_flag(next, TIF_KERNEL_FPSTATE)) {
		fpsimd_flush_cpu_state();
		fpsimd_load_kernel_state(next);
	} else {
		/*
		 * Fix up TIF_FOREIGN_FPSTATE to correctly describe next's
		 * state.  For kernel threads, FPSIMD registers are never
		 * loaded with user mode FPSIMD state and so wrong_task and
		 * wrong_cpu will always be true.
		 */
		wrong_task = __this_cpu_read(fpsimd_last_state.st) !=
			&next->thread.uw.fpsimd_state;
		wrong_cpu = next->thread.fpsimd_cpu != smp_processor_id();

		update_tsk_thread_flag(next, TIF_FOREIGN_FPSTATE,
				       wrong_task || wrong_cpu);
	}
}

static void fpsimd_flush_thread_vl(enum vec_type type)
{
	int vl, supported_vl;

	/*
	 * Reset the task vector length as required.  This is where we
	 * ensure that all user tasks have a valid vector length
	 * configured: no kernel task can become a user task without
	 * an exec and hence a call to this function.  By the time the
	 * first call to this function is made, all early hardware
	 * probing is complete, so __sve_default_vl should be valid.
	 * If a bug causes this to go wrong, we make some noise and
	 * try to fudge thread.sve_vl to a safe value here.
	 */
	vl = task_get_vl_onexec(current, type);
	if (!vl)
		vl = get_default_vl(type);

	if (WARN_ON(!sve_vl_valid(vl)))
		vl = vl_info[type].min_vl;

	supported_vl = find_supported_vector_length(type, vl);
	if (WARN_ON(supported_vl != vl))
		vl = supported_vl;

	task_set_vl(current, type, vl);

	/*
	 * If the task is not set to inherit, ensure that the vector
	 * length will be reset by a subsequent exec:
	 */
	if (!test_thread_flag(vec_vl_inherit_flag(type)))
		task_set_vl_onexec(current, type, 0);
}

void fpsimd_flush_thread(void)
{
	void *sve_state = NULL;
	void *sme_state = NULL;

	if (!system_supports_fpsimd())
		return;

	get_cpu_fpsimd_context();

	fpsimd_flush_task_state(current);
	memset(&current->thread.uw.fpsimd_state, 0,
	       sizeof(current->thread.uw.fpsimd_state));

	if (system_supports_sve()) {
		clear_thread_flag(TIF_SVE);

		/* Defer kfree() while in atomic context */
		sve_state = current->thread.sve_state;
		current->thread.sve_state = NULL;

		fpsimd_flush_thread_vl(ARM64_VEC_SVE);
	}

	if (system_supports_sme()) {
		clear_thread_flag(TIF_SME);

		/* Defer kfree() while in atomic context */
		sme_state = current->thread.sme_state;
		current->thread.sme_state = NULL;

		fpsimd_flush_thread_vl(ARM64_VEC_SME);
		current->thread.svcr = 0;
	}

	if (system_supports_fpmr())
		current->thread.uw.fpmr = 0;

	current->thread.fp_type = FP_STATE_FPSIMD;

	put_cpu_fpsimd_context();
	kfree(sve_state);
	kfree(sme_state);
}

/*
 * Save the userland FPSIMD state of 'current' to memory, but only if the state
 * currently held in the registers does in fact belong to 'current'
 */
void fpsimd_preserve_current_state(void)
{
	if (!system_supports_fpsimd())
		return;

	get_cpu_fpsimd_context();
	fpsimd_save_user_state();
	put_cpu_fpsimd_context();
}

/*
 * Associate current's FPSIMD context with this cpu
 * The caller must have ownership of the cpu FPSIMD context before calling
 * this function.
 */
static void fpsimd_bind_task_to_cpu(void)
{
	struct cpu_fp_state *last = this_cpu_ptr(&fpsimd_last_state);

	WARN_ON(!system_supports_fpsimd());
	last->st = &current->thread.uw.fpsimd_state;
	last->sve_state = current->thread.sve_state;
	last->sme_state = current->thread.sme_state;
	last->sve_vl = task_get_sve_vl(current);
	last->sme_vl = task_get_sme_vl(current);
	last->svcr = &current->thread.svcr;
	last->fpmr = &current->thread.uw.fpmr;
	last->fp_type = &current->thread.fp_type;
	last->to_save = FP_STATE_CURRENT;
	current->thread.fpsimd_cpu = smp_processor_id();

	/*
	 * Toggle SVE and SME trapping for userspace if needed, these
	 * are serialsied by ret_to_user().
	 */
	if (system_supports_sme()) {
		if (test_thread_flag(TIF_SME))
			sme_user_enable();
		else
			sme_user_disable();
	}

	if (system_supports_sve()) {
		if (test_thread_flag(TIF_SVE))
			sve_user_enable();
		else
			sve_user_disable();
	}
}

void fpsimd_bind_state_to_cpu(struct cpu_fp_state *state)
{
	struct cpu_fp_state *last = this_cpu_ptr(&fpsimd_last_state);

	WARN_ON(!system_supports_fpsimd());
	WARN_ON(!in_softirq() && !irqs_disabled());

	*last = *state;
}

/*
 * Load the userland FPSIMD state of 'current' from memory, but only if the
 * FPSIMD state already held in the registers is /not/ the most recent FPSIMD
 * state of 'current'.  This is called when we are preparing to return to
 * userspace to ensure that userspace sees a good register state.
 */
void fpsimd_restore_current_state(void)
{
	/*
	 * TIF_FOREIGN_FPSTATE is set on the init task and copied by
	 * arch_dup_task_struct() regardless of whether FP/SIMD is detected.
	 * Thus user threads can have this set even when FP/SIMD hasn't been
	 * detected.
	 *
	 * When FP/SIMD is detected, begin_new_exec() will set
	 * TIF_FOREIGN_FPSTATE via flush_thread() -> fpsimd_flush_thread(),
	 * and fpsimd_thread_switch() will set TIF_FOREIGN_FPSTATE when
	 * switching tasks. We detect FP/SIMD before we exec the first user
	 * process, ensuring this has TIF_FOREIGN_FPSTATE set and
	 * do_notify_resume() will call fpsimd_restore_current_state() to
	 * install the user FP/SIMD context.
	 *
	 * When FP/SIMD is not detected, nothing else will clear or set
	 * TIF_FOREIGN_FPSTATE prior to the first return to userspace, and
	 * we must clear TIF_FOREIGN_FPSTATE to avoid do_notify_resume()
	 * looping forever calling fpsimd_restore_current_state().
	 */
	if (!system_supports_fpsimd()) {
		clear_thread_flag(TIF_FOREIGN_FPSTATE);
		return;
	}

	get_cpu_fpsimd_context();

	if (test_and_clear_thread_flag(TIF_FOREIGN_FPSTATE)) {
		task_fpsimd_load();
		fpsimd_bind_task_to_cpu();
	}

	put_cpu_fpsimd_context();
}

void fpsimd_update_current_state(struct user_fpsimd_state const *state)
{
	if (WARN_ON(!system_supports_fpsimd()))
		return;

	current->thread.uw.fpsimd_state = *state;
	if (current->thread.fp_type == FP_STATE_SVE)
		fpsimd_to_sve(current);
}

/*
 * Invalidate live CPU copies of task t's FPSIMD state
 *
 * This function may be called with preemption enabled.  The barrier()
 * ensures that the assignment to fpsimd_cpu is visible to any
 * preemption/softirq that could race with set_tsk_thread_flag(), so
 * that TIF_FOREIGN_FPSTATE cannot be spuriously re-cleared.
 *
 * The final barrier ensures that TIF_FOREIGN_FPSTATE is seen set by any
 * subsequent code.
 */
void fpsimd_flush_task_state(struct task_struct *t)
{
	t->thread.fpsimd_cpu = NR_CPUS;
	t->thread.kernel_fpsimd_state = NULL;
	/*
	 * If we don't support fpsimd, bail out after we have
	 * reset the fpsimd_cpu for this task and clear the
	 * FPSTATE.
	 */
	if (!system_supports_fpsimd())
		return;
	barrier();
	set_tsk_thread_flag(t, TIF_FOREIGN_FPSTATE);

	barrier();
}

void fpsimd_save_and_flush_current_state(void)
{
	if (!system_supports_fpsimd())
		return;

	get_cpu_fpsimd_context();
	fpsimd_save_user_state();
	fpsimd_flush_task_state(current);
	put_cpu_fpsimd_context();
}

/*
 * Save the FPSIMD state to memory and invalidate cpu view.
 * This function must be called with preemption disabled.
 */
void fpsimd_save_and_flush_cpu_state(void)
{
	unsigned long flags;

	if (!system_supports_fpsimd())
		return;
	WARN_ON(preemptible());
	local_irq_save(flags);
	fpsimd_save_user_state();
	fpsimd_flush_cpu_state();
	local_irq_restore(flags);
}

#ifdef CONFIG_KERNEL_MODE_NEON

/*
 * Kernel-side NEON support functions
 */

/*
 * kernel_neon_begin(): obtain the CPU FPSIMD registers for use by the calling
 * context
 *
 * Must not be called unless may_use_simd() returns true.
 * Task context in the FPSIMD registers is saved back to memory as necessary.
 *
 * A matching call to kernel_neon_end() must be made before returning from the
 * calling context.
 *
 * The caller may freely use the FPSIMD registers until kernel_neon_end() is
 * called.
 *
 * Unless called from non-preemptible task context, @state must point to a
 * caller provided buffer that will be used to preserve the task's kernel mode
 * FPSIMD context when it is scheduled out, or if it is interrupted by kernel
 * mode FPSIMD occurring in softirq context. May be %NULL otherwise.
 */
void kernel_neon_begin(struct user_fpsimd_state *state)
{
	if (WARN_ON(!system_supports_fpsimd()))
		return;

	WARN_ON((preemptible() || in_serving_softirq()) && !state);

	BUG_ON(!may_use_simd());

	get_cpu_fpsimd_context();

	/* Save unsaved fpsimd state, if any: */
	if (test_thread_flag(TIF_KERNEL_FPSTATE)) {
		BUG_ON(IS_ENABLED(CONFIG_PREEMPT_RT) || !in_serving_softirq());
		fpsimd_save_state(state);
	} else {
		fpsimd_save_user_state();

		/*
		 * Set the thread flag so that the kernel mode FPSIMD state
		 * will be context switched along with the rest of the task
		 * state.
		 *
		 * On non-PREEMPT_RT, softirqs may interrupt task level kernel
		 * mode FPSIMD, but the task will not be preemptible so setting
		 * TIF_KERNEL_FPSTATE for those would be both wrong (as it
		 * would mark the task context FPSIMD state as requiring a
		 * context switch) and unnecessary.
		 *
		 * On PREEMPT_RT, softirqs are serviced from a separate thread,
		 * which is scheduled as usual, and this guarantees that these
		 * softirqs are not interrupting use of the FPSIMD in kernel
		 * mode in task context. So in this case, setting the flag here
		 * is always appropriate.
		 */
		if (IS_ENABLED(CONFIG_PREEMPT_RT) || !in_serving_softirq()) {
			/*
			 * Record the caller provided buffer as the kernel mode
			 * FP/SIMD buffer for this task, so that the state can
			 * be preserved and restored on a context switch.
			 */
			WARN_ON(current->thread.kernel_fpsimd_state != NULL);
			current->thread.kernel_fpsimd_state = state;
			set_thread_flag(TIF_KERNEL_FPSTATE);
		}
	}

	/* Invalidate any task state remaining in the fpsimd regs: */
	fpsimd_flush_cpu_state();

	put_cpu_fpsimd_context();
}
EXPORT_SYMBOL_GPL(kernel_neon_begin);

/*
 * kernel_neon_end(): give the CPU FPSIMD registers back to the current task
 *
 * Must be called from a context in which kernel_neon_begin() was previously
 * called, with no call to kernel_neon_end() in the meantime.
 *
 * The caller must not use the FPSIMD registers after this function is called,
 * unless kernel_neon_begin() is called again in the meantime.
 *
 * The value of @state must match the value passed to the preceding call to
 * kernel_neon_begin().
 */
void kernel_neon_end(struct user_fpsimd_state *state)
{
	if (!system_supports_fpsimd())
		return;

	if (!test_thread_flag(TIF_KERNEL_FPSTATE))
		return;

	/*
	 * If we are returning from a nested use of kernel mode FPSIMD, restore
	 * the task context kernel mode FPSIMD state. This can only happen when
	 * running in softirq context on non-PREEMPT_RT.
	 */
	if (!IS_ENABLED(CONFIG_PREEMPT_RT) && in_serving_softirq()) {
		fpsimd_load_state(state);
	} else {
		clear_thread_flag(TIF_KERNEL_FPSTATE);
		WARN_ON(current->thread.kernel_fpsimd_state != state);
		current->thread.kernel_fpsimd_state = NULL;
	}
}
EXPORT_SYMBOL_GPL(kernel_neon_end);

#ifdef CONFIG_EFI

static struct user_fpsimd_state efi_fpsimd_state;

/*
 * EFI runtime services support functions
 *
 * The ABI for EFI runtime services allows EFI to use FPSIMD during the call.
 * This means that for EFI (and only for EFI), we have to assume that FPSIMD
 * is always used rather than being an optional accelerator.
 *
 * These functions provide the necessary support for ensuring FPSIMD
 * save/restore in the contexts from which EFI is used.
 *
 * Do not use them for any other purpose -- if tempted to do so, you are
 * either doing something wrong or you need to propose some refactoring.
 */

/*
 * __efi_fpsimd_begin(): prepare FPSIMD for making an EFI runtime services call
 */
void __efi_fpsimd_begin(void)
{
	if (!system_supports_fpsimd())
		return;

	if (may_use_simd()) {
		kernel_neon_begin(&efi_fpsimd_state);
	} else {
		/*
		 * We are running in hardirq or NMI context, and the only
		 * legitimate case where this might happen is when EFI pstore
		 * is attempting to record the system's dying gasps into EFI
		 * variables. This could be due to an oops, a panic or a call
		 * to emergency_restart(), and in none of those cases, we can
		 * expect the current task to ever return to user space again,
		 * or for the kernel to resume any normal execution, for that
		 * matter (an oops in hardirq context triggers a panic too).
		 *
		 * Therefore, there is no point in attempting to preserve any
		 * SVE/SME state here. On the off chance that we might have
		 * ended up here for a different reason inadvertently, kill the
		 * task and preserve/restore the base FP/SIMD state, which
		 * might belong to kernel mode FP/SIMD.
		 */
		pr_warn_ratelimited("Calling EFI runtime from %s context\n",
				    in_nmi() ? "NMI" : "hardirq");
		force_signal_inject(SIGKILL, SI_KERNEL, 0, 0);
		fpsimd_save_state(&efi_fpsimd_state);
	}
}

/*
 * __efi_fpsimd_end(): clean up FPSIMD after an EFI runtime services call
 */
void __efi_fpsimd_end(void)
{
	if (!system_supports_fpsimd())
		return;

	if (may_use_simd()) {
		kernel_neon_end(&efi_fpsimd_state);
	} else {
		fpsimd_load_state(&efi_fpsimd_state);
	}
}

#endif /* CONFIG_EFI */

#endif /* CONFIG_KERNEL_MODE_NEON */

#ifdef CONFIG_CPU_PM
static int fpsimd_cpu_pm_notifier(struct notifier_block *self,
				  unsigned long cmd, void *v)
{
	switch (cmd) {
	case CPU_PM_ENTER:
		fpsimd_save_and_flush_cpu_state();
		break;
	case CPU_PM_EXIT:
		break;
	case CPU_PM_ENTER_FAILED:
	default:
		return NOTIFY_DONE;
	}
	return NOTIFY_OK;
}

static struct notifier_block fpsimd_cpu_pm_notifier_block = {
	.notifier_call = fpsimd_cpu_pm_notifier,
};

static void __init fpsimd_pm_init(void)
{
	cpu_pm_register_notifier(&fpsimd_cpu_pm_notifier_block);
}

#else
static inline void fpsimd_pm_init(void) { }
#endif /* CONFIG_CPU_PM */

#ifdef CONFIG_HOTPLUG_CPU
static int fpsimd_cpu_dead(unsigned int cpu)
{
	per_cpu(fpsimd_last_state.st, cpu) = NULL;
	return 0;
}

static inline void fpsimd_hotplug_init(void)
{
	cpuhp_setup_state_nocalls(CPUHP_ARM64_FPSIMD_DEAD, "arm64/fpsimd:dead",
				  NULL, fpsimd_cpu_dead);
}

#else
static inline void fpsimd_hotplug_init(void) { }
#endif

void cpu_enable_fpsimd(const struct arm64_cpu_capabilities *__always_unused p)
{
	unsigned long enable = CPACR_EL1_FPEN_EL1EN | CPACR_EL1_FPEN_EL0EN;
	write_sysreg(read_sysreg(CPACR_EL1) | enable, CPACR_EL1);
	isb();
}

/*
 * FP/SIMD support code initialisation.
 */
static int __init fpsimd_init(void)
{
	if (cpu_have_named_feature(FP)) {
		fpsimd_pm_init();
		fpsimd_hotplug_init();
	} else {
		pr_notice("Floating-point is not implemented\n");
	}

	if (!cpu_have_named_feature(ASIMD))
		pr_notice("Advanced SIMD is not implemented\n");


	sve_sysctl_init();
	sme_sysctl_init();

	return 0;
}
core_initcall(fpsimd_init);
