// 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)) {
				unsigned long vq = sve_vq_from_vl(task_get_sve_vl(current));
				sysreg_clear_set_s(SYS_ZCR_EL1, ZCR_ELx_LEN, vq - 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)) {
			unsigned long vq = sve_vq_from_vl(sme_vl);
			sysreg_clear_set_s(SYS_SMCR_EL1, SMCR_ELx_LEN, vq - 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(current->thread.sve_state, restore_ffr);
		fpsimd_load_common(&current->thread.uw.fpsimd_state);
	} 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(last->sve_state, save_ffr);
		fpsimd_save_common(last->st);
		*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(struct arm64_sve_state *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;
	struct arm64_sve_state *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;
	const struct arm64_sve_state *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;
	struct arm64_sve_state *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);
	struct arm64_sve_state *sve_state = NULL;
	struct arm64_sme_state *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 */

/*
 * 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 */

	/*
	 * Convert the FPSIMD state to SVE. Stale SVE state can be present in
	 * registers or memory, so we must zero all state that is not shared
	 * with FPSIMD.
	 *
	 * SVE traps cannot be taken from streaming mode, so there cannot be
	 * any effective streaming mode SVE state.
	 */
	if (!test_thread_flag(TIF_FOREIGN_FPSTATE)) {
		unsigned long vq = sve_vq_from_vl(task_get_sve_vl(current));
		sysreg_clear_set_s(SYS_ZCR_EL1, ZCR_ELx_LEN, vq - 1);
		sve_flush_live();
		fpsimd_bind_task_to_cpu();
	} else {
		fpsimd_to_sve(current);
		current->thread.fp_type = FP_STATE_SVE;
		fpsimd_flush_task_state(current);
	}

	put_cpu_fpsimd_context();
}

#ifdef CONFIG_ARM64_ERRATUM_4193714

/*
 * SME/CME erratum handling.
 */
static cpumask_t sme_dvmsync_cpus;
cpumask_t sme_active_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));
	cpumask_set_cpu(cpu, &sme_active_cpus);

	/*
	 * 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 the cpumask_set_cpu() operations above as they
	 * appear in program order before the SME access. The post-TLBI+DSB
	 * read of mm_cpumask() or sme_active_cpus 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));
	cpumask_clear_cpu(cpu, &sme_active_cpus);
}

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 = sve_vq_from_vl(task_get_sme_vl(current));
		sysreg_clear_set_s(SYS_SMCR_EL1, SMCR_ELx_LEN, vq - 1);

		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)
{
	struct arm64_sve_state *sve_state = NULL;
	struct arm64_sme_state *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);
