|
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