Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Roman Kisel and committed by
Wei Liu
ced518ad fe142626

+23
+23
arch/x86/hyperv/hv_vtl.c
··· 12 12 #include <asm/i8259.h> 13 13 #include <asm/mshyperv.h> 14 14 #include <asm/realmode.h> 15 + #include <asm/reboot.h> 15 16 #include <../kernel/smpboot.h> 16 17 17 18 extern struct boot_params boot_params; ··· 21 20 static bool __init hv_vtl_msi_ext_dest_id(void) 22 21 { 23 22 return true; 23 + } 24 + 25 + /* 26 + * The `native_machine_emergency_restart` function from `reboot.c` writes 27 + * to the physical address 0x472 to indicate the type of reboot for the 28 + * firmware. We cannot have that in VSM as the memory composition might 29 + * be more generic, and such write effectively corrupts the memory thus 30 + * making diagnostics harder at the very least. 31 + */ 32 + static void __noreturn hv_vtl_emergency_restart(void) 33 + { 34 + /* 35 + * Cause a triple fault and the immediate reset. Here the code does not run 36 + * on the top of any firmware, whereby cannot reach out to its services. 37 + * The inifinite loop is for the improbable case that the triple fault does 38 + * not work and have to preserve the state intact for debugging. 39 + */ 40 + for (;;) { 41 + idt_invalidate(); 42 + __asm__ __volatile__("int3"); 43 + } 24 44 } 25 45 26 46 void __init hv_vtl_init_platform(void) ··· 257 235 258 236 int __init hv_vtl_early_init(void) 259 237 { 238 + machine_ops.emergency_restart = hv_vtl_emergency_restart; 260 239 /* 261 240 * `boot_cpu_has` returns the runtime feature support, 262 241 * and here is the earliest it can be used.