From nobody Mon Sep 22 04:59:33 2025 X-Original-To: dev-commits-src-branches@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 4cVW9x3d3Xz68Zt6; Mon, 22 Sep 2025 04:59:33 +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 4cVW9x2Wk4z3Qy5; Mon, 22 Sep 2025 04:59:33 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1758517173; 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=ND98FnKMMVEPG2XuM9KH733kVKekQAyG55GJ7xAt1WY=; b=R2qwdxtOyyUs1BtQ9IEyCiRXn8m292B9/uN9G6Muxguv0EaX62g2izuKM28JsU2WF9Itl2 DnFHIHRT9NkkvEMWRZC3fZI+rw+FE/mqasDEEg975efrfeuD+jSuuTkXjPxS3xdcHsx5uW WbQqhjvahUk1SgFobTnuXHSxLzzMau16fD2cmSIgatBuJw0xdkPjbwZaCaySy9QY6Iwz9i QK1O0jRjAaOSI2ZINSIplJNiOM3hg0iHKFetFL53twwpW7kfNimBccHpzzKKS0DGeyAk9V nH7PTJq6ZDBj7uBAW1DpYwEzCaiFTUuLhZdp4LzfaHcbvJlS+2dmHSbTMLfFtQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1758517173; 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=ND98FnKMMVEPG2XuM9KH733kVKekQAyG55GJ7xAt1WY=; b=yaNaDjuY0c85gE0BMY4usnjXP2zY7U8lgqjFJaQAHAJ7AUXWxkaBEfOaNhHvCjSf1NxIc+ RviNapQbqKDPCKSIgcN4CNeXrZc6ARzRwQP7IgApxa2zQwoaSaK42eeC7UjrstErP1cP39 KLQr/ovV1hMYnF9M2DhOKZDfkeX87bGxajK/g1QbilcDqfVrFTSIdVdqrOGGXgx2Ag++PE aVR2RGGPAS43/mraqlZsQIaA804JP63mmKQsEvzRhdjg/fVAXMvu7AKg6VgOr6+vd1T1ZW CtDP+DP3nykcjipB5782NTpAP1gewgTCYGa15gJOQcNqJGTrQDYQD62YdDQ+tQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1758517173; a=rsa-sha256; cv=none; b=rMKkAggFtvc8QT9VdPKj2vs3rctZngf4qsYLlYrBqEihb1D75GRZjA2L2xxihI4LSWB3QL MgpVe1ZvujFZn9Rnn8SnCGEgwYcnjeobHiCYZajLb/y3EuogKr5axxzOP7O0c/kATUMbmN a4+GN9YanrGz3GwP1RNZXa71AvaELLgV7Mby6Gaf7K0KxdGt8WLyE4gX60deL9/TzhaCRr W691ddGHOWWzW0ABeYDveFRnf1vGqsrbQ9+KBF/nVnR+ZZnQQ/vzNWBj2+REKzm25+QKVr ppgJWWLjBKdCPJmKsIlcExElKQK/0785us64Y5B5AZguLDRo0yOzIKo1UPtJbA== 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 4cVW9x1zP0zm43; Mon, 22 Sep 2025 04:59:33 +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 58M4xXRj094866; Mon, 22 Sep 2025 04:59:33 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 58M4xXB7094863; Mon, 22 Sep 2025 04:59:33 GMT (envelope-from git) Date: Mon, 22 Sep 2025 04:59:33 GMT Message-Id: <202509220459.58M4xXB7094863@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Konstantin Belousov Subject: git: ea4e916858ef - stable/14 - iommu_get_requester(): make it more resilient against arbitrary dev arg List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-branches@freebsd.org Sender: owner-dev-commits-src-branches@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/stable/14 X-Git-Reftype: branch X-Git-Commit: ea4e916858ef29a29236b292c188d83eac5e1ebc Auto-Submitted: auto-generated The branch stable/14 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=ea4e916858ef29a29236b292c188d83eac5e1ebc commit ea4e916858ef29a29236b292c188d83eac5e1ebc Author: Konstantin Belousov AuthorDate: 2025-09-05 23:06:18 +0000 Commit: Konstantin Belousov CommitDate: 2025-09-22 04:59:08 +0000 iommu_get_requester(): make it more resilient against arbitrary dev arg PR: 289318 (cherry picked from commit c745a6818bcbf33cf7f59641c925d19b3f98cea8) --- 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 8c97965bcdf1..afb6267fc792 100644 --- a/sys/dev/iommu/busdma_iommu.c +++ b/sys/dev/iommu/busdma_iommu.c @@ -115,8 +115,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; @@ -130,7 +130,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); @@ -142,16 +143,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, @@ -230,7 +254,8 @@ iommu_get_requester(device_t dev, uint16_t *rid) } } } - return (requester); + *requesterp = requester; + return (0); } struct iommu_ctx * @@ -238,10 +263,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 211fe45b1374..28d37ad8d450 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 c5c1706f1f3e..d49d40375448 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 4f69e2d44996..88d46cfdf67b 100644 --- a/sys/x86/iommu/intel_intrmap.c +++ b/sys/x86/iommu/intel_intrmap.c @@ -235,6 +235,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 @@ -254,8 +256,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); }