Merge tag 'iommu-updates-v6.4' of git://git.kernel.org/pub/scm/linux/kernel/git/joro...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 30 Apr 2023 20:00:38 +0000 (13:00 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 30 Apr 2023 20:00:38 +0000 (13:00 -0700)
Pull iommu updates from Joerg Roedel:

 - Convert to platform remove callback returning void

 - Extend changing default domain to normal group

 - Intel VT-d updates:
     - Remove VT-d virtual command interface and IOASID
     - Allow the VT-d driver to support non-PRI IOPF
     - Remove PASID supervisor request support
     - Various small and misc cleanups

 - ARM SMMU updates:
     - Device-tree binding updates:
         * Allow Qualcomm GPU SMMUs to accept relevant clock properties
         * Document Qualcomm 8550 SoC as implementing an MMU-500
         * Favour new "qcom,smmu-500" binding for Adreno SMMUs

     - Fix S2CR quirk detection on non-architectural Qualcomm SMMU
       implementations

     - Acknowledge SMMUv3 PRI queue overflow when consuming events

     - Document (in a comment) why ATS is disabled for bypass streams

 - AMD IOMMU updates:
     - 5-level page-table support
     - NUMA awareness for memory allocations

 - Unisoc driver: Support for reattaching an existing domain

 - Rockchip driver: Add missing set_platform_dma_ops callback

 - Mediatek driver: Adjust the dma-ranges

 - Various other small fixes and cleanups

* tag 'iommu-updates-v6.4' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu: (82 commits)
  iommu: Remove iommu_group_get_by_id()
  iommu: Make iommu_release_device() static
  iommu/vt-d: Remove BUG_ON in dmar_insert_dev_scope()
  iommu/vt-d: Remove a useless BUG_ON(dev->is_virtfn)
  iommu/vt-d: Remove BUG_ON in map/unmap()
  iommu/vt-d: Remove BUG_ON when domain->pgd is NULL
  iommu/vt-d: Remove BUG_ON in handling iotlb cache invalidation
  iommu/vt-d: Remove BUG_ON on checking valid pfn range
  iommu/vt-d: Make size of operands same in bitwise operations
  iommu/vt-d: Remove PASID supervisor request support
  iommu/vt-d: Use non-privileged mode for all PASIDs
  iommu/vt-d: Remove extern from function prototypes
  iommu/vt-d: Do not use GFP_ATOMIC when not needed
  iommu/vt-d: Remove unnecessary checks in iopf disabling path
  iommu/vt-d: Move PRI handling to IOPF feature path
  iommu/vt-d: Move pfsid and ats_qdep calculation to device probe path
  iommu/vt-d: Move iopf code from SVA to IOPF enabling path
  iommu/vt-d: Allow SVA with device-specific IOPF
  dmaengine: idxd: Add enable/disable device IOPF feature
  arm64: dts: mt8186: Add dma-ranges for the parent "soc" node
  ...

15 files changed:
1  2 
Documentation/arch/x86/sva.rst
arch/arm64/boot/dts/mediatek/mt8186.dtsi
arch/arm64/boot/dts/mediatek/mt8195.dtsi
arch/x86/kernel/process_64.c
arch/x86/kernel/traps.c
drivers/iommu/intel/Kconfig
drivers/iommu/iommu-sva.c
drivers/iommu/iommu.c
drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c
drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc_drv.c
include/linux/iommu.h
include/linux/sched/mm.h
kernel/fork.c
mm/init-mm.c

Simple merge
index 223b223f713ff1dac8afbb572f62aa988d1a6747,bb65a68b4b49968c6d33ea9324b37c3a242e1458..3d181c16a2f67fb5f93dc221d7583b145f576578
@@@ -39,6 -39,6 +39,7 @@@
  #include <linux/io.h>
  #include <linux/ftrace.h>
  #include <linux/syscalls.h>
++#include <linux/iommu.h>
  
  #include <asm/processor.h>
  #include <asm/pkru.h>
Simple merge
index 12e1e90fdae138647eab7c004e080fc34fa5da5b,12e1e90fdae138647eab7c004e080fc34fa5da5b..2e56bd79f589d30c2787e695b5c93750fcb480e0
@@@ -18,7 -18,7 +18,6 @@@ config INTEL_IOMM
        select NEED_DMA_MAP_STATE
        select DMAR_TABLE
        select SWIOTLB
--      select IOASID
        select PCI_ATS
        select PCI_PRI
        select PCI_PASID
index dd76a1a09cf708ce7f92ed8396531e0d20ec89d2,c434b95dc8ebb1fd65f308df50a8b192331f65f3..9821bc44f5ac1d4d5e85175f57963081734464fe
  #include "iommu-sva.h"
  
  static DEFINE_MUTEX(iommu_sva_lock);
- static DECLARE_IOASID_SET(iommu_sva_pasid);
+ static DEFINE_IDA(iommu_global_pasid_ida);
  
