diff options
| author | Nicholas Piggin <npiggin@gmail.com> | 2018-01-09 11:07:15 -0500 |
|---|---|---|
| committer | Michael Ellerman <mpe@ellerman.id.au> | 2018-01-09 11:07:33 -0500 |
| commit | c7305645eb0c1621351cfc104038831ae87c0053 (patch) | |
| tree | 269ca8ff476da11c608f2d744915ddc20772f065 | |
| parent | a08f828cf47e6c605af21d2cdec68f84e799c318 (diff) | |
powerpc/64s: Convert slb_miss_common to use RFI_TO_USER/KERNEL
In the SLB miss handler we may be returning to user or kernel. We need
to add a check early on and save the result in the cr4 register, and
then we bifurcate the return path based on that.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
| -rw-r--r-- | arch/powerpc/kernel/exceptions-64s.S | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 5502b0147c4e..ed356194f09c 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S | |||
| @@ -598,6 +598,9 @@ EXC_COMMON_BEGIN(slb_miss_common) | |||
| 598 | stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */ | 598 | stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */ |
| 599 | std r10,PACA_EXSLB+EX_LR(r13) /* save LR */ | 599 | std r10,PACA_EXSLB+EX_LR(r13) /* save LR */ |
| 600 | 600 | ||
| 601 | andi. r9,r11,MSR_PR // Check for exception from userspace | ||
| 602 | cmpdi cr4,r9,MSR_PR // And save the result in CR4 for later | ||
| 603 | |||
| 601 | /* | 604 | /* |
| 602 | * Test MSR_RI before calling slb_allocate_realmode, because the | 605 | * Test MSR_RI before calling slb_allocate_realmode, because the |
| 603 | * MSR in r11 gets clobbered. However we still want to allocate | 606 | * MSR in r11 gets clobbered. However we still want to allocate |
| @@ -624,9 +627,32 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_RADIX) | |||
| 624 | 627 | ||
| 625 | /* All done -- return from exception. */ | 628 | /* All done -- return from exception. */ |
| 626 | 629 | ||
| 630 | bne cr4,1f /* returning to kernel */ | ||
| 631 | |||
| 632 | .machine push | ||
| 633 | .machine "power4" | ||
| 634 | mtcrf 0x80,r9 | ||
| 635 | mtcrf 0x08,r9 /* MSR[PR] indication is in cr4 */ | ||
| 636 | mtcrf 0x04,r9 /* MSR[RI] indication is in cr5 */ | ||
| 637 | mtcrf 0x02,r9 /* I/D indication is in cr6 */ | ||
| 638 | mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */ | ||
| 639 | .machine pop | ||
| 640 | |||
| 641 | RESTORE_CTR(r9, PACA_EXSLB) | ||
| 642 | RESTORE_PPR_PACA(PACA_EXSLB, r9) | ||
| 643 | mr r3,r12 | ||
| 644 | ld r9,PACA_EXSLB+EX_R9(r13) | ||
| 645 | ld r10,PACA_EXSLB+EX_R10(r13) | ||
| 646 | ld r11,PACA_EXSLB+EX_R11(r13) | ||
| 647 | ld r12,PACA_EXSLB+EX_R12(r13) | ||
| 648 | ld r13,PACA_EXSLB+EX_R13(r13) | ||
| 649 | RFI_TO_USER | ||
| 650 | b . /* prevent speculative execution */ | ||
| 651 | 1: | ||
| 627 | .machine push | 652 | .machine push |
| 628 | .machine "power4" | 653 | .machine "power4" |
| 629 | mtcrf 0x80,r9 | 654 | mtcrf 0x80,r9 |
| 655 | mtcrf 0x08,r9 /* MSR[PR] indication is in cr4 */ | ||
| 630 | mtcrf 0x04,r9 /* MSR[RI] indication is in cr5 */ | 656 | mtcrf 0x04,r9 /* MSR[RI] indication is in cr5 */ |
| 631 | mtcrf 0x02,r9 /* I/D indication is in cr6 */ | 657 | mtcrf 0x02,r9 /* I/D indication is in cr6 */ |
| 632 | mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */ | 658 | mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */ |
| @@ -640,9 +666,10 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_RADIX) | |||
| 640 | ld r11,PACA_EXSLB+EX_R11(r13) | 666 | ld r11,PACA_EXSLB+EX_R11(r13) |
| 641 | ld r12,PACA_EXSLB+EX_R12(r13) | 667 | ld r12,PACA_EXSLB+EX_R12(r13) |
| 642 | ld r13,PACA_EXSLB+EX_R13(r13) | 668 | ld r13,PACA_EXSLB+EX_R13(r13) |
| 643 | rfid | 669 | RFI_TO_KERNEL |
| 644 | b . /* prevent speculative execution */ | 670 | b . /* prevent speculative execution */ |
| 645 | 671 | ||
| 672 | |||
| 646 | 2: std r3,PACA_EXSLB+EX_DAR(r13) | 673 | 2: std r3,PACA_EXSLB+EX_DAR(r13) |
| 647 | mr r3,r12 | 674 | mr r3,r12 |
| 648 | mfspr r11,SPRN_SRR0 | 675 | mfspr r11,SPRN_SRR0 |
