kernel:display:sync qcom update

msm: disp: fix the race condition of vsync handler
fbdev: msm: Avoid UAF in mdss_dsi_cmd_write

JIRA:WEAROS-3158

Change-Id: I6d4dd85e1702caa743b7c38f6bda25a90554f5b5
diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c
index be98d2c..4d5f090 100755
--- a/drivers/video/fbdev/msm/mdss_dsi.c
+++ b/drivers/video/fbdev/msm/mdss_dsi.c
@@ -1009,7 +1009,7 @@
 {
 	struct buf_data *pcmds = file->private_data;
 	ssize_t ret = 0;
-	int blen = 0;
+	unsigned int blen = 0;
 	char *string_buf;
 
 	mutex_lock(&pcmds->dbg_mutex);
diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h
index e72a315..48a234e 100644
--- a/drivers/video/fbdev/msm/mdss_mdp.h
+++ b/drivers/video/fbdev/msm/mdss_mdp.h
@@ -600,6 +600,7 @@
 	struct mutex flush_lock;
 	struct mutex *shared_lock;
 	struct mutex rsrc_lock;
+	struct mutex vsync_handler_lock;
 	spinlock_t spin_lock;
 
 	struct mdss_panel_data *panel_data;
diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
index 029634b..75c2b6f 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2019, 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
@@ -2452,6 +2452,7 @@
 			mutex_init(&ctl->offlock);
 			mutex_init(&ctl->flush_lock);
 			mutex_init(&ctl->rsrc_lock);
+			mutex_init(&ctl->vsync_handler_lock);
 			spin_lock_init(&ctl->spin_lock);
 			BLOCKING_INIT_NOTIFIER_HEAD(&ctl->notifier_head);
 			pr_debug("alloc ctl_num=%d\n", ctl->num);
diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c
old mode 100644
new mode 100755
index 8c5f407..d22dee6
--- a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2019, 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
@@ -1982,6 +1982,49 @@
 	pr_debug("%pS->%s ctl:%d\n",
 		__builtin_return_address(0), __func__, ctl->num);
 
+	mutex_lock(&ctl->vsync_handler_lock);
+
+	MDSS_XLOG(ctl->num, atomic_read(&ctx->koff_cnt), 0x88888);
+	sctl = mdss_mdp_get_split_ctl(ctl);
+	if (sctl)
+		sctx = (struct mdss_mdp_cmd_ctx *) sctl->intf_ctx[MASTER_CTX];
+
+	spin_lock_irqsave(&ctx->clk_lock, flags);
+	if (handle->enabled) {
+		handle->enabled = false;
+		list_del_init(&handle->list);
+		disable_vsync_irq = !handle->cmd_post_flush;
+	}
+	spin_unlock_irqrestore(&ctx->clk_lock, flags);
+
+	if (disable_vsync_irq) {
+		/* disable rd_ptr interrupt and clocks */
+		mdss_mdp_setup_vsync(ctx, false);
+		complete(&ctx->stop_comp);
+	}
+
+	mutex_unlock(&ctl->vsync_handler_lock);
+
+	return 0;
+}
+
+static int mdss_mdp_cmd_remove_vsync_handler_nolock(struct mdss_mdp_ctl *ctl,
+		struct mdss_mdp_vsync_handler *handle)
+{
+	struct mdss_mdp_ctl *sctl;
+	struct mdss_mdp_cmd_ctx *ctx, *sctx = NULL;
+	unsigned long flags;
+	bool disable_vsync_irq = false;
+
+	ctx = (struct mdss_mdp_cmd_ctx *) ctl->intf_ctx[MASTER_CTX];
+	if (!ctx) {
+		pr_err("%s: invalid ctx\n", __func__);
+		return -ENODEV;
+	}
+
+	pr_debug("%pS->%s ctl:%d\n",
+		__builtin_return_address(0), __func__, ctl->num);
+
 	MDSS_XLOG(ctl->num, atomic_read(&ctx->koff_cnt), 0x88888);
 	sctl = mdss_mdp_get_split_ctl(ctl);
 	if (sctl)
@@ -3216,8 +3259,12 @@
 		return -ENODEV;
 	}
 
-	list_for_each_entry_safe(handle, tmp, &ctx->vsync_handlers, list)
-		mdss_mdp_cmd_remove_vsync_handler(ctl, handle);
+	mutex_lock(&ctl->vsync_handler_lock);
+	list_for_each_entry_safe(handle, tmp, &ctx->vsync_handlers, list) {
+		mdss_mdp_cmd_remove_vsync_handler_nolock(ctl, handle);
+	}
+	mutex_unlock(&ctl->vsync_handler_lock);
+
 	if (mdss_mdp_is_lineptr_supported(ctl))
 		mdss_mdp_cmd_lineptr_ctrl(ctl, false);
 	MDSS_XLOG(ctl->num, atomic_read(&ctx->koff_cnt), XLOG_FUNC_ENTRY);