Index: sys/dev/iommu/busdma_iommu.c =================================================================== --- sys/dev/iommu/busdma_iommu.c +++ sys/dev/iommu/busdma_iommu.c @@ -1068,3 +1068,19 @@ free(ma, M_TEMP); return (error); } + +void +iommu_domain_init(struct iommu_domain *domain) +{ + + RB_INIT(&domain->rb_root); + TAILQ_INIT(&domain->unload_entries); + mtx_init(&domain->lock, "iodom", NULL, MTX_DEF); +} + +void +iommu_domain_fini(struct iommu_domain *domain) +{ + + mtx_destroy(&domain->lock); +} Index: sys/dev/iommu/iommu.h =================================================================== --- sys/dev/iommu/iommu.h +++ sys/dev/iommu/iommu.h @@ -223,6 +223,8 @@ void iommu_set_buswide_ctx(struct iommu_unit *unit, u_int busno); bool iommu_is_buswide_ctx(struct iommu_unit *unit, u_int busno); +void iommu_domain_init(struct iommu_domain *domain); +void iommu_domain_fini(struct iommu_domain *domain); bool bus_dma_iommu_set_buswide(device_t dev); int bus_dma_iommu_load_ident(bus_dma_tag_t dmat, bus_dmamap_t map, Index: sys/x86/iommu/intel_ctx.c =================================================================== --- sys/x86/iommu/intel_ctx.c +++ sys/x86/iommu/intel_ctx.c @@ -332,11 +332,10 @@ iodom = DOM2IODOM(domain); domain->domain = id; LIST_INIT(&domain->contexts); - RB_INIT(&domain->iodom.rb_root); - TAILQ_INIT(&domain->iodom.unload_entries); TASK_INIT(&domain->iodom.unload_task, 0, dmar_domain_unload_task, domain); - mtx_init(&domain->iodom.lock, "dmardom", NULL, MTX_DEF); + iommu_domain_init(iodom); + domain->dmar = dmar; domain->iodom.iommu = &dmar->iommu; domain_pgtbl_init(domain); @@ -430,8 +429,11 @@ static void dmar_domain_destroy(struct dmar_domain *domain) { + struct iommu_domain *iodom; struct dmar_unit *dmar; + iodom = DOM2IODOM(domain); + KASSERT(TAILQ_EMPTY(&domain->iodom.unload_entries), ("unfinished unloads %p", domain)); KASSERT(LIST_EMPTY(&domain->contexts), @@ -442,7 +444,7 @@ ("destroying dom %p with refs %d", domain, domain->refs)); if ((domain->iodom.flags & IOMMU_DOMAIN_GAS_INITED) != 0) { DMAR_DOMAIN_LOCK(domain); - iommu_gas_fini_domain(DOM2IODOM(domain)); + iommu_gas_fini_domain(iodom); DMAR_DOMAIN_UNLOCK(domain); } if ((domain->iodom.flags & IOMMU_DOMAIN_PGTBL_INITED) != 0) { @@ -450,7 +452,7 @@ DMAR_DOMAIN_PGLOCK(domain); domain_free_pgtbl(domain); } - mtx_destroy(&domain->iodom.lock); + iommu_domain_fini(iodom); dmar = DOM2DMAR(domain); free_unr(dmar->domids, domain->domain); free(domain, M_DMAR_DOMAIN);