Skip to content

Commit 7497f42

Browse files
jgunthorpewilldeacon
authored andcommitted
iommu/arm-smmu-v3: Make changing domains be hitless for ATS
The core code allows the domain to be changed on the fly without a forced stop in BLOCKED/IDENTITY. In this flow the driver should just continually maintain the ATS with no change while the STE is updated. ATS relies on a linked list smmu_domain->devices to keep track of which masters have the domain programmed, but this list is also used by arm_smmu_share_asid(), unrelated to ats. Create two new functions to encapsulate this combined logic: arm_smmu_attach_prepare() <caller generates and sets the STE> arm_smmu_attach_commit() The two functions can sequence both enabling ATS and disabling across the STE store. Have every update of the STE use this sequence. Installing a S1/S2 domain always enables the ATS if the PCIe device supports it. The enable flow is now ordered differently to allow it to be hitless: 1) Add the master to the new smmu_domain->devices list 2) Program the STE 3) Enable ATS at PCIe 4) Remove the master from the old smmu_domain This flow ensures that invalidations to either domain will generate an ATC invalidation to the device while the STE is being switched. Thus we don't need to turn off the ATS anymore for correctness. The disable flow is the reverse: 1) Disable ATS at PCIe 2) Program the STE 3) Invalidate the ATC 4) Remove the master from the old smmu_domain Move the nr_ats_masters adjustments to be close to the list manipulations. It is a count of the number of ATS enabled masters currently in the list. This is stricly before and after the STE/CD are revised, and done under the list's spin_lock. This is part of the bigger picture to allow changing the RID domain while a PASID is in use. If a SVA PASID is relying on ATS to function then changing the RID domain cannot just temporarily toggle ATS off without also wrecking the SVA PASID. The new infrastructure here is organized so that the PASID attach/detach flows will make use of it as well in following patches. Tested-by: Nicolin Chen <[email protected]> Tested-by: Shameer Kolothum <[email protected]> Reviewed-by: Nicolin Chen <[email protected]> Reviewed-by: Michael Shavit <[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 ad10dce commit 7497f42

File tree

3 files changed

+177
-71
lines changed

3 files changed

+177
-71
lines changed

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ static void arm_smmu_test_make_cdtable_ste(struct arm_smmu_ste *ste,
164164
.smmu = &smmu,
165165
};
166166

167-
arm_smmu_make_cdtable_ste(ste, &master);
167+
arm_smmu_make_cdtable_ste(ste, &master, true);
168168
}
169169

170170
static void arm_smmu_v3_write_ste_test_bypass_to_abort(struct kunit *test)
@@ -231,7 +231,6 @@ static void arm_smmu_test_make_s2_ste(struct arm_smmu_ste *ste,
231231
{
232232
struct arm_smmu_master master = {
233233
.smmu = &smmu,
234-
.ats_enabled = ats_enabled,
235234
};
236235
struct io_pgtable io_pgtable = {};
237236
struct arm_smmu_domain smmu_domain = {
@@ -247,7 +246,7 @@ static void arm_smmu_test_make_s2_ste(struct arm_smmu_ste *ste,
247246
io_pgtable.cfg.arm_lpae_s2_cfg.vtcr.sl = 3;
248247
io_pgtable.cfg.arm_lpae_s2_cfg.vtcr.tsz = 4;
249248

250-
arm_smmu_make_s2_domain_ste(ste, &master, &smmu_domain);
249+
arm_smmu_make_s2_domain_ste(ste, &master, &smmu_domain, ats_enabled);
251250
}
252251

253252
static void arm_smmu_v3_write_ste_test_s2_to_abort(struct kunit *test)

0 commit comments

Comments
 (0)