Commit aef5de75 authored by Jason Gunthorpe's avatar Jason Gunthorpe Committed by Joerg Roedel
Browse files

iommupt: Add the x86 64 bit page table format



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%.

Reviewed-by: default avatarKevin Tian <kevin.tian@intel.com>
Reviewed-by: default avatarVasant Hegde <vasant.hegde@amd.com>
Tested-by: default avatarAlejandro Jimenez <alejandro.j.jimenez@oracle.com>
Tested-by: default avatarPasha Tatashin <pasha.tatashin@soleen.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
Signed-off-by: default avatarJoerg Roedel <joerg.roedel@amd.com>
parent e93d5945
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@ CONFIG_GENERIC_PT=y
CONFIG_DEBUG_GENERIC_PT=y
CONFIG_IOMMU_PT=y
CONFIG_IOMMU_PT_AMDV1=y
CONFIG_IOMMU_PT_X86_64=y
CONFIG_IOMMU_PT_KUNIT_TEST=y

CONFIG_IOMMUFD=y
+11 −0
Original line number Diff line number Diff line
@@ -42,10 +42,21 @@ config IOMMU_PT_AMDV1

	  Selected automatically by an IOMMU driver that uses this format.

config IOMMU_PT_X86_64
	tristate "IOMMU page table for x86 64-bit, 4/5 levels"
	depends on !GENERIC_ATOMIC64 # for cmpxchg64
	help
	  iommu_domain implementation for the x86 64-bit 4/5 level page table.
	  It supports 4K/2M/1G page sizes and can decode a sign-extended
	  portion of the 64-bit IOVA space.

	  Selected automatically by an IOMMU driver that uses this format.

config IOMMU_PT_KUNIT_TEST
	tristate "IOMMU Page Table KUnit Test" if !KUNIT_ALL_TESTS
	depends on KUNIT
	depends on IOMMU_PT_AMDV1 || !IOMMU_PT_AMDV1
	depends on IOMMU_PT_X86_64 || !IOMMU_PT_X86_64
	default KUNIT_ALL_TESTS
	help
	  Enable kunit tests for GENERIC_PT and IOMMU_PT that covers all the
+2 −0
Original line number Diff line number Diff line
@@ -3,6 +3,8 @@
iommu_pt_fmt-$(CONFIG_IOMMU_PT_AMDV1) += amdv1
iommu_pt_fmt-$(CONFIG_IOMMUFD_TEST) += mock

iommu_pt_fmt-$(CONFIG_IOMMU_PT_X86_64) += x86_64

IOMMU_PT_KUNIT_TEST :=
define create_format
obj-$(2) += iommu_$(1).o
+21 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2024-2025, NVIDIA CORPORATION & AFFILIATES
 *
 */
#ifndef __GENERIC_PT_FMT_DEFS_X86_64_H
#define __GENERIC_PT_FMT_DEFS_X86_64_H

#include <linux/generic_pt/common.h>
#include <linux/types.h>

typedef u64 pt_vaddr_t;
typedef u64 pt_oaddr_t;

struct x86_64_pt_write_attrs {
	u64 descriptor_bits;
	gfp_t gfp;
};
#define pt_write_attrs x86_64_pt_write_attrs

#endif
+11 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2024-2025, NVIDIA CORPORATION & AFFILIATES
 */
#define PT_FMT x86_64
#define PT_SUPPORTED_FEATURES                                  \
	(BIT(PT_FEAT_SIGN_EXTEND) | BIT(PT_FEAT_FLUSH_RANGE) | \
	 BIT(PT_FEAT_FLUSH_RANGE_NO_GAPS) |                    \
	 BIT(PT_FEAT_X86_64_AMD_ENCRYPT_TABLES))

#include "iommu_template.h"
Loading