|
17 | 17 | #include <asm/fpu/xcr.h> |
18 | 18 | #include <asm/realmode.h> |
19 | 19 | #include <asm/tdx.h> |
| 20 | +#include <asm/reboot.h> |
20 | 21 | #include <asm/sev.h> |
21 | 22 | #include <uapi/asm/mtrr.h> |
22 | 23 |
|
@@ -47,6 +48,27 @@ static bool hv_vtl_is_private_mmio_tdx(u64 addr) |
47 | 48 | return mb_addr && within_page(addr, mb_addr); |
48 | 49 | } |
49 | 50 |
|
| 51 | +/* |
| 52 | + * The `native_machine_emergency_restart` function from `reboot.c` writes |
| 53 | + * to the physical address 0x472 to indicate the type of reboot for the |
| 54 | + * firmware. We cannot have that in VSM as the memory composition might |
| 55 | + * be more generic, and such write effectively corrupts the memory thus |
| 56 | + * making diagnostics harder at the very least. |
| 57 | + */ |
| 58 | +static void __noreturn hv_vtl_emergency_restart(void) |
| 59 | +{ |
| 60 | + /* |
| 61 | + * Cause a triple fault and the immediate reset. Here the code does not run |
| 62 | + * on the top of any firmware, whereby cannot reach out to its services. |
| 63 | + * The inifinite loop is for the improbable case that the triple fault does |
| 64 | + * not work and have to preserve the state intact for debugging. |
| 65 | + */ |
| 66 | + for (;;) { |
| 67 | + idt_invalidate(); |
| 68 | + __asm__ __volatile__("int3"); |
| 69 | + } |
| 70 | +} |
| 71 | + |
50 | 72 | void __init hv_vtl_init_platform(void) |
51 | 73 | { |
52 | 74 | pr_info("Linux runs in Hyper-V Virtual Trust Level\n"); |
@@ -231,6 +253,7 @@ static int hv_vtl_wakeup_secondary_cpu(u32 apicid, unsigned long start_eip, unsi |
231 | 253 |
|
232 | 254 | int __init hv_vtl_early_init(void) |
233 | 255 | { |
| 256 | + machine_ops.emergency_restart = hv_vtl_emergency_restart; |
234 | 257 | /* |
235 | 258 | * `boot_cpu_has` returns the runtime feature support, |
236 | 259 | * and here is the earliest it can be used. |
|
0 commit comments