aboutsummaryrefslogtreecommitdiffstats
path: root/virt/kvm/ioapic.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 /virt/kvm/ioapic.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 'virt/kvm/ioapic.c')
-rw-r--r--virt/kvm/ioapic.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c
index f3abbef46c42..ce82b9401958 100644
--- a/virt/kvm/ioapic.c
+++ b/virt/kvm/ioapic.c
@@ -35,6 +35,7 @@
35#include <linux/hrtimer.h> 35#include <linux/hrtimer.h>
36#include <linux/io.h> 36#include <linux/io.h>
37#include <linux/slab.h> 37#include <linux/slab.h>
38#include <linux/export.h>
38#include <asm/processor.h> 39#include <asm/processor.h>
39#include <asm/page.h> 40#include <asm/page.h>
40#include <asm/current.h> 41#include <asm/current.h>
@@ -115,6 +116,42 @@ static void update_handled_vectors(struct kvm_ioapic *ioapic)
115 smp_wmb(); 116 smp_wmb();
116} 117}
117 118
119void kvm_ioapic_calculate_eoi_exitmap(struct kvm_vcpu *vcpu,
120 u64 *eoi_exit_bitmap)
121{
122 struct kvm_ioapic *ioapic = vcpu->kvm->arch.vioapic;
123 union kvm_ioapic_redirect_entry *e;
124 struct kvm_lapic_irq irqe;
125 int index;
126
127 spin_lock(&ioapic->lock);
128 /* traverse ioapic entry to set eoi exit bitmap*/
129 for (index = 0; index < IOAPIC_NUM_PINS; index++) {
130 e = &ioapic->redirtbl[index];
131 if (!e->fields.mask &&
132 (e->fields.trig_mode == IOAPIC_LEVEL_TRIG ||
133 kvm_irq_has_notifier(ioapic->kvm, KVM_IRQCHIP_IOAPIC,
134 index))) {
135 irqe.dest_id = e->fields.dest_id;
136 irqe.vector = e->fields.vector;
137 irqe.dest_mode = e->fields.dest_mode;
138 irqe.delivery_mode = e->fields.delivery_mode << 8;
139 kvm_calculate_eoi_exitmap(vcpu, &irqe, eoi_exit_bitmap);
140 }
141 }
142 spin_unlock(&ioapic->lock);
143}
144EXPORT_SYMBOL_GPL(kvm_ioapic_calculate_eoi_exitmap);
145
146void kvm_ioapic_make_eoibitmap_request(struct kvm *kvm)
147{
148 struct kvm_ioapic *ioapic = kvm->arch.vioapic;
149
150 if (!kvm_apic_vid_enabled(kvm) || !ioapic)
151 return;
152 kvm_make_update_eoibitmap_request(kvm);
153}
154
118static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val) 155static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val)
119{ 156{
120 unsigned index; 157 unsigned index;
@@ -156,6 +193,7 @@ static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val)
156 if (e->fields.trig_mode == IOAPIC_LEVEL_TRIG 193 if (e->fields.trig_mode == IOAPIC_LEVEL_TRIG
157 && ioapic->irr & (1 << index)) 194 && ioapic->irr & (1 << index))
158 ioapic_service(ioapic, index); 195 ioapic_service(ioapic, index);
196 kvm_ioapic_make_eoibitmap_request(ioapic->kvm);
159 break; 197 break;
160 } 198 }
161} 199}
@@ -455,6 +493,7 @@ int kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state)
455 spin_lock(&ioapic->lock); 493 spin_lock(&ioapic->lock);
456 memcpy(ioapic, state, sizeof(struct kvm_ioapic_state)); 494 memcpy(ioapic, state, sizeof(struct kvm_ioapic_state));
457 update_handled_vectors(ioapic); 495 update_handled_vectors(ioapic);
496 kvm_ioapic_make_eoibitmap_request(kvm);
458 spin_unlock(&ioapic->lock); 497 spin_unlock(&ioapic->lock);
459 return 0; 498 return 0;
460} 499}