| 169 | } |
| 170 | |
| 171 | static void |
| 172 | ctx_id_entry_init(struct dmar_ctx *ctx, dmar_ctx_entry_t *ctxp, bool move, |
| 173 | int busno) |
| 174 | { |
| 175 | struct dmar_unit *unit; |
| 176 | struct dmar_domain *domain; |
| 177 | vm_page_t ctx_root; |
| 178 | int i; |
| 179 | |
| 180 | domain = CTX2DOM(ctx); |
| 181 | unit = DOM2DMAR(domain); |
| 182 | KASSERT(move || (ctxp->ctx1 == 0 && ctxp->ctx2 == 0), |
| 183 | ("dmar%d: initialized ctx entry %d:%d:%d 0x%jx 0x%jx", |
| 184 | unit->iommu.unit, busno, pci_get_slot(ctx->context.tag->owner), |
| 185 | pci_get_function(ctx->context.tag->owner), |
| 186 | ctxp->ctx1, ctxp->ctx2)); |
| 187 | |
| 188 | if ((domain->iodom.flags & IOMMU_DOMAIN_IDMAP) != 0 && |
| 189 | (unit->hw_ecap & DMAR_ECAP_PT) != 0) { |
| 190 | KASSERT(domain->pgtbl_obj == NULL, |
| 191 | ("ctx %p non-null pgtbl_obj", ctx)); |
| 192 | ctx_root = NULL; |
| 193 | } else { |
| 194 | ctx_root = dmar_pgalloc(domain->pgtbl_obj, 0, |
| 195 | IOMMU_PGF_NOALLOC); |
| 196 | } |
| 197 | |
| 198 | if (iommu_is_buswide_ctx(DMAR2IOMMU(unit), busno)) { |
| 199 | MPASS(!move); |
| 200 | for (i = 0; i <= PCI_BUSMAX; i++) { |
| 201 | ctx_id_entry_init_one(&ctxp[i], domain, ctx_root); |
| 202 | } |
| 203 | } else { |
| 204 | ctx_id_entry_init_one(ctxp, domain, ctx_root); |
| 205 | } |
| 206 | dmar_flush_ctx_to_ram(unit, ctxp); |
| 207 | } |
| 208 | |
| 209 | static int |
| 210 | dmar_flush_for_ctx_entry(struct dmar_unit *dmar, bool force) |
no test coverage detected