vmx_run() injects a pending interrupt before it checks whether the vCPU
has to leave the loop: vmx_inject_interrupts() lets the vlapic accept
the interrupt (the ISR bit is set) and writes it into the VM-entry
interruption information field. bhyve stops the vCPUs for a snapshot
with a debug suspend, which is one of those checks, so a vCPU can be
stopped with an accepted interrupt that has not reached the guest yet.
Without a snapshot it is injected at the next VM entry.
vmx_vcpu_snapshot() did not save the VM-entry event injection fields.
After a restore the guest never got that interrupt, never wrote the EOI,
the ISR bit stayed set, and the vCPU took no interrupt of the same or a
lower priority any more: its timer, then every device.
Save VM-entry interruption information, exception error code and
instruction length. This changes the format of the snapshot.
Signed-off-by: Wanpeng Qian <wanpengqian@gmail.com>
Sponsored by: keelos.dev