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

Commit e0e807df authored by Chintan Pandya's avatar Chintan Pandya
Browse files

iommu: msm: Use CB index as ASID



ASID conflict between 2 CBs can lead to some odd behavior
of SMMU. Present way of ASID allotment can conflict with
the ASID being used by secure world. Use the CB number
as ASID. That will ensure that we will not use any other
ASID which secure world may think of using it.

Change-Id: I622d5c1aee7dac5913706588ae7ff1c490a2981c
Signed-off-by: default avatarChintan Pandya <cpandya@codeaurora.org>
parent c5353f99
Loading
Loading
Loading
Loading
+1 −29
Original line number Diff line number Diff line
@@ -559,35 +559,9 @@ static void msm_iommu_assign_ASID(const struct msm_iommu_drvdata *iommu_drvdata,
				  struct msm_iommu_ctx_drvdata *curr_ctx,
				  struct msm_iommu_priv *priv)
{
	unsigned int found = 0;
	void __iomem *cb_base = iommu_drvdata->cb_base;
	unsigned int i;
	unsigned int ncb = iommu_drvdata->ncb;
	struct msm_iommu_ctx_drvdata *tmp_drvdata;

	/* Find if this page table is used elsewhere, and re-use ASID */
	if (!list_empty(&priv->list_attached)) {
		tmp_drvdata = list_first_entry(&priv->list_attached,
				struct msm_iommu_ctx_drvdata, attached_elm);

		++iommu_drvdata->asid[tmp_drvdata->asid - 1];
		curr_ctx->asid = tmp_drvdata->asid;
		found = 1;
	}

	/* If page table is new, find an unused ASID */
	if (!found) {
		for (i = 0; i < ncb; ++i) {
			if (iommu_drvdata->asid[i] == 0) {
				++iommu_drvdata->asid[i];
				curr_ctx->asid = i + 1;
				found = 1;
				break;
			}
		}
		BUG_ON(!found);
	}

	curr_ctx->asid = curr_ctx->num;
	msm_iommu_set_ASID(cb_base, curr_ctx->num, curr_ctx->asid);
}

@@ -928,8 +902,6 @@ static void msm_iommu_detach_dev(struct iommu_domain *domain,
	SET_TLBIASID(iommu_drvdata->cb_base, ctx_drvdata->num,
					ctx_drvdata->asid);

	BUG_ON(iommu_drvdata->asid[ctx_drvdata->asid - 1] == 0);
	iommu_drvdata->asid[ctx_drvdata->asid - 1]--;
	ctx_drvdata->asid = -1;

	__reset_context(iommu_drvdata, ctx_drvdata->num);
+0 −9
Original line number Diff line number Diff line
@@ -200,15 +200,6 @@ static int msm_iommu_parse_dt(struct platform_device *pdev,
	for_each_available_child_of_node(pdev->dev.of_node, child)
		drvdata->ncb++;

	drvdata->asid = devm_kzalloc(&pdev->dev, drvdata->ncb * sizeof(int),
				     GFP_KERNEL);

	if (!drvdata->asid) {
		pr_err("Unable to get memory for asid array\n");
		ret = -ENOMEM;
		goto fail;
	}

	ret = of_property_read_string(pdev->dev.of_node, "label",
				      &drvdata->name);
	if (ret)
+0 −2
Original line number Diff line number Diff line
@@ -100,7 +100,6 @@ struct msm_iommu_bfb_settings {
 * @list:	List head to link all iommus together
 * @clk_reg_virt: Optional clock register virtual address.
 * @halt_enabled: Set to 1 if IOMMU halt is supported in the IOMMU, 0 otherwise.
 * @asid:         List of ASID and their usage count (index is ASID value).
 * @ctx_attach_count: Count of how many context are attached.
 * @bus_client  : Bus client needed to vote for bus bandwidth.
 * @needs_rem_spinlock  : 1 if remote spinlock is needed, 0 otherwise
@@ -130,7 +129,6 @@ struct msm_iommu_drvdata {
	struct list_head list;
	void __iomem *clk_reg_virt;
	int halt_enabled;
	int *asid;
	unsigned int ctx_attach_count;
	unsigned int bus_client;
	int needs_rem_spinlock;