From 1d2302bdf2003a3b3abc1b2a8bca210ff52fbbfe Mon Sep 17 00:00:00 2001 From: Veera Sundaram Sankaran Date: Mon, 18 Jul 2016 18:35:06 -0700 Subject: [PATCH] msm: mdss: fix race condition between iommu attach and sending DCS cmds There might be cases during bootup when backlight cmds or ESD thread sends DCS cmds to the panel when iommu attach is yet to happen. DSI uses physical or virtual address based on the iommu_attached status check. If iommu attach happens when the DCS cmds are using the physical address, it would lead to SMMU page faults. Protect iommu attach/detach and DCS cmd sending with an iommu_lock to avoid such race conditions. Change-Id: I16fb0bf884f0dbbce1cd9099ec5619d132379054 Signed-off-by: Veera Sundaram Sankaran --- drivers/video/fbdev/msm/mdss_smmu.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/video/fbdev/msm/mdss_smmu.c b/drivers/video/fbdev/msm/mdss_smmu.c index 9906f10a7911..9a00eff9ade9 100644 --- a/drivers/video/fbdev/msm/mdss_smmu.c +++ b/drivers/video/fbdev/msm/mdss_smmu.c @@ -172,6 +172,7 @@ static int mdss_smmu_attach_v2(struct mdss_data_type *mdata) struct mdss_smmu_client *mdss_smmu; int i, rc = 0; + mutex_lock(&mdp_iommu_lock); for (i = 0; i < MDSS_IOMMU_MAX_DOMAIN; i++) { if (!mdss_smmu_is_valid_domain_type(mdata, i)) continue; @@ -203,9 +204,12 @@ static int mdss_smmu_attach_v2(struct mdss_data_type *mdata) } } else { pr_err("iommu device not attached for domain[%d]\n", i); + mutex_unlock(&mdp_iommu_lock); return -ENODEV; } } + mutex_unlock(&mdp_iommu_lock); + return 0; err: @@ -217,6 +221,8 @@ err: mdss_smmu->domain_attached = false; } } + mutex_unlock(&mdp_iommu_lock); + return rc; } @@ -231,6 +237,7 @@ static int mdss_smmu_detach_v2(struct mdss_data_type *mdata) struct mdss_smmu_client *mdss_smmu; int i; + mutex_lock(&mdp_iommu_lock); for (i = 0; i < MDSS_IOMMU_MAX_DOMAIN; i++) { if (!mdss_smmu_is_valid_domain_type(mdata, i)) continue; @@ -239,6 +246,8 @@ static int mdss_smmu_detach_v2(struct mdss_data_type *mdata) if (mdss_smmu && mdss_smmu->dev && !mdss_smmu->handoff_pending) mdss_smmu_enable_power(mdss_smmu, false); } + mutex_unlock(&mdp_iommu_lock); + return 0; }