Commit c4b000c3 authored by Andrew Scull's avatar Andrew Scull Committed by Paolo Bonzini
Browse files

KVM: arm64: Fix nVHE hyp panic host context restore



When panicking from the nVHE hyp and restoring the host context, x29 is
expected to hold a pointer to the host context. This wasn't being done
so fix it to make sure there's a valid pointer the host context being
used.

Rather than passing a boolean indicating whether or not the host context
should be restored, instead pass the pointer to the host context. NULL
is passed to indicate that no context should be restored.

Fixes: a2e102e2 ("KVM: arm64: nVHE: Handle hyp panics")
Cc: stable@vger.kernel.org
Signed-off-by: default avatarAndrew Scull <ascull@google.com>
[maz: partial rewrite to fit 5.12-rc1]
Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20210219122406.1337626-1-ascull@google.com


Message-Id: <20210305185254.3730990-4-maz@kernel.org>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 31948332
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -102,7 +102,8 @@ bool kvm_host_psci_handler(struct kvm_cpu_context *host_ctxt);

void __noreturn hyp_panic(void);
#ifdef __KVM_NVHE_HYPERVISOR__
void __noreturn __hyp_do_panic(bool restore_host, u64 spsr, u64 elr, u64 par);
void __noreturn __hyp_do_panic(struct kvm_cpu_context *host_ctxt, u64 spsr,
			       u64 elr, u64 par);
#endif

#endif /* __ARM64_KVM_HYP_H__ */
+8 −7
Original line number Diff line number Diff line
@@ -71,7 +71,8 @@ SYM_FUNC_START(__host_enter)
SYM_FUNC_END(__host_enter)

/*
 * void __noreturn __hyp_do_panic(bool restore_host, u64 spsr, u64 elr, u64 par);
 * void __noreturn __hyp_do_panic(struct kvm_cpu_context *host_ctxt, u64 spsr,
 * 				  u64 elr, u64 par);
 */
SYM_FUNC_START(__hyp_do_panic)
	/* Prepare and exit to the host's panic funciton. */
@@ -82,9 +83,11 @@ SYM_FUNC_START(__hyp_do_panic)
	hyp_kimg_va lr, x6
	msr	elr_el2, lr

	/* Set the panic format string. Use the, now free, LR as scratch. */
	ldr	lr, =__hyp_panic_string
	hyp_kimg_va lr, x6
	mov	x29, x0

	/* Load the format string into x0 and arguments into x1-7 */
	ldr	x0, =__hyp_panic_string
	hyp_kimg_va x0, x6

	/* Load the format arguments into x1-7. */
	mov	x6, x3
@@ -94,9 +97,7 @@ SYM_FUNC_START(__hyp_do_panic)
	mrs	x5, hpfar_el2

	/* Enter the host, conditionally restoring the host context. */
	cmp	x0, xzr
	mov	x0, lr
	b.eq	__host_enter_without_restoring
	cbz	x29, __host_enter_without_restoring
	b	__host_enter_for_panic
SYM_FUNC_END(__hyp_do_panic)

+1 −2
Original line number Diff line number Diff line
@@ -266,7 +266,6 @@ void __noreturn hyp_panic(void)
	u64 spsr = read_sysreg_el2(SYS_SPSR);
	u64 elr = read_sysreg_el2(SYS_ELR);
	u64 par = read_sysreg_par();
	bool restore_host = true;
	struct kvm_cpu_context *host_ctxt;
	struct kvm_vcpu *vcpu;

@@ -280,7 +279,7 @@ void __noreturn hyp_panic(void)
		__sysreg_restore_state_nvhe(host_ctxt);
	}

	__hyp_do_panic(restore_host, spsr, elr, par);
	__hyp_do_panic(host_ctxt, spsr, elr, par);
	unreachable();
}