Skip to content

Commit fa7a549

Browse files
committed
KVM: x86: accept userspace interrupt only if no event is injected
Once an exception has been injected, any side effects related to the exception (such as setting CR2 or DR6) have been taked place. Therefore, once KVM sets the VM-entry interruption information field or the AMD EVENTINJ field, the next VM-entry must deliver that exception. Pending interrupts are processed after injected exceptions, so in theory it would not be a problem to use KVM_INTERRUPT when an injected exception is present. However, DOSEMU is using run->ready_for_interrupt_injection to detect interrupt windows and then using KVM_SET_SREGS/KVM_SET_REGS to inject the interrupt manually. For this to work, the interrupt window must be delayed after the completion of the previous event injection. Cc: stable@vger.kernel.org Reported-by: Stas Sergeev <stsp2@yandex.ru> Tested-by: Stas Sergeev <stsp2@yandex.ru> Fixes: 71cc849 ("KVM: x86: Fix split-irqchip vs interrupt injection window request") Reviewed-by: Sean Christopherson <seanjc@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent 8750f9b commit fa7a549

1 file changed

Lines changed: 11 additions & 2 deletions

File tree

arch/x86/kvm/x86.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4358,8 +4358,17 @@ static int kvm_cpu_accept_dm_intr(struct kvm_vcpu *vcpu)
43584358

43594359
static int kvm_vcpu_ready_for_interrupt_injection(struct kvm_vcpu *vcpu)
43604360
{
4361-
return kvm_arch_interrupt_allowed(vcpu) &&
4362-
kvm_cpu_accept_dm_intr(vcpu);
4361+
/*
4362+
* Do not cause an interrupt window exit if an exception
4363+
* is pending or an event needs reinjection; userspace
4364+
* might want to inject the interrupt manually using KVM_SET_REGS
4365+
* or KVM_SET_SREGS. For that to work, we must be at an
4366+
* instruction boundary and with no events half-injected.
4367+
*/
4368+
return (kvm_arch_interrupt_allowed(vcpu) &&
4369+
kvm_cpu_accept_dm_intr(vcpu) &&
4370+
!kvm_event_needs_reinjection(vcpu) &&
4371+
!vcpu->arch.exception.pending);
43634372
}
43644373

43654374
static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,

0 commit comments

Comments
 (0)