DivestOS/Patches/Linux_CVEs/CVE-2016-10293/ANY/0001.patch
2017-11-07 17:32:46 -05:00

185 lines
5.6 KiB
Diff

From 2469d5374745a2228f774adbca6fb95a79b9047f Mon Sep 17 00:00:00 2001
From: Yang Xu <yangxu@codeaurora.org>
Date: Thu, 29 Oct 2015 17:46:15 +0800
Subject: msm: mdss: Add debugfs support for panel command data type
Register debugfs node to read from and write to the panel command
data type. The default data type is DCS_LONG_WRITE 0x39.
Give following command in adb shell to read panel register:
cat /sys/kernel/debug/mdp/panel_cmd_data_type
To write panel command data type:
echo "command_data_type" >
/sys/kernel/debug/mdp/panel_cmd_data_type
Change-Id: I6dbe5bccb3142e93400825eddf7f05180acfc710
Signed-off-by: Yang Xu <yangxu@codeaurora.org>
---
drivers/video/msm/mdss/mdss_debug.c | 73 ++++++++++++++++++++++---------------
drivers/video/msm/mdss/mdss_debug.h | 3 +-
2 files changed, 46 insertions(+), 30 deletions(-)
diff --git a/drivers/video/msm/mdss/mdss_debug.c b/drivers/video/msm/mdss/mdss_debug.c
index eaeccac..13d2b16 100644
--- a/drivers/video/msm/mdss/mdss_debug.c
+++ b/drivers/video/msm/mdss/mdss_debug.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2009-2017, 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
@@ -124,32 +124,22 @@ static ssize_t panel_debug_base_reg_write(struct file *file,
const char __user *user_buf, size_t count, loff_t *ppos)
{
struct mdss_debug_base *dbg = file->private_data;
-
- u32 cnt, tmp, i;
- u32 len = 0;
char buf[PANEL_TX_MAX_BUF] = {0x0};
- char *p = NULL;
char reg[PANEL_TX_MAX_BUF] = {0x0};
+ u32 len = 0, step = 0, value = 0;
+ char *bufp;
struct mdss_data_type *mdata = mdss_res;
- struct mdss_mdp_ctl *ctl = mdata->ctl_off + 0;
- struct mdss_panel_data *panel_data = ctl->panel_data;
- struct mdss_dsi_ctrl_pdata *ctrl_pdata = container_of(panel_data,
- struct mdss_dsi_ctrl_pdata, panel_data);
-
+ struct mdss_mdp_ctl *ctl;
+ struct mdss_dsi_ctrl_pdata *ctrl_pdata;
struct dsi_cmd_desc dsi_write_cmd = {
- {DTYPE_GEN_LWRITE, 1, 0, 0, 0, 0/*len*/}, reg};
+ {0/*data type*/, 1, 0, 0, 0, 0/* len */}, reg};
struct dcs_cmd_req cmdreq;
- cmdreq.cmds = &dsi_write_cmd;
- cmdreq.cmds_cnt = 1;
- cmdreq.flags = CMD_REQ_COMMIT;
- cmdreq.rlen = 0;
- cmdreq.cb = NULL;
-
if (!dbg || !mdata)
return -ENODEV;
+ /* get command string from user */
if (count >= sizeof(buf))
return -EFAULT;
@@ -158,26 +148,38 @@ static ssize_t panel_debug_base_reg_write(struct file *file,
buf[count] = 0; /* end of string */
- len = count / 3;
-
+ bufp = buf;
+ while (sscanf(bufp, "%x%n", &value, &step) > 0) {
+ reg[len++] = value;
+ if (len >= PANEL_TX_MAX_BUF) {
+ pr_err("wrong input reg len\n");
+ return -EFAULT;
+ }
+ bufp += step;
+ }
if (len < PANEL_CMD_MIN_TX_COUNT) {
pr_err("wrong input reg len\n");
return -EFAULT;
}
- for (i = 0; i < len; i++) {
- p = buf + i * 3;
- p[2] = 0;
- pr_debug("p[%d] = %p:%s\n", i, p, p);
- cnt = sscanf(p, "%x", &tmp);
- reg[i] = tmp;
- pr_debug("reg[%d] = %x\n", i, (int)reg[i]);
- }
+ /* put command to cmdlist */
+ dsi_write_cmd.dchdr.dtype = dbg->cmd_data_type;
+ dsi_write_cmd.dchdr.dlen = len;
+ dsi_write_cmd.payload = reg;
+
+ cmdreq.cmds = &dsi_write_cmd;
+ cmdreq.cmds_cnt = 1;
+ cmdreq.flags = CMD_REQ_COMMIT;
+ cmdreq.rlen = 0;
+ cmdreq.cb = NULL;
+
+ ctl = mdata->ctl_off + 0;
+ ctrl_pdata = container_of(ctl->panel_data,
+ struct mdss_dsi_ctrl_pdata, panel_data);
if (mdata->debug_inf.debug_enable_clock)
mdata->debug_inf.debug_enable_clock(1);
- dsi_write_cmd.dchdr.dlen = len;
mdss_dsi_cmdlist_put(ctrl_pdata, &cmdreq);
if (mdata->debug_inf.debug_enable_clock)
@@ -262,7 +264,7 @@ int panel_debug_register_base(const char *name, void __iomem *base,
struct mdss_data_type *mdata = mdss_res;
struct mdss_debug_data *mdd;
struct mdss_debug_base *dbg;
- struct dentry *ent_off, *ent_reg;
+ struct dentry *ent_off, *ent_reg, *ent_type;
char dn[PANEL_DATA_NODE_LEN] = "";
int prefix_len = 0;
@@ -279,10 +281,20 @@ int panel_debug_register_base(const char *name, void __iomem *base,
dbg->max_offset = max_offset;
dbg->off = 0x0a;
dbg->cnt = 0x01;
+ dbg->cmd_data_type = DTYPE_DCS_LWRITE;
if (name)
prefix_len = snprintf(dn, sizeof(dn), "%s_", name);
+ strlcpy(dn + prefix_len, "cmd_data_type", sizeof(dn) - prefix_len);
+ ent_type = debugfs_create_x8(dn, 0644, mdd->root,
+ (u8 *)&dbg->cmd_data_type);
+
+ if (IS_ERR_OR_NULL(ent_type)) {
+ pr_err("debugfs_create_file: data_type fail\n");
+ goto type_fail;
+ }
+
strlcpy(dn + prefix_len, "off", sizeof(dn) - prefix_len);
ent_off = debugfs_create_file(dn, 0644, mdd->root,
dbg, &panel_off_fops);
@@ -303,9 +315,12 @@ int panel_debug_register_base(const char *name, void __iomem *base,
list_add(&dbg->head, &mdd->base_list);
return 0;
+
reg_fail:
debugfs_remove(ent_off);
off_fail:
+ debugfs_remove(ent_type);
+type_fail:
kfree(dbg);
return -ENODEV;
}
diff --git a/drivers/video/msm/mdss/mdss_debug.h b/drivers/video/msm/mdss/mdss_debug.h
index ef665e7..1bb54d2 100644
--- a/drivers/video/msm/mdss/mdss_debug.h
+++ b/drivers/video/msm/mdss/mdss_debug.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 2017 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
@@ -49,6 +49,7 @@ struct mdss_debug_base {
void __iomem *base;
size_t off;
size_t cnt;
+ u8 cmd_data_type;
size_t max_offset;
char *buf;
size_t buf_len;
--
cgit v1.1