Commit ce514000 authored by Mark Brown's avatar Mark Brown Committed by Catalin Marinas
Browse files

arm64/sme: Rename za_state to sme_state



In preparation for adding support for storage for ZT0 to the thread_struct
rename za_state to sme_state. Since ZT0 is accessible when PSTATE.ZA is
set just like ZA itself we will extend the allocation done for ZA to
cover it, avoiding the need to further expand task_struct for non-SME
tasks.

No functional changes.

Signed-off-by: default avatarMark Brown <broonie@kernel.org>
Link: https://lore.kernel.org/r/20221208-arm64-sme2-v4-1-f2fa0aef982f@kernel.org


Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent b7bfaa76
Loading
Loading
Loading
Loading
+9 −6
Original line number Diff line number Diff line
@@ -61,7 +61,7 @@ extern void fpsimd_kvm_prepare(void);
struct cpu_fp_state {
	struct user_fpsimd_state *st;
	void *sve_state;
	void *za_state;
	void *sme_state;
	u64 *svcr;
	unsigned int sve_vl;
	unsigned int sme_vl;
@@ -355,14 +355,17 @@ extern int sme_get_current_vl(void);

/*
 * Return how many bytes of memory are required to store the full SME
 * specific state (currently just ZA) for task, given task's currently
 * configured vector length.
 * specific state for task, given task's currently configured vector
 * length.
 */
static inline size_t za_state_size(struct task_struct const *task)
static inline size_t sme_state_size(struct task_struct const *task)
{
	unsigned int vl = task_get_sme_vl(task);
	size_t size;

	return ZA_SIG_REGS_SIZE(sve_vq_from_vl(vl));
	size = ZA_SIG_REGS_SIZE(sve_vq_from_vl(vl));

	return size;
}

#else
@@ -382,7 +385,7 @@ static inline int sme_max_virtualisable_vl(void) { return 0; }
static inline int sme_set_current_vl(unsigned long arg) { return -EINVAL; }
static inline int sme_get_current_vl(void) { return -EINVAL; }

static inline size_t za_state_size(struct task_struct const *task)
static inline size_t sme_state_size(struct task_struct const *task)
{
	return 0;
}
+1 −1
Original line number Diff line number Diff line
@@ -161,7 +161,7 @@ struct thread_struct {
	enum fp_type		fp_type;	/* registers FPSIMD or SVE? */
	unsigned int		fpsimd_cpu;
	void			*sve_state;	/* SVE registers, if any */
	void			*za_state;	/* ZA register, if any */
	void			*sme_state;	/* ZA and ZT state, if any */
	unsigned int		vl[ARM64_VEC_MAX];	/* vector length */
	unsigned int		vl_onexec[ARM64_VEC_MAX]; /* vl after next exec */
	unsigned long		fault_address;	/* fault info */
+17 −17
Original line number Diff line number Diff line
@@ -299,7 +299,7 @@ void task_set_vl_onexec(struct task_struct *task, enum vec_type type,
/*
 * TIF_SME controls whether a task can use SME without trapping while
 * in userspace, when TIF_SME is set then we must have storage
 * alocated in sve_state and za_state to store the contents of both ZA
 * alocated 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
@@ -429,7 +429,7 @@ static void task_fpsimd_load(void)
		write_sysreg_s(current->thread.svcr, SYS_SVCR);

		if (thread_za_enabled(&current->thread))
			za_load_state(current->thread.za_state);
			za_load_state(current->thread.sme_state);

		if (thread_sm_enabled(&current->thread))
			restore_ffr = system_supports_fa64();
@@ -490,7 +490,7 @@ static void fpsimd_save(void)
		*svcr = read_sysreg_s(SYS_SVCR);

		if (*svcr & SVCR_ZA_MASK)
			za_save_state(last->za_state);
			za_save_state(last->sme_state);

		/* If we are in streaming mode override regular SVE. */
		if (*svcr & SVCR_SM_MASK) {
@@ -1257,30 +1257,30 @@ void fpsimd_release_task(struct task_struct *dead_task)
#ifdef CONFIG_ARM64_SME

/*
 * Ensure that task->thread.za_state is allocated and sufficiently large.
 * Ensure that task->thread.sme_state is allocated and sufficiently large.
 *
 * This function should be used only in preparation for replacing
 * task->thread.za_state with new data.  The memory is always zeroed
 * 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)
{
	if (task->thread.za_state) {
		memset(task->thread.za_state, 0, za_state_size(task));
	if (task->thread.sme_state) {
		memset(task->thread.sme_state, 0, sme_state_size(task));
		return;
	}

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

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

void sme_kernel_enable(const struct arm64_cpu_capabilities *__always_unused p)
@@ -1488,7 +1488,7 @@ void do_sme_acc(unsigned long esr, struct pt_regs *regs)

	sve_alloc(current, false);
	sme_alloc(current);
	if (!current->thread.sve_state || !current->thread.za_state) {
	if (!current->thread.sve_state || !current->thread.sme_state) {
		force_sig(SIGKILL);
		return;
	}
@@ -1609,7 +1609,7 @@ static void fpsimd_flush_thread_vl(enum vec_type type)
void fpsimd_flush_thread(void)
{
	void *sve_state = NULL;
	void *za_state = NULL;
	void *sme_state = NULL;

	if (!system_supports_fpsimd())
		return;
@@ -1634,8 +1634,8 @@ void fpsimd_flush_thread(void)
		clear_thread_flag(TIF_SME);

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

		fpsimd_flush_thread_vl(ARM64_VEC_SME);
		current->thread.svcr = 0;
@@ -1645,7 +1645,7 @@ void fpsimd_flush_thread(void)

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

/*
@@ -1711,7 +1711,7 @@ static void fpsimd_bind_task_to_cpu(void)
	WARN_ON(!system_supports_fpsimd());
	last->st = &current->thread.uw.fpsimd_state;
	last->sve_state = current->thread.sve_state;
	last->za_state = current->thread.za_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;
+7 −6
Original line number Diff line number Diff line
@@ -311,23 +311,24 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
	 * This may be shortly freed if we exec() or if CLONE_SETTLS
	 * but it's simpler to do it here. To avoid confusing the rest
	 * of the code ensure that we have a sve_state allocated
	 * whenever za_state is allocated.
	 * whenever sme_state is allocated.
	 */
	if (thread_za_enabled(&src->thread)) {
		dst->thread.sve_state = kzalloc(sve_state_size(src),
						GFP_KERNEL);
		if (!dst->thread.sve_state)
			return -ENOMEM;
		dst->thread.za_state = kmemdup(src->thread.za_state,
					       za_state_size(src),

		dst->thread.sme_state = kmemdup(src->thread.sme_state,
						sme_state_size(src),
						GFP_KERNEL);
		if (!dst->thread.za_state) {
		if (!dst->thread.sme_state) {
			kfree(dst->thread.sve_state);
			dst->thread.sve_state = NULL;
			return -ENOMEM;
		}
	} else {
		dst->thread.za_state = NULL;
		dst->thread.sme_state = NULL;
		clear_tsk_thread_flag(dst, TIF_SME);
	}

+3 −3
Original line number Diff line number Diff line
@@ -1045,7 +1045,7 @@ static int za_get(struct task_struct *target,
	if (thread_za_enabled(&target->thread)) {
		start = end;
		end = ZA_PT_SIZE(vq);
		membuf_write(&to, target->thread.za_state, end - start);
		membuf_write(&to, target->thread.sme_state, end - start);
	}

	/* Zero any trailing padding */
@@ -1099,7 +1099,7 @@ static int za_set(struct task_struct *target,

	/* Allocate/reinit ZA storage */
	sme_alloc(target);
	if (!target->thread.za_state) {
	if (!target->thread.sme_state) {
		ret = -ENOMEM;
		goto out;
	}
@@ -1124,7 +1124,7 @@ static int za_set(struct task_struct *target,
	start = ZA_PT_ZA_OFFSET;
	end = ZA_PT_SIZE(vq);
	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
				 target->thread.za_state,
				 target->thread.sme_state,
				 start, end);
	if (ret)
		goto out;
Loading