aboutsummaryrefslogtreecommitdiffstats
path: root/virt/kvm/kvm_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'virt/kvm/kvm_main.c')
-rw-r--r--virt/kvm/kvm_main.c50
1 files changed, 49 insertions, 1 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index fc6127cbea1f..3a5a08298aab 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -496,6 +496,7 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm,
496 match->assigned_dev_id = assigned_dev->assigned_dev_id; 496 match->assigned_dev_id = assigned_dev->assigned_dev_id;
497 match->host_busnr = assigned_dev->busnr; 497 match->host_busnr = assigned_dev->busnr;
498 match->host_devfn = assigned_dev->devfn; 498 match->host_devfn = assigned_dev->devfn;
499 match->flags = assigned_dev->flags;
499 match->dev = dev; 500 match->dev = dev;
500 match->irq_source_id = -1; 501 match->irq_source_id = -1;
501 match->kvm = kvm; 502 match->kvm = kvm;
@@ -503,7 +504,12 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm,
503 list_add(&match->list, &kvm->arch.assigned_dev_head); 504 list_add(&match->list, &kvm->arch.assigned_dev_head);
504 505
505 if (assigned_dev->flags & KVM_DEV_ASSIGN_ENABLE_IOMMU) { 506 if (assigned_dev->flags & KVM_DEV_ASSIGN_ENABLE_IOMMU) {
506 r = kvm_iommu_map_guest(kvm, match); 507 if (!kvm->arch.iommu_domain) {
508 r = kvm_iommu_map_guest(kvm);
509 if (r)
510 goto out_list_del;
511 }
512 r = kvm_assign_device(kvm, match);
507 if (r) 513 if (r)
508 goto out_list_del; 514 goto out_list_del;
509 } 515 }
@@ -525,6 +531,35 @@ out_free:
525} 531}
526#endif 532#endif
527 533
534#ifdef KVM_CAP_DEVICE_DEASSIGNMENT
535static int kvm_vm_ioctl_deassign_device(struct kvm *kvm,
536 struct kvm_assigned_pci_dev *assigned_dev)
537{
538 int r = 0;
539 struct kvm_assigned_dev_kernel *match;
540
541 mutex_lock(&kvm->lock);
542
543 match = kvm_find_assigned_dev(&kvm->arch.assigned_dev_head,
544 assigned_dev->assigned_dev_id);
545 if (!match) {
546 printk(KERN_INFO "%s: device hasn't been assigned before, "
547 "so cannot be deassigned\n", __func__);
548 r = -EINVAL;
549 goto out;
550 }
551
552 if (assigned_dev->flags & KVM_DEV_ASSIGN_ENABLE_IOMMU)
553 kvm_deassign_device(kvm, match);
554
555 kvm_free_assigned_device(kvm, match);
556
557out:
558 mutex_unlock(&kvm->lock);
559 return r;
560}
561#endif
562
528static inline int valid_vcpu(int n) 563static inline int valid_vcpu(int n)
529{ 564{
530 return likely(n >= 0 && n < KVM_MAX_VCPUS); 565 return likely(n >= 0 && n < KVM_MAX_VCPUS);
@@ -1858,6 +1893,19 @@ static long kvm_vm_ioctl(struct file *filp,
1858 break; 1893 break;
1859 } 1894 }
1860#endif 1895#endif
1896#ifdef KVM_CAP_DEVICE_DEASSIGNMENT
1897 case KVM_DEASSIGN_PCI_DEVICE: {
1898 struct kvm_assigned_pci_dev assigned_dev;
1899
1900 r = -EFAULT;
1901 if (copy_from_user(&assigned_dev, argp, sizeof assigned_dev))
1902 goto out;
1903 r = kvm_vm_ioctl_deassign_device(kvm, &assigned_dev);
1904 if (r)
1905 goto out;
1906 break;
1907 }
1908#endif
1861 default: 1909 default:
1862 r = kvm_arch_vm_ioctl(filp, ioctl, arg); 1910 r = kvm_arch_vm_ioctl(filp, ioctl, arg);
1863 } 1911 }