]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
iommu_pt: Fix pgsize_bitmap calculation in get_info for smaller vasz's
authorAnkit Soni <Ankit.Soni@amd.com>
Mon, 13 Apr 2026 14:45:18 +0000 (14:45 +0000)
committerJoerg Roedel <joerg.roedel@amd.com>
Tue, 19 May 2026 08:49:02 +0000 (10:49 +0200)
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 <jgg@nvidia.com>
Signed-off-by: Ankit Soni <Ankit.Soni@amd.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
drivers/iommu/generic_pt/iommu_pt.h
drivers/iommu/generic_pt/kunit_generic_pt.h

index 19b6daf88f2ab1a277b86613f8179c56c6954c7c..1765986e24e82ac3b9efce892269492491f836b8 100644 (file)
@@ -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)
index 374e475f591e15b0b8015ed07a3288046354ef10..ef2c90b6d6af303c7221208f73babfec51da9a52 100644 (file)
@@ -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)