On Thu, Oct 23, 2025 at 11:21 AM Jason Gunthorpe <[email protected]> wrote: > > The iommufd self test uses an xarray to store the pfns and their orders to > emulate a page table. Slightly modify the amdv1 page table to create a > real page table that has similar properties: > > - 2k base granule to simulate something like a 4k page table on a 64K > PAGE_SIZE ARM system > - Contiguous page support for every PFN order > - Dirty tracking > > AMDv1 is the closest format, as it is the only one that already supports > every page size. Tweak it to have only 5 levels and an 11 bit base granule > and compile it separately as a format variant. > > Tested-by: Alejandro Jimenez <[email protected]> > Reviewed-by: Kevin Tian <[email protected]> > Signed-off-by: Jason Gunthorpe <[email protected]> > --- > drivers/iommu/generic_pt/fmt/Makefile | 1 + > drivers/iommu/generic_pt/fmt/amdv1.h | 18 ++++++++++++++++-- > drivers/iommu/generic_pt/fmt/iommu_mock.c | 10 ++++++++++ > include/linux/generic_pt/iommu.h | 6 ++++++ > 4 files changed, 33 insertions(+), 2 deletions(-) > create mode 100644 drivers/iommu/generic_pt/fmt/iommu_mock.c > > diff --git a/drivers/iommu/generic_pt/fmt/Makefile > b/drivers/iommu/generic_pt/fmt/Makefile > index 32f3956c7509f8..f0c22cf5f7bee6 100644 > --- a/drivers/iommu/generic_pt/fmt/Makefile > +++ b/drivers/iommu/generic_pt/fmt/Makefile > @@ -1,6 +1,7 @@ > # SPDX-License-Identifier: GPL-2.0 > > iommu_pt_fmt-$(CONFIG_IOMMU_PT_AMDV1) += amdv1 > +iommu_pt_fmt-$(CONFIG_IOMMUFD_TEST) += mock > > IOMMU_PT_KUNIT_TEST := > define create_format > diff --git a/drivers/iommu/generic_pt/fmt/amdv1.h > b/drivers/iommu/generic_pt/fmt/amdv1.h > index 706a70c8603017..81ced24585ff93 100644 > --- a/drivers/iommu/generic_pt/fmt/amdv1.h > +++ b/drivers/iommu/generic_pt/fmt/amdv1.h > @@ -26,11 +26,23 @@ > #include <linux/string.h> > > enum { > - PT_MAX_OUTPUT_ADDRESS_LG2 = 52, > - PT_MAX_VA_ADDRESS_LG2 = 64, > PT_ITEM_WORD_SIZE = sizeof(u64), > + /* > + * The IOMMUFD selftest uses the AMDv1 format with some alterations It > + * uses a 2k page size to test cases where the CPU page size is not > the > + * same. > + */ > +#ifdef AMDV1_IOMMUFD_SELFTEST > + PT_MAX_VA_ADDRESS_LG2 = 56, > + PT_MAX_OUTPUT_ADDRESS_LG2 = 51, > + PT_MAX_TOP_LEVEL = 4, > + PT_GRANULE_LG2SZ = 11, > +#else > + PT_MAX_VA_ADDRESS_LG2 = 64, > + PT_MAX_OUTPUT_ADDRESS_LG2 = 52, > PT_MAX_TOP_LEVEL = 5, > PT_GRANULE_LG2SZ = 12, > +#endif > PT_TABLEMEM_LG2SZ = 12, > > /* The DTE only has these bits for the top phyiscal address */ > @@ -378,6 +390,7 @@ static inline int amdv1pt_iommu_fmt_init(struct > pt_iommu_amdv1 *iommu_table, > } > #define pt_iommu_fmt_init amdv1pt_iommu_fmt_init > > +#ifndef PT_FMT_VARIANT > static inline void > amdv1pt_iommu_fmt_hw_info(struct pt_iommu_amdv1 *table, > const struct pt_range *top_range, > @@ -388,6 +401,7 @@ amdv1pt_iommu_fmt_hw_info(struct pt_iommu_amdv1 *table, > info->mode = top_range->top_level + 1; > } > #define pt_iommu_fmt_hw_info amdv1pt_iommu_fmt_hw_info > +#endif > > #if defined(GENERIC_PT_KUNIT) > static const struct pt_iommu_amdv1_cfg amdv1_kunit_fmt_cfgs[] = { > diff --git a/drivers/iommu/generic_pt/fmt/iommu_mock.c > b/drivers/iommu/generic_pt/fmt/iommu_mock.c > new file mode 100644 > index 00000000000000..74e597cba9d9cd > --- /dev/null > +++ b/drivers/iommu/generic_pt/fmt/iommu_mock.c > @@ -0,0 +1,10 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * Copyright (c) 2024-2025, NVIDIA CORPORATION & AFFILIATES > + */ > +#define AMDV1_IOMMUFD_SELFTEST 1 > +#define PT_FMT amdv1 > +#define PT_FMT_VARIANT mock > +#define PT_SUPPORTED_FEATURES 0 > + > +#include "iommu_template.h" > diff --git a/include/linux/generic_pt/iommu.h > b/include/linux/generic_pt/iommu.h > index 03a906fbe12a83..848a5fb76272a9 100644 > --- a/include/linux/generic_pt/iommu.h > +++ b/include/linux/generic_pt/iommu.h > @@ -237,6 +237,12 @@ struct pt_iommu_amdv1_hw_info { > > IOMMU_FORMAT(amdv1, amdpt); > > +/* amdv1_mock is used by the iommufd selftest */ > +#define pt_iommu_amdv1_mock pt_iommu_amdv1 > +#define pt_iommu_amdv1_mock_cfg pt_iommu_amdv1_cfg > +struct pt_iommu_amdv1_mock_hw_info; > +IOMMU_PROTOTYPES(amdv1_mock); > + > #undef IOMMU_PROTOTYPES > #undef IOMMU_FORMAT > #endif > -- > 2.43.0 > >
Reviewed-by: Samiullah Khawaja <[email protected]>
