aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/entry_64.S
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2007-02-06 21:13:26 -0500
committerPaul Mackerras <paulus@samba.org>2007-02-06 22:03:23 -0500
commite56a6e20f3029ed5c178dd0328bd688dbbc8272a (patch)
treed71551d8c5f7fac0a839c02d7bd6abe4d4e571bd /arch/powerpc/kernel/entry_64.S
parent449d846dbcbf61bdf7d50a923e4791102168c292 (diff)
[POWERPC] Clear RI bit in MSR before restoring r13 when returning to userspace
Some instruction tracing tools use the RI (recoverable interrupt) bit in the MSR to indicate when it's safe to single-step. Currently we clear RI after restoring r13 when returning to userspace. However, if we single-step past the point where r13 is restored, we'll corrupt r13 in the exception entry code and not restore it. This moves the clearing of RI to just before r13 is restored so this doesn't happen. Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/entry_64.S')
-rw-r--r--arch/powerpc/kernel/entry_64.S59
1 files changed, 33 insertions, 26 deletions
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 2551c0884afc..2b66d53dcc55 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -172,13 +172,18 @@ syscall_error_cont:
172 stdcx. r0,0,r1 /* to clear the reservation */ 172 stdcx. r0,0,r1 /* to clear the reservation */
173 andi. r6,r8,MSR_PR 173 andi. r6,r8,MSR_PR
174 ld r4,_LINK(r1) 174 ld r4,_LINK(r1)
175 /*
176 * Clear RI before restoring r13. If we are returning to
177 * userspace and we take an exception after restoring r13,
178 * we end up corrupting the userspace r13 value.
179 */
180 li r12,MSR_RI
181 andc r11,r10,r12
182 mtmsrd r11,1 /* clear MSR.RI */
175 beq- 1f 183 beq- 1f
176 ACCOUNT_CPU_USER_EXIT(r11, r12) 184 ACCOUNT_CPU_USER_EXIT(r11, r12)
177 ld r13,GPR13(r1) /* only restore r13 if returning to usermode */ 185 ld r13,GPR13(r1) /* only restore r13 if returning to usermode */
1781: ld r2,GPR2(r1) 1861: ld r2,GPR2(r1)
179 li r12,MSR_RI
180 andc r11,r10,r12
181 mtmsrd r11,1 /* clear MSR.RI */
182 ld r1,GPR1(r1) 187 ld r1,GPR1(r1)
183 mtlr r4 188 mtlr r4
184 mtcr r5 189 mtcr r5
@@ -488,42 +493,44 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
488#endif 493#endif
489 stb r5,PACASOFTIRQEN(r13) 494 stb r5,PACASOFTIRQEN(r13)
490 495
496 /* extract EE bit and use it to restore paca->hard_enabled */
491 ld r3,_MSR(r1) 497 ld r3,_MSR(r1)
498 rldicl r4,r3,49,63 /* r0 = (r3 >> 15) & 1 */
499 stb r4,PACAHARDIRQEN(r13)
500
501 ld r4,_CTR(r1)
502 ld r0,_LINK(r1)
503 mtctr r4
504 mtlr r0
505 ld r4,_XER(r1)
506 mtspr SPRN_XER,r4
507
508 REST_8GPRS(5, r1)
509
492 andi. r0,r3,MSR_RI 510 andi. r0,r3,MSR_RI
493 beq- unrecov_restore 511 beq- unrecov_restore
494 512
495 /* extract EE bit and use it to restore paca->hard_enabled */ 513 stdcx. r0,0,r1 /* to clear the reservation */
496 rldicl r4,r3,49,63 /* r0 = (r3 >> 15) & 1 */
497 stb r4,PACAHARDIRQEN(r13)
498 514
499 andi. r0,r3,MSR_PR 515 /*
516 * Clear RI before restoring r13. If we are returning to
517 * userspace and we take an exception after restoring r13,
518 * we end up corrupting the userspace r13 value.
519 */
520 mfmsr r4
521 andc r4,r4,r0 /* r0 contains MSR_RI here */
522 mtmsrd r4,1
500 523
501 /* 524 /*
502 * r13 is our per cpu area, only restore it if we are returning to 525 * r13 is our per cpu area, only restore it if we are returning to
503 * userspace 526 * userspace
504 */ 527 */
528 andi. r0,r3,MSR_PR
505 beq 1f 529 beq 1f
506 ACCOUNT_CPU_USER_EXIT(r3, r4) 530 ACCOUNT_CPU_USER_EXIT(r2, r4)
507 REST_GPR(13, r1) 531 REST_GPR(13, r1)
5081: 5321:
509 ld r3,_CTR(r1) 533 mtspr SPRN_SRR1,r3
510 ld r0,_LINK(r1)
511 mtctr r3
512 mtlr r0
513 ld r3,_XER(r1)
514 mtspr SPRN_XER,r3
515
516 REST_8GPRS(5, r1)
517
518 stdcx. r0,0,r1 /* to clear the reservation */
519
520 mfmsr r0
521 li r2, MSR_RI
522 andc r0,r0,r2
523 mtmsrd r0,1
524
525 ld r0,_MSR(r1)
526 mtspr SPRN_SRR1,r0
527 534
528 ld r2,_CCR(r1) 535 ld r2,_CCR(r1)
529 mtcrf 0xFF,r2 536 mtcrf 0xFF,r2