From nobody Tue Sep 9 03:06:12 2025 X-Original-To: dev-commits-src-main@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 4cLTH8340Xz66Fhf; Tue, 09 Sep 2025 03:06:12 +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 "R12" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4cLTH82KBbz3vgq; Tue, 09 Sep 2025 03:06:12 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1757387172; 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=u4GR+0MfR8bwOtuAkUdBkiNVSTemjvucD2KHNn6dIXo=; b=alIXF7Emk/sp4oNww9GasGMVeis+e9uSLv+5EcwHtrd8ODXaB5fESQVWYG9CfQ1MehVBMk qld0lvHwGjuBSGSXGpyzd6Pah/2ubf6b4i+SSxSLIgCb3gf0lPLm0DE4uMRdZzrhlkYzQl nor7I83Eiei7rrU8moZFEtXre1ur2Z2iHi4SKJUaWmI5xEKt7u9gRmni4NgVFfbf++NKEM cjQ1lMp/ZCTJS3XeFzGh5kVghAMuT66CVVEhNDERdT3DS9PkK5qUneFGpWHdC4Lstwm6+/ 9MnxWM3zQNUUOZ6LvHtG4tDOu/07aJ5yoYCANGZraf3aVHD8w2vtdJVqoW5j5g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1757387172; 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=u4GR+0MfR8bwOtuAkUdBkiNVSTemjvucD2KHNn6dIXo=; b=pHZvZ++H8JMCeV/Zf/uHGTsYltv7pbhPwaCqrOHmasB1Vy13BPXsPCPx547ixsOnRqBYjW ebXu3Na5xQ7phKR9ScDGeM+zvc9qvi/oiHJKnDt8JWKEFXMi8xr57V38T83Bbnq3qKw3fl 4EG0dHnPfVfVMMUwB86JWLCHUDwGu+z8iyyzP5FJMlVwA7m6mgSUK4BTy9KZUH+jsmNCBd P9pRMR3UTPzUQDmPyrPwhYw0e2q6dNhdo/AjoPMa/qO8IH7AdRgcB7BHSwYSAuVBjcsEdR HT1jQezHz/4iUS2zpk/tcEHarkW6Un94f0lMDs4o2UvQequ4rIIZqfUEd7nbOw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1757387172; a=rsa-sha256; cv=none; b=o1zRHc0xcgAAVUU+QnpRDuBM2PIvY8XwbLC6SgIPpALKHzTq6VR9ljWFqRtm3f3cjjTUIM UjDKVglpyXshqcHfDXt94L4mb3s6JKwXdx88YzGHXl5SY9FuIo/HebTP9rE6hW8d6cEiWn NbIvo8D5S8cC9A1tAvzmODSBJvfizY4DfS8SQC64W8+cj7KmDXxn6sQpTZPrYAh5RpjJEM 2hz2nqZe/ggJ7b/d7c+Nun6HhDtiSryexijGfRJP5Abri3hSRp7DLV9zLmDPymNwlm0MGV cWtCAcwSH7S82hx8VrvcRWIHZKue/JuD3wMa5e61Jkl5tMNCoZHM/YG4r5Umhg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none 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 4cLTH81w2nz3XL; Tue, 09 Sep 2025 03:06:12 +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 58936CMi093820; Tue, 9 Sep 2025 03:06:12 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 58936Ctu093817; Tue, 9 Sep 2025 03:06:12 GMT (envelope-from git) Date: Tue, 9 Sep 2025 03:06:12 GMT Message-Id: <202509090306.58936Ctu093817@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: c745a6818bcb - main - iommu_get_requester(): make it more resilient against arbitrary dev arg List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@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: c745a6818bcbf33cf7f59641c925d19b3f98cea8 Auto-Submitted: auto-generated The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=c745a6818bcbf33cf7f59641c925d19b3f98cea8 commit c745a6818bcbf33cf7f59641c925d19b3f98cea8 Author: Konstantin Belousov AuthorDate: 2025-09-05 23:06:18 +0000 Commit: Konstantin Belousov CommitDate: 2025-09-09 02:51:08 +0000 iommu_get_requester(): make it more resilient against arbitrary dev arg If passed the parent of a device instead of the device, the loop might end up with the host bridge in the pci local variable. If the passed device is not from the pci hierarchy, any of the calculated parents might be NULL. Change the interface to allow the caller to receive error. Instead of asserting, just issue a message and return ENXIO, allowing the caller to select appropriate action. PR: 289318 Reviewed by: jah Sponsored by: The FreeBSD Foundation MFC after: 2 weeks Differential revision: https://reviews.freebsd.org/D52406 --- sys/dev/iommu/busdma_iommu.c | 54 ++++++++++++++++++++++++++++++++----------- sys/dev/iommu/iommu.h | 2 +- sys/kern/subr_bus.c | 13 +++++++++-- sys/x86/iommu/amd_intrmap.c | 14 ++++++++--- sys/x86/iommu/intel_intrmap.c | 8 +++++-- 5 files changed, 70 insertions(+), 21 deletions(-) diff --git a/sys/dev/iommu/busdma_iommu.c b/sys/dev/iommu/busdma_iommu.c index 6856b0551dde..668ccf056463 100644 --- a/sys/dev/iommu/busdma_iommu.c +++ b/sys/dev/iommu/busdma_iommu.c @@ -114,8 +114,8 @@ iommu_bus_dma_is_dev_disabled(int domain, int bus, int slot, int func) * domain, and must collectively be assigned to use either IOMMU or * bounce mapping. */ -device_t -iommu_get_requester(device_t dev, uint16_t *rid) +int +iommu_get_requester(device_t dev, device_t *requesterp, uint16_t *rid) { devclass_t pci_class; device_t l, pci, pcib, pcip, pcibp, requester; @@ -129,7 +129,8 @@ iommu_get_requester(device_t dev, uint16_t *rid) pci = device_get_parent(dev); if (pci == NULL || device_get_devclass(pci) != pci_class) { *rid = 0; /* XXXKIB: Could be ACPI HID */ - return (requester); + *requesterp = NULL; + return (ENOTTY); } *rid = pci_get_rid(dev); @@ -141,16 +142,39 @@ iommu_get_requester(device_t dev, uint16_t *rid) */ for (;;) { pci = device_get_parent(l); - KASSERT(pci != NULL, ("iommu_get_requester(%s): NULL parent " - "for %s", device_get_name(dev), device_get_name(l))); - KASSERT(device_get_devclass(pci) == pci_class, - ("iommu_get_requester(%s): non-pci parent %s for %s", - device_get_name(dev), device_get_name(pci), - device_get_name(l))); + if (pci == NULL) { + if (bootverbose) { + printf( + "iommu_get_requester(%s): NULL parent for %s\n", + device_get_name(dev), device_get_name(l)); + } + *rid = 0; + *requesterp = NULL; + return (ENXIO); + } + if (device_get_devclass(pci) != pci_class) { + if (bootverbose) { + printf( + "iommu_get_requester(%s): non-pci parent %s for %s\n", + device_get_name(dev), device_get_name(pci), + device_get_name(l)); + } + *rid = 0; + *requesterp = NULL; + return (ENXIO); + } pcib = device_get_parent(pci); - KASSERT(pcib != NULL, ("iommu_get_requester(%s): NULL bridge " - "for %s", device_get_name(dev), device_get_name(pci))); + if (pcib == NULL) { + if (bootverbose) { + printf( + "iommu_get_requester(%s): NULL bridge for %s\n", + device_get_name(dev), device_get_name(pci)); + } + *rid = 0; + *requesterp = NULL; + return (ENXIO); + } /* * The parent of our "bridge" isn't another PCI bus, @@ -229,7 +253,8 @@ iommu_get_requester(device_t dev, uint16_t *rid) } } } - return (requester); + *requesterp = requester; + return (0); } struct iommu_ctx * @@ -237,10 +262,13 @@ iommu_instantiate_ctx(struct iommu_unit *unit, device_t dev, bool rmrr) { device_t requester; struct iommu_ctx *ctx; + int error; bool disabled; uint16_t rid; - requester = iommu_get_requester(dev, &rid); + error = iommu_get_requester(dev, &requester, &rid); + if (error != 0) + return (NULL); /* * If the user requested the IOMMU disabled for the device, we diff --git a/sys/dev/iommu/iommu.h b/sys/dev/iommu/iommu.h index b1858f0df9f7..55044042c5d2 100644 --- a/sys/dev/iommu/iommu.h +++ b/sys/dev/iommu/iommu.h @@ -170,7 +170,7 @@ void iommu_domain_unload(struct iommu_domain *domain, void iommu_unit_pre_instantiate_ctx(struct iommu_unit *iommu); struct iommu_ctx *iommu_instantiate_ctx(struct iommu_unit *iommu, device_t dev, bool rmrr); -device_t iommu_get_requester(device_t dev, uint16_t *rid); +int iommu_get_requester(device_t dev, device_t *requester, uint16_t *rid); int iommu_init_busdma(struct iommu_unit *unit); void iommu_fini_busdma(struct iommu_unit *unit); diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c index 62a3da964c37..bf5bda7e058d 100644 --- a/sys/kern/subr_bus.c +++ b/sys/kern/subr_bus.c @@ -280,6 +280,9 @@ device_sysctl_handler(SYSCTL_HANDLER_ARGS) struct sbuf sb; device_t dev = (device_t)arg1; device_t iommu; +#ifdef IOMMU + device_t requester; +#endif int error; uint16_t rid; const char *c; @@ -314,9 +317,15 @@ device_sysctl_handler(SYSCTL_HANDLER_ARGS) } rid = 0; #ifdef IOMMU - iommu_get_requester(dev, &rid); + error = iommu_get_requester(dev, &requester, &rid); + /* + * Do not return requester error from sysctl, iommu + * unit might be assigned by other means. + */ +#else + error = ENXIO; #endif - if (rid != 0) + if (error == 0) sbuf_printf(&sb, "%srid=%#x", c, rid); break; default: diff --git a/sys/x86/iommu/amd_intrmap.c b/sys/x86/iommu/amd_intrmap.c index a4c1a7836268..f8900fe0561f 100644 --- a/sys/x86/iommu/amd_intrmap.c +++ b/sys/x86/iommu/amd_intrmap.c @@ -112,6 +112,8 @@ amdiommu_map_msi_intr(device_t src, u_int cpu, u_int vector, { struct amdiommu_ctx *ctx; struct amdiommu_unit *unit; + device_t requester; + int error __diagused; uint16_t rid; bool is_iommu; @@ -180,7 +182,8 @@ amdiommu_map_msi_intr(device_t src, u_int cpu, u_int vector, *addr |= ((uint64_t)cpu & 0xffffff00) << 32; } - iommu_get_requester(src, &rid); + error = iommu_get_requester(src, &requester, &rid); + MPASS(error == 0); AMDIOMMU_LOCK(unit); amdiommu_qi_invalidate_ir_locked(unit, rid); AMDIOMMU_UNLOCK(unit); @@ -220,6 +223,7 @@ static struct amdiommu_ctx * amdiommu_ir_find(device_t src, uint16_t *ridp, bool *is_iommu) { devclass_t src_class; + device_t requester; struct amdiommu_unit *unit; struct amdiommu_ctx *ctx; uint32_t edte; @@ -251,7 +255,8 @@ amdiommu_ir_find(device_t src, uint16_t *ridp, bool *is_iommu) error = amdiommu_find_unit(src, &unit, &rid, &dte, &edte, bootverbose); if (error == 0) { - iommu_get_requester(src, &rid); + error = iommu_get_requester(src, &requester, &rid); + MPASS(error == 0); ctx = amdiommu_get_ctx_for_dev(unit, src, rid, 0, false /* XXXKIB */, false, dte, edte); } @@ -266,6 +271,8 @@ amdiommu_ir_free_irte(struct amdiommu_ctx *ctx, device_t src, u_int cookie) { struct amdiommu_unit *unit; + device_t requester; + int error __diagused; uint16_t rid; MPASS(ctx != NULL); @@ -291,7 +298,8 @@ amdiommu_ir_free_irte(struct amdiommu_ctx *ctx, device_t src, atomic_thread_fence_rel(); bzero(irte, sizeof(*irte)); } - iommu_get_requester(src, &rid); + error = iommu_get_requester(src, &requester, &rid); + MPASS(error == 0); AMDIOMMU_LOCK(unit); amdiommu_qi_invalidate_ir_locked(unit, rid); AMDIOMMU_UNLOCK(unit); diff --git a/sys/x86/iommu/intel_intrmap.c b/sys/x86/iommu/intel_intrmap.c index 06e41523624b..f12a0c9bae9b 100644 --- a/sys/x86/iommu/intel_intrmap.c +++ b/sys/x86/iommu/intel_intrmap.c @@ -234,6 +234,8 @@ dmar_ir_find(device_t src, uint16_t *rid, int *is_dmar) { devclass_t src_class; struct dmar_unit *unit; + device_t requester; + int error __diagused; /* * We need to determine if the interrupt source generates FSB @@ -253,8 +255,10 @@ dmar_ir_find(device_t src, uint16_t *rid, int *is_dmar) unit = dmar_find_hpet(src, rid); } else { unit = dmar_find(src, bootverbose); - if (unit != NULL && rid != NULL) - iommu_get_requester(src, rid); + if (unit != NULL && rid != NULL) { + error = iommu_get_requester(src, &requester, rid); + MPASS(error == 0); + } } return (unit); }