diff options
Diffstat (limited to 'arch/powerpc/kernel/entry_64.S')
-rw-r--r-- | arch/powerpc/kernel/entry_64.S | 37 |
1 files changed, 19 insertions, 18 deletions
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 5971c85df136..4b01a25e29ef 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S | |||
@@ -146,7 +146,7 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR) | |||
146 | REST_2GPRS(7,r1) | 146 | REST_2GPRS(7,r1) |
147 | addi r9,r1,STACK_FRAME_OVERHEAD | 147 | addi r9,r1,STACK_FRAME_OVERHEAD |
148 | #endif | 148 | #endif |
149 | clrrdi r11,r1,THREAD_SHIFT | 149 | CURRENT_THREAD_INFO(r11, r1) |
150 | ld r10,TI_FLAGS(r11) | 150 | ld r10,TI_FLAGS(r11) |
151 | andi. r11,r10,_TIF_SYSCALL_T_OR_A | 151 | andi. r11,r10,_TIF_SYSCALL_T_OR_A |
152 | bne- syscall_dotrace | 152 | bne- syscall_dotrace |
@@ -181,7 +181,7 @@ syscall_exit: | |||
181 | bl .do_show_syscall_exit | 181 | bl .do_show_syscall_exit |
182 | ld r3,RESULT(r1) | 182 | ld r3,RESULT(r1) |
183 | #endif | 183 | #endif |
184 | clrrdi r12,r1,THREAD_SHIFT | 184 | CURRENT_THREAD_INFO(r12, r1) |
185 | 185 | ||
186 | ld r8,_MSR(r1) | 186 | ld r8,_MSR(r1) |
187 | #ifdef CONFIG_PPC_BOOK3S | 187 | #ifdef CONFIG_PPC_BOOK3S |
@@ -197,7 +197,16 @@ syscall_exit: | |||
197 | wrteei 0 | 197 | wrteei 0 |
198 | #else | 198 | #else |
199 | ld r10,PACAKMSR(r13) | 199 | ld r10,PACAKMSR(r13) |
200 | mtmsrd r10,1 | 200 | /* |
201 | * For performance reasons we clear RI the same time that we | ||
202 | * clear EE. We only need to clear RI just before we restore r13 | ||
203 | * below, but batching it with EE saves us one expensive mtmsrd call. | ||
204 | * We have to be careful to restore RI if we branch anywhere from | ||
205 | * here (eg syscall_exit_work). | ||
206 | */ | ||
207 | li r9,MSR_RI | ||
208 | andc r11,r10,r9 | ||
209 | mtmsrd r11,1 | ||
201 | #endif /* CONFIG_PPC_BOOK3E */ | 210 | #endif /* CONFIG_PPC_BOOK3E */ |
202 | 211 | ||
203 | ld r9,TI_FLAGS(r12) | 212 | ld r9,TI_FLAGS(r12) |
@@ -214,17 +223,6 @@ BEGIN_FTR_SECTION | |||
214 | END_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) | 223 | END_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) |
215 | andi. r6,r8,MSR_PR | 224 | andi. r6,r8,MSR_PR |
216 | ld r4,_LINK(r1) | 225 | ld r4,_LINK(r1) |
217 | /* | ||
218 | * Clear RI before restoring r13. If we are returning to | ||
219 | * userspace and we take an exception after restoring r13, | ||
220 | * we end up corrupting the userspace r13 value. | ||
221 | */ | ||
222 | #ifdef CONFIG_PPC_BOOK3S | ||
223 | /* No MSR:RI on BookE */ | ||
224 | li r12,MSR_RI | ||
225 | andc r11,r10,r12 | ||
226 | mtmsrd r11,1 /* clear MSR.RI */ | ||
227 | #endif /* CONFIG_PPC_BOOK3S */ | ||
228 | 226 | ||
229 | beq- 1f | 227 | beq- 1f |
230 | ACCOUNT_CPU_USER_EXIT(r11, r12) | 228 | ACCOUNT_CPU_USER_EXIT(r11, r12) |
@@ -262,7 +260,7 @@ syscall_dotrace: | |||
262 | ld r7,GPR7(r1) | 260 | ld r7,GPR7(r1) |
263 | ld r8,GPR8(r1) | 261 | ld r8,GPR8(r1) |
264 | addi r9,r1,STACK_FRAME_OVERHEAD | 262 | addi r9,r1,STACK_FRAME_OVERHEAD |
265 | clrrdi r10,r1,THREAD_SHIFT | 263 | CURRENT_THREAD_INFO(r10, r1) |
266 | ld r10,TI_FLAGS(r10) | 264 | ld r10,TI_FLAGS(r10) |
267 | b .Lsyscall_dotrace_cont | 265 | b .Lsyscall_dotrace_cont |
268 | 266 | ||
@@ -271,6 +269,9 @@ syscall_enosys: | |||
271 | b syscall_exit | 269 | b syscall_exit |
272 | 270 | ||
273 | syscall_exit_work: | 271 | syscall_exit_work: |
272 | #ifdef CONFIG_PPC_BOOK3S | ||
273 | mtmsrd r10,1 /* Restore RI */ | ||
274 | #endif | ||
274 | /* If TIF_RESTOREALL is set, don't scribble on either r3 or ccr. | 275 | /* If TIF_RESTOREALL is set, don't scribble on either r3 or ccr. |
275 | If TIF_NOERROR is set, just save r3 as it is. */ | 276 | If TIF_NOERROR is set, just save r3 as it is. */ |
276 | 277 | ||
@@ -499,7 +500,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) | |||
499 | 2: | 500 | 2: |
500 | #endif /* !CONFIG_PPC_BOOK3S */ | 501 | #endif /* !CONFIG_PPC_BOOK3S */ |
501 | 502 | ||
502 | clrrdi r7,r8,THREAD_SHIFT /* base of new stack */ | 503 | CURRENT_THREAD_INFO(r7, r8) /* base of new stack */ |
503 | /* Note: this uses SWITCH_FRAME_SIZE rather than INT_FRAME_SIZE | 504 | /* Note: this uses SWITCH_FRAME_SIZE rather than INT_FRAME_SIZE |
504 | because we don't need to leave the 288-byte ABI gap at the | 505 | because we don't need to leave the 288-byte ABI gap at the |
505 | top of the kernel stack. */ | 506 | top of the kernel stack. */ |
@@ -558,7 +559,7 @@ _GLOBAL(ret_from_except_lite) | |||
558 | mtmsrd r10,1 /* Update machine state */ | 559 | mtmsrd r10,1 /* Update machine state */ |
559 | #endif /* CONFIG_PPC_BOOK3E */ | 560 | #endif /* CONFIG_PPC_BOOK3E */ |
560 | 561 | ||
561 | clrrdi r9,r1,THREAD_SHIFT /* current_thread_info() */ | 562 | CURRENT_THREAD_INFO(r9, r1) |
562 | ld r3,_MSR(r1) | 563 | ld r3,_MSR(r1) |
563 | ld r4,TI_FLAGS(r9) | 564 | ld r4,TI_FLAGS(r9) |
564 | andi. r3,r3,MSR_PR | 565 | andi. r3,r3,MSR_PR |
@@ -601,7 +602,7 @@ resume_kernel: | |||
601 | 1: bl .preempt_schedule_irq | 602 | 1: bl .preempt_schedule_irq |
602 | 603 | ||
603 | /* Re-test flags and eventually loop */ | 604 | /* Re-test flags and eventually loop */ |
604 | clrrdi r9,r1,THREAD_SHIFT | 605 | CURRENT_THREAD_INFO(r9, r1) |
605 | ld r4,TI_FLAGS(r9) | 606 | ld r4,TI_FLAGS(r9) |
606 | andi. r0,r4,_TIF_NEED_RESCHED | 607 | andi. r0,r4,_TIF_NEED_RESCHED |
607 | bne 1b | 608 | bne 1b |