aboutsummaryrefslogtreecommitdiff
path: root/arch/powerpc/kernel/entry_64.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/entry_64.S')
-rw-r--r--arch/powerpc/kernel/entry_64.S48
1 files changed, 28 insertions, 20 deletions
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 38847767012d..3f53a9a7bce5 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -1,5 +1,5 @@
/*
- * PowerPC version
+ * PowerPC version
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
* Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
* Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
@@ -239,12 +239,12 @@ END_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
RFI
b . /* prevent speculative execution */
-syscall_error:
+syscall_error:
oris r5,r5,0x1000 /* Set SO bit in CR */
neg r3,r3
std r5,_CCR(r1)
b .Lsyscall_error_cont
-
+
/* Traced system call support */
syscall_dotrace:
bl .save_nvgprs
@@ -270,7 +270,7 @@ syscall_dotrace:
syscall_enosys:
li r3,-ENOSYS
b syscall_exit
-
+
syscall_exit_work:
#ifdef CONFIG_PPC_BOOK3S
mtmsrd r10,1 /* Restore RI */
@@ -333,7 +333,7 @@ _GLOBAL(save_nvgprs)
std r0,_TRAP(r1)
blr
-
+
/*
* The sigsuspend and rt_sigsuspend system calls can call do_signal
* and thus put the process into the stopped state where we might
@@ -406,7 +406,7 @@ DSCR_DEFAULT:
* the fork code also.
*
* The code which creates the new task context is in 'copy_thread'
- * in arch/powerpc/kernel/process.c
+ * in arch/powerpc/kernel/process.c
*/
.align 7
_GLOBAL(_switch)
@@ -653,7 +653,7 @@ _GLOBAL(ret_from_except_lite)
andi. r0,r4,_TIF_USER_WORK_MASK
beq restore
- andi. r0,r4,_TIF_NEED_RESCHED
+ andi. r0,r4,_TIF_NEED_RESCHED_MASK
beq 1f
bl .restore_interrupts
SCHEDULE_USER
@@ -703,10 +703,18 @@ resume_kernel:
#ifdef CONFIG_PREEMPT
/* Check if we need to preempt */
+ lwz r8,TI_PREEMPT(r9)
+ cmpwi 0,r8,0 /* if non-zero, just restore regs and return */
+ bne restore
andi. r0,r4,_TIF_NEED_RESCHED
+ bne+ check_count
+
+ andi. r0,r4,_TIF_NEED_RESCHED_LAZY
beq+ restore
+ lwz r8,TI_PREEMPT_LAZY(r9)
+
/* Check that preempt_count() == 0 and interrupts are enabled */
- lwz r8,TI_PREEMPT(r9)
+check_count:
cmpwi cr1,r8,0
ld r0,SOFTE(r1)
cmpdi r0,0
@@ -723,7 +731,7 @@ resume_kernel:
/* Re-test flags and eventually loop */
CURRENT_THREAD_INFO(r9, r1)
ld r4,TI_FLAGS(r9)
- andi. r0,r4,_TIF_NEED_RESCHED
+ andi. r0,r4,_TIF_NEED_RESCHED_MASK
bne 1b
/*
@@ -890,7 +898,7 @@ restore_check_irq_replay:
bl .__check_irq_replay
cmpwi cr0,r3,0
beq restore_no_replay
-
+
/*
* We need to re-emit an interrupt. We do so by re-using our
* existing exception frame. We first change the trap value,
@@ -932,7 +940,7 @@ restore_check_irq_replay:
b .ret_from_except
#endif /* CONFIG_PPC_DOORBELL */
1: b .ret_from_except /* What else to do here ? */
-
+
unrecov_restore:
addi r3,r1,STACK_FRAME_OVERHEAD
bl .unrecoverable_exception
@@ -944,7 +952,7 @@ unrecov_restore:
* called with the MMU off.
*
* In addition, we need to be in 32b mode, at least for now.
- *
+ *
* Note: r3 is an input parameter to rtas, so don't trash it...
*/
_GLOBAL(enter_rtas)
@@ -978,7 +986,7 @@ _GLOBAL(enter_rtas)
li r0,0
mtcr r0
-#ifdef CONFIG_BUG
+#ifdef CONFIG_BUG
/* There is no way it is acceptable to get here with interrupts enabled,
* check it with the asm equivalent of WARN_ON
*/
@@ -986,7 +994,7 @@ _GLOBAL(enter_rtas)
1: tdnei r0,0
EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,BUGFLAG_WARNING
#endif
-
+
/* Hard-disable interrupts */
mfmsr r6
rldicl r7,r6,48,1
@@ -1000,7 +1008,7 @@ _GLOBAL(enter_rtas)
std r1,PACAR1(r13)
std r6,PACASAVEDMSR(r13)
- /* Setup our real return addr */
+ /* Setup our real return addr */
LOAD_REG_ADDR(r4,.rtas_return_loc)
clrldi r4,r4,2 /* convert to realmode address */
mtlr r4
@@ -1008,7 +1016,7 @@ _GLOBAL(enter_rtas)
li r0,0
ori r0,r0,MSR_EE|MSR_SE|MSR_BE|MSR_RI
andc r0,r6,r0
-
+
li r9,1
rldicr r9,r9,MSR_SF_LG,(63-MSR_SF_LG)
ori r9,r9,MSR_IR|MSR_DR|MSR_FE0|MSR_FE1|MSR_FP|MSR_RI
@@ -1019,7 +1027,7 @@ _GLOBAL(enter_rtas)
LOAD_REG_ADDR(r4, rtas)
ld r5,RTASENTRY(r4) /* get the rtas->entry value */
ld r4,RTASBASE(r4) /* get the rtas->base value */
-
+
mtspr SPRN_SRR0,r5
mtspr SPRN_SRR1,r6
rfid
@@ -1037,9 +1045,9 @@ _STATIC(rtas_return_loc)
mfmsr r6
li r0,MSR_RI
andc r6,r6,r0
- sync
+ sync
mtmsrd r6
-
+
ld r1,PACAR1(r4) /* Restore our SP */
ld r4,PACASAVEDMSR(r4) /* Restore our MSR */
@@ -1137,7 +1145,7 @@ _GLOBAL(enter_prom)
REST_10GPRS(22, r1)
ld r4,_CCR(r1)
mtcr r4
-
+
addi r1,r1,PROM_FRAME_SIZE
ld r0,16(r1)
mtlr r0