diff options
author | Weidong Han <weidong.han@intel.com> | 2008-12-02 16:24:23 +0300 |
---|---|---|
committer | Joerg Roedel <joerg.roedel@amd.com> | 2009-01-03 16:02:19 +0300 |
commit | 0a920356748df4fb06e86c21c23d2ed6d31d37ad (patch) | |
tree | 545bf8591b48b8f33af3f03f50a536424853a259 /virt/kvm/kvm_main.c | |
parent | 260782bcfdaaa7850f29d6bb2ec6603019168c57 (diff) | |
download | linux-0a920356748df4fb06e86c21c23d2ed6d31d37ad.tar.xz |
KVM: support device deassignment
Support device deassignment, it can be used in device hotplug.
Signed-off-by: Weidong Han <weidong.han@intel.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Diffstat (limited to 'virt/kvm/kvm_main.c')
-rw-r--r-- | virt/kvm/kvm_main.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index c92b63462b79..3238e08e4651 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -530,6 +530,35 @@ out_free: } #endif +#ifdef KVM_CAP_DEVICE_DEASSIGNMENT +static int kvm_vm_ioctl_deassign_device(struct kvm *kvm, + struct kvm_assigned_pci_dev *assigned_dev) +{ + int r = 0; + struct kvm_assigned_dev_kernel *match; + + mutex_lock(&kvm->lock); + + match = kvm_find_assigned_dev(&kvm->arch.assigned_dev_head, + assigned_dev->assigned_dev_id); + if (!match) { + printk(KERN_INFO "%s: device hasn't been assigned before, " + "so cannot be deassigned\n", __func__); + r = -EINVAL; + goto out; + } + + if (assigned_dev->flags & KVM_DEV_ASSIGN_ENABLE_IOMMU) + kvm_deassign_device(kvm, match); + + kvm_free_assigned_device(kvm, match); + +out: + mutex_unlock(&kvm->lock); + return r; +} +#endif + static inline int valid_vcpu(int n) { return likely(n >= 0 && n < KVM_MAX_VCPUS); @@ -1863,6 +1892,19 @@ static long kvm_vm_ioctl(struct file *filp, break; } #endif +#ifdef KVM_CAP_DEVICE_DEASSIGNMENT + case KVM_DEASSIGN_PCI_DEVICE: { + struct kvm_assigned_pci_dev assigned_dev; + + r = -EFAULT; + if (copy_from_user(&assigned_dev, argp, sizeof assigned_dev)) + goto out; + r = kvm_vm_ioctl_deassign_device(kvm, &assigned_dev); + if (r) + goto out; + break; + } +#endif default: r = kvm_arch_vm_ioctl(filp, ioctl, arg); } |