aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kvm
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2016-01-06 04:12:42 -0500
committerMarc Zyngier <marc.zyngier@arm.com>2016-02-29 13:34:14 -0500
commitc36b6db5f3e4c1bd21659aee8e67226352d254ae (patch)
treef4a002e0cc3e0876a29724bdf25e534720a11eb5 /arch/arm/kvm
parentbafc6c2a22553193d1d1ce83783b7faa0924158e (diff)
ARM: KVM: Add panic handling code
Instead of spinning forever, let's "properly" handle any unexpected exception ("properly" meaning "print a spat on the console and die"). This has proved useful quite a few times... Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'arch/arm/kvm')
-rw-r--r--arch/arm/kvm/hyp/hyp-entry.S28
-rw-r--r--arch/arm/kvm/hyp/switch.c38
2 files changed, 59 insertions, 7 deletions
diff --git a/arch/arm/kvm/hyp/hyp-entry.S b/arch/arm/kvm/hyp/hyp-entry.S
index 1b4aa02fd364..54a8d67ad980 100644
--- a/arch/arm/kvm/hyp/hyp-entry.S
+++ b/arch/arm/kvm/hyp/hyp-entry.S
@@ -75,15 +75,29 @@ __kvm_hyp_vector:
75 75
76.macro invalid_vector label, cause 76.macro invalid_vector label, cause
77 .align 77 .align
78\label: b . 78\label: mov r0, #\cause
79 b __hyp_panic
79.endm 80.endm
80 81
81 invalid_vector hyp_reset 82 invalid_vector hyp_reset ARM_EXCEPTION_RESET
82 invalid_vector hyp_undef 83 invalid_vector hyp_undef ARM_EXCEPTION_UNDEFINED
83 invalid_vector hyp_svc 84 invalid_vector hyp_svc ARM_EXCEPTION_SOFTWARE
84 invalid_vector hyp_pabt 85 invalid_vector hyp_pabt ARM_EXCEPTION_PREF_ABORT
85 invalid_vector hyp_dabt 86 invalid_vector hyp_dabt ARM_EXCEPTION_DATA_ABORT
86 invalid_vector hyp_fiq 87 invalid_vector hyp_fiq ARM_EXCEPTION_FIQ
88
89ENTRY(__hyp_do_panic)
90 mrs lr, cpsr
91 bic lr, lr, #MODE_MASK
92 orr lr, lr, #SVC_MODE
93THUMB( orr lr, lr, #PSR_T_BIT )
94 msr spsr_cxsf, lr
95 ldr lr, =panic
96 msr ELR_hyp, lr
97 ldr lr, =kvm_call_hyp
98 clrex
99 eret
100ENDPROC(__hyp_do_panic)
87 101
88hyp_hvc: 102hyp_hvc:
89 /* 103 /*
diff --git a/arch/arm/kvm/hyp/switch.c b/arch/arm/kvm/hyp/switch.c
index 0dd0ba33b8a7..abbe90b5f2ff 100644
--- a/arch/arm/kvm/hyp/switch.c
+++ b/arch/arm/kvm/hyp/switch.c
@@ -192,3 +192,41 @@ again:
192} 192}
193 193
194__alias(__guest_run) int __weak __kvm_vcpu_run(struct kvm_vcpu *vcpu); 194__alias(__guest_run) int __weak __kvm_vcpu_run(struct kvm_vcpu *vcpu);
195
196static const char * const __hyp_panic_string[] = {
197 [ARM_EXCEPTION_RESET] = "\nHYP panic: RST PC:%08x CPSR:%08x",
198 [ARM_EXCEPTION_UNDEFINED] = "\nHYP panic: UNDEF PC:%08x CPSR:%08x",
199 [ARM_EXCEPTION_SOFTWARE] = "\nHYP panic: SVC PC:%08x CPSR:%08x",
200 [ARM_EXCEPTION_PREF_ABORT] = "\nHYP panic: PABRT PC:%08x CPSR:%08x",
201 [ARM_EXCEPTION_DATA_ABORT] = "\nHYP panic: DABRT PC:%08x ADDR:%08x",
202 [ARM_EXCEPTION_IRQ] = "\nHYP panic: IRQ PC:%08x CPSR:%08x",
203 [ARM_EXCEPTION_FIQ] = "\nHYP panic: FIQ PC:%08x CPSR:%08x",
204 [ARM_EXCEPTION_HVC] = "\nHYP panic: HVC PC:%08x CPSR:%08x",
205};
206
207void __hyp_text __noreturn __hyp_panic(int cause)
208{
209 u32 elr = read_special(ELR_hyp);
210 u32 val;
211
212 if (cause == ARM_EXCEPTION_DATA_ABORT)
213 val = read_sysreg(HDFAR);
214 else
215 val = read_special(SPSR);
216
217 if (read_sysreg(VTTBR)) {
218 struct kvm_vcpu *vcpu;
219 struct kvm_cpu_context *host_ctxt;
220
221 vcpu = (struct kvm_vcpu *)read_sysreg(HTPIDR);
222 host_ctxt = kern_hyp_va(vcpu->arch.host_cpu_context);
223 __deactivate_traps(vcpu);
224 __deactivate_vm(vcpu);
225 __sysreg_restore_state(host_ctxt);
226 }
227
228 /* Call panic for real */
229 __hyp_do_panic(__hyp_panic_string[cause], elr, val);
230
231 unreachable();
232}