Ejemplo n.º 1
0
void
iommu_init(void)
{
	int error, bus, slot, func;
	vm_paddr_t maxaddr;
	const char *name;
	device_t dev;

	if (vmm_is_intel())
		ops = &iommu_ops_intel;
	else if (vmm_is_amd())
		ops = &iommu_ops_amd;
	else
		ops = NULL;

	error = IOMMU_INIT();
	if (error)
		return;

	iommu_avail = 1;

	/*
	 * Create a domain for the devices owned by the host
	 */
	maxaddr = vmm_mem_maxaddr();
	host_domain = IOMMU_CREATE_DOMAIN(maxaddr);
	if (host_domain == NULL)
		panic("iommu_init: unable to create a host domain");

	/*
	 * Create 1:1 mappings from '0' to 'maxaddr' for devices assigned to
	 * the host
	 */
	iommu_create_mapping(host_domain, 0, 0, maxaddr);

	for (bus = 0; bus <= PCI_BUSMAX; bus++) {
		for (slot = 0; slot <= PCI_SLOTMAX; slot++) {
			for (func = 0; func <= PCI_FUNCMAX; func++) {
				dev = pci_find_dbsf(0, bus, slot, func);
				if (dev == NULL)
					continue;

				/* skip passthrough devices */
				name = device_get_name(dev);
				if (name != NULL && strcmp(name, "ppt") == 0)
					continue;

				/* everything else belongs to the host domain */
				iommu_add_device(host_domain, bus, slot, func);
			}
		}
	}
	IOMMU_ENABLE();

}
Ejemplo n.º 2
0
static void pnv_pci_p5ioc2_dma_dev_setup(struct pnv_phb *phb,
					 struct pci_dev *pdev)
{
	struct iommu_table *tbl = phb->p5ioc2.table_group.tables[0];

	if (!tbl->it_map) {
		tbl->it_ops = &pnv_p5ioc2_iommu_ops;
		iommu_init_table(tbl, phb->hose->node);
		iommu_register_group(&phb->p5ioc2.table_group,
				pci_domain_nr(phb->hose->bus), phb->opal_id);
		INIT_LIST_HEAD_RCU(&tbl->it_group_list);
		pnv_pci_link_table_and_group(phb->hose->node, 0,
				tbl, &phb->p5ioc2.table_group);
	}

	set_iommu_table_base(&pdev->dev, tbl);
	iommu_add_device(&pdev->dev);
}
Ejemplo n.º 3
0
int
ppt_assign_device(struct vm *vm, int bus, int slot, int func)
{
	struct pptdev *ppt;

	ppt = ppt_find(bus, slot, func);
	if (ppt != NULL) {
		/*
		 * If this device is owned by a different VM then we
		 * cannot change its owner.
		 */
		if (ppt->vm != NULL && ppt->vm != vm)
			return (EBUSY);

		ppt->vm = vm;
		iommu_add_device(vm_iommu_domain(vm), bus, slot, func);
		return (0);
	}
	return (ENOENT);
}