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);