diff --git a/drivers/iommu/generic_pt/pt_fmt_defaults.h 
b/drivers/iommu/generic_pt/pt_fmt_defaults.h
new file mode 100644
index 00000000000000..19e8f820c1dccf
--- /dev/null
+++ b/drivers/iommu/generic_pt/pt_fmt_defaults.h
@@ -0,0 +1,193 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024-2025, NVIDIA CORPORATION & AFFILIATES
+ *
+ * Default definitions for formats that don't define these functions.
+ */
+#ifndef __GENERIC_PT_PT_FMT_DEFAULTS_H
+#define __GENERIC_PT_PT_FMT_DEFAULTS_H
+
+#include "pt_defs.h"
+#include <linux/log2.h>
+
+/* Header self-compile default defines */
+#ifndef pt_load_entry_raw
+#include "fmt/amdv1.h"
+#endif
+
+/*
+ * The format must provide PT_GRANULE_LG2SZ, PT_TABLEMEM_LG2SZ, and
+ * PT_ITEM_WORD_SIZE. They must be the same at every level excluding the top.
+ */
+#ifndef pt_table_item_lg2sz
+static inline unsigned int pt_table_item_lg2sz(const struct pt_state *pts)
+{
+       return PT_GRANULE_LG2SZ +
+              (PT_TABLEMEM_LG2SZ - ilog2(PT_ITEM_WORD_SIZE)) * pts->level;
+}
+#endif
+
+#ifndef pt_pgsz_lg2_to_level
+static inline unsigned int pt_pgsz_lg2_to_level(struct pt_common *common,
+                                               unsigned int pgsize_lg2)
+{
+       return (pgsize_lg2 - PT_GRANULE_LG2SZ) /
+              (PT_TABLEMEM_LG2SZ - ilog2(PT_ITEM_WORD_SIZE));
+       return 0;

this return is dead code.

+}
+#endif
+
[snip]
+/**
+ * pt_compute_best_pgsize() - Determine the best page size for leaf entries
+ * @pgsz_bitmap: Permitted page sizes
+ * @va: Starting virtual address for the leaf entry
+ * @last_va: Last virtual address for the leaf entry, sets the max page size
+ * @oa: Starting output address for the leaf entry
+ *
+ * Compute the largest page size for va, last_va, and oa together and return it
+ * in lg2. The largest page size depends on the format's supported page sizes 
at
+ * this level, and the relative alignment of the VA and OA addresses. 0 means
+ * the OA cannot be stored with the provided pgsz_bitmap.
+ */
+static inline unsigned int pt_compute_best_pgsize(pt_vaddr_t pgsz_bitmap,
+                                                 pt_vaddr_t va,
+                                                 pt_vaddr_t last_va,
+                                                 pt_oaddr_t oa)
+{
+       unsigned int best_pgsz_lg2;
+       unsigned int pgsz_lg2;
+       pt_vaddr_t len = last_va - va + 1;
+       pt_vaddr_t mask;
+
+       if (PT_WARN_ON(va >= last_va))
+               return 0;
+
+       /*
+        * Given a VA/OA pair the best page size is the largest page side

largest page side or largest page size

+        * where:
+        *
+        * 1) VA and OA start at the page. Bitwise this is the count of least
+        *    significant 0 bits.
+        *    This also implies that last_va/oa has the same prefix as va/oa.
+        */
+       mask = va | oa;
+
+       /*
+        * 2) The page size is not larger than the last_va (length). Since page
+        *    sizes are always power of two this can't be larger than the
+        *    largest power of two factor of the length.
+        */
+       mask |= log2_to_int(log2_fls(len) - 1);
+
+       best_pgsz_lg2 = log2_ffs(mask);
+
+       /* Choose the higest bit <= best_pgsz_lg2 */

higest -> highest

+       if (best_pgsz_lg2 < PT_VADDR_MAX_LG2 - 1)
+               pgsz_bitmap = log2_mod(pgsz_bitmap, best_pgsz_lg2 + 1);
+
+       pgsz_lg2 = log2_fls(pgsz_bitmap);
+       if (!pgsz_lg2)
+               return 0;
+
+       pgsz_lg2--;
+
+       PT_WARN_ON(log2_mod(va, pgsz_lg2) != 0);
+       PT_WARN_ON(oalog2_mod(oa, pgsz_lg2) != 0);
+       PT_WARN_ON(va + log2_to_int(pgsz_lg2) - 1 > last_va);
+       PT_WARN_ON(!log2_div_eq(va, va + log2_to_int(pgsz_lg2) - 1, pgsz_lg2));
+       PT_WARN_ON(
+               !oalog2_div_eq(oa, oa + log2_to_int(pgsz_lg2) - 1, pgsz_lg2));
+       return pgsz_lg2;
+}


Thanks,
Alok

Reply via email to