diff options
Diffstat (limited to 'arch/powerpc/kernel/exceptions-64s.S')
-rw-r--r-- | arch/powerpc/kernel/exceptions-64s.S | 257 |
1 files changed, 186 insertions, 71 deletions
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index f53029a01554..a85f4874cba7 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S | |||
@@ -5,7 +5,7 @@ | |||
5 | * handling and other fixed offset specific things. | 5 | * handling and other fixed offset specific things. |
6 | * | 6 | * |
7 | * This file is meant to be #included from head_64.S due to | 7 | * This file is meant to be #included from head_64.S due to |
8 | * position dependant assembly. | 8 | * position dependent assembly. |
9 | * | 9 | * |
10 | * Most of this originates from head_64.S and thus has the same | 10 | * Most of this originates from head_64.S and thus has the same |
11 | * copyright history. | 11 | * copyright history. |
@@ -13,6 +13,7 @@ | |||
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <asm/exception-64s.h> | 15 | #include <asm/exception-64s.h> |
16 | #include <asm/ptrace.h> | ||
16 | 17 | ||
17 | /* | 18 | /* |
18 | * We layout physical memory as follows: | 19 | * We layout physical memory as follows: |
@@ -36,23 +37,51 @@ | |||
36 | .globl __start_interrupts | 37 | .globl __start_interrupts |
37 | __start_interrupts: | 38 | __start_interrupts: |
38 | 39 | ||
39 | STD_EXCEPTION_PSERIES(0x100, system_reset) | 40 | .globl system_reset_pSeries; |
41 | system_reset_pSeries: | ||
42 | HMT_MEDIUM; | ||
43 | DO_KVM 0x100; | ||
44 | SET_SCRATCH0(r13) | ||
45 | #ifdef CONFIG_PPC_P7_NAP | ||
46 | BEGIN_FTR_SECTION | ||
47 | /* Running native on arch 2.06 or later, check if we are | ||
48 | * waking up from nap. We only handle no state loss and | ||
49 | * supervisor state loss. We do -not- handle hypervisor | ||
50 | * state loss at this time. | ||
51 | */ | ||
52 | mfspr r13,SPRN_SRR1 | ||
53 | rlwinm r13,r13,47-31,30,31 | ||
54 | cmpwi cr0,r13,1 | ||
55 | bne 1f | ||
56 | b .power7_wakeup_noloss | ||
57 | 1: cmpwi cr0,r13,2 | ||
58 | bne 1f | ||
59 | b .power7_wakeup_loss | ||
60 | /* Total loss of HV state is fatal, we could try to use the | ||
61 | * PIR to locate a PACA, then use an emergency stack etc... | ||
62 | * but for now, let's just stay stuck here | ||
63 | */ | ||
64 | 1: cmpwi cr0,r13,3 | ||
65 | beq . | ||
66 | END_FTR_SECTION_IFSET(CPU_FTR_HVMODE_206) | ||
67 | #endif /* CONFIG_PPC_P7_NAP */ | ||
68 | EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD) | ||
40 | 69 | ||
41 | . = 0x200 | 70 | . = 0x200 |
42 | _machine_check_pSeries: | 71 | _machine_check_pSeries: |
43 | HMT_MEDIUM | 72 | HMT_MEDIUM |
44 | DO_KVM 0x200 | 73 | DO_KVM 0x200 |
45 | mtspr SPRN_SPRG_SCRATCH0,r13 /* save r13 */ | 74 | SET_SCRATCH0(r13) |
46 | EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common) | 75 | EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common, EXC_STD) |
47 | 76 | ||
48 | . = 0x300 | 77 | . = 0x300 |
49 | .globl data_access_pSeries | 78 | .globl data_access_pSeries |
50 | data_access_pSeries: | 79 | data_access_pSeries: |
51 | HMT_MEDIUM | 80 | HMT_MEDIUM |
52 | DO_KVM 0x300 | 81 | DO_KVM 0x300 |
53 | mtspr SPRN_SPRG_SCRATCH0,r13 | 82 | SET_SCRATCH0(r13) |
54 | BEGIN_FTR_SECTION | 83 | BEGIN_FTR_SECTION |
55 | mfspr r13,SPRN_SPRG_PACA | 84 | GET_PACA(r13) |
56 | std r9,PACA_EXSLB+EX_R9(r13) | 85 | std r9,PACA_EXSLB+EX_R9(r13) |
57 | std r10,PACA_EXSLB+EX_R10(r13) | 86 | std r10,PACA_EXSLB+EX_R10(r13) |
58 | mfspr r10,SPRN_DAR | 87 | mfspr r10,SPRN_DAR |
@@ -66,22 +95,22 @@ BEGIN_FTR_SECTION | |||
66 | std r11,PACA_EXGEN+EX_R11(r13) | 95 | std r11,PACA_EXGEN+EX_R11(r13) |
67 | ld r11,PACA_EXSLB+EX_R9(r13) | 96 | ld r11,PACA_EXSLB+EX_R9(r13) |
68 | std r12,PACA_EXGEN+EX_R12(r13) | 97 | std r12,PACA_EXGEN+EX_R12(r13) |
69 | mfspr r12,SPRN_SPRG_SCRATCH0 | 98 | GET_SCRATCH0(r12) |
70 | std r10,PACA_EXGEN+EX_R10(r13) | 99 | std r10,PACA_EXGEN+EX_R10(r13) |
71 | std r11,PACA_EXGEN+EX_R9(r13) | 100 | std r11,PACA_EXGEN+EX_R9(r13) |
72 | std r12,PACA_EXGEN+EX_R13(r13) | 101 | std r12,PACA_EXGEN+EX_R13(r13) |
73 | EXCEPTION_PROLOG_PSERIES_1(data_access_common) | 102 | EXCEPTION_PROLOG_PSERIES_1(data_access_common, EXC_STD) |
74 | FTR_SECTION_ELSE | 103 | FTR_SECTION_ELSE |
75 | EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common) | 104 | EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common, EXC_STD) |
76 | ALT_FTR_SECTION_END_IFCLR(CPU_FTR_SLB) | 105 | ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_SLB) |
77 | 106 | ||
78 | . = 0x380 | 107 | . = 0x380 |
79 | .globl data_access_slb_pSeries | 108 | .globl data_access_slb_pSeries |
80 | data_access_slb_pSeries: | 109 | data_access_slb_pSeries: |
81 | HMT_MEDIUM | 110 | HMT_MEDIUM |
82 | DO_KVM 0x380 | 111 | DO_KVM 0x380 |
83 | mtspr SPRN_SPRG_SCRATCH0,r13 | 112 | SET_SCRATCH0(r13) |
84 | mfspr r13,SPRN_SPRG_PACA /* get paca address into r13 */ | 113 | GET_PACA(r13) |
85 | std r3,PACA_EXSLB+EX_R3(r13) | 114 | std r3,PACA_EXSLB+EX_R3(r13) |
86 | mfspr r3,SPRN_DAR | 115 | mfspr r3,SPRN_DAR |
87 | std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */ | 116 | std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */ |
@@ -94,7 +123,7 @@ data_access_slb_pSeries: | |||
94 | std r10,PACA_EXSLB+EX_R10(r13) | 123 | std r10,PACA_EXSLB+EX_R10(r13) |
95 | std r11,PACA_EXSLB+EX_R11(r13) | 124 | std r11,PACA_EXSLB+EX_R11(r13) |
96 | std r12,PACA_EXSLB+EX_R12(r13) | 125 | std r12,PACA_EXSLB+EX_R12(r13) |
97 | mfspr r10,SPRN_SPRG_SCRATCH0 | 126 | GET_SCRATCH0(r10) |
98 | std r10,PACA_EXSLB+EX_R13(r13) | 127 | std r10,PACA_EXSLB+EX_R13(r13) |
99 | mfspr r12,SPRN_SRR1 /* and SRR1 */ | 128 | mfspr r12,SPRN_SRR1 /* and SRR1 */ |
100 | #ifndef CONFIG_RELOCATABLE | 129 | #ifndef CONFIG_RELOCATABLE |
@@ -112,15 +141,15 @@ data_access_slb_pSeries: | |||
112 | bctr | 141 | bctr |
113 | #endif | 142 | #endif |
114 | 143 | ||
115 | STD_EXCEPTION_PSERIES(0x400, instruction_access) | 144 | STD_EXCEPTION_PSERIES(0x400, 0x400, instruction_access) |
116 | 145 | ||
117 | . = 0x480 | 146 | . = 0x480 |
118 | .globl instruction_access_slb_pSeries | 147 | .globl instruction_access_slb_pSeries |
119 | instruction_access_slb_pSeries: | 148 | instruction_access_slb_pSeries: |
120 | HMT_MEDIUM | 149 | HMT_MEDIUM |
121 | DO_KVM 0x480 | 150 | DO_KVM 0x480 |
122 | mtspr SPRN_SPRG_SCRATCH0,r13 | 151 | SET_SCRATCH0(r13) |
123 | mfspr r13,SPRN_SPRG_PACA /* get paca address into r13 */ | 152 | GET_PACA(r13) |
124 | std r3,PACA_EXSLB+EX_R3(r13) | 153 | std r3,PACA_EXSLB+EX_R3(r13) |
125 | mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */ | 154 | mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */ |
126 | std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */ | 155 | std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */ |
@@ -133,7 +162,7 @@ instruction_access_slb_pSeries: | |||
133 | std r10,PACA_EXSLB+EX_R10(r13) | 162 | std r10,PACA_EXSLB+EX_R10(r13) |
134 | std r11,PACA_EXSLB+EX_R11(r13) | 163 | std r11,PACA_EXSLB+EX_R11(r13) |
135 | std r12,PACA_EXSLB+EX_R12(r13) | 164 | std r12,PACA_EXSLB+EX_R12(r13) |
136 | mfspr r10,SPRN_SPRG_SCRATCH0 | 165 | GET_SCRATCH0(r10) |
137 | std r10,PACA_EXSLB+EX_R13(r13) | 166 | std r10,PACA_EXSLB+EX_R13(r13) |
138 | mfspr r12,SPRN_SRR1 /* and SRR1 */ | 167 | mfspr r12,SPRN_SRR1 /* and SRR1 */ |
139 | #ifndef CONFIG_RELOCATABLE | 168 | #ifndef CONFIG_RELOCATABLE |
@@ -146,13 +175,29 @@ instruction_access_slb_pSeries: | |||
146 | bctr | 175 | bctr |
147 | #endif | 176 | #endif |
148 | 177 | ||
149 | MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt) | 178 | /* We open code these as we can't have a ". = x" (even with |
150 | STD_EXCEPTION_PSERIES(0x600, alignment) | 179 | * x = "." within a feature section |
151 | STD_EXCEPTION_PSERIES(0x700, program_check) | 180 | */ |
152 | STD_EXCEPTION_PSERIES(0x800, fp_unavailable) | 181 | . = 0x500; |
153 | MASKABLE_EXCEPTION_PSERIES(0x900, decrementer) | 182 | .globl hardware_interrupt_pSeries; |
154 | STD_EXCEPTION_PSERIES(0xa00, trap_0a) | 183 | .globl hardware_interrupt_hv; |
155 | STD_EXCEPTION_PSERIES(0xb00, trap_0b) | 184 | hardware_interrupt_pSeries: |
185 | hardware_interrupt_hv: | ||
186 | BEGIN_FTR_SECTION | ||
187 | _MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt, EXC_STD) | ||
188 | FTR_SECTION_ELSE | ||
189 | _MASKABLE_EXCEPTION_PSERIES(0x502, hardware_interrupt, EXC_HV) | ||
190 | ALT_FTR_SECTION_END_IFCLR(CPU_FTR_HVMODE_206) | ||
191 | |||
192 | STD_EXCEPTION_PSERIES(0x600, 0x600, alignment) | ||
193 | STD_EXCEPTION_PSERIES(0x700, 0x700, program_check) | ||
194 | STD_EXCEPTION_PSERIES(0x800, 0x800, fp_unavailable) | ||
195 | |||
196 | MASKABLE_EXCEPTION_PSERIES(0x900, 0x900, decrementer) | ||
197 | MASKABLE_EXCEPTION_HV(0x980, 0x980, decrementer) | ||
198 | |||
199 | STD_EXCEPTION_PSERIES(0xa00, 0xa00, trap_0a) | ||
200 | STD_EXCEPTION_PSERIES(0xb00, 0xb00, trap_0b) | ||
156 | 201 | ||
157 | . = 0xc00 | 202 | . = 0xc00 |
158 | .globl system_call_pSeries | 203 | .globl system_call_pSeries |
@@ -164,13 +209,13 @@ BEGIN_FTR_SECTION | |||
164 | beq- 1f | 209 | beq- 1f |
165 | END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) | 210 | END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) |
166 | mr r9,r13 | 211 | mr r9,r13 |
167 | mfspr r13,SPRN_SPRG_PACA | 212 | GET_PACA(r13) |
168 | mfspr r11,SPRN_SRR0 | 213 | mfspr r11,SPRN_SRR0 |
169 | ld r12,PACAKBASE(r13) | ||
170 | ld r10,PACAKMSR(r13) | ||
171 | LOAD_HANDLER(r12, system_call_entry) | ||
172 | mtspr SPRN_SRR0,r12 | ||
173 | mfspr r12,SPRN_SRR1 | 214 | mfspr r12,SPRN_SRR1 |
215 | ld r10,PACAKBASE(r13) | ||
216 | LOAD_HANDLER(r10, system_call_entry) | ||
217 | mtspr SPRN_SRR0,r10 | ||
218 | ld r10,PACAKMSR(r13) | ||
174 | mtspr SPRN_SRR1,r10 | 219 | mtspr SPRN_SRR1,r10 |
175 | rfid | 220 | rfid |
176 | b . /* prevent speculative execution */ | 221 | b . /* prevent speculative execution */ |
@@ -182,8 +227,21 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) | |||
182 | rfid /* return to userspace */ | 227 | rfid /* return to userspace */ |
183 | b . | 228 | b . |
184 | 229 | ||
185 | STD_EXCEPTION_PSERIES(0xd00, single_step) | 230 | STD_EXCEPTION_PSERIES(0xd00, 0xd00, single_step) |
186 | STD_EXCEPTION_PSERIES(0xe00, trap_0e) | 231 | |
232 | /* At 0xe??? we have a bunch of hypervisor exceptions, we branch | ||
233 | * out of line to handle them | ||
234 | */ | ||
235 | . = 0xe00 | ||
236 | b h_data_storage_hv | ||
237 | . = 0xe20 | ||
238 | b h_instr_storage_hv | ||
239 | . = 0xe40 | ||
240 | b emulation_assist_hv | ||
241 | . = 0xe50 | ||
242 | b hmi_exception_hv | ||
243 | . = 0xe60 | ||
244 | b hmi_exception_hv | ||
187 | 245 | ||
188 | /* We need to deal with the Altivec unavailable exception | 246 | /* We need to deal with the Altivec unavailable exception |
189 | * here which is at 0xf20, thus in the middle of the | 247 | * here which is at 0xf20, thus in the middle of the |
@@ -192,39 +250,42 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) | |||
192 | */ | 250 | */ |
193 | performance_monitor_pSeries_1: | 251 | performance_monitor_pSeries_1: |
194 | . = 0xf00 | 252 | . = 0xf00 |
195 | DO_KVM 0xf00 | ||
196 | b performance_monitor_pSeries | 253 | b performance_monitor_pSeries |
197 | 254 | ||
198 | altivec_unavailable_pSeries_1: | 255 | altivec_unavailable_pSeries_1: |
199 | . = 0xf20 | 256 | . = 0xf20 |
200 | DO_KVM 0xf20 | ||
201 | b altivec_unavailable_pSeries | 257 | b altivec_unavailable_pSeries |
202 | 258 | ||
203 | vsx_unavailable_pSeries_1: | 259 | vsx_unavailable_pSeries_1: |
204 | . = 0xf40 | 260 | . = 0xf40 |
205 | DO_KVM 0xf40 | ||
206 | b vsx_unavailable_pSeries | 261 | b vsx_unavailable_pSeries |
207 | 262 | ||
208 | #ifdef CONFIG_CBE_RAS | 263 | #ifdef CONFIG_CBE_RAS |
209 | HSTD_EXCEPTION_PSERIES(0x1200, cbe_system_error) | 264 | STD_EXCEPTION_HV(0x1200, 0x1202, cbe_system_error) |
210 | #endif /* CONFIG_CBE_RAS */ | 265 | #endif /* CONFIG_CBE_RAS */ |
211 | STD_EXCEPTION_PSERIES(0x1300, instruction_breakpoint) | 266 | STD_EXCEPTION_PSERIES(0x1300, 0x1300, instruction_breakpoint) |
212 | #ifdef CONFIG_CBE_RAS | 267 | #ifdef CONFIG_CBE_RAS |
213 | HSTD_EXCEPTION_PSERIES(0x1600, cbe_maintenance) | 268 | STD_EXCEPTION_HV(0x1600, 0x1602, cbe_maintenance) |
214 | #endif /* CONFIG_CBE_RAS */ | 269 | #endif /* CONFIG_CBE_RAS */ |
215 | STD_EXCEPTION_PSERIES(0x1700, altivec_assist) | 270 | STD_EXCEPTION_PSERIES(0x1700, 0x1700, altivec_assist) |
216 | #ifdef CONFIG_CBE_RAS | 271 | #ifdef CONFIG_CBE_RAS |
217 | HSTD_EXCEPTION_PSERIES(0x1800, cbe_thermal) | 272 | STD_EXCEPTION_HV(0x1800, 0x1802, cbe_thermal) |
218 | #endif /* CONFIG_CBE_RAS */ | 273 | #endif /* CONFIG_CBE_RAS */ |
219 | 274 | ||
220 | . = 0x3000 | 275 | . = 0x3000 |
221 | 276 | ||
222 | /*** pSeries interrupt support ***/ | 277 | /*** Out of line interrupts support ***/ |
278 | |||
279 | /* moved from 0xe00 */ | ||
280 | STD_EXCEPTION_HV(., 0xe00, h_data_storage) | ||
281 | STD_EXCEPTION_HV(., 0xe20, h_instr_storage) | ||
282 | STD_EXCEPTION_HV(., 0xe40, emulation_assist) | ||
283 | STD_EXCEPTION_HV(., 0xe60, hmi_exception) /* need to flush cache ? */ | ||
223 | 284 | ||
224 | /* moved from 0xf00 */ | 285 | /* moved from 0xf00 */ |
225 | STD_EXCEPTION_PSERIES(., performance_monitor) | 286 | STD_EXCEPTION_PSERIES(., 0xf00, performance_monitor) |
226 | STD_EXCEPTION_PSERIES(., altivec_unavailable) | 287 | STD_EXCEPTION_PSERIES(., 0xf20, altivec_unavailable) |
227 | STD_EXCEPTION_PSERIES(., vsx_unavailable) | 288 | STD_EXCEPTION_PSERIES(., 0xf40, vsx_unavailable) |
228 | 289 | ||
229 | /* | 290 | /* |
230 | * An interrupt came in while soft-disabled; clear EE in SRR1, | 291 | * An interrupt came in while soft-disabled; clear EE in SRR1, |
@@ -239,17 +300,30 @@ masked_interrupt: | |||
239 | rotldi r10,r10,16 | 300 | rotldi r10,r10,16 |
240 | mtspr SPRN_SRR1,r10 | 301 | mtspr SPRN_SRR1,r10 |
241 | ld r10,PACA_EXGEN+EX_R10(r13) | 302 | ld r10,PACA_EXGEN+EX_R10(r13) |
242 | mfspr r13,SPRN_SPRG_SCRATCH0 | 303 | GET_SCRATCH0(r13) |
243 | rfid | 304 | rfid |
244 | b . | 305 | b . |
245 | 306 | ||
307 | masked_Hinterrupt: | ||
308 | stb r10,PACAHARDIRQEN(r13) | ||
309 | mtcrf 0x80,r9 | ||
310 | ld r9,PACA_EXGEN+EX_R9(r13) | ||
311 | mfspr r10,SPRN_HSRR1 | ||
312 | rldicl r10,r10,48,1 /* clear MSR_EE */ | ||
313 | rotldi r10,r10,16 | ||
314 | mtspr SPRN_HSRR1,r10 | ||
315 | ld r10,PACA_EXGEN+EX_R10(r13) | ||
316 | GET_SCRATCH0(r13) | ||
317 | hrfid | ||
318 | b . | ||
319 | |||
246 | .align 7 | 320 | .align 7 |
247 | do_stab_bolted_pSeries: | 321 | do_stab_bolted_pSeries: |
248 | std r11,PACA_EXSLB+EX_R11(r13) | 322 | std r11,PACA_EXSLB+EX_R11(r13) |
249 | std r12,PACA_EXSLB+EX_R12(r13) | 323 | std r12,PACA_EXSLB+EX_R12(r13) |
250 | mfspr r10,SPRN_SPRG_SCRATCH0 | 324 | GET_SCRATCH0(r10) |
251 | std r10,PACA_EXSLB+EX_R13(r13) | 325 | std r10,PACA_EXSLB+EX_R13(r13) |
252 | EXCEPTION_PROLOG_PSERIES_1(.do_stab_bolted) | 326 | EXCEPTION_PROLOG_PSERIES_1(.do_stab_bolted, EXC_STD) |
253 | 327 | ||
254 | #ifdef CONFIG_PPC_PSERIES | 328 | #ifdef CONFIG_PPC_PSERIES |
255 | /* | 329 | /* |
@@ -259,15 +333,15 @@ do_stab_bolted_pSeries: | |||
259 | .align 7 | 333 | .align 7 |
260 | system_reset_fwnmi: | 334 | system_reset_fwnmi: |
261 | HMT_MEDIUM | 335 | HMT_MEDIUM |
262 | mtspr SPRN_SPRG_SCRATCH0,r13 /* save r13 */ | 336 | SET_SCRATCH0(r13) /* save r13 */ |
263 | EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common) | 337 | EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD) |
264 | 338 | ||
265 | .globl machine_check_fwnmi | 339 | .globl machine_check_fwnmi |
266 | .align 7 | 340 | .align 7 |
267 | machine_check_fwnmi: | 341 | machine_check_fwnmi: |
268 | HMT_MEDIUM | 342 | HMT_MEDIUM |
269 | mtspr SPRN_SPRG_SCRATCH0,r13 /* save r13 */ | 343 | SET_SCRATCH0(r13) /* save r13 */ |
270 | EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common) | 344 | EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common, EXC_STD) |
271 | 345 | ||
272 | #endif /* CONFIG_PPC_PSERIES */ | 346 | #endif /* CONFIG_PPC_PSERIES */ |
273 | 347 | ||
@@ -281,7 +355,7 @@ slb_miss_user_pseries: | |||
281 | std r10,PACA_EXGEN+EX_R10(r13) | 355 | std r10,PACA_EXGEN+EX_R10(r13) |
282 | std r11,PACA_EXGEN+EX_R11(r13) | 356 | std r11,PACA_EXGEN+EX_R11(r13) |
283 | std r12,PACA_EXGEN+EX_R12(r13) | 357 | std r12,PACA_EXGEN+EX_R12(r13) |
284 | mfspr r10,SPRG_SCRATCH0 | 358 | GET_SCRATCH0(r10) |
285 | ld r11,PACA_EXSLB+EX_R9(r13) | 359 | ld r11,PACA_EXSLB+EX_R9(r13) |
286 | ld r12,PACA_EXSLB+EX_R3(r13) | 360 | ld r12,PACA_EXSLB+EX_R3(r13) |
287 | std r10,PACA_EXGEN+EX_R13(r13) | 361 | std r10,PACA_EXGEN+EX_R13(r13) |
@@ -299,6 +373,12 @@ slb_miss_user_pseries: | |||
299 | b . /* prevent spec. execution */ | 373 | b . /* prevent spec. execution */ |
300 | #endif /* __DISABLED__ */ | 374 | #endif /* __DISABLED__ */ |
301 | 375 | ||
376 | /* KVM's trampoline code needs to be close to the interrupt handlers */ | ||
377 | |||
378 | #ifdef CONFIG_KVM_BOOK3S_64_HANDLER | ||
379 | #include "../kvm/book3s_rmhandlers.S" | ||
380 | #endif | ||
381 | |||
302 | .align 7 | 382 | .align 7 |
303 | .globl __end_interrupts | 383 | .globl __end_interrupts |
304 | __end_interrupts: | 384 | __end_interrupts: |
@@ -335,6 +415,8 @@ machine_check_common: | |||
335 | STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception) | 415 | STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception) |
336 | STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception) | 416 | STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception) |
337 | STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception) | 417 | STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception) |
418 | STD_EXCEPTION_COMMON(0xe40, emulation_assist, .program_check_exception) | ||
419 | STD_EXCEPTION_COMMON(0xe60, hmi_exception, .unknown_exception) | ||
338 | STD_EXCEPTION_COMMON_IDLE(0xf00, performance_monitor, .performance_monitor_exception) | 420 | STD_EXCEPTION_COMMON_IDLE(0xf00, performance_monitor, .performance_monitor_exception) |
339 | STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception) | 421 | STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception) |
340 | #ifdef CONFIG_ALTIVEC | 422 | #ifdef CONFIG_ALTIVEC |
@@ -379,9 +461,24 @@ bad_stack: | |||
379 | std r12,_XER(r1) | 461 | std r12,_XER(r1) |
380 | SAVE_GPR(0,r1) | 462 | SAVE_GPR(0,r1) |
381 | SAVE_GPR(2,r1) | 463 | SAVE_GPR(2,r1) |
382 | SAVE_4GPRS(3,r1) | 464 | ld r10,EX_R3(r3) |
383 | SAVE_2GPRS(7,r1) | 465 | std r10,GPR3(r1) |
384 | SAVE_10GPRS(12,r1) | 466 | SAVE_GPR(4,r1) |
467 | SAVE_4GPRS(5,r1) | ||
468 | ld r9,EX_R9(r3) | ||
469 | ld r10,EX_R10(r3) | ||
470 | SAVE_2GPRS(9,r1) | ||
471 | ld r9,EX_R11(r3) | ||
472 | ld r10,EX_R12(r3) | ||
473 | ld r11,EX_R13(r3) | ||
474 | std r9,GPR11(r1) | ||
475 | std r10,GPR12(r1) | ||
476 | std r11,GPR13(r1) | ||
477 | BEGIN_FTR_SECTION | ||
478 | ld r10,EX_CFAR(r3) | ||
479 | std r10,ORIG_GPR3(r1) | ||
480 | END_FTR_SECTION_IFSET(CPU_FTR_CFAR) | ||
481 | SAVE_8GPRS(14,r1) | ||
385 | SAVE_10GPRS(22,r1) | 482 | SAVE_10GPRS(22,r1) |
386 | lhz r12,PACA_TRAP_SAVE(r13) | 483 | lhz r12,PACA_TRAP_SAVE(r13) |
387 | std r12,_TRAP(r1) | 484 | std r12,_TRAP(r1) |
@@ -390,6 +487,9 @@ bad_stack: | |||
390 | li r12,0 | 487 | li r12,0 |
391 | std r12,0(r11) | 488 | std r12,0(r11) |
392 | ld r2,PACATOC(r13) | 489 | ld r2,PACATOC(r13) |
490 | ld r11,exception_marker@toc(r2) | ||
491 | std r12,RESULT(r1) | ||
492 | std r11,STACK_FRAME_OVERHEAD-16(r1) | ||
393 | 1: addi r3,r1,STACK_FRAME_OVERHEAD | 493 | 1: addi r3,r1,STACK_FRAME_OVERHEAD |
394 | bl .kernel_bad_stack | 494 | bl .kernel_bad_stack |
395 | b 1b | 495 | b 1b |
@@ -412,6 +512,19 @@ data_access_common: | |||
412 | li r5,0x300 | 512 | li r5,0x300 |
413 | b .do_hash_page /* Try to handle as hpte fault */ | 513 | b .do_hash_page /* Try to handle as hpte fault */ |
414 | 514 | ||
515 | .align 7 | ||
516 | .globl h_data_storage_common | ||
517 | h_data_storage_common: | ||
518 | mfspr r10,SPRN_HDAR | ||
519 | std r10,PACA_EXGEN+EX_DAR(r13) | ||
520 | mfspr r10,SPRN_HDSISR | ||
521 | stw r10,PACA_EXGEN+EX_DSISR(r13) | ||
522 | EXCEPTION_PROLOG_COMMON(0xe00, PACA_EXGEN) | ||
523 | bl .save_nvgprs | ||
524 | addi r3,r1,STACK_FRAME_OVERHEAD | ||
525 | bl .unknown_exception | ||
526 | b .ret_from_except | ||
527 | |||
415 | .align 7 | 528 | .align 7 |
416 | .globl instruction_access_common | 529 | .globl instruction_access_common |
417 | instruction_access_common: | 530 | instruction_access_common: |
@@ -421,6 +534,8 @@ instruction_access_common: | |||
421 | li r5,0x400 | 534 | li r5,0x400 |
422 | b .do_hash_page /* Try to handle as hpte fault */ | 535 | b .do_hash_page /* Try to handle as hpte fault */ |
423 | 536 | ||
537 | STD_EXCEPTION_COMMON(0xe20, h_instr_storage, .unknown_exception) | ||
538 | |||
424 | /* | 539 | /* |
425 | * Here is the common SLB miss user that is used when going to virtual | 540 | * Here is the common SLB miss user that is used when going to virtual |
426 | * mode for SLB misses, that is currently not used | 541 | * mode for SLB misses, that is currently not used |
@@ -743,7 +858,7 @@ _STATIC(do_hash_page) | |||
743 | BEGIN_FTR_SECTION | 858 | BEGIN_FTR_SECTION |
744 | andis. r0,r4,0x0020 /* Is it a segment table fault? */ | 859 | andis. r0,r4,0x0020 /* Is it a segment table fault? */ |
745 | bne- do_ste_alloc /* If so handle it */ | 860 | bne- do_ste_alloc /* If so handle it */ |
746 | END_FTR_SECTION_IFCLR(CPU_FTR_SLB) | 861 | END_MMU_FTR_SECTION_IFCLR(MMU_FTR_SLB) |
747 | 862 | ||
748 | clrrdi r11,r1,THREAD_SHIFT | 863 | clrrdi r11,r1,THREAD_SHIFT |
749 | lwz r0,TI_PREEMPT(r11) /* If we're in an "NMI" */ | 864 | lwz r0,TI_PREEMPT(r11) /* If we're in an "NMI" */ |
@@ -818,12 +933,12 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES) | |||
818 | 933 | ||
819 | /* | 934 | /* |
820 | * hash_page couldn't handle it, set soft interrupt enable back | 935 | * hash_page couldn't handle it, set soft interrupt enable back |
821 | * to what it was before the trap. Note that .raw_local_irq_restore | 936 | * to what it was before the trap. Note that .arch_local_irq_restore |
822 | * handles any interrupts pending at this point. | 937 | * handles any interrupts pending at this point. |
823 | */ | 938 | */ |
824 | ld r3,SOFTE(r1) | 939 | ld r3,SOFTE(r1) |
825 | TRACE_AND_RESTORE_IRQ_PARTIAL(r3, 11f) | 940 | TRACE_AND_RESTORE_IRQ_PARTIAL(r3, 11f) |
826 | bl .raw_local_irq_restore | 941 | bl .arch_local_irq_restore |
827 | b 11f | 942 | b 11f |
828 | 943 | ||
829 | /* We have a data breakpoint exception - handle it */ | 944 | /* We have a data breakpoint exception - handle it */ |
@@ -970,20 +1085,6 @@ _GLOBAL(do_stab_bolted) | |||
970 | rfid | 1085 | rfid |
971 | b . /* prevent speculative execution */ | 1086 | b . /* prevent speculative execution */ |
972 | 1087 | ||
973 | /* | ||
974 | * Space for CPU0's segment table. | ||
975 | * | ||
976 | * On iSeries, the hypervisor must fill in at least one entry before | ||
977 | * we get control (with relocate on). The address is given to the hv | ||
978 | * as a page number (see xLparMap below), so this must be at a | ||
979 | * fixed address (the linker can't compute (u64)&initial_stab >> | ||
980 | * PAGE_SHIFT). | ||
981 | */ | ||
982 | . = STAB0_OFFSET /* 0x6000 */ | ||
983 | .globl initial_stab | ||
984 | initial_stab: | ||
985 | .space 4096 | ||
986 | |||
987 | #ifdef CONFIG_PPC_PSERIES | 1088 | #ifdef CONFIG_PPC_PSERIES |
988 | /* | 1089 | /* |
989 | * Data area reserved for FWNMI option. | 1090 | * Data area reserved for FWNMI option. |
@@ -1020,3 +1121,17 @@ xLparMap: | |||
1020 | #ifdef CONFIG_PPC_PSERIES | 1121 | #ifdef CONFIG_PPC_PSERIES |
1021 | . = 0x8000 | 1122 | . = 0x8000 |
1022 | #endif /* CONFIG_PPC_PSERIES */ | 1123 | #endif /* CONFIG_PPC_PSERIES */ |
1124 | |||
1125 | /* | ||
1126 | * Space for CPU0's segment table. | ||
1127 | * | ||
1128 | * On iSeries, the hypervisor must fill in at least one entry before | ||
1129 | * we get control (with relocate on). The address is given to the hv | ||
1130 | * as a page number (see xLparMap above), so this must be at a | ||
1131 | * fixed address (the linker can't compute (u64)&initial_stab >> | ||
1132 | * PAGE_SHIFT). | ||
1133 | */ | ||
1134 | . = STAB0_OFFSET /* 0x8000 */ | ||
1135 | .globl initial_stab | ||
1136 | initial_stab: | ||
1137 | .space 4096 | ||