aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/kvm_host.h2
-rw-r--r--include/trace/events/kvm.h8
-rw-r--r--virt/kvm/eventfd.c122
-rw-r--r--virt/kvm/kvm_main.c2
4 files changed, 69 insertions, 65 deletions
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 8593d2e61cbf..a4c33b34fe3f 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -388,6 +388,8 @@ struct kvm {
388 */ 388 */
389 struct kvm_irq_routing_table __rcu *irq_routing; 389 struct kvm_irq_routing_table __rcu *irq_routing;
390 struct hlist_head mask_notifier_list; 390 struct hlist_head mask_notifier_list;
391#endif
392#ifdef CONFIG_HAVE_KVM_IRQFD
391 struct hlist_head irq_ack_notifier_list; 393 struct hlist_head irq_ack_notifier_list;
392#endif 394#endif
393 395
diff --git a/include/trace/events/kvm.h b/include/trace/events/kvm.h
index 131a0bda7aec..908925ace776 100644
--- a/include/trace/events/kvm.h
+++ b/include/trace/events/kvm.h
@@ -37,7 +37,7 @@ TRACE_EVENT(kvm_userspace_exit,
37 __entry->errno < 0 ? -__entry->errno : __entry->reason) 37 __entry->errno < 0 ? -__entry->errno : __entry->reason)
38); 38);
39 39
40#if defined(CONFIG_HAVE_KVM_IRQCHIP) 40#if defined(CONFIG_HAVE_KVM_IRQFD)
41TRACE_EVENT(kvm_set_irq, 41TRACE_EVENT(kvm_set_irq,
42 TP_PROTO(unsigned int gsi, int level, int irq_source_id), 42 TP_PROTO(unsigned int gsi, int level, int irq_source_id),
43 TP_ARGS(gsi, level, irq_source_id), 43 TP_ARGS(gsi, level, irq_source_id),
@@ -57,7 +57,7 @@ TRACE_EVENT(kvm_set_irq,
57 TP_printk("gsi %u level %d source %d", 57 TP_printk("gsi %u level %d source %d",
58 __entry->gsi, __entry->level, __entry->irq_source_id) 58 __entry->gsi, __entry->level, __entry->irq_source_id)
59); 59);
60#endif 60#endif /* defined(CONFIG_HAVE_KVM_IRQFD) */
61 61
62#if defined(__KVM_HAVE_IOAPIC) 62#if defined(__KVM_HAVE_IOAPIC)
63#define kvm_deliver_mode \ 63#define kvm_deliver_mode \
@@ -124,7 +124,7 @@ TRACE_EVENT(kvm_msi_set_irq,
124 124
125#endif /* defined(__KVM_HAVE_IOAPIC) */ 125#endif /* defined(__KVM_HAVE_IOAPIC) */
126 126
127#if defined(CONFIG_HAVE_KVM_IRQCHIP) 127#if defined(CONFIG_HAVE_KVM_IRQFD)
128 128
129TRACE_EVENT(kvm_ack_irq, 129TRACE_EVENT(kvm_ack_irq,
130 TP_PROTO(unsigned int irqchip, unsigned int pin), 130 TP_PROTO(unsigned int irqchip, unsigned int pin),
@@ -149,7 +149,7 @@ TRACE_EVENT(kvm_ack_irq,
149#endif 149#endif
150); 150);
151 151
152#endif /* defined(CONFIG_HAVE_KVM_IRQCHIP) */ 152#endif /* defined(CONFIG_HAVE_KVM_IRQFD) */
153 153
154 154
155 155
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index f5f61548f60d..3c5981c87c3f 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -445,6 +445,67 @@ out:
445 kfree(irqfd); 445 kfree(irqfd);
446 return ret; 446 return ret;
447} 447}
448
449bool kvm_irq_has_notifier(struct kvm *kvm, unsigned irqchip, unsigned pin)
450{
451 struct kvm_irq_ack_notifier *kian;
452 int gsi, idx;
453
454 idx = srcu_read_lock(&kvm->irq_srcu);
455 gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin);
456 if (gsi != -1)
457 hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list,
458 link)
459 if (kian->gsi == gsi) {
460 srcu_read_unlock(&kvm->irq_srcu, idx);
461 return true;
462 }
463
464 srcu_read_unlock(&kvm->irq_srcu, idx);
465
466 return false;
467}
468EXPORT_SYMBOL_GPL(kvm_irq_has_notifier);
469
470void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin)
471{
472 struct kvm_irq_ack_notifier *kian;
473 int gsi, idx;
474
475 trace_kvm_ack_irq(irqchip, pin);
476
477 idx = srcu_read_lock(&kvm->irq_srcu);
478 gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin);
479 if (gsi != -1)
480 hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list,
481 link)
482 if (kian->gsi == gsi)
483 kian->irq_acked(kian);
484 srcu_read_unlock(&kvm->irq_srcu, idx);
485}
486
487void kvm_register_irq_ack_notifier(struct kvm *kvm,
488 struct kvm_irq_ack_notifier *kian)
489{
490 mutex_lock(&kvm->irq_lock);
491 hlist_add_head_rcu(&kian->link, &kvm->irq_ack_notifier_list);
492 mutex_unlock(&kvm->irq_lock);
493#ifdef __KVM_HAVE_IOAPIC
494 kvm_vcpu_request_scan_ioapic(kvm);
495#endif
496}
497
498void kvm_unregister_irq_ack_notifier(struct kvm *kvm,
499 struct kvm_irq_ack_notifier *kian)
500{
501 mutex_lock(&kvm->irq_lock);
502 hlist_del_init_rcu(&kian->link);
503 mutex_unlock(&kvm->irq_lock);
504 synchronize_srcu(&kvm->irq_srcu);
505#ifdef __KVM_HAVE_IOAPIC
506 kvm_vcpu_request_scan_ioapic(kvm);
507#endif
508}
448#endif 509#endif
449 510
450void 511void
@@ -867,64 +928,3 @@ kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
867 928
868 return kvm_assign_ioeventfd(kvm, args); 929 return kvm_assign_ioeventfd(kvm, args);
869} 930}
870
871bool kvm_irq_has_notifier(struct kvm *kvm, unsigned irqchip, unsigned pin)
872{
873 struct kvm_irq_ack_notifier *kian;
874 int gsi, idx;
875
876 idx = srcu_read_lock(&kvm->irq_srcu);
877 gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin);
878 if (gsi != -1)
879 hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list,
880 link)
881 if (kian->gsi == gsi) {
882 srcu_read_unlock(&kvm->irq_srcu, idx);
883 return true;
884 }
885
886 srcu_read_unlock(&kvm->irq_srcu, idx);
887
888 return false;
889}
890EXPORT_SYMBOL_GPL(kvm_irq_has_notifier);
891
892void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin)
893{
894 struct kvm_irq_ack_notifier *kian;
895 int gsi, idx;
896
897 trace_kvm_ack_irq(irqchip, pin);
898
899 idx = srcu_read_lock(&kvm->irq_srcu);
900 gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin);
901 if (gsi != -1)
902 hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list,
903 link)
904 if (kian->gsi == gsi)
905 kian->irq_acked(kian);
906 srcu_read_unlock(&kvm->irq_srcu, idx);
907}
908
909void kvm_register_irq_ack_notifier(struct kvm *kvm,
910 struct kvm_irq_ack_notifier *kian)
911{
912 mutex_lock(&kvm->irq_lock);
913 hlist_add_head_rcu(&kian->link, &kvm->irq_ack_notifier_list);
914 mutex_unlock(&kvm->irq_lock);
915#ifdef __KVM_HAVE_IOAPIC
916 kvm_vcpu_request_scan_ioapic(kvm);
917#endif
918}
919
920void kvm_unregister_irq_ack_notifier(struct kvm *kvm,
921 struct kvm_irq_ack_notifier *kian)
922{
923 mutex_lock(&kvm->irq_lock);
924 hlist_del_init_rcu(&kian->link);
925 mutex_unlock(&kvm->irq_lock);
926 synchronize_srcu(&kvm->irq_srcu);
927#ifdef __KVM_HAVE_IOAPIC
928 kvm_vcpu_request_scan_ioapic(kvm);
929#endif
930}
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index a69a623938b8..33712fb26eb1 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -465,6 +465,8 @@ static struct kvm *kvm_create_vm(unsigned long type)
465 465
466#ifdef CONFIG_HAVE_KVM_IRQCHIP 466#ifdef CONFIG_HAVE_KVM_IRQCHIP
467 INIT_HLIST_HEAD(&kvm->mask_notifier_list); 467 INIT_HLIST_HEAD(&kvm->mask_notifier_list);
468#endif
469#ifdef CONFIG_HAVE_KVM_IRQFD
468 INIT_HLIST_HEAD(&kvm->irq_ack_notifier_list); 470 INIT_HLIST_HEAD(&kvm->irq_ack_notifier_list);
469#endif 471#endif
470 472