aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/include/asm/hw_irq.h2
-rw-r--r--arch/powerpc/kvm/booke.c21
-rw-r--r--arch/powerpc/kvm/booke_emulate.c25
-rw-r--r--arch/powerpc/kvm/booke_interrupts.S55
-rw-r--r--arch/powerpc/kvm/bookehv_interrupts.S2
-rw-r--r--arch/powerpc/kvm/e500mc.c8
-rw-r--r--arch/powerpc/kvm/emulate.c16
7 files changed, 98 insertions, 31 deletions
diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h
index c9aac24b02e2..2aadb47efaec 100644
--- a/arch/powerpc/include/asm/hw_irq.h
+++ b/arch/powerpc/include/asm/hw_irq.h
@@ -34,6 +34,8 @@ extern void __replay_interrupt(unsigned int vector);
34 34
35extern void timer_interrupt(struct pt_regs *); 35extern void timer_interrupt(struct pt_regs *);
36extern void performance_monitor_exception(struct pt_regs *regs); 36extern void performance_monitor_exception(struct pt_regs *regs);
37extern void WatchdogException(struct pt_regs *regs);
38extern void unknown_exception(struct pt_regs *regs);
37 39
38#ifdef CONFIG_PPC64 40#ifdef CONFIG_PPC64
39#include <asm/paca.h> 41#include <asm/paca.h>
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 86681eec60b1..d25a097c852b 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -612,6 +612,12 @@ static void kvmppc_fill_pt_regs(struct pt_regs *regs)
612 regs->link = lr; 612 regs->link = lr;
613} 613}
614 614
615/*
616 * For interrupts needed to be handled by host interrupt handlers,
617 * corresponding host handler are called from here in similar way
618 * (but not exact) as they are called from low level handler
619 * (such as from arch/powerpc/kernel/head_fsl_booke.S).
620 */
615static void kvmppc_restart_interrupt(struct kvm_vcpu *vcpu, 621static void kvmppc_restart_interrupt(struct kvm_vcpu *vcpu,
616 unsigned int exit_nr) 622 unsigned int exit_nr)
617{ 623{
@@ -639,6 +645,17 @@ static void kvmppc_restart_interrupt(struct kvm_vcpu *vcpu,
639 kvmppc_fill_pt_regs(&regs); 645 kvmppc_fill_pt_regs(&regs);
640 performance_monitor_exception(&regs); 646 performance_monitor_exception(&regs);
641 break; 647 break;
648 case BOOKE_INTERRUPT_WATCHDOG:
649 kvmppc_fill_pt_regs(&regs);
650#ifdef CONFIG_BOOKE_WDT
651 WatchdogException(&regs);
652#else
653 unknown_exception(&regs);
654#endif
655 break;
656 case BOOKE_INTERRUPT_CRITICAL:
657 unknown_exception(&regs);
658 break;
642 } 659 }
643} 660}
644 661
@@ -683,6 +700,10 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
683 r = RESUME_GUEST; 700 r = RESUME_GUEST;
684 break; 701 break;
685 702
703 case BOOKE_INTERRUPT_WATCHDOG:
704 r = RESUME_GUEST;
705 break;
706
686 case BOOKE_INTERRUPT_DOORBELL: 707 case BOOKE_INTERRUPT_DOORBELL:
687 kvmppc_account_exit(vcpu, DBELL_EXITS); 708 kvmppc_account_exit(vcpu, DBELL_EXITS);
688 r = RESUME_GUEST; 709 r = RESUME_GUEST;
diff --git a/arch/powerpc/kvm/booke_emulate.c b/arch/powerpc/kvm/booke_emulate.c
index 9eb9809eb13e..12834bb608ab 100644
--- a/arch/powerpc/kvm/booke_emulate.c
+++ b/arch/powerpc/kvm/booke_emulate.c
@@ -24,6 +24,7 @@
24#include "booke.h" 24#include "booke.h"
25 25
26#define OP_19_XOP_RFI 50 26#define OP_19_XOP_RFI 50
27#define OP_19_XOP_RFCI 51
27 28
28#define OP_31_XOP_MFMSR 83 29#define OP_31_XOP_MFMSR 83
29#define OP_31_XOP_WRTEE 131 30#define OP_31_XOP_WRTEE 131
@@ -36,6 +37,12 @@ static void kvmppc_emul_rfi(struct kvm_vcpu *vcpu)
36 kvmppc_set_msr(vcpu, vcpu->arch.shared->srr1); 37 kvmppc_set_msr(vcpu, vcpu->arch.shared->srr1);
37} 38}
38 39
40static void kvmppc_emul_rfci(struct kvm_vcpu *vcpu)
41{
42 vcpu->arch.pc = vcpu->arch.csrr0;
43 kvmppc_set_msr(vcpu, vcpu->arch.csrr1);
44}
45
39int kvmppc_booke_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, 46int kvmppc_booke_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
40 unsigned int inst, int *advance) 47 unsigned int inst, int *advance)
41{ 48{
@@ -52,6 +59,12 @@ int kvmppc_booke_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
52 *advance = 0; 59 *advance = 0;
53 break; 60 break;
54 61
62 case OP_19_XOP_RFCI:
63 kvmppc_emul_rfci(vcpu);
64 kvmppc_set_exit_type(vcpu, EMULATED_RFCI_EXITS);
65 *advance = 0;
66 break;
67
55 default: 68 default:
56 emulated = EMULATE_FAIL; 69 emulated = EMULATE_FAIL;
57 break; 70 break;
@@ -113,6 +126,12 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val)
113 case SPRN_ESR: 126 case SPRN_ESR:
114 vcpu->arch.shared->esr = spr_val; 127 vcpu->arch.shared->esr = spr_val;
115 break; 128 break;
129 case SPRN_CSRR0:
130 vcpu->arch.csrr0 = spr_val;
131 break;
132 case SPRN_CSRR1:
133 vcpu->arch.csrr1 = spr_val;
134 break;
116 case SPRN_DBCR0: 135 case SPRN_DBCR0:
117 vcpu->arch.dbcr0 = spr_val; 136 vcpu->arch.dbcr0 = spr_val;
118 break; 137 break;
@@ -232,6 +251,12 @@ int kvmppc_booke_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val)
232 case SPRN_ESR: 251 case SPRN_ESR:
233 *spr_val = vcpu->arch.shared->esr; 252 *spr_val = vcpu->arch.shared->esr;
234 break; 253 break;
254 case SPRN_CSRR0:
255 *spr_val = vcpu->arch.csrr0;
256 break;
257 case SPRN_CSRR1:
258 *spr_val = vcpu->arch.csrr1;
259 break;
235 case SPRN_DBCR0: 260 case SPRN_DBCR0:
236 *spr_val = vcpu->arch.dbcr0; 261 *spr_val = vcpu->arch.dbcr0;
237 break; 262 break;
diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S
index 8feec2ff3928..09456c4719f3 100644
--- a/arch/powerpc/kvm/booke_interrupts.S
+++ b/arch/powerpc/kvm/booke_interrupts.S
@@ -53,16 +53,21 @@
53 (1<<BOOKE_INTERRUPT_PROGRAM) | \ 53 (1<<BOOKE_INTERRUPT_PROGRAM) | \
54 (1<<BOOKE_INTERRUPT_DTLB_MISS)) 54 (1<<BOOKE_INTERRUPT_DTLB_MISS))
55 55
56.macro KVM_HANDLER ivor_nr 56.macro KVM_HANDLER ivor_nr scratch srr0
57_GLOBAL(kvmppc_handler_\ivor_nr) 57_GLOBAL(kvmppc_handler_\ivor_nr)
58 /* Get pointer to vcpu and record exit number. */ 58 /* Get pointer to vcpu and record exit number. */
59 mtspr SPRN_SPRG_WSCRATCH0, r4 59 mtspr \scratch , r4
60 mfspr r4, SPRN_SPRG_RVCPU 60 mfspr r4, SPRN_SPRG_RVCPU
61 stw r3, VCPU_GPR(r3)(r4)
61 stw r5, VCPU_GPR(r5)(r4) 62 stw r5, VCPU_GPR(r5)(r4)
62 stw r6, VCPU_GPR(r6)(r4) 63 stw r6, VCPU_GPR(r6)(r4)
64 mfspr r3, \scratch
63 mfctr r5 65 mfctr r5
64 lis r6, kvmppc_resume_host@h 66 stw r3, VCPU_GPR(r4)(r4)
65 stw r5, VCPU_CTR(r4) 67 stw r5, VCPU_CTR(r4)
68 mfspr r3, \srr0
69 lis r6, kvmppc_resume_host@h
70 stw r3, VCPU_PC(r4)
66 li r5, \ivor_nr 71 li r5, \ivor_nr
67 ori r6, r6, kvmppc_resume_host@l 72 ori r6, r6, kvmppc_resume_host@l
68 mtctr r6 73 mtctr r6
@@ -70,37 +75,35 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
70.endm 75.endm
71 76
72_GLOBAL(kvmppc_handlers_start) 77_GLOBAL(kvmppc_handlers_start)
73KVM_HANDLER BOOKE_INTERRUPT_CRITICAL 78KVM_HANDLER BOOKE_INTERRUPT_CRITICAL SPRN_SPRG_RSCRATCH_CRIT SPRN_CSRR0
74KVM_HANDLER BOOKE_INTERRUPT_MACHINE_CHECK 79KVM_HANDLER BOOKE_INTERRUPT_MACHINE_CHECK SPRN_SPRG_RSCRATCH_MC SPRN_MCSRR0
75KVM_HANDLER BOOKE_INTERRUPT_DATA_STORAGE 80KVM_HANDLER BOOKE_INTERRUPT_DATA_STORAGE SPRN_SPRG_RSCRATCH0 SPRN_SRR0
76KVM_HANDLER BOOKE_INTERRUPT_INST_STORAGE 81KVM_HANDLER BOOKE_INTERRUPT_INST_STORAGE SPRN_SPRG_RSCRATCH0 SPRN_SRR0
77KVM_HANDLER BOOKE_INTERRUPT_EXTERNAL 82KVM_HANDLER BOOKE_INTERRUPT_EXTERNAL SPRN_SPRG_RSCRATCH0 SPRN_SRR0
78KVM_HANDLER BOOKE_INTERRUPT_ALIGNMENT 83KVM_HANDLER BOOKE_INTERRUPT_ALIGNMENT SPRN_SPRG_RSCRATCH0 SPRN_SRR0