Skip to content

Commit be7c90d

Browse files
jgunthorpewilldeacon
authored andcommitted
iommu/arm-smmu-v3: Do not use master->sva_enable to restrict attaches
We no longer need a master->sva_enable to control what attaches are allowed. Instead we can tell if the attach is legal based on the current configuration of the master. Keep track of the number of valid CD entries for SSID's in the cd_table and if the cd_table has been installed in the STE directly so we know what the configuration is. The attach logic is then made into: - SVA bind, check if the CD is installed - RID attach of S2, block if SSIDs are used - RID attach of IDENTITY/BLOCKING, block if SSIDs are used arm_smmu_set_pasid() is already checking if it is possible to setup a CD entry, at this patch it means the RID path already set a STE pointing at the CD table. Tested-by: Nicolin Chen <[email protected]> Reviewed-by: Nicolin Chen <[email protected]> Reviewed-by: Jerry Snitselaar <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]>
1 parent 64efb3d commit be7c90d

File tree

2 files changed

+19
-12
lines changed

2 files changed

+19
-12
lines changed

drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1289,6 +1289,8 @@ void arm_smmu_write_cd_entry(struct arm_smmu_master *master, int ssid,
12891289
struct arm_smmu_cd *cdptr,
12901290
const struct arm_smmu_cd *target)
12911291
{
1292+
bool target_valid = target->data[0] & cpu_to_le64(CTXDESC_CD_0_V);
1293+
bool cur_valid = cdptr->data[0] & cpu_to_le64(CTXDESC_CD_0_V);
12921294
struct arm_smmu_cd_writer cd_writer = {
12931295
.writer = {
12941296
.ops = &arm_smmu_cd_writer_ops,
@@ -1297,6 +1299,13 @@ void arm_smmu_write_cd_entry(struct arm_smmu_master *master, int ssid,
12971299
.ssid = ssid,
12981300
};
12991301

1302+
if (ssid != IOMMU_NO_PASID && cur_valid != target_valid) {
1303+
if (cur_valid)
1304+
master->cd_table.used_ssids--;
1305+
else
1306+
master->cd_table.used_ssids++;
1307+
}
1308+
13001309
arm_smmu_write_entry(&cd_writer.writer, cdptr->data, target->data);
13011310
}
13021311

@@ -2733,16 +2742,6 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
27332742
state.master = master = dev_iommu_priv_get(dev);
27342743
smmu = master->smmu;
27352744

2736-
/*
2737-
* Checking that SVA is disabled ensures that this device isn't bound to
2738-
* any mm, and can be safely detached from its old domain. Bonds cannot
2739-
* be removed concurrently since we're holding the group mutex.
2740-
*/
2741-
if (arm_smmu_master_sva_enabled(master)) {
2742-
dev_err(dev, "cannot attach - SVA enabled\n");
2743-
return -EBUSY;
2744-
}
2745-
27462745
mutex_lock(&smmu_domain->init_mutex);
27472746

27482747
if (!smmu_domain->smmu) {
@@ -2758,7 +2757,8 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
27582757
cdptr = arm_smmu_alloc_cd_ptr(master, IOMMU_NO_PASID);
27592758
if (!cdptr)
27602759
return -ENOMEM;
2761-
}
2760+
} else if (arm_smmu_ssids_in_use(&master->cd_table))
2761+
return -EBUSY;
27622762

27632763
/*
27642764
* Prevent arm_smmu_share_asid() from trying to change the ASID
@@ -2831,7 +2831,7 @@ static int arm_smmu_attach_dev_ste(struct iommu_domain *domain,
28312831
.old_domain = iommu_get_domain_for_dev(dev),
28322832
};
28332833

2834-
if (arm_smmu_master_sva_enabled(master))
2834+
if (arm_smmu_ssids_in_use(&master->cd_table))
28352835
return -EBUSY;
28362836

28372837
/*

drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,12 +602,19 @@ struct arm_smmu_ctx_desc_cfg {
602602
dma_addr_t cdtab_dma;
603603
struct arm_smmu_l1_ctx_desc *l1_desc;
604604
unsigned int num_l1_ents;
605+
unsigned int used_ssids;
605606
u8 in_ste;
606607
u8 s1fmt;
607608
/* log2 of the maximum number of CDs supported by this table */
608609
u8 s1cdmax;
609610
};
610611

612+
/* True if the cd table has SSIDS > 0 in use. */
613+
static inline bool arm_smmu_ssids_in_use(struct arm_smmu_ctx_desc_cfg *cd_table)
614+
{
615+
return cd_table->used_ssids;
616+
}
617+
611618
struct arm_smmu_s2_cfg {
612619
u16 vmid;
613620
};

0 commit comments

Comments
 (0)