|
|
@@ -5313,29 +5313,30 @@ static void vmx_inject_nmi(struct kvm_vcpu *vcpu)
|
|
|
{
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
|
|
|
|
|
- if (is_guest_mode(vcpu))
|
|
|
- return;
|
|
|
+ if (!is_guest_mode(vcpu)) {
|
|
|
+ if (!cpu_has_virtual_nmis()) {
|
|
|
+ /*
|
|
|
+ * Tracking the NMI-blocked state in software is built upon
|
|
|
+ * finding the next open IRQ window. This, in turn, depends on
|
|
|
+ * well-behaving guests: They have to keep IRQs disabled at
|
|
|
+ * least as long as the NMI handler runs. Otherwise we may
|
|
|
+ * cause NMI nesting, maybe breaking the guest. But as this is
|
|
|
+ * highly unlikely, we can live with the residual risk.
|
|
|
+ */
|
|
|
+ vmx->soft_vnmi_blocked = 1;
|
|
|
+ vmx->vnmi_blocked_time = 0;
|
|
|
+ }
|
|
|
|
|
|
- if (!cpu_has_virtual_nmis()) {
|
|
|
- /*
|
|
|
- * Tracking the NMI-blocked state in software is built upon
|
|
|
- * finding the next open IRQ window. This, in turn, depends on
|
|
|
- * well-behaving guests: They have to keep IRQs disabled at
|
|
|
- * least as long as the NMI handler runs. Otherwise we may
|
|
|
- * cause NMI nesting, maybe breaking the guest. But as this is
|
|
|
- * highly unlikely, we can live with the residual risk.
|
|
|
- */
|
|
|
- vmx->soft_vnmi_blocked = 1;
|
|
|
- vmx->vnmi_blocked_time = 0;
|
|
|
+ ++vcpu->stat.nmi_injections;
|
|
|
+ vmx->nmi_known_unmasked = false;
|
|
|
}
|
|
|
|
|
|
- ++vcpu->stat.nmi_injections;
|
|
|
- vmx->nmi_known_unmasked = false;
|
|
|
if (vmx->rmode.vm86_active) {
|
|
|
if (kvm_inject_realmode_interrupt(vcpu, NMI_VECTOR, 0) != EMULATE_DONE)
|
|
|
kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu);
|
|
|
return;
|
|
|
}
|
|
|
+
|
|
|
vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
|
|
|
INTR_TYPE_NMI_INTR | INTR_INFO_VALID_MASK | NMI_VECTOR);
|
|
|
}
|