diff options
Diffstat (limited to 'arch/powerpc/kernel/entry_64.S')
-rw-r--r-- | arch/powerpc/kernel/entry_64.S | 59 |
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 */ |
178 | 1: ld r2,GPR2(r1) | 186 | 1: 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) |
508 | 1: | 532 | 1: |
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 |