From ac87f57ed8f43597265dfd0c8d5b7ef1e9c953cb Mon Sep 17 00:00:00 2001 From: Tsiry Sandratraina Date: Sun, 2 Aug 2026 14:04:50 +0300 Subject: [PATCH] x86_64: dump vcpu regs/sregs on KVM_EXIT_SHUTDOWN (triple-fault debug) So a PVH triple-fault is actually debuggable: rip shows whether it faulted on the first instruction (bad segment/mode) or later (bad start_info); cr0/cr2/ cr3/cr4/efer + cs/gdt/tr show the CPU mode and whether protected mode + the GDT/TR were set up as intended. --- src/vmm/src/linux/vstate.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/vmm/src/linux/vstate.rs b/src/vmm/src/linux/vstate.rs index a7a2955..efc3f1b 100644 --- a/src/vmm/src/linux/vstate.rs +++ b/src/vmm/src/linux/vstate.rs @@ -1532,6 +1532,25 @@ impl Vcpu { } VcpuExit::Shutdown => { info!("Received KVM_EXIT_SHUTDOWN signal"); + // Dump the vcpu state so a triple-fault (e.g. a bad PVH entry + // state) is debuggable: rip tells us if it faulted on the first + // instruction vs later, cr0/cr2/cr3/efer show the CPU mode. + if let Ok(regs) = self.fd.get_regs() { + error!( + "SHUTDOWN vcpu regs: rip={:#x} rsp={:#x} rbx={:#x} rax={:#x} rflags={:#x}", + regs.rip, regs.rsp, regs.rbx, regs.rax, regs.rflags + ); + } + if let Ok(s) = self.fd.get_sregs() { + error!( + "SHUTDOWN vcpu sregs: cr0={:#x} cr2={:#x} cr3={:#x} cr4={:#x} efer={:#x} \ + cs.base={:#x} cs.limit={:#x} cs.db={} cs.l={} cs.g={} cs.present={} \ + gdt.base={:#x} gdt.limit={:#x} tr.type={} tr.present={}", + s.cr0, s.cr2, s.cr3, s.cr4, s.efer, + s.cs.base, s.cs.limit, s.cs.db, s.cs.l, s.cs.g, s.cs.present, + s.gdt.base, s.gdt.limit, s.tr.type_, s.tr.present + ); + } Ok(VcpuEmulation::Stopped) } // Documentation specifies that below kvm exits are considered -- 2.51.2