From owner-svn-src-head@freebsd.org Sat Jul 18 13:10:33 2020 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 93C81369269; Sat, 18 Jul 2020 13:10:33 +0000 (UTC) (envelope-from br@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 "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4B87dj2T3fz4J1L; Sat, 18 Jul 2020 13:10:33 +0000 (UTC) (envelope-from br@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 397B6B035; Sat, 18 Jul 2020 13:10:33 +0000 (UTC) (envelope-from br@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 06IDAXeQ085996; Sat, 18 Jul 2020 13:10:33 GMT (envelope-from br@FreeBSD.org) Received: (from br@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 06IDAWNm085990; Sat, 18 Jul 2020 13:10:32 GMT (envelope-from br@FreeBSD.org) Message-Id: <202007181310.06IDAWNm085990@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: br set sender to br@FreeBSD.org using -f From: Ruslan Bukin Date: Sat, 18 Jul 2020 13:10:32 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r363310 - in head/sys: sys x86/iommu X-SVN-Group: head X-SVN-Commit-Author: br X-SVN-Commit-Paths: in head/sys: sys x86/iommu X-SVN-Commit-Revision: 363310 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 18 Jul 2020 13:10:33 -0000 Author: br Date: Sat Jul 18 13:10:31 2020 New Revision: 363310 URL: https://svnweb.freebsd.org/changeset/base/363310 Log: o Move iommu_test_boundary() to sys/iommu.h o Rename DMAR -> IOMMU in comments o Add IOMMU_PAGE_SIZE / IOMMU_PAGE_MASK macroses o x86 only: dmar_quirks_pre_use() / dmar_instantiate_rmrr_ctxs() Reviewed by: kib Sponsored by: DARPA/AFRL Differential Revision: https://reviews.freebsd.org/D25665 Modified: head/sys/sys/iommu.h head/sys/x86/iommu/busdma_dmar.c head/sys/x86/iommu/intel_dmar.h head/sys/x86/iommu/intel_drv.c head/sys/x86/iommu/intel_gas.c head/sys/x86/iommu/intel_reg.h Modified: head/sys/sys/iommu.h ============================================================================== --- head/sys/sys/iommu.h Sat Jul 18 13:10:02 2020 (r363309) +++ head/sys/sys/iommu.h Sat Jul 18 13:10:31 2020 (r363310) @@ -35,6 +35,7 @@ #define _SYS_IOMMU_H_ #include +#include #include #include @@ -43,6 +44,7 @@ typedef uint64_t iommu_haddr_t; /* Guest or bus address, before translation. */ typedef uint64_t iommu_gaddr_t; +struct bus_dma_tag_common; struct iommu_map_entry; TAILQ_HEAD(iommu_map_entries_tailq, iommu_map_entry); @@ -102,6 +104,7 @@ struct iommu_domain { struct iommu_unit *iommu; /* (c) */ struct mtx lock; /* (c) */ struct task unload_task; /* (c) */ + u_int entries_cnt; /* (d) */ struct iommu_map_entries_tailq unload_entries; /* (d) Entries to unload */ }; @@ -128,6 +131,16 @@ struct iommu_ctx { #define IOMMU_DOMAIN_LOCK(dom) mtx_lock(&(dom)->lock) #define IOMMU_DOMAIN_UNLOCK(dom) mtx_unlock(&(dom)->lock) #define IOMMU_DOMAIN_ASSERT_LOCKED(dom) mtx_assert(&(dom)->lock, MA_OWNED) + +static inline bool +iommu_test_boundary(iommu_gaddr_t start, iommu_gaddr_t size, + iommu_gaddr_t boundary) +{ + + if (boundary == 0) + return (true); + return (start + size <= ((start + boundary) & ~(boundary - 1))); +} void iommu_free_ctx(struct iommu_ctx *ctx); void iommu_free_ctx_locked(struct iommu_unit *iommu, struct iommu_ctx *ctx); Modified: head/sys/x86/iommu/busdma_dmar.c ============================================================================== --- head/sys/x86/iommu/busdma_dmar.c Sat Jul 18 13:10:02 2020 (r363309) +++ head/sys/x86/iommu/busdma_dmar.c Sat Jul 18 13:10:31 2020 (r363310) @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -62,11 +63,13 @@ __FBSDID("$FreeBSD$"); #include #include #include +#if defined(__amd64__) || defined(__i386__) #include #include #include #include #include +#endif /* * busdma_dmar.c, the implementation of the busdma(9) interface using @@ -112,11 +115,11 @@ iommu_bus_dma_is_dev_disabled(int domain, int bus, int /* * Given original device, find the requester ID that will be seen by - * the DMAR unit and used for page table lookup. PCI bridges may take + * the IOMMU unit and used for page table lookup. PCI bridges may take * ownership of transactions from downstream devices, so it may not be * the same as the BSF of the target device. In those cases, all * devices downstream of the bridge must share a single mapping - * domain, and must collectively be assigned to use either DMAR or + * domain, and must collectively be assigned to use either IOMMU or * bounce mapping. */ device_t @@ -135,7 +138,7 @@ iommu_get_requester(device_t dev, uint16_t *rid) /* * Walk the bridge hierarchy from the target device to the - * host port to find the translating bridge nearest the DMAR + * host port to find the translating bridge nearest the IOMMU * unit. */ for (;;) { @@ -173,7 +176,7 @@ iommu_get_requester(device_t dev, uint16_t *rid) } else { /* * Device is not PCIe, it cannot be seen as a - * requester by DMAR unit. Check whether the + * requester by IOMMU unit. Check whether the * bridge is PCIe. */ bridge_is_pcie = pci_find_cap(pcib, PCIY_EXPRESS, @@ -243,8 +246,8 @@ iommu_instantiate_ctx(struct iommu_unit *unit, device_ /* * If the user requested the IOMMU disabled for the device, we - * cannot disable the DMAR, due to possibility of other - * devices on the same DMAR still requiring translation. + * cannot disable the IOMMU unit, due to possibility of other + * devices on the same IOMMU unit still requiring translation. * Instead provide the identity mapping for the device * context. */ @@ -279,13 +282,16 @@ acpi_iommu_get_dma_tag(device_t dev, device_t child) bus_dma_tag_t res; unit = iommu_find(child, bootverbose); - /* Not in scope of any DMAR ? */ + /* Not in scope of any IOMMU ? */ if (unit == NULL) return (NULL); if (!unit->dma_enabled) return (NULL); + +#if defined(__amd64__) || defined(__i386__) dmar_quirks_pre_use(unit); dmar_instantiate_rmrr_ctxs(unit); +#endif ctx = iommu_instantiate_ctx(unit, child, false); res = ctx == NULL ? NULL : (bus_dma_tag_t)ctx->tag; @@ -536,7 +542,7 @@ iommu_bus_dmamap_load_something1(struct bus_dma_tag_io bus_size_t buflen1; int error, idx, gas_flags, seg; - KASSERT(offset < DMAR_PAGE_SIZE, ("offset %d", offset)); + KASSERT(offset < IOMMU_PAGE_SIZE, ("offset %d", offset)); if (segs == NULL) segs = tag->segments; ctx = tag->ctx; @@ -621,7 +627,7 @@ iommu_bus_dmamap_load_something1(struct bus_dma_tag_io idx += OFF_TO_IDX(trunc_page(offset + buflen1)); offset += buflen1; - offset &= DMAR_PAGE_MASK; + offset &= IOMMU_PAGE_MASK; buflen -= buflen1; } if (error == 0) @@ -841,7 +847,7 @@ iommu_bus_dmamap_complete(bus_dma_tag_t dmat, bus_dmam } /* - * The limitations of busdma KPI forces the dmar to perform the actual + * The limitations of busdma KPI forces the iommu to perform the actual * unload, consisting of the unmapping of the map entries page tables, * from the delayed context on i386, since page table page mapping * might require a sleep to be successfull. The unfortunate Modified: head/sys/x86/iommu/intel_dmar.h ============================================================================== --- head/sys/x86/iommu/intel_dmar.h Sat Jul 18 13:10:02 2020 (r363309) +++ head/sys/x86/iommu/intel_dmar.h Sat Jul 18 13:10:31 2020 (r363310) @@ -77,7 +77,6 @@ struct dmar_domain { LIST_HEAD(, dmar_ctx) contexts; /* (u) */ vm_object_t pgtbl_obj; /* (c) Page table pages */ u_int flags; /* (u) */ - u_int entries_cnt; /* (d) */ struct dmar_gas_entries_tree rb_root; /* (d) */ struct iommu_map_entry *first_place, *last_place; /* (d) */ u_int batch_no; @@ -458,16 +457,6 @@ dmar_pte_clear(volatile uint64_t *dst) #else *dst = 0; #endif -} - -static inline bool -iommu_test_boundary(iommu_gaddr_t start, iommu_gaddr_t size, - iommu_gaddr_t boundary) -{ - - if (boundary == 0) - return (true); - return (start + size <= ((start + boundary) & ~(boundary - 1))); } extern struct timespec dmar_hw_timeout; Modified: head/sys/x86/iommu/intel_drv.c ============================================================================== --- head/sys/x86/iommu/intel_drv.c Sat Jul 18 13:10:02 2020 (r363309) +++ head/sys/x86/iommu/intel_drv.c Sat Jul 18 13:10:31 2020 (r363310) @@ -1160,7 +1160,7 @@ dmar_print_domain(struct dmar_domain *domain, bool sho " 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); + domain->flags, domain->pgtbl_obj, domain->iodom.entries_cnt); if (!LIST_EMPTY(&domain->contexts)) { db_printf(" Contexts:\n"); LIST_FOREACH(ctx, &domain->contexts, link) Modified: head/sys/x86/iommu/intel_gas.c ============================================================================== --- head/sys/x86/iommu/intel_gas.c Sat Jul 18 13:10:02 2020 (r363309) +++ head/sys/x86/iommu/intel_gas.c Sat Jul 18 13:10:31 2020 (r363310) @@ -98,7 +98,7 @@ dmar_gas_alloc_entry(struct dmar_domain *domain, u_int 0 ? M_WAITOK : M_NOWAIT) | M_ZERO); if (res != NULL) { res->domain = (struct iommu_domain *)domain; - atomic_add_int(&domain->entries_cnt, 1); + atomic_add_int(&domain->iodom.entries_cnt, 1); } return (res); } @@ -110,7 +110,7 @@ dmar_gas_free_entry(struct dmar_domain *domain, struct KASSERT(domain == (struct dmar_domain *)entry->domain, ("mismatched free domain %p entry %p entry->domain %p", domain, entry, entry->domain)); - atomic_subtract_int(&domain->entries_cnt, 1); + atomic_subtract_int(&domain->iodom.entries_cnt, 1); uma_zfree(iommu_map_entry_zone, entry); } @@ -214,7 +214,7 @@ dmar_gas_init_domain(struct dmar_domain *domain) end = dmar_gas_alloc_entry(domain, DMAR_PGF_WAITOK); DMAR_DOMAIN_LOCK(domain); - KASSERT(domain->entries_cnt == 2, ("dirty domain %p", domain)); + KASSERT(domain->iodom.entries_cnt == 2, ("dirty domain %p", domain)); KASSERT(RB_EMPTY(&domain->rb_root), ("non-empty entries %p", domain)); begin->start = 0; @@ -239,7 +239,8 @@ dmar_gas_fini_domain(struct dmar_domain *domain) struct iommu_map_entry *entry, *entry1; DMAR_DOMAIN_ASSERT_LOCKED(domain); - KASSERT(domain->entries_cnt == 2, ("domain still in use %p", domain)); + KASSERT(domain->iodom.entries_cnt == 2, + ("domain still in use %p", domain)); entry = RB_MIN(dmar_gas_entries_tree, &domain->rb_root); KASSERT(entry->start == 0, ("start entry start %p", domain)); Modified: head/sys/x86/iommu/intel_reg.h ============================================================================== --- head/sys/x86/iommu/intel_reg.h Sat Jul 18 13:10:02 2020 (r363309) +++ head/sys/x86/iommu/intel_reg.h Sat Jul 18 13:10:31 2020 (r363310) @@ -41,6 +41,9 @@ #define DMAR_NPTEPGSHIFT 9 #define DMAR_PTEMASK (DMAR_NPTEPG - 1) +#define IOMMU_PAGE_SIZE DMAR_PAGE_SIZE +#define IOMMU_PAGE_MASK DMAR_PAGE_MASK + typedef struct dmar_root_entry { uint64_t r1; uint64_t r2;