kvm_rip_write(vcpu, svm->next_rip);
        svm->vmcb->control.int_state &= ~SVM_INTERRUPT_SHADOW_MASK;
 
-       vcpu->arch.interrupt_window_open = 1;
+       vcpu->arch.interrupt_window_open = (svm->vcpu.arch.hflags & HF_GIF_MASK);
 }
 
 static int has_svm(void)
                save->cr4 = 0;
        }
        force_new_asid(&svm->vcpu);
+
+       svm->vcpu.arch.hflags = HF_GIF_MASK;
 }
 
 static int svm_vcpu_reset(struct kvm_vcpu *vcpu)
        return retval;
 }
 
+static int stgi_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+{
+       if (nested_svm_check_permissions(svm))
+               return 1;
+
+       svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
+       skip_emulated_instruction(&svm->vcpu);
+
+       svm->vcpu.arch.hflags |= HF_GIF_MASK;
+
+       return 1;
+}
+
+static int clgi_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+{
+       if (nested_svm_check_permissions(svm))
+               return 1;
+
+       svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
+       skip_emulated_instruction(&svm->vcpu);
+
+       svm->vcpu.arch.hflags &= ~HF_GIF_MASK;
+
+       /* After a CLGI no interrupts should come */
+       svm_clear_vintr(svm);
+       svm->vmcb->control.int_ctl &= ~V_IRQ_MASK;
+
+       return 1;
+}
+
 static int invalid_op_interception(struct vcpu_svm *svm,
                                   struct kvm_run *kvm_run)
 {
        [SVM_EXIT_VMMCALL]                      = vmmcall_interception,
        [SVM_EXIT_VMLOAD]                       = invalid_op_interception,
        [SVM_EXIT_VMSAVE]                       = invalid_op_interception,
-       [SVM_EXIT_STGI]                         = invalid_op_interception,
-       [SVM_EXIT_CLGI]                         = invalid_op_interception,
+       [SVM_EXIT_STGI]                         = stgi_interception,
+       [SVM_EXIT_CLGI]                         = clgi_interception,
        [SVM_EXIT_SKINIT]                       = invalid_op_interception,
        [SVM_EXIT_WBINVD]                       = emulate_on_interception,
        [SVM_EXIT_MONITOR]                      = invalid_op_interception,
        if (!kvm_cpu_has_interrupt(vcpu))
                goto out;
 
+       if (!(svm->vcpu.arch.hflags & HF_GIF_MASK))
+               goto out;
+
        if (!(vmcb->save.rflags & X86_EFLAGS_IF) ||
            (vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK) ||
            (vmcb->control.event_inj & SVM_EVTINJ_VALID)) {
        }
 
        svm->vcpu.arch.interrupt_window_open =
-               !(control->int_state & SVM_INTERRUPT_SHADOW_MASK);
+               !(control->int_state & SVM_INTERRUPT_SHADOW_MASK) &&
+                (svm->vcpu.arch.hflags & HF_GIF_MASK);
 }
 
 static void svm_do_inject_vector(struct vcpu_svm *svm)
 
        svm->vcpu.arch.interrupt_window_open =
                (!(control->int_state & SVM_INTERRUPT_SHADOW_MASK) &&
-                (svm->vmcb->save.rflags & X86_EFLAGS_IF));
+                (svm->vmcb->save.rflags & X86_EFLAGS_IF) &&
+                (svm->vcpu.arch.hflags & HF_GIF_MASK));
 
        if (svm->vcpu.arch.interrupt_window_open && svm->vcpu.arch.irq_summary)
                /*