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

Commit 5005f6c5 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "iommu/arm-smmu: pass CB index for smmu programming by TZ"

parents 6293e143 ec6f7826
Loading
Loading
Loading
Loading
+31 −9
Original line number Diff line number Diff line
@@ -355,11 +355,13 @@ struct arm_smmu_s2cr {
	enum arm_smmu_s2cr_privcfg	privcfg;
	u8				cbndx;
	bool				cb_handoff;
	bool				write_protected;
};

#define s2cr_init_val (struct arm_smmu_s2cr){				\
	.type = disable_bypass ? S2CR_TYPE_FAULT : S2CR_TYPE_BYPASS,	\
	.cb_handoff = false,						\
	.write_protected = false,					\
}

struct arm_smmu_smr {
@@ -627,7 +629,7 @@ static bool is_dynamic_domain(struct iommu_domain *domain)
	return !!(smmu_domain->attributes & (1 << DOMAIN_ATTR_DYNAMIC));
}

static int arm_smmu_restore_sec_cfg(struct arm_smmu_device *smmu)
static int arm_smmu_restore_sec_cfg(struct arm_smmu_device *smmu, u32 cb)
{
	int ret;
	int scm_ret = 0;
@@ -635,7 +637,7 @@ static int arm_smmu_restore_sec_cfg(struct arm_smmu_device *smmu)
	if (!arm_smmu_is_static_cb(smmu))
		return 0;

	ret = scm_restore_sec_cfg(smmu->sec_id, 0x0, &scm_ret);
	ret = scm_restore_sec_cfg(smmu->sec_id, cb, &scm_ret);
	if (ret || scm_ret) {
		pr_err("scm call IOMMU_SECURE_CFG failed\n");
		return -EINVAL;
@@ -2758,14 +2760,29 @@ static struct arm_smmu_device *arm_smmu_get_by_addr(void __iomem *addr)
bool arm_smmu_skip_write(void __iomem *addr)
{
	struct arm_smmu_device *smmu;
	unsigned long cb;
	int i;

	smmu = arm_smmu_get_by_addr(addr);
	if (smmu &&
	    ((unsigned long)addr & (smmu->size - 1)) >= (smmu->size >> 1))
		return false;
	else

	/* Skip write if smmu not available by now */
	if (!smmu)
		return true;

	/* Do not write to global space */
	if (((unsigned long)addr & (smmu->size - 1)) < (smmu->size >> 1))
		return true;

	/* Finally skip writing to secure CB */
	cb = ((unsigned long)addr & ((smmu->size >> 1) - 1)) >> PAGE_SHIFT;
	for (i = 0; i < smmu->num_mapping_groups; i++) {
		if ((smmu->s2crs[i].cbndx == cb) &&
		    (smmu->s2crs[i].write_protected))
			return true;
	}

	return false;
}
#endif

static struct arm_smmu_device *arm_smmu_get_by_list(struct device_node *np)
@@ -3698,9 +3715,14 @@ static int arm_smmu_alloc_cb(struct iommu_domain *domain,
			cb = smmu->s2crs[idx].cbndx;
	}

	if (cb >= 0 && arm_smmu_is_static_cb(smmu))
	if (cb >= 0 && arm_smmu_is_static_cb(smmu)) {
		smmu_domain->slave_side_secure = true;

		if (arm_smmu_is_slave_side_secure(smmu_domain))
			for_each_cfg_sme(fwspec, i, idx)
				smmu->s2crs[idx].write_protected = true;
	}

	if (cb < 0 && !arm_smmu_is_static_cb(smmu)) {
		mutex_unlock(&smmu->stream_map_mutex);
		return __arm_smmu_alloc_bitmap(smmu->context_map,
@@ -3875,7 +3897,7 @@ static int regulator_notifier(struct notifier_block *nb,
	if (event == REGULATOR_EVENT_PRE_DISABLE)
		qsmmuv2_halt(smmu);
	else if (event == REGULATOR_EVENT_ENABLE) {
		if (arm_smmu_restore_sec_cfg(smmu))
		if (arm_smmu_restore_sec_cfg(smmu, 0))
			goto power_off;
		qsmmuv2_resume(smmu);
	}
@@ -4028,7 +4050,7 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
	bool cttw_dt, cttw_reg;
	int i;

	if (arm_smmu_restore_sec_cfg(smmu))
	if (arm_smmu_restore_sec_cfg(smmu, 0))
		return -ENODEV;

	dev_dbg(smmu->dev, "probing hardware configuration...\n");
+6 −1
Original line number Diff line number Diff line
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -60,11 +60,16 @@ bool arm_smmu_skip_write(void __iomem *addr);

/* Donot write to smmu global space with CONFIG_MSM_TZ_SMMU */
#undef writel_relaxed
#undef writeq_relaxed
#define writel_relaxed(v, c)	do {					\
	if (!arm_smmu_skip_write(c))					\
		((void)__raw_writel((__force u32)cpu_to_le32(v), (c)));	\
	} while (0)

#define writeq_relaxed(v, c) do {					\
	if (!arm_smmu_skip_write(c))					\
		((void)__raw_writeq((__force u64)cpu_to_le64(v), (c)));	\
	} while (0)
#else

static inline int msm_tz_smmu_atos_start(struct device *dev, int cb_num)