[PATCH] drviers/iommu/amd: support P2P access through IOMMU when SME is enabled

Wencheng Yang posted 1 patch 1 year ago
There is a newer version of this series
drivers/iommu/amd/amd_iommu_types.h | 7 ++++---
drivers/iommu/amd/io_pgtable.c      | 2 ++
drivers/iommu/amd/io_pgtable_v2.c   | 4 +++-
drivers/iommu/amd/iommu.c           | 2 ++
4 files changed, 11 insertions(+), 4 deletions(-)
[PATCH] drviers/iommu/amd: support P2P access through IOMMU when SME is enabled
Posted by Wencheng Yang 1 year ago
When SME is enabled, SME bit is set in IOMMU page table pte entry,
it works fine if the pfn of the pte entry is memory. However, if
the pfn is MMIO address, for example, map other device's mmio
space to its io page table, in such situation, setting SME bit
in pte would cause P2P failure.

Clear SME bit in io page table if the mapping is MMIO rather
than memory.

Signed-off-by: Wencheng Yang <east.moutain.yang@gmail.com>
---
 drivers/iommu/amd/amd_iommu_types.h | 7 ++++---
 drivers/iommu/amd/io_pgtable.c      | 2 ++
 drivers/iommu/amd/io_pgtable_v2.c   | 4 +++-
 drivers/iommu/amd/iommu.c           | 2 ++
 4 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/amd/amd_iommu_types.h b/drivers/iommu/amd/amd_iommu_types.h
index fdb0357e0bb9..b0f055200cf3 100644
--- a/drivers/iommu/amd/amd_iommu_types.h
+++ b/drivers/iommu/amd/amd_iommu_types.h
@@ -434,9 +434,10 @@
 #define IOMMU_PTE_PAGE(pte) (iommu_phys_to_virt((pte) & IOMMU_PAGE_MASK))
 #define IOMMU_PTE_MODE(pte) (((pte) >> 9) & 0x07)
 
-#define IOMMU_PROT_MASK 0x03
-#define IOMMU_PROT_IR 0x01
-#define IOMMU_PROT_IW 0x02
+#define IOMMU_PROT_MASK 0x07
+#define IOMMU_PROT_IR   0x01
+#define IOMMU_PROT_IW   0x02
+#define IOMMU_PROT_MMIO 0x04
 
 #define IOMMU_UNITY_MAP_FLAG_EXCL_RANGE	(1 << 2)
 
