On Mon, 2011-08-29 at 15:35 +0800, Tian, Kevin wrote:
> > From: Avi Kivity [mailto:[email protected]]
> > Sent: Monday, August 29, 2011 3:24 PM
> >
> > On 08/29/2011 09:09 AM, Tian, Kevin wrote:
> > >
> > > static int handle_apic_access(struct kvm_vcpu *vcpu)
> > > {
> > > + unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
> > > + int access_type, offset;
> > > +
> > > + access_type = (exit_qualification>> 12)& 0xf;
> > > + offset = exit_qualification& 0xfff;
> > > + /*
> > > + * Sane guest uses MOV instead of string operations to
> > > + * write EOI, with written value not cared. So make a
> > > + * short-circuit here by avoiding heavy instruction
> > > + * emulation.
> > > + */
> > > + if ((access_type == 1)&& (offset == APIC_EOI)) {
> >
> > Please replace this 1 with a #define.
> >
>
> updated.
>
> --
>
> KVM: APIC: avoid instruction emulation for EOI writes
>
> Instruction emulation for EOI writes can be skipped, since sane
> guest simply uses MOV instead of string operations. This is a nice
> improvement when guest doesn't support x2apic or hyper-V EOI
> support.
>
> a single VM bandwidth is observed with ~8% bandwidth improvement
> (7.4Gbps->8Gbps), by saving ~5% cycles from EOI emulation.
>
> Signed-off-by: Kevin Tian <[email protected]>
> <Based on earlier work from>:
> Signed-off-by: Eddie Dong <[email protected]>
> Signed-off-by: Marcelo Tosatti <[email protected]>
>
> diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
> index 57dcbd4..933187e 100644
> --- a/arch/x86/kvm/lapic.c
> +++ b/arch/x86/kvm/lapic.c
> @@ -864,6 +864,15 @@ static int apic_mmio_write(struct kvm_io_device *this,
> return 0;
> }
>
> +void kvm_lapic_set_eoi(struct kvm_vcpu *vcpu)
> +{
> + struct kvm_lapic *apic = vcpu->arch.apic;
> +
> + if (apic)
> + apic_set_eoi(vcpu->arch.apic);
> +}
> +EXPORT_SYMBOL_GPL(kvm_lapic_set_eoi);
> +
> void kvm_free_lapic(struct kvm_vcpu *vcpu)
> {
> if (!vcpu->arch.apic)
> diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
> index 52c9e6b..8287243 100644
> --- a/arch/x86/kvm/lapic.h
> +++ b/arch/x86/kvm/lapic.h
> @@ -26,6 +26,7 @@ int kvm_get_apic_interrupt(struct kvm_vcpu *vcpu);
> void kvm_lapic_reset(struct kvm_vcpu *vcpu);
> u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu);
> void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8);
> +void kvm_lapic_set_eoi(struct kvm_vcpu *vcpu);
> void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value);
> u64 kvm_lapic_get_base(struct kvm_vcpu *vcpu);
> void kvm_apic_set_version(struct kvm_vcpu *vcpu);
> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> index 5e8d411..34c094f 100644
> --- a/arch/x86/kvm/vmx.c
> +++ b/arch/x86/kvm/vmx.c
> @@ -4538,8 +4538,25 @@ static int handle_xsetbv(struct kvm_vcpu *vcpu)
> return 1;
> }
>
> +#define APIC_ACCESS_TYPE_W 1 /* Linear write access during inst execution */
> static int handle_apic_access(struct kvm_vcpu *vcpu)
> {
> + unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
> + int access_type, offset;
> +
> + access_type = (exit_qualification >> 12) & 0xf;
> + offset = exit_qualification & 0xfff;
Maybe it's worth moving that #define above, and '#define'ing all the
magic that happens in these 2 lines in vmx.h along with all the other
exit qualification parameters?
> + /*
> + * Sane guest uses MOV instead of string operations to
> + * write EOI, with written value not cared. So make a
> + * short-circuit here by avoiding heavy instruction
> + * emulation.
> + */
> + if ((access_type == APIC_ACCESS_TYPE_W) && (offset == APIC_EOI)) {
> + kvm_lapic_set_eoi(vcpu);
> + skip_emulated_instruction(vcpu);
> + return 1;
> + }
> return emulate_instruction(vcpu, 0) == EMULATE_DONE;
> }
>
> Thanks
> Kevin
--
Sasha.
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html