|
@@ -558,27 +558,54 @@ _GLOBAL(ret_from_except_lite)
|
|
|
mtmsrd r10,1 /* Update machine state */
|
|
|
#endif /* CONFIG_PPC_BOOK3E */
|
|
|
|
|
|
-#ifdef CONFIG_PREEMPT
|
|
|
clrrdi r9,r1,THREAD_SHIFT /* current_thread_info() */
|
|
|
- li r0,_TIF_NEED_RESCHED /* bits to check */
|
|
|
ld r3,_MSR(r1)
|
|
|
ld r4,TI_FLAGS(r9)
|
|
|
- /* Move MSR_PR bit in r3 to _TIF_SIGPENDING position in r0 */
|
|
|
- rlwimi r0,r3,32+TIF_SIGPENDING-MSR_PR_LG,_TIF_SIGPENDING
|
|
|
- and. r0,r4,r0 /* check NEED_RESCHED and maybe SIGPENDING */
|
|
|
- bne do_work
|
|
|
-
|
|
|
-#else /* !CONFIG_PREEMPT */
|
|
|
- ld r3,_MSR(r1) /* Returning to user mode? */
|
|
|
andi. r3,r3,MSR_PR
|
|
|
- beq restore /* if not, just restore regs and return */
|
|
|
+ beq resume_kernel
|
|
|
|
|
|
/* Check current_thread_info()->flags */
|
|
|
+ andi. r0,r4,_TIF_USER_WORK_MASK
|
|
|
+ beq restore
|
|
|
+
|
|
|
+ andi. r0,r4,_TIF_NEED_RESCHED
|
|
|
+ beq 1f
|
|
|
+ bl .restore_interrupts
|
|
|
+ bl .schedule
|
|
|
+ b .ret_from_except_lite
|
|
|
+
|
|
|
+1: bl .save_nvgprs
|
|
|
+ bl .restore_interrupts
|
|
|
+ addi r3,r1,STACK_FRAME_OVERHEAD
|
|
|
+ bl .do_notify_resume
|
|
|
+ b .ret_from_except
|
|
|
+
|
|
|
+resume_kernel:
|
|
|
+#ifdef CONFIG_PREEMPT
|
|
|
+ /* Check if we need to preempt */
|
|
|
+ andi. r0,r4,_TIF_NEED_RESCHED
|
|
|
+ beq+ restore
|
|
|
+ /* Check that preempt_count() == 0 and interrupts are enabled */
|
|
|
+ lwz r8,TI_PREEMPT(r9)
|
|
|
+ cmpwi cr1,r8,0
|
|
|
+ ld r0,SOFTE(r1)
|
|
|
+ cmpdi r0,0
|
|
|
+ crandc eq,cr1*4+eq,eq
|
|
|
+ bne restore
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Here we are preempting the current task. We want to make
|
|
|
+ * sure we are soft-disabled first
|
|
|
+ */
|
|
|
+ SOFT_DISABLE_INTS(r3,r4)
|
|
|
+1: bl .preempt_schedule_irq
|
|
|
+
|
|
|
+ /* Re-test flags and eventually loop */
|
|
|
clrrdi r9,r1,THREAD_SHIFT
|
|
|
ld r4,TI_FLAGS(r9)
|
|
|
- andi. r0,r4,_TIF_USER_WORK_MASK
|
|
|
- bne do_work
|
|
|
-#endif /* !CONFIG_PREEMPT */
|
|
|
+ andi. r0,r4,_TIF_NEED_RESCHED
|
|
|
+ bne 1b
|
|
|
+#endif /* CONFIG_PREEMPT */
|
|
|
|
|
|
.globl fast_exc_return_irq
|
|
|
fast_exc_return_irq:
|
|
@@ -759,50 +786,6 @@ restore_check_irq_replay:
|
|
|
#endif /* CONFIG_PPC_BOOK3E */
|
|
|
1: b .ret_from_except /* What else to do here ? */
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-3:
|
|
|
-do_work:
|
|
|
-#ifdef CONFIG_PREEMPT
|
|
|
- andi. r0,r3,MSR_PR /* Returning to user mode? */
|
|
|
- bne user_work
|
|
|
- /* Check that preempt_count() == 0 and interrupts are enabled */
|
|
|
- lwz r8,TI_PREEMPT(r9)
|
|
|
- cmpwi cr1,r8,0
|
|
|
- ld r0,SOFTE(r1)
|
|
|
- cmpdi r0,0
|
|
|
- crandc eq,cr1*4+eq,eq
|
|
|
- bne restore
|
|
|
-
|
|
|
- /*
|
|
|
- * Here we are preempting the current task. We want to make
|
|
|
- * sure we are soft-disabled first
|
|
|
- */
|
|
|
- SOFT_DISABLE_INTS(r3,r4)
|
|
|
-1: bl .preempt_schedule_irq
|
|
|
-
|
|
|
- /* Re-test flags and eventually loop */
|
|
|
- clrrdi r9,r1,THREAD_SHIFT
|
|
|
- ld r4,TI_FLAGS(r9)
|
|
|
- andi. r0,r4,_TIF_NEED_RESCHED
|
|
|
- bne 1b
|
|
|
- b restore
|
|
|
-
|
|
|
-user_work:
|
|
|
-#endif /* CONFIG_PREEMPT */
|
|
|
-
|
|
|
- andi. r0,r4,_TIF_NEED_RESCHED
|
|
|
- beq 1f
|
|
|
- bl .restore_interrupts
|
|
|
- bl .schedule
|
|
|
- b .ret_from_except_lite
|
|
|
-
|
|
|
-1: bl .save_nvgprs
|
|
|
- bl .restore_interrupts
|
|
|
- addi r3,r1,STACK_FRAME_OVERHEAD
|
|
|
- bl .do_notify_resume
|
|
|
- b .ret_from_except
|
|
|
-
|
|
|
unrecov_restore:
|
|
|
addi r3,r1,STACK_FRAME_OVERHEAD
|
|
|
bl .unrecoverable_exception
|