diff options
-rw-r--r-- | include/linux/kvm_host.h | 2 | ||||
-rw-r--r-- | include/trace/events/kvm.h | 8 | ||||
-rw-r--r-- | virt/kvm/eventfd.c | 122 | ||||
-rw-r--r-- | virt/kvm/kvm_main.c | 2 |
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) |
41 | TRACE_EVENT(kvm_set_irq, | 41 | TRACE_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 | ||
129 | TRACE_EVENT(kvm_ack_irq, | 129 | TRACE_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 | |||
449 | bool 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 | } | ||
468 | EXPORT_SYMBOL_GPL(kvm_irq_has_notifier); | ||
469 | |||
470 | void 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 | |||
487 | void 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 | |||
498 | void 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 | ||
450 | void | 511 | void |
@@ -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 | |||
871 | bool 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 | } | ||
890 | EXPORT_SYMBOL_GPL(kvm_irq_has_notifier); | ||
891 | |||
892 | void 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 | |||
909 | void 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 | |||
920 | void 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 | ||