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

[Xen-devel] [PATCH] vmx, apicv: fix save/restore issue with apicv



From: Yang Zhang <yang.z.zhang@xxxxxxxxx>

This patch fix two issues:

1. Interrupts on PIR are lost during save/restore. Syncing the PIR
into IRR during save will fix it.

2. EOI exit bitmap doesn't setup correctly after restore. Here we
will construct the eoi exit bimap via (IRR | ISR). Though it may cause
unnecessary eoi exit of the interrupts that pending in IRR or ISR during
save/resotre, each pending interrupt only causes one vmexit. The
subsequent interrupts will adjust the eoi exit bitmap correctly. So
the performace hurt can be ignored.

Signed-off-by: Yang Zhang <yang.z.zhang@xxxxxxxxx>
---
Hi Olaf and Malcolm, Can you help to retest it? Because the key part
is changed in this patch, so i'm not sure whether it still works in
your side.

Also, Olaf, is it ok to add your SOB in this patch? If yes, I can resend
it to do it.

 xen/arch/x86/hvm/vlapic.c  |    3 +++
 xen/arch/x86/hvm/vmx/vmx.c |   27 ++++++++++++++++++++++++++-
 2 files changed, 29 insertions(+), 1 deletions(-)

diff --git a/xen/arch/x86/hvm/vlapic.c b/xen/arch/x86/hvm/vlapic.c
index 99ae1be..e702ed3 100644
--- a/xen/arch/x86/hvm/vlapic.c
+++ b/xen/arch/x86/hvm/vlapic.c
@@ -1259,6 +1259,9 @@ static int lapic_save_regs(struct domain *d, 
hvm_domain_context_t *h)
 
     for_each_vcpu ( d, v )
     {
+        if ( hvm_funcs.sync_pir_to_irr )
+            hvm_funcs.sync_pir_to_irr(v);
+
         s = vcpu_vlapic(v);
         if ( (rc = hvm_save_entry(LAPIC_REGS, v->vcpu_id, h, s->regs)) != 0 )
             break;
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index 304aeea..fb38d15 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -1583,7 +1583,9 @@ static int vmx_virtual_intr_delivery_enabled(void)
 static void vmx_process_isr(int isr, struct vcpu *v)
 {
     unsigned long status;
-    u8 old;
+    u8 old, i;
+    unsigned int *eoi_exit_bitmap, val;
+    struct vlapic *vlapic = vcpu_vlapic(v);
 
     if ( isr < 0 )
         isr = 0;
@@ -1597,6 +1599,29 @@ static void vmx_process_isr(int isr, struct vcpu *v)
         status |= isr << VMX_GUEST_INTR_STATUS_SVI_OFFSET;
         __vmwrite(GUEST_INTR_STATUS, status);
     }
+
+    eoi_exit_bitmap = (unsigned int *)v->arch.hvm_vmx.eoi_exit_bitmap;
+    /*
+     * We cannot simple copy the TMR as eoi exit bitmap due to the special
+     * periodic timer interrupt which is edge trigger but need a mandatory
+     * EOI-induced VM exit to let pending periodic timer interrupts have the
+     * chance to be injected for compensation.
+     * Here we will construct the eoi exit bimap via (IRR | ISR). Though it
+     * may cause unnecessary eoi exit of the interrupts that pending in IRR or
+     * ISR during save/resotre, each pending interrupt only causes one vmexit.
+     * The subsequent interrupts will adjust the eoi exit bitmap correctly. So
+     * the performace hurt can be ingored.
+     */
+    for ( i = 0x10; i < 0x80; i += 0x10 )
+    {
+        val = vlapic_get_reg(vlapic, APIC_IRR + i);
+        val |= vlapic_get_reg(vlapic, APIC_ISR + i);
+        eoi_exit_bitmap[i >> 4] |= val;
+    }
+
+    for ( i = 0; i < 4; i++ )
+        __vmwrite(EOI_EXIT_BITMAP(i), v->arch.hvm_vmx.eoi_exit_bitmap[i]);
+
     vmx_vmcs_exit(v);
 }
 
-- 
1.7.6.3


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

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