Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fa744a0f authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "iommu: arm-smmu: Fail device attach when SMR write fails"

parents 71c60275 e49e9c98
Loading
Loading
Loading
Loading
+26 −4
Original line number Diff line number Diff line
@@ -2392,14 +2392,30 @@ static void arm_smmu_domain_free(struct iommu_domain *domain)
	kfree(smmu_domain);
}

static void arm_smmu_write_smr(struct arm_smmu_device *smmu, int idx)
static int arm_smmu_write_smr(struct arm_smmu_device *smmu, int idx)
{
	struct arm_smmu_smr *smr = smmu->smrs + idx;
	u32 reg = FIELD_PREP(SMR_ID, smr->id) | FIELD_PREP(SMR_MASK, smr->mask);
	u32 val;

	if (!(smmu->features & ARM_SMMU_FEAT_EXIDS) && smr->valid)
		reg |= SMR_VALID;
	arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_SMR(idx), reg);

	/*
	 * Check if the write went properly. If failed, we would have to fail
	 * the attach sequence to avoid any USF faults being generated in the
	 * future due to device transactions, since this SID entry would not
	 * be present in the stream mapping table.
	 */
	val = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_SMR(idx));
	if (val != reg) {
		dev_err(smmu->dev, "SMR[%d] write err write:0x%lx, read:0x%lx\n",
				idx, reg, val);
		return -EINVAL;
	}

	return 0;
}

static void arm_smmu_write_s2cr(struct arm_smmu_device *smmu, int idx)
@@ -2416,11 +2432,14 @@ static void arm_smmu_write_s2cr(struct arm_smmu_device *smmu, int idx)
	arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_S2CR(idx), reg);
}

static void arm_smmu_write_sme(struct arm_smmu_device *smmu, int idx)
static int arm_smmu_write_sme(struct arm_smmu_device *smmu, int idx)
{
	arm_smmu_write_s2cr(smmu, idx);
	if (smmu->smrs)
		arm_smmu_write_smr(smmu, idx);
		if (arm_smmu_write_smr(smmu, idx))
			return -EINVAL;

	return 0;
}

/*
@@ -2674,7 +2693,10 @@ static int arm_smmu_domain_add_master(struct arm_smmu_domain *smmu_domain,
		s2cr[idx].type = type;
		s2cr[idx].privcfg = S2CR_PRIVCFG_DEFAULT;
		s2cr[idx].cbndx = cbndx;
		arm_smmu_write_sme(smmu, idx);
		if (arm_smmu_write_sme(smmu, idx)) {
			mutex_unlock(&smmu->stream_map_mutex);
			return -EINVAL;
		}
	}
	mutex_unlock(&smmu->stream_map_mutex);