aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/x86.c
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@redhat.com>2012-06-24 12:25:07 -0400
committerAvi Kivity <avi@redhat.com>2012-06-25 05:40:55 -0400
commitae7a2a3fb6f8b784c2752863f4f1f20c656f76fb (patch)
tree5f4053265d244bb12ccff88494d70124b6d603c3 /arch/x86/kvm/x86.c
parentd905c0693514e6f713b207377b67c9972c5d7d49 (diff)
KVM: host side for eoi optimization
Implementation of PV EOI using shared memory. This reduces the number of exits an interrupt causes as much as by half. The idea is simple: there's a bit, per APIC, in guest memory, that tells the guest that it does not need EOI. We set it before injecting an interrupt and clear before injecting a nested one. Guest tests it using a test and clear operation - this is necessary so that host can detect interrupt nesting - and if set, it can skip the EOI MSR. There's a new MSR to set the address of said register in guest memory. Otherwise not much changed: - Guest EOI is not required - Register is tested & ISR is automatically cleared on exit For testing results see description of previous patch 'kvm_para: guest side for eoi avoidance'. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r--arch/x86/kvm/x86.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 7ea0f611bc89..8eacb2e64560 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -795,6 +795,7 @@ static u32 msrs_to_save[] = {
795 MSR_KVM_SYSTEM_TIME_NEW, MSR_KVM_WALL_CLOCK_NEW, 795 MSR_KVM_SYSTEM_TIME_NEW, MSR_KVM_WALL_CLOCK_NEW,
796 HV_X64_MSR_GUEST_OS_ID, HV_X64_MSR_HYPERCALL, 796 HV_X64_MSR_GUEST_OS_ID, HV_X64_MSR_HYPERCALL,
797 HV_X64_MSR_APIC_ASSIST_PAGE, MSR_KVM_ASYNC_PF_EN, MSR_KVM_STEAL_TIME, 797 HV_X64_MSR_APIC_ASSIST_PAGE, MSR_KVM_ASYNC_PF_EN, MSR_KVM_STEAL_TIME,
798 MSR_KVM_PV_EOI_EN,
798 MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP, 799 MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP,
799 MSR_STAR, 800 MSR_STAR,
800#ifdef CONFIG_X86_64 801#ifdef CONFIG_X86_64
@@ -1653,6 +1654,10 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
1653 kvm_make_request(KVM_REQ_STEAL_UPDATE, vcpu); 1654 kvm_make_request(KVM_REQ_STEAL_UPDATE, vcpu);
1654 1655
1655 break; 1656 break;
1657 case MSR_KVM_PV_EOI_EN:
1658 if (kvm_lapic_enable_pv_eoi(vcpu, data))
1659 return 1;
1660 break;
1656 1661
1657 case MSR_IA32_MCG_CTL: 1662 case MSR_IA32_MCG_CTL:
1658 case MSR_IA32_MCG_STATUS: 1663 case MSR_IA32_MCG_STATUS:
@@ -5394,6 +5399,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
5394 5399
5395cancel_injection: 5400cancel_injection:
5396 kvm_x86_ops->cancel_injection(vcpu); 5401 kvm_x86_ops->cancel_injection(vcpu);
5402 if (unlikely(vcpu->arch.apic_attention))
5403 kvm_lapic_sync_from_vapic(vcpu);
5397out: 5404out:
5398 return r; 5405 return r;
5399} 5406}