Re: [PATCH v2] KVM: x86: sync old tmr with ioapic to update

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

 



Il 27/08/2014 16:05, Wei Wang ha scritto:
> kvm_ioapic_scan_entry() needs to update tmr. The previous lapic tmr value
> (old_tmr) needs to sync with ioapic to get an accurate updated tmr
> value before the updating work.
> 
> Tested-by: Rongrong Liu <rongrongx.liu@xxxxxxxxx>
> Signed-off-by: Yang Zhang <yang.z.zhang@xxxxxxxxx>
> Signed-off-by: Wei Wang <wei.w.wang@xxxxxxxxx>

This is also a very terse commit message.  As mentioned in the review 
of the other patch, I'm not sure this change is correct, but in any case
here is how a better commit message could have looked like:

    According to the Intel manuals, TMR is only modified upon "acceptance
    of an interrupt into the IRR".  Currently, this is not what KVM does;
    any IOAPIC scan will modify the TMR.
    
    The TMR is used to track whether an EOI message needs to be sent to
    the IOAPIC.  In KVM, this means that we need to add the vector to the
    EOI exit bitmap, and in fact the next patch will use the TMR exactly
    for this purpose.  However, if we change the TMR value for an active
    interrupt we risk missing an EOI, similar to the scenario fixed by
    commit 0f6c0a740b7d (KVM: x86: always exit on EOIs for interrupts listed
    in the IOAPIC redir table, 2014-07-30).
    
    This patch ensures that the TMR does not change between acceptance of
    an interrupt into the IRR and the corresponding EOI cycle; to do this,
    we mix values from the old TMR (where ISR|IRR=1) and from the IOAPIC's
    redirection table (where ISR|IRR=0 in the LAPIC).
    
    We still deviate from the spec by setting a value for the TMR even
    when the corresponding bit in IRR|ISR is 0, but that's mostly invisible
    to guests.
    
Paolo

> ---
>  arch/x86/kvm/lapic.c |   19 +++++++++++++++++--
>  arch/x86/kvm/x86.c   |    2 +-
>  2 files changed, 18 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
> index 08e8a89..8c1162d 100644
> --- a/arch/x86/kvm/lapic.c
> +++ b/arch/x86/kvm/lapic.c
> @@ -518,10 +518,25 @@ static void pv_eoi_clr_pending(struct kvm_vcpu *vcpu)
>  void kvm_apic_update_tmr(struct kvm_vcpu *vcpu, u32 *tmr)
>  {
>  	struct kvm_lapic *apic = vcpu->arch.apic;
> +	u32 irr;
> +	u32 isr;
> +	u32 old_tmr, new_tmr;
>  	int i;
>  
> -	for (i = 0; i < 8; i++)
> -		apic_set_reg(apic, APIC_TMR + 0x10 * i, tmr[i]);
> +	/*
> +	 * The updated tmr value comes from level-triggerd interrupts that
> +	 * have already been delieverd to lapic and new coming ones which
> +	 * are pending in ioapic. According to the x86 spec, tmr is valid
> +	 * when irr or isr is set.
> +	 */
> +	for (i = 0; i < 8; i++) {
> +		irr = kvm_apic_get_reg(apic, APIC_IRR + 0x10 * i);
> +		isr = kvm_apic_get_reg(apic, APIC_ISR + 0x10 * i);
> +		old_tmr = kvm_apic_get_reg(apic, APIC_TMR + 0x10 * i);
> +		new_tmr = (~(irr | isr) & tmr[i])
> +				| ((irr | isr) & old_tmr);
> +		apic_set_reg(apic, APIC_TMR + 0x10 * i, new_tmr);
> +	}
>  }
>  
>  static void apic_update_ppr(struct kvm_lapic *apic)
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 5f5edb6..d401684 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -5991,8 +5991,8 @@ static void vcpu_scan_ioapic(struct kvm_vcpu *vcpu)
>  	memset(tmr, 0, 32);
>  
>  	kvm_ioapic_scan_entry(vcpu, eoi_exit_bitmap, tmr);
> -	kvm_x86_ops->load_eoi_exitmap(vcpu, eoi_exit_bitmap);
>  	kvm_apic_update_tmr(vcpu, tmr);
> +	kvm_x86_ops->load_eoi_exitmap(vcpu, eoi_exit_bitmap);
>  }
>  
>  /*
> 

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[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