diff options
Diffstat (limited to 'virt')
-rw-r--r-- | virt/kvm/eventfd.c | 63 | ||||
-rw-r--r-- | virt/kvm/irqchip.c | 61 |
2 files changed, 63 insertions, 61 deletions
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c index f0075ffb0c35..99957df69cf2 100644 --- a/virt/kvm/eventfd.c +++ b/virt/kvm/eventfd.c | |||
@@ -34,7 +34,9 @@ | |||
34 | #include <linux/srcu.h> | 34 | #include <linux/srcu.h> |
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/seqlock.h> | 36 | #include <linux/seqlock.h> |
37 | #include <trace/events/kvm.h> | ||
37 | 38 | ||
39 | #include "irq.h" | ||
38 | #include "iodev.h" | 40 | #include "iodev.h" |
39 | 41 | ||
40 | #ifdef CONFIG_HAVE_KVM_IRQ_ROUTING | 42 | #ifdef CONFIG_HAVE_KVM_IRQ_ROUTING |
@@ -865,3 +867,64 @@ kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args) | |||
865 | 867 | ||
866 | return kvm_assign_ioeventfd(kvm, args); | 868 | return kvm_assign_ioeventfd(kvm, args); |
867 | } | 869 | } |
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/irqchip.c b/virt/kvm/irqchip.c index 04faac50cef5..7f256f31df10 100644 --- a/virt/kvm/irqchip.c +++ b/virt/kvm/irqchip.c | |||
@@ -69,67 +69,6 @@ int kvm_irq_map_chip_pin(struct kvm *kvm, unsigned irqchip, unsigned pin) | |||
69 | return irq_rt->chip[irqchip][pin]; | 69 | return irq_rt->chip[irqchip][pin]; |
70 | } | 70 | } |
71 | 71 | ||
72 | bool kvm_irq_has_notifier(struct kvm *kvm, unsigned irqchip, unsigned pin) | ||
73 | { | ||
74 | struct kvm_irq_ack_notifier *kian; | ||
75 | int gsi, idx; | ||
76 | |||
77 | idx = srcu_read_lock(&kvm->irq_srcu); | ||
78 | gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin); | ||
79 | if (gsi != -1) | ||
80 | hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list, | ||
81 | link) | ||
82 | if (kian->gsi == gsi) { | ||
83 | srcu_read_unlock(&kvm->irq_srcu, idx); | ||
84 | return true; | ||
85 | } | ||
86 | |||
87 | srcu_read_unlock(&kvm->irq_srcu, idx); | ||
88 | |||
89 | return false; | ||
90 | } | ||
91 | EXPORT_SYMBOL_GPL(kvm_irq_has_notifier); | ||
92 | |||
93 | void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin) | ||
94 | { | ||
95 | struct kvm_irq_ack_notifier *kian; | ||
96 | int gsi, idx; | ||
97 | |||
98 | trace_kvm_ack_irq(irqchip, pin); | ||
99 | |||
100 | idx = srcu_read_lock(&kvm->irq_srcu); | ||
101 | gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin); | ||
102 | if (gsi != -1) | ||
103 | hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list, | ||
104 | link) | ||
105 | if (kian->gsi == gsi) | ||
106 | kian->irq_acked(kian); | ||
107 | srcu_read_unlock(&kvm->irq_srcu, idx); | ||
108 | } | ||
109 | |||
110 | void kvm_register_irq_ack_notifier(struct kvm *kvm, | ||
111 | struct kvm_irq_ack_notifier *kian) | ||
112 | { | ||
113 | mutex_lock(&kvm->irq_lock); | ||
114 | hlist_add_head_rcu(&kian->link, &kvm->irq_ack_notifier_list); | ||
115 | mutex_unlock(&kvm->irq_lock); | ||
116 | #ifdef __KVM_HAVE_IOAPIC | ||
117 | kvm_vcpu_request_scan_ioapic(kvm); | ||
118 | #endif | ||
119 | } | ||
120 | |||
121 | void kvm_unregister_irq_ack_notifier(struct kvm *kvm, | ||
122 | struct kvm_irq_ack_notifier *kian) | ||
123 | { | ||
124 | mutex_lock(&kvm->irq_lock); | ||
125 | hlist_del_init_rcu(&kian->link); | ||
126 | mutex_unlock(&kvm->irq_lock); | ||
127 | synchronize_srcu(&kvm->irq_srcu); | ||
128 | #ifdef __KVM_HAVE_IOAPIC | ||
129 | kvm_vcpu_request_scan_ioapic(kvm); | ||
130 | #endif | ||
131 | } | ||
132 | |||
133 | int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi) | 72 | int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi) |
134 | { | 73 | { |
135 | struct kvm_kernel_irq_routing_entry route; | 74 | struct kvm_kernel_irq_routing_entry route; |