diff options
author | Grant Likely <grant.likely@secretlab.ca> | 2012-07-25 00:31:09 -0400 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2012-07-25 00:34:40 -0400 |
commit | 6aeea3ecc33b1f36dbc3b80461d15a7052ae424f (patch) | |
tree | bbd273e3e0ca76094aed8e9c77e5adfe2b07f779 /virt | |
parent | 9844a5524ec532aee826c35e3031637c7fc8287b (diff) | |
parent | bdc0077af574800d24318b6945cf2344e8dbb050 (diff) |
Merge remote-tracking branch 'origin' into irqdomain/next
Diffstat (limited to 'virt')
-rw-r--r-- | virt/kvm/assigned-dev.c | 15 | ||||
-rw-r--r-- | virt/kvm/ioapic.c | 19 | ||||
-rw-r--r-- | virt/kvm/ioapic.h | 4 | ||||
-rw-r--r-- | virt/kvm/irq_comm.c | 31 | ||||
-rw-r--r-- | virt/kvm/kvm_main.c | 36 |
5 files changed, 60 insertions, 45 deletions
diff --git a/virt/kvm/assigned-dev.c b/virt/kvm/assigned-dev.c index b1e091ae2f37..23a41a9f8db9 100644 --- a/virt/kvm/assigned-dev.c +++ b/virt/kvm/assigned-dev.c | |||
@@ -334,6 +334,11 @@ static int assigned_device_enable_host_intx(struct kvm *kvm, | |||
334 | } | 334 | } |
335 | 335 | ||
336 | #ifdef __KVM_HAVE_MSI | 336 | #ifdef __KVM_HAVE_MSI |
337 | static irqreturn_t kvm_assigned_dev_msi(int irq, void *dev_id) | ||
338 | { | ||
339 | return IRQ_WAKE_THREAD; | ||
340 | } | ||
341 | |||
337 | static int assigned_device_enable_host_msi(struct kvm *kvm, | 342 | static int assigned_device_enable_host_msi(struct kvm *kvm, |
338 | struct kvm_assigned_dev_kernel *dev) | 343 | struct kvm_assigned_dev_kernel *dev) |
339 | { | 344 | { |
@@ -346,7 +351,7 @@ static int assigned_device_enable_host_msi(struct kvm *kvm, | |||
346 | } | 351 | } |
347 | 352 | ||
348 | dev->host_irq = dev->dev->irq; | 353 | dev->host_irq = dev->dev->irq; |
349 | if (request_threaded_irq(dev->host_irq, NULL, | 354 | if (request_threaded_irq(dev->host_irq, kvm_assigned_dev_msi, |
350 | kvm_assigned_dev_thread_msi, 0, | 355 | kvm_assigned_dev_thread_msi, 0, |
351 | dev->irq_name, dev)) { | 356 | dev->irq_name, dev)) { |
352 | pci_disable_msi(dev->dev); | 357 | pci_disable_msi(dev->dev); |
@@ -358,6 +363,11 @@ static int assigned_device_enable_host_msi(struct kvm *kvm, | |||
358 | #endif | 363 | #endif |
359 | 364 | ||
360 | #ifdef __KVM_HAVE_MSIX | 365 | #ifdef __KVM_HAVE_MSIX |
366 | static irqreturn_t kvm_assigned_dev_msix(int irq, void *dev_id) | ||
367 | { | ||
368 | return IRQ_WAKE_THREAD; | ||
369 | } | ||
370 | |||
361 | static int assigned_device_enable_host_msix(struct kvm *kvm, | 371 | static int assigned_device_enable_host_msix(struct kvm *kvm, |
362 | struct kvm_assigned_dev_kernel *dev) | 372 | struct kvm_assigned_dev_kernel *dev) |
363 | { | 373 | { |
@@ -374,7 +384,8 @@ static int assigned_device_enable_host_msix(struct kvm *kvm, | |||
374 | 384 | ||
375 | for (i = 0; i < dev->entries_nr; i++) { | 385 | for (i = 0; i < dev->entries_nr; i++) { |
376 | r = request_threaded_irq(dev->host_msix_entries[i].vector, | 386 | r = request_threaded_irq(dev->host_msix_entries[i].vector, |
377 | NULL, kvm_assigned_dev_thread_msix, | 387 | kvm_assigned_dev_msix, |
388 | kvm_assigned_dev_thread_msix, | ||
378 | 0, dev->irq_name, dev); | 389 | 0, dev->irq_name, dev); |
379 | if (r) | 390 | if (r) |
380 | goto err; | 391 | goto err; |
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c index 26fd54dc459e..ef61d529a6c4 100644 --- a/virt/kvm/ioapic.c +++ b/virt/kvm/ioapic.c | |||
@@ -191,7 +191,8 @@ static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq) | |||
191 | return kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe); | 191 | return kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe); |
192 | } | 192 | } |
193 | 193 | ||
194 | int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level) | 194 | int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int irq_source_id, |
195 | int level) | ||
195 | { | 196 | { |
196 | u32 old_irr; | 197 | u32 old_irr; |
197 | u32 mask = 1 << irq; | 198 | u32 mask = 1 << irq; |
@@ -201,9 +202,11 @@ int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level) | |||
201 | spin_lock(&ioapic->lock); | 202 | spin_lock(&ioapic->lock); |
202 | old_irr = ioapic->irr; | 203 | old_irr = ioapic->irr; |
203 | if (irq >= 0 && irq < IOAPIC_NUM_PINS) { | 204 | if (irq >= 0 && irq < IOAPIC_NUM_PINS) { |
205 | int irq_level = __kvm_irq_line_state(&ioapic->irq_states[irq], | ||
206 | irq_source_id, level); | ||
204 | entry = ioapic->redirtbl[irq]; | 207 | entry = ioapic->redirtbl[irq]; |
205 | level ^= entry.fields.polarity; | 208 | irq_level ^= entry.fields.polarity; |
206 | if (!level) | 209 | if (!irq_level) |
207 | ioapic->irr &= ~mask; | 210 | ioapic->irr &= ~mask; |
208 | else { | 211 | else { |
209 | int edge = (entry.fields.trig_mode == IOAPIC_EDGE_TRIG); | 212 | int edge = (entry.fields.trig_mode == IOAPIC_EDGE_TRIG); |
@@ -221,6 +224,16 @@ int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level) | |||
221 | return ret; | 224 | return ret; |
222 | } | 225 | } |
223 | 226 | ||
227 | void kvm_ioapic_clear_all(struct kvm_ioapic *ioapic, int irq_source_id) | ||
228 | { | ||
229 | int i; | ||
230 | |||
231 | spin_lock(&ioapic->lock); | ||
232 | for (i = 0; i < KVM_IOAPIC_NUM_PINS; i++) | ||
233 | __clear_bit(irq_source_id, &ioapic->irq_states[i]); | ||
234 | spin_unlock(&ioapic->lock); | ||
235 | } | ||
236 | |||
224 | static void __kvm_ioapic_update_eoi(struct kvm_ioapic *ioapic, int vector, | 237 | static void __kvm_ioapic_update_eoi(struct kvm_ioapic *ioapic, int vector, |
225 | int trigger_mode) | 238 | int trigger_mode) |
226 | { | 239 | { |
diff --git a/virt/kvm/ioapic.h b/virt/kvm/ioapic.h index 32872a09b63f..a30abfe6ed16 100644 --- a/virt/kvm/ioapic.h +++ b/virt/kvm/ioapic.h | |||
@@ -74,7 +74,9 @@ void kvm_ioapic_update_eoi(struct kvm *kvm, int vector, int trigger_mode); | |||
74 | bool kvm_ioapic_handles_vector(struct kvm *kvm, int vector); | 74 | bool kvm_ioapic_handles_vector(struct kvm *kvm, int vector); |
75 | int kvm_ioapic_init(struct kvm *kvm); | 75 | int kvm_ioapic_init(struct kvm *kvm); |
76 | void kvm_ioapic_destroy(struct kvm *kvm); | 76 | void kvm_ioapic_destroy(struct kvm *kvm); |
77 | int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level); | 77 | int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int irq_source_id, |
78 | int level); | ||
79 | void kvm_ioapic_clear_all(struct kvm_ioapic *ioapic, int irq_source_id); | ||
78 | void kvm_ioapic_reset(struct kvm_ioapic *ioapic); | 80 | void kvm_ioapic_reset(struct kvm_ioapic *ioapic); |
79 | int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src, | 81 | int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src, |
80 | struct kvm_lapic_irq *irq); | 82 | struct kvm_lapic_irq *irq); |
diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c index 5afb43114020..83402d74a767 100644 --- a/virt/kvm/irq_comm.c +++ b/virt/kvm/irq_comm.c | |||
@@ -33,26 +33,12 @@ | |||
33 | 33 | ||
34 | #include "ioapic.h" | 34 | #include "ioapic.h" |
35 | 35 | ||
36 | static inline int kvm_irq_line_state(unsigned long *irq_state, | ||
37 | int irq_source_id, int level) | ||
38 | { | ||
39 | /* Logical OR for level trig interrupt */ | ||
40 | if (level) | ||
41 | set_bit(irq_source_id, irq_state); | ||
42 | else | ||
43 | clear_bit(irq_source_id, irq_state); | ||
44 | |||
45 | return !!(*irq_state); | ||
46 | } | ||
47 | |||
48 | static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e, | 36 | static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e, |
49 | struct kvm *kvm, int irq_source_id, int level) | 37 | struct kvm *kvm, int irq_source_id, int level) |
50 | { | 38 | { |
51 | #ifdef CONFIG_X86 | 39 | #ifdef CONFIG_X86 |
52 | struct kvm_pic *pic = pic_irqchip(kvm); | 40 | struct kvm_pic *pic = pic_irqchip(kvm); |
53 | level = kvm_irq_line_state(&pic->irq_states[e->irqchip.pin], | 41 | return kvm_pic_set_irq(pic, e->irqchip.pin, irq_source_id, level); |
54 | irq_source_id, level); | ||
55 | return kvm_pic_set_irq(pic, e->irqchip.pin, level); | ||
56 | #else | 42 | #else |
57 | return -1; | 43 | return -1; |
58 | #endif | 44 | #endif |
@@ -62,10 +48,7 @@ static int kvm_set_ioapic_irq(struct kvm_kernel_irq_routing_entry *e, | |||
62 | struct kvm *kvm, int irq_source_id, int level) | 48 | struct kvm *kvm, int irq_source_id, int level) |
63 | { | 49 | { |
64 | struct kvm_ioapic *ioapic = kvm->arch.vioapic; | 50 | struct kvm_ioapic *ioapic = kvm->arch.vioapic; |
65 | level = kvm_irq_line_state(&ioapic->irq_states[e->irqchip.pin], | 51 | return kvm_ioapic_set_irq(ioapic, e->irqchip.pin, irq_source_id, level); |
66 | irq_source_id, level); | ||
67 | |||
68 | return kvm_ioapic_set_irq(ioapic, e->irqchip.pin, level); | ||
69 | } | 52 | } |
70 | 53 | ||
71 | inline static bool kvm_is_dm_lowest_prio(struct kvm_lapic_irq *irq) | 54 | inline static bool kvm_is_dm_lowest_prio(struct kvm_lapic_irq *irq) |
@@ -249,8 +232,6 @@ unlock: | |||
249 | 232 | ||
250 | void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id) | 233 | void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id) |
251 | { | 234 | { |
252 | int i; | ||
253 | |||
254 | ASSERT(irq_source_id != KVM_USERSPACE_IRQ_SOURCE_ID); | 235 | ASSERT(irq_source_id != KVM_USERSPACE_IRQ_SOURCE_ID); |
255 | 236 | ||
256 | mutex_lock(&kvm->irq_lock); | 237 | mutex_lock(&kvm->irq_lock); |
@@ -263,14 +244,10 @@ void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id) | |||
263 | if (!irqchip_in_kernel(kvm)) | 244 | if (!irqchip_in_kernel(kvm)) |
264 | goto unlock; | 245 | goto unlock; |
265 | 246 | ||
266 | for (i = 0; i < KVM_IOAPIC_NUM_PINS; i++) { | 247 | kvm_ioapic_clear_all(kvm->arch.vioapic, irq_source_id); |
267 | clear_bit(irq_source_id, &kvm->arch.vioapic->irq_states[i]); | ||
268 | if (i >= 16) | ||
269 | continue; | ||
270 | #ifdef CONFIG_X86 | 248 | #ifdef CONFIG_X86 |
271 | clear_bit(irq_source_id, &pic_irqchip(kvm)->irq_states[i]); | 249 | kvm_pic_clear_all(pic_irqchip(kvm), irq_source_id); |
272 | #endif | 250 | #endif |
273 | } | ||
274 | unlock: | 251 | unlock: |
275 | mutex_unlock(&kvm->irq_lock); | 252 | mutex_unlock(&kvm->irq_lock); |
276 | } | 253 | } |
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 44ee7124b16d..246852397e30 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -516,16 +516,32 @@ out_err_nodisable: | |||
516 | return ERR_PTR(r); | 516 | return ERR_PTR(r); |
517 | } | 517 | } |
518 | 518 | ||
519 | /* | ||
520 | * Avoid using vmalloc for a small buffer. | ||
521 | * Should not be used when the size is statically known. | ||
522 | */ | ||
523 | void *kvm_kvzalloc(unsigned long size) | ||
524 | { | ||
525 | if (size > PAGE_SIZE) | ||
526 | return vzalloc(size); | ||
527 | else | ||
528 | return kzalloc(size, GFP_KERNEL); | ||
529 | } | ||
530 | |||
531 | void kvm_kvfree(const void *addr) | ||
532 | { | ||
533 | if (is_vmalloc_addr(addr)) | ||
534 | vfree(addr); | ||
535 | else | ||
536 | kfree(addr); | ||
537 | } | ||
538 | |||
519 | static void kvm_destroy_dirty_bitmap(struct kvm_memory_slot *memslot) | 539 | static void kvm_destroy_dirty_bitmap(struct kvm_memory_slot *memslot) |
520 | { | 540 | { |
521 | if (!memslot->dirty_bitmap) | 541 | if (!memslot->dirty_bitmap) |
522 | return; | 542 | return; |
523 | 543 | ||
524 | if (2 * kvm_dirty_bitmap_bytes(memslot) > PAGE_SIZE) | 544 | kvm_kvfree(memslot->dirty_bitmap); |
525 | vfree(memslot->dirty_bitmap); | ||
526 | else | ||
527 | kfree(memslot->dirty_bitmap); | ||
528 | |||
529 | memslot->dirty_bitmap = NULL; | 545 | memslot->dirty_bitmap = NULL; |
530 | } | 546 | } |
531 | 547 | ||
@@ -617,11 +633,7 @@ static int kvm_create_dirty_bitmap(struct kvm_memory_slot *memslot) | |||
617 | #ifndef CONFIG_S390 | 633 | #ifndef CONFIG_S390 |
618 | unsigned long dirty_bytes = 2 * kvm_dirty_bitmap_bytes(memslot); | 634 | unsigned long dirty_bytes = 2 * kvm_dirty_bitmap_bytes(memslot); |
619 | 635 | ||
620 | if (dirty_bytes > PAGE_SIZE) | 636 | memslot->dirty_bitmap = kvm_kvzalloc(dirty_bytes); |
621 | memslot->dirty_bitmap = vzalloc(dirty_bytes); | ||
622 | else | ||
623 | memslot->dirty_bitmap = kzalloc(dirty_bytes, GFP_KERNEL); | ||
624 | |||
625 | if (!memslot->dirty_bitmap) | 637 | if (!memslot->dirty_bitmap) |
626 | return -ENOMEM; | 638 | return -ENOMEM; |
627 | 639 | ||
@@ -1586,7 +1598,7 @@ void kvm_vcpu_on_spin(struct kvm_vcpu *me) | |||
1586 | */ | 1598 | */ |
1587 | for (pass = 0; pass < 2 && !yielded; pass++) { | 1599 | for (pass = 0; pass < 2 && !yielded; pass++) { |
1588 | kvm_for_each_vcpu(i, vcpu, kvm) { | 1600 | kvm_for_each_vcpu(i, vcpu, kvm) { |
1589 | if (!pass && i < last_boosted_vcpu) { | 1601 | if (!pass && i <= last_boosted_vcpu) { |
1590 | i = last_boosted_vcpu; | 1602 | i = last_boosted_vcpu; |
1591 | continue; | 1603 | continue; |
1592 | } else if (pass && i > last_boosted_vcpu) | 1604 | } else if (pass && i > last_boosted_vcpu) |
@@ -2213,7 +2225,7 @@ static long kvm_dev_ioctl_check_extension_generic(long arg) | |||
2213 | case KVM_CAP_SIGNAL_MSI: | 2225 | case KVM_CAP_SIGNAL_MSI: |
2214 | #endif | 2226 | #endif |
2215 | return 1; | 2227 | return 1; |
2216 | #ifdef CONFIG_HAVE_KVM_IRQCHIP | 2228 | #ifdef KVM_CAP_IRQ_ROUTING |
2217 | case KVM_CAP_IRQ_ROUTING: | 2229 | case KVM_CAP_IRQ_ROUTING: |
2218 | return KVM_MAX_IRQ_ROUTES; | 2230 | return KVM_MAX_IRQ_ROUTES; |
2219 | #endif | 2231 | #endif |