On Thursday 15 April 2010 18:44:15 Avi Kivity wrote:
On 04/15/2010 01:40 PM, Joerg Roedel wrote:After more investigating, I realized that I had interpreted the SDM wrong.
The point is not well defined. Considering there are already at leastThat means an NMI that happens outside guest code (for example, in theHmm, true. The same is true for an NMI that happens between VMSAVE and
mmu, or during the exit itself) would be counted as if in guest code.
STGI but that window is smaller. Anyway, I think we don't need the
busy-wait loop. The NMI should be executed at a well defined point and
we set the cpu_var back to NULL after that point.
two implementations svm, I don't want to rely on implementation details.
Sorry.
There is *no* risk with the original method of calling "int $2".
According to the SDM 24.1:
The following bullets detail when architectural state is and is not updatedin response to VM exits:
[...]
- An NMI causes subsequent NMIs to be blocked, but only after the VM exitcompletes.
So the truth is, after NMI directly caused VMExit, the following NMIs would be
blocked, until encountered next "iret". So execute "int $2" is safe in
vmx_complete_interrupts(), no risk in causing nested NMI. And it would unblock
the following NMIs as well due to "iret" it executed.
So there is unnecessary to make change to avoid "potential nested NMI".
The following bullets detail when architectural state is and is not updated in response
to VM exits:
â If an event causes a VM exit directly, it does not update architectural state as it
would have if it had it not caused the VM exit:
â A debug exception does not update DR6, DR7.GD, or IA32_DEBUGCTL.LBR.
(Information about the nature of the debug exception is saved in the exit
qualification field.)
â A page fault does not update CR2. (The linear address causing the page fault
is saved in the exit-qualification field.)
â An NMI causes subsequent NMIs to be blocked, but only after the VM exit
completes.
â An external interrupt does not acknowledge the interrupt controller and the
interrupt remains pending, unless the âacknowledge interrupt on exitâ
VM-exit control is 1. In such a case, the interrupt controller is acknowledged
and the interrupt is no longer pending.