aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorMichael Neuling <mikey@neuling.org>2012-11-02 02:21:28 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-11-14 23:08:04 -0500
commit4700dfaf1e988b785bd9791064df92d3353e8b88 (patch)
treedc3b9cae491aae77bd9938777bfea12104b3f408 /arch
parent742415d6b66bf09e3e73280178ef7ec85c90b7ee (diff)
powerpc: Add new macros needed for relocation on exceptions
POWER8/v2.07 allows exceptions to be taken with the MMU still on. A new set of exception vectors is added at 0xc000_0000_0000_4xxx. When the HW takes us here, MSR IR/DR will be set already and we no longer need a costly RFID to turn the MMU back on again. The original 0x0 based exception vectors remain for when the HW can't leave the MMU on. Examples of this are when we can't trust the current the MMU mappings, like when we are changing from guest to hypervisor (HV 0 -> 1) or when the MMU was off already. In these cases the HW will take us to the original 0x0 based exception vectors with the MMU off as before. The below macros are copies of the macros used at the 0x0 offset but modified to handle the MMU being on. In these macros we use the link register to jump to the secondary handlers rather than using RFID (RFID was also use to turn on the MMU). Signed-off-by: Matt Evans <matt@ozlabs.org> Signed-off-by: Michael Neuling <mikey@neuling.org> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/include/asm/exception-64s.h90
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S25
2 files changed, 115 insertions, 0 deletions
diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h
index 9258daac4964..10787d3673ac 100644
--- a/arch/powerpc/include/asm/exception-64s.h
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -48,6 +48,35 @@
48#define EX_LR 72 48#define EX_LR 72
49#define EX_CFAR 80 49#define EX_CFAR 80
50 50
51#ifdef CONFIG_RELOCATABLE
52#define EXCEPTION_RELON_PROLOG_PSERIES_1(label, h) \
53 ld r12,PACAKBASE(r13); /* get high part of &label */ \
54 mfspr r11,SPRN_##h##SRR0; /* save SRR0 */ \
55 LOAD_HANDLER(r12,label); \
56 mtlr r12; \
57 mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \
58 li r10,MSR_RI; \
59 mtmsrd r10,1; /* Set RI (EE=0) */ \
60 blr;
61#else
62/* If not relocatable, we can jump directly -- and save messing with LR */
63#define EXCEPTION_RELON_PROLOG_PSERIES_1(label, h) \
64 mfspr r11,SPRN_##h##SRR0; /* save SRR0 */ \
65 mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \
66 li r10,MSR_RI; \
67 mtmsrd r10,1; /* Set RI (EE=0) */ \
68 b label;
69#endif
70
71/*
72 * As EXCEPTION_PROLOG_PSERIES(), except we've already got relocation on
73 * so no need to rfid. Save lr in case we're CONFIG_RELOCATABLE, in which
74 * case EXCEPTION_RELON_PROLOG_PSERIES_1 will be using lr.
75 */
76#define EXCEPTION_RELON_PROLOG_PSERIES(area, label, h, extra, vec) \
77 EXCEPTION_PROLOG_1(area, extra, vec); \
78 EXCEPTION_RELON_PROLOG_PSERIES_1(label, h)
79
51/* 80/*
52 * We're short on space and time in the exception prolog, so we can't 81 * We're short on space and time in the exception prolog, so we can't
53 * use the normal SET_REG_IMMEDIATE macro. Normally we just need the 82 * use the normal SET_REG_IMMEDIATE macro. Normally we just need the
@@ -62,6 +91,22 @@
62#define EXC_HV H 91#define EXC_HV H
63#define EXC_STD 92#define EXC_STD
64 93
94#if defined(CONFIG_RELOCATABLE)
95/*
96 * If we support interrupts with relocation on AND we're a relocatable
97 * kernel, we need to use LR to get to the 2nd level handler. So, save/restore
98 * it when required.
99 */
100#define SAVE_LR(reg, area) mflr reg ; std reg,area+EX_LR(r13)
101#define GET_LR(reg, area) ld reg,area+EX_LR(r13)
102#define RESTORE_LR(reg, area) ld reg,area+EX_LR(r13) ; mtlr reg
103#else
104/* ...else LR is unused and in register. */
105#define SAVE_LR(reg, area)
106#define GET_LR(reg, area) mflr reg
107#define RESTORE_LR(reg, area)
108#endif
109
65#define __EXCEPTION_PROLOG_1(area, extra, vec) \ 110#define __EXCEPTION_PROLOG_1(area, extra, vec) \
66 GET_PACA(r13); \ 111 GET_PACA(r13); \
67 std r9,area+EX_R9(r13); /* save r9 - r12 */ \ 112 std r9,area+EX_R9(r13); /* save r9 - r12 */ \
@@ -233,6 +278,26 @@ label##_hv: \
233 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, \ 278 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, \
234 EXC_HV, KVMTEST, vec) 279 EXC_HV, KVMTEST, vec)
235 280
281#define STD_RELON_EXCEPTION_PSERIES(loc, vec, label) \
282 . = loc; \
283 .globl label##_relon_pSeries; \
284label##_relon_pSeries: \
285 HMT_MEDIUM; \
286 /* No guest interrupts come through here */ \
287 SET_SCRATCH0(r13); /* save r13 */ \
288 EXCEPTION_RELON_PROLOG_PSERIES(PACA_EXGEN, label##_common, \
289 EXC_STD, KVMTEST_PR, vec)
290
291#define STD_RELON_EXCEPTION_HV(loc, vec, label) \
292 . = loc; \
293 .globl label##_relon_hv; \
294label##_relon_hv: \
295 HMT_MEDIUM; \
296 /* No guest interrupts come through here */ \
297 SET_SCRATCH0(r13); /* save r13 */ \
298 EXCEPTION_RELON_PROLOG_PSERIES(PACA_EXGEN, label##_common, \
299 EXC_HV, KVMTEST, vec)
300
236/* This associate vector numbers with bits in paca->irq_happened */ 301/* This associate vector numbers with bits in paca->irq_happened */
237#define SOFTEN_VALUE_0x500 PACA_IRQ_EE 302#define SOFTEN_VALUE_0x500 PACA_IRQ_EE
238#define SOFTEN_VALUE_0x502 PACA_IRQ_EE 303#define SOFTEN_VALUE_0x502 PACA_IRQ_EE
@@ -258,6 +323,9 @@ label##_hv: \
258 KVMTEST(vec); \ 323 KVMTEST(vec); \
259 _SOFTEN_TEST(EXC_STD, vec) 324 _SOFTEN_TEST(EXC_STD, vec)
260 325
326#define SOFTEN_NOTEST_PR(vec) _SOFTEN_TEST(EXC_STD, vec)
327#define SOFTEN_NOTEST_HV(vec) _SOFTEN_TEST(EXC_HV, vec)
328
261#define __MASKABLE_EXCEPTION_PSERIES(vec, label, h, extra) \ 329#define __MASKABLE_EXCEPTION_PSERIES(vec, label, h, extra) \
262 HMT_MEDIUM; \ 330 HMT_MEDIUM; \
263 SET_SCRATCH0(r13); /* save r13 */ \ 331 SET_SCRATCH0(r13); /* save r13 */ \
@@ -280,6 +348,28 @@ label##_hv: \
280 _MASKABLE_EXCEPTION_PSERIES(vec, label, \ 348 _MASKABLE_EXCEPTION_PSERIES(vec, label, \
281 EXC_HV, SOFTEN_TEST_HV) 349 EXC_HV, SOFTEN_TEST_HV)
282 350
351#define __MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, h, extra) \
352 HMT_MEDIUM; \
353 SET_SCRATCH0(r13); /* save r13 */ \
354 __EXCEPTION_PROLOG_1(PACA_EXGEN, extra, vec); \
355 EXCEPTION_RELON_PROLOG_PSERIES_1(label##_common, h);
356#define _MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, h, extra) \
357 __MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, h, extra)
358
359#define MASKABLE_RELON_EXCEPTION_PSERIES(loc, vec, label) \
360 . = loc; \
361 .globl label##_relon_pSeries; \
362label##_relon_pSeries: \
363 _MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, \
364 EXC_STD, SOFTEN_NOTEST_PR)
365
366#define MASKABLE_RELON_EXCEPTION_HV(loc, vec, label) \
367 . = loc; \
368 .globl label##_relon_hv; \
369label##_relon_hv: \
370 _MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, \
371 EXC_HV, SOFTEN_NOTEST_HV)
372
283/* 373/*
284 * Our exception common code can be passed various "additions" 374 * Our exception common code can be passed various "additions"
285 * to specify the behaviour of interrupts, whether to kick the 375 * to specify the behaviour of interrupts, whether to kick the
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 85b3c7e9dd6d..4dc1a045052a 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -62,6 +62,31 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) \
62 rfid ; \ 62 rfid ; \
63 b . ; /* prevent speculative execution */ 63 b . ; /* prevent speculative execution */
64 64
65#if defined(CONFIG_RELOCATABLE)
66 /*
67 * We can't branch directly; in the direct case we use LR
68 * and system_call_entry restores LR. (We thus need to move
69 * LR to r10 in the RFID case too.)
70 */
71#define SYSCALL_PSERIES_2_DIRECT \
72 mflr r10 ; \
73 ld r12,PACAKBASE(r13) ; \
74 LOAD_HANDLER(r12, system_call_entry_direct) ; \
75 mtlr r12 ; \
76 mfspr r12,SPRN_SRR1 ; \
77 /* Re-use of r13... No spare regs to do this */ \
78 li r13,MSR_RI ; \
79 mtmsrd r13,1 ; \
80 GET_PACA(r13) ; /* get r13 back */ \
81 blr ;
82#else
83 /* We can branch directly */
84#define SYSCALL_PSERIES_2_DIRECT \
85 mfspr r12,SPRN_SRR1 ; \
86 li r10,MSR_RI ; \
87 mtmsrd r10,1 ; /* Set RI (EE=0) */ \
88 b system_call_entry_direct ;
89#endif
65 90
66/* 91/*
67 * This is the start of the interrupt handlers for pSeries 92 * This is the start of the interrupt handlers for pSeries