From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9E55A368D50 for ; Fri, 7 Aug 2026 18:17:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786126642; cv=none; b=Q9HF6OApGUyKjXtuVV/KkLjaYqa++IGfF6Tng77RDdS9qFKmorbPdRoJJZ/UcZg374UfmX2eDNimM5S2Yxpjt5EQHfAP4q+2skOROEoXSJGGHLsuI7yh45vMH1L4nH6+X5aXBXuzS+gB2/M1GCzw/fJB8OTfRfMpw3NyFsjkpBQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786126642; c=relaxed/simple; bh=cs8xqe5jTSTMP/cRFiAHim9r9cnzCfBWDanSTu/cBjo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=SJLhO6G1lxNAyDVQC9Rsg/FEKJwe6dXr9yoeu263V3EhVenJAqVWRVvTjEchjqOV2GGrpMTVtbZwi1s/eF979c5MZL9fhDTogSy8uuyJwDY/GHM489f+cgcXcSsohTzKtILfYS55ammv7ouoZppCBNO6fvXLyGr2Liu5gnjucxQ= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=jSTHZsQN; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=kxMb8jNh; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="jSTHZsQN"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="kxMb8jNh" Received: from pps.filterd (m0279871.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 677GbV3u1825898 for ; Fri, 7 Aug 2026 18:17:19 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=x4BbeW4tbgB s5QyG02520XP2wqPwKgkuyyfFvzacp9M=; b=jSTHZsQNCDus3Y1t7VZCEp9azzF 69zt/DYBg9EUlNYPu2zli6aNtxnqU8B5fSpbW2tCsPXPmyRfMq8VndH/qm13Rz7e jirJWPIFU3VUq8KLI/U1iSaleJ9O2xsvHWlq1jb5NoDmZDtbrkLUf1B3cfecnfnP bs7AxK4bli6sKg6bTr6NuCS1vAueYZSku/TihPYrazQvKt2kM/ADBNYkQE7f0O5B sKbmnjKytU4a+oEHkcvIwghLnCMo/Vx1SZAJFnsOAaVv0AYxN6jCxTZ9Pj3aOPVn P+Nx3kysuGL+ufNDih1r5cU56rZNx0WPtB1E6lzLeq6OEZAvNKjFYhNfaRA== Received: from mail-qt1-f199.google.com (mail-qt1-f199.google.com [209.85.160.199]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4fwk21geyc-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 07 Aug 2026 18:17:19 +0000 (GMT) Received: by mail-qt1-f199.google.com with SMTP id d75a77b69052e-51a8db414c7so45496031cf.0 for ; Fri, 07 Aug 2026 11:17:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1786126639; x=1786731439; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=x4BbeW4tbgBs5QyG02520XP2wqPwKgkuyyfFvzacp9M=; b=kxMb8jNh2kw0f/Q6MURMEmn96/rWbh4l2B9Epu4IPQpahqkp3DDWBFta/Bmp/iE2To byJOK0jhJykdiGvrDBFNWGcvZNmKTswW2QBtqHQiiXNfD/LbD/vC3engF0UB2PuvjxHf rojVO0cy5eyPt3AUW6aDWoVd0NsfVlZ7nT51nFYiVsAxIBVCNYPYSYNi8ZrksMDAs+BG lyki2phCj+sGrnBL3X1OLpewa/HF2ETUR6pVz3hGtBtayvsNuBJY5qGh8GDP1KGHUlpS 9ZtDx2vb2NgH94GAWiAc6CznC2TT7jxBgf7gyu7CR73J5miyLGlz7D5unCQhd5z9M8aO 8iRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786126639; x=1786731439; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=x4BbeW4tbgBs5QyG02520XP2wqPwKgkuyyfFvzacp9M=; b=bEeBrTLVYr69PsinuT2o4tGkCnwxmUF7TaWWUpf3Ptr7ON84pN1Ye4rgD22dDrccaG TC2inRM+o5BdjamE1SaJyPu523LcPuLuOHdCJVlgW0WceIDQSzEa0wTp+PCcxcKXesTF ZrGyH++CMd3AEGDuZHetnFScPbV70tZ1pGmrF+RcWgFGy/oy5/s07C+IX9j5C1F+H0Vp p+vLY0i/o7UuKkEEcd7xaakoVLMpRsgKVkKiswWvXfft07IQXceYXsuMboVAWRrwC1up HNra421OHETLpQSOQW0It20h/m+5+7fk+BsRfN+DSqNpXC0PW9M8MxqRvFGGw2dro9oF O3Tw== X-Gm-Message-State: AOJu0YxQi8h5AoRsnbc8Xqac1JHLAEzE78T4aIiz8CGFlWbB0c0LpRUm pvdya6aPwzFJQz5Wma/FtJBFRHYPwkDDVl1U9IAapXKzG7a95ZwQhWckOeOZ7MIuCVzDP9PRMUo IwvnGtbOhGaW3gcZYVZwqnJNFpILyhjktZXee9i0AVoMeBOd1ylJoyXuPjttERhrxqdQ= X-Gm-Gg: AR+sD10nsm/B5RZ8Db21JkntvOGxEXdAWJRxoDZhT2f36dlbdKp/yCV3gZj8WERL6+b Bnq8QN9Dt60q6A7CUyvG+zVxR0OOiohVoMDFJx0DHdRhIpOobVxpa4ieJYmdP92PL6Px114FWbn DZ6RKnjsfhbrz/pgA1XtPmskJ3ybvJpa357eaRmOO086pPnojwjnYOEM514USyTmdLliFjau1u0 BvIYV1BPCZ9YEXblBkSKhMtaqXy1i6q17wK0/Z5HtJ17Yd9X7Dfs74VxhvjAK7GlWJFZqmSOJy+ 0ktG8s5baX3gJ/3bbm5wVI0wRYHSnPS3TzkjApLK0WRWkNssxWTqzV59lOBk4JeR6/JjKiFLqTe B7ZZOawvzF0HUBDoglENDdYt/H2aHsmjf6cLotmY= X-Received: by 2002:a05:622a:451:b0:51c:1006:a024 with SMTP id d75a77b69052e-52d20a9abe2mr32327301cf.43.1786126638646; Fri, 07 Aug 2026 11:17:18 -0700 (PDT) X-Received: by 2002:a05:622a:451:b0:51c:1006:a024 with SMTP id d75a77b69052e-52d20a9abe2mr32326551cf.43.1786126638220; Fri, 07 Aug 2026 11:17:18 -0700 (PDT) Received: from localhost (ip-86-49-241-13.bb.vodafone.cz. [86.49.241.13]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-6a1e7cae4d1sm857274a12.11.2026.08.07.11.17.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Aug 2026 11:17:17 -0700 (PDT) From: Andrew Jones To: linux-riscv@lists.infradead.org, iommu@lists.linux.dev Cc: linux-kernel@vger.kernel.org, tomasz.jeznach@linux.dev, tjeznach@rivosinc.com, jgg@ziepe.ca, jgg@nvidia.com, joro@8bytes.org, will@kernel.org, robin.murphy@arm.com, pjw@kernel.org, palmer@dabbelt.com, anup@brainfault.org, tglx@kernel.org, kevin.tian@intel.com, fangyu.yu@linux.alibaba.com Subject: [PATCH v3 01/19] iommufd: Convert struct iommufd_sw_msi_maps to a growable bitmap Date: Fri, 7 Aug 2026 20:16:55 +0200 Message-ID: <20260807181713.228535-2-andrew.jones@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260807181713.228535-1-andrew.jones@oss.qualcomm.com> References: <20260807181713.228535-1-andrew.jones@oss.qualcomm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Proofpoint-ORIG-GUID: vtyOH2CqJUZPAHbpul5yHzkB35MRjcyH X-Proofpoint-GUID: vtyOH2CqJUZPAHbpul5yHzkB35MRjcyH X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODA3MDE0MyBTYWx0ZWRfX6PVmbC3tMlfR 5Jzn3KROdfufk1AuM1vsl8EBQ9qhZkoSkl2zpTgv6XD+Jmkd3NBflQe8w5rfQyNSZYCm1SEVMH5 ZlCJ1ZOrp0/ZPKliq7bDpFTK827+YkNRU3O/uGQN9TS3izH7+6qTDWj7OuQDhd0OfShkvp6SsrI ZQQgxgcHQushylF2kkssSZtFhSdZrh0/xQMrsTu2fKvp+UPzhZ/XF7MZH2Rxzz1WM+ij6+E6HO5 vzSgWIOteMsK8J335el/7z1y2eFEnn7Ql2xk4ibQ9SDhaYNn3rdNGnRx5YxXj77X2CQsS+xi40m JXU3BPJ+7q8z0ZdedmGWbJbBHxxlSC4THz+m5BKhl2keoesYlgA7CAjpes7q3m7DGzuw62yw2gt Y21C/AOIPLzh7ZOBls4BroMv2lvDW+qgoluLeuqmFpgmhi1w08gcx2PA6ivYqm5pBs++1ZkDM91 eM2CgVh19cqwf5Xxo6w== X-Proofpoint-Spam-Info: AW1haW4tMjYwODA3MDE0MyBTYWx0ZWRfXxiMHIgxPJQZ2 egPbQhruT1fii3RbSSJnN1n4qn6D1z9lWbEyDZQJ91B1+3ayo7lyHmZg0dHvLrmcE0549d1vfs4 n6H2XNhyZ6fNvQkdpcW+/YwLUgwnSt8= X-Authority-Analysis: v=2.4 cv=YJevDxGx c=1 sm=1 tr=0 ts=6a76212f cx=c_pps a=WeENfcodrlLV9YRTxbY/uA==:117 a=VPysOpcHbS0DNrM1Xqmyow==:17 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=3WHJM1ZQz_JShphwDgj5:22 a=EUspDBNiAAAA:8 a=sJeJdZliiPf9M_nNF58A:9 a=kacYvNCVWA4VmyqE58fU:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-07_03,2026-08-07_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 phishscore=0 lowpriorityscore=0 spamscore=0 clxscore=1015 suspectscore=0 priorityscore=1501 impostorscore=0 bulkscore=0 adultscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608070143 struct iommufd_sw_msi_maps currently uses a fixed 64-bit bitmap, capping the number of distinct SW MSI mappings a context or hwpt can track. An upcoming caller needs one mapping per possible CPU. Convert the fixed bitmap to a pointer plus size that grows on demand via iommufd_sw_msi_maps_ensure(). Add iommufd_sw_msi_maps_test_bit() alongside it: unlike the __set_bit() call sites, which always follow their own successful iommufd_sw_msi_maps_ensure() call on the same id, iommufd_group_setup_msi() tests an id from the fd-global sw_msi_list against a specific group's required_sw_msi map, which may not have been grown to cover that id yet. The bitmap is arbitrarily capped at 16K entries in order to simplify arithmetic validation (i.e. simple bounds checks vs. integer wrap control). Signed-off-by: Andrew Jones --- drivers/iommu/iommufd/device.c | 3 +- drivers/iommu/iommufd/driver.c | 38 +++++++++++++++-------- drivers/iommu/iommufd/hw_pagetable.c | 1 + drivers/iommu/iommufd/iommufd_private.h | 41 +++++++++++++++++++++++-- 4 files changed, 67 insertions(+), 16 deletions(-) diff --git a/drivers/iommu/iommufd/device.c b/drivers/iommu/iommufd/device.c index 170a7005f0bc..402251c7b887 100644 --- a/drivers/iommu/iommufd/device.c +++ b/drivers/iommu/iommufd/device.c @@ -34,6 +34,7 @@ static void iommufd_group_release(struct kref *kref) NULL, GFP_KERNEL); iommu_group_put(igroup->group); mutex_destroy(&igroup->lock); + kfree(igroup->required_sw_msi.bitmap); kfree(igroup); } @@ -384,7 +385,7 @@ static int iommufd_group_setup_msi(struct iommufd_group *igroup, int rc; if (cur->sw_msi_start != igroup->sw_msi_start || - !test_bit(cur->id, igroup->required_sw_msi.bitmap)) + !iommufd_sw_msi_maps_test_bit(&igroup->required_sw_msi, cur->id)) continue; rc = iommufd_sw_msi_install(ictx, hwpt_paging, cur); diff --git a/drivers/iommu/iommufd/driver.c b/drivers/iommu/iommufd/driver.c index 3b8067976eac..9b9316ae4266 100644 --- a/drivers/iommu/iommufd/driver.c +++ b/drivers/iommu/iommufd/driver.c @@ -196,13 +196,15 @@ iommufd_sw_msi_get_map(struct iommufd_ctx *ictx, phys_addr_t msi_addr, list_for_each_entry(cur, &ictx->sw_msi_list, sw_msi_item) { if (cur->sw_msi_start != sw_msi_start) continue; + if (cur->pgoff == UINT_MAX) + return ERR_PTR(-EOVERFLOW); max_pgoff = max(max_pgoff, cur->pgoff + 1); if (cur->msi_addr == msi_addr) return cur; } - if (ictx->sw_msi_id >= - BITS_PER_BYTE * sizeof_field(struct iommufd_sw_msi_maps, bitmap)) + if (ictx->sw_msi_id > IOMMUFD_SW_MSI_MAX_ID || + max_pgoff > (ULONG_MAX - sw_msi_start) / PAGE_SIZE) return ERR_PTR(-EOVERFLOW); cur = kzalloc_obj(*cur); @@ -222,21 +224,26 @@ int iommufd_sw_msi_install(struct iommufd_ctx *ictx, struct iommufd_sw_msi_map *msi_map) { unsigned long iova; + int rc; lockdep_assert_held(&ictx->sw_msi_lock); + if (iommufd_sw_msi_maps_test_bit(&hwpt_paging->present_sw_msi, + msi_map->id)) + return 0; + iova = msi_map->sw_msi_start + msi_map->pgoff * PAGE_SIZE; - if (!test_bit(msi_map->id, hwpt_paging->present_sw_msi.bitmap)) { - int rc; - - rc = iommu_map(hwpt_paging->common.domain, iova, - msi_map->msi_addr, PAGE_SIZE, - IOMMU_WRITE | IOMMU_READ | IOMMU_MMIO, - GFP_KERNEL_ACCOUNT); - if (rc) - return rc; - __set_bit(msi_map->id, hwpt_paging->present_sw_msi.bitmap); - } + rc = iommufd_sw_msi_maps_ensure(&hwpt_paging->present_sw_msi, msi_map->id); + if (rc) + return rc; + + rc = iommu_map(hwpt_paging->common.domain, iova, + msi_map->msi_addr, PAGE_SIZE, + IOMMU_WRITE | IOMMU_READ | IOMMU_MMIO, + GFP_KERNEL_ACCOUNT); + if (rc) + return rc; + __set_bit(msi_map->id, hwpt_paging->present_sw_msi.bitmap); return 0; } EXPORT_SYMBOL_NS_GPL(iommufd_sw_msi_install, "IOMMUFD_INTERNAL"); @@ -290,6 +297,11 @@ int iommufd_sw_msi(struct iommu_domain *domain, struct msi_desc *desc, if (IS_ERR(msi_map)) return PTR_ERR(msi_map); + rc = iommufd_sw_msi_maps_ensure(&handle->idev->igroup->required_sw_msi, + msi_map->id); + if (rc) + return rc; + rc = iommufd_sw_msi_install(ictx, hwpt_paging, msi_map); if (rc) return rc; diff --git a/drivers/iommu/iommufd/hw_pagetable.c b/drivers/iommu/iommufd/hw_pagetable.c index 623cc608ca0c..54873de43eb0 100644 --- a/drivers/iommu/iommufd/hw_pagetable.c +++ b/drivers/iommu/iommufd/hw_pagetable.c @@ -32,6 +32,7 @@ void iommufd_hwpt_paging_destroy(struct iommufd_object *obj) } __iommufd_hwpt_destroy(&hwpt_paging->common); + kfree(hwpt_paging->present_sw_msi.bitmap); refcount_dec(&hwpt_paging->ioas->obj.users); } diff --git a/drivers/iommu/iommufd/iommufd_private.h b/drivers/iommu/iommufd/iommufd_private.h index 43fbc5bed8de..9ca5f9f92cdf 100644 --- a/drivers/iommu/iommufd/iommufd_private.h +++ b/drivers/iommu/iommufd/iommufd_private.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -29,11 +30,47 @@ struct iommufd_sw_msi_map { unsigned int id; }; -/* Bitmap of struct iommufd_sw_msi_map::id */ +/* Bitmap of struct iommufd_sw_msi_map::id; starts empty, grows on demand. */ struct iommufd_sw_msi_maps { - DECLARE_BITMAP(bitmap, 64); + unsigned long *bitmap; + unsigned int nbits; }; +/* Large enough for foreseeable SW MSI users while bounding bitmap growth. */ +#define IOMMUFD_SW_MSI_MAX_ID (16U * 1024 - 1) + +/* Grow bitmap to accommodate id. Must be called under ictx->sw_msi_lock. */ +static inline int iommufd_sw_msi_maps_ensure(struct iommufd_sw_msi_maps *maps, + unsigned int id) +{ + unsigned long *new_bitmap; + unsigned int new_nbits; + + if (id < maps->nbits) + return 0; + if (id > IOMMUFD_SW_MSI_MAX_ID) + return -EOVERFLOW; + + new_nbits = max(ALIGN(id + 1, BITS_PER_LONG), 64U); + new_bitmap = krealloc(maps->bitmap, + BITS_TO_LONGS(new_nbits) * sizeof(unsigned long), + GFP_KERNEL_ACCOUNT); + if (!new_bitmap) + return -ENOMEM; + bitmap_clear(new_bitmap, maps->nbits, new_nbits - maps->nbits); + maps->bitmap = new_bitmap; + maps->nbits = new_nbits; + return 0; +} + +static inline bool iommufd_sw_msi_maps_test_bit(const struct iommufd_sw_msi_maps *maps, + unsigned int id) +{ + if (id >= maps->nbits) + return false; + return test_bit(id, maps->bitmap); +} + #ifdef CONFIG_IRQ_MSI_IOMMU int iommufd_sw_msi_install(struct iommufd_ctx *ictx, struct iommufd_hwpt_paging *hwpt_paging, -- 2.43.0