Re: [RFC PATCH] Fix split-irqchip vs interrupt injection window request.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 2020-11-25 at 21:19 +0000, Sean Christopherson wrote:
> > --- a/arch/x86/kvm/x86.c
> > +++ b/arch/x86/kvm/x86.c
> > @@ -4028,7 +4028,7 @@ static int kvm_cpu_accept_dm_intr(struct kvm_vcpu *vcpu)
> >   static int kvm_vcpu_ready_for_interrupt_injection(struct kvm_vcpu *vcpu)
> >   {
> >          return kvm_arch_interrupt_allowed(vcpu) &&
> > -               !kvm_cpu_has_interrupt(vcpu) &&
> > +               !kvm_cpu_has_injectable_intr(vcpu) &&
> 
> Interrupt window exiting explicitly has priority over virtual interrupt delivery,
> so this is correct from that perspective.
> 
> But I wonder if would make sense to be more precise so that KVM behavior is
> consistent for APICv and legacy IRQ injection.  If the LAPIC is in-kernel,
> KVM_INTERRUPT can only be used for EXTINT; 

I think it should be used for injecting Xen event channel vectors too,
shouldn't it? Those have their own EOI/mask mechanism and shouldn't be
injected through the LAPIC (for example by simulating MSI to the
appropriate APIC+vector) because the guest won't EOI them there.

Although to all extents and purposes that basically means we *are*
treating them like ExtINT.

Not that it makes a difference to the outcome right now, although there
was once a patch floating around to allow KVM_INTERRUPT even when the
PIC was in-kernel, precisely for that reason.

> whether or not there's an IRQ in the
> LAPIC should be irrelevant when deciding to exit to userspace.  Note, the
> reinjection check covers vcpu->arch.interrupt.injected for the case where LAPIC
> is in userspace.
> 
>         return kvm_arch_interrupt_allowed(vcpu) &&
>                (!lapic_in_kernel(vcpu) || !kvm_cpu_has_extint(vcpu)) &&
>                !kvm_event_needs_reinjection(vcpu) &&
>                kvm_cpu_accept_dm_intr(vcpu);
> }

Makes sense. I'm putting this version through some testing and will
post it later...


diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index f002cdb13a0b..e85e2f1c661c 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1656,6 +1656,7 @@ int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end,
 int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end);
 int kvm_test_age_hva(struct kvm *kvm, unsigned long hva);
 int kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte);
+int kvm_cpu_has_extint(struct kvm_vcpu *v);
 int kvm_cpu_has_injectable_intr(struct kvm_vcpu *v);
 int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu);
 int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu);
diff --git a/arch/x86/kvm/irq.c b/arch/x86/kvm/irq.c
index 99d118ffc67d..9c4ef1682b81 100644
--- a/arch/x86/kvm/irq.c
+++ b/arch/x86/kvm/irq.c
@@ -40,7 +40,7 @@ static int pending_userspace_extint(struct kvm_vcpu *v)
  * check if there is pending interrupt from
  * non-APIC source without intack.
  */
-static int kvm_cpu_has_extint(struct kvm_vcpu *v)
+int kvm_cpu_has_extint(struct kvm_vcpu *v)
 {
 	u8 accept = kvm_apic_accept_pic_intr(v);
 
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index a3fdc16cfd6f..b50ae8ba66e9 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4080,12 +4080,14 @@ static int kvm_cpu_accept_dm_intr(struct kvm_vcpu *vcpu)
  * if userspace requested an interrupt window, check that the
  * interrupt window is open.
  *
- * No need to exit to userspace if we already have an interrupt queued.
+ * If there is already an event which needs reinjection or a
+ * pending ExtINT, allow that to be processed by the kernel
+ * before letting userspace have the opportunity.
  */
 static int kvm_vcpu_ready_for_interrupt_injection(struct kvm_vcpu *vcpu)
 {
 	return kvm_arch_interrupt_allowed(vcpu) &&
-		!kvm_cpu_has_interrupt(vcpu) &&
+		!(lapic_in_kernel(vcpu) && kvm_cpu_has_extint(vcpu)) &&
 		!kvm_event_needs_reinjection(vcpu) &&
 		kvm_cpu_accept_dm_intr(vcpu);
 }

Attachment: smime.p7s
Description: S/MIME cryptographic signature


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux