I am running a guest OS on KVM with Intel VT-x. I am trying to understand how NMI (Intel PEBS) is handled when it is running in non-root mode. Does Intel VT-x automatically cause an NMI at the guest or the Linux kernel's kvm subsystem sends the NMI to VCPU? Although I have registered an NMI handler in guest OS, I only get a host NMI trigger during non-root execution.
Don't have a quick answer for you but I found some information that may provide some hints for you: https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software...
I will also check with peers for any further input.
Here are some feedback from my peer:
" Firstly, when real NMI happens in VMX non-root mode, whether this cause VMEXIT is controlled by bit-3 in pin-based vm-execution control. Depending on this bit, real NMI either causes VMEXIT, or is delivered to guest’s IDT directly. In the latter case, the guest’s NMI handler is invoked directly w/o hypervisor intervention.
If VMEXIT is caused when real NMI happens, Intel VT-x doesn’t automatically inject NMI to guest, and KVM typically doesn’t need to inject vNMI to guest either. I personally don’t see any reason why KVM should inject vNMI to guest when real NMI happens, but maybe there are some very rare cases that we may need to do.
Depending on implementation, we need to inject vNMI to guest when real NMI happens, we can do this via event injection during VMENTRY. Virtual NMI injection is the same as normal interrupt injection. Please refer to 24.8.3 VM-Entry controls for Event Injection for details.
Btw, vNMI can be totally virtual, meaning you can inject vNMI to guest w/o real NMI happening. For example, Qemu supports inject vNMI by qemu monitor.
And there’s also “virtual NMI” bit (bit5) in pin-based vm-execution control, we should turn on that when supported."