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

[PATCH 6/6] vmx/apicv: Don't defer RVI update when an event is pending injection



With virtual interrupt delivery, vmx_intr_assist() bails out early when
VM_ENTRY_INTR_INFO already holds an event to inject (e.g. a re-injected
exception, or a #DB from single-stepping an emulated instruction). For
PIC, NMI and MCE sources it arms the interrupt window, so Xen gets
another go once the event has been delivered. For LAPIC sources it
does nothing, leaving RVI stale.

Hardware only delivers virtual interrupts based on RVI, so a LAPIC
vector which became pending in the same VM exit (synced from the PIR,
or raised by the emulated instruction itself) isn't seen by the guest
until some unrelated VM exit runs vmx_intr_assist() again.  That can
take an arbitrary amount of time if the guest doesn't exit; up to
~10ms was observed in testing.

There is no need to wait: an event in VM_ENTRY_INTR_INFO doesn't
prevent RVI from being updated, and hardware evaluates pending virtual
interrupts once the injected event has been delivered. Only skip the
early exit for LAPIC sources; the others still need VM_ENTRY_INTR_INFO
themselves.

Fixes: 25b81a7941d7 ("xen: enable Virtual-interrupt delivery")
Signed-off-by: Teddy Astie <teddy.astie@xxxxxxxxxx>
Assisted-by: Claude Fable 5.1
---
 xen/arch/x86/hvm/vmx/intr.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/xen/arch/x86/hvm/vmx/intr.c b/xen/arch/x86/hvm/vmx/intr.c
index 6c220c4c2e..85d8bfa31d 100644
--- a/xen/arch/x86/hvm/vmx/intr.c
+++ b/xen/arch/x86/hvm/vmx/intr.c
@@ -274,8 +274,17 @@ void asmlinkage vmx_intr_assist(void)
                 goto out;
             }
 
+            /*
+             * An event already queued for injection only gets in the way of
+             * interrupts which need VM_ENTRY_INTR_INFO themselves.  LAPIC
+             * interrupts are delivered by hardware based on RVI, which can be
+             * updated regardless: the virtual interrupt is then recognised
+             * once the injected event has been delivered, without needing a
+             * further VM exit for Xen to notice the pending vector.
+             */
             __vmread(VM_ENTRY_INTR_INFO, &intr_info);
-            if ( intr_info & INTR_INFO_VALID_MASK )
+            if ( (intr_info & INTR_INFO_VALID_MASK) &&
+                 intack.source != hvm_intsrc_lapic )
             {
                 if ( (intack.source == hvm_intsrc_pic) ||
                      (intack.source == hvm_intsrc_nmi) ||
-- 
2.56.0



--
Teddy Astie | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.