From nobody Sun Feb 8 03:27:05 2026 Received: from mx0a-00082601.pphosted.com (mx0b-00082601.pphosted.com [67.231.153.30]) (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 705742DECAA; Mon, 10 Nov 2025 21:11:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=67.231.153.30 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762809095; cv=none; b=UOL2D5k0AHr8GQsGXyfIzbdU3nJnR7/ipewAZ/6nDVSw17YFWx9MOpVA8IUSnB70L+jdwGHFBtFX5fZcz0wIQ76nba62hPvFoSrk5bUCbEwPwF5m72Cj9sZD1YDEKonaMs0Xve1DkgGwg17B7oLLekw7cY6+cZeivRgOYt6XeC0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762809095; c=relaxed/simple; bh=CvNCzClS3F9CeS6NlOXQoYzHdFP2wQlqK609RvrY0lE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=HpPFSa/qG+YT2CwNrHQBKmZgsebJewcacFALn2yJwRPTPcCjlCohUlDFb5yWVER99y6NkGRCo4K83wuRcEFp/3Sex9ty6wbnUu3BC+8uH23eMA+W62rDnaiDWc2eMyBpvSSOvoyufrIaai2GZSLBcpSfdQ9iYDlAJ33K0eboqq0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=fb.com; spf=pass smtp.mailfrom=meta.com; dkim=pass (2048-bit key) header.d=fb.com header.i=@fb.com header.b=vSF+kPoP; arc=none smtp.client-ip=67.231.153.30 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=fb.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=meta.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=fb.com header.i=@fb.com header.b="vSF+kPoP" Received: from pps.filterd (m0089730.ppops.net [127.0.0.1]) by m0089730.ppops.net (8.18.1.11/8.18.1.11) with ESMTP id 5AAL4UPe3887404; Mon, 10 Nov 2025 13:11:27 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fb.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=s2048-2025-q2; bh=XZrTORv8/MEDMS/mIwjcBCcw44J2F1zST6nf6nBGOFA=; b=vSF+kPoPiErQ ej8d1JA84k8znzm708wHaE5nf0tsLPz5XGCaGir/P/8KelY8GGCJPzeBP9fqsIxq aFK53979nZYPzN1i0zDAUzVTJNTYAteaqfgzbNEMlM+B1n2HWekN1VhlI3i9Cq/w 1DIs8UyYZ23T5atSMlD1cC1LYE6APEMO7GfHhZ1zGUGqhfvuKFemLStynGdhzlX/ OJMNVbSdLzixgGxIqLx9ixdUkZyV5zZcjceg9iRyqwiCjKGwG5hvEAGoqm3Cls+m oUOfPa37nFbNfwQI0CezQkGiQKk+lq5anhnWlW4pezfcC4T1s8D7mdn2CVTHbJkx kWGN78q+Tw== Received: from mail.thefacebook.com ([163.114.134.16]) by m0089730.ppops.net (PPS) with ESMTPS id 4abqn6r1sm-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Mon, 10 Nov 2025 13:11:27 -0800 (PST) Received: from devgpu015.cco6.facebook.com (2620:10d:c085:108::4) by mail.thefacebook.com (2620:10d:c08b:78::c78f) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.2.2562.20; Mon, 10 Nov 2025 21:11:25 +0000 From: Alex Mastro Date: Mon, 10 Nov 2025 13:10:41 -0800 Subject: [PATCH 1/4] vfio: selftests: add iova range query helpers Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-ID: <20251110-iova-ranges-v1-1-4d441cf5bf6d@fb.com> References: <20251110-iova-ranges-v1-0-4d441cf5bf6d@fb.com> In-Reply-To: <20251110-iova-ranges-v1-0-4d441cf5bf6d@fb.com> To: Alex Williamson , David Matlack , Shuah Khan CC: , , , Alex Mastro , Jason Gunthorpe X-Mailer: b4 0.13.0 X-Proofpoint-GUID: sC6y3rFXGFCzIc6DgSpnuzMGAHA-Upyx X-Proofpoint-ORIG-GUID: sC6y3rFXGFCzIc6DgSpnuzMGAHA-Upyx X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMTEwMDE3OSBTYWx0ZWRfXxtql15zP4Akx HKYqXNE2AtiF0yKwcJRLfugSgNTfA6a2dihdd3ulDC9F8o91uTZw8c5KzmhoZ8s9EiH9Eaf4Fxu 3TUQVXoDQStS6ph4yS5ivIj02+rRecIB5A83mWGJM9jnGMDHcVUSbV9xBfeqcsWhF8c7bx0xyly L0HRBiMtjkwJipCQz/vrRWYkBNwUvrrqUZrS1y12SV2PJgsq7y2LJtXRq7rMkj2yMTmMNS4Hxyv g888kmXkEyam8qnfMxiwy15wu3tE3I1W6NBChc0ahrfeHjlaS+d6KVStTA5McrRpHoWMeWh74mY wbcfzGSi5mdxaTK/V293lZPmvTCpf81lhNaSs690YD89xvNNZIcLnFo/fMldogft9OKRH8aag0S 3zyQou3ZLHy8JbJbgZmdCVyh5kl2YQ== X-Authority-Analysis: v=2.4 cv=Qdprf8bv c=1 sm=1 tr=0 ts=691254ff cx=c_pps a=CB4LiSf2rd0gKozIdrpkBw==:117 a=CB4LiSf2rd0gKozIdrpkBw==:17 a=IkcTkHD0fZMA:10 a=6UeiqGixMTsA:10 a=VkNPw1HP01LnGYTKEx00:22 a=FOH2dFAWAAAA:8 a=Xs3x4vty3K2JW6oWMr8A:9 a=QEXdDO2ut3YA:10 a=cPQSjfK2_nFv0Q5t_7PE:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2025-11-10_07,2025-11-10_02,2025-10-01_01 VFIO selftests need to map IOVAs from legally accessible ranges, which could vary between hardware. Tests in vfio_dma_mapping_test.c are making excessively strong assumptions about which IOVAs can be mapped. Add vfio_iommu_iova_ranges(), which queries IOVA ranges from the IOMMUFD or VFIO container associated with the device. The queried ranges are normalized to IOMMUFD's iommu_iova_range representation so that handling of IOVA ranges up the stack can be implementation-agnostic. iommu_iova_range and vfio_iova_range are equivalent, so bias to using the new interface's struct. Query IOMMUFD's ranges with IOMMU_IOAS_IOVA_RANGES. Query VFIO container's ranges with VFIO_IOMMU_GET_INFO and VFIO_IOMMU_TYPE1_INFO_CAP_IOVA_RANGE. The underlying vfio_iommu_type1_info buffer-related functionality has been kept generic so the same helpers can be used to query other capability chain information, if needed. Signed-off-by: Alex Mastro --- .../testing/selftests/vfio/lib/include/vfio_util.h | 8 +- tools/testing/selftests/vfio/lib/vfio_pci_device.c | 161 +++++++++++++++++= ++++ 2 files changed, 168 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/vfio/lib/include/vfio_util.h b/tools/t= esting/selftests/vfio/lib/include/vfio_util.h index 240409bf5f8a..fb5efec52316 100644 --- a/tools/testing/selftests/vfio/lib/include/vfio_util.h +++ b/tools/testing/selftests/vfio/lib/include/vfio_util.h @@ -4,9 +4,12 @@ =20 #include #include -#include + +#include +#include #include #include +#include =20 #include "../../../kselftest.h" =20 @@ -206,6 +209,9 @@ struct vfio_pci_device *vfio_pci_device_init(const char= *bdf, const char *iommu_ void vfio_pci_device_cleanup(struct vfio_pci_device *device); void vfio_pci_device_reset(struct vfio_pci_device *device); =20 +struct iommu_iova_range *vfio_pci_iova_ranges(struct vfio_pci_device *devi= ce, + size_t *nranges); + int __vfio_pci_dma_map(struct vfio_pci_device *device, struct vfio_dma_region *region); int __vfio_pci_dma_unmap(struct vfio_pci_device *device, diff --git a/tools/testing/selftests/vfio/lib/vfio_pci_device.c b/tools/tes= ting/selftests/vfio/lib/vfio_pci_device.c index a381fd253aa7..6bedbe65f0a1 100644 --- a/tools/testing/selftests/vfio/lib/vfio_pci_device.c +++ b/tools/testing/selftests/vfio/lib/vfio_pci_device.c @@ -29,6 +29,167 @@ VFIO_ASSERT_EQ(__ret, 0, "ioctl(%s, %s, %s) returned %d\n", #_fd, #_op, #= _arg, __ret); \ } while (0) =20 +static struct vfio_info_cap_header *next_cap_hdr(void *buf, size_t bufsz, + size_t *cap_offset) +{ + struct vfio_info_cap_header *hdr; + + if (!*cap_offset) + return NULL; + + /* Cap offset must be in bounds */ + VFIO_ASSERT_LT(*cap_offset, bufsz); + /* There must be enough remaining space to contain the header */ + VFIO_ASSERT_GE(bufsz - *cap_offset, sizeof(*hdr)); + + hdr =3D (struct vfio_info_cap_header *)((u8 *)buf + *cap_offset); + + /* If there is a next, offset must increase by at least the header size */ + if (hdr->next) { + VFIO_ASSERT_GT(hdr->next, *cap_offset); + VFIO_ASSERT_GE(hdr->next - *cap_offset, sizeof(*hdr)); + } + + *cap_offset =3D hdr->next; + + return hdr; +} + +static struct vfio_info_cap_header *vfio_iommu_info_cap_hdr(struct vfio_io= mmu_type1_info *buf, + u16 cap_id) +{ + struct vfio_info_cap_header *hdr; + size_t cap_offset =3D buf->cap_offset; + + if (!(buf->flags & VFIO_IOMMU_INFO_CAPS)) + return NULL; + + if (cap_offset) + VFIO_ASSERT_GE(cap_offset, sizeof(struct vfio_iommu_type1_info)); + + while ((hdr =3D next_cap_hdr(buf, buf->argsz, &cap_offset))) { + if (hdr->id =3D=3D cap_id) + return hdr; + } + + return NULL; +} + +/* Return buffer including capability chain, if present. Free with free() = */ +static struct vfio_iommu_type1_info *vfio_iommu_info_buf(struct vfio_pci_d= evice *device) +{ + struct vfio_iommu_type1_info *buf; + + buf =3D malloc(sizeof(*buf)); + VFIO_ASSERT_NOT_NULL(buf); + + *buf =3D (struct vfio_iommu_type1_info) { + .argsz =3D sizeof(*buf), + }; + + ioctl_assert(device->container_fd, VFIO_IOMMU_GET_INFO, buf); + + buf =3D realloc(buf, buf->argsz); + VFIO_ASSERT_NOT_NULL(buf); + + ioctl_assert(device->container_fd, VFIO_IOMMU_GET_INFO, buf); + + return buf; +} + +/* + * Return iova ranges for the device's container. Normalize vfio_iommu_typ= e1 to + * report iommufd's iommu_iova_range. Free with free(). + */ +static struct iommu_iova_range *vfio_iommu_iova_ranges(struct vfio_pci_dev= ice *device, + size_t *nranges) +{ + struct vfio_iommu_type1_info_cap_iova_range *cap_range; + struct vfio_iommu_type1_info *buf; + struct vfio_info_cap_header *hdr; + struct iommu_iova_range *ranges =3D NULL; + + buf =3D vfio_iommu_info_buf(device); + VFIO_ASSERT_NOT_NULL(buf); + + hdr =3D vfio_iommu_info_cap_hdr(buf, VFIO_IOMMU_TYPE1_INFO_CAP_IOVA_RANGE= ); + if (!hdr) + goto free_buf; + + cap_range =3D container_of(hdr, struct vfio_iommu_type1_info_cap_iova_ran= ge, header); + if (!cap_range->nr_iovas) + goto free_buf; + + ranges =3D malloc(cap_range->nr_iovas * sizeof(*ranges)); + VFIO_ASSERT_NOT_NULL(ranges); + + for (u32 i =3D 0; i < cap_range->nr_iovas; i++) { + ranges[i] =3D (struct iommu_iova_range){ + .start =3D cap_range->iova_ranges[i].start, + .last =3D cap_range->iova_ranges[i].end, + }; + } + + *nranges =3D cap_range->nr_iovas; + +free_buf: + free(buf); + return ranges; +} + +/* Return iova ranges of the device's IOAS. Free with free() */ +struct iommu_iova_range *iommufd_iova_ranges(struct vfio_pci_device *devic= e, + size_t *nranges) +{ + struct iommu_iova_range *ranges; + int ret; + + struct iommu_ioas_iova_ranges query =3D { + .size =3D sizeof(query), + .ioas_id =3D device->ioas_id, + }; + + ret =3D ioctl(device->iommufd, IOMMU_IOAS_IOVA_RANGES, &query); + VFIO_ASSERT_EQ(ret, -1); + VFIO_ASSERT_EQ(errno, EMSGSIZE); + VFIO_ASSERT_GT(query.num_iovas, 0); + + ranges =3D malloc(query.num_iovas * sizeof(*ranges)); + VFIO_ASSERT_NOT_NULL(ranges); + + query.allowed_iovas =3D (uintptr_t)ranges; + + ioctl_assert(device->iommufd, IOMMU_IOAS_IOVA_RANGES, &query); + *nranges =3D query.num_iovas; + + return ranges; +} + +struct iommu_iova_range *vfio_pci_iova_ranges(struct vfio_pci_device *devi= ce, + size_t *nranges) +{ + struct iommu_iova_range *ranges; + + if (device->iommufd) + ranges =3D iommufd_iova_ranges(device, nranges); + else + ranges =3D vfio_iommu_iova_ranges(device, nranges); + + if (!ranges) + return NULL; + + /* ranges should be valid, ascending, and non-overlapping */ + VFIO_ASSERT_GT(*nranges, 0); + VFIO_ASSERT_LT(ranges[0].start, ranges[0].last); + + for (size_t i =3D 1; i < *nranges; i++) { + VFIO_ASSERT_LT(ranges[i].start, ranges[i].last); + VFIO_ASSERT_LT(ranges[i - 1].last, ranges[i].start); + } + + return ranges; +} + iova_t __to_iova(struct vfio_pci_device *device, void *vaddr) { struct vfio_dma_region *region; --=20 2.47.3 From nobody Sun Feb 8 03:27:05 2026 Received: from mx0a-00082601.pphosted.com (mx0b-00082601.pphosted.com [67.231.153.30]) (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 1520D2F5A02; Mon, 10 Nov 2025 21:11:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=67.231.153.30 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762809095; cv=none; b=BNsvrNgQN1axG+AYZvebVVsz/nvAxTSvlzHQ/g5r75pVElYoB8Wdttx+p70ge38T5to42mTIsbh2NRDa7PbrDn4FARIbuj2eSs5wQu+rNkU+jwyi3oD2qiDyQXljg5Ha9BGi8uIT+TcHovH3IlBQ+jODmUHUVHOPu21G8OBTNzE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762809095; c=relaxed/simple; bh=NaPTNEHpV6A0u993PlaIXhUmsY18jZ4WOH4BpYu3Zp4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=MHINKHBAEnY4VjptV7Kg7RpdADWsmu9Z1IiKBzXpdlq+YHONzsAtDoRJdQ6vSJTEB0He2E/6rwYeux01sBSX7MUUQP/5WqEM1IQlmQkq2Sin10+edFnQanUGJMxFnyPDLf86Vlu98q0lPmmu2peNLrW6lkgBESwIUY1VfxT/NA0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=fb.com; spf=pass smtp.mailfrom=meta.com; dkim=pass (2048-bit key) header.d=fb.com header.i=@fb.com header.b=BW5fBngo; arc=none smtp.client-ip=67.231.153.30 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=fb.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=meta.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=fb.com header.i=@fb.com header.b="BW5fBngo" Received: from pps.filterd (m0089730.ppops.net [127.0.0.1]) by m0089730.ppops.net (8.18.1.11/8.18.1.11) with ESMTP id 5AAL4UPf3887404; Mon, 10 Nov 2025 13:11:27 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fb.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=s2048-2025-q2; bh=kXIomevZxcHatDoppWvHoctejlEdcrJSBgRRuUN+8rA=; b=BW5fBngo0q9t j4EryAe+KtqLn5BfwMKimUn/Khy9Kg+taT3JOq0pvVXzFLG59IIq9ow5ctCCa2u8 eVDznCuKbtRJD5pAd8vSWz9zqornQishkmLFgZYHvVbzY2KfSR8TdjqQGVqla0jK gB7BbHnGsaQyqljtumI6UGpIVsFZI+i+mdB7gdPttV1UZJS4GVG9ihVWLKJJ31Xe TKarByoUza+FShcjrp/MzXqwopknHhEYYCGOB61i6hAhaPwT4xeCwJZvhRUyfg6J enJMnplrh7soCxI5JgjdcVZDP2+PRxU7YUme8Gif2jfQh3Akc6ubRo1z3hj0VC2/ INPsVbWhxg== Received: from mail.thefacebook.com ([163.114.134.16]) by m0089730.ppops.net (PPS) with ESMTPS id 4abqn6r1sm-3 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Mon, 10 Nov 2025 13:11:27 -0800 (PST) Received: from devgpu015.cco6.facebook.com (2620:10d:c085:108::4) by mail.thefacebook.com (2620:10d:c08b:78::c78f) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.2.2562.20; Mon, 10 Nov 2025 21:11:25 +0000 From: Alex Mastro Date: Mon, 10 Nov 2025 13:10:42 -0800 Subject: [PATCH 2/4] vfio: selftests: fix map limit tests to use last available iova Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-ID: <20251110-iova-ranges-v1-2-4d441cf5bf6d@fb.com> References: <20251110-iova-ranges-v1-0-4d441cf5bf6d@fb.com> In-Reply-To: <20251110-iova-ranges-v1-0-4d441cf5bf6d@fb.com> To: Alex Williamson , David Matlack , Shuah Khan CC: , , , Alex Mastro , Jason Gunthorpe X-Mailer: b4 0.13.0 X-Proofpoint-GUID: 38qHkLTYQuudBznWeH22BTDbfBxzTEsr X-Proofpoint-ORIG-GUID: 38qHkLTYQuudBznWeH22BTDbfBxzTEsr X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMTEwMDE3OSBTYWx0ZWRfXxBsPC1t0w+G8 OymGgB+QoaIOCDK0Mp134dqYtMhKoDpEllgK9jWLG7f7dJRtlXhz5GL9RJCuTBXHUag/iaqqSgf X+UASP64SLncGpwYc8VkUpbnTjB8GM7Z+W/5ESt8pKxzKdfrhZJhNec2Yd7Aq4+7sz49xEj6VOS 1wGlnVcniI1UxTuLu/kIglSV/LWyu+i0Al8vFmST1FY23F3DIbP60yKw1Ty+c2sGAq08A8TMkw1 0YRYEI1IRsRwh0GAtGZ6oi/l29Y9f66IRolycldHT5ghYLCBpds1MvUOO42uRq+q1tqinhRPYTM P9+8GoiCdBCSehuS1SbkU76VqjgRKOD4UOoaGjK+axWUMoYPExwbVwHXH2tDA8xl9YbNzOi5Uyg 2d5CHpO8/DB6CX9C48MlL50/fodWvA== X-Authority-Analysis: v=2.4 cv=Qdprf8bv c=1 sm=1 tr=0 ts=691254ff cx=c_pps a=CB4LiSf2rd0gKozIdrpkBw==:117 a=CB4LiSf2rd0gKozIdrpkBw==:17 a=IkcTkHD0fZMA:10 a=6UeiqGixMTsA:10 a=VkNPw1HP01LnGYTKEx00:22 a=FOH2dFAWAAAA:8 a=2r72hCCS2uxvEu3KRW0A:9 a=QEXdDO2ut3YA:10 a=cPQSjfK2_nFv0Q5t_7PE:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2025-11-10_07,2025-11-10_02,2025-10-01_01 Use the newly available vfio_pci_iova_ranges() to determine the last legal IOVA, and use this as the basis for vfio_dma_map_limit_test tests. Fixes: de8d1f2fd5a5 ("vfio: selftests: add end of address space DMA map/unm= ap tests") Signed-off-by: Alex Mastro --- tools/testing/selftests/vfio/vfio_dma_mapping_test.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/vfio/vfio_dma_mapping_test.c b/tools/t= esting/selftests/vfio/vfio_dma_mapping_test.c index 4f1ea79a200c..37c2a342df8d 100644 --- a/tools/testing/selftests/vfio/vfio_dma_mapping_test.c +++ b/tools/testing/selftests/vfio/vfio_dma_mapping_test.c @@ -3,6 +3,8 @@ #include #include =20 +#include +#include #include #include #include @@ -219,7 +221,10 @@ FIXTURE_VARIANT_ADD_ALL_IOMMU_MODES(); FIXTURE_SETUP(vfio_dma_map_limit_test) { struct vfio_dma_region *region =3D &self->region; + struct iommu_iova_range *ranges; u64 region_size =3D getpagesize(); + iova_t last_iova; + size_t nranges; =20 /* * Over-allocate mmap by double the size to provide enough backing vaddr @@ -232,8 +237,13 @@ FIXTURE_SETUP(vfio_dma_map_limit_test) MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); ASSERT_NE(region->vaddr, MAP_FAILED); =20 - /* One page prior to the end of address space */ - region->iova =3D ~(iova_t)0 & ~(region_size - 1); + ranges =3D vfio_pci_iova_ranges(self->device, &nranges); + VFIO_ASSERT_NOT_NULL(ranges); + last_iova =3D ranges[nranges - 1].last; + free(ranges); + + /* One page prior to the last iova */ + region->iova =3D last_iova & ~(region_size - 1); region->size =3D region_size; } =20 @@ -276,6 +286,9 @@ TEST_F(vfio_dma_map_limit_test, overflow) struct vfio_dma_region *region =3D &self->region; int rc; =20 + if (region->iova !=3D (~(iova_t)0 & ~(region->size - 1))) + SKIP(return, "IOMMU address space insufficient for overflow test"); + region->size =3D self->mmap_size; =20 rc =3D __vfio_pci_dma_map(self->device, region); --=20 2.47.3 From nobody Sun Feb 8 03:27:05 2026 Received: from mx0a-00082601.pphosted.com (mx0b-00082601.pphosted.com [67.231.153.30]) (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 152DB2F5A1F; Mon, 10 Nov 2025 21:11:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=67.231.153.30 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762809095; cv=none; b=a8w/ncTDd/IvBbPDCg5phhlzM6vPHYZsnrk24v1dTbo1rM3B2SfLIVwEsQn0HEUNMjx5ULKoblktJeYemwWiv2l4QhD4F08aa9hPvAJ4RiVLH5DYvQEk1GetpSz+hds7d/tWBiz5BpaMSn75TnEVPXT4+a537rvWy0qKDW0SmRM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762809095; c=relaxed/simple; bh=36NNZlWGkPqCNufWdxA9yUezYpCxoNIBRntN9pC5+hQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=Z0XioFvDOB+HWOw//lWnjKfjElcBwtdnRBoeKF9+Q/dxnE7r/GkiLsk0VKHNbEHQAYb39IaxQnDi0BXZDbeBt5AgeuozBPxV0mwezcUIDctyA8UN/N7ivitR3szmJ7gzmZDVfJekcuzASHLC3gxiZ7v8XWuVVypjlPY6tQ1WrNo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=fb.com; spf=pass smtp.mailfrom=meta.com; dkim=pass (2048-bit key) header.d=fb.com header.i=@fb.com header.b=mpL81Co3; arc=none smtp.client-ip=67.231.153.30 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=fb.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=meta.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=fb.com header.i=@fb.com header.b="mpL81Co3" Received: from pps.filterd (m0089730.ppops.net [127.0.0.1]) by m0089730.ppops.net (8.18.1.11/8.18.1.11) with ESMTP id 5AAL4UPg3887404; Mon, 10 Nov 2025 13:11:28 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fb.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=s2048-2025-q2; bh=P2DpALUQ2j1bmgnVxYT9lAMyxIqAk0TLgtPOAA7vWjY=; b=mpL81Co3CD1K 1EysnhjCRkvXcxgbnbWMWOfp5s6cbAFApbPBhvOSK2Vsl9ur4b/pcY7XKfzEV37e X+uFFE4FULytYEWNO+UM/RqAk53H55em/8Vi6OX0G1+NX5mxi65TUrkmPO1mFVwv 6WWWN/g2aORdlxyM5dV5EkUksCZHEyFNW2MwGEoBSGot8JTCZNy6nKtELtLr+Sbl 2GgS9rfcfqwYdvQPB705im6HWIYaO4Ih5/0IItacVXDowxi1XUvJQKGw7skn0SLE aC3oq2NDPxDvK/1D5xZAAYgqq3OhXgsCVbKEP6tcT/EPqlsvTtsLOc8cjo/t4cJd pE5RBKHbrA== Received: from mail.thefacebook.com ([163.114.134.16]) by m0089730.ppops.net (PPS) with ESMTPS id 4abqn6r1sm-4 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Mon, 10 Nov 2025 13:11:28 -0800 (PST) Received: from devgpu015.cco6.facebook.com (2620:10d:c085:108::4) by mail.thefacebook.com (2620:10d:c08b:78::c78f) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.2.2562.20; Mon, 10 Nov 2025 21:11:26 +0000 From: Alex Mastro Date: Mon, 10 Nov 2025 13:10:43 -0800 Subject: [PATCH 3/4] vfio: selftests: add iova allocator Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-ID: <20251110-iova-ranges-v1-3-4d441cf5bf6d@fb.com> References: <20251110-iova-ranges-v1-0-4d441cf5bf6d@fb.com> In-Reply-To: <20251110-iova-ranges-v1-0-4d441cf5bf6d@fb.com> To: Alex Williamson , David Matlack , Shuah Khan CC: , , , Alex Mastro , Jason Gunthorpe X-Mailer: b4 0.13.0 X-Proofpoint-GUID: 4aXobMbUOICBgbezd9ts0KbkJ1TXMpW5 X-Proofpoint-ORIG-GUID: 4aXobMbUOICBgbezd9ts0KbkJ1TXMpW5 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMTEwMDE3OSBTYWx0ZWRfX7DXWx3a7dXsD gjSBWUWTJmozlPqAwjTmZtIWAQUTcRnFDHGV8QSc+o/PxioZVuUNoM9Nqos4k5GbL5W0gcsfwkv h5YrXG5mjLeeZvMZ3uPH/gRgnVjIN2Haj185XSMREHEAkPdxHIBNWNTs7VBl650jY0YEt+e0O3M jvm5wIA+G07SJQB68dV5YyEEaMB95B5oy1dAjuiOf6a6eIrUqeBbM84TZPwVu1o/KDkIq9WSGYp VkSWMrVhLyP2B4xoF6HbRSbC/3ElBnnaTKLFe/2OWj7EJz4tHWb1sZNFUAQFcAYLWojRS1CpAWZ +YdER1FOH3iAHZt6ZjC9mbKvUUWbmmZZCLiIT7dq03RbG3r2qnC9R9ZwVB91Q2ZZhWuJGVSuh2q DreZfdlGdHrqxeehmkcPXfj+CRhR+Q== X-Authority-Analysis: v=2.4 cv=Qdprf8bv c=1 sm=1 tr=0 ts=69125500 cx=c_pps a=CB4LiSf2rd0gKozIdrpkBw==:117 a=CB4LiSf2rd0gKozIdrpkBw==:17 a=IkcTkHD0fZMA:10 a=6UeiqGixMTsA:10 a=VkNPw1HP01LnGYTKEx00:22 a=VwQbUJbxAAAA:8 a=r1p2_3pzAAAA:8 a=FOH2dFAWAAAA:8 a=MOGvrfbzQFtMZxHpfkcA:9 a=QEXdDO2ut3YA:10 a=r_pkcD-q9-ctt7trBg_g:22 a=cPQSjfK2_nFv0Q5t_7PE:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2025-11-10_07,2025-11-10_02,2025-10-01_01 Add struct iova_allocator, which gives tests a convenient way to generate legally-accessible IOVAs to map. This is based on Alex Williamson's patch series for adding an IOVA allocator [1]. [1] https://lore.kernel.org/all/20251108212954.26477-1-alex@shazbot.org/ Signed-off-by: Alex Mastro --- .../testing/selftests/vfio/lib/include/vfio_util.h | 14 +++++ tools/testing/selftests/vfio/lib/vfio_pci_device.c | 65 ++++++++++++++++++= +++- 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/vfio/lib/include/vfio_util.h b/tools/t= esting/selftests/vfio/lib/include/vfio_util.h index fb5efec52316..bb1e7d39dfb9 100644 --- a/tools/testing/selftests/vfio/lib/include/vfio_util.h +++ b/tools/testing/selftests/vfio/lib/include/vfio_util.h @@ -13,6 +13,8 @@ =20 #include "../../../kselftest.h" =20 +#define ALIGN(x, a) (((x) + (a - 1)) & (~((a) - 1))) + #define VFIO_LOG_AND_EXIT(...) do { \ fprintf(stderr, " " __VA_ARGS__); \ fprintf(stderr, "\n"); \ @@ -188,6 +190,13 @@ struct vfio_pci_device { struct vfio_pci_driver driver; }; =20 +struct iova_allocator { + struct iommu_iova_range *ranges; + size_t nranges; + size_t range_idx; + iova_t iova_next; +}; + /* * Return the BDF string of the device that the test should use. * @@ -212,6 +221,11 @@ void vfio_pci_device_reset(struct vfio_pci_device *dev= ice); struct iommu_iova_range *vfio_pci_iova_ranges(struct vfio_pci_device *devi= ce, size_t *nranges); =20 +int iova_allocator_init(struct vfio_pci_device *device, + struct iova_allocator *allocator); +void iova_allocator_deinit(struct iova_allocator *allocator); +iova_t iova_allocator_alloc(struct iova_allocator *allocator, size_t size); + int __vfio_pci_dma_map(struct vfio_pci_device *device, struct vfio_dma_region *region); int __vfio_pci_dma_unmap(struct vfio_pci_device *device, diff --git a/tools/testing/selftests/vfio/lib/vfio_pci_device.c b/tools/tes= ting/selftests/vfio/lib/vfio_pci_device.c index 6bedbe65f0a1..a634feb1d378 100644 --- a/tools/testing/selftests/vfio/lib/vfio_pci_device.c +++ b/tools/testing/selftests/vfio/lib/vfio_pci_device.c @@ -12,11 +12,12 @@ #include =20 #include +#include #include #include +#include #include #include -#include =20 #include "../../../kselftest.h" #include @@ -190,6 +191,68 @@ struct iommu_iova_range *vfio_pci_iova_ranges(struct v= fio_pci_device *device, return ranges; } =20 +int iova_allocator_init(struct vfio_pci_device *device, + struct iova_allocator *allocator) +{ + struct iommu_iova_range *ranges; + size_t nranges; + + memset(allocator, 0, sizeof(*allocator)); + + ranges =3D vfio_pci_iova_ranges(device, &nranges); + if (!ranges) + return -ENOENT; + + *allocator =3D (struct iova_allocator){ + .ranges =3D ranges, + .nranges =3D nranges, + .range_idx =3D 0, + .iova_next =3D 0, + }; + + return 0; +} + +void iova_allocator_deinit(struct iova_allocator *allocator) +{ + free(allocator->ranges); +} + +iova_t iova_allocator_alloc(struct iova_allocator *allocator, size_t size) +{ + int idx =3D allocator->range_idx; + struct iommu_iova_range *range =3D &allocator->ranges[idx]; + + VFIO_ASSERT_LT(idx, allocator->nranges, "IOVA allocator out of space\n"); + VFIO_ASSERT_GT(size, 0, "Invalid size arg, zero\n"); + VFIO_ASSERT_EQ(size & (size - 1), 0, "Invalid size arg, non-power-of-2\n"= ); + + for (;;) { + iova_t iova, last; + + iova =3D ALIGN(allocator->iova_next, size); + + if (iova < allocator->iova_next || iova > range->last || + check_add_overflow(iova, size - 1, &last) || + last > range->last) { + allocator->range_idx =3D ++idx; + VFIO_ASSERT_LT(idx, allocator->nranges, + "Out of ranges for allocation\n"); + allocator->iova_next =3D (++range)->start; + continue; + } + + if (check_add_overflow(last, (iova_t)1, &allocator->iova_next) || + allocator->iova_next > range->last) { + allocator->range_idx =3D ++idx; + if (idx < allocator->nranges) + allocator->iova_next =3D (++range)->start; + } + + return iova; + } +} + iova_t __to_iova(struct vfio_pci_device *device, void *vaddr) { struct vfio_dma_region *region; --=20 2.47.3 From nobody Sun Feb 8 03:27:05 2026 Received: from mx0a-00082601.pphosted.com (mx0b-00082601.pphosted.com [67.231.153.30]) (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 6769A2F5A28; Mon, 10 Nov 2025 21:11:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=67.231.153.30 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762809095; cv=none; b=in4ec17bcDM+hxkswQE1nn9tn5DaLvkaS2qHh/y/UfR94bCd/sPSEThE2+2TuKki/v096PKUv/Hkeu3kSAUfcVo/i5sbD0B5FJI2rk8Rfd0K5i4NUn54oX2zsKWWx3oJycdYWiSG3AzV8SrwGkCqlDlkL6BXc40VSj7SYbHa2ME= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762809095; c=relaxed/simple; bh=kr7TNcA6znn4hBDQw09hIZoDi92UBEe1+B+3Ft72+sk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=oWiNbw1TeiWy+hn6Qce3OYaZaQMLyES+Qwrsgk8LCcecQJ++/RiDhKCO6b86D9rhKhUSMQcjCDwJiJzVYVvs8Z/HzXrq4lZosYQSMXPUux+CmNT+d8z8bn5h8qs0mbHBPHoMsNY8ZLlGn36Cq3Pyait1IsOXoX5dw6dBNT7sp0M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=fb.com; spf=pass smtp.mailfrom=meta.com; dkim=pass (2048-bit key) header.d=fb.com header.i=@fb.com header.b=BJYhiOwb; arc=none smtp.client-ip=67.231.153.30 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=fb.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=meta.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=fb.com header.i=@fb.com header.b="BJYhiOwb" Received: from pps.filterd (m0089730.ppops.net [127.0.0.1]) by m0089730.ppops.net (8.18.1.11/8.18.1.11) with ESMTP id 5AAL4UPh3887404; Mon, 10 Nov 2025 13:11:28 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fb.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=s2048-2025-q2; bh=Gs0ephI9j2wqu8FIW7DJqlGCeZ/KcGtqWuvPSKl7wyw=; b=BJYhiOwbisGq EcprymVaYGXx88vaJvSuXQBNVtF/75l5Wj8tB6HYqTXmVr88vVYlBcEb9v3LTHpa 3fmhO6lYHmUCQ8ltjoIhSUysIqHFjpPV/H9VXEg2EVkjDxiDwQjXQUZNoWjnpNwo PJkiJOF+JPfDJTy0AcubXBRQA7xwBeyAkhVIf3jHwr/ybFd+z4cjxMsB3zYEZ9DD YXfC84TP4cjMPN/H9u3Y9qqmuhN9JGPSZgvOrjgLG3rbEQh1oHFDnvkzvslrm9zV gGR9AACBd0rT9zIjGQKY9MktBYfL2zlzRbayQYO9+VE4wYc+0StKsyVvDnnM8K6Z KRmrGfBpoA== Received: from mail.thefacebook.com ([163.114.134.16]) by m0089730.ppops.net (PPS) with ESMTPS id 4abqn6r1sm-5 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Mon, 10 Nov 2025 13:11:28 -0800 (PST) Received: from devgpu015.cco6.facebook.com (2620:10d:c085:108::4) by mail.thefacebook.com (2620:10d:c08b:78::c78f) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.2.2562.20; Mon, 10 Nov 2025 21:11:26 +0000 From: Alex Mastro Date: Mon, 10 Nov 2025 13:10:44 -0800 Subject: [PATCH 4/4] vfio: selftests: update vfio_dma_mapping_test to allocate iovas Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-ID: <20251110-iova-ranges-v1-4-4d441cf5bf6d@fb.com> References: <20251110-iova-ranges-v1-0-4d441cf5bf6d@fb.com> In-Reply-To: <20251110-iova-ranges-v1-0-4d441cf5bf6d@fb.com> To: Alex Williamson , David Matlack , Shuah Khan CC: , , , Alex Mastro , Jason Gunthorpe X-Mailer: b4 0.13.0 X-Proofpoint-GUID: lvdlIAQToOLsUDI4LVfhZfEaKiyuBaFI X-Proofpoint-ORIG-GUID: lvdlIAQToOLsUDI4LVfhZfEaKiyuBaFI X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMTEwMDE3OSBTYWx0ZWRfX3XmhX0h2FzJI KwEmpcu9VCHb64N4RZsZW486KzxhXPieNsDukT/A+ZN/pnTJGMVqyO4YnTg1ivP0iW8ZmCCJAw9 JbVJ4bvTA4TAOrMlxCjEwvmHFGxkeH/e7aCkQqrxzv8D1g42qlCO5K2gq7GPQI223DpWR45A049 /Y+GJK5OcrmjMB2+aBAPizixpNPOhKkO45EAGgRP99Gq5M4n1dfFvKSlzRypjBxf53wwV9HA825 nFtmqKfHEII1LAblY/SaxVXIG7E5PqKEJeOZk8KHW0Fi6yZFNTOnp/IEOzaj77gms1FRN8RtbZM Tj0koy95wC5S+R66k/glX/vZwws+x/0+QivsagFw61gcXT79uIMYY6BQXu924u8DXHQEltKZeAs H4h5nW+Razf6d7qG4sq59L88sD11hQ== X-Authority-Analysis: v=2.4 cv=Qdprf8bv c=1 sm=1 tr=0 ts=69125500 cx=c_pps a=CB4LiSf2rd0gKozIdrpkBw==:117 a=CB4LiSf2rd0gKozIdrpkBw==:17 a=IkcTkHD0fZMA:10 a=6UeiqGixMTsA:10 a=VkNPw1HP01LnGYTKEx00:22 a=FOH2dFAWAAAA:8 a=GKGmy9NU5bqHy5LlMbcA:9 a=QEXdDO2ut3YA:10 a=cPQSjfK2_nFv0Q5t_7PE:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2025-11-10_07,2025-11-10_02,2025-10-01_01 vfio_dma_mapping_test currently uses iova=3Dvaddr as part of DMA mapping validation. The assumption that these IOVAs are legal has held up on all the hardware we've tested so far, but but is not guaranteed. Make the test more robust by using iova_allocator to vend IOVAs, which queries legally accessible IOVAs from the underlying IOMMUFD or VFIO container. Signed-off-by: Alex Mastro --- tools/testing/selftests/vfio/vfio_dma_mapping_test.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/vfio/vfio_dma_mapping_test.c b/tools/t= esting/selftests/vfio/vfio_dma_mapping_test.c index 37c2a342df8d..c1a015385b0f 100644 --- a/tools/testing/selftests/vfio/vfio_dma_mapping_test.c +++ b/tools/testing/selftests/vfio/vfio_dma_mapping_test.c @@ -95,6 +95,7 @@ static int iommu_mapping_get(const char *bdf, u64 iova, =20 FIXTURE(vfio_dma_mapping_test) { struct vfio_pci_device *device; + struct iova_allocator iova_allocator; }; =20 FIXTURE_VARIANT(vfio_dma_mapping_test) { @@ -118,11 +119,16 @@ FIXTURE_VARIANT_ADD_ALL_IOMMU_MODES(anonymous_hugetlb= _1gb, SZ_1G, MAP_HUGETLB | =20 FIXTURE_SETUP(vfio_dma_mapping_test) { + int ret; + self->device =3D vfio_pci_device_init(device_bdf, variant->iommu_mode); + ret =3D iova_allocator_init(self->device, &self->iova_allocator); + VFIO_ASSERT_EQ(ret, 0); } =20 FIXTURE_TEARDOWN(vfio_dma_mapping_test) { + iova_allocator_deinit(&self->iova_allocator); vfio_pci_device_cleanup(self->device); } =20 @@ -144,7 +150,7 @@ TEST_F(vfio_dma_mapping_test, dma_map_unmap) else ASSERT_NE(region.vaddr, MAP_FAILED); =20 - region.iova =3D (u64)region.vaddr; + region.iova =3D iova_allocator_alloc(&self->iova_allocator, size); region.size =3D size; =20 vfio_pci_dma_map(self->device, ®ion); --=20 2.47.3