From nobody Sun Oct 13 22:30:52 2024 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4XRZnn2Wrdz5YfyQ; Sun, 13 Oct 2024 22:30:53 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4XRZnm658Sz4qJ0; Sun, 13 Oct 2024 22:30:52 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1728858652; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=+vnpeegZv3A0xrf9Gboc1B14mW3A3VcX/85Qsx8XNeg=; b=kmXA+vv2/ZT7XsuvxP0+1/c4GaZ4aWxmBI4dn/qVOiuu2T9lWiFs0nHeSac4a7lrbaLmpb vrinXmOMpG1bQEVkbx7VDS2H3sekFHyEoeX8JyMsm9LSFLoHV7j1ikc/du8XhMoj3SYLKY D9a7dmAfCKdJ1+jdP+O1STOnEnZ7gSukHATL36GjKtCEmNlSLGYUyJNANeCFttyWK8cpc2 WeN5MueTgMOl4uxlIPE6YWA0VeRnZhSa7KY7ZbB3vHaiqqh+MvNg7fRVfz8j3U4ehWiYVO J2BiNuzQ60RwZwCel7ghksMqFPp9/YRxEUokvz45ACUhy+7AM0Si7gWgvnf4mA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1728858652; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=+vnpeegZv3A0xrf9Gboc1B14mW3A3VcX/85Qsx8XNeg=; b=pwdLq1X+EZM3sWBEag6cKQvrxmY5iL0lLOA+TX68DxFeHkHihyfNclpdxg7g5dlDKCE0NN ZOTUPWuy514AHPkNylYmhZBGNgi9fhmmvsB1QgoLG1KNw6NuCHjWh5qlkCptjcaCqHqd5m 3MYnEnNNW49NXjGrGbRigfHwtcb9lHdvcUtlDaahMmwAGMQSIGOLyYGszIY0glMhJzSkaB /Az3feiswi2Ybh6SzQ1ki1hdMrlIn8w/ndQOxGnwvbGdiLBi1TfcvP1mE2luVg0vEKOIRE xpuuwuPgGbgUR820zoN02hzmEBwyzOmB4cMo+LALU/+z7H0sFmxvH/XNh/S1dw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1728858652; a=rsa-sha256; cv=none; b=po/no+/q5Cxl46epLj+VR6o42Z2XPwlx46doTTqXuFQvuzjGPw3v9/+iwj27s6fVCu3wxE AQedcHKrlDjJQ9Ls+HTdogWulvp2qODX+WgIbjMUZkTRcZFqVX8OvsSip+q5vCQVT+Nd7u uJRYAC2yR17eZ0nSoMWzr1cuCBrJmsNuLoG9FpjeG6v0oi9INBnLIvIB05MTKe6Q2oQiOw gRkgh7cQKzWgiFhNWrJYTkC/yeH82HQThSCKbkgOZssA5HP4wvofi9JVLxTCTt+fSn/7Hk N61ZP6AIe2rVrn55ej/tdpZRtRblxMcUQw5ku0UyqOdneltW5M7dIf5FRMHOsg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4XRZnm5fj9z1BxB; Sun, 13 Oct 2024 22:30:52 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 49DMUqH6040174; Sun, 13 Oct 2024 22:30:52 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 49DMUqnC040171; Sun, 13 Oct 2024 22:30:52 GMT (envelope-from git) Date: Sun, 13 Oct 2024 22:30:52 GMT Message-Id: <202410132230.49DMUqnC040171@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Konstantin Belousov Subject: git: e9d948cfe0d2 - main - iommu: move context link and ref count into device-independent parts List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: e9d948cfe0d21780d2e94137e322ecfe89f75d6a Auto-Submitted: auto-generated The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=e9d948cfe0d21780d2e94137e322ecfe89f75d6a commit e9d948cfe0d21780d2e94137e322ecfe89f75d6a Author: Konstantin Belousov AuthorDate: 2024-10-12 19:56:14 +0000 Commit: Konstantin Belousov CommitDate: 2024-10-13 22:30:26 +0000 iommu: move context link and ref count into device-independent parts This also allows to move some bits of ddb print routines into iommu_utils.c common for x86 iommu drivers. Sponsored by: Advanced Micro Devices (AMD) Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/dev/iommu/iommu.h | 3 +++ sys/x86/iommu/intel_ctx.c | 38 ++++++++++++++-------------- sys/x86/iommu/intel_dmar.h | 3 --- sys/x86/iommu/intel_drv.c | 61 +++++++++------------------------------------ sys/x86/iommu/iommu_utils.c | 41 ++++++++++++++++++++++++++++++ sys/x86/iommu/x86_iommu.h | 3 +++ 6 files changed, 78 insertions(+), 71 deletions(-) diff --git a/sys/dev/iommu/iommu.h b/sys/dev/iommu/iommu.h index f425024117d3..b1858f0df9f7 100644 --- a/sys/dev/iommu/iommu.h +++ b/sys/dev/iommu/iommu.h @@ -121,11 +121,14 @@ struct iommu_domain { iommu_gaddr_t msi_base; /* (d) Arch-specific */ vm_paddr_t msi_phys; /* (d) Arch-specific */ u_int flags; /* (u) */ + LIST_HEAD(, iommu_ctx) contexts;/* (u) */ }; struct iommu_ctx { struct iommu_domain *domain; /* (c) */ struct bus_dma_tag_iommu *tag; /* (c) Root tag */ + LIST_ENTRY(iommu_ctx) link; /* (u) Member in the domain list */ + u_int refs; /* (u) References from tags */ u_long loads; /* atomic updates, for stat only */ u_long unloads; /* same */ u_int flags; /* (u) */ diff --git a/sys/x86/iommu/intel_ctx.c b/sys/x86/iommu/intel_ctx.c index 5af5ac7335b8..c2371d4d9c4f 100644 --- a/sys/x86/iommu/intel_ctx.c +++ b/sys/x86/iommu/intel_ctx.c @@ -375,7 +375,7 @@ dmar_domain_alloc(struct dmar_unit *dmar, bool id_mapped) iodom = DOM2IODOM(domain); unit = DMAR2IOMMU(dmar); domain->domain = id; - LIST_INIT(&domain->contexts); + LIST_INIT(&iodom->contexts); iommu_domain_init(unit, iodom, &dmar_domain_map_ops); domain->dmar = dmar; @@ -430,7 +430,7 @@ dmar_ctx_alloc(struct dmar_domain *domain, uint16_t rid) ctx->context.tag = malloc(sizeof(struct bus_dma_tag_iommu), M_DMAR_CTX, M_WAITOK | M_ZERO); ctx->context.rid = rid; - ctx->refs = 1; + ctx->context.refs = 1; return (ctx); } @@ -446,7 +446,7 @@ dmar_ctx_link(struct dmar_ctx *ctx) domain->ctx_cnt)); domain->refs++; domain->ctx_cnt++; - LIST_INSERT_HEAD(&domain->contexts, ctx, link); + LIST_INSERT_HEAD(&domain->iodom.contexts, &ctx->context, link); } static void @@ -463,7 +463,7 @@ dmar_ctx_unlink(struct dmar_ctx *ctx) domain->refs, domain->ctx_cnt)); domain->refs--; domain->ctx_cnt--; - LIST_REMOVE(ctx, link); + LIST_REMOVE(&ctx->context, link); } static void @@ -476,7 +476,7 @@ dmar_domain_destroy(struct dmar_domain *domain) KASSERT(TAILQ_EMPTY(&domain->iodom.unload_entries), ("unfinished unloads %p", domain)); - KASSERT(LIST_EMPTY(&domain->contexts), + KASSERT(LIST_EMPTY(&iodom->contexts), ("destroying dom %p with contexts", domain)); KASSERT(domain->ctx_cnt == 0, ("destroying dom %p with ctx_cnt %d", domain, domain->ctx_cnt)); @@ -593,13 +593,13 @@ dmar_get_ctx_for_dev1(struct dmar_unit *dmar, device_t dev, uint16_t rid, /* Nothing needs to be done to destroy ctx1. */ free(ctx1, M_DMAR_CTX); domain = CTX2DOM(ctx); - ctx->refs++; /* tag referenced us */ + ctx->context.refs++; /* tag referenced us */ } } else { domain = CTX2DOM(ctx); if (ctx->context.tag->owner == NULL) ctx->context.tag->owner = dev; - ctx->refs++; /* tag referenced us */ + ctx->context.refs++; /* tag referenced us */ } error = dmar_flush_for_ctx_entry(dmar, enable); @@ -737,15 +737,15 @@ dmar_free_ctx_locked(struct dmar_unit *dmar, struct dmar_ctx *ctx) struct dmar_domain *domain; DMAR_ASSERT_LOCKED(dmar); - KASSERT(ctx->refs >= 1, - ("dmar %p ctx %p refs %u", dmar, ctx, ctx->refs)); + KASSERT(ctx->context.refs >= 1, + ("dmar %p ctx %p refs %u", dmar, ctx, ctx->context.refs)); /* * If our reference is not last, only the dereference should * be performed. */ - if (ctx->refs > 1) { - ctx->refs--; + if (ctx->context.refs > 1) { + ctx->context.refs--; DMAR_UNLOCK(dmar); return; } @@ -762,15 +762,15 @@ dmar_free_ctx_locked(struct dmar_unit *dmar, struct dmar_ctx *ctx) TD_PREP_PINNED_ASSERT; ctxp = dmar_map_ctx_entry(ctx, &sf); DMAR_LOCK(dmar); - KASSERT(ctx->refs >= 1, - ("dmar %p ctx %p refs %u", dmar, ctx, ctx->refs)); + KASSERT(ctx->context.refs >= 1, + ("dmar %p ctx %p refs %u", dmar, ctx, ctx->context.refs)); /* * Other thread might have referenced the context, in which * case again only the dereference should be performed. */ - if (ctx->refs > 1) { - ctx->refs--; + if (ctx->context.refs > 1) { + ctx->context.refs--; DMAR_UNLOCK(dmar); iommu_unmap_pgtbl(sf); TD_PINNED_ASSERT; @@ -820,14 +820,14 @@ struct dmar_ctx * dmar_find_ctx_locked(struct dmar_unit *dmar, uint16_t rid) { struct dmar_domain *domain; - struct dmar_ctx *ctx; + struct iommu_ctx *ctx; DMAR_ASSERT_LOCKED(dmar); LIST_FOREACH(domain, &dmar->domains, link) { - LIST_FOREACH(ctx, &domain->contexts, link) { - if (ctx->context.rid == rid) - return (ctx); + LIST_FOREACH(ctx, &domain->iodom.contexts, link) { + if (ctx->rid == rid) + return (IOCTX2CTX(ctx)); } } return (NULL); diff --git a/sys/x86/iommu/intel_dmar.h b/sys/x86/iommu/intel_dmar.h index fcdc915abcfd..c3163abf6f92 100644 --- a/sys/x86/iommu/intel_dmar.h +++ b/sys/x86/iommu/intel_dmar.h @@ -65,7 +65,6 @@ struct dmar_domain { u_int refs; /* (u) Refs, including ctx */ struct dmar_unit *dmar; /* (c) */ LIST_ENTRY(dmar_domain) link; /* (u) Member in the dmar list */ - LIST_HEAD(, dmar_ctx) contexts; /* (u) */ vm_object_t pgtbl_obj; /* (c) Page table pages */ u_int batch_no; }; @@ -73,8 +72,6 @@ struct dmar_domain { struct dmar_ctx { struct iommu_ctx context; uint64_t last_fault_rec[2]; /* Last fault reported */ - LIST_ENTRY(dmar_ctx) link; /* (u) Member in the domain list */ - u_int refs; /* (u) References from tags */ }; #define DMAR_DOMAIN_PGLOCK(dom) VM_OBJECT_WLOCK((dom)->pgtbl_obj) diff --git a/sys/x86/iommu/intel_drv.c b/sys/x86/iommu/intel_drv.c index cc16759ebe34..e973115df21b 100644 --- a/sys/x86/iommu/intel_drv.c +++ b/sys/x86/iommu/intel_drv.c @@ -1053,48 +1053,12 @@ dmar_instantiate_rmrr_ctxs(struct iommu_unit *unit) #include #include -static void -dmar_print_domain_entry(const struct iommu_map_entry *entry) -{ - struct iommu_map_entry *l, *r; - - db_printf( - " start %jx end %jx first %jx last %jx free_down %jx flags %x ", - entry->start, entry->end, entry->first, entry->last, - entry->free_down, entry->flags); - db_printf("left "); - l = RB_LEFT(entry, rb_entry); - if (l == NULL) - db_printf("NULL "); - else - db_printf("%jx ", l->start); - db_printf("right "); - r = RB_RIGHT(entry, rb_entry); - if (r == NULL) - db_printf("NULL"); - else - db_printf("%jx", r->start); - db_printf("\n"); -} - -static void -dmar_print_ctx(struct dmar_ctx *ctx) -{ - - db_printf( - " @%p pci%d:%d:%d refs %d flags %x loads %lu unloads %lu\n", - ctx, pci_get_bus(ctx->context.tag->owner), - pci_get_slot(ctx->context.tag->owner), - pci_get_function(ctx->context.tag->owner), ctx->refs, - ctx->context.flags, ctx->context.loads, ctx->context.unloads); -} - static void dmar_print_domain(struct dmar_domain *domain, bool show_mappings) { struct iommu_domain *iodom; struct iommu_map_entry *entry; - struct dmar_ctx *ctx; + struct iommu_ctx *ctx; iodom = DOM2IODOM(domain); @@ -1104,16 +1068,16 @@ dmar_print_domain(struct dmar_domain *domain, bool show_mappings) domain, domain->domain, domain->mgaw, domain->agaw, domain->pglvl, (uintmax_t)domain->iodom.end, domain->refs, domain->ctx_cnt, domain->iodom.flags, domain->pgtbl_obj, domain->iodom.entries_cnt); - if (!LIST_EMPTY(&domain->contexts)) { + if (!LIST_EMPTY(&iodom->contexts)) { db_printf(" Contexts:\n"); - LIST_FOREACH(ctx, &domain->contexts, link) - dmar_print_ctx(ctx); + LIST_FOREACH(ctx, &iodom->contexts, link) + iommu_db_print_ctx(ctx); } if (!show_mappings) return; db_printf(" mapped:\n"); RB_FOREACH(entry, iommu_gas_entries_tree, &iodom->rb_root) { - dmar_print_domain_entry(entry); + iommu_db_print_domain_entry(entry); if (db_pager_quit) break; } @@ -1121,7 +1085,7 @@ dmar_print_domain(struct dmar_domain *domain, bool show_mappings) return; db_printf(" unloading:\n"); TAILQ_FOREACH(entry, &domain->iodom.unload_entries, dmamap_link) { - dmar_print_domain_entry(entry); + iommu_db_print_domain_entry(entry); if (db_pager_quit) break; } @@ -1131,7 +1095,7 @@ DB_SHOW_COMMAND_FLAGS(dmar_domain, db_dmar_print_domain, CS_OWN) { struct dmar_unit *unit; struct dmar_domain *domain; - struct dmar_ctx *ctx; + struct iommu_ctx *ctx; bool show_mappings, valid; int pci_domain, bus, device, function, i, t; db_expr_t radix; @@ -1179,13 +1143,12 @@ DB_SHOW_COMMAND_FLAGS(dmar_domain, db_dmar_print_domain, CS_OWN) for (i = 0; i < dmar_devcnt; i++) { unit = device_get_softc(dmar_devs[i]); LIST_FOREACH(domain, &unit->domains, link) { - LIST_FOREACH(ctx, &domain->contexts, link) { + LIST_FOREACH(ctx, &domain->iodom.contexts, link) { if (pci_domain == unit->segment && - bus == pci_get_bus(ctx->context.tag->owner) && - device == - pci_get_slot(ctx->context.tag->owner) && - function == - pci_get_function(ctx->context.tag->owner)) { + bus == pci_get_bus(ctx->tag->owner) && + device == pci_get_slot(ctx->tag->owner) && + function == pci_get_function(ctx->tag-> + owner)) { dmar_print_domain(domain, show_mappings); goto out; diff --git a/sys/x86/iommu/iommu_utils.c b/sys/x86/iommu/iommu_utils.c index db8f94eb584f..fde3f150947b 100644 --- a/sys/x86/iommu/iommu_utils.c +++ b/sys/x86/iommu/iommu_utils.c @@ -34,6 +34,7 @@ #else #include "opt_apic.h" #endif +#include "opt_ddb.h" #include #include @@ -756,3 +757,43 @@ pglvl_page_size(int total_pglvl, int lvl) KASSERT(rlvl < nitems(pg_sz), ("sizeof pg_sz lvl %d", lvl)); return (pg_sz[rlvl]); } + +#ifdef DDB +#include +#include + +void +iommu_db_print_domain_entry(const struct iommu_map_entry *entry) +{ + struct iommu_map_entry *l, *r; + + db_printf( + " start %jx end %jx first %jx last %jx free_down %jx flags %x ", + entry->start, entry->end, entry->first, entry->last, + entry->free_down, entry->flags); + db_printf("left "); + l = RB_LEFT(entry, rb_entry); + if (l == NULL) + db_printf("NULL "); + else + db_printf("%jx ", l->start); + db_printf("right "); + r = RB_RIGHT(entry, rb_entry); + if (r == NULL) + db_printf("NULL"); + else + db_printf("%jx", r->start); + db_printf("\n"); +} + +void +iommu_db_print_ctx(struct iommu_ctx *ctx) +{ + db_printf( + " @%p pci%d:%d:%d refs %d flags %#x loads %lu unloads %lu\n", + ctx, pci_get_bus(ctx->tag->owner), + pci_get_slot(ctx->tag->owner), + pci_get_function(ctx->tag->owner), ctx->refs, + ctx->flags, ctx->loads, ctx->unloads); +} +#endif diff --git a/sys/x86/iommu/x86_iommu.h b/sys/x86/iommu/x86_iommu.h index 4d0ac8351e2e..043935a3e0de 100644 --- a/sys/x86/iommu/x86_iommu.h +++ b/sys/x86/iommu/x86_iommu.h @@ -194,4 +194,7 @@ vm_pindex_t pglvl_pgtbl_get_pindex(int pglvl, iommu_gaddr_t base, int lvl); vm_pindex_t pglvl_max_pages(int pglvl); iommu_gaddr_t pglvl_page_size(int total_pglvl, int lvl); +void iommu_db_print_domain_entry(const struct iommu_map_entry *entry); +void iommu_db_print_ctx(struct iommu_ctx *ctx); + #endif