aboutsummaryrefslogtreecommitdiffstats
path: root/virt/kvm/irq_comm.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/irq_comm.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/irq_comm.c')
-rw-r--r--virt/kvm/irq_comm.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c
index 656fa455e154..ff6d40e2c06d 100644
--- a/virt/kvm/irq_comm.c
+++ b/virt/kvm/irq_comm.c
@@ -22,6 +22,7 @@
22 22
23#include <linux/kvm_host.h> 23#include <linux/kvm_host.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/export.h>
25#include <trace/events/kvm.h> 26#include <trace/events/kvm.h>
26 27
27#include <asm/msidef.h> 28#include <asm/msidef.h>
@@ -237,6 +238,28 @@ int kvm_set_irq_inatomic(struct kvm *kvm, int irq_source_id, u32 irq, int level)
237 return ret; 238 return ret;
238} 239}
239 240
241bool kvm_irq_has_notifier(struct kvm *kvm, unsigned irqchip, unsigned pin)
242{
243 struct kvm_irq_ack_notifier *kian;
244 struct hlist_node *n;
245 int gsi;
246
247 rcu_read_lock();
248 gsi = rcu_dereference(kvm->irq_routing)->chip[irqchip][pin];
249 if (gsi != -1)
250 hlist_for_each_entry_rcu(kian, n, &kvm->irq_ack_notifier_list,
251 link)
252 if (kian->gsi == gsi) {
253 rcu_read_unlock();
254 return true;
255 }
256
257 rcu_read_unlock();
258
259 return false;
260}
261EXPORT_SYMBOL_GPL(kvm_irq_has_notifier);
262
240void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin) 263void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin)
241{ 264{
242 struct kvm_irq_ack_notifier *kian; 265 struct kvm_irq_ack_notifier *kian;
@@ -261,6 +284,7 @@ void kvm_register_irq_ack_notifier(struct kvm *kvm,
261 mutex_lock(&kvm->irq_lock); 284 mutex_lock(&kvm->irq_lock);
262 hlist_add_head_rcu(&kian->link, &kvm->irq_ack_notifier_list); 285 hlist_add_head_rcu(&kian->link, &kvm->irq_ack_notifier_list);
263 mutex_unlock(&kvm->irq_lock); 286 mutex_unlock(&kvm->irq_lock);
287 kvm_ioapic_make_eoibitmap_request(kvm);
264} 288}
265 289
266void kvm_unregister_irq_ack_notifier(struct kvm *kvm, 290void kvm_unregister_irq_ack_notifier(struct kvm *kvm,
@@ -270,6 +294,7 @@ void kvm_unregister_irq_ack_notifier(struct kvm *kvm,
270 hlist_del_init_rcu(&kian->link); 294 hlist_del_init_rcu(&kian->link);
271 mutex_unlock(&kvm->irq_lock); 295 mutex_unlock(&kvm->irq_lock);
272 synchronize_rcu(); 296 synchronize_rcu();
297 kvm_ioapic_make_eoibitmap_request(kvm);
273} 298}
274 299
275int kvm_request_irq_source_id(struct kvm *kvm) 300int kvm_request_irq_source_id(struct kvm *kvm)