diff options
| author | Michael Ellerman <mpe@ellerman.id.au> | 2016-09-30 05:43:18 -0400 |
|---|---|---|
| committer | Michael Ellerman <mpe@ellerman.id.au> | 2016-10-03 22:06:36 -0400 |
| commit | da2bc4644c75d992427c45c5ade3bdf18ca1b52d (patch) | |
| tree | 412a6767cf27d5fd6e09f3a85cc17efcab35bf2f /arch/powerpc/include | |
| parent | 5045ea37377ce8cca6890d32b127ad6770e6dce5 (diff) | |
powerpc/64s: Add new exception vector macros
Create arch/powerpc/include/asm/head-64.h with macros that specify
an exception vector (name, type, location), which will be used to
label and lay out exceptions into the object file.
Naming is moved out of exception-64s.h, which is used to specify the
implementation of exception handlers.
objdump of generated code in exception vectors is unchanged except for
names. Alignment directives scattered around are annoying, but done
this way so that disassembly can verify identical instruction
generation before and after patch. These get cleaned up in future
patch.
We change the way KVMTEST works, explicitly passing EXC_HV or EXC_STD
rather than overloading the trap number. This removes the need to have
SOFTEN values for the overloaded trap numbers, eg. 0x502.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc/include')
| -rw-r--r-- | arch/powerpc/include/asm/exception-64s.h | 135 | ||||
| -rw-r--r-- | arch/powerpc/include/asm/head-64.h | 163 |
2 files changed, 217 insertions, 81 deletions
diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index 5032a80e8f6a..72f2b1e3f343 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | * exception handlers (including pSeries LPAR) and iSeries LPAR | 34 | * exception handlers (including pSeries LPAR) and iSeries LPAR |
| 35 | * implementations as possible. | 35 | * implementations as possible. |
| 36 | */ | 36 | */ |
| 37 | #include <asm/head-64.h> | ||
| 37 | 38 | ||
| 38 | #define EX_R9 0 | 39 | #define EX_R9 0 |
| 39 | #define EX_R10 8 | 40 | #define EX_R10 8 |
| @@ -191,10 +192,10 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) | |||
| 191 | EXCEPTION_PROLOG_1(area, extra, vec); \ | 192 | EXCEPTION_PROLOG_1(area, extra, vec); \ |
| 192 | EXCEPTION_PROLOG_PSERIES_1(label, h); | 193 | EXCEPTION_PROLOG_PSERIES_1(label, h); |
| 193 | 194 | ||
| 194 | #define __KVMTEST(n) \ | 195 | #define __KVMTEST(h, n) \ |
| 195 | lbz r10,HSTATE_IN_GUEST(r13); \ | 196 | lbz r10,HSTATE_IN_GUEST(r13); \ |
| 196 | cmpwi r10,0; \ | 197 | cmpwi r10,0; \ |
| 197 | bne do_kvm_##n | 198 | bne do_kvm_##h##n |
| 198 | 199 | ||
| 199 | #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE | 200 | #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE |
| 200 | /* | 201 | /* |
| @@ -207,8 +208,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) | |||
| 207 | #define kvmppc_interrupt kvmppc_interrupt_pr | 208 | #define kvmppc_interrupt kvmppc_interrupt_pr |
| 208 | #endif | 209 | #endif |
| 209 | 210 | ||
| 210 | #define __KVM_HANDLER(area, h, n) \ | 211 | #define __KVM_HANDLER_PROLOG(area, n) \ |
| 211 | do_kvm_##n: \ | ||
| 212 | BEGIN_FTR_SECTION_NESTED(947) \ | 212 | BEGIN_FTR_SECTION_NESTED(947) \ |
| 213 | ld r10,area+EX_CFAR(r13); \ | 213 | ld r10,area+EX_CFAR(r13); \ |
| 214 | std r10,HSTATE_CFAR(r13); \ | 214 | std r10,HSTATE_CFAR(r13); \ |
| @@ -221,21 +221,23 @@ do_kvm_##n: \ | |||
| 221 | stw r9,HSTATE_SCRATCH1(r13); \ | 221 | stw r9,HSTATE_SCRATCH1(r13); \ |
| 222 | ld r9,area+EX_R9(r13); \ | 222 | ld r9,area+EX_R9(r13); \ |
| 223 | std r12,HSTATE_SCRATCH0(r13); \ | 223 | std r12,HSTATE_SCRATCH0(r13); \ |
| 224 | |||
| 225 | #define __KVM_HANDLER(area, h, n) \ | ||
| 226 | __KVM_HANDLER_PROLOG(area, n) \ | ||
| 224 | li r12,n; \ | 227 | li r12,n; \ |
| 225 | b kvmppc_interrupt | 228 | b kvmppc_interrupt |
| 226 | 229 | ||
| 227 | #define __KVM_HANDLER_SKIP(area, h, n) \ | 230 | #define __KVM_HANDLER_SKIP(area, h, n) \ |
| 228 | do_kvm_##n: \ | ||
| 229 | cmpwi r10,KVM_GUEST_MODE_SKIP; \ | 231 | cmpwi r10,KVM_GUEST_MODE_SKIP; \ |
| 230 | ld r10,area+EX_R10(r13); \ | 232 | ld r10,area+EX_R10(r13); \ |
| 231 | beq 89f; \ | 233 | beq 89f; \ |
| 232 | stw r9,HSTATE_SCRATCH1(r13); \ | 234 | stw r9,HSTATE_SCRATCH1(r13); \ |
| 233 | BEGIN_FTR_SECTION_NESTED(948) \ | 235 | BEGIN_FTR_SECTION_NESTED(948) \ |
| 234 | ld r9,area+EX_PPR(r13); \ | 236 | ld r9,area+EX_PPR(r13); \ |
| 235 | std r9,HSTATE_PPR(r13); \ | 237 | std r9,HSTATE_PPR(r13); \ |
| 236 | END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,948); \ | 238 | END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,948); \ |
| 237 | ld r9,area+EX_R9(r13); \ | 239 | ld r9,area+EX_R9(r13); \ |
| 238 | std r12,HSTATE_SCRATCH0(r13); \ | 240 | std r12,HSTATE_SCRATCH0(r13); \ |
| 239 | li r12,n; \ | 241 | li r12,n; \ |
| 240 | b kvmppc_interrupt; \ | 242 | b kvmppc_interrupt; \ |
| 241 | 89: mtocrf 0x80,r9; \ | 243 | 89: mtocrf 0x80,r9; \ |
| @@ -243,12 +245,12 @@ do_kvm_##n: \ | |||
| 243 | b kvmppc_skip_##h##interrupt | 245 | b kvmppc_skip_##h##interrupt |
| 244 | 246 | ||
| 245 | #ifdef CONFIG_KVM_BOOK3S_64_HANDLER | 247 | #ifdef CONFIG_KVM_BOOK3S_64_HANDLER |
| 246 | #define KVMTEST(n) __KVMTEST(n) | 248 | #define KVMTEST(h, n) __KVMTEST(h, n) |
| 247 | #define KVM_HANDLER(area, h, n) __KVM_HANDLER(area, h, n) | 249 | #define KVM_HANDLER(area, h, n) __KVM_HANDLER(area, h, n) |
| 248 | #define KVM_HANDLER_SKIP(area, h, n) __KVM_HANDLER_SKIP(area, h, n) | 250 | #define KVM_HANDLER_SKIP(area, h, n) __KVM_HANDLER_SKIP(area, h, n) |
| 249 | 251 | ||
| 250 | #else | 252 | #else |
| 251 | #define KVMTEST(n) | 253 | #define KVMTEST(h, n) |
| 252 | #define KVM_HANDLER(area, h, n) | 254 | #define KVM_HANDLER(area, h, n) |
| 253 | #define KVM_HANDLER_SKIP(area, h, n) | 255 | #define KVM_HANDLER_SKIP(area, h, n) |
| 254 | #endif | 256 | #endif |
| @@ -332,94 +334,79 @@ do_kvm_##n: \ | |||
| 332 | /* | 334 | /* |
| 333 | * Exception vectors. | 335 | * Exception vectors. |
| 334 | */ | 336 | */ |
| 335 | #define STD_EXCEPTION_PSERIES(vec, label) \ | 337 | #define STD_EXCEPTION_PSERIES(vec, label) \ |
| 336 | . = vec; \ | ||
| 337 | .globl label##_pSeries; \ | ||
| 338 | label##_pSeries: \ | ||
| 339 | SET_SCRATCH0(r13); /* save r13 */ \ | 338 | SET_SCRATCH0(r13); /* save r13 */ \ |
| 340 | EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, \ | 339 | EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label, \ |
| 341 | EXC_STD, KVMTEST, vec) | 340 | EXC_STD, KVMTEST_PR, vec); \ |
| 342 | 341 | ||
| 343 | /* Version of above for when we have to branch out-of-line */ | 342 | /* Version of above for when we have to branch out-of-line */ |
| 343 | #define __OOL_EXCEPTION(vec, label, hdlr) \ | ||
| 344 | SET_SCRATCH0(r13) \ | ||
| 345 | EXCEPTION_PROLOG_0(PACA_EXGEN) \ | ||
| 346 | b hdlr; | ||
| 347 | |||
| 344 | #define STD_EXCEPTION_PSERIES_OOL(vec, label) \ | 348 | #define STD_EXCEPTION_PSERIES_OOL(vec, label) \ |
| 345 | .globl label##_pSeries; \ | 349 | EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_PR, vec); \ |
| 346 | label##_pSeries: \ | 350 | EXCEPTION_PROLOG_PSERIES_1(label, EXC_STD) |
| 347 | EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST, vec); \ | 351 | |
| 348 | EXCEPTION_PROLOG_PSERIES_1(label##_common, EXC_STD) | 352 | #define STD_EXCEPTION_HV(loc, vec, label) \ |
| 349 | |||
| 350 | #define STD_EXCEPTION_HV(loc, vec, label) \ | ||
| 351 | . = loc; \ | ||
| 352 | .globl label##_hv; \ | ||
| 353 | label##_hv: \ | ||
| 354 | SET_SCRATCH0(r13); /* save r13 */ \ | 353 | SET_SCRATCH0(r13); /* save r13 */ \ |
| 355 | EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, \ | 354 | EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label, \ |
| 356 | EXC_HV, KVMTEST, vec) | 355 | EXC_HV, KVMTEST_HV, vec); |
| 357 | 356 | ||
| 358 | /* Version of above for when we have to branch out-of-line */ | 357 | #define STD_EXCEPTION_HV_OOL(vec, label) \ |
| 359 | #define STD_EXCEPTION_HV_OOL(vec, label) \ | 358 | EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_HV, vec); \ |
| 360 | .globl label##_hv; \ | 359 | EXCEPTION_PROLOG_PSERIES_1(label, EXC_HV) |
| 361 | label##_hv: \ | ||
| 362 | EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST, vec); \ | ||
| 363 | EXCEPTION_PROLOG_PSERIES_1(label##_common, EXC_HV) | ||
| 364 | 360 | ||
| 365 | #define STD_RELON_EXCEPTION_PSERIES(loc, vec, label) \ | 361 | #define STD_RELON_EXCEPTION_PSERIES(loc, vec, label) \ |
| 366 | . = loc; \ | ||
| 367 | .globl label##_relon_pSeries; \ | ||
| 368 | label##_relon_pSeries: \ | ||
| 369 | /* No guest interrupts come through here */ \ | 362 | /* No guest interrupts come through here */ \ |
| 370 | SET_SCRATCH0(r13); /* save r13 */ \ | 363 | SET_SCRATCH0(r13); /* save r13 */ \ |
| 371 | EXCEPTION_RELON_PROLOG_PSERIES(PACA_EXGEN, label##_common, \ | 364 | EXCEPTION_RELON_PROLOG_PSERIES(PACA_EXGEN, label, EXC_STD, NOTEST, vec); |
| 372 | EXC_STD, NOTEST, vec) | ||
| 373 | 365 | ||
| 374 | #define STD_RELON_EXCEPTION_PSERIES_OOL(vec, label) \ | 366 | #define STD_RELON_EXCEPTION_PSERIES_OOL(vec, label) \ |
| 375 | .globl label##_relon_pSeries; \ | ||
| 376 | label##_relon_pSeries: \ | ||
| 377 | EXCEPTION_PROLOG_1(PACA_EXGEN, NOTEST, vec); \ | 367 | EXCEPTION_PROLOG_1(PACA_EXGEN, NOTEST, vec); \ |
| 378 | EXCEPTION_RELON_PROLOG_PSERIES_1(label##_common, EXC_STD) | 368 | EXCEPTION_RELON_PROLOG_PSERIES_1(label, EXC_STD) |
| 379 | 369 | ||
| 380 | #define STD_RELON_EXCEPTION_HV(loc, vec, label) \ | 370 | #define STD_RELON_EXCEPTION_HV(loc, vec, label) \ |
| 381 | . = loc; \ | ||
| 382 | .globl label##_relon_hv; \ | ||
| 383 | label##_relon_hv: \ | ||
| 384 | /* No guest interrupts come through here */ \ | 371 | /* No guest interrupts come through here */ \ |
| 385 | SET_SCRATCH0(r13); /* save r13 */ \ | 372 | SET_SCRATCH0(r13); /* save r13 */ \ |
| 386 | EXCEPTION_RELON_PROLOG_PSERIES(PACA_EXGEN, label##_common, \ | 373 | EXCEPTION_RELON_PROLOG_PSERIES(PACA_EXGEN, label, EXC_HV, NOTEST, vec); |
| 387 | EXC_HV, NOTEST, vec) | ||
| 388 | 374 | ||
| 389 | #define STD_RELON_EXCEPTION_HV_OOL(vec, label) \ | 375 | #define STD_RELON_EXCEPTION_HV_OOL(vec, label) \ |
