diff mbox series

[v11,2/5] arm64: hyperv: Add panic handler

Message ID 1626793023-13830-3-git-send-email-mikelley@microsoft.com
State Accepted
Commit 512c1117fb2eeb944df1b88bff6e0c002990b369
Headers show
Series Enable Linux guests on Hyper-V on ARM64 | expand

Commit Message

Michael Kelley July 20, 2021, 2:57 p.m. UTC
Add a function to inform Hyper-V about a guest panic.

This code is built only when CONFIG_HYPERV is enabled.

Signed-off-by: Michael Kelley <mikelley@microsoft.com>
---
 arch/arm64/hyperv/hv_core.c | 52 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

Comments

Boqun Feng July 21, 2021, 2:54 p.m. UTC | #1
On Tue, Jul 20, 2021 at 07:57:00AM -0700, Michael Kelley wrote:
> Add a function to inform Hyper-V about a guest panic.

> 

> This code is built only when CONFIG_HYPERV is enabled.

> 

> Signed-off-by: Michael Kelley <mikelley@microsoft.com>


Reviewed-by: Boqun Feng <boqun.feng@gmail.com>


Regards,
Boqun

> ---

>  arch/arm64/hyperv/hv_core.c | 52 +++++++++++++++++++++++++++++++++++++++++++++

>  1 file changed, 52 insertions(+)

> 

> diff --git a/arch/arm64/hyperv/hv_core.c b/arch/arm64/hyperv/hv_core.c

> index 4c5dc0f..b54c347 100644

> --- a/arch/arm64/hyperv/hv_core.c

> +++ b/arch/arm64/hyperv/hv_core.c

> @@ -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);

> -- 

> 1.8.3.1

>
Sunil Muthuswamy July 27, 2021, 5:08 p.m. UTC | #2
> Add a function to inform Hyper-V about a guest panic.

> 

> This code is built only when CONFIG_HYPERV is enabled.

> 

> Signed-off-by: Michael Kelley <mikelley@microsoft.com>

> ---

>  arch/arm64/hyperv/hv_core.c | 52 +++++++++++++++++++++++++++++++++++++++++++++

>  1 file changed, 52 insertions(+)

> 

> diff --git a/arch/arm64/hyperv/hv_core.c b/arch/arm64/hyperv/hv_core.c

> index 4c5dc0f..b54c347 100644

> --- a/arch/arm64/hyperv/hv_core.c

> +++ b/arch/arm64/hyperv/hv_core.c

> @@ -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);

> --

> 1.8.3.1


Reviewed-by: Sunil Muthuswamy <sunilmut@microsoft.com>
diff mbox series

Patch

diff --git a/arch/arm64/hyperv/hv_core.c b/arch/arm64/hyperv/hv_core.c
index 4c5dc0f..b54c347 100644
--- a/arch/arm64/hyperv/hv_core.c
+++ b/arch/arm64/hyperv/hv_core.c
@@ -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);