AMD/SVM does not have hardware assist for NMI window exiting. The hypervisor
tracks the state of NMI blocking in two stages.
In the first stage the "iret" intercept is enabled. This causes a #VMEXIT
when the guest tries to execute an "iret" to return from the NMI handler.
In the second stage the "iret" intercept is cleared and the "iret" instruction
is single-stepped by the hypervisor by setting the 'Trap' and 'Resume' bits
in the %rflags register. Additionally the hypervisor also enables intercepts
for all exceptions.
If the "iret" executes successfully the #DB exception triggers a #VMEXIT.
In response to this the hypervisor unblocks NMIs, disables the exception
intercepts and resumes guest execution.
If the "iret" causes an exception (#GP, #PF etc) then it will trigger a
#VMEXIT. In response to this the hypervisor unblocks NMIs, disables the
exception intercepts and reflects the exception back into the guest.
The odd case is when the "iret" results in a hardware task switch and the
single-stepping described above does not work. In this case the NMI is
unblocked before the "iret" is executed by the vcpu.