summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Burton <paul.burton@imgtec.com>2016-10-17 15:34:35 +0100
committerRalf Baechle <ralf@linux-mips.org>2017-01-03 16:34:41 +0100
commite11124d8ffcdf893d64e0b29624fd88e0ae4ceac (patch)
tree7698f9e5e76fd685a8548ba807a6be07592475a7
parentdaa10170da271ed82b34c39a5f10f993569eec79 (diff)
downloadop-kernel-dev-e11124d8ffcdf893d64e0b29624fd88e0ae4ceac.zip
op-kernel-dev-e11124d8ffcdf893d64e0b29624fd88e0ae4ceac.tar.gz
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 7c151d3d5d7a ("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 <paul.burton@imgtec.com> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14408/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r--arch/mips/include/asm/stackframe.h4
-rw-r--r--arch/mips/include/asm/thread_info.h1
-rw-r--r--arch/mips/kernel/asm-offsets.c1
-rw-r--r--arch/mips/kernel/entry.S18
-rw-r--r--arch/mips/kernel/traps.c2
5 files changed, 4 insertions, 22 deletions
diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h
index 2f182bd..6c74a80 100644
--- a/arch/mips/include/asm/stackframe.h
+++ b/arch/mips/include/asm/stackframe.h
@@ -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
diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h
index e309d8f..b439e51 100644
--- a/arch/mips/include/asm/thread_info.h
+++ b/arch/mips/include/asm/thread_info.h
@@ -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
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c
index a727769..bb5c5d3 100644
--- a/arch/mips/kernel/asm-offsets.c
+++ b/arch/mips/kernel/asm-offsets.c
@@ -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);
diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S
index 7791840..8d83fc2 100644
--- a/arch/mips/kernel/entry.S
+++ b/arch/mips/kernel/entry.S
@@ -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
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 9ea6959..cb479be3 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -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;
}
}
OpenPOWER on IntegriCloud