Пример #1
0
int kvm_iommu_map_guest(struct kvm *kvm)
{
	int r;

	if (!iommu_found()) {
		printk(KERN_ERR "%s: iommu not found\n", __func__);
		return -ENODEV;
	}

	kvm->arch.iommu_domain = iommu_domain_alloc();
	if (!kvm->arch.iommu_domain)
		return -ENOMEM;

	if (!allow_unsafe_assigned_interrupts &&
	    !iommu_domain_has_cap(kvm->arch.iommu_domain,
				  IOMMU_CAP_INTR_REMAP)) {
		printk(KERN_WARNING "%s: No interrupt remapping support, disallowing device assignment.  Re-enble with \"allow_unsafe_assigned_interrupts=1\" module option.\n", __func__);
		iommu_domain_free(kvm->arch.iommu_domain);
		kvm->arch.iommu_domain = NULL;
		return -EPERM;
	}

	r = kvm_iommu_map_memslots(kvm);
	if (r)
		goto out_unmap;

	return 0;

out_unmap:
	kvm_iommu_unmap_memslots(kvm);
	return r;
}
Пример #2
0
int kvm_assign_device(struct kvm *kvm,
                      struct kvm_assigned_dev_kernel *assigned_dev)
{
    struct pci_dev *pdev = NULL;
    struct iommu_domain *domain = kvm->arch.iommu_domain;
    int r, last_flags;

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

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

    r = iommu_attach_device(domain, &pdev->dev);
    if (r) {
        printk(KERN_ERR "assign device %x:%x:%x.%x failed",
               pci_domain_nr(pdev->bus),
               pdev->bus->number,
               PCI_SLOT(pdev->devfn),
               PCI_FUNC(pdev->devfn));
        return r;
    }

    last_flags = kvm->arch.iommu_flags;
    if (iommu_domain_has_cap(kvm->arch.iommu_domain,
                             IOMMU_CAP_CACHE_COHERENCY))
        kvm->arch.iommu_flags |= KVM_IOMMU_CACHE_COHERENCY;

    /* Check if need to update IOMMU page table for guest memory */
    if ((last_flags ^ kvm->arch.iommu_flags) ==
            KVM_IOMMU_CACHE_COHERENCY) {
        kvm_iommu_unmap_memslots(kvm);
        r = kvm_iommu_map_memslots(kvm);
        if (r)
            goto out_unmap;
    }

    printk(KERN_DEBUG "assign device %x:%x:%x.%x\n",
           assigned_dev->host_segnr,
           assigned_dev->host_busnr,
           PCI_SLOT(assigned_dev->host_devfn),
           PCI_FUNC(assigned_dev->host_devfn));

    return 0;
out_unmap:
    kvm_iommu_unmap_memslots(kvm);
    return r;
}
Пример #3
0
int kvm_iommu_map_guest(struct kvm *kvm)
{
    int r;

    if (!iommu_found()) {
        printk(KERN_ERR "%s: iommu not found\n", __func__);
        return -ENODEV;
    }

    kvm->arch.iommu_domain = iommu_domain_alloc();
    if (!kvm->arch.iommu_domain)
        return -ENOMEM;

    r = kvm_iommu_map_memslots(kvm);
    if (r)
        goto out_unmap;

    return 0;

out_unmap:
    kvm_iommu_unmap_memslots(kvm);
    return r;
}