Index: sys/dev/iommu/iommu.h =================================================================== --- sys/dev/iommu/iommu.h +++ sys/dev/iommu/iommu.h @@ -100,6 +100,13 @@ uint32_t buswide_ctxs[(PCI_BUSMAX + 1) / NBBY / sizeof(uint32_t)]; }; +struct iommu_domain_map_ops { + int (*map)(struct iommu_domain *domain, iommu_gaddr_t base, + iommu_gaddr_t size, vm_page_t *ma, uint64_t pflags, int flags); + int (*unmap)(struct iommu_domain *domain, iommu_gaddr_t base, + iommu_gaddr_t size, int flags); +}; + /* * Locking annotations: * (u) - Protected by iommu unit lock @@ -109,6 +116,7 @@ struct iommu_domain { struct iommu_unit *iommu; /* (c) */ + struct iommu_domain_map_ops ops; struct mtx lock; /* (c) */ struct task unload_task; /* (c) */ u_int entries_cnt; /* (d) */ Index: sys/dev/iommu/iommu_gas.c =================================================================== --- sys/dev/iommu/iommu_gas.c +++ sys/dev/iommu/iommu_gas.c @@ -66,10 +66,7 @@ #include #include #if defined(__amd64__) || defined(__i386__) -#include -#include #include -#include #endif #include @@ -620,7 +617,7 @@ entry->flags |= eflags; IOMMU_DOMAIN_UNLOCK(domain); - error = domain_map_buf(domain, entry->start, entry->end - entry->start, + error = domain->ops.map(domain, entry->start, entry->end - entry->start, ma, eflags, ((flags & IOMMU_MF_CANWAIT) != 0 ? IOMMU_PGF_WAITOK : 0)); if (error == ENOMEM) { @@ -658,7 +655,7 @@ if (entry->end == entry->start) return (0); - error = domain_map_buf(domain, entry->start, entry->end - entry->start, + error = domain->ops.map(domain, entry->start, entry->end - entry->start, ma + OFF_TO_IDX(start - entry->start), eflags, ((flags & IOMMU_MF_CANWAIT) != 0 ? IOMMU_PGF_WAITOK : 0)); if (error == ENOMEM) { Index: sys/x86/iommu/intel_ctx.c =================================================================== --- sys/x86/iommu/intel_ctx.c +++ sys/x86/iommu/intel_ctx.c @@ -342,6 +342,9 @@ domain->dmar = dmar; domain->iodom.iommu = &dmar->iommu; + iodom->ops.map = domain_map_buf; + iodom->ops.unmap = domain_unmap_buf; + /* * For now, use the maximal usable physical address of the * installed memory to calculate the mgaw on id_mapped domain. @@ -842,15 +845,17 @@ struct iommu_map_entries_tailq *entries, bool cansleep) { struct dmar_unit *unit; + struct iommu_domain *iodom; struct iommu_map_entry *entry, *entry1; int error; + iodom = (struct iommu_domain *)domain; unit = (struct dmar_unit *)domain->iodom.iommu; TAILQ_FOREACH_SAFE(entry, entries, dmamap_link, entry1) { KASSERT((entry->flags & IOMMU_MAP_ENTRY_MAP) != 0, ("not mapped entry %p %p", domain, entry)); - error = domain_unmap_buf(domain, entry->start, entry->end - + error = iodom->ops.unmap(iodom, entry->start, entry->end - entry->start, cansleep ? IOMMU_PGF_WAITOK : 0); KASSERT(error == 0, ("unmap %p error %d", domain, error)); if (!unit->qi_enabled) { Index: sys/x86/iommu/intel_dmar.h =================================================================== --- sys/x86/iommu/intel_dmar.h +++ sys/x86/iommu/intel_dmar.h @@ -246,7 +246,7 @@ void put_idmap_pgtbl(vm_object_t obj); int domain_map_buf(struct iommu_domain *domain, iommu_gaddr_t base, iommu_gaddr_t size, vm_page_t *ma, uint64_t pflags, int flags); -int domain_unmap_buf(struct dmar_domain *domain, iommu_gaddr_t base, +int domain_unmap_buf(struct iommu_domain *domain, iommu_gaddr_t base, iommu_gaddr_t size, int flags); void domain_flush_iotlb_sync(struct dmar_domain *domain, iommu_gaddr_t base, iommu_gaddr_t size); Index: sys/x86/iommu/intel_idpgtbl.c =================================================================== --- sys/x86/iommu/intel_idpgtbl.c +++ sys/x86/iommu/intel_idpgtbl.c @@ -685,11 +685,14 @@ } int -domain_unmap_buf(struct dmar_domain *domain, iommu_gaddr_t base, +domain_unmap_buf(struct iommu_domain *iodom, iommu_gaddr_t base, iommu_gaddr_t size, int flags) { + struct dmar_domain *domain; int error; + domain = (struct dmar_domain *)iodom; + DMAR_DOMAIN_PGLOCK(domain); error = domain_unmap_buf_locked(domain, base, size, flags); DMAR_DOMAIN_PGUNLOCK(domain);