Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c36b6db5 authored by Marc Zyngier's avatar Marc Zyngier
Browse files

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: default avatarChristoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
parent bafc6c2a
Loading
Loading
Loading
Loading
+21 −7
Original line number Diff line number Diff line
@@ -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:
	/*
+38 −0
Original line number Diff line number Diff line
@@ -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();
}