From: Linus Torvalds Date: Sun, 30 Apr 2023 20:00:38 +0000 (-0700) Subject: Merge tag 'iommu-updates-v6.4' of git://git.kernel.org/pub/scm/linux/kernel/git/joro... X-Git-Tag: 6.4-rc-smb3-client-fixes-part2~11 X-Git-Url: http://git.samba.org/samba.git/?a=commitdiff_plain;h=58390c8ce1bddb6c623f62e7ed36383e7fa5c02f;p=sfrench%2Fcifs-2.6.git Merge tag 'iommu-updates-v6.4' of git://git./linux/kernel/git/joro/iommu 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 ... --- 58390c8ce1bddb6c623f62e7ed36383e7fa5c02f diff --cc arch/x86/kernel/process_64.c index 223b223f713f,bb65a68b4b49..3d181c16a2f6 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@@ -39,6 -39,6 +39,7 @@@ #include #include #include ++#include #include #include diff --cc drivers/iommu/intel/Kconfig index 12e1e90fdae1,12e1e90fdae1..2e56bd79f589 --- a/drivers/iommu/intel/Kconfig +++ b/drivers/iommu/intel/Kconfig @@@ -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 diff --cc drivers/iommu/iommu-sva.c index dd76a1a09cf7,c434b95dc8eb..9821bc44f5ac --- a/drivers/iommu/iommu-sva.c +++ b/drivers/iommu/iommu-sva.c @@@ -10,36 -9,21 +10,25 @@@ #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; } + + void mm_pasid_drop(struct mm_struct *mm) + { - if (likely(!pasid_valid(mm->pasid))) ++ if (likely(!mm_valid_pasid(mm))) + return; + + ida_free(&iommu_global_pasid_ida, mm->pasid); + } diff --cc drivers/iommu/iommu.c index 807c98de40d4,153a3dab568c..f1dcfa3f1a1b --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@@ -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); diff --cc include/linux/iommu.h index 0fd4e6734d5b,7dbdd13d7ce0..e8c9a7da1060 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@@ -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 */ diff --cc kernel/fork.c index 735d9f4f5acf,e7d10ad98a69..ed4e01daccaa --- a/kernel/fork.c +++ b/kernel/fork.c @@@ -97,7 -97,7 +97,8 @@@ #include #include #include +#include + #include #include #include