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>
This commit is contained in:
parent
bafc6c2a22
commit
c36b6db5f3
2 changed files with 59 additions and 7 deletions
|
@ -75,15 +75,29 @@ __kvm_hyp_vector:
|
||||||
|
|
||||||
.macro invalid_vector label, cause
|
.macro invalid_vector label, cause
|
||||||
.align
|
.align
|
||||||
\label: b .
|
\label: mov r0, #\cause
|
||||||
|
b __hyp_panic
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
invalid_vector hyp_reset
|
invalid_vector hyp_reset ARM_EXCEPTION_RESET
|
||||||
invalid_vector hyp_undef
|
invalid_vector hyp_undef ARM_EXCEPTION_UNDEFINED
|
||||||
invalid_vector hyp_svc
|
invalid_vector hyp_svc ARM_EXCEPTION_SOFTWARE
|
||||||
invalid_vector hyp_pabt
|
invalid_vector hyp_pabt ARM_EXCEPTION_PREF_ABORT
|
||||||
invalid_vector hyp_dabt
|
invalid_vector hyp_dabt ARM_EXCEPTION_DATA_ABORT
|
||||||
invalid_vector hyp_fiq
|
invalid_vector hyp_fiq ARM_EXCEPTION_FIQ
|
||||||
|
|
||||||
|
ENTRY(__hyp_do_panic)
|
||||||
|
mrs lr, cpsr
|
||||||
|
bic lr, lr, #MODE_MASK
|
||||||
|
orr lr, lr, #SVC_MODE
|
||||||
|
THUMB( orr lr, lr, #PSR_T_BIT )
|
||||||
|
msr spsr_cxsf, lr
|
||||||
|
ldr lr, =panic
|
||||||
|
msr ELR_hyp, lr
|
||||||
|
ldr lr, =kvm_call_hyp
|
||||||
|
clrex
|
||||||
|
eret
|
||||||
|
ENDPROC(__hyp_do_panic)
|
||||||
|
|
||||||
hyp_hvc:
|
hyp_hvc:
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -192,3 +192,41 @@ static int __hyp_text __guest_run(struct kvm_vcpu *vcpu)
|
||||||
}
|
}
|
||||||
|
|
||||||
__alias(__guest_run) int __weak __kvm_vcpu_run(struct kvm_vcpu *vcpu);
|
__alias(__guest_run) int __weak __kvm_vcpu_run(struct kvm_vcpu *vcpu);
|
||||||
|
|
||||||
|
static const char * const __hyp_panic_string[] = {
|
||||||
|
[ARM_EXCEPTION_RESET] = "\nHYP panic: RST PC:%08x CPSR:%08x",
|
||||||
|
[ARM_EXCEPTION_UNDEFINED] = "\nHYP panic: UNDEF PC:%08x CPSR:%08x",
|
||||||
|
[ARM_EXCEPTION_SOFTWARE] = "\nHYP panic: SVC PC:%08x CPSR:%08x",
|
||||||
|
[ARM_EXCEPTION_PREF_ABORT] = "\nHYP panic: PABRT PC:%08x CPSR:%08x",
|
||||||
|
[ARM_EXCEPTION_DATA_ABORT] = "\nHYP panic: DABRT PC:%08x ADDR:%08x",
|
||||||
|
[ARM_EXCEPTION_IRQ] = "\nHYP panic: IRQ PC:%08x CPSR:%08x",
|
||||||
|
[ARM_EXCEPTION_FIQ] = "\nHYP panic: FIQ PC:%08x CPSR:%08x",
|
||||||
|
[ARM_EXCEPTION_HVC] = "\nHYP panic: HVC PC:%08x CPSR:%08x",
|
||||||
|
};
|
||||||
|
|
||||||
|
void __hyp_text __noreturn __hyp_panic(int cause)
|
||||||
|
{
|
||||||
|
u32 elr = read_special(ELR_hyp);
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
if (cause == ARM_EXCEPTION_DATA_ABORT)
|
||||||
|
val = read_sysreg(HDFAR);
|
||||||
|
else
|
||||||
|
val = read_special(SPSR);
|
||||||
|
|
||||||
|
if (read_sysreg(VTTBR)) {
|
||||||
|
struct kvm_vcpu *vcpu;
|
||||||
|
struct kvm_cpu_context *host_ctxt;
|
||||||
|
|
||||||
|
vcpu = (struct kvm_vcpu *)read_sysreg(HTPIDR);
|
||||||
|
host_ctxt = kern_hyp_va(vcpu->arch.host_cpu_context);
|
||||||
|
__deactivate_traps(vcpu);
|
||||||
|
__deactivate_vm(vcpu);
|
||||||
|
__sysreg_restore_state(host_ctxt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Call panic for real */
|
||||||
|
__hyp_do_panic(__hyp_panic_string[cause], elr, val);
|
||||||
|
|
||||||
|
unreachable();
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue