disp: msm: avoid sde_dbg HW access based on HW ownership
Add VM ownership checks before accessing the HW through the debugfs path in sde dbg module to avoid illegal access. Set the ownership status on bootup based on the VM. Change-Id: I30f2a1eb7e049740f1f7fe3ed03aa411264ba7b3 Signed-off-by: Veera Sundaram Sankaran <veeras@codeaurora.org>
This commit is contained in:

committed by
Dhaval Patel

父節點
d26e510b77
當前提交
b261fe33db
@@ -255,6 +255,7 @@ struct sde_dbg_regbuf {
|
||||
* @cur_evt_index: index used for tracking event logs dump in hw recovery
|
||||
* @dbgbus_dump_idx: index used for tracking dbg-bus dump in hw recovery
|
||||
* @vbif_dbgbus_dump_idx: index for tracking vbif dumps in hw recovery
|
||||
* @hw_ownership: indicates if the VM owns the HW resources
|
||||
*/
|
||||
static struct sde_dbg_base {
|
||||
struct sde_dbg_evtlog *evtlog;
|
||||
@@ -283,6 +284,7 @@ static struct sde_dbg_base {
|
||||
struct sde_dbg_regbuf regbuf;
|
||||
u32 cur_evt_index;
|
||||
enum sde_dbg_dump_context dump_mode;
|
||||
bool hw_ownership;
|
||||
} sde_dbg_base;
|
||||
|
||||
static LIST_HEAD(sde_dbg_dsi_list);
|
||||
@@ -1431,6 +1433,12 @@ static ssize_t sde_recovery_regdump_read(struct file *file, char __user *ubuf,
|
||||
struct sde_dbg_regbuf *rbuf = &dbg_base->regbuf;
|
||||
|
||||
mutex_lock(&sde_dbg_base.mutex);
|
||||
if (!sde_dbg_base.hw_ownership) {
|
||||
pr_debug("op not supported due to HW unavailablity\n");
|
||||
len = -EOPNOTSUPP;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!rbuf->dump_done && !rbuf->cur_blk) {
|
||||
if (!rbuf->buf)
|
||||
rbuf->buf = kzalloc(DUMP_BUF_SIZE, GFP_KERNEL);
|
||||
@@ -1511,6 +1519,12 @@ static ssize_t sde_recovery_dbgbus_dump_read(struct file *file,
|
||||
|
||||
memset(log_buf, 0, sizeof(log_buf));
|
||||
mutex_lock(&sde_dbg_base.mutex);
|
||||
if (!sde_dbg_base.hw_ownership) {
|
||||
pr_debug("op not supported due to HW unavailablity\n");
|
||||
len = -EOPNOTSUPP;
|
||||
goto dump_done;
|
||||
}
|
||||
|
||||
if (!cmn->dumped_content || !cmn->entries_size)
|
||||
goto dump_done;
|
||||
|
||||
@@ -1876,32 +1890,41 @@ static ssize_t sde_dbg_reg_base_reg_write(struct file *file,
|
||||
return -EFAULT;
|
||||
|
||||
mutex_lock(&sde_dbg_base.mutex);
|
||||
if (!sde_dbg_base.hw_ownership) {
|
||||
pr_debug("op not supported due to hw unavailablity\n");
|
||||
count = -EOPNOTSUPP;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (off >= dbg->max_offset) {
|
||||
mutex_unlock(&sde_dbg_base.mutex);
|
||||
return -EFAULT;
|
||||
count = -EFAULT;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!list_empty(&dbg->sub_range_list)) {
|
||||
rc = sde_dbg_reg_base_is_valid_range(dbg, off, cnt);
|
||||
if (!rc)
|
||||
return -EINVAL;
|
||||
if (!rc) {
|
||||
count = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
rc = pm_runtime_get_sync(sde_dbg_base.dev);
|
||||
if (rc < 0) {
|
||||
mutex_unlock(&sde_dbg_base.mutex);
|
||||
pr_err("failed to enable power %d\n", rc);
|
||||
return rc;
|
||||
count = rc;
|
||||
goto end;
|
||||
}
|
||||
|
||||
writel_relaxed(data, dbg->base + off);
|
||||
|
||||
pm_runtime_put_sync(sde_dbg_base.dev);
|
||||
|
||||
mutex_unlock(&sde_dbg_base.mutex);
|
||||
|
||||
pr_debug("addr=%zx data=%x\n", off, data);
|
||||
|
||||
end:
|
||||
mutex_unlock(&sde_dbg_base.mutex);
|
||||
|
||||
return count;
|
||||
}
|
||||
#endif
|
||||
@@ -1933,6 +1956,12 @@ static ssize_t sde_dbg_reg_base_reg_read(struct file *file,
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&sde_dbg_base.mutex);
|
||||
if (!sde_dbg_base.hw_ownership) {
|
||||
pr_debug("op not supported due to hw unavailablity\n");
|
||||
len = -EOPNOTSUPP;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!dbg->buf) {
|
||||
char dump_buf[64];
|
||||
char *ptr;
|
||||
@@ -1943,13 +1972,13 @@ static ssize_t sde_dbg_reg_base_reg_read(struct file *file,
|
||||
dbg->buf = kzalloc(dbg->buf_len, GFP_KERNEL);
|
||||
|
||||
if (!dbg->buf) {
|
||||
mutex_unlock(&sde_dbg_base.mutex);
|
||||
return -ENOMEM;
|
||||
len = -ENOMEM;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (dbg->off % sizeof(u32)) {
|
||||
mutex_unlock(&sde_dbg_base.mutex);
|
||||
return -EFAULT;
|
||||
len = -EFAULT;
|
||||
goto end;
|
||||
}
|
||||
|
||||
ptr = dbg->base + dbg->off;
|
||||
@@ -1957,9 +1986,9 @@ static ssize_t sde_dbg_reg_base_reg_read(struct file *file,
|
||||
|
||||
rc = pm_runtime_get_sync(sde_dbg_base.dev);
|
||||
if (rc < 0) {
|
||||
mutex_unlock(&sde_dbg_base.mutex);
|
||||
pr_err("failed to enable power %d\n", rc);
|
||||
return rc;
|
||||
len = rc;
|
||||
goto end;
|
||||
}
|
||||
|
||||
for (cnt = dbg->cnt; cnt > 0; cnt -= ROW_BYTES) {
|
||||
@@ -1984,18 +2013,20 @@ static ssize_t sde_dbg_reg_base_reg_read(struct file *file,
|
||||
}
|
||||
|
||||
if (*ppos >= dbg->buf_len) {
|
||||
mutex_unlock(&sde_dbg_base.mutex);
|
||||
return 0; /* done reading */
|
||||
len = 0; /* done reading */
|
||||
goto end;
|
||||
}
|
||||
|
||||
len = min(count, dbg->buf_len - (size_t) *ppos);
|
||||
if (copy_to_user(user_buf, dbg->buf + *ppos, len)) {
|
||||
mutex_unlock(&sde_dbg_base.mutex);
|
||||
pr_err("failed to copy to user\n");
|
||||
return -EFAULT;
|
||||
len = -EFAULT;
|
||||
goto end;
|
||||
}
|
||||
|
||||
*ppos += len; /* increase offset */
|
||||
|
||||
end:
|
||||
mutex_unlock(&sde_dbg_base.mutex);
|
||||
|
||||
return len;
|
||||
@@ -2388,6 +2419,13 @@ void sde_dbg_reg_register_dump_range(const char *base_name,
|
||||
range->offset.start, range->offset.end);
|
||||
}
|
||||
|
||||
void sde_dbg_set_hw_ownership_status(bool enable)
|
||||
{
|
||||
mutex_lock(&sde_dbg_base.mutex);
|
||||
sde_dbg_base.hw_ownership = enable;
|
||||
mutex_unlock(&sde_dbg_base.mutex);
|
||||
}
|
||||
|
||||
void sde_dbg_set_sde_top_offset(u32 blk_off)
|
||||
{
|
||||
sde_dbg_base.dbgbus_sde.top_blk_off = blk_off;
|
||||
|
Reference in New Issue
Block a user