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

Commit 9916f484 authored by Olav Haugan's avatar Olav Haugan
Browse files

iommu: msm: Make VFE SMMU conditionally secure



VFE SMMU needs to be secure for new secure camera use
cases. Change the VFE to be secure and designate the
last context bank (CB) as secure. Also ensure backwards
compatability so that when running with old secure environment
we fall back to VFE SMMU being non-secure.

Change-Id: I25f31b0350ef0c1b16ebb0db531cc0e6bc556fcf
Signed-off-by: default avatarOlav Haugan <ohaugan@codeaurora.org>
parent ce80330c
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -448,6 +448,7 @@
		interrupt-names = "pmon",
				"global_cfg_NS_irq", "global_client_NS_irq",
				"global_cfg_S_irq", "global_client_S_irq";
		qcom,iommu-secure-id = <19>;
		qcom,needs-alt-core-clk;
		label = "vfe_iommu";
		qcom,msm-bus,name = "vfe_ebi";
@@ -535,9 +536,10 @@
		qcom,iommu-ctx@fda4e000 {
			compatible = "qcom,msm-smmu-v1-ctx";
			reg = <0xfda4e000 0x1000>;
			interrupts = <0 65 0>;
			interrupts = <0 65 0>, <0 64 0>;
			qcom,iommu-ctx-sids = <>;
			label = "vfe_secure";
			qcom,secure-context;
		};
	};

+2 −1
Original line number Diff line number Diff line
@@ -332,7 +332,8 @@ static inline struct device *msm_iommu_get_ctx(const char *ctx_name)
 * of global registers is not possible
 */
void msm_iommu_sec_set_access_ops(struct iommu_access_ops *access_ops);
int msm_iommu_sec_program_iommu(int sec_id);
int msm_iommu_sec_program_iommu(int sec_id, u32 cb_num);
int is_vfe_secure(void);

