Skip to content

Commit

Permalink
MIPS: Remove r2_emul_return from struct thread_info
Browse files Browse the repository at this point in the history
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 7c151d3 ("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: Paul Burton <[email protected]>
Cc: [email protected]
Patchwork: https://patchwork.linux-mips.org/patch/14408/
Signed-off-by: Ralf Baechle <[email protected]>
  • Loading branch information
paulburton authored and ralfbaechle committed Jan 3, 2017
1 parent daa1017 commit e11124d
Show file tree
Hide file tree
Showing 5 changed files with 4 additions and 22 deletions.
4 changes: 4 additions & 0 deletions arch/mips/include/asm/stackframe.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 0 additions & 1 deletion arch/mips/include/asm/thread_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 0 additions & 1 deletion arch/mips/kernel/asm-offsets.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
18 changes: 0 additions & 18 deletions arch/mips/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
2 changes: 0 additions & 2 deletions arch/mips/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -1108,15 +1108,13 @@ 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;
default:
process_fpemu_return(status,
&current->thread.cp0_baduaddr,
fcr31);
task_thread_info(current)->r2_emul_return = 1;
return;
}
}
Expand Down

0 comments on commit e11124d

Please sign in to comment.