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

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

MIPS: Remove r2_emul_return from struct thread_info



The r2_emul_return field in struct thread_info was used in order to take
an alternate codepath when returning to userland, which (besides not
implementing certain features) effectively used the eretnc instruction
in place of eret. The difference is that eretnc doesn't clear LLBit, and
therefore doesn't cause a linked load & store sequence to fail due to
emulation like eret would.

The reason eret would usually be used to clear LLBit is so that after
context switching we ensure that a load performed by one task doesn't
influence another task. However commit 7c151d3d ("MIPS: Make use of
the ERETNC instruction on MIPS R6") which introduced the r2_emul_return
field and conditional use of eretnc also for some reason began
explicitly clearing LLBit during context switches - despite retaining
the use of eret for everything but returns from the pre-r6 instruction
emulation code.

As LLBit is cleared upon context switches anyway, simplify this by using
eretnc unconditionally for MIPSr6 kernels. This allows us to remove the
4 byte r2_emul_return boolean from struct thread_info, simplify the
return to user code in entry.S and avoid the overhead of tracking &
checking state which we don't need.

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


Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent daa10170
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -364,9 +364,13 @@

		.macro	RESTORE_SP_AND_RET
		LONG_L	sp, PT_R29(sp)
#ifdef CONFIG_CPU_MIPSR6
		eretnc
#else
		.set	arch=r4000
		eret
		.set	mips0
#endif
		.endm

#endif
+0 −1
Original line number Diff line number Diff line
@@ -27,7 +27,6 @@ struct thread_info {
	unsigned long		tp_value;	/* thread pointer */
	__u32			cpu;		/* current CPU */
	int			preempt_count;	/* 0 => preemptable, <0 => BUG */
	int			r2_emul_return; /* 1 => Returning from R2 emulator */
	mm_segment_t		addr_limit;	/*
						 * thread address space limit:
						 * 0x7fffffff for user-thead
+0 −1
Original line number Diff line number Diff line
@@ -97,7 +97,6 @@ void output_thread_info_defines(void)
	OFFSET(TI_TP_VALUE, thread_info, tp_value);
	OFFSET(TI_CPU, thread_info, cpu);
	OFFSET(TI_PRE_COUNT, thread_info, preempt_count);
	OFFSET(TI_R2_EMUL_RET, thread_info, r2_emul_return);
	OFFSET(TI_ADDR_LIMIT, thread_info, addr_limit);
	OFFSET(TI_REGS, thread_info, regs);
	DEFINE(_THREAD_SIZE, THREAD_SIZE);
+0 −18
Original line number Diff line number Diff line
@@ -47,11 +47,6 @@ resume_userspace:
	local_irq_disable		# make sure we dont miss an
					# interrupt setting need_resched
					# between sampling and return
#ifdef CONFIG_MIPSR2_TO_R6_EMULATOR
	lw	k0, TI_R2_EMUL_RET($28)
	bnez	k0, restore_all_from_r2_emul
#endif

	LONG_L	a2, TI_FLAGS($28)	# current->work
	andi	t0, a2, _TIF_WORK_MASK	# (ignoring syscall_trace)
	bnez	t0, work_pending
@@ -120,19 +115,6 @@ restore_partial: # restore partial frame
	RESTORE_SP_AND_RET
	.set	at

#ifdef CONFIG_MIPSR2_TO_R6_EMULATOR
restore_all_from_r2_emul:			# restore full frame
	.set	noat
	sw	zero, TI_R2_EMUL_RET($28)	# reset it
	RESTORE_TEMP
	RESTORE_AT
	RESTORE_STATIC
	RESTORE_SOME
	LONG_L	sp, PT_R29(sp)
	eretnc
	.set	at
#endif

work_pending:
	andi	t0, a2, _TIF_NEED_RESCHED # a2 is preloaded with TI_FLAGS
	beqz	t0, work_notifysig
+0 −2
Original line number Diff line number Diff line
@@ -1108,7 +1108,6 @@ asmlinkage void do_ri(struct pt_regs *regs)
		switch (status) {
		case 0:
		case SIGEMT:
			task_thread_info(current)->r2_emul_return = 1;
			return;
		case SIGILL:
			goto no_r2_instr;
@@ -1116,7 +1115,6 @@ asmlinkage void do_ri(struct pt_regs *regs)
			process_fpemu_return(status,
					     &current->thread.cp0_baduaddr,
					     fcr31);
			task_thread_info(current)->r2_emul_return = 1;
			return;
		}
	}