diff --git a/drivers/iommu/amd/io_pgtable.c b/drivers/iommu/amd/io_pgtable.c
index f3399087859f..204f497f0b88 100644
--- a/drivers/iommu/amd/io_pgtable.c
+++ b/drivers/iommu/amd/io_pgtable.c
@@ -373,6 +373,8 @@ static int iommu_v1_map_pages(struct io_pgtable_ops *ops, unsigned long iova,
 			__pte |= IOMMU_PTE_IR;
 		if (prot & IOMMU_PROT_IW)
 			__pte |= IOMMU_PTE_IW;
+		if (prot & IOMMU_PROT_MMIO)
+			__pte |= __sme_clr(__pte);
 
 		for (i = 0; i < count; ++i)
 			pte[i] = __pte;
diff --git a/drivers/iommu/amd/io_pgtable_v2.c b/drivers/iommu/amd/io_pgtable_v2.c
index c616de2c5926..a03db2d2390e 100644
--- a/drivers/iommu/amd/io_pgtable_v2.c
+++ b/drivers/iommu/amd/io_pgtable_v2.c
@@ -65,7 +65,9 @@ static u64 set_pte_attr(u64 paddr, u64 pg_size, int prot)
 {
 	u64 pte;
 
-	pte = __sme_set(paddr & PM_ADDR_MASK);
+	if (!(prot & IOMMU_PROT_MMIO))
+		pte = __sme_set(paddr & PM_ADDR_MASK);
+
 	pte |= IOMMU_PAGE_PRESENT | IOMMU_PAGE_USER;
 	pte |= IOMMU_PAGE_ACCESS | IOMMU_PAGE_DIRTY;
 
diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index 16f40b8000d7..9194ad681504 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -2578,6 +2578,8 @@ static int amd_iommu_map_pages(struct iommu_domain *dom, unsigned long iova,
 		prot |= IOMMU_PROT_IR;
 	if (iommu_prot & IOMMU_WRITE)
 		prot |= IOMMU_PROT_IW;
+	if (iommu_prot & IOMMU_MMIO)
+		prot |= IOMMU_PROT_MMIO;
 
 	if (ops->map_pages) {
 		ret = ops->map_pages(ops, iova, paddr, pgsize,
-- 
2.43.0
Re: [PATCH] drviers/iommu/amd: support P2P access through IOMMU when SME is enabled
Posted by kernel test robot 1 year ago
Hi Wencheng,

kernel test robot noticed the following build warnings:

[auto build test WARNING on arm-perf/for-next/perf]
[also build test WARNING on linus/master joro-iommu/next v6.13-rc6 next-20250110]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Wencheng-Yang/drviers-iommu-amd-support-P2P-access-through-IOMMU-when-SME-is-enabled/20250110-210948
base:   https://git.kernel.org/pub/scm/linux/kernel/git/will/linux.git for-next/perf
patch link:    https://lore.kernel.org/r/20250110130756.333265-1-east.moutain.yang%40gmail.com
patch subject: [PATCH] drviers/iommu/amd: support P2P access through IOMMU when SME is enabled
config: x86_64-buildonly-randconfig-001-20250111 (https://download.01.org/0day-ci/archive/20250111/202501111847.N7CwntR4-lkp@intel.com/config)
compiler: clang version 19.1.3 (https://github.com/llvm/llvm-project ab51eccf88f5321e7c60591c5546b254b6afab99)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250111/202501111847.N7CwntR4-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202501111847.N7CwntR4-lkp@intel.com/

All warnings (new ones prefixed by >>):

   In file included from drivers/iommu/amd/io_pgtable_v2.c:14:
   In file included from include/linux/io-pgtable.h:6:
   In file included from include/linux/iommu.h:10:
   In file included from include/linux/scatterlist.h:8:
   In file included from include/linux/mm.h:2223:
   include/linux/vmstat.h:518:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion]
     518 |         return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
         |                               ~~~~~~~~~~~ ^ ~~~
>> drivers/iommu/amd/io_pgtable_v2.c:68:6: warning: variable 'pte' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized]
      68 |         if (!(prot & IOMMU_PROT_MMIO))
         |             ^~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/iommu/amd/io_pgtable_v2.c:71:2: note: uninitialized use occurs here
      71 |         pte |= IOMMU_PAGE_PRESENT | IOMMU_PAGE_USER;
         |         ^~~
   drivers/iommu/amd/io_pgtable_v2.c:68:2: note: remove the 'if' if its condition is always true
      68 |         if (!(prot & IOMMU_PROT_MMIO))
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      69 |                 pte = __sme_set(paddr & PM_ADDR_MASK);
   drivers/iommu/amd/io_pgtable_v2.c:66:9: note: initialize the variable 'pte' to silence this warning
      66 |         u64 pte;
         |                ^
         |                 = 0
   2 warnings generated.


vim +68 drivers/iommu/amd/io_pgtable_v2.c

    63	
    64	static u64 set_pte_attr(u64 paddr, u64 pg_size, int prot)
    65	{
    66		u64 pte;
    67	
  > 68		if (!(prot & IOMMU_PROT_MMIO))
    69			pte = __sme_set(paddr & PM_ADDR_MASK);
    70	
    71		pte |= IOMMU_PAGE_PRESENT | IOMMU_PAGE_USER;
    72		pte |= IOMMU_PAGE_ACCESS | IOMMU_PAGE_DIRTY;
    73	
    74		if (prot & IOMMU_PROT_IW)
    75			pte |= IOMMU_PAGE_RW;
    76	
    77		/* Large page */
    78		if (pg_size == IOMMU_PAGE_SIZE_1G || pg_size == IOMMU_PAGE_SIZE_2M)
    79			pte |= IOMMU_PAGE_PSE;
    80	
    81		return pte;
    82	}
    83	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki