]> Gentwo Git Trees - linux/.git/commitdiff
Merge branches 'arm/smmu/updates', 'arm/smmu/bindings', 'mediatek', 'nvidia/tegra...
authorJoerg Roedel <joerg.roedel@amd.com>
Fri, 28 Nov 2025 07:44:21 +0000 (08:44 +0100)
committerJoerg Roedel <joerg.roedel@amd.com>
Fri, 28 Nov 2025 07:44:21 +0000 (08:44 +0100)
1  2  3  4  5  6  7  8 
.mailmap
MAINTAINERS
drivers/iommu/Kconfig
drivers/iommu/amd/amd_iommu_types.h
drivers/iommu/amd/iommu.c
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
drivers/iommu/intel/Kconfig
drivers/iommu/intel/iommu.h
drivers/iommu/mtk_iommu.c
tools/testing/selftests/iommu/iommufd.c
tools/testing/selftests/iommu/iommufd_utils.h

diff --cc .mailmap
Simple merge
diff --cc MAINTAINERS
Simple merge
Simple merge
Simple merge
index 2e1865daa1cee87aedd759063a19f1f5f31951e6,2e1865daa1cee87aedd759063a19f1f5f31951e6,2e1865daa1cee87aedd759063a19f1f5f31951e6,2e1865daa1cee87aedd759063a19f1f5f31951e6,2e1865daa1cee87aedd759063a19f1f5f31951e6,2e1865daa1cee87aedd759063a19f1f5f31951e6,a5fb6af4fd2d6aded4f92d8231c7e5d7018a412f,273951b4501cd571115af9a4024542a44619a216..9f1d56a5e145fe798c09f6065dd44a38e07e591d
@@@@@@@@@ -2500,29 -2500,29 -2500,29 -2500,29 -2500,29 -2500,29 -2526,29 -2489,66 +2515,66 @@@@@@@@@ struct protection_domain *protection_do
                return domain;
        }
        
------- static int pdom_setup_pgtable(struct protection_domain *domain,
-------                               struct device *dev)
+++++++ static bool amd_iommu_hd_support(struct amd_iommu *iommu)
++++++  {
      -         struct io_pgtable_ops *pgtbl_ops;
      -         enum io_pgtable_fmt fmt;
+++++++         if (amd_iommu_hatdis)
+++++++                 return false;
++++++  
      -         switch (domain->pd_mode) {
      -         case PD_MODE_V1:
      -                 fmt = AMD_IOMMU_V1;
      -                 break;
      -         case PD_MODE_V2:
      -                 fmt = AMD_IOMMU_V2;
      -                 break;
      -         case PD_MODE_NONE:
      -                 WARN_ON_ONCE(1);
      -                 return -EPERM;
+++++++         return iommu && (iommu->features & FEATURE_HDSUP);
+++++++ }
+++++++ 
+++++++ static spinlock_t *amd_iommu_get_top_lock(struct pt_iommu *iommupt)
      + {
------          struct io_pgtable_ops *pgtbl_ops;
------          enum io_pgtable_fmt fmt;
+++++++         struct protection_domain *pdom =
+++++++                 container_of(iommupt, struct protection_domain, iommu);
      + 
------          switch (domain->pd_mode) {
------          case PD_MODE_V1:
------                  fmt = AMD_IOMMU_V1;
------                  break;
------          case PD_MODE_V2:
------                  fmt = AMD_IOMMU_V2;
------                  break;
------          case PD_MODE_NONE:
------                  WARN_ON_ONCE(1);
------                  return -EPERM;
+++++++         return &pdom->lock;
+++++++ }
+++++++ 
+++++++ /*
+++++++  * Update all HW references to the domain with a new pgtable configuration.
+++++++  */
+++++++ static void amd_iommu_change_top(struct pt_iommu *iommu_table,
+++++++                                  phys_addr_t top_paddr, unsigned int top_level)
+++++++ {
+++++++         struct protection_domain *pdom =
+++++++                 container_of(iommu_table, struct protection_domain, iommu);
+++++++         struct iommu_dev_data *dev_data;
+++++++ 
+++++++         lockdep_assert_held(&pdom->lock);
+++++++ 
+++++++         /* Update the DTE for all devices attached to this domain */
+++++++         list_for_each_entry(dev_data, &pdom->dev_list, list) {
+++++++                 struct amd_iommu *iommu = rlookup_amd_iommu(dev_data->dev);
+++++++ 
+++++++                 /* Update the HW references with the new level and top ptr */
+++++++                 set_dte_entry(iommu, dev_data, top_paddr, top_level);
+++++++                 clone_aliases(iommu, dev_data->dev);
                }
        
-------         domain->iop.pgtbl.cfg.amd.nid = dev_to_node(dev);
-------         pgtbl_ops = alloc_io_pgtable_ops(fmt, &domain->iop.pgtbl.cfg, domain);
-------         if (!pgtbl_ops)
-------                 return -ENOMEM;
+++++++         list_for_each_entry(dev_data, &pdom->dev_list, list)
+++++++                 device_flush_dte(dev_data);
+++++++ 
+++++++         domain_flush_complete(pdom);
+++++++ }
++++++  
+++++++ /*
+++++++  * amd_iommu_iotlb_sync_map() is used to generate flushes for non-present to
+++++++  * present (ie mapping) operations. It is a NOP if the IOMMU doesn't have non
+++++++  * present caching (like hypervisor shadowing).
+++++++  */
+++++++ static int amd_iommu_iotlb_sync_map(struct iommu_domain *dom,
+++++++                                     unsigned long iova, size_t size)
+++++++ {
+++++++         struct protection_domain *domain = to_pdomain(dom);
+++++++         unsigned long flags;
      + 
+++++++         if (likely(!amd_iommu_np_cache))
+++++++                 return 0;
+++++++ 
+++++++         spin_lock_irqsave(&domain->lock, flags);
+++++++         amd_iommu_domain_flush_pages(domain, iova, size);
+++++++         spin_unlock_irqrestore(&domain->lock, flags);
                return 0;
        }
        
@@@@@@@@@ -2577,17 -2577,17 -2577,17 -2577,17 -2577,17 -2577,17 -2603,17 -2650,79 +2676,79 @@@@@@@@@ static struct iommu_domain *amd_iommu_d
                        return ERR_PTR(ret);
                }
        
-------         domain->domain.geometry.aperture_start = 0;
-------         domain->domain.geometry.aperture_end   = dma_max_address(pgtable);
-------         domain->domain.geometry.force_aperture = true;
-------         domain->domain.pgsize_bitmap = domain->iop.pgtbl.cfg.pgsize_bitmap;
+++++++         /*
+++++++          * Narrow the supported page sizes to those selected by the kernel
+++++++          * command line.
+++++++          */
+++++++         domain->domain.pgsize_bitmap &= amd_iommu_pgsize_bitmap;
+++++++         return &domain->domain;
+++++++ }
      + 
------          domain->domain.type = IOMMU_DOMAIN_UNMANAGED;
------          domain->domain.ops = iommu->iommu.ops->default_domain_ops;
+++++++ static const struct iommu_domain_ops amdv2_ops = {
+++++++         IOMMU_PT_DOMAIN_OPS(x86_64),
+++++++         .iotlb_sync_map = amd_iommu_iotlb_sync_map,
+++++++         .flush_iotlb_all = amd_iommu_flush_iotlb_all,
+++++++         .iotlb_sync = amd_iommu_iotlb_sync,
+++++++         .attach_dev = amd_iommu_attach_device,
+++++++         .free = amd_iommu_domain_free,
+++++++         /*
+++++++          * Note the AMDv2 page table format does not support a Force Coherency
+++++++          * bit, so enforce_cache_coherency should not be set. However VFIO is
+++++++          * not prepared to handle a case where some domains will support
+++++++          * enforcement and others do not. VFIO and iommufd will have to be fixed
+++++++          * before it can fully use the V2 page table. See the comment in
+++++++          * iommufd_hwpt_paging_alloc(). For now leave things as they have
+++++++          * historically been and lie about enforce_cache_coherencey.
+++++++          */
+++++++         .enforce_cache_coherency = amd_iommu_enforce_cache_coherency,
+++++++ };
        
------          if (dirty_tracking)
------                  domain->domain.dirty_ops = &amd_dirty_ops;
      -         domain->domain.type = IOMMU_DOMAIN_UNMANAGED;
      -         domain->domain.ops = iommu->iommu.ops->default_domain_ops;
+++++++ static struct iommu_domain *amd_iommu_domain_alloc_paging_v2(struct device *dev,
+++++++                                                              u32 flags)
+++++++ {
+++++++         struct pt_iommu_x86_64_cfg cfg = {};
+++++++         struct protection_domain *domain;
+++++++         int ret;
        
      -         if (dirty_tracking)
      -                 domain->domain.dirty_ops = &amd_dirty_ops;
+++++++         if (!amd_iommu_v2_pgtbl_supported())
+++++++                 return ERR_PTR(-EOPNOTSUPP);
++++++  
+++++++         domain = protection_domain_alloc();
+++++++         if (!domain)
+++++++                 return ERR_PTR(-ENOMEM);
+++++++ 
+++++++         domain->pd_mode = PD_MODE_V2;
+++++++         domain->iommu.nid = dev_to_node(dev);
+++++++ 
+++++++         cfg.common.features = BIT(PT_FEAT_X86_64_AMD_ENCRYPT_TABLES);
+++++++         if (amd_iommu_np_cache)
+++++++                 cfg.common.features |= BIT(PT_FEAT_FLUSH_RANGE_NO_GAPS);
+++++++         else
+++++++                 cfg.common.features |= BIT(PT_FEAT_FLUSH_RANGE);
+++++++ 
+++++++         /*
+++++++          * The v2 table behaves differently if it is attached to PASID 0 vs a
+++++++          * non-zero PASID. On PASID 0 it has no sign extension and the full
+++++++          * 57/48 bits decode the lower addresses. Otherwise it behaves like a
+++++++          * normal sign extended x86 page table. Since we want the domain to work
+++++++          * in both modes the top bit is removed and PT_FEAT_SIGN_EXTEND is not
+++++++          * set which creates a table that is compatible in both modes.
+++++++          */
+++++++         if (amd_iommu_gpt_level == PAGE_MODE_5_LEVEL) {
+++++++                 cfg.common.hw_max_vasz_lg2 = 56;
+++++++                 cfg.top_level = 4;
+++++++         } else {
+++++++                 cfg.common.hw_max_vasz_lg2 = 47;
+++++++                 cfg.top_level = 3;
+++++++         }
+++++++         cfg.common.hw_max_oasz_lg2 = 52;
+++++++         domain->domain.ops = &amdv2_ops;
+++++++ 
+++++++         ret = pt_iommu_x86_64_init(&domain->amdv2, &cfg, GFP_KERNEL);
+++++++         if (ret) {
+++++++                 amd_iommu_domain_free(&domain->domain);
+++++++                 return ERR_PTR(ret);
+++++++         }
                return &domain->domain;
        }
        
Simple merge
Simple merge
Simple merge