summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXiaogang Cui <xiaogang@codeaurora.org>2015-10-09 16:33:08 +0800
committerJeevan Shriram <jshriram@codeaurora.org>2016-05-16 20:10:42 -0700
commit4b36c0b4c4e3036631c46d971707ab5c0b06acdb (patch)
treec50ede470448e8fe4cb618921ae5a9d3fecb52eb
parent59a1235ece88da398c856aef0a8031a1fad7e295 (diff)
soc: qcom: dcc: add check if sram data oversteps
If the size of captured data oversteps over SRAM boundary then it causes corruption of configuration data. Add boundary check while programming configuration linked list in SRAM, to avoid this problem. Change-Id: Idd33f53560585fdbfee4d3822fd93d6f3a365e17 Signed-off-by: Xiaogang Cui <xiaogang@codeaurora.org> Signed-off-by: Shashank Mittal <mittals@codeaurora.org>
-rw-r--r--drivers/soc/qcom/dcc.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/drivers/soc/qcom/dcc.c b/drivers/soc/qcom/dcc.c
index ac2c09be7641..aced50bf7fda 100644
--- a/drivers/soc/qcom/dcc.c
+++ b/drivers/soc/qcom/dcc.c
@@ -253,7 +253,7 @@ static int __dcc_ll_cfg(struct dcc_drvdata *drvdata)
uint32_t prev_addr, addr;
uint32_t prev_off = 0, off;
uint32_t link;
- uint32_t pos;
+ uint32_t pos, total_len = 0;
struct dcc_config_entry *entry;
if (list_empty(&drvdata->config_head)) {
@@ -272,6 +272,7 @@ static int __dcc_ll_cfg(struct dcc_drvdata *drvdata)
addr = (entry->base >> 4) & BM(0, 27);
addr |= BIT(31);
off = entry->offset/4;
+ total_len += entry->len * 4;
if (!prev_addr || prev_addr != addr || prev_off > off) {
/* Check if we need to write link of prev entry */
@@ -289,7 +290,7 @@ static int __dcc_ll_cfg(struct dcc_drvdata *drvdata)
prev_off = 0;
}
- if ((off - prev_off) > 0xFF || entry->len > 0x7F) {
+ if ((off - prev_off) > 0xFF || entry->len > MAX_DCC_LEN) {
dev_err(drvdata->dev,
"DCC: Progamming error! Base: 0x%x, offset 0x%x.\n",
entry->base, entry->offset);
@@ -339,8 +340,25 @@ static int __dcc_ll_cfg(struct dcc_drvdata *drvdata)
dcc_sram_writel(drvdata, 0, sram_offset);
sram_offset += 4;
- drvdata->ram_cfg = (sram_offset / 4);
+ /* check if the data will overstep */
+ if (drvdata->data_sink == DCC_DATA_SINK_SRAM
+ && drvdata->func_type == DCC_FUNC_TYPE_CAPTURE) {
+ if (sram_offset + total_len > drvdata->ram_size) {
+ sram_offset += total_len;
+ goto overstep;
+ }
+ } else {
+ if (sram_offset > drvdata->ram_size)
+ goto overstep;
+ }
+ drvdata->ram_cfg = (sram_offset / 4);
+ return 0;
+overstep:
+ ret = -EINVAL;
+ memset_io(drvdata->ram_base, 0, drvdata->ram_size);
+ dev_err(drvdata->dev, "DCC SRAM oversteps, 0x%x (0x%x)\n",
+ sram_offset, drvdata->ram_size);
err:
return ret;
}