summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2017-03-21 13:29:01 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2017-03-21 13:29:01 -0700
commit202f816129d30f74f9920a6607ab817ca87a40a9 (patch)
tree1324a26f00a04378b2b3c5b6d66065201af17b06
parentf4ec231edf2b30ef53fee0190116b461a1fdc682 (diff)
parent0095fe909e259525e093650cf799ceecf4ec3447 (diff)
Merge "msm: mdss: fix race condition in mdp debugfs"
-rw-r--r--drivers/video/fbdev/msm/mdss_debug.c46
1 files changed, 39 insertions, 7 deletions
diff --git a/drivers/video/fbdev/msm/mdss_debug.c b/drivers/video/fbdev/msm/mdss_debug.c
index 3e1dbba7c9ae..e60869144339 100644
--- a/drivers/video/fbdev/msm/mdss_debug.c
+++ b/drivers/video/fbdev/msm/mdss_debug.c
@@ -44,6 +44,8 @@
#define INVALID_XIN_ID 0xFF
+static DEFINE_MUTEX(mdss_debug_lock);
+
static char panel_reg[2] = {DEFAULT_READ_PANEL_POWER_MODE_REG, 0x00};
static int panel_debug_base_open(struct inode *inode, struct file *file)
@@ -93,8 +95,10 @@ static ssize_t panel_debug_base_offset_write(struct file *file,
if (cnt > (dbg->max_offset - off))
cnt = dbg->max_offset - off;
+ mutex_lock(&mdss_debug_lock);
dbg->off = off;
dbg->cnt = cnt;
+ mutex_unlock(&mdss_debug_lock);
pr_debug("offset=%x cnt=%d\n", off, cnt);
@@ -114,15 +118,21 @@ static ssize_t panel_debug_base_offset_read(struct file *file,
if (*ppos)
return 0; /* the end */
+ mutex_lock(&mdss_debug_lock);
len = snprintf(buf, sizeof(buf), "0x%02zx %zx\n", dbg->off, dbg->cnt);
- if (len < 0 || len >= sizeof(buf))
+ if (len < 0 || len >= sizeof(buf)) {
+ mutex_unlock(&mdss_debug_lock);
return 0;
+ }
- if ((count < sizeof(buf)) || copy_to_user(buff, buf, len))
+ if ((count < sizeof(buf)) || copy_to_user(buff, buf, len)) {
+ mutex_unlock(&mdss_debug_lock);
return -EFAULT;
+ }
*ppos += len; /* increase offset */
+ mutex_unlock(&mdss_debug_lock);
return len;
}
@@ -220,11 +230,16 @@ static ssize_t panel_debug_base_reg_read(struct file *file,
if (!dbg)
return -ENODEV;
- if (!dbg->cnt)
+ mutex_lock(&mdss_debug_lock);
+ if (!dbg->cnt) {
+ mutex_unlock(&mdss_debug_lock);
return 0;
+ }
- if (*ppos)
+ if (*ppos) {
+ mutex_unlock(&mdss_debug_lock);
return 0; /* the end */
+ }
/* '0x' + 2 digit + blank = 5 bytes for each number */
reg_buf_len = (dbg->cnt * PANEL_REG_FORMAT_LEN)
@@ -265,11 +280,13 @@ static ssize_t panel_debug_base_reg_read(struct file *file,
kfree(panel_reg_buf);
*ppos += len; /* increase offset */
+ mutex_unlock(&mdss_debug_lock);
return len;
read_reg_fail:
kfree(rx_buf);
kfree(panel_reg_buf);
+ mutex_unlock(&mdss_debug_lock);
return rc;
}
@@ -403,8 +420,10 @@ static ssize_t mdss_debug_base_offset_write(struct file *file,
if (cnt > (dbg->max_offset - off))
cnt = dbg->max_offset - off;
+ mutex_lock(&mdss_debug_lock);
dbg->off = off;
dbg->cnt = cnt;
+ mutex_unlock(&mdss_debug_lock);
pr_debug("offset=%x cnt=%x\n", off, cnt);
@@ -424,15 +443,21 @@ static ssize_t mdss_debug_base_offset_read(struct file *file,
if (*ppos)
return 0; /* the end */
+ mutex_lock(&mdss_debug_lock);
len = snprintf(buf, sizeof(buf), "0x%08zx %zx\n", dbg->off, dbg->cnt);
- if (len < 0 || len >= sizeof(buf))
+ if (len < 0 || len >= sizeof(buf)) {
+ mutex_unlock(&mdss_debug_lock);
return 0;
+ }
- if ((count < sizeof(buf)) || copy_to_user(buff, buf, len))
+ if ((count < sizeof(buf)) || copy_to_user(buff, buf, len)) {
+ mutex_unlock(&mdss_debug_lock);
return -EFAULT;
+ }
*ppos += len; /* increase offset */
+ mutex_unlock(&mdss_debug_lock);
return len;
}
@@ -489,6 +514,8 @@ static ssize_t mdss_debug_base_reg_read(struct file *file,
return -ENODEV;
}
+ mutex_lock(&mdss_debug_lock);
+
if (!dbg->buf) {
char dump_buf[64];
char *ptr;
@@ -500,6 +527,7 @@ static ssize_t mdss_debug_base_reg_read(struct file *file,
if (!dbg->buf) {
pr_err("not enough memory to hold reg dump\n");
+ mutex_unlock(&mdss_debug_lock);
return -ENOMEM;
}
@@ -530,17 +558,21 @@ static ssize_t mdss_debug_base_reg_read(struct file *file,
dbg->buf_len = tot;
}
- if (*ppos >= dbg->buf_len)
+ if (*ppos >= dbg->buf_len) {
+ mutex_unlock(&mdss_debug_lock);
return 0; /* done reading */
+ }
len = min(count, dbg->buf_len - (size_t) *ppos);
if (copy_to_user(user_buf, dbg->buf + *ppos, len)) {
pr_err("failed to copy to user\n");
+ mutex_unlock(&mdss_debug_lock);
return -EFAULT;
}
*ppos += len; /* increase offset */
+ mutex_unlock(&mdss_debug_lock);
return len;
}