#ifdef CONFIG_MSM_IOMMU_V0
static inline int msm_soc_version_supports_iommu_v0(void)
+1 −1
Original line number Diff line number Diff line
@@ -824,7 +824,7 @@ static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
			iommu_resume(iommu_drvdata);
		} else {
			ret = msm_iommu_sec_program_iommu(
				iommu_drvdata->sec_id);
				iommu_drvdata->sec_id, ctx_drvdata->num);
			if (ret) {
				__disable_regulators(iommu_drvdata);
				__disable_clocks(iommu_drvdata);
+26 −7
Original line number Diff line number Diff line
@@ -138,26 +138,44 @@ static inline void get_secure_id(struct device_node *node,
}

static inline void get_secure_ctx(struct device_node *node,
				  struct msm_iommu_drvdata *iommu_drvdata,
				  struct msm_iommu_ctx_drvdata *ctx_drvdata)
{
	ctx_drvdata->secure_context = 0;
}
#else

static inline int is_vfe_smmu(char const *iommu_name)
{
	return (strcmp(iommu_name, "vfe_iommu") == 0);
}

static void get_secure_id(struct device_node *node,
			  struct msm_iommu_drvdata *drvdata)
{
	if (msm_iommu_get_scm_call_avail())
	if (msm_iommu_get_scm_call_avail()) {
		if (!is_vfe_smmu(drvdata->name) || is_vfe_secure())
			of_property_read_u32(node, "qcom,iommu-secure-id",
					     &drvdata->sec_id);
		else
			pr_info("vfe_iommu: Keeping vfe non-secure\n");
	}
}

static void get_secure_ctx(struct device_node *node,
			   struct msm_iommu_drvdata *iommu_drvdata,
			   struct msm_iommu_ctx_drvdata *ctx_drvdata)
{
	if (msm_iommu_get_scm_call_avail())
		ctx_drvdata->secure_context =
	u32 secure_ctx = 0;

	if (msm_iommu_get_scm_call_avail()) {
		if (!is_vfe_smmu(iommu_drvdata->name) || is_vfe_secure()) {
			secure_ctx =
			of_property_read_bool(node, "qcom,secure-context");
		}
	}
	ctx_drvdata->secure_context = secure_ctx;
}
#endif

static int msm_iommu_parse_dt(struct platform_device *pdev,
@@ -473,7 +491,9 @@ static int msm_iommu_ctx_parse_dt(struct platform_device *pdev,
	u32 nsid;
	unsigned long cb_offset;

	get_secure_ctx(pdev->dev.of_node, ctx_drvdata);
	drvdata = dev_get_drvdata(pdev->dev.parent);

	get_secure_ctx(pdev->dev.of_node, drvdata, ctx_drvdata);

	if (ctx_drvdata->secure_context) {
		irq = platform_get_irq(pdev, 1);
@@ -518,7 +538,6 @@ static int msm_iommu_ctx_parse_dt(struct platform_device *pdev,
	 * of CBs are <=8. So, assume the offset 0x8000 until mentioned
	 * explicitely.
	 */
	drvdata = dev_get_drvdata(pdev->dev.parent);
	cb_offset = drvdata->cb_base - drvdata->base;
	ctx_drvdata->num = ((r->start - rp.start - cb_offset)
					>> CTX_SHIFT);
+22 −4
Original line number Diff line number Diff line
@@ -56,7 +56,7 @@
#define MAXIMUM_VIRT_SIZE	(300*SZ_1M)


#define MAKE_CP_VERSION(major, minor, patch) \
#define MAKE_VERSION(major, minor, patch) \
	(((major & 0x3FF) << 22) | ((minor & 0x3FF) << 12) | (patch & 0xFFF))


@@ -349,7 +349,7 @@ static int msm_iommu_sec_ptbl_init(void)

	version = scm_get_feat_version(SCM_SVC_MP);

	if (version >= MAKE_CP_VERSION(1, 1, 1)) {
	if (version >= MAKE_VERSION(1, 1, 1)) {
		struct msm_cp_pool_size psize;
		int retval;

@@ -410,7 +410,7 @@ fail:
	return ret;
}

int msm_iommu_sec_program_iommu(int sec_id)
int msm_iommu_sec_program_iommu(int sec_id, u32 cb_num)
{
	struct msm_scm_sec_cfg {
		unsigned int id;
@@ -419,6 +419,7 @@ int msm_iommu_sec_program_iommu(int sec_id)
	int ret, scm_ret = 0;

	cfg.id = sec_id;
	cfg.spare = cb_num;

	ret = scm_call(SCM_SVC_MP, IOMMU_SECURE_CFG, &cfg, sizeof(cfg),
			&scm_ret, sizeof(scm_ret));
@@ -638,7 +639,8 @@ static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
			goto fail;
		}

		ret = msm_iommu_sec_program_iommu(iommu_drvdata->sec_id);
		ret = msm_iommu_sec_program_iommu(iommu_drvdata->sec_id,
						ctx_drvdata->num);

		/* bfb settings are always programmed by HLOS */
		program_iommu_bfb_settings(iommu_drvdata->base,
@@ -830,6 +832,22 @@ int msm_iommu_get_scm_call_avail(void)
	return is_secure;
}

/*
 * VFE SMMU is changing from being non-secure to being secure.
 * For backwards compatibility we need to check whether the secure environment
 * has support for this.
 */
static s32 secure_camera_enabled = -1;
int is_vfe_secure(void)
{
	if (secure_camera_enabled == -1) {
		u32 ver = scm_get_feat_version(SCM_SVC_SEC_CAMERA);
		secure_camera_enabled = ver >= MAKE_VERSION(1, 0, 0);
	}
	return secure_camera_enabled;
}


static struct iommu_ops msm_iommu_ops = {
	.domain_init = msm_iommu_domain_init,
	.domain_destroy = msm_iommu_domain_destroy,
Loading