@@ -42,16 +42,18 @@
#define EX_R11 16
#define EX_R12 24
#define EX_R13 32
-#define EX_DAR 40
-#define EX_DSISR 48
-#define EX_CCR 52
-#define EX_CFAR 56
-#define EX_PPR 64
+#define EX_R14 40
+#define EX_DAR 48
+#define EX_DSISR 56
+#define EX_CCR 60
+#define EX_CFAR 64
+#define EX_PPR 72
+
#if defined(CONFIG_RELOCATABLE)
-#define EX_CTR 72
-#define EX_SIZE 10 /* size in u64 units */
+#define EX_CTR 80
+#define EX_SIZE 11 /* size in u64 units */
#else
-#define EX_SIZE 9 /* size in u64 units */
+#define EX_SIZE 10 /* size in u64 units */
#endif
/*
@@ -77,9 +79,8 @@
#ifdef CONFIG_RELOCATABLE
#define __EXCEPTION_RELON_PROLOG_PSERIES_1(label, h) \
mfspr r11,SPRN_##h##SRR0; /* save SRR0 */ \
- LOAD_HANDLER(r12,label); \
- mtctr r12; \
- mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \
+ LOAD_HANDLER(r10,label); \
+ mtctr r10; \
li r10,MSR_RI; \
mtmsrd r10,1; /* Set RI (EE=0) */ \
bctr;
@@ -87,7 +88,6 @@
/* If not relocatable, we can jump directly -- and save messing with LR */
#define __EXCEPTION_RELON_PROLOG_PSERIES_1(label, h) \
mfspr r11,SPRN_##h##SRR0; /* save SRR0 */ \
- mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \
li r10,MSR_RI; \
mtmsrd r10,1; /* Set RI (EE=0) */ \
b label;
@@ -102,7 +102,7 @@
*/
#define EXCEPTION_RELON_PROLOG_PSERIES(area, label, h, extra, vec) \
EXCEPTION_PROLOG_0(area); \
- EXCEPTION_PROLOG_1(area, extra, vec); \
+ EXCEPTION_PROLOG_1(area, h, extra, vec); \
EXCEPTION_RELON_PROLOG_PSERIES_1(label, h)
/*
@@ -198,17 +198,21 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
std r10,area+EX_R10(r13); /* save r10 - r12 */ \
OPT_GET_SPR(r10, SPRN_CFAR, CPU_FTR_CFAR)
-#define __EXCEPTION_PROLOG_1_PRE(area) \
+#define __EXCEPTION_PROLOG_1(area, h) \
+ std r11,area+EX_R11(r13); \
+ std r12,area+EX_R12(r13); \
+ mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \
+ GET_SCRATCH0(r11); \
OPT_SAVE_REG_TO_PACA(area+EX_PPR, r9, CPU_FTR_HAS_PPR); \
OPT_SAVE_REG_TO_PACA(area+EX_CFAR, r10, CPU_FTR_CFAR); \
SAVE_CTR(r10, area); \
- mfcr r9;
-
-#define __EXCEPTION_PROLOG_1_POST(area) \
- std r11,area+EX_R11(r13); \
- std r12,area+EX_R12(r13); \
- GET_SCRATCH0(r10); \
- std r10,area+EX_R13(r13)
+ mfcr r9; \
+ std r11,area+EX_R13(r13); \
+ std r14,area+EX_R14(r13); \
+ andi. r10,r12,MSR_PR; \
+ beq 1f; \
+ ld r14,PACA_R14(r13); \
+1:
/*
* This version of the EXCEPTION_PROLOG_1 will carry
@@ -216,30 +220,27 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
* checking of the interrupt maskable level in the SOFTEN_TEST.
* Intended to be used in MASKABLE_EXCPETION_* macros.
*/
-#define MASKABLE_EXCEPTION_PROLOG_1(area, extra, vec, bitmask) \
- __EXCEPTION_PROLOG_1_PRE(area); \
- extra(vec, bitmask); \
- __EXCEPTION_PROLOG_1_POST(area);
+#define MASKABLE_EXCEPTION_PROLOG_1(area, h, extra, vec, bitmask) \
+ __EXCEPTION_PROLOG_1(area, h); \
+ extra(vec, bitmask);
/*
* This version of the EXCEPTION_PROLOG_1 is intended
* to be used in STD_EXCEPTION* macros
*/
-#define _EXCEPTION_PROLOG_1(area, extra, vec) \
- __EXCEPTION_PROLOG_1_PRE(area); \
- extra(vec); \
- __EXCEPTION_PROLOG_1_POST(area);
+#define _EXCEPTION_PROLOG_1(area, h, extra, vec) \
+ __EXCEPTION_PROLOG_1(area, h); \
+ extra(vec);
-#define EXCEPTION_PROLOG_1(area, extra, vec) \
- _EXCEPTION_PROLOG_1(area, extra, vec)
+#define EXCEPTION_PROLOG_1(area, h, extra, vec) \
+ _EXCEPTION_PROLOG_1(area, h, extra, vec)
#define __EXCEPTION_PROLOG_PSERIES_1(label, h) \
- ld r10,PACAKMSR(r13); /* get MSR value for kernel */ \
mfspr r11,SPRN_##h##SRR0; /* save SRR0 */ \
- LOAD_HANDLER(r12,label) \
- mtspr SPRN_##h##SRR0,r12; \
- mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \
+ ld r10,PACAKMSR(r13); /* get MSR value for kernel */ \
mtspr SPRN_##h##SRR1,r10; \
+ LOAD_HANDLER(r10,label) \
+ mtspr SPRN_##h##SRR0,r10; \
h##rfid; \
b . /* prevent speculative execution */
#define EXCEPTION_PROLOG_PSERIES_1(label, h) \
@@ -247,13 +248,12 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
/* _NORI variant keeps MSR_RI clear */
#define __EXCEPTION_PROLOG_PSERIES_1_NORI(label, h) \
+ mfspr r11,SPRN_##h##SRR0; /* save SRR0 */ \
ld r10,PACAKMSR(r13); /* get MSR value for kernel */ \
xori r10,r10,MSR_RI; /* Clear MSR_RI */ \
- mfspr r11,SPRN_##h##SRR0; /* save SRR0 */ \
- LOAD_HANDLER(r12,label) \
- mtspr SPRN_##h##SRR0,r12; \
- mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \
mtspr SPRN_##h##SRR1,r10; \
+ LOAD_HANDLER(r10,label) \
+ mtspr SPRN_##h##SRR0,r10; \
h##rfid; \
b . /* prevent speculative execution */
@@ -262,7 +262,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
#define EXCEPTION_PROLOG_PSERIES(area, label, h, extra, vec) \
EXCEPTION_PROLOG_0(area); \
- EXCEPTION_PROLOG_1(area, extra, vec); \
+ EXCEPTION_PROLOG_1(area, h, extra, vec); \
EXCEPTION_PROLOG_PSERIES_1(label, h);
#define __KVMTEST(h, n) \
@@ -336,7 +336,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
/* Do not enable RI */
#define EXCEPTION_PROLOG_PSERIES_NORI(area, label, h, extra, vec) \
EXCEPTION_PROLOG_0(area); \
- EXCEPTION_PROLOG_1(area, extra, vec); \
+ EXCEPTION_PROLOG_1(area, h, extra, vec); \
EXCEPTION_PROLOG_PSERIES_1_NORI(label, h);
@@ -349,8 +349,9 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
ld r10,area+EX_PPR(r13); \
std r10,HSTATE_PPR(r13); \
END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,948); \
+ ld r10,area+EX_R12(r13); \
+ std r10,HSTATE_SCRATCH0(r13); \
ld r10,area+EX_R10(r13); \
- std r12,HSTATE_SCRATCH0(r13); \
sldi r12,r9,32; \
ori r12,r12,(n); \
/* This reloads r9 before branching to kvmppc_interrupt */ \
@@ -363,8 +364,9 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
ld r10,area+EX_PPR(r13); \
std r10,HSTATE_PPR(r13); \
END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,948); \
+ ld r10,area+EX_R12(r13); \
+ std r10,HSTATE_SCRATCH0(r13); \
ld r10,area+EX_R10(r13); \
- std r12,HSTATE_SCRATCH0(r13); \
sldi r12,r9,32; \
ori r12,r12,(n); \
/* This reloads r9 before branching to kvmppc_interrupt */ \
@@ -372,6 +374,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
89: mtocrf 0x80,r9; \
ld r9,area+EX_R9(r13); \
ld r10,area+EX_R10(r13); \
+ ld r12,area+EX_R12(r13); \
b kvmppc_skip_##h##interrupt
#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
@@ -393,7 +396,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
std r12,_MSR(r1); /* save SRR1 in stackframe */ \
std r10,0(r1); /* make stack chain pointer */ \
std r0,GPR0(r1); /* save r0 in stackframe */ \
- std r10,GPR1(r1); /* save r1 in stackframe */ \
+ std r10,GPR1(r1) /* save r1 in stackframe */
/*
@@ -430,16 +433,18 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
/* Save original regs values from save area to stack frame. */
#define EXCEPTION_PROLOG_COMMON_2(area) \
- ld r9,area+EX_R9(r13); /* move r9, r10 to stackframe */ \
+ ld r9,area+EX_R9(r13); /* move r9-r14 to stackframe */ \
ld r10,area+EX_R10(r13); \
std r9,GPR9(r1); \
std r10,GPR10(r1); \
- ld r9,area+EX_R11(r13); /* move r11 - r13 to stackframe */ \
+ ld r9,area+EX_R11(r13); \
ld r10,area+EX_R12(r13); \
- ld r11,area+EX_R13(r13); \
std r9,GPR11(r1); \
std r10,GPR12(r1); \
- std r11,GPR13(r1); \
+ ld r9,area+EX_R13(r13); \
+ ld r10,area+EX_R14(r13); \
+ std r9,GPR13(r1); \
+ std r10,GPR14(r1); \
BEGIN_FTR_SECTION_NESTED(66); \
ld r10,area+EX_CFAR(r13); \
std r10,ORIG_GPR3(r1); \
@@ -480,7 +485,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
b hdlr;
#define STD_EXCEPTION_PSERIES_OOL(vec, label) \
- EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_PR, vec); \
+ EXCEPTION_PROLOG_1(PACA_EXGEN, EXC_STD, KVMTEST_PR, vec); \
EXCEPTION_PROLOG_PSERIES_1(label, EXC_STD)
#define STD_EXCEPTION_HV(loc, vec, label) \
@@ -489,7 +494,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
EXC_HV, KVMTEST_HV, vec);
#define STD_EXCEPTION_HV_OOL(vec, label) \
- EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_HV, vec); \
+ EXCEPTION_PROLOG_1(PACA_EXGEN, EXC_HV, KVMTEST_HV, vec); \
EXCEPTION_PROLOG_PSERIES_1(label, EXC_HV)
#define STD_RELON_EXCEPTION_PSERIES(loc, vec, label) \
@@ -498,7 +503,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
EXCEPTION_RELON_PROLOG_PSERIES(PACA_EXGEN, label, EXC_STD, NOTEST, vec);
#define STD_RELON_EXCEPTION_PSERIES_OOL(vec, label) \
- EXCEPTION_PROLOG_1(PACA_EXGEN, NOTEST, vec); \
+ EXCEPTION_PROLOG_1(PACA_EXGEN, EXC_STD, NOTEST, vec); \
EXCEPTION_RELON_PROLOG_PSERIES_1(label, EXC_STD)
#define STD_RELON_EXCEPTION_HV(loc, vec, label) \
@@ -507,7 +512,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
EXC_HV, KVMTEST_HV, vec);
#define STD_RELON_EXCEPTION_HV_OOL(vec, label) \
- EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_HV, vec); \
+ EXCEPTION_PROLOG_1(PACA_EXGEN, EXC_HV, KVMTEST_HV, vec); \
EXCEPTION_RELON_PROLOG_PSERIES_1(label, EXC_HV)
/* This associate vector numbers with bits in paca->irq_happened */
@@ -548,7 +553,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
#define __MASKABLE_EXCEPTION_PSERIES(vec, label, h, extra, bitmask) \
SET_SCRATCH0(r13); /* save r13 */ \
EXCEPTION_PROLOG_0(PACA_EXGEN); \
- MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, extra, vec, bitmask); \
+ MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, h, extra, vec, bitmask);\
EXCEPTION_PROLOG_PSERIES_1(label, h);
#define _MASKABLE_EXCEPTION_PSERIES(vec, label, h, extra, bitmask) \
@@ -559,7 +564,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
EXC_STD, SOFTEN_TEST_PR, bitmask)
#define MASKABLE_EXCEPTION_PSERIES_OOL(vec, label, bitmask) \
- MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_TEST_PR, vec, bitmask);\
+ MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, EXC_STD, SOFTEN_TEST_PR, vec, bitmask);\
EXCEPTION_PROLOG_PSERIES_1(label, EXC_STD)
#define MASKABLE_EXCEPTION_HV(loc, vec, label, bitmask) \
@@ -567,13 +572,13 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
EXC_HV, SOFTEN_TEST_HV, bitmask)
#define MASKABLE_EXCEPTION_HV_OOL(vec, label, bitmask) \
- MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_TEST_HV, vec, bitmask);\
+ MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, EXC_HV, SOFTEN_TEST_HV, vec, bitmask);\
EXCEPTION_PROLOG_PSERIES_1(label, EXC_HV)
#define __MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, h, extra, bitmask) \
SET_SCRATCH0(r13); /* save r13 */ \
EXCEPTION_PROLOG_0(PACA_EXGEN); \
- MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, extra, vec, bitmask); \
+ MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, h, extra, vec, bitmask);\
EXCEPTION_RELON_PROLOG_PSERIES_1(label, h)
#define _MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, h, extra, bitmask)\
@@ -584,7 +589,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
EXC_STD, SOFTEN_NOTEST_PR, bitmask)
#define MASKABLE_RELON_EXCEPTION_PSERIES_OOL(vec, label, bitmask) \
- MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_NOTEST_PR, vec, bitmask);\
+ MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, EXC_STD, SOFTEN_NOTEST_PR, vec, bitmask);\
EXCEPTION_PROLOG_PSERIES_1(label, EXC_STD);
#define MASKABLE_RELON_EXCEPTION_HV(loc, vec, label, bitmask) \
@@ -592,7 +597,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
EXC_HV, SOFTEN_TEST_HV, bitmask)
#define MASKABLE_RELON_EXCEPTION_HV_OOL(vec, label, bitmask) \
- MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_NOTEST_HV, vec, bitmask);\
+ MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, EXC_HV, SOFTEN_NOTEST_HV, vec, bitmask);\
EXCEPTION_RELON_PROLOG_PSERIES_1(label, EXC_HV)
/*
@@ -34,6 +34,9 @@
#include <asm/cpuidle.h>
register struct paca_struct *local_paca asm("r13");
+#ifdef CONFIG_PPC_BOOK3S
+register u64 local_r14 asm("r14");
+#endif
#if defined(CONFIG_DEBUG_PREEMPT) && defined(CONFIG_SMP)
extern unsigned int debug_smp_processor_id(void); /* from linux/smp.h */
@@ -65,7 +68,6 @@ struct paca_struct {
* read-only (after boot) fields in the first cacheline to
* avoid cacheline bouncing.
*/
-
struct lppaca *lppaca_ptr; /* Pointer to LpPaca for PLIC */
#endif /* CONFIG_PPC_BOOK3S */
/*
@@ -104,6 +106,7 @@ struct paca_struct {
*/
/* used for most interrupts/exceptions */
u64 exgen[EX_SIZE] __attribute__((aligned(0x80)));
+ u64 r14;
u64 exslb[EX_SIZE]; /* used for SLB/segment table misses
* on the linear mapping */
/* SLB related definitions */
@@ -218,8 +218,9 @@ int main(void)
OFFSET(PACACONTEXTSLLP, paca_struct, mm_ctx_sllp);
#endif /* CONFIG_PPC_MM_SLICES */
OFFSET(PACA_EXGEN, paca_struct, exgen);
- OFFSET(PACA_EXMC, paca_struct, exmc);
+ OFFSET(PACA_R14, paca_struct, r14);
OFFSET(PACA_EXSLB, paca_struct, exslb);
+ OFFSET(PACA_EXMC, paca_struct, exmc);
OFFSET(PACA_EXNMI, paca_struct, exnmi);
OFFSET(PACALPPACAPTR, paca_struct, lppaca_ptr);
OFFSET(PACA_SLBSHADOWPTR, paca_struct, slb_shadow_ptr);
@@ -37,6 +37,11 @@
#include <asm/tm.h>
#include <asm/ppc-opcode.h>
#include <asm/export.h>
+#ifdef CONFIG_PPC_BOOK3S
+#include <asm/exception-64s.h>
+#else
+#include <asm/exception-64e.h>
+#endif
/*
* System calls.
@@ -65,11 +70,18 @@ END_FTR_SECTION_IFSET(CPU_FTR_TM)
addi r1,r1,-INT_FRAME_SIZE
beq- 1f
ld r1,PACAKSAVE(r13)
+#ifdef CONFIG_PPC_BOOK3S
+ ld r14,PACA_R14(r13)
+#endif
1: std r10,0(r1)
std r11,_NIP(r1)
std r12,_MSR(r1)
std r0,GPR0(r1)
std r10,GPR1(r1)
+#ifdef CONFIG_PPC_BOOK3S
+ ld r10,PACA_EXGEN+EX_R14(r13)
+ std r10,GPR14(r1)
+#endif
beq 2f /* if from kernel mode */
ACCOUNT_CPU_USER_ENTRY(r13, r10, r11)
2: std r2,GPR2(r1)
@@ -250,6 +262,11 @@ system_call_exit:
BEGIN_FTR_SECTION
stdcx. r0,0,r1 /* to clear the reservation */
END_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
+ LOAD_REG_IMMEDIATE(r10, 0xdeadbeefULL << 32)
+ mfspr r11,SPRN_PIR
+ or r10,r10,r11
+ tdne r10,r14
+
andi. r6,r8,MSR_PR
ld r4,_LINK(r1)
@@ -261,6 +278,9 @@ BEGIN_FTR_SECTION
END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
ld r13,GPR13(r1) /* only restore r13 if returning to usermode */
+#ifdef CONFIG_PPC_BOOK3S
+ ld r14,GPR14(r1) /* only restore r14 if returning to usermode */
+#endif
1: ld r2,GPR2(r1)
ld r1,GPR1(r1)
mtlr r4
@@ -874,6 +894,9 @@ BEGIN_FTR_SECTION
END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
ACCOUNT_CPU_USER_EXIT(r13, r2, r4)
REST_GPR(13, r1)
+#ifdef CONFIG_PPC_BOOK3S
+ REST_GPR(14, r1)
+#endif
1:
mtspr SPRN_SRR1,r3
@@ -196,7 +196,7 @@ EXC_REAL_END(machine_check, 0x200, 0x100)
EXC_VIRT_NONE(0x4200, 0x100)
TRAMP_REAL_BEGIN(machine_check_powernv_early)
BEGIN_FTR_SECTION
- EXCEPTION_PROLOG_1(PACA_EXMC, NOTEST, 0x200)
+ EXCEPTION_PROLOG_1(PACA_EXMC, EXC_STD, NOTEST, 0x200)
/*
* Register contents:
* R13 = PACA
@@ -248,7 +248,7 @@ BEGIN_FTR_SECTION
mfspr r11,SPRN_DSISR /* Save DSISR */
std r11,_DSISR(r1)
std r9,_CCR(r1) /* Save CR in stackframe */
- /* Save r9 through r13 from EXMC save area to stack frame. */
+ /* Save r9 through r14 from EXMC save area to stack frame. */
EXCEPTION_PROLOG_COMMON_2(PACA_EXMC)
mfmsr r11 /* get MSR value */
ori r11,r11,MSR_ME /* turn on ME bit */
@@ -278,7 +278,7 @@ machine_check_fwnmi:
SET_SCRATCH0(r13) /* save r13 */
EXCEPTION_PROLOG_0(PACA_EXMC)
machine_check_pSeries_0:
- EXCEPTION_PROLOG_1(PACA_EXMC, KVMTEST_PR, 0x200)
+ EXCEPTION_PROLOG_1(PACA_EXMC, EXC_STD, KVMTEST_PR, 0x200)
/*
* MSR_RI is not enabled, because PACA_EXMC is being used, so a
* nested machine check corrupts it. machine_check_common enables
@@ -338,8 +338,7 @@ EXC_COMMON_BEGIN(machine_check_common)
lhz r12,PACA_IN_MCE(r13); \
subi r12,r12,1; \
sth r12,PACA_IN_MCE(r13); \
- REST_GPR(11, r1); \
- REST_2GPRS(12, r1); \
+ REST_4GPRS(11, r1); \
/* restore original r1. */ \
ld r1,GPR1(r1)
@@ -514,7 +513,7 @@ ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX)
EXC_REAL_BEGIN(data_access_slb, 0x380, 0x80)
SET_SCRATCH0(r13)
EXCEPTION_PROLOG_0(PACA_EXSLB)
- EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST_PR, 0x380)
+ EXCEPTION_PROLOG_1(PACA_EXSLB, EXC_STD, KVMTEST_PR, 0x380)
mr r12,r3 /* save r3 */
mfspr r3,SPRN_DAR
mfspr r11,SPRN_SRR1
@@ -525,7 +524,7 @@ EXC_REAL_END(data_access_slb, 0x380, 0x80)
EXC_VIRT_BEGIN(data_access_slb, 0x4380, 0x80)
SET_SCRATCH0(r13)
EXCEPTION_PROLOG_0(PACA_EXSLB)
- EXCEPTION_PROLOG_1(PACA_EXSLB, NOTEST, 0x380)
+ EXCEPTION_PROLOG_1(PACA_EXSLB, EXC_STD, NOTEST, 0x380)
mr r12,r3 /* save r3 */
mfspr r3,SPRN_DAR
mfspr r11,SPRN_SRR1
@@ -558,7 +557,7 @@ ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX)
EXC_REAL_BEGIN(instruction_access_slb, 0x480, 0x80)
SET_SCRATCH0(r13)
EXCEPTION_PROLOG_0(PACA_EXSLB)
- EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST_PR, 0x480)
+ EXCEPTION_PROLOG_1(PACA_EXSLB, EXC_STD, KVMTEST_PR, 0x480)
mr r12,r3 /* save r3 */
mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */
mfspr r11,SPRN_SRR1
@@ -569,7 +568,7 @@ EXC_REAL_END(instruction_access_slb, 0x480, 0x80)
EXC_VIRT_BEGIN(instruction_access_slb, 0x4480, 0x80)
SET_SCRATCH0(r13)
EXCEPTION_PROLOG_0(PACA_EXSLB)
- EXCEPTION_PROLOG_1(PACA_EXSLB, NOTEST, 0x480)
+ EXCEPTION_PROLOG_1(PACA_EXSLB, EXC_STD, NOTEST, 0x480)
mr r12,r3 /* save r3 */
mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */
mfspr r11,SPRN_SRR1
@@ -639,6 +638,7 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_RADIX)
ld r10,PACA_EXSLB+EX_R10(r13)
ld r11,PACA_EXSLB+EX_R11(r13)
ld r12,PACA_EXSLB+EX_R12(r13)
+ ld r14,PACA_EXSLB+EX_R14(r13)
ld r13,PACA_EXSLB+EX_R13(r13)
rfid
b . /* prevent speculative execution */
@@ -806,7 +806,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_TM)
#endif
-EXC_REAL_MASKABLE(decrementer, 0x900, 0x80, IRQ_SOFT_MASK_STD)
+EXC_REAL_OOL_MASKABLE(decrementer, 0x900, 0x80, IRQ_SOFT_MASK_STD)
EXC_VIRT_MASKABLE(decrementer, 0x4900, 0x80, 0x900, IRQ_SOFT_MASK_STD)
TRAMP_KVM(PACA_EXGEN, 0x900)
EXC_COMMON_ASYNC(decrementer_common, 0x900, timer_interrupt)
@@ -907,6 +907,7 @@ EXC_COMMON(trap_0b_common, 0xb00, unknown_exception)
mtspr SPRN_SRR0,r10 ; \
ld r10,PACAKMSR(r13) ; \
mtspr SPRN_SRR1,r10 ; \
+ std r14,PACA_EXGEN+EX_R14(r13); \
rfid ; \
b . ; /* prevent speculative execution */
@@ -942,6 +943,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) \
mfspr r12,SPRN_SRR1 ; \
li r10,MSR_RI ; \
mtmsrd r10,1 ; \
+ std r14,PACA_EXGEN+EX_R14(r13); \
bctr ;
#else
/* We can branch directly */
@@ -950,6 +952,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) \
mfspr r12,SPRN_SRR1 ; \
li r10,MSR_RI ; \
mtmsrd r10,1 ; /* Set RI (EE=0) */ \
+ std r14,PACA_EXGEN+EX_R14(r13); \
b system_call_common ;
#endif
@@ -1035,12 +1038,11 @@ __TRAMP_REAL_OOL_MASKABLE_HV(hmi_exception, 0xe60, IRQ_SOFT_MASK_STD)
EXC_VIRT_NONE(0x4e60, 0x20)
TRAMP_KVM_HV(PACA_EXGEN, 0xe60)
TRAMP_REAL_BEGIN(hmi_exception_early)
- EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_HV, 0xe60)
+ EXCEPTION_PROLOG_1(PACA_EXGEN, EXC_HV, KVMTEST_HV, 0xe60)
mr r10,r1 /* Save r1 */
ld r1,PACAEMERGSP(r13) /* Use emergency stack for realmode */
subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */
mfspr r11,SPRN_HSRR0 /* Save HSRR0 */
- mfspr r12,SPRN_HSRR1 /* Save HSRR1 */
EXCEPTION_PROLOG_COMMON_1()
EXCEPTION_PROLOG_COMMON_2(PACA_EXGEN)
EXCEPTION_PROLOG_COMMON_3(0xe60)
@@ -1236,7 +1238,7 @@ EXC_VIRT_NONE(0x5400, 0x100)
EXC_REAL_BEGIN(denorm_exception_hv, 0x1500, 0x100)
mtspr SPRN_SPRG_HSCRATCH0,r13
EXCEPTION_PROLOG_0(PACA_EXGEN)
- EXCEPTION_PROLOG_1(PACA_EXGEN, NOTEST, 0x1500)
+ EXCEPTION_PROLOG_1(PACA_EXGEN, EXC_HV, NOTEST, 0x1500)
#ifdef CONFIG_PPC_DENORMALISATION
mfspr r10,SPRN_HSRR1
@@ -1319,6 +1321,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
ld r10,PACA_EXGEN+EX_R10(r13)
ld r11,PACA_EXGEN+EX_R11(r13)
ld r12,PACA_EXGEN+EX_R12(r13)
+ ld r14,PACA_EXGEN+EX_R14(r13)
ld r13,PACA_EXGEN+EX_R13(r13)
HRFID
b .
@@ -1364,9 +1367,6 @@ EXC_VIRT_NONE(0x5800, 0x100)
#define MASKED_DEC_HANDLER(_H) \
3: /* soft-nmi */ \
- std r12,PACA_EXGEN+EX_R12(r13); \
- GET_SCRATCH0(r10); \
- std r10,PACA_EXGEN+EX_R13(r13); \
EXCEPTION_PROLOG_PSERIES_1(soft_nmi_common, _H)
/*
@@ -1404,7 +1404,6 @@ EXC_COMMON_BEGIN(soft_nmi_common)
*/
#define MASKED_INTERRUPT(_H) \
masked_##_H##interrupt: \
- std r11,PACA_EXGEN+EX_R11(r13); \
lbz r11,PACAIRQHAPPENED(r13); \
or r11,r11,r10; \
stb r11,PACAIRQHAPPENED(r13); \
@@ -1416,13 +1415,13 @@ masked_##_H##interrupt: \
b MASKED_DEC_HANDLER_LABEL; \
1: andi. r10,r10,(PACA_IRQ_DBELL|PACA_IRQ_HMI); \
bne 2f; \
- mfspr r10,SPRN_##_H##SRR1; \
- xori r10,r10,MSR_EE; /* clear MSR_EE */ \
- mtspr SPRN_##_H##SRR1,r10; \
+ xori r12,r12,MSR_EE; /* clear MSR_EE */ \
+ mtspr SPRN_##_H##SRR1,r12; \
2: mtcrf 0x80,r9; \
ld r9,PACA_EXGEN+EX_R9(r13); \
ld r10,PACA_EXGEN+EX_R10(r13); \
ld r11,PACA_EXGEN+EX_R11(r13); \
+ ld r12,PACA_EXGEN+EX_R12(r13); \
/* returns to kernel where r13 must be set up, so don't restore it */ \
##_H##rfid; \
b .; \
@@ -1648,10 +1647,12 @@ bad_stack:
SAVE_2GPRS(9,r1)
ld r9,EX_R11(r3)
ld r10,EX_R12(r3)
- ld r11,EX_R13(r3)
std r9,GPR11(r1)
std r10,GPR12(r1)
- std r11,GPR13(r1)
+ ld r9,EX_R13(r3)
+ ld r10,EX_R14(r3)
+ std r9,GPR13(r1)
+ std r10,GPR14(r1)
BEGIN_FTR_SECTION
ld r10,EX_CFAR(r3)
std r10,ORIG_GPR3(r1)
@@ -413,6 +413,11 @@ generic_secondary_common_init:
b kexec_wait /* next kernel might do better */
2: SET_PACA(r13)
+ LOAD_REG_IMMEDIATE(r14, 0xdeadbeef << 32)
+ mfspr r3,SPRN_PIR
+ or r14,r14,r3
+ std r14,PACA_R14(r13)
+
#ifdef CONFIG_PPC_BOOK3E
addi r12,r13,PACA_EXTLB /* and TLB exc frame in another */
mtspr SPRN_SPRG_TLB_EXFRAME,r12
@@ -195,6 +195,7 @@ pnv_powersave_common:
/* Continue saving state */
SAVE_GPR(2, r1)
+ SAVE_GPR(14, r1) /* XXX: check if we need to save/restore or can rely on PACA_R14 reload */
SAVE_NVGPRS(r1)
mfcr r5
std r5,_CCR(r1)
@@ -464,6 +465,7 @@ power9_dd1_recover_paca:
/* Load paca->thread_sibling_pacas[i] into r13 */
ldx r13, r4, r5
SET_PACA(r13)
+ /* R14 will be restored */
/*
* Indicate that we have lost NVGPR state
* which needs to be restored from the stack.
@@ -926,6 +928,7 @@ fastsleep_workaround_at_exit:
.global pnv_wakeup_loss
pnv_wakeup_loss:
ld r1,PACAR1(r13)
+ REST_GPR(14, r1)
BEGIN_FTR_SECTION
CHECK_HMI_INTERRUPT
END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
@@ -950,6 +953,7 @@ pnv_wakeup_noloss:
cmpwi r0,0
bne pnv_wakeup_loss
ld r1,PACAR1(r13)
+ REST_GPR(14, r1)
BEGIN_FTR_SECTION
CHECK_HMI_INTERRUPT
END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
@@ -198,7 +198,6 @@ void setup_paca(struct paca_struct *new_paca)
mtspr(SPRN_SPRG_HPACA, local_paca);
#endif
mtspr(SPRN_SPRG_PACA, local_paca);
-
}
static int __initdata paca_size;
@@ -192,6 +192,9 @@ static void __init fixup_boot_paca(void)
get_paca()->data_offset = 0;
/* Mark interrupts disabled in PACA */
irq_soft_mask_set(IRQ_SOFT_MASK_STD);
+ /* Set r14 and paca_r14 to debug value */
+ get_paca()->r14 = (0xdeadbeefULL << 32) | mfspr(SPRN_PIR);
+ local_r14 = get_paca()->r14;
}
static void __init configure_exceptions(void)
@@ -3073,6 +3073,7 @@ int emulate_step(struct pt_regs *regs, unsigned int instr)
regs->gpr[11] = regs->nip + 4;
regs->gpr[12] = regs->msr & MSR_MASK;
regs->gpr[13] = (unsigned long) get_paca();
+ regs->gpr[14] = local_r14;
regs->nip = (unsigned long) &system_call_common;
regs->msr = MSR_KERNEL;
return 1;