On 10/23/2025 11:50 PM, Jason Gunthorpe wrote: > This is used by x86 CPUs and can be used in AMD/VT-d x86 IOMMUs. When a > x86 IOMMU is running SVA the MM will be using this format. > > This implementation follows the AMD v2 io-pgtable version. > > There is nothing remarkable here, the format can have 4 or 5 levels and > limited support for different page sizes. No contiguous pages support. > > x86 uses a sign extension mechanism where the top bits of the VA must > match the sign bit. The core code supports this through > PT_FEAT_SIGN_EXTEND which creates and upper and lower VA range. All the > new operations will work correctly in both spaces, however currently there > is no way to report the upper space to other layers. Future patches can > improve that. > > In principle this can support 3 page tables levels matching the 32 bit PAE > table format, but no iommu driver needs this. The focus is on the modern > 64 bit 4 and 5 level formats. > > Comparing the performance of several operations to the existing version: > > iommu_map() > pgsz ,avg new,old ns, min new,old ns , min % (+ve is better) > 2^12, 71,61 , 66,58 , -13.13 > 2^21, 66,60 , 61,55 , -10.10 > 2^30, 59,56 , 56,54 , -3.03 > 256*2^12, 392,1360 , 345,1289 , 73.73 > 256*2^21, 383,1159 , 335,1145 , 70.70 > 256*2^30, 378,965 , 331,892 , 62.62 > > iommu_unmap() > pgsz ,avg new,old ns, min new,old ns , min % (+ve is better) > 2^12, 77,71 , 73,68 , -7.07 > 2^21, 76,70 , 70,66 , -6.06 > 2^30, 69,66 , 66,63 , -4.04 > 256*2^12, 225,899 , 210,870 , 75.75 > 256*2^21, 262,722 , 248,710 , 65.65 > 256*2^30, 251,643 , 244,634 , 61.61 > > The small -ve values in the iommu_unmap() are due to the core code calling > iommu_pgsize() before invoking the domain op. This is unncessary with this > implementation. Future work optimizes this and gets to 2%, 4%, 3%. > > Tested-by: Alejandro Jimenez <[email protected]> > Reviewed-by: Kevin Tian <[email protected]> > Signed-off-by: Jason Gunthorpe <[email protected]>
Reviewed-by: Vasant Hegde <[email protected]> > --- > drivers/iommu/generic_pt/.kunitconfig | 1 + > drivers/iommu/generic_pt/Kconfig | 11 + > drivers/iommu/generic_pt/fmt/Makefile | 2 + > drivers/iommu/generic_pt/fmt/defs_x86_64.h | 21 ++ > drivers/iommu/generic_pt/fmt/iommu_x86_64.c | 11 + > drivers/iommu/generic_pt/fmt/x86_64.h | 259 ++++++++++++++++++++ > include/linux/generic_pt/common.h | 13 + > include/linux/generic_pt/iommu.h | 11 + > 8 files changed, 329 insertions(+) > create mode 100644 drivers/iommu/generic_pt/fmt/defs_x86_64.h > create mode 100644 drivers/iommu/generic_pt/fmt/iommu_x86_64.c > create mode 100644 drivers/iommu/generic_pt/fmt/x86_64.h > .../... > + > +/* Shared descriptor bits */ > +enum { > + X86_64_FMT_P = BIT(0), > + X86_64_FMT_RW = BIT(1), > + X86_64_FMT_U = BIT(2), > + X86_64_FMT_A = BIT(5), > + X86_64_FMT_D = BIT(6), > + X86_64_FMT_OA = GENMASK_ULL(51, 12), > + X86_64_FMT_XD = BIT_ULL(63), > +}; > + > +/* PDPTE/PDE */ > +enum { > + X86_64_FMT_PS = BIT(7), > +}; > + > +#define common_to_x86_64_pt(common_ptr) \ > + container_of_const(common_ptr, struct pt_x86_64, common) > +#define to_x86_64_pt(pts) common_to_x86_64_pt((pts)->range->common) Unused macros? -Vasant
