vmm: Only return from reset driven I/O once event received

The reset system is asynchronous with an I/O event (PIO or MMIO) for
ACPI/i8042/CMOS triggering a write to the reset_evt event handler. The
VMM thread will pick up this event on the VMM main loop and then trigger
a shutdown in the CpuManager. However since there is some delay between
the CPU threads being marked to be killed (through the
CpuManager::cpus_kill_signalled bool) it is possible for the guest vCPU
that triggered the exit to be re-entered when the vCPU KVM_RUN is called
after the I/O exit is completed.

This is undesirable and in particular the Linux kernel will attempt to
jump to real mode after a CMOS based exit - this is unsupported in
nested KVM on AMD on Azure and will trigger an error in KVM_RUN.

Solve this problem by spinning in the device that has triggered the
reset until the vcpus_kill_signalled boolean has been updated
indicating that the VMM thread has received the event and called
CpuManager::shutdown(). In particular if this bool is set then the vCPU
threads will not re-enter the guest.

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
This commit is contained in:
Rob Bradford
2023-08-03 15:13:03 +01:00
committed by Bo Chen
parent 70cfd1be67
commit 06dc708515
6 changed files with 82 additions and 6 deletions

View File

@@ -1725,6 +1725,10 @@ impl CpuManager {
) {
self.interrupt_controller = Some(interrupt_controller);
}
pub(crate) fn vcpus_kill_signalled(&self) -> &Arc<AtomicBool> {
&self.vcpus_kill_signalled
}
}
struct Cpu {