diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-05 17:47:31 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-05 17:47:31 -0400 |
commit | 01227a889ed56ae53aeebb9f93be9d54dd8b2de8 (patch) | |
tree | d5eba9359a9827e84d4112b84d48c54df5c5acde /virt/kvm/irq_comm.c | |
parent | 9e6879460c8edb0cd3c24c09b83d06541b5af0dc (diff) | |
parent | db6ae6158186a17165ef990bda2895ae7594b039 (diff) |
Merge tag 'kvm-3.10-1' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull kvm updates from Gleb Natapov:
"Highlights of the updates are:
general:
- new emulated device API
- legacy device assignment is now optional
- irqfd interface is more generic and can be shared between arches
x86:
- VMCS shadow support and other nested VMX improvements
- APIC virtualization and Posted Interrupt hardware support
- Optimize mmio spte zapping
ppc:
- BookE: in-kernel MPIC emulation with irqfd support
- Book3S: in-kernel XICS emulation (incomplete)
- Book3S: HV: migration fixes
- BookE: more debug support preparation
- BookE: e6500 support
ARM:
- reworking of Hyp idmaps
s390:
- ioeventfd for virtio-ccw
And many other bug fixes, cleanups and improvements"
* tag 'kvm-3.10-1' of git://git.kernel.org/pub/scm/virt/kvm/kvm: (204 commits)
kvm: Add compat_ioctl for device control API
KVM: x86: Account for failing enable_irq_window for NMI window request
KVM: PPC: Book3S: Add API for in-kernel XICS emulation
kvm/ppc/mpic: fix missing unlock in set_base_addr()
kvm/ppc: Hold srcu lock when calling kvm_io_bus_read/write
kvm/ppc/mpic: remove users
kvm/ppc/mpic: fix mmio region lists when multiple guests used
kvm/ppc/mpic: remove default routes from documentation
kvm: KVM_CAP_IOMMU only available with device assignment
ARM: KVM: iterate over all CPUs for CPU compatibility check
KVM: ARM: Fix spelling in error message
ARM: KVM: define KVM_ARM_MAX_VCPUS unconditionally
KVM: ARM: Fix API documentation for ONE_REG encoding
ARM: KVM: promote vfp_host pointer to generic host cpu context
ARM: KVM: add architecture specific hook for capabilities
ARM: KVM: perform HYP initilization for hotplugged CPUs
ARM: KVM: switch to a dual-step HYP init code
ARM: KVM: rework HYP page table freeing
ARM: KVM: enforce maximum size for identity mapped code
ARM: KVM: move to a KVM provided HYP idmap
...
Diffstat (limited to 'virt/kvm/irq_comm.c')
-rw-r--r-- | virt/kvm/irq_comm.c | 215 |
1 files changed, 16 insertions, 199 deletions
diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c index e9073cf4d040..e2e6b4473a96 100644 --- a/virt/kvm/irq_comm.c +++ b/virt/kvm/irq_comm.c | |||
@@ -35,7 +35,8 @@ | |||
35 | #include "ioapic.h" | 35 | #include "ioapic.h" |
36 | 36 | ||
37 | static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e, | 37 | static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e, |
38 | struct kvm *kvm, int irq_source_id, int level) | 38 | struct kvm *kvm, int irq_source_id, int level, |
39 | bool line_status) | ||
39 | { | 40 | { |
40 | #ifdef CONFIG_X86 | 41 | #ifdef CONFIG_X86 |
41 | struct kvm_pic *pic = pic_irqchip(kvm); | 42 | struct kvm_pic *pic = pic_irqchip(kvm); |
@@ -46,10 +47,12 @@ static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e, | |||
46 | } | 47 | } |
47 | 48 | ||
48 | static int kvm_set_ioapic_irq(struct kvm_kernel_irq_routing_entry *e, | 49 | static int kvm_set_ioapic_irq(struct kvm_kernel_irq_routing_entry *e, |
49 | struct kvm *kvm, int irq_source_id, int level) | 50 | struct kvm *kvm, int irq_source_id, int level, |
51 | bool line_status) | ||
50 | { | 52 | { |
51 | struct kvm_ioapic *ioapic = kvm->arch.vioapic; | 53 | struct kvm_ioapic *ioapic = kvm->arch.vioapic; |
52 | return kvm_ioapic_set_irq(ioapic, e->irqchip.pin, irq_source_id, level); | 54 | return kvm_ioapic_set_irq(ioapic, e->irqchip.pin, irq_source_id, level, |
55 | line_status); | ||
53 | } | 56 | } |
54 | 57 | ||
55 | inline static bool kvm_is_dm_lowest_prio(struct kvm_lapic_irq *irq) | 58 | inline static bool kvm_is_dm_lowest_prio(struct kvm_lapic_irq *irq) |
@@ -63,7 +66,7 @@ inline static bool kvm_is_dm_lowest_prio(struct kvm_lapic_irq *irq) | |||
63 | } | 66 | } |
64 | 67 | ||
65 | int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src, | 68 | int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src, |
66 | struct kvm_lapic_irq *irq) | 69 | struct kvm_lapic_irq *irq, unsigned long *dest_map) |
67 | { | 70 | { |
68 | int i, r = -1; | 71 | int i, r = -1; |
69 | struct kvm_vcpu *vcpu, *lowest = NULL; | 72 | struct kvm_vcpu *vcpu, *lowest = NULL; |
@@ -74,7 +77,7 @@ int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src, | |||
74 | irq->delivery_mode = APIC_DM_FIXED; | 77 | irq->delivery_mode = APIC_DM_FIXED; |
75 | } | 78 | } |
76 | 79 | ||
77 | if (kvm_irq_delivery_to_apic_fast(kvm, src, irq, &r)) | 80 | if (kvm_irq_delivery_to_apic_fast(kvm, src, irq, &r, dest_map)) |
78 | return r; | 81 | return r; |
79 | 82 | ||
80 | kvm_for_each_vcpu(i, vcpu, kvm) { | 83 | kvm_for_each_vcpu(i, vcpu, kvm) { |
@@ -88,7 +91,7 @@ int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src, | |||
88 | if (!kvm_is_dm_lowest_prio(irq)) { | 91 | if (!kvm_is_dm_lowest_prio(irq)) { |
89 | if (r < 0) | 92 | if (r < 0) |
90 | r = 0; | 93 | r = 0; |
91 | r += kvm_apic_set_irq(vcpu, irq); | 94 | r += kvm_apic_set_irq(vcpu, irq, dest_map); |
92 | } else if (kvm_lapic_enabled(vcpu)) { | 95 | } else if (kvm_lapic_enabled(vcpu)) { |
93 | if (!lowest) | 96 | if (!lowest) |
94 | lowest = vcpu; | 97 | lowest = vcpu; |
@@ -98,7 +101,7 @@ int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src, | |||
98 | } | 101 | } |
99 | 102 | ||
100 | if (lowest) | 103 | if (lowest) |
101 | r = kvm_apic_set_irq(lowest, irq); | 104 | r = kvm_apic_set_irq(lowest, irq, dest_map); |
102 | 105 | ||
103 | return r; | 106 | return r; |
104 | } | 107 | } |
@@ -121,7 +124,7 @@ static inline void kvm_set_msi_irq(struct kvm_kernel_irq_routing_entry *e, | |||
121 | } | 124 | } |
122 | 125 | ||
123 | int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, | 126 | int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, |
124 | struct kvm *kvm, int irq_source_id, int level) | 127 | struct kvm *kvm, int irq_source_id, int level, bool line_status) |
125 | { | 128 | { |
126 | struct kvm_lapic_irq irq; | 129 | struct kvm_lapic_irq irq; |
127 | 130 | ||
@@ -130,7 +133,7 @@ int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, | |||
130 | 133 | ||
131 | kvm_set_msi_irq(e, &irq); | 134 | kvm_set_msi_irq(e, &irq); |
132 | 135 | ||
133 | return kvm_irq_delivery_to_apic(kvm, NULL, &irq); | 136 | return kvm_irq_delivery_to_apic(kvm, NULL, &irq, NULL); |
134 | } | 137 | } |
135 | 138 | ||
136 | 139 | ||
@@ -142,63 +145,12 @@ static int kvm_set_msi_inatomic(struct kvm_kernel_irq_routing_entry *e, | |||
142 | 145 | ||
143 | kvm_set_msi_irq(e, &irq); | 146 | kvm_set_msi_irq(e, &irq); |
144 | 147 | ||
145 | if (kvm_irq_delivery_to_apic_fast(kvm, NULL, &irq, &r)) | 148 | if (kvm_irq_delivery_to_apic_fast(kvm, NULL, &irq, &r, NULL)) |
146 | return r; | 149 | return r; |
147 | else | 150 | else |
148 | return -EWOULDBLOCK; | 151 | return -EWOULDBLOCK; |
149 | } | 152 | } |
150 | 153 | ||
151 | int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi) | ||
152 | { | ||
153 | struct kvm_kernel_irq_routing_entry route; | ||
154 | |||
155 | if (!irqchip_in_kernel(kvm) || msi->flags != 0) | ||
156 | return -EINVAL; | ||
157 | |||
158 | route.msi.address_lo = msi->address_lo; | ||
159 | route.msi.address_hi = msi->address_hi; | ||
160 | route.msi.data = msi->data; | ||
161 | |||
162 | return kvm_set_msi(&route, kvm, KVM_USERSPACE_IRQ_SOURCE_ID, 1); | ||
163 | } | ||
164 | |||
165 | /* | ||
166 | * Return value: | ||
167 | * < 0 Interrupt was ignored (masked or not delivered for other reasons) | ||
168 | * = 0 Interrupt was coalesced (previous irq is still pending) | ||
169 | * > 0 Number of CPUs interrupt was delivered to | ||
170 | */ | ||
171 | int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level) | ||
172 | { | ||
173 | struct kvm_kernel_irq_routing_entry *e, irq_set[KVM_NR_IRQCHIPS]; | ||
174 | int ret = -1, i = 0; | ||
175 | struct kvm_irq_routing_table *irq_rt; | ||
176 | |||
177 | trace_kvm_set_irq(irq, level, irq_source_id); | ||
178 | |||
179 | /* Not possible to detect if the guest uses the PIC or the | ||
180 | * IOAPIC. So set the bit in both. The guest will ignore | ||
181 | * writes to the unused one. | ||
182 | */ | ||
183 | rcu_read_lock(); | ||
184 | irq_rt = rcu_dereference(kvm->irq_routing); | ||
185 | if (irq < irq_rt->nr_rt_entries) | ||
186 | hlist_for_each_entry(e, &irq_rt->map[irq], link) | ||
187 | irq_set[i++] = *e; | ||
188 | rcu_read_unlock(); | ||
189 | |||
190 | while(i--) { | ||
191 | int r; | ||
192 | r = irq_set[i].set(&irq_set[i], kvm, irq_source_id, level); | ||
193 | if (r < 0) | ||
194 | continue; | ||
195 | |||
196 | ret = r + ((ret < 0) ? 0 : ret); | ||
197 | } | ||
198 | |||
199 | return ret; | ||
200 | } | ||
201 | |||
202 | /* | 154 | /* |
203 | * Deliver an IRQ in an atomic context if we can, or return a failure, | 155 | * Deliver an IRQ in an atomic context if we can, or return a failure, |
204 | * user can retry in a process context. | 156 | * user can retry in a process context. |
@@ -236,63 +188,6 @@ int kvm_set_irq_inatomic(struct kvm *kvm, int irq_source_id, u32 irq, int level) | |||
236 | return ret; | 188 | return ret; |
237 | } | 189 | } |
238 | 190 | ||
239 | bool kvm_irq_has_notifier(struct kvm *kvm, unsigned irqchip, unsigned pin) | ||
240 | { | ||
241 | struct kvm_irq_ack_notifier *kian; | ||
242 | int gsi; | ||
243 | |||
244 | rcu_read_lock(); | ||
245 | gsi = rcu_dereference(kvm->irq_routing)->chip[irqchip][pin]; | ||
246 | if (gsi != -1) | ||
247 | hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list, | ||
248 | link) | ||
249 | if (kian->gsi == gsi) { | ||
250 | rcu_read_unlock(); | ||
251 | return true; | ||
252 | } | ||
253 | |||
254 | rcu_read_unlock(); | ||
255 | |||
256 | return false; | ||
257 | } | ||
258 | EXPORT_SYMBOL_GPL(kvm_irq_has_notifier); | ||
259 | |||
260 | void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin) | ||
261 | { | ||
262 | struct kvm_irq_ack_notifier *kian; | ||
263 | int gsi; | ||
264 | |||
265 | trace_kvm_ack_irq(irqchip, pin); | ||
266 | |||
267 | rcu_read_lock(); | ||
268 | gsi = rcu_dereference(kvm->irq_routing)->chip[irqchip][pin]; | ||
269 | if (gsi != -1) | ||
270 | hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list, | ||
271 | link) | ||
272 | if (kian->gsi == gsi) | ||
273 | kian->irq_acked(kian); | ||
274 | rcu_read_unlock(); | ||
275 | } | ||
276 | |||
277 | void kvm_register_irq_ack_notifier(struct kvm *kvm, | ||
278 | struct kvm_irq_ack_notifier *kian) | ||
279 | { | ||
280 | mutex_lock(&kvm->irq_lock); | ||
281 | hlist_add_head_rcu(&kian->link, &kvm->irq_ack_notifier_list); | ||
282 | mutex_unlock(&kvm->irq_lock); | ||
283 | kvm_ioapic_make_eoibitmap_request(kvm); | ||
284 | } | ||
285 | |||
286 | void kvm_unregister_irq_ack_notifier(struct kvm *kvm, | ||
287 | struct kvm_irq_ack_notifier *kian) | ||
288 | { | ||
289 | mutex_lock(&kvm->irq_lock); | ||
290 | hlist_del_init_rcu(&kian->link); | ||
291 | mutex_unlock(&kvm->irq_lock); | ||
292 | synchronize_rcu(); | ||
293 | kvm_ioapic_make_eoibitmap_request(kvm); | ||
294 | } | ||
295 | |||
296 | int kvm_request_irq_source_id(struct kvm *kvm) | 191 | int kvm_request_irq_source_id(struct kvm *kvm) |
297 | { | 192 | { |
298 | unsigned long *bitmap = &kvm->arch.irq_sources_bitmap; | 193 | unsigned long *bitmap = &kvm->arch.irq_sources_bitmap; |
@@ -376,34 +271,14 @@ void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin, | |||
376 | rcu_read_unlock(); | 271 | rcu_read_unlock(); |
377 | } | 272 | } |
378 | 273 | ||
379 | void kvm_free_irq_routing(struct kvm *kvm) | 274 | int kvm_set_routing_entry(struct kvm_irq_routing_table *rt, |
380 | { | 275 | struct kvm_kernel_irq_routing_entry *e, |
381 | /* Called only during vm destruction. Nobody can use the pointer | 276 | const struct kvm_irq_routing_entry *ue) |
382 | at this stage */ | ||
383 | kfree(kvm->irq_routing); | ||
384 | } | ||
385 | |||
386 | static int setup_routing_entry(struct kvm_irq_routing_table *rt, | ||
387 | struct kvm_kernel_irq_routing_entry *e, | ||
388 | const struct kvm_irq_routing_entry *ue) | ||
389 | { | 277 | { |
390 | int r = -EINVAL; | 278 | int r = -EINVAL; |
391 | int delta; | 279 | int delta; |
392 | unsigned max_pin; | 280 | unsigned max_pin; |
393 | struct kvm_kernel_irq_routing_entry *ei; | ||
394 | 281 | ||
395 | /* | ||
396 | * Do not allow GSI to be mapped to the same irqchip more than once. | ||
397 | * Allow only one to one mapping between GSI and MSI. | ||
398 | */ | ||
399 | hlist_for_each_entry(ei, &rt->map[ue->gsi], link) | ||
400 | if (ei->type == KVM_IRQ_ROUTING_MSI || | ||
401 | ue->type == KVM_IRQ_ROUTING_MSI || | ||
402 | ue->u.irqchip.irqchip == ei->irqchip.irqchip) | ||
403 | return r; | ||
404 | |||
405 | e->gsi = ue->gsi; | ||
406 | e->type = ue->type; | ||
407 | switch (ue->type) { | 282 | switch (ue->type) { |
408 | case KVM_IRQ_ROUTING_IRQCHIP: | 283 | case KVM_IRQ_ROUTING_IRQCHIP: |
409 | delta = 0; | 284 | delta = 0; |
@@ -440,69 +315,11 @@ static int setup_routing_entry(struct kvm_irq_routing_table *rt, | |||
440 | goto out; | 315 | goto out; |
441 | } | 316 | } |
442 | 317 | ||
443 | hlist_add_head(&e->link, &rt->map[e->gsi]); | ||
444 | r = 0; | 318 | r = 0; |
445 | out: | 319 | out: |
446 | return r; | 320 | return r; |
447 | } | 321 | } |
448 | 322 | ||
449 | |||
450 | int kvm_set_irq_routing(struct kvm *kvm, | ||
451 | const struct kvm_irq_routing_entry *ue, | ||
452 | unsigned nr, | ||
453 | unsigned flags) | ||
454 | { | ||
455 | struct kvm_irq_routing_table *new, *old; | ||
456 | u32 i, j, nr_rt_entries = 0; | ||
457 | int r; | ||
458 | |||
459 | for (i = 0; i < nr; ++i) { | ||
460 | if (ue[i].gsi >= KVM_MAX_IRQ_ROUTES) | ||
461 | return -EINVAL; | ||
462 | nr_rt_entries = max(nr_rt_entries, ue[i].gsi); | ||
463 | } | ||
464 | |||
465 | nr_rt_entries += 1; | ||
466 | |||
467 | new = kzalloc(sizeof(*new) + (nr_rt_entries * sizeof(struct hlist_head)) | ||
468 | + (nr * sizeof(struct kvm_kernel_irq_routing_entry)), | ||
469 | GFP_KERNEL); | ||
470 | |||
471 | if (!new) | ||
472 | return -ENOMEM; | ||
473 | |||
474 | new->rt_entries = (void *)&new->map[nr_rt_entries]; | ||
475 | |||
476 | new->nr_rt_entries = nr_rt_entries; | ||
477 | for (i = 0; i < 3; i++) | ||
478 | for (j = 0; j < KVM_IOAPIC_NUM_PINS; j++) | ||
479 | new->chip[i][j] = -1; | ||
480 | |||
481 | for (i = 0; i < nr; ++i) { | ||
482 | r = -EINVAL; | ||
483 | if (ue->flags) | ||
484 | goto out; | ||
485 | r = setup_routing_entry(new, &new->rt_entries[i], ue); | ||
486 | if (r) | ||
487 | goto out; | ||
488 | ++ue; | ||
489 | } | ||
490 | |||
491 | mutex_lock(&kvm->irq_lock); | ||
492 | old = kvm->irq_routing; | ||
493 | kvm_irq_routing_update(kvm, new); | ||
494 | mutex_unlock(&kvm->irq_lock); | ||
495 | |||
496 | synchronize_rcu(); | ||
497 | |||
498 | new = old; | ||
499 | r = 0; | ||
500 | |||
501 | out: | ||
502 | kfree(new); | ||
503 | return r; | ||
504 | } | ||
505 | |||
506 | #define IOAPIC_ROUTING_ENTRY(irq) \ | 323 | #define IOAPIC_ROUTING_ENTRY(irq) \ |
507 | { .gsi = irq, .type = KVM_IRQ_ROUTING_IRQCHIP, \ | 324 | { .gsi = irq, .type = KVM_IRQ_ROUTING_IRQCHIP, \ |
508 | .u.irqchip.irqchip = KVM_IRQCHIP_IOAPIC, .u.irqchip.pin = (irq) } | 325 | .u.irqchip.irqchip = KVM_IRQCHIP_IOAPIC, .u.irqchip.pin = (irq) } |