aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2013-11-05 00:33:22 -0500
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2013-11-05 22:13:53 -0500
commit0c4888ef1d8a8b82c29075ce7e257ff795af15c7 (patch)
tree22f37dca43e49a79236b1279511778a1e8d12c61
parent36954dc78d8a1dcd4780cf4bd0fc6292791821b9 (diff)
powerpc: Fix fatal SLB miss when restoring PPR
When restoring the PPR value, we incorrectly access the thread structure at a time where MSR:RI is clear, which means we cannot recover from nested faults. However the thread structure isn't covered by the "bolted" SLB entries and thus accessing can fault. This fixes it by splitting the code so that the PPR value is loaded into a GPR before MSR:RI is cleared. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--arch/powerpc/include/asm/ppc_asm.h7
-rw-r--r--arch/powerpc/kernel/entry_64.S10
2 files changed, 9 insertions, 8 deletions
diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h
index 8deaaad3b32f..3c1acc31a092 100644
--- a/arch/powerpc/include/asm/ppc_asm.h
+++ b/arch/powerpc/include/asm/ppc_asm.h
@@ -406,13 +406,6 @@ BEGIN_FTR_SECTION_NESTED(945) \
406 std ra,TASKTHREADPPR(rb); \ 406 std ra,TASKTHREADPPR(rb); \
407END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,945) 407END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,945)
408 408
409#define RESTORE_PPR(ra, rb) \
410BEGIN_FTR_SECTION_NESTED(946) \
411 ld ra,PACACURRENT(r13); \
412 ld rb,TASKTHREADPPR(ra); \
413 mtspr SPRN_PPR,rb; /* Restore PPR */ \
414END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,946)
415
416#endif 409#endif
417 410
418/* 411/*
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 12679cd43e0c..bbfb0294b354 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -818,6 +818,12 @@ fast_exception_return:
818 andi. r0,r3,MSR_RI 818 andi. r0,r3,MSR_RI
819 beq- unrecov_restore 819 beq- unrecov_restore
820 820
821 /* Load PPR from thread struct before we clear MSR:RI */
822BEGIN_FTR_SECTION
823 ld r2,PACACURRENT(r13)
824 ld r2,TASKTHREADPPR(r2)
825END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
826
821 /* 827 /*
822 * Clear RI before restoring r13. If we are returning to 828 * Clear RI before restoring r13. If we are returning to
823 * userspace and we take an exception after restoring r13, 829 * userspace and we take an exception after restoring r13,
@@ -838,8 +844,10 @@ fast_exception_return:
838 */ 844 */
839 andi. r0,r3,MSR_PR 845 andi. r0,r3,MSR_PR
840 beq 1f 846 beq 1f
847BEGIN_FTR_SECTION
848 mtspr SPRN_PPR,r2 /* Restore PPR */
849END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
841 ACCOUNT_CPU_USER_EXIT(r2, r4) 850 ACCOUNT_CPU_USER_EXIT(r2, r4)
842 RESTORE_PPR(r2, r4)
843 REST_GPR(13, r1) 851 REST_GPR(13, r1)
8441: 8521:
845 mtspr SPRN_SRR1,r3 853 mtspr SPRN_SRR1,r3