On Tue, Feb 18, 2025 at 01:08:24PM -0400, Jason Gunthorpe wrote: > On Fri, Jan 24, 2025 at 04:30:41PM -0800, Nicolin Chen wrote: > > + int ret; > > struct arm_smmu_ste ste; > > struct arm_smmu_master *master = dev_iommu_priv_get(dev); > > + struct arm_smmu_attach_state state = { > > + .master = master, > > + }; > > + > > + ret = arm_smmu_attach_prepare_vmaster(&state, domain); > > + if (ret) > > + return ret; > > + arm_smmu_attach_commit_vmaster(&state); > > I think you should make this into just a arm_smmu_clear_vmaster() > with less complication.. Ack: +void arm_smmu_master_clear_vmaster(struct arm_smmu_master *master) +{ + mutex_lock(&master->smmu->streams_mutex); + kfree(master->vmaster); + master->vmaster = NULL; + mutex_unlock(&master->smmu->streams_mutex); +} [...] @@ -3162,6 +3172,7 @@ static int arm_smmu_attach_dev_identity(struct iommu_domain *domain, struct arm_smmu_ste ste; struct arm_smmu_master *master = dev_iommu_priv_get(dev); + arm_smmu_master_clear_vmaster(master); arm_smmu_make_bypass_ste(master->smmu, &ste); arm_smmu_attach_dev_ste(domain, dev, &ste, STRTAB_STE_1_S1DSS_BYPASS); return 0; @@ -3180,7 +3191,9 @@ static int arm_smmu_attach_dev_blocked(struct iommu_domain *domain, struct device *dev) { struct arm_smmu_ste ste; + struct arm_smmu_master *master = dev_iommu_priv_get(dev); + arm_smmu_master_clear_vmaster(master); arm_smmu_make_abort_ste(&ste); arm_smmu_attach_dev_ste(domain, dev, &ste, STRTAB_STE_1_S1DSS_TERMINATE); Thanks Nicolin