EOI is one of key VM Exit at high bandwidth IO such as VT-d with 10Gb/s NIC. This patch accelerate guest EOI emulation utilizing HW VM Exit information. Signed-off-by: Eddie Dong <eddie.dong@xxxxxxxxx> diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index ccafe0d..b63138f 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -875,6 +875,15 @@ void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8) | (apic_get_reg(apic, APIC_TASKPRI) & 4)); } +void kvm_lapic_set_eoi(struct kvm_vcpu *vcpu) +{ + struct kvm_lapic *apic = vcpu->arch.apic; + + if (apic) + apic_set_eoi(apic); +} +EXPORT_SYMBOL_GPL(kvm_lapic_set_eoi); + u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu) { struct kvm_lapic *apic = vcpu->arch.apic; diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h index 40010b0..3a7a29a 100644 --- a/arch/x86/kvm/lapic.h +++ b/arch/x86/kvm/lapic.h @@ -27,6 +27,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 3a75db3..6eea29d 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -3125,6 +3125,12 @@ static int handle_apic_access(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) exit_qualification = vmcs_readl(EXIT_QUALIFICATION); offset = exit_qualification & 0xffful; + if ((exit_qualification >> 12) & 0xf == 1 && + offset == APIC_EOI) { /* EOI write */ + kvm_lapic_set_eoi(vcpu); + skip_emulated_instruction(vcpu); + return 1; + } er = emulate_instruction(vcpu, kvm_run, 0, 0, 0);
Attachment:
eoi2.patch
Description: eoi2.patch