Browse Source

disp: msm: sde: Fix open method in sde_reg_fops and sde_off_fops

The open method for the debug fops are supposed to extract
the appropriate register base for the corresponding
hardware blocks, which are later used for the register
read and writes for the associated hardware block. But
the current open method being used points to some random
register base which can lead to fatal issues when performed
reads and writes to registers. Hence implemented a new
open method to extract the appropriate register base of the
various mdp hardware blocks. This patch also fixes
the valid sub range check against the corresponding
hardware blocks instead of checking across all the hardware
blocks.

Change-Id: I2a08fae74b3cbd31f2931c3b89b7308feb4b84e8
Signed-off-by: Lakshmi Narayana Kalavala <[email protected]>
Lakshmi Narayana Kalavala 6 năm trước cách đây
mục cha
commit
a4570ec11b
1 tập tin đã thay đổi với 55 bổ sung17 xóa
  1. 55 17
      msm/sde_dbg.c

+ 55 - 17
msm/sde_dbg.c

@@ -3608,6 +3608,36 @@ static int sde_dbg_debugfs_open(struct inode *inode, struct file *file)
 	return 0;
 }
 
+/*
+ * sde_dbg_reg_base_open - debugfs open handler for reg base
+ * @inode: debugfs inode
+ * @file: file handle
+ */
+static int sde_dbg_reg_base_open(struct inode *inode, struct file *file)
+{
+	char base_name[64] = {0};
+	struct sde_dbg_reg_base *reg_base = NULL;
+
+	if (!inode || !file)
+		return -EINVAL;
+
+	snprintf(base_name, sizeof(base_name), "%s",
+		file->f_path.dentry->d_iname);
+
+	base_name[strlen(file->f_path.dentry->d_iname) - 4] = '\0';
+	reg_base = _sde_dump_get_blk_addr(base_name);
+	if (!reg_base) {
+		pr_err("error: unable to locate base %s\n",
+				base_name);
+		return -EINVAL;
+	}
+
+	/* non-seekable */
+	file->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE);
+	file->private_data = reg_base;
+	return 0;
+}
+
 /**
  * sde_evtlog_dump_read - debugfs read handler for evtlog dump
  * @file: file handler
@@ -4098,25 +4128,23 @@ static int sde_dbg_reg_base_release(struct inode *inode, struct file *file)
  * @cnt: memory size in bytes
  * Return: true if valid; false otherwise
  */
-static bool sde_dbg_reg_base_is_valid_range(u32 off, u32 cnt)
+static bool sde_dbg_reg_base_is_valid_range(
+	struct sde_dbg_reg_base *base,
+	u32 off, u32 cnt)
 {
-	static struct sde_dbg_base *dbg_base = &sde_dbg_base;
 	struct sde_dbg_reg_range *node;
-	struct sde_dbg_reg_base *base;
 
 	pr_debug("check offset=0x%x cnt=0x%x\n", off, cnt);
 
-	list_for_each_entry(base, &dbg_base->reg_base_list, reg_base_head) {
-		list_for_each_entry(node, &base->sub_range_list, head) {
-			pr_debug("%s: start=0x%x end=0x%x\n", node->range_name,
-					node->offset.start, node->offset.end);
+	list_for_each_entry(node, &base->sub_range_list, head) {
+		pr_debug("%s: start=0x%x end=0x%x\n", node->range_name,
+			node->offset.start, node->offset.end);
 
-			if (node->offset.start <= off
-					&& off <= node->offset.end
-					&& off + cnt <= node->offset.end) {
-				pr_debug("valid range requested\n");
-				return true;
-			}
+		if (node->offset.start <= off
+				&& off <= node->offset.end
+				&& off + cnt <= node->offset.end) {
+			pr_debug("valid range requested\n");
+			return true;
 		}
 	}
 
@@ -4138,6 +4166,7 @@ static ssize_t sde_dbg_reg_base_offset_write(struct file *file,
 	u32 off = 0;
 	u32 cnt = DEFAULT_BASE_REG_CNT;
 	char buf[24];
+	int rc;
 
 	if (!file)
 		return -EINVAL;
@@ -4169,8 +4198,11 @@ static ssize_t sde_dbg_reg_base_offset_write(struct file *file,
 	if (cnt == 0)
 		return -EINVAL;
 
-	if (!sde_dbg_reg_base_is_valid_range(off, cnt))
-		return -EINVAL;
+	if (!list_empty(&dbg->sub_range_list)) {
+		rc = sde_dbg_reg_base_is_valid_range(dbg, off, cnt);
+		if (!rc)
+			return -EINVAL;
+	}
 
 	mutex_lock(&sde_dbg_base.mutex);
 	dbg->off = off;
@@ -4277,6 +4309,12 @@ static ssize_t sde_dbg_reg_base_reg_write(struct file *file,
 		return -EFAULT;
 	}
 
+	if (!list_empty(&dbg->sub_range_list)) {
+		rc = sde_dbg_reg_base_is_valid_range(dbg, off, cnt);
+		if (!rc)
+			return -EINVAL;
+	}
+
 	rc = pm_runtime_get_sync(sde_dbg_base.dev);
 	if (rc < 0) {
 		mutex_unlock(&sde_dbg_base.mutex);
@@ -4391,14 +4429,14 @@ static ssize_t sde_dbg_reg_base_reg_read(struct file *file,
 }
 
 static const struct file_operations sde_off_fops = {
-	.open = sde_dbg_debugfs_open,
+	.open = sde_dbg_reg_base_open,
 	.release = sde_dbg_reg_base_release,
 	.read = sde_dbg_reg_base_offset_read,
 	.write = sde_dbg_reg_base_offset_write,
 };
 
 static const struct file_operations sde_reg_fops = {
-	.open = sde_dbg_debugfs_open,
+	.open = sde_dbg_reg_base_open,
 	.release = sde_dbg_reg_base_release,
 	.read = sde_dbg_reg_base_reg_read,
 	.write = sde_dbg_reg_base_reg_write,