int iommu_attach_device(struct iommu_domain *domain, struct device *dev)
{
	if (!iommu_found())
		return -ENODEV;

	return iommu_ops->attach_dev(domain, dev);
}
void iommu_detach_device(struct iommu_domain *domain, struct device *dev)
{
	if (!iommu_found())
		return;

	iommu_ops->detach_dev(domain, dev);
}
phys_addr_t iommu_get_pt_base_addr(struct iommu_domain *domain)
{
	if (!iommu_found())
		return 0;

	return iommu_ops->get_pt_base_addr(domain);
}
Пример #4
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;
}
void iommu_domain_free(struct iommu_domain *domain)
{
	if (!iommu_found())
		return;

	iommu_ops->domain_destroy(domain);
	kfree(domain);
}
int iommu_domain_has_cap(struct iommu_domain *domain,
			 unsigned long cap)
{
	if (!iommu_found())
		return -ENODEV;

	return iommu_ops->domain_has_cap(domain, cap);
}
phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain,
			       unsigned long iova)
{
	if (!iommu_found())
		return 0;

	return iommu_ops->iova_to_phys(domain, iova);
}
int iommu_unmap_range(struct iommu_domain *domain, unsigned int iova,
		      unsigned int len)
{
	if (!iommu_found())
		return -ENODEV;

	BUG_ON(iova & (~PAGE_MASK));

	return iommu_ops->unmap_range(domain, iova, len);
}
int iommu_map_range(struct iommu_domain *domain, unsigned int iova,
		    struct scatterlist *sg, unsigned int len, int prot)
{
	if (!iommu_found())
		return -ENODEV;

	BUG_ON(iova & (~PAGE_MASK));

	return iommu_ops->map_range(domain, iova, sg, len, prot);
}
int iommu_unmap(struct iommu_domain *domain, unsigned long iova, int gfp_order)
{
	unsigned long invalid_mask;
	size_t size;

	if (!iommu_found())
		return -ENODEV;

	size         = 0x1000UL << gfp_order;
	invalid_mask = size - 1;

	BUG_ON(iova & invalid_mask);

	return iommu_ops->unmap(domain, iova, gfp_order);
}
int iommu_map(struct iommu_domain *domain, unsigned long iova,
	      phys_addr_t paddr, int gfp_order, int prot)
{
	unsigned long invalid_mask;
	size_t size;

	if (!iommu_found())
		return -ENODEV;

	size         = 0x1000UL << gfp_order;
	invalid_mask = size - 1;

	BUG_ON((iova | paddr) & invalid_mask);

	return iommu_ops->map(domain, iova, paddr, gfp_order, prot);
}
Пример #12
0
int kvm_dev_ioctl_check_extension(long ext)
{

	int r;

	switch (ext) {
	case KVM_CAP_IRQCHIP:
	case KVM_CAP_MP_STATE:
	case KVM_CAP_IRQ_INJECT_STATUS:
		r = 1;
		break;
	case KVM_CAP_COALESCED_MMIO:
		r = KVM_COALESCED_MMIO_PAGE_OFFSET;
		break;
	case KVM_CAP_IOMMU:
		r = iommu_found();
		break;
	default:
		r = 0;
	}
	return r;

}
struct iommu_domain *iommu_domain_alloc(int flags)
{
	struct iommu_domain *domain;
	int ret;

	if (!iommu_found())
		return NULL;

	domain = kzalloc(sizeof(*domain), GFP_KERNEL);
	if (!domain)
		return NULL;

	ret = iommu_ops->domain_init(domain, flags);
	if (ret)
		goto out_free;

	return domain;

out_free:
	kfree(domain);

	return NULL;
}
Пример #14
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;
}
Пример #15
0
/**
 * Initialize module.
 *
 * @returns appropriate status code.
 */
static int __init VBoxPciLinuxInit(void)
{
    int rc;
    /*
     * Initialize IPRT.
     */
    rc = RTR0Init(0);

    if (RT_FAILURE(rc))
        goto error;


    LogRel(("VBoxPciLinuxInit\n"));

    RT_ZERO(g_VBoxPciGlobals);

    rc = vboxPciInit(&g_VBoxPciGlobals);
    if (RT_FAILURE(rc))
    {
        LogRel(("cannot do VBoxPciInit: %Rc\n", rc));
        goto error;
    }

#if defined(CONFIG_PCI_STUB)
    /* nothing to do, pci_stub module part of the kernel */
    g_VBoxPciGlobals.fPciStubModuleAvail = true;

#elif defined(CONFIG_PCI_STUB_MODULE)
    if (request_module(PCI_STUB_MODULE) == 0)
    {
# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
        /* find_module() is static before Linux 2.6.30 */
        g_VBoxPciGlobals.pciStubModule = find_module(PCI_STUB_MODULE_NAME);
        if (g_VBoxPciGlobals.pciStubModule)
        {
            if (try_module_get(g_VBoxPciGlobals.pciStubModule))
                g_VBoxPciGlobals.fPciStubModuleAvail = true;
        }
        else
            printk(KERN_INFO "vboxpci: find_module %s failed\n", PCI_STUB_MODULE);
# endif
    }
    else
        printk(KERN_INFO "vboxpci: cannot load %s\n", PCI_STUB_MODULE);

#else
    printk(KERN_INFO "vboxpci: %s module not available, cannot detach PCI devices\n",
                      PCI_STUB_MODULE);
#endif

#ifdef VBOX_WITH_IOMMU
    if (iommu_found())
        printk(KERN_INFO "vboxpci: IOMMU found\n");
    else
        printk(KERN_INFO "vboxpci: IOMMU not found (not registered)\n");
#else
    printk(KERN_INFO "vboxpci: IOMMU not found (not compiled)\n");
#endif

    return 0;

  error:
    return -RTErrConvertToErrno(rc);
}