diff options
Diffstat (limited to 'arch/tile/kernel/intvec_64.S')
-rw-r--r-- | arch/tile/kernel/intvec_64.S | 56 |
1 files changed, 20 insertions, 36 deletions
diff --git a/arch/tile/kernel/intvec_64.S b/arch/tile/kernel/intvec_64.S index 58964d209d4d..3b51bdf37d11 100644 --- a/arch/tile/kernel/intvec_64.S +++ b/arch/tile/kernel/intvec_64.S @@ -658,7 +658,7 @@ intvec_\vecname: */ mfspr r32, SPR_EX_CONTEXT_K_1 { - IS_KERNEL_EX1(r22, r22) + IS_KERNEL_EX1(r32, r32) PTREGS_PTR(r21, PTREGS_OFFSET_FLAGS) } beqzt r32, 1f /* zero if from user space */ @@ -753,7 +753,7 @@ intvec_\vecname: } wh64 r52 -#ifdef CONFIG_TRACE_IRQFLAGS +#if defined(CONFIG_TRACE_IRQFLAGS) || defined(CONFIG_CONTEXT_TRACKING) .ifnc \function,handle_nmi /* * We finally have enough state set up to notify the irq @@ -769,6 +769,9 @@ intvec_\vecname: { move r32, r2; move r33, r3 } .endif TRACE_IRQS_OFF +#ifdef CONFIG_CONTEXT_TRACKING + jal context_tracking_user_exit +#endif .ifnc \function,handle_syscall { move r0, r30; move r1, r31 } { move r2, r32; move r3, r33 } @@ -879,20 +882,6 @@ STD_ENTRY(interrupt_return) FEEDBACK_REENTER(interrupt_return) /* - * Use r33 to hold whether we have already loaded the callee-saves - * into ptregs. We don't want to do it twice in this loop, since - * then we'd clobber whatever changes are made by ptrace, etc. - */ - { - movei r33, 0 - move r32, sp - } - - /* Get base of stack in r32. */ - EXTRACT_THREAD_INFO(r32) - -.Lretry_work_pending: - /* * Disable interrupts so as to make sure we don't * miss an interrupt that sets any of the thread flags (like * need_resched or sigpending) between sampling and the iret. @@ -902,33 +891,28 @@ STD_ENTRY(interrupt_return) IRQ_DISABLE(r20, r21) TRACE_IRQS_OFF /* Note: clobbers registers r0-r29 */ - - /* Check to see if there is any work to do before returning to user. */ + /* + * See if there are any work items (including single-shot items) + * to do. If so, save the callee-save registers to pt_regs + * and then dispatch to C code. + */ + move r21, sp + EXTRACT_THREAD_INFO(r21) { - addi r29, r32, THREAD_INFO_FLAGS_OFFSET - moveli r1, hw1_last(_TIF_ALLWORK_MASK) + addi r22, r21, THREAD_INFO_FLAGS_OFFSET + moveli r20, hw1_last(_TIF_ALLWORK_MASK) } { - ld r29, r29 - shl16insli r1, r1, hw0(_TIF_ALLWORK_MASK) + ld r22, r22 + shl16insli r20, r20, hw0(_TIF_ALLWORK_MASK) } - and r1, r29, r1 - beqzt r1, .Lrestore_all - - /* - * Make sure we have all the registers saved for signal - * handling or notify-resume. Call out to C code to figure out - * exactly what we need to do for each flag bit, then if - * necessary, reload the flags and recheck. - */ + and r1, r22, r20 { PTREGS_PTR(r0, PTREGS_OFFSET_BASE) - bnez r33, 1f + beqzt r1, .Lrestore_all } push_extra_callee_saves r0 - movei r33, 1 -1: jal do_work_pending - bnez r0, .Lretry_work_pending + jal prepare_exit_to_usermode /* * In the NMI case we @@ -1411,7 +1395,7 @@ STD_ENTRY(ret_from_kernel_thread) FEEDBACK_REENTER(ret_from_kernel_thread) { movei r30, 0 /* not an NMI */ - j .Lresume_userspace /* jump into middle of interrupt_return */ + j interrupt_return } STD_ENDPROC(ret_from_kernel_thread) |