From: Ankit Soni Date: Mon, 13 Apr 2026 14:45:18 +0000 (+0000) Subject: iommu_pt: Fix pgsize_bitmap calculation in get_info for smaller vasz's X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=04f1f4bf30b8b00e9eca7143dea094ccc2ec478e;p=thirdparty%2Fkernel%2Flinux.git iommu_pt: Fix pgsize_bitmap calculation in get_info for smaller vasz's To properly enforce the domain VA limit, clamp pgsize_bitmap using the requested max_vasz_lg2 in get_info(). Apply the same VA limit as get_info() in the kunit possible_sizes test so assertions stay consistent with the domain bitmap. Suggested-by: Jason Gunthorpe Signed-off-by: Ankit Soni Reviewed-by: Jason Gunthorpe Signed-off-by: Joerg Roedel --- diff --git a/drivers/iommu/generic_pt/iommu_pt.h b/drivers/iommu/generic_pt/iommu_pt.h index 19b6daf88f2ab..1765986e24e82 100644 --- a/drivers/iommu/generic_pt/iommu_pt.h +++ b/drivers/iommu/generic_pt/iommu_pt.h @@ -1102,8 +1102,12 @@ static void NS(get_info)(struct pt_iommu *iommu_table, pgsize_bitmap |= pt_possible_sizes(&pts); } - /* Hide page sizes larger than the maximum OA */ - info->pgsize_bitmap = oalog2_mod(pgsize_bitmap, common->max_oasz_lg2); + /* + * Hide page sizes larger than the maximum. -1 because a whole table + * pgsize is not allowed + */ + info->pgsize_bitmap = log2_mod(pgsize_bitmap, common->max_vasz_lg2 - 1); + info->pgsize_bitmap = oalog2_mod(info->pgsize_bitmap, common->max_oasz_lg2); } static void NS(deinit)(struct pt_iommu *iommu_table) diff --git a/drivers/iommu/generic_pt/kunit_generic_pt.h b/drivers/iommu/generic_pt/kunit_generic_pt.h index 374e475f591e1..ef2c90b6d6af3 100644 --- a/drivers/iommu/generic_pt/kunit_generic_pt.h +++ b/drivers/iommu/generic_pt/kunit_generic_pt.h @@ -438,6 +438,9 @@ static void test_lvl_possible_sizes(struct kunit *test, struct pt_state *pts, { unsigned int num_items_lg2 = safe_pt_num_items_lg2(pts); pt_vaddr_t pgsize_bitmap = pt_possible_sizes(pts); + /* Matches get_info() */ + pt_vaddr_t limited_pgsize_bitmap = + log2_mod(pgsize_bitmap, pts->range->common->max_vasz_lg2 - 1); unsigned int isz_lg2 = pt_table_item_lg2sz(pts); if (!pt_can_have_leaf(pts)) { @@ -448,7 +451,8 @@ static void test_lvl_possible_sizes(struct kunit *test, struct pt_state *pts, /* No bits for sizes that would be outside this table */ KUNIT_ASSERT_EQ(test, log2_mod(pgsize_bitmap, isz_lg2), 0); KUNIT_ASSERT_EQ( - test, fvalog2_div(pgsize_bitmap, num_items_lg2 + isz_lg2), 0); + test, + fvalog2_div(limited_pgsize_bitmap, num_items_lg2 + isz_lg2), 0); /* * Non contiguous must be supported. AMDv1 has a HW bug where it does @@ -463,8 +467,8 @@ static void test_lvl_possible_sizes(struct kunit *test, struct pt_state *pts, /* A contiguous entry should not span the whole table */ if (num_items_lg2 + isz_lg2 != PT_VADDR_MAX_LG2) KUNIT_ASSERT_FALSE( - test, - pgsize_bitmap & log2_to_int(num_items_lg2 + isz_lg2)); + test, limited_pgsize_bitmap & + log2_to_int(num_items_lg2 + isz_lg2)); } static void test_entry_possible_sizes(struct kunit *test)