MIPS: Remove r2_emul_return from struct thread_info
authorPaul Burton <paul.burton@imgtec.com>
Mon, 17 Oct 2016 14:34:35 +0000 (15:34 +0100)
committerRalf Baechle <ralf@linux-mips.org>
Tue, 3 Jan 2017 15:34:41 +0000 (16:34 +0100)
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>
arch/mips/include/asm/stackframe.h
arch/mips/include/asm/thread_info.h
arch/mips/kernel/asm-offsets.c
arch/mips/kernel/entry.S
arch/mips/kernel/traps.c

index 2f182bdf024f03044ca3ea541adba311f2cafe8a..6c74a804fe983e76c6c390f5fd02b3911bc7602f 100644 (file)
 
                .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
index e309d8fcb5167b40abdca4f07c82d5d97665d1bc..b439e512792ba45c328c40167992e5fa5b365043 100644 (file)
@@ -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
index a7277698d32844a608ed8ac9d74214b87e6b54a3..bb5c5d34ba8152459eb4f9bfeace3e04315b7528 100644 (file)
@@ -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);
index 7791840cf22c0f7c058d32f3abb722eb132f90f8..8d83fc2a96b7196b47367fe8bfb6a39b0f67730e 100644 (file)
@@ -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
index 9ea6959cd5bb652d217521de57b95485549fcd0f..cb479be31a500cec8827cbdfaf5e78da070bd416 100644 (file)
@@ -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;
                }
        }