diff options
Diffstat (limited to 'sys/x86/iommu/intel_drv.c')
-rw-r--r-- | sys/x86/iommu/intel_drv.c | 111 |
1 files changed, 69 insertions, 42 deletions
diff --git a/sys/x86/iommu/intel_drv.c b/sys/x86/iommu/intel_drv.c index c239579..47588af 100644 --- a/sys/x86/iommu/intel_drv.c +++ b/sys/x86/iommu/intel_drv.c @@ -459,6 +459,7 @@ dmar_attach(device_t dev) mtx_init(&unit->lock, "dmarhw", NULL, MTX_DEF); unit->domids = new_unrhdr(0, dmar_nd2mask(DMAR_CAP_ND(unit->hw_cap)), &unit->lock); + LIST_INIT(&unit->domains); /* * 9.2 "Context Entry": @@ -842,7 +843,7 @@ dmar_find_ioapic(u_int apic_id, uint16_t *rid) } struct rmrr_iter_args { - struct dmar_ctx *ctx; + struct dmar_domain *domain; device_t dev; int dev_domain; int dev_busno; @@ -887,7 +888,8 @@ dmar_rmrr_iter(ACPI_DMAR_HEADER *dmarh, void *arg) if (match == 1) { if (dmar_match_verbose) printf("matched\n"); - entry = dmar_gas_alloc_entry(ria->ctx, DMAR_PGF_WAITOK); + entry = dmar_gas_alloc_entry(ria->domain, + DMAR_PGF_WAITOK); entry->start = resmem->BaseAddress; /* The RMRR entry end address is inclusive. */ entry->end = resmem->EndAddress; @@ -902,7 +904,7 @@ dmar_rmrr_iter(ACPI_DMAR_HEADER *dmarh, void *arg) } void -dmar_ctx_parse_rmrr(struct dmar_ctx *ctx, device_t dev, +dmar_dev_parse_rmrr(struct dmar_domain *domain, device_t dev, struct dmar_map_entries_tailq *rmrr_entries) { struct rmrr_iter_args ria; @@ -918,7 +920,7 @@ dmar_ctx_parse_rmrr(struct dmar_ctx *ctx, device_t dev, dev_path); } - ria.ctx = ctx; + ria.domain = domain; ria.dev = dev; ria.dev_path = dev_path; ria.rmrr_entries = rmrr_entries; @@ -1038,7 +1040,7 @@ dmar_instantiate_rmrr_ctxs(struct dmar_unit *dmar) printf("dmar%d: instantiating RMRR contexts\n", dmar->unit); dmar_iterate_tbl(dmar_inst_rmrr_iter, &iria); DMAR_LOCK(dmar); - if (!LIST_EMPTY(&dmar->contexts)) { + if (!LIST_EMPTY(&dmar->domains)) { KASSERT((dmar->hw_gcmd & DMAR_GCMD_TE) == 0, ("dmar%d: RMRR not handled but translation is already enabled", dmar->unit)); @@ -1053,7 +1055,7 @@ dmar_instantiate_rmrr_ctxs(struct dmar_unit *dmar) #include <ddb/db_lex.h> static void -dmar_print_ctx_entry(const struct dmar_map_entry *entry) +dmar_print_domain_entry(const struct dmar_map_entry *entry) { struct dmar_map_entry *l, *r; @@ -1077,43 +1079,59 @@ dmar_print_ctx_entry(const struct dmar_map_entry *entry) } static void -dmar_print_ctx(struct dmar_ctx *ctx, bool show_mappings) +dmar_print_ctx(struct dmar_ctx *ctx) { - struct dmar_map_entry *entry; db_printf( - " @%p pci%d:%d:%d dom %d mgaw %d agaw %d pglvl %d end %jx\n" - " refs %d flags %x pgobj %p map_ents %u loads %lu unloads %lu\n", + " @%p pci%d:%d:%d refs %d flags %x loads %lu unloads %lu\n", ctx, pci_get_bus(ctx->ctx_tag.owner), pci_get_slot(ctx->ctx_tag.owner), - pci_get_function(ctx->ctx_tag.owner), ctx->domain, ctx->mgaw, - ctx->agaw, ctx->pglvl, (uintmax_t)ctx->end, ctx->refs, - ctx->flags, ctx->pgtbl_obj, ctx->entries_cnt, ctx->loads, - ctx->unloads); + pci_get_function(ctx->ctx_tag.owner), ctx->refs, ctx->flags, + ctx->loads, ctx->unloads); +} + +static void +dmar_print_domain(struct dmar_domain *domain, bool show_mappings) +{ + struct dmar_map_entry *entry; + struct dmar_ctx *ctx; + + db_printf( + " @%p dom %d mgaw %d agaw %d pglvl %d end %jx refs %d\n" + " ctx_cnt %d flags %x pgobj %p map_ents %u\n", + domain, domain->domain, domain->mgaw, domain->agaw, domain->pglvl, + (uintmax_t)domain->end, domain->refs, domain->ctx_cnt, + domain->flags, domain->pgtbl_obj, domain->entries_cnt); + if (!LIST_EMPTY(&domain->contexts)) { + db_printf(" Contexts:\n"); + LIST_FOREACH(ctx, &domain->contexts, link) + dmar_print_ctx(ctx); + } if (!show_mappings) return; db_printf(" mapped:\n"); - RB_FOREACH(entry, dmar_gas_entries_tree, &ctx->rb_root) { - dmar_print_ctx_entry(entry); + RB_FOREACH(entry, dmar_gas_entries_tree, &domain->rb_root) { + dmar_print_domain_entry(entry); if (db_pager_quit) break; } if (db_pager_quit) return; db_printf(" unloading:\n"); - TAILQ_FOREACH(entry, &ctx->unload_entries, dmamap_link) { - dmar_print_ctx_entry(entry); + TAILQ_FOREACH(entry, &domain->unload_entries, dmamap_link) { + dmar_print_domain_entry(entry); if (db_pager_quit) break; } } -DB_FUNC(dmar_ctx, db_dmar_print_ctx, db_show_table, CS_OWN, NULL) +DB_FUNC(dmar_domain, db_dmar_print_domain, db_show_table, CS_OWN, NULL) { struct dmar_unit *unit; + struct dmar_domain *domain; struct dmar_ctx *ctx; bool show_mappings, valid; - int domain, bus, device, function, i, t; + int pci_domain, bus, device, function, i, t; db_expr_t radix; valid = false; @@ -1134,7 +1152,7 @@ DB_FUNC(dmar_ctx, db_dmar_print_ctx, db_show_table, CS_OWN, NULL) show_mappings = false; } if (t == tNUMBER) { - domain = db_tok_number; + pci_domain = db_tok_number; t = db_read_token(); if (t == tNUMBER) { bus = db_tok_number; @@ -1152,19 +1170,24 @@ DB_FUNC(dmar_ctx, db_dmar_print_ctx, db_show_table, CS_OWN, NULL) db_radix = radix; db_skip_to_eol(); if (!valid) { - db_printf("usage: show dmar_ctx [/m] " + db_printf("usage: show dmar_domain [/m] " "<domain> <bus> <device> <func>\n"); return; } for (i = 0; i < dmar_devcnt; i++) { unit = device_get_softc(dmar_devs[i]); - LIST_FOREACH(ctx, &unit->contexts, link) { - if (domain == unit->segment && - bus == pci_get_bus(ctx->ctx_tag.owner) && - device == pci_get_slot(ctx->ctx_tag.owner) && - function == pci_get_function(ctx->ctx_tag.owner)) { - dmar_print_ctx(ctx, show_mappings); - goto out; + LIST_FOREACH(domain, &unit->domains, link) { + LIST_FOREACH(ctx, &domain->contexts, link) { + if (pci_domain == unit->segment && + bus == pci_get_bus(ctx->ctx_tag.owner) && + device == + pci_get_slot(ctx->ctx_tag.owner) && + function == + pci_get_function(ctx->ctx_tag.owner)) { + dmar_print_domain(domain, + show_mappings); + goto out; + } } } } @@ -1172,10 +1195,10 @@ out:; } static void -dmar_print_one(int idx, bool show_ctxs, bool show_mappings) +dmar_print_one(int idx, bool show_domains, bool show_mappings) { struct dmar_unit *unit; - struct dmar_ctx *ctx; + struct dmar_domain *domain; int i, frir; unit = device_get_softc(dmar_devs[idx]); @@ -1187,6 +1210,10 @@ dmar_print_one(int idx, bool show_ctxs, bool show_mappings) dmar_read4(unit, DMAR_GSTS_REG), dmar_read4(unit, DMAR_FSTS_REG), dmar_read4(unit, DMAR_FECTL_REG)); + if (unit->ir_enabled) { + db_printf("ir is enabled; IRT @%p phys 0x%jx maxcnt %d\n", + unit->irt, (uintmax_t)unit->irt_phys, unit->irte_cnt); + } db_printf("fed 0x%x fea 0x%x feua 0x%x\n", dmar_read4(unit, DMAR_FEDATA_REG), dmar_read4(unit, DMAR_FEADDR_REG), @@ -1225,10 +1252,10 @@ dmar_print_one(int idx, bool show_ctxs, bool show_mappings) db_printf("qi is disabled\n"); } } - if (show_ctxs) { - db_printf("contexts:\n"); - LIST_FOREACH(ctx, &unit->contexts, link) { - dmar_print_ctx(ctx, show_mappings); + if (show_domains) { + db_printf("domains:\n"); + LIST_FOREACH(domain, &unit->domains, link) { + dmar_print_domain(domain, show_mappings); if (db_pager_quit) break; } @@ -1237,27 +1264,27 @@ dmar_print_one(int idx, bool show_ctxs, bool show_mappings) DB_SHOW_COMMAND(dmar, db_dmar_print) { - bool show_ctxs, show_mappings; + bool show_domains, show_mappings; - show_ctxs = strchr(modif, 'c') != NULL; + show_domains = strchr(modif, 'd') != NULL; show_mappings = strchr(modif, 'm') != NULL; if (!have_addr) { - db_printf("usage: show dmar [/c] [/m] index\n"); + db_printf("usage: show dmar [/d] [/m] index\n"); return; } - dmar_print_one((int)addr, show_ctxs, show_mappings); + dmar_print_one((int)addr, show_domains, show_mappings); } DB_SHOW_ALL_COMMAND(dmars, db_show_all_dmars) { int i; - bool show_ctxs, show_mappings; + bool show_domains, show_mappings; - show_ctxs = strchr(modif, 'c') != NULL; + show_domains = strchr(modif, 'd') != NULL; show_mappings = strchr(modif, 'm') != NULL; for (i = 0; i < dmar_devcnt; i++) { - dmar_print_one(i, show_ctxs, show_mappings); + dmar_print_one(i, show_domains, show_mappings); if (db_pager_quit) break; } |