aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/x86.c
diff options
context:
space:
mode:
authorYang Zhang <yang.z.zhang@Intel.com>2013-01-24 21:18:51 -0500
committerGleb Natapov <gleb@redhat.com>2013-01-29 03:48:19 -0500
commitc7c9c56ca26f7b9458711b2d78b60b60e0d38ba7 (patch)
treefeab61b2f3a5587dd502a9d2bf4b27a8b2ebe507 /arch/x86/kvm/x86.c
parent8d14695f9542e9e0195d6e41ddaa52c32322adf5 (diff)
x86, apicv: add virtual interrupt delivery support
Virtual interrupt delivery avoids KVM to inject vAPIC interrupts manually, which is fully taken care of by the hardware. This needs some special awareness into existing interrupr injection path: - for pending interrupt, instead of direct injection, we may need update architecture specific indicators before resuming to guest. - A pending interrupt, which is masked by ISR, should be also considered in above update action, since hardware will decide when to inject it at right time. Current has_interrupt and get_interrupt only returns a valid vector from injection p.o.v. Reviewed-by: Marcelo Tosatti <mtosatti@redhat.com> Signed-off-by: Kevin Tian <kevin.tian@intel.com> Signed-off-by: Yang Zhang <yang.z.zhang@Intel.com> Signed-off-by: Gleb Natapov <gleb@redhat.com>
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r--arch/x86/kvm/x86.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index b9f55299ed7e..cf512e70c797 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -5565,7 +5565,7 @@ static void inject_pending_event(struct kvm_vcpu *vcpu)
5565 vcpu->arch.nmi_injected = true; 5565 vcpu->arch.nmi_injected = true;
5566 kvm_x86_ops->set_nmi(vcpu); 5566 kvm_x86_ops->set_nmi(vcpu);
5567 } 5567 }
5568 } else if (kvm_cpu_has_interrupt(vcpu)) { 5568 } else if (kvm_cpu_has_injectable_intr(vcpu)) {
5569 if (kvm_x86_ops->interrupt_allowed(vcpu)) { 5569 if (kvm_x86_ops->interrupt_allowed(vcpu)) {
5570 kvm_queue_interrupt(vcpu, kvm_cpu_get_interrupt(vcpu), 5570 kvm_queue_interrupt(vcpu, kvm_cpu_get_interrupt(vcpu),
5571 false); 5571 false);
@@ -5633,6 +5633,16 @@ static void kvm_gen_update_masterclock(struct kvm *kvm)
5633#endif 5633#endif
5634} 5634}
5635 5635
5636static void update_eoi_exitmap(struct kvm_vcpu *vcpu)
5637{
5638 u64 eoi_exit_bitmap[4];
5639
5640 memset(eoi_exit_bitmap, 0, 32);
5641
5642 kvm_ioapic_calculate_eoi_exitmap(vcpu, eoi_exit_bitmap);
5643 kvm_x86_ops->load_eoi_exitmap(vcpu, eoi_exit_bitmap);
5644}
5645
5636static int vcpu_enter_guest(struct kvm_vcpu *vcpu) 5646static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
5637{ 5647{
5638 int r; 5648 int r;
@@ -5686,6 +5696,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
5686 kvm_handle_pmu_event(vcpu); 5696 kvm_handle_pmu_event(vcpu);
5687 if (kvm_check_request(KVM_REQ_PMI, vcpu)) 5697 if (kvm_check_request(KVM_REQ_PMI, vcpu))
5688 kvm_deliver_pmi(vcpu); 5698 kvm_deliver_pmi(vcpu);
5699 if (kvm_check_request(KVM_REQ_EOIBITMAP, vcpu))
5700 update_eoi_exitmap(vcpu);
5689 } 5701 }
5690 5702
5691 if (kvm_check_request(KVM_REQ_EVENT, vcpu) || req_int_win) { 5703 if (kvm_check_request(KVM_REQ_EVENT, vcpu) || req_int_win) {
@@ -5694,10 +5706,17 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
5694 /* enable NMI/IRQ window open exits if needed */ 5706 /* enable NMI/IRQ window open exits if needed */
5695 if (vcpu->arch.nmi_pending) 5707 if (vcpu->arch.nmi_pending)
5696 kvm_x86_ops->enable_nmi_window(vcpu); 5708 kvm_x86_ops->enable_nmi_window(vcpu);
5697 else if (kvm_cpu_has_interrupt(vcpu) || req_int_win) 5709 else if (kvm_cpu_has_injectable_intr(vcpu) || req_int_win)
5698 kvm_x86_ops->enable_irq_window(vcpu); 5710 kvm_x86_ops->enable_irq_window(vcpu);
5699 5711
5700 if (kvm_lapic_enabled(vcpu)) { 5712 if (kvm_lapic_enabled(vcpu)) {
5713 /*
5714 * Update architecture specific hints for APIC
5715 * virtual interrupt delivery.
5716 */
5717 if (kvm_x86_ops->hwapic_irr_update)
5718 kvm_x86_ops->hwapic_irr_update(vcpu,
5719 kvm_lapic_find_highest_irr(vcpu));
5701 update_cr8_intercept(vcpu); 5720 update_cr8_intercept(vcpu);
5702 kvm_lapic_sync_to_vapic(vcpu); 5721 kvm_lapic_sync_to_vapic(vcpu);
5703 } 5722 }