Commit 512c1117 authored by Michael Kelley's avatar Michael Kelley Committed by Wei Liu
Browse files

arm64: hyperv: Add panic handler



Add a function to inform Hyper-V about a guest panic.

This code is built only when CONFIG_HYPERV is enabled.

Signed-off-by: default avatarMichael Kelley <mikelley@microsoft.com>
Reviewed-by: default avatarSunil Muthuswamy <sunilmut@microsoft.com>
Reviewed-by: default avatarBoqun Feng <boqun.feng@gmail.com>
Acked-by: default avatarMarc Zyngier <maz@kernel.org>
Acked-by: default avatarMark Rutland <mark.rutland@arm.com>
Acked-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
Link: https://lore.kernel.org/r/1628092359-61351-3-git-send-email-mikelley@microsoft.com


Signed-off-by: default avatarWei Liu <wei.liu@kernel.org>
parent 57d276bb
Loading
Loading
Loading
Loading
+52 −0
Original line number Diff line number Diff line
@@ -127,3 +127,55 @@ u64 hv_get_vpreg(u32 msr)
	return output.as64.low;
}
EXPORT_SYMBOL_GPL(hv_get_vpreg);

/*
 * hyperv_report_panic - report a panic to Hyper-V.  This function uses
 * the older version of the Hyper-V interface that admittedly doesn't
 * pass enough information to be useful beyond just recording the
 * occurrence of a panic. The parallel hv_kmsg_dump() uses the
 * new interface that allows reporting 4 Kbytes of data, which is much
 * more useful. Hyper-V on ARM64 always supports the newer interface, but
 * we retain support for the older version because the sysadmin is allowed
 * to disable the newer version via sysctl in case of information security
 * concerns about the more verbose version.
 */
void hyperv_report_panic(struct pt_regs *regs, long err, bool in_die)
{
	static bool	panic_reported;
	u64		guest_id;

	/* Don't report a panic to Hyper-V if we're not going to panic */
	if (in_die && !panic_on_oops)
		return;

	/*
	 * We prefer to report panic on 'die' chain as we have proper
	 * registers to report, but if we miss it (e.g. on BUG()) we need
	 * to report it on 'panic'.
	 *
	 * Calling code in the 'die' and 'panic' paths ensures that only
	 * one CPU is running this code, so no atomicity is needed.
	 */
	if (panic_reported)
		return;
	panic_reported = true;

	guest_id = hv_get_vpreg(HV_REGISTER_GUEST_OSID);

	/*
	 * Hyper-V provides the ability to store only 5 values.
	 * Pick the passed in error value, the guest_id, the PC,
	 * and the SP.
	 */
	hv_set_vpreg(HV_REGISTER_CRASH_P0, err);
	hv_set_vpreg(HV_REGISTER_CRASH_P1, guest_id);
	hv_set_vpreg(HV_REGISTER_CRASH_P2, regs->pc);
	hv_set_vpreg(HV_REGISTER_CRASH_P3, regs->sp);
	hv_set_vpreg(HV_REGISTER_CRASH_P4, 0);

	/*
	 * Let Hyper-V know there is crash data available
	 */
	hv_set_vpreg(HV_REGISTER_CRASH_CTL, HV_CRASH_CTL_CRASH_NOTIFY);
}
EXPORT_SYMBOL_GPL(hyperv_report_panic);