diff options
Diffstat (limited to 'arch/powerpc/kvm/booke_interrupts.S')
-rw-r--r-- | arch/powerpc/kvm/booke_interrupts.S | 49 |
1 files changed, 40 insertions, 9 deletions
diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S index bb46b32f9813..f4bb55c96517 100644 --- a/arch/powerpc/kvm/booke_interrupts.S +++ b/arch/powerpc/kvm/booke_interrupts.S | |||
@@ -45,18 +45,21 @@ | |||
45 | (1<<BOOKE_INTERRUPT_DEBUG)) | 45 | (1<<BOOKE_INTERRUPT_DEBUG)) |
46 | 46 | ||
47 | #define NEED_DEAR_MASK ((1<<BOOKE_INTERRUPT_DATA_STORAGE) | \ | 47 | #define NEED_DEAR_MASK ((1<<BOOKE_INTERRUPT_DATA_STORAGE) | \ |
48 | (1<<BOOKE_INTERRUPT_DTLB_MISS)) | 48 | (1<<BOOKE_INTERRUPT_DTLB_MISS) | \ |
49 | (1<<BOOKE_INTERRUPT_ALIGNMENT)) | ||
49 | 50 | ||
50 | #define NEED_ESR_MASK ((1<<BOOKE_INTERRUPT_DATA_STORAGE) | \ | 51 | #define NEED_ESR_MASK ((1<<BOOKE_INTERRUPT_DATA_STORAGE) | \ |
51 | (1<<BOOKE_INTERRUPT_INST_STORAGE) | \ | 52 | (1<<BOOKE_INTERRUPT_INST_STORAGE) | \ |
52 | (1<<BOOKE_INTERRUPT_PROGRAM) | \ | 53 | (1<<BOOKE_INTERRUPT_PROGRAM) | \ |
53 | (1<<BOOKE_INTERRUPT_DTLB_MISS)) | 54 | (1<<BOOKE_INTERRUPT_DTLB_MISS) | \ |
55 | (1<<BOOKE_INTERRUPT_ALIGNMENT)) | ||
54 | 56 | ||
55 | .macro KVM_HANDLER ivor_nr scratch srr0 | 57 | .macro KVM_HANDLER ivor_nr scratch srr0 |
56 | _GLOBAL(kvmppc_handler_\ivor_nr) | 58 | _GLOBAL(kvmppc_handler_\ivor_nr) |
57 | /* Get pointer to vcpu and record exit number. */ | 59 | /* Get pointer to vcpu and record exit number. */ |
58 | mtspr \scratch , r4 | 60 | mtspr \scratch , r4 |
59 | mfspr r4, SPRN_SPRG_RVCPU | 61 | mfspr r4, SPRN_SPRG_THREAD |
62 | lwz r4, THREAD_KVM_VCPU(r4) | ||
60 | stw r3, VCPU_GPR(R3)(r4) | 63 | stw r3, VCPU_GPR(R3)(r4) |
61 | stw r5, VCPU_GPR(R5)(r4) | 64 | stw r5, VCPU_GPR(R5)(r4) |
62 | stw r6, VCPU_GPR(R6)(r4) | 65 | stw r6, VCPU_GPR(R6)(r4) |
@@ -73,6 +76,14 @@ _GLOBAL(kvmppc_handler_\ivor_nr) | |||
73 | bctr | 76 | bctr |
74 | .endm | 77 | .endm |
75 | 78 | ||
79 | .macro KVM_HANDLER_ADDR ivor_nr | ||
80 | .long kvmppc_handler_\ivor_nr | ||
81 | .endm | ||
82 | |||
83 | .macro KVM_HANDLER_END | ||
84 | .long kvmppc_handlers_end | ||
85 | .endm | ||
86 | |||
76 | _GLOBAL(kvmppc_handlers_start) | 87 | _GLOBAL(kvmppc_handlers_start) |
77 | KVM_HANDLER BOOKE_INTERRUPT_CRITICAL SPRN_SPRG_RSCRATCH_CRIT SPRN_CSRR0 | 88 | KVM_HANDLER BOOKE_INTERRUPT_CRITICAL SPRN_SPRG_RSCRATCH_CRIT SPRN_CSRR0 |
78 | KVM_HANDLER BOOKE_INTERRUPT_MACHINE_CHECK SPRN_SPRG_RSCRATCH_MC SPRN_MCSRR0 | 89 | KVM_HANDLER BOOKE_INTERRUPT_MACHINE_CHECK SPRN_SPRG_RSCRATCH_MC SPRN_MCSRR0 |
@@ -93,9 +104,7 @@ KVM_HANDLER BOOKE_INTERRUPT_DEBUG SPRN_SPRG_RSCRATCH_CRIT SPRN_CSRR0 | |||
93 | KVM_HANDLER BOOKE_INTERRUPT_SPE_UNAVAIL SPRN_SPRG_RSCRATCH0 SPRN_SRR0 | 104 | KVM_HANDLER BOOKE_INTERRUPT_SPE_UNAVAIL SPRN_SPRG_RSCRATCH0 SPRN_SRR0 |
94 | KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_DATA SPRN_SPRG_RSCRATCH0 SPRN_SRR0 | 105 | KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_DATA SPRN_SPRG_RSCRATCH0 SPRN_SRR0 |
95 | KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_ROUND SPRN_SPRG_RSCRATCH0 SPRN_SRR0 | 106 | KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_ROUND SPRN_SPRG_RSCRATCH0 SPRN_SRR0 |
96 | 107 | _GLOBAL(kvmppc_handlers_end) | |
97 | _GLOBAL(kvmppc_handler_len) | ||
98 | .long kvmppc_handler_1 - kvmppc_handler_0 | ||
99 | 108 | ||
100 | /* Registers: | 109 | /* Registers: |
101 | * SPRG_SCRATCH0: guest r4 | 110 | * SPRG_SCRATCH0: guest r4 |
@@ -402,9 +411,6 @@ lightweight_exit: | |||
402 | lwz r8, kvmppc_booke_handlers@l(r8) | 411 | lwz r8, kvmppc_booke_handlers@l(r8) |
403 | mtspr SPRN_IVPR, r8 | 412 | mtspr SPRN_IVPR, r8 |
404 | 413 | ||
405 | /* Save vcpu pointer for the exception handlers. */ | ||
406 | mtspr SPRN_SPRG_WVCPU, r4 | ||
407 | |||
408 | lwz r5, VCPU_SHARED(r4) | 414 | lwz r5, VCPU_SHARED(r4) |
409 | 415 | ||
410 | /* Can't switch the stack pointer until after IVPR is switched, | 416 | /* Can't switch the stack pointer until after IVPR is switched, |
@@ -463,6 +469,31 @@ lightweight_exit: | |||
463 | lwz r4, VCPU_GPR(R4)(r4) | 469 | lwz r4, VCPU_GPR(R4)(r4) |
464 | rfi | 470 | rfi |
465 | 471 | ||
472 | .data | ||
473 | .align 4 | ||
474 | .globl kvmppc_booke_handler_addr | ||
475 | kvmppc_booke_handler_addr: | ||
476 | KVM_HANDLER_ADDR BOOKE_INTERRUPT_CRITICAL | ||
477 | KVM_HANDLER_ADDR BOOKE_INTERRUPT_MACHINE_CHECK | ||
478 | KVM_HANDLER_ADDR BOOKE_INTERRUPT_DATA_STORAGE | ||
479 | KVM_HANDLER_ADDR BOOKE_INTERRUPT_INST_STORAGE | ||
480 | KVM_HANDLER_ADDR BOOKE_INTERRUPT_EXTERNAL | ||
481 | KVM_HANDLER_ADDR BOOKE_INTERRUPT_ALIGNMENT | ||
482 | KVM_HANDLER_ADDR BOOKE_INTERRUPT_PROGRAM | ||
483 | KVM_HANDLER_ADDR BOOKE_INTERRUPT_FP_UNAVAIL | ||
484 | KVM_HANDLER_ADDR BOOKE_INTERRUPT_SYSCALL | ||
485 | KVM_HANDLER_ADDR BOOKE_INTERRUPT_AP_UNAVAIL | ||
486 | KVM_HANDLER_ADDR BOOKE_INTERRUPT_DECREMENTER | ||
487 | KVM_HANDLER_ADDR BOOKE_INTERRUPT_FIT | ||
488 | KVM_HANDLER_ADDR BOOKE_INTERRUPT_WATCHDOG | ||
489 | KVM_HANDLER_ADDR BOOKE_INTERRUPT_DTLB_MISS | ||
490 | KVM_HANDLER_ADDR BOOKE_INTERRUPT_ITLB_MISS | ||
491 | KVM_HANDLER_ADDR BOOKE_INTERRUPT_DEBUG | ||
492 | KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_UNAVAIL | ||
493 | KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_FP_DATA | ||
494 | KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_FP_ROUND | ||
495 | KVM_HANDLER_END /*Always keep this in end*/ | ||
496 | |||
466 | #ifdef CONFIG_SPE | 497 | #ifdef CONFIG_SPE |
467 | _GLOBAL(kvmppc_save_guest_spe) | 498 | _GLOBAL(kvmppc_save_guest_spe) |
468 | cmpi 0,r3,0 | 499 | cmpi 0,r3,0 |