Commit 2396046d authored by Tina Zhang's avatar Tina Zhang Committed by Joerg Roedel

iommu: Add mm_get_enqcmd_pasid() helper function

mm_get_enqcmd_pasid() should be used by architecture code and closely
related to learn the PASID value that the x86 ENQCMD operation should
use for the mm.

For the moment SMMUv3 uses this without any connection to ENQCMD, it
will be cleaned up similar to how the prior patch made VT-d use the
PASID argument of set_dev_pasid().

The motivation is to replace mm->pasid with an iommu private data
structure that is introduced in a later patch.
Reviewed-by: default avatarLu Baolu <baolu.lu@linux.intel.com>
Reviewed-by: default avatarJason Gunthorpe <jgg@nvidia.com>
Tested-by: default avatarNicolin Chen <nicolinc@nvidia.com>
Signed-off-by: default avatarTina Zhang <tina.zhang@intel.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
Link: https://lore.kernel.org/r/20231027000525.1278806-4-tina.zhang@intel.comSigned-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent 5c79705d
...@@ -591,7 +591,7 @@ static bool try_fixup_enqcmd_gp(void) ...@@ -591,7 +591,7 @@ static bool try_fixup_enqcmd_gp(void)
if (!mm_valid_pasid(current->mm)) if (!mm_valid_pasid(current->mm))
return false; return false;
pasid = current->mm->pasid; pasid = mm_get_enqcmd_pasid(current->mm);
/* /*
* Did this thread already have its PASID activated? * Did this thread already have its PASID activated?
......
...@@ -246,7 +246,8 @@ static void arm_smmu_mm_arch_invalidate_secondary_tlbs(struct mmu_notifier *mn, ...@@ -246,7 +246,8 @@ static void arm_smmu_mm_arch_invalidate_secondary_tlbs(struct mmu_notifier *mn,
smmu_domain); smmu_domain);
} }
arm_smmu_atc_inv_domain(smmu_domain, mm->pasid, start, size); arm_smmu_atc_inv_domain(smmu_domain, mm_get_enqcmd_pasid(mm), start,
size);
} }
static void arm_smmu_mm_release(struct mmu_notifier *mn, struct mm_struct *mm) static void arm_smmu_mm_release(struct mmu_notifier *mn, struct mm_struct *mm)
...@@ -264,10 +265,11 @@ static void arm_smmu_mm_release(struct mmu_notifier *mn, struct mm_struct *mm) ...@@ -264,10 +265,11 @@ static void arm_smmu_mm_release(struct mmu_notifier *mn, struct mm_struct *mm)
* DMA may still be running. Keep the cd valid to avoid C_BAD_CD events, * DMA may still be running. Keep the cd valid to avoid C_BAD_CD events,
* but disable translation. * but disable translation.
*/ */
arm_smmu_update_ctx_desc_devices(smmu_domain, mm->pasid, &quiet_cd); arm_smmu_update_ctx_desc_devices(smmu_domain, mm_get_enqcmd_pasid(mm),
&quiet_cd);
arm_smmu_tlb_inv_asid(smmu_domain->smmu, smmu_mn->cd->asid); arm_smmu_tlb_inv_asid(smmu_domain->smmu, smmu_mn->cd->asid);
arm_smmu_atc_inv_domain(smmu_domain, mm->pasid, 0, 0); arm_smmu_atc_inv_domain(smmu_domain, mm_get_enqcmd_pasid(mm), 0, 0);
smmu_mn->cleared = true; smmu_mn->cleared = true;
mutex_unlock(&sva_lock); mutex_unlock(&sva_lock);
...@@ -325,10 +327,13 @@ arm_smmu_mmu_notifier_get(struct arm_smmu_domain *smmu_domain, ...@@ -325,10 +327,13 @@ arm_smmu_mmu_notifier_get(struct arm_smmu_domain *smmu_domain,
spin_lock_irqsave(&smmu_domain->devices_lock, flags); spin_lock_irqsave(&smmu_domain->devices_lock, flags);
list_for_each_entry(master, &smmu_domain->devices, domain_head) { list_for_each_entry(master, &smmu_domain->devices, domain_head) {
ret = arm_smmu_write_ctx_desc(master, mm->pasid, cd); ret = arm_smmu_write_ctx_desc(master, mm_get_enqcmd_pasid(mm),
cd);
if (ret) { if (ret) {
list_for_each_entry_from_reverse(master, &smmu_domain->devices, domain_head) list_for_each_entry_from_reverse(
arm_smmu_write_ctx_desc(master, mm->pasid, NULL); master, &smmu_domain->devices, domain_head)
arm_smmu_write_ctx_desc(
master, mm_get_enqcmd_pasid(mm), NULL);
break; break;
} }
} }
...@@ -358,7 +363,8 @@ static void arm_smmu_mmu_notifier_put(struct arm_smmu_mmu_notifier *smmu_mn) ...@@ -358,7 +363,8 @@ static void arm_smmu_mmu_notifier_put(struct arm_smmu_mmu_notifier *smmu_mn)
list_del(&smmu_mn->list); list_del(&smmu_mn->list);
arm_smmu_update_ctx_desc_devices(smmu_domain, mm->pasid, NULL); arm_smmu_update_ctx_desc_devices(smmu_domain, mm_get_enqcmd_pasid(mm),
NULL);
/* /*
* If we went through clear(), we've already invalidated, and no * If we went through clear(), we've already invalidated, and no
...@@ -366,7 +372,8 @@ static void arm_smmu_mmu_notifier_put(struct arm_smmu_mmu_notifier *smmu_mn) ...@@ -366,7 +372,8 @@ static void arm_smmu_mmu_notifier_put(struct arm_smmu_mmu_notifier *smmu_mn)
*/ */
if (!smmu_mn->cleared) { if (!smmu_mn->cleared) {
arm_smmu_tlb_inv_asid(smmu_domain->smmu, cd->asid); arm_smmu_tlb_inv_asid(smmu_domain->smmu, cd->asid);
arm_smmu_atc_inv_domain(smmu_domain, mm->pasid, 0, 0); arm_smmu_atc_inv_domain(smmu_domain, mm_get_enqcmd_pasid(mm), 0,
0);
} }
/* Frees smmu_mn */ /* Frees smmu_mn */
......
...@@ -141,7 +141,7 @@ u32 iommu_sva_get_pasid(struct iommu_sva *handle) ...@@ -141,7 +141,7 @@ u32 iommu_sva_get_pasid(struct iommu_sva *handle)
{ {
struct iommu_domain *domain = handle->domain; struct iommu_domain *domain = handle->domain;
return domain->mm->pasid; return mm_get_enqcmd_pasid(domain->mm);
} }
EXPORT_SYMBOL_GPL(iommu_sva_get_pasid); EXPORT_SYMBOL_GPL(iommu_sva_get_pasid);
......
...@@ -1346,6 +1346,12 @@ static inline bool mm_valid_pasid(struct mm_struct *mm) ...@@ -1346,6 +1346,12 @@ static inline bool mm_valid_pasid(struct mm_struct *mm)
{ {
return mm->pasid != IOMMU_PASID_INVALID; return mm->pasid != IOMMU_PASID_INVALID;
} }
static inline u32 mm_get_enqcmd_pasid(struct mm_struct *mm)
{
return mm->pasid;
}
void mm_pasid_drop(struct mm_struct *mm); void mm_pasid_drop(struct mm_struct *mm);
struct iommu_sva *iommu_sva_bind_device(struct device *dev, struct iommu_sva *iommu_sva_bind_device(struct device *dev,
struct mm_struct *mm); struct mm_struct *mm);
...@@ -1368,6 +1374,12 @@ static inline u32 iommu_sva_get_pasid(struct iommu_sva *handle) ...@@ -1368,6 +1374,12 @@ static inline u32 iommu_sva_get_pasid(struct iommu_sva *handle)
} }
static inline void mm_pasid_init(struct mm_struct *mm) {} static inline void mm_pasid_init(struct mm_struct *mm) {}
static inline bool mm_valid_pasid(struct mm_struct *mm) { return false; } static inline bool mm_valid_pasid(struct mm_struct *mm) { return false; }
static inline u32 mm_get_enqcmd_pasid(struct mm_struct *mm)
{
return IOMMU_PASID_INVALID;
}
static inline void mm_pasid_drop(struct mm_struct *mm) {} static inline void mm_pasid_drop(struct mm_struct *mm) {}
#endif /* CONFIG_IOMMU_SVA */ #endif /* CONFIG_IOMMU_SVA */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment