[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |