Skip to content

Commit ced518a

Browse files
romank-msftliuw
authored andcommitted
x86/hyperv: Add VTL mode emergency restart callback
By default, X86(-64) systems use the emergecy restart routine in the course of which the code unconditionally writes to the physical address of 0x472 to indicate the boot mode to the firmware (BIOS or UEFI). When the kernel itself runs as a firmware in the VTL mode, that write corrupts the memory of the guest upon emergency restarting. Preserving the state intact in that situation is important for debugging, at least. Define the specialized machine callback to avoid that write and use the triple fault to perform emergency restart. Signed-off-by: Roman Kisel <romank@linux.microsoft.com> Link: https://lore.kernel.org/r/20250227214728.15672-2-romank@linux.microsoft.com Signed-off-by: Wei Liu <wei.liu@kernel.org> Message-ID: <20250227214728.15672-2-romank@linux.microsoft.com>
1 parent fe14262 commit ced518a

File tree

1 file changed

+23
-0
lines changed

1 file changed

+23
-0
lines changed

arch/x86/hyperv/hv_vtl.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <asm/i8259.h>
1313
#include <asm/mshyperv.h>
1414
#include <asm/realmode.h>
15+
#include <asm/reboot.h>
1516
#include <../kernel/smpboot.h>
1617

1718
extern struct boot_params boot_params;
@@ -22,6 +23,27 @@ static bool __init hv_vtl_msi_ext_dest_id(void)
2223
return true;
2324
}
2425

26+
/*
27+
* The `native_machine_emergency_restart` function from `reboot.c` writes
28+
* to the physical address 0x472 to indicate the type of reboot for the
29+
* firmware. We cannot have that in VSM as the memory composition might
30+
* be more generic, and such write effectively corrupts the memory thus
31+
* making diagnostics harder at the very least.
32+
*/
33+
static void __noreturn hv_vtl_emergency_restart(void)
34+
{
35+
/*
36+
* Cause a triple fault and the immediate reset. Here the code does not run
37+
* on the top of any firmware, whereby cannot reach out to its services.
38+
* The inifinite loop is for the improbable case that the triple fault does
39+
* not work and have to preserve the state intact for debugging.
40+
*/
41+
for (;;) {
42+
idt_invalidate();
43+
__asm__ __volatile__("int3");
44+
}
45+
}
46+
2547
void __init hv_vtl_init_platform(void)
2648
{
2749
pr_info("Linux runs in Hyper-V Virtual Trust Level\n");
@@ -235,6 +257,7 @@ static int hv_vtl_wakeup_secondary_cpu(u32 apicid, unsigned long start_eip)
235257

236258
int __init hv_vtl_early_init(void)
237259
{
260+
machine_ops.emergency_restart = hv_vtl_emergency_restart;
238261
/*
239262
* `boot_cpu_has` returns the runtime feature support,
240263
* and here is the earliest it can be used.

0 commit comments

Comments
 (0)