Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 125583
b: refs/heads/master
c: 0a92035
h: refs/heads/master
i:
  125581: e41efb6
  125579: 329adfb
  125575: 95bfc52
  125567: 01a407c
v: v3
  • Loading branch information
Weidong Han authored and Joerg Roedel committed Jan 3, 2009
1 parent bd5f460 commit 396b6d7
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 260782bcfdaaa7850f29d6bb2ec6603019168c57
refs/heads/master: 0a920356748df4fb06e86c21c23d2ed6d31d37ad
8 changes: 8 additions & 0 deletions trunk/include/linux/kvm_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,8 @@ int kvm_iommu_map_guest(struct kvm *kvm);
int kvm_iommu_unmap_guest(struct kvm *kvm);
int kvm_assign_device(struct kvm *kvm,
struct kvm_assigned_dev_kernel *assigned_dev);
int kvm_deassign_device(struct kvm *kvm,
struct kvm_assigned_dev_kernel *assigned_dev);
#else /* CONFIG_DMAR */
static inline int kvm_iommu_map_pages(struct kvm *kvm,
gfn_t base_gfn,
Expand All @@ -357,6 +359,12 @@ static inline int kvm_assign_device(struct kvm *kvm,
{
return 0;
}

static inline int kvm_deassign_device(struct kvm *kvm,
struct kvm_assigned_dev_kernel *assigned_dev)
{
return 0;
}
#endif /* CONFIG_DMAR */

static inline void kvm_guest_enter(void)
Expand Down
42 changes: 42 additions & 0 deletions trunk/virt/kvm/kvm_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,35 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm,
}
#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);
Expand Down Expand Up @@ -1862,6 +1891,19 @@ static long kvm_vm_ioctl(struct file *filp,
goto out;
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);
Expand Down
24 changes: 24 additions & 0 deletions trunk/virt/kvm/vtd.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,30 @@ int kvm_assign_device(struct kvm *kvm,
return 0;
}

int kvm_deassign_device(struct kvm *kvm,
struct kvm_assigned_dev_kernel *assigned_dev)
{
struct dmar_domain *domain = kvm->arch.intel_iommu_domain;
struct pci_dev *pdev = NULL;

/* check if iommu exists and in use */
if (!domain)
return 0;

pdev = assigned_dev->dev;
if (pdev == NULL)
return -ENODEV;

intel_iommu_detach_device(domain, pdev);

printk(KERN_DEBUG "deassign device: host bdf = %x:%x:%x\n",
assigned_dev->host_busnr,
PCI_SLOT(assigned_dev->host_devfn),
PCI_FUNC(assigned_dev->host_devfn));

return 0;
}

int kvm_iommu_map_guest(struct kvm *kvm)
{
int r;
Expand Down

0 comments on commit 396b6d7

Please sign in to comment.