Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[POWERPC] Fix handling of unrecoverable SLB miss interrupts

If an SLB miss interrupt happens while the RI bit of MSR is zero, we
can't just return, because RI being zero indicates that SRR0/SRR1
potentially had live values in them, and the process of taking an
interrupt overwrites them.

This should never happen, but if it does, we try to print a nice oops
message. That doesn't work, however, because the code at unrecov_slb
assumes that the MMU has been turned on, but we call it with the MMU
off (and have done so since the SLB miss handler was rewritten to run
without turning the MMU on) -- except on iSeries, where everything runs
with the MMU on.

This fixes it by adding the necessary code to turn the MMU on if
necessary.

Signed-off-by: Paul Mackerras <paulus@samba.org>

+17 -1
+17 -1
arch/powerpc/kernel/head_64.S
··· 621 621 mtlr r10 622 622 623 623 andi. r10,r12,MSR_RI /* check for unrecoverable exception */ 624 - beq- unrecov_slb 624 + beq- 2f 625 625 626 626 .machine push 627 627 .machine "power4" ··· 642 642 ld r13,PACA_EXSLB+EX_R13(r13) 643 643 rfid 644 644 b . /* prevent speculative execution */ 645 + 646 + 2: 647 + #ifdef CONFIG_PPC_ISERIES 648 + BEGIN_FW_FTR_SECTION 649 + b unrecov_slb 650 + END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) 651 + #endif /* CONFIG_PPC_ISERIES */ 652 + mfspr r11,SPRN_SRR0 653 + clrrdi r10,r13,32 654 + LOAD_HANDLER(r10,unrecov_slb) 655 + mtspr SPRN_SRR0,r10 656 + mfmsr r10 657 + ori r10,r10,MSR_IR|MSR_DR|MSR_RI 658 + mtspr SPRN_SRR1,r10 659 + rfid 660 + b . 645 661 646 662 unrecov_slb: 647 663 EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB)