Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 762a1f43 authored by Paul Burton's avatar Paul Burton Committed by Ralf Baechle
Browse files

MIPS: disable preemption whilst initialising MSA



Preemption must be disabled throughout the process of enabling the FPU,
enabling MSA & initialising the vector registers. Without doing so it
is possible to lose the FPU or MSA whilst initialising them causing
that initialisation to fail.

Signed-off-by: default avatarPaul Burton <paul.burton@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/7307/


Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 3587ea88
Loading
Loading
Loading
Loading
+0 −4
Original line number Diff line number Diff line
@@ -164,8 +164,6 @@ static inline int init_fpu(void)
{
	int ret = 0;

	preempt_disable();

	if (cpu_has_fpu) {
		ret = __own_fpu();
		if (!ret)
@@ -173,8 +171,6 @@ static inline int init_fpu(void)
	} else
		fpu_emulator_init_fpu();

	preempt_enable();

	return ret;
}

+11 −3
Original line number Diff line number Diff line
@@ -1093,6 +1093,7 @@ static int enable_restore_fp_context(int msa)

	if (!used_math()) {
		/* First time FP context user. */
		preempt_disable();
		err = init_fpu();
		if (msa && !err) {
			enable_msa();
@@ -1100,6 +1101,7 @@ static int enable_restore_fp_context(int msa)
			set_thread_flag(TIF_USEDMSA);
			set_thread_flag(TIF_MSA_CTX_LIVE);
		}
		preempt_enable();
		if (!err)
			set_used_math();
		return err;
@@ -1139,10 +1141,11 @@ static int enable_restore_fp_context(int msa)
	 * This task is using or has previously used MSA. Thus we require
	 * that Status.FR == 1.
	 */
	preempt_disable();
	was_fpu_owner = is_fpu_owner();
	err = own_fpu(0);
	err = own_fpu_inatomic(0);
	if (err)
		return err;
		goto out;

	enable_msa();
	write_msa_csr(current->thread.fpu.msacsr);
@@ -1158,7 +1161,8 @@ static int enable_restore_fp_context(int msa)
	prior_msa = test_and_set_thread_flag(TIF_MSA_CTX_LIVE);
	if (!prior_msa && was_fpu_owner) {
		_init_msa_upper();
		return 0;

		goto out;
	}

	if (!prior_msa) {
@@ -1182,6 +1186,10 @@ static int enable_restore_fp_context(int msa)
		if (!was_fpu_owner)
			asm volatile("ctc1 %0, $31" : : "r"(current->thread.fpu.fcr31));
	}

out:
	preempt_enable();

	return 0;
}