aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm/booke_interrupts.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kvm/booke_interrupts.S')
-rw-r--r--arch/powerpc/kvm/booke_interrupts.S49
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)
77KVM_HANDLER BOOKE_INTERRUPT_CRITICAL SPRN_SPRG_RSCRATCH_CRIT SPRN_CSRR0 88KVM_HANDLER BOOKE_INTERRUPT_CRITICAL SPRN_SPRG_RSCRATCH_CRIT SPRN_CSRR0
78KVM_HANDLER BOOKE_INTERRUPT_MACHINE_CHECK SPRN_SPRG_RSCRATCH_MC SPRN_MCSRR0 89KVM_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
93KVM_HANDLER BOOKE_INTERRUPT_SPE_UNAVAIL SPRN_SPRG_RSCRATCH0 SPRN_SRR0 104KVM_HANDLER BOOKE_INTERRUPT_SPE_UNAVAIL SPRN_SPRG_RSCRATCH0 SPRN_SRR0
94KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_DATA SPRN_SPRG_RSCRATCH0 SPRN_SRR0 105KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_DATA SPRN_SPRG_RSCRATCH0 SPRN_SRR0
95KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_ROUND SPRN_SPRG_RSCRATCH0 SPRN_SRR0 106KVM_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
475kvmppc_booke_handler_addr:
476KVM_HANDLER_ADDR BOOKE_INTERRUPT_CRITICAL
477KVM_HANDLER_ADDR BOOKE_INTERRUPT_MACHINE_CHECK
478KVM_HANDLER_ADDR BOOKE_INTERRUPT_DATA_STORAGE
479KVM_HANDLER_ADDR BOOKE_INTERRUPT_INST_STORAGE
480KVM_HANDLER_ADDR BOOKE_INTERRUPT_EXTERNAL
481KVM_HANDLER_ADDR BOOKE_INTERRUPT_ALIGNMENT
482KVM_HANDLER_ADDR BOOKE_INTERRUPT_PROGRAM
483KVM_HANDLER_ADDR BOOKE_INTERRUPT_FP_UNAVAIL
484KVM_HANDLER_ADDR BOOKE_INTERRUPT_SYSCALL
485KVM_HANDLER_ADDR BOOKE_INTERRUPT_AP_UNAVAIL
486KVM_HANDLER_ADDR BOOKE_INTERRUPT_DECREMENTER
487KVM_HANDLER_ADDR BOOKE_INTERRUPT_FIT
488KVM_HANDLER_ADDR BOOKE_INTERRUPT_WATCHDOG
489KVM_HANDLER_ADDR BOOKE_INTERRUPT_DTLB_MISS
490KVM_HANDLER_ADDR BOOKE_INTERRUPT_ITLB_MISS
491KVM_HANDLER_ADDR BOOKE_INTERRUPT_DEBUG
492KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_UNAVAIL
493KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_FP_DATA
494KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_FP_ROUND
495KVM_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