- /**
-  * iommu_sva_alloc_pasid - Allocate a PASID for the mm
-  * @mm: the mm
-  * @min: minimum PASID value (inclusive)
-  * @max: maximum PASID value (inclusive)
-  *
-  * Try to allocate a PASID for this mm, or take a reference to the existing one
-  * provided it fits within the [@min, @max] range. On success the PASID is
-  * available in mm->pasid and will be available for the lifetime of the mm.
-  *
-  * Returns 0 on success and < 0 on error.
-  */
- int iommu_sva_alloc_pasid(struct mm_struct *mm, ioasid_t min, ioasid_t max)
+ /* Allocate a PASID for the mm within range (inclusive) */
+ static int iommu_sva_alloc_pasid(struct mm_struct *mm, ioasid_t min, ioasid_t max)
  {
        int ret = 0;
-       ioasid_t pasid;
  
-       if (min == INVALID_IOASID || max == INVALID_IOASID ||
 -      if (!pasid_valid(min) || !pasid_valid(max) ||
++      if (min == IOMMU_PASID_INVALID ||
++          max == IOMMU_PASID_INVALID ||
            min == 0 || max < min)
                return -EINVAL;
  
 +      if (!arch_pgtable_dma_compat(mm))
 +              return -EBUSY;
 +
        mutex_lock(&iommu_sva_lock);
        /* Is a PASID already associated with this mm? */
 -      if (pasid_valid(mm->pasid)) {
 +      if (mm_valid_pasid(mm)) {
-               if (mm->pasid < min || mm->pasid >= max)
+               if (mm->pasid < min || mm->pasid > max)
                        ret = -EOVERFLOW;
                goto out;
        }
@@@ -242,3 -205,11 +210,11 @@@ out_put_mm
  
        return status;
  }
 -      if (likely(!pasid_valid(mm->pasid)))
+ void mm_pasid_drop(struct mm_struct *mm)
+ {
++      if (likely(!mm_valid_pasid(mm)))
+               return;
+       ida_free(&iommu_global_pasid_ida, mm->pasid);
+ }
index 807c98de40d4f681045ef03af4e0f805642350a3,153a3dab568c63a75bb71f6830b85846a1e59992..f1dcfa3f1a1b48ab8a48bb6976f524e3dc4c29e0
@@@ -88,9 -87,10 +88,10 @@@ static const char * const iommu_group_r
  
  static int iommu_bus_notifier(struct notifier_block *nb,
                              unsigned long action, void *data);
+ static void iommu_release_device(struct device *dev);
  static int iommu_alloc_default_domain(struct iommu_group *group,
                                      struct device *dev);
 -static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus,
 +static struct iommu_domain *__iommu_domain_alloc(const struct bus_type *bus,
                                                 unsigned type);
  static int __iommu_attach_device(struct iommu_domain *domain,
                                 struct device *dev);
index 0fd4e6734d5b255b629531a45395f2db0f887ea8,7dbdd13d7ce046eee0af5f2d9bcad26fbbb00411..e8c9a7da1060969a0c9ab1f9311e223bf9df3c96
@@@ -455,12 -455,11 +455,11 @@@ static inline const struct iommu_ops *d
        return dev->iommu->iommu_dev->ops;
  }
  
 -extern int bus_iommu_probe(struct bus_type *bus);
 -extern bool iommu_present(struct bus_type *bus);
 +extern int bus_iommu_probe(const struct bus_type *bus);
 +extern bool iommu_present(const struct bus_type *bus);
  extern bool device_iommu_capable(struct device *dev, enum iommu_cap cap);
  extern bool iommu_group_has_isolated_msi(struct iommu_group *group);
 -extern struct iommu_domain *iommu_domain_alloc(struct bus_type *bus);
 +extern struct iommu_domain *iommu_domain_alloc(const struct bus_type *bus);
- extern struct iommu_group *iommu_group_get_by_id(int id);
  extern void iommu_domain_free(struct iommu_domain *domain);
  extern int iommu_attach_device(struct iommu_domain *domain,
                               struct device *dev);
@@@ -1172,7 -1165,17 +1165,16 @@@ static inline bool tegra_dev_iommu_get_
        return false;
  }
  
 -static inline bool pasid_valid(ioasid_t ioasid)
 -{
 -      return ioasid != IOMMU_PASID_INVALID;
 -}
 -
  #ifdef CONFIG_IOMMU_SVA
+ static inline void mm_pasid_init(struct mm_struct *mm)
+ {
+       mm->pasid = IOMMU_PASID_INVALID;
+ }
++static inline bool mm_valid_pasid(struct mm_struct *mm)
++{
++      return mm->pasid != IOMMU_PASID_INVALID;
++}
+ void mm_pasid_drop(struct mm_struct *mm);
  struct iommu_sva *iommu_sva_bind_device(struct device *dev,
                                        struct mm_struct *mm);
  void iommu_sva_unbind_device(struct iommu_sva *handle);
@@@ -1192,6 -1195,8 +1194,9 @@@ static inline u32 iommu_sva_get_pasid(s
  {
        return IOMMU_PASID_INVALID;
  }
+ static inline void mm_pasid_init(struct mm_struct *mm) {}
++static inline bool mm_valid_pasid(struct mm_struct *mm) { return false; }
+ static inline void mm_pasid_drop(struct mm_struct *mm) {}
  #endif /* CONFIG_IOMMU_SVA */
  
  #endif /* __LINUX_IOMMU_H */
Simple merge
diff --cc kernel/fork.c
index 735d9f4f5acff93d06a21f138fd7bed594344753,e7d10ad98a6912d918abd2530f1b00dfdc5c2f39..ed4e01daccaa008ed0ef98c1a011aa5a4dddab36
@@@ -97,7 -97,7 +97,8 @@@
  #include <linux/io_uring.h>
  #include <linux/bpf.h>
  #include <linux/stackprotector.h>
 +#include <linux/user_events.h>
+ #include <linux/iommu.h>
  
  #include <asm/pgalloc.h>
  #include <linux/uaccess.h>
diff --cc mm/init-mm.c
Simple merge