Skip to content

Commit

Permalink
iommu/arm-smmu-v3: Keep track of arm_smmu_master_domain for SVA
Browse files Browse the repository at this point in the history
Fill in the smmu_domain->devices list in the new struct arm_smmu_domain
that SVA allocates. Keep track of every SSID and master that is using the
domain reusing the logic for the RID attach.

This is the first step to making the SVA invalidation follow the same
design as S1/S2 invalidation. At present nothing will read this list.

Tested-by: Nicolin Chen <nicolinc@nvidia.com>
Tested-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Link: https://lore.kernel.org/r/9-v9-5cd718286059+79186-smmuv3_newapi_p2b_jgg@nvidia.com
Signed-off-by: Will Deacon <will@kernel.org>
  • Loading branch information
Jason Gunthorpe authored and Will Deacon committed Jul 2, 2024
1 parent d7b2d2b commit 49db2ed
Showing 1 changed file with 28 additions and 2 deletions.
30 changes: 28 additions & 2 deletions drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
Original file line number Diff line number Diff line change
Expand Up @@ -2587,7 +2587,8 @@ to_smmu_domain_devices(struct iommu_domain *domain)
/* The domain can be NULL only when processing the first attach */
if (!domain)
return NULL;
if (domain->type & __IOMMU_DOMAIN_PAGING)
if ((domain->type & __IOMMU_DOMAIN_PAGING) ||
domain->type == IOMMU_DOMAIN_SVA)
return to_smmu_domain(domain);
return NULL;
}
Expand Down Expand Up @@ -2820,7 +2821,16 @@ int arm_smmu_set_pasid(struct arm_smmu_master *master,
struct arm_smmu_domain *smmu_domain, ioasid_t pasid,
const struct arm_smmu_cd *cd)
{
struct arm_smmu_attach_state state = {
.master = master,
/*
* For now the core code prevents calling this when a domain is
* already attached, no need to set old_domain.
*/
.ssid = pasid,
};
struct arm_smmu_cd *cdptr;
int ret;

/* The core code validates pasid */

Expand All @@ -2830,14 +2840,30 @@ int arm_smmu_set_pasid(struct arm_smmu_master *master,
cdptr = arm_smmu_alloc_cd_ptr(master, pasid);
if (!cdptr)
return -ENOMEM;

mutex_lock(&arm_smmu_asid_lock);
ret = arm_smmu_attach_prepare(&state, &smmu_domain->domain);
if (ret)
goto out_unlock;

arm_smmu_write_cd_entry(master, pasid, cdptr, cd);
return 0;

arm_smmu_attach_commit(&state);

out_unlock:
mutex_unlock(&arm_smmu_asid_lock);
return ret;
}

void arm_smmu_remove_pasid(struct arm_smmu_master *master,
struct arm_smmu_domain *smmu_domain, ioasid_t pasid)
{
mutex_lock(&arm_smmu_asid_lock);
arm_smmu_clear_cd(master, pasid);
if (master->ats_enabled)
arm_smmu_atc_inv_master(master, pasid);
arm_smmu_remove_master_domain(master, &smmu_domain->domain, pasid);
mutex_unlock(&arm_smmu_asid_lock);
}

static int arm_smmu_attach_dev_ste(struct iommu_domain *domain,
Expand Down

0 comments on commit 49db2ed

Please sign in to comment.