Commit fc6f7c03 authored by Paolo Bonzini's avatar Paolo Bonzini

KVM: nSVM: Report interrupts as allowed when in L2 and exit-on-interrupt is set

Report interrupts as allowed when the vCPU is in L2 and L2 is being run with
exit-on-interrupts enabled and EFLAGS.IF=1 (either on the host or on the guest
according to VINTR).  Interrupts are always unblocked from L1's perspective
in this case.

While moving nested_exit_on_intr to svm.h, use INTERCEPT_INTR properly instead
of assuming it's zero (which it is of course).
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 1cd2f0b0
...@@ -828,11 +828,6 @@ static void nested_svm_intr(struct vcpu_svm *svm) ...@@ -828,11 +828,6 @@ static void nested_svm_intr(struct vcpu_svm *svm)
nested_svm_vmexit(svm); nested_svm_vmexit(svm);
} }
static bool nested_exit_on_intr(struct vcpu_svm *svm)
{
return (svm->nested.intercept & 1ULL);
}
static int svm_check_nested_events(struct kvm_vcpu *vcpu) static int svm_check_nested_events(struct kvm_vcpu *vcpu)
{ {
struct vcpu_svm *svm = to_svm(vcpu); struct vcpu_svm *svm = to_svm(vcpu);
......
...@@ -3117,14 +3117,25 @@ bool svm_interrupt_blocked(struct kvm_vcpu *vcpu) ...@@ -3117,14 +3117,25 @@ bool svm_interrupt_blocked(struct kvm_vcpu *vcpu)
struct vcpu_svm *svm = to_svm(vcpu); struct vcpu_svm *svm = to_svm(vcpu);
struct vmcb *vmcb = svm->vmcb; struct vmcb *vmcb = svm->vmcb;
if (!gif_set(svm) || if (!gif_set(svm))
(vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK))
return true; return true;
if (is_guest_mode(vcpu) && (svm->vcpu.arch.hflags & HF_VINTR_MASK)) if (is_guest_mode(vcpu)) {
return !(svm->vcpu.arch.hflags & HF_HIF_MASK); /* As long as interrupts are being delivered... */
else if ((svm->vcpu.arch.hflags & HF_VINTR_MASK)
return !(kvm_get_rflags(vcpu) & X86_EFLAGS_IF); ? !(svm->vcpu.arch.hflags & HF_HIF_MASK)
: !(kvm_get_rflags(vcpu) & X86_EFLAGS_IF))
return true;
/* ... vmexits aren't blocked by the interrupt shadow */
if (nested_exit_on_intr(svm))
return false;
} else {
if (!(kvm_get_rflags(vcpu) & X86_EFLAGS_IF))
return true;
}
return (vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK);
} }
static bool svm_interrupt_allowed(struct kvm_vcpu *vcpu) static bool svm_interrupt_allowed(struct kvm_vcpu *vcpu)
......
...@@ -386,6 +386,11 @@ static inline bool nested_exit_on_smi(struct vcpu_svm *svm) ...@@ -386,6 +386,11 @@ static inline bool nested_exit_on_smi(struct vcpu_svm *svm)
return (svm->nested.intercept & (1ULL << INTERCEPT_SMI)); return (svm->nested.intercept & (1ULL << INTERCEPT_SMI));
} }
static inline bool nested_exit_on_intr(struct vcpu_svm *svm)
{
return (svm->nested.intercept & (1ULL << INTERCEPT_INTR));
}
static inline bool nested_exit_on_nmi(struct vcpu_svm *svm) static inline bool nested_exit_on_nmi(struct vcpu_svm *svm)
{ {
return (svm->nested.intercept & (1ULL << INTERCEPT_NMI)); return (svm->nested.intercept & (1ULL << INTERCEPT_NMI));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment