From 98d5110f90ae0dbc5f2f13f033e06f6d57009e0d Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Mon, 19 Jan 2026 20:19:49 -0400 Subject: [PATCH] iommupt: Make it clearer to the compiler that pts.level == 0 for single page Older versions of gcc and clang sometimes get tripped up by the build time assertion in FIELD_PREP because they can see that the argument to FIELD_PREP is constant but can't see that the if condition protecting it is also a constant false. In file included from : In function 'amdv1pt_install_leaf_entry', inlined from '__do_map_single_page' at drivers/iommu/generic_pt/fmt/../iommu_pt.h:651:3, inlined from '__map_single_page0' at drivers/iommu/generic_pt/fmt/../iommu_pt.h:662:1, inlined from 'pt_descend' at drivers/iommu/generic_pt/fmt/../pt_iter.h:391:9, inlined from '__do_map_single_page' at drivers/iommu/generic_pt/fmt/../iommu_pt.h:658:10, inlined from '__map_single_page1.constprop' at drivers/iommu/generic_pt/fmt/../iommu_pt.h:662:1: ././include/linux/compiler_types.h:631:45: error: call to '__compiletime_assert_251' declared with attribute error: FIELD_PREP: value too large for the field 631 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__) | ^ ././include/linux/compiler_types.h:612:25: note: in definition of macro '__compiletime_assert' 612 | prefix ## suffix(); \ | ^~~~~~ ././include/linux/compiler_types.h:631:9: note: in expansion of macro '_compiletime_assert' 631 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__) | ^~~~~~~~~~~~~~~~~~~ ./include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert' 39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg) | ^~~~~~~~~~~~~~~~~~ ./include/linux/bitfield.h:69:17: note: in expansion of macro 'BUILD_BUG_ON_MSG' 69 | BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ? \ | ^~~~~~~~~~~~~~~~ ./include/linux/bitfield.h:90:17: note: in expansion of macro '__BF_FIELD_CHECK_MASK' 90 | __BF_FIELD_CHECK_MASK(mask, val, pfx); \ | ^~~~~~~~~~~~~~~~~~~~~ ./include/linux/bitfield.h:137:17: note: in expansion of macro '__FIELD_PREP' 137 | __FIELD_PREP(_mask, _val, "FIELD_PREP: "); \ | ^~~~~~~~~~~~ drivers/iommu/generic_pt/fmt/amdv1.h:220:26: note: in expansion of macro 'FIELD_PREP' 220 | FIELD_PREP(AMDV1PT_FMT_OA, | ^~~~~~~~~~ Changing the caller to check pts.level == 0 avoids demanding a bit of complex reasoning from the compiler that pts.level == level == 0. Instead the compiler sees that pt_install_leaf_entry() is called with a constant pts.level == 0 which makes it more reliable to see the constant false in the if. Fixes: dcd6a011a8d5 ("iommupt: Add map_pages op") Reported-by: Chunyu Hu Closes: https://lore.kernel.org/all/aUn9uGPCooqB-RIF@gmail.com/ Signed-off-by: Jason Gunthorpe Signed-off-by: Joerg Roedel --- drivers/iommu/generic_pt/iommu_pt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iommu/generic_pt/iommu_pt.h b/drivers/iommu/generic_pt/iommu_pt.h index 3327116a441c..52ef028ed2db 100644 --- a/drivers/iommu/generic_pt/iommu_pt.h +++ b/drivers/iommu/generic_pt/iommu_pt.h @@ -645,7 +645,7 @@ static __always_inline int __do_map_single_page(struct pt_range *range, struct pt_iommu_map_args *map = arg; pts.type = pt_load_single_entry(&pts); - if (level == 0) { + if (pts.level == 0) { if (pts.type != PT_ENTRY_EMPTY) return -EADDRINUSE; pt_install_leaf_entry(&pts, map->oa, PAGE_SHIFT, -- 2.47.3