瀏覽代碼

disp: msm: avoid double unmap during secure vid to secure UI transition

During secure video to secure ui transition, since
secure ui requires s2 direct translation, display driver
will detach the iommu device after unmap of the buffers
attached to the CB.

In this regard, upstream framework which can independently
request for buffer free to unmap on the buffer creates an
illegal state where in dma ops are attached and iommu device
is dettached.

Cache the dma ops before detaching the CB and set it to
NULL during iommu device detach, to avoid multiple unmap
calls on the buffer.

Change-Id: I11cd33f5f52b8c9c4f3a627c520bff57e340c8a4
Signed-off-by: Jayaprakash <[email protected]>
Jayaprakash 5 年之前
父節點
當前提交
508dad9261
共有 1 個文件被更改,包括 16 次插入1 次删除
  1. 16 1
      msm/msm_smmu.c

+ 16 - 1
msm/msm_smmu.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
  * Copyright (C) 2013 Red Hat
  * Author: Rob Clark <[email protected]>
  *
@@ -20,6 +20,7 @@
 #include <linux/of_platform.h>
 #include <linux/pm_runtime.h>
 #include <linux/msm_dma_iommu_mapping.h>
+#include <linux/dma-mapping.h>
 
 #include <soc/qcom/secure_buffer.h>
 
@@ -31,6 +32,7 @@
 struct msm_smmu_client {
 	struct device *dev;
 	struct iommu_domain *domain;
+	const struct dma_map_ops *dma_ops;
 	bool domain_attached;
 	bool secure;
 };
@@ -65,6 +67,12 @@ static int msm_smmu_attach(struct msm_mmu *mmu, const char * const *names,
 	if (client->domain_attached)
 		return 0;
 
+	if (client->dma_ops) {
+		set_dma_ops(client->dev, client->dma_ops);
+		client->dma_ops = NULL;
+		dev_dbg(client->dev, "iommu domain ops restored\n");
+	}
+
 	rc = iommu_attach_device(client->domain, client->dev);
 	if (rc) {
 		dev_err(client->dev, "iommu attach dev failed (%d)\n", rc);
@@ -95,6 +103,13 @@ static void msm_smmu_detach(struct msm_mmu *mmu, const char * const *names,
 	pm_runtime_get_sync(mmu->dev);
 	msm_dma_unmap_all_for_dev(client->dev);
 	iommu_detach_device(client->domain, client->dev);
+
+	client->dma_ops = get_dma_ops(client->dev);
+	if (client->dma_ops) {
+		set_dma_ops(client->dev, NULL);
+		dev_dbg(client->dev, "iommu domain ops removed\n");
+	}
+
 	pm_runtime_put_sync(mmu->dev);
 
 	client->domain_attached = false;