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
|
||||
.align
|
||||
\label: b .
|
||||
\label: mov r0, #\cause
|
||||
b __hyp_panic
|
||||
.endm
|
||||
|
||||
invalid_vector hyp_reset
|
||||
invalid_vector hyp_undef
|
||||
invalid_vector hyp_svc
|
||||
invalid_vector hyp_pabt
|
||||
invalid_vector hyp_dabt
|
||||
invalid_vector hyp_fiq
|
||||
invalid_vector hyp_reset ARM_EXCEPTION_RESET
|
||||
invalid_vector hyp_undef ARM_EXCEPTION_UNDEFINED
|
||||
invalid_vector hyp_svc ARM_EXCEPTION_SOFTWARE
|
||||
invalid_vector hyp_pabt ARM_EXCEPTION_PREF_ABORT
|
||||
invalid_vector hyp_dabt ARM_EXCEPTION_DATA_ABORT
|
||||
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:
|
||||
/*
|
||||
|
|
|
@ -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);
|
||||
|
||||
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