|
@@ -4392,6 +4392,12 @@ static bool nested_exit_on_intr(struct kvm_vcpu *vcpu)
|
|
|
PIN_BASED_EXT_INTR_MASK;
|
|
|
}
|
|
|
|
|
|
+static bool nested_exit_on_nmi(struct kvm_vcpu *vcpu)
|
|
|
+{
|
|
|
+ return get_vmcs12(vcpu)->pin_based_vm_exec_control &
|
|
|
+ PIN_BASED_NMI_EXITING;
|
|
|
+}
|
|
|
+
|
|
|
static void enable_irq_window(struct kvm_vcpu *vcpu)
|
|
|
{
|
|
|
u32 cpu_based_vm_exec_control;
|
|
@@ -4517,6 +4523,26 @@ static void vmx_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked)
|
|
|
|
|
|
static int vmx_nmi_allowed(struct kvm_vcpu *vcpu)
|
|
|
{
|
|
|
+ if (is_guest_mode(vcpu)) {
|
|
|
+ struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
|
|
|
+
|
|
|
+ if (to_vmx(vcpu)->nested.nested_run_pending)
|
|
|
+ return 0;
|
|
|
+ if (nested_exit_on_nmi(vcpu)) {
|
|
|
+ nested_vmx_vmexit(vcpu);
|
|
|
+ vmcs12->vm_exit_reason = EXIT_REASON_EXCEPTION_NMI;
|
|
|
+ vmcs12->vm_exit_intr_info = NMI_VECTOR |
|
|
|
+ INTR_TYPE_NMI_INTR | INTR_INFO_VALID_MASK;
|
|
|
+ /*
|
|
|
+ * The NMI-triggered VM exit counts as injection:
|
|
|
+ * clear this one and block further NMIs.
|
|
|
+ */
|
|
|
+ vcpu->arch.nmi_pending = 0;
|
|
|
+ vmx_set_nmi_mask(vcpu, true);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
if (!cpu_has_virtual_nmis() && to_vmx(vcpu)->soft_vnmi_blocked)
|
|
|
return 0;
|
|
|
|