diff options
author | Michal Marek <mmarek@suse.cz> | 2010-10-27 18:15:57 -0400 |
---|---|---|
committer | Michal Marek <mmarek@suse.cz> | 2010-10-27 18:15:57 -0400 |
commit | b74b953b998bcc2db91b694446f3a2619ec32de6 (patch) | |
tree | 6ce24caabd730f6ae9287ed0676ec32e6ff31e9d /virt/kvm/assigned-dev.c | |
parent | abb438526201c6a79949ad45375c051b6681c253 (diff) | |
parent | f6f94e2ab1b33f0082ac22d71f66385a60d8157f (diff) |
Merge commit 'v2.6.36' into kbuild/misc
Update to be able to fix a recent change to scripts/basic/docproc.c
(commit eda603f).
Diffstat (limited to 'virt/kvm/assigned-dev.c')
-rw-r--r-- | virt/kvm/assigned-dev.c | 28 |
1 files changed, 15 insertions, 13 deletions
diff --git a/virt/kvm/assigned-dev.c b/virt/kvm/assigned-dev.c index f73de631e3ee..7c98928b09d9 100644 --- a/virt/kvm/assigned-dev.c +++ b/virt/kvm/assigned-dev.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Kernel-based Virtual Machine - device assignment support | 2 | * Kernel-based Virtual Machine - device assignment support |
3 | * | 3 | * |
4 | * Copyright (C) 2006-9 Red Hat, Inc | 4 | * Copyright (C) 2010 Red Hat, Inc. and/or its affiliates. |
5 | * | 5 | * |
6 | * This work is licensed under the terms of the GNU GPL, version 2. See | 6 | * This work is licensed under the terms of the GNU GPL, version 2. See |
7 | * the COPYING file in the top-level directory. | 7 | * the COPYING file in the top-level directory. |
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/spinlock.h> | 16 | #include <linux/spinlock.h> |
17 | #include <linux/pci.h> | 17 | #include <linux/pci.h> |
18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
19 | #include <linux/slab.h> | ||
19 | #include "irq.h" | 20 | #include "irq.h" |
20 | 21 | ||
21 | static struct kvm_assigned_dev_kernel *kvm_find_assigned_dev(struct list_head *head, | 22 | static struct kvm_assigned_dev_kernel *kvm_find_assigned_dev(struct list_head *head, |
@@ -57,12 +58,10 @@ static int find_index_from_host_irq(struct kvm_assigned_dev_kernel | |||
57 | static void kvm_assigned_dev_interrupt_work_handler(struct work_struct *work) | 58 | static void kvm_assigned_dev_interrupt_work_handler(struct work_struct *work) |
58 | { | 59 | { |
59 | struct kvm_assigned_dev_kernel *assigned_dev; | 60 | struct kvm_assigned_dev_kernel *assigned_dev; |
60 | struct kvm *kvm; | ||
61 | int i; | 61 | int i; |
62 | 62 | ||
63 | assigned_dev = container_of(work, struct kvm_assigned_dev_kernel, | 63 | assigned_dev = container_of(work, struct kvm_assigned_dev_kernel, |
64 | interrupt_work); | 64 | interrupt_work); |
65 | kvm = assigned_dev->kvm; | ||
66 | 65 | ||
67 | spin_lock_irq(&assigned_dev->assigned_dev_lock); | 66 | spin_lock_irq(&assigned_dev->assigned_dev_lock); |
68 | if (assigned_dev->irq_requested_type & KVM_DEV_IRQ_HOST_MSIX) { | 67 | if (assigned_dev->irq_requested_type & KVM_DEV_IRQ_HOST_MSIX) { |
@@ -315,12 +314,16 @@ static int assigned_device_enable_host_msix(struct kvm *kvm, | |||
315 | kvm_assigned_dev_intr, 0, | 314 | kvm_assigned_dev_intr, 0, |
316 | "kvm_assigned_msix_device", | 315 | "kvm_assigned_msix_device", |
317 | (void *)dev); | 316 | (void *)dev); |
318 | /* FIXME: free requested_irq's on failure */ | ||
319 | if (r) | 317 | if (r) |
320 | return r; | 318 | goto err; |
321 | } | 319 | } |
322 | 320 | ||
323 | return 0; | 321 | return 0; |
322 | err: | ||
323 | for (i -= 1; i >= 0; i--) | ||
324 | free_irq(dev->host_msix_entries[i].vector, (void *)dev); | ||
325 | pci_disable_msix(dev->dev); | ||
326 | return r; | ||
324 | } | 327 | } |
325 | 328 | ||
326 | #endif | 329 | #endif |
@@ -443,9 +446,6 @@ static int kvm_vm_ioctl_assign_irq(struct kvm *kvm, | |||
443 | struct kvm_assigned_dev_kernel *match; | 446 | struct kvm_assigned_dev_kernel *match; |
444 | unsigned long host_irq_type, guest_irq_type; | 447 | unsigned long host_irq_type, guest_irq_type; |
445 | 448 | ||
446 | if (!capable(CAP_SYS_RAWIO)) | ||
447 | return -EPERM; | ||
448 | |||
449 | if (!irqchip_in_kernel(kvm)) | 449 | if (!irqchip_in_kernel(kvm)) |
450 | return r; | 450 | return r; |
451 | 451 | ||
@@ -504,12 +504,12 @@ out: | |||
504 | static int kvm_vm_ioctl_assign_device(struct kvm *kvm, | 504 | static int kvm_vm_ioctl_assign_device(struct kvm *kvm, |
505 | struct kvm_assigned_pci_dev *assigned_dev) | 505 | struct kvm_assigned_pci_dev *assigned_dev) |
506 | { | 506 | { |
507 | int r = 0; | 507 | int r = 0, idx; |
508 | struct kvm_assigned_dev_kernel *match; | 508 | struct kvm_assigned_dev_kernel *match; |
509 | struct pci_dev *dev; | 509 | struct pci_dev *dev; |
510 | 510 | ||
511 | mutex_lock(&kvm->lock); | 511 | mutex_lock(&kvm->lock); |
512 | down_read(&kvm->slots_lock); | 512 | idx = srcu_read_lock(&kvm->srcu); |
513 | 513 | ||
514 | match = kvm_find_assigned_dev(&kvm->arch.assigned_dev_head, | 514 | match = kvm_find_assigned_dev(&kvm->arch.assigned_dev_head, |
515 | assigned_dev->assigned_dev_id); | 515 | assigned_dev->assigned_dev_id); |
@@ -526,7 +526,8 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm, | |||
526 | r = -ENOMEM; | 526 | r = -ENOMEM; |
527 | goto out; | 527 | goto out; |
528 | } | 528 | } |
529 | dev = pci_get_bus_and_slot(assigned_dev->busnr, | 529 | dev = pci_get_domain_bus_and_slot(assigned_dev->segnr, |
530 | assigned_dev->busnr, | ||
530 | assigned_dev->devfn); | 531 | assigned_dev->devfn); |
531 | if (!dev) { | 532 | if (!dev) { |
532 | printk(KERN_INFO "%s: host device not found\n", __func__); | 533 | printk(KERN_INFO "%s: host device not found\n", __func__); |
@@ -548,6 +549,7 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm, | |||
548 | pci_reset_function(dev); | 549 | pci_reset_function(dev); |
549 | 550 | ||
550 | match->assigned_dev_id = assigned_dev->assigned_dev_id; | 551 | match->assigned_dev_id = assigned_dev->assigned_dev_id; |
552 | match->host_segnr = assigned_dev->segnr; | ||
551 | match->host_busnr = assigned_dev->busnr; | 553 | match->host_busnr = assigned_dev->busnr; |
552 | match->host_devfn = assigned_dev->devfn; | 554 | match->host_devfn = assigned_dev->devfn; |
553 | match->flags = assigned_dev->flags; | 555 | match->flags = assigned_dev->flags; |
@@ -573,7 +575,7 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm, | |||
573 | } | 575 | } |
574 | 576 | ||
575 | out: | 577 | out: |
576 | up_read(&kvm->slots_lock); | 578 | srcu_read_unlock(&kvm->srcu, idx); |
577 | mutex_unlock(&kvm->lock); | 579 | mutex_unlock(&kvm->lock); |
578 | return r; | 580 | return r; |
579 | out_list_del: | 581 | out_list_del: |
@@ -585,7 +587,7 @@ out_put: | |||
585 | pci_dev_put(dev); | 587 | pci_dev_put(dev); |
586 | out_free: | 588 | out_free: |
587 | kfree(match); | 589 | kfree(match); |
588 | up_read(&kvm->slots_lock); | 590 | srcu_read_unlock(&kvm->srcu, idx); |
589 | mutex_unlock(&kvm->lock); | 591 | mutex_unlock(&kvm->lock); |
590 | return r; | 592 | return r; |
591 | } | 593 | } |