aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2019-08-13 07:28:13 -0700
committerLinux Build Service Account <lnxbuild@localhost>2019-08-13 07:28:13 -0700
commit2395ba8e7c0d08538f32933de4ee5e1400948d16 (patch)
tree3ad5ca9efc2d9d8c6eb7fbef4cc04136982cf053
parente5fa5bc754a84b0e1fbf8f24db1e788f04ac25cd (diff)
parentc67c59a61a1e7f06e6a39e13a3d063b299b0ffaf (diff)
Merge c67c59a61a1e7f06e6a39e13a3d063b299b0ffaf on remote branchLA.UM.6.8.2.r1-02100-SDM710.0
Change-Id: I6414345160fe338a3f2a8476896dcf47b56794f7
-rw-r--r--arch/arm64/mm/init.c2
-rw-r--r--drivers/char/adsprpc.c260
-rw-r--r--drivers/char/diag/diag_dci.c12
-rw-r--r--drivers/char/diag/diag_dci.h4
-rw-r--r--drivers/gpu/msm/kgsl_drawobj.c39
-rw-r--r--drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c22
-rw-r--r--drivers/media/platform/msm/vidc/hfi_response_handler.c184
-rw-r--r--drivers/media/platform/msm/vidc_3x/hfi_response_handler.c167
-rw-r--r--drivers/scsi/ufs/ufs-qcom-ice.c36
-rw-r--r--drivers/tty/serial/msm_geni_serial.c6
-rw-r--r--fs/ext4/move_extent.c13
11 files changed, 580 insertions, 165 deletions
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 2b35b67540b9..0421d0872f95 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -271,7 +271,7 @@ void __init arm64_memblock_init(void)
* memory spans, randomize the linear region as well.
*/
if (memstart_offset_seed > 0 && range >= ARM64_MEMSTART_ALIGN) {
- range = range / ARM64_MEMSTART_ALIGN + 1;
+ range /= ARM64_MEMSTART_ALIGN;
memstart_addr -= ARM64_MEMSTART_ALIGN *
((range * memstart_offset_seed) >> 16);
}
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index ad507e3c1a65..f40a5b9c4a5c 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -60,7 +60,9 @@
#define FASTRPC_ENOSUCH 39
#define VMID_SSC_Q6 5
#define VMID_ADSP_Q6 6
-#define DEBUGFS_SIZE 1024
+#define DEBUGFS_SIZE 3072
+#define UL_SIZE 25
+#define PID_SIZE 10
#define AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME "audio_pdr_adsprpc"
#define AUDIO_PDR_ADSP_SERVICE_NAME "avs/audio"
@@ -404,6 +406,7 @@ struct fastrpc_file {
int refcount;
/* Identifies the device (MINOR_NUM_DEV / MINOR_NUM_SECURE_DEV) */
int dev_minor;
+ char *debug_buf;
};
static struct fastrpc_apps gfa;
@@ -2921,6 +2924,7 @@ static int fastrpc_file_free(struct fastrpc_file *fl)
spin_lock(&fl->apps->hlock);
hlist_del_init(&fl->hn);
spin_unlock(&fl->apps->hlock);
+ kfree(fl->debug_buf);
if (!fl->sctx) {
kfree(fl);
@@ -3109,105 +3113,208 @@ static int fastrpc_debugfs_open(struct inode *inode, struct file *filp)
static ssize_t fastrpc_debugfs_read(struct file *filp, char __user *buffer,
size_t count, loff_t *position)
{
+ struct fastrpc_apps *me = &gfa;
struct fastrpc_file *fl = filp->private_data;
struct hlist_node *n;
- struct fastrpc_buf *buf = NULL;
struct fastrpc_mmap *map = NULL;
+ struct fastrpc_mmap *gmaps = NULL;
struct smq_invoke_ctx *ictx = NULL;
- struct fastrpc_channel_ctx *chan;
- struct fastrpc_session_ctx *sess;
+ struct fastrpc_channel_ctx *chan = NULL;
unsigned int len = 0;
- int i, j, ret = 0;
+ int i, j, sess_used = 0, ret = 0;
char *fileinfo = NULL;
+ char single_line[UL_SIZE] = "----------------";
+ char title[UL_SIZE] = "=========================";
fileinfo = kzalloc(DEBUGFS_SIZE, GFP_KERNEL);
if (!fileinfo)
goto bail;
if (fl == NULL) {
+ len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
+ "\n%s %s %s\n", title, " CHANNEL INFO ", title);
+ len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
+ "%-8s|%-9s|%-9s|%-14s|%-9s|%-13s\n",
+ "susbsys", "refcount", "sesscount", "issubsystemup",
+ "ssrcount", "session_used");
+ len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
+ "-%s%s%s%s-\n", single_line, single_line,
+ single_line, single_line);
for (i = 0; i < NUM_CHANNELS; i++) {
+ sess_used = 0;
chan = &gcinfo[i];
len += scnprintf(fileinfo + len,
- DEBUGFS_SIZE - len, "%s\n\n",
- chan->name);
+ DEBUGFS_SIZE - len, "%-8s", chan->subsys);
+ len += scnprintf(fileinfo + len,
+ DEBUGFS_SIZE - len, "|%-9d",
+ chan->kref.refcount.counter);
len += scnprintf(fileinfo + len,
- DEBUGFS_SIZE - len, "%s %d\n",
- "secure:", chan->secure);
+ DEBUGFS_SIZE - len, "|%-9d",
+ chan->sesscount);
len += scnprintf(fileinfo + len,
- DEBUGFS_SIZE - len, "%s %d\n",
- "sesscount:", chan->sesscount);
+ DEBUGFS_SIZE - len, "|%-14d",
+ chan->issubsystemup);
+ len += scnprintf(fileinfo + len,
+ DEBUGFS_SIZE - len, "|%-9d",
+ chan->ssrcount);
for (j = 0; j < chan->sesscount; j++) {
- sess = &chan->session[j];
- len += scnprintf(fileinfo + len,
- DEBUGFS_SIZE - len,
- "%s%d\n\n", "SESSION", j);
- len += scnprintf(fileinfo + len,
- DEBUGFS_SIZE - len,
- "%s %d\n", "sid:",
- sess->smmu.cb);
- len += scnprintf(fileinfo + len,
- DEBUGFS_SIZE - len,
- "%s %d\n", "SECURE:",
- sess->smmu.secure);
- }
+ sess_used += chan->session[j].used;
+ }
+ len += scnprintf(fileinfo + len,
+ DEBUGFS_SIZE - len, "|%-13d\n", sess_used);
+
+ }
+ len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
+ "\n%s%s%s\n", "=============",
+ " CMA HEAP ", "==============");
+ len += scnprintf(fileinfo + len,
+ DEBUGFS_SIZE - len, "%-20s|%-20s\n", "addr", "size");
+ len += scnprintf(fileinfo + len,
+ DEBUGFS_SIZE - len, "--%s%s---\n",
+ single_line, single_line);
+ len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
+ "0x%-18llX", me->range.addr);
+ len += scnprintf(fileinfo + len,
+ DEBUGFS_SIZE - len, "|0x%-18llX\n", me->range.size);
+ len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
+ "\n==========%s %s %s===========\n",
+ title, " GMAPS ", title);
+ len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
+ "%-20s|%-20s|%-20s|%-20s\n",
+ "fd", "phys", "size", "va");
+ len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
+ "%s%s%s%s%s\n", single_line, single_line,
+ single_line, single_line, single_line);
+ hlist_for_each_entry_safe(gmaps, n, &me->maps, hn) {
+ len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
+ "%-20d|0x%-18llX|0x%-18X|0x%-20lX\n\n",
+ gmaps->fd, gmaps->phys,
+ (uint32_t)gmaps->size,
+ gmaps->va);
+ }
+ len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
+ "%-20s|%-20s|%-20s|%-20s\n",
+ "len", "refs", "raddr", "flags");
+ len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
+ "%s%s%s%s%s\n", single_line, single_line,
+ single_line, single_line, single_line);
+ hlist_for_each_entry_safe(gmaps, n, &me->maps, hn) {
+ len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
+ "0x%-18X|%-20d|%-20lu|%-20u\n",
+ (uint32_t)gmaps->len, gmaps->refs,
+ gmaps->raddr, gmaps->flags);
}
} else {
len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
- "%s %d\n\n",
- "PROCESS_ID:", fl->tgid);
+ "\n%s %13s %d\n", "cid", ":", fl->cid);
len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
- "%s %d\n\n",
- "CHANNEL_ID:", fl->cid);
+ "%s %12s %d\n", "tgid", ":", fl->tgid);
len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
- "%s %d\n\n",
- "SSRCOUNT:", fl->ssrcount);
+ "%s %7s %d\n", "sessionid", ":", fl->sessionid);
len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
- "%s %d\n\n",
- "DEV_MINOR:", fl->dev_minor);
+ "%s %8s %d\n", "ssrcount", ":", fl->ssrcount);
len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
- "%s %d\n\n",
- "KERNEL MEMORY ALLOCATION:", 1);
+ "%s %8s %d\n", "refcount", ":", fl->refcount);
len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
- "%s\n",
- "LIST OF CACHED BUFS:");
- spin_lock(&fl->hlock);
- hlist_for_each_entry_safe(buf, n, &fl->cached_bufs, hn) {
- len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
- "%s %pK %s %pK %s %llx %s %lx\n",
- "buf:", buf, "buf->virt:", buf->virt,
- "buf->phys:", buf->phys,
- "buf->dma_attr:", buf->dma_attr);
+ "%s %14s %d\n", "pd", ":", fl->pd);
+ len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
+ "%s %9s %s\n", "spdname", ":", fl->spdname);
+ len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
+ "%s %6s %d\n", "file_close", ":", fl->file_close);
+ len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
+ "%s %8s %d\n", "sharedcb", ":", fl->sharedcb);
+ len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
+ "%s %9s %d\n", "profile", ":", fl->profile);
+ len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
+ "%s %3s %d\n", "smmu.coherent", ":",
+ fl->sctx->smmu.coherent);
+ len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
+ "%s %4s %d\n", "smmu.enabled", ":",
+ fl->sctx->smmu.enabled);
+ len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
+ "%s %9s %d\n", "smmu.cb", ":", fl->sctx->smmu.cb);
+ len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
+ "%s %5s %d\n", "smmu.secure", ":",
+ fl->sctx->smmu.secure);
+ len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
+ "%s %5s %d\n", "smmu.faults", ":",
+ fl->sctx->smmu.faults);
+ len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
+ "%s %s %d\n", "link.link_state",
+ ":", *&me->channel[fl->cid].link.link_state);
+
+ len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
+ "\n=======%s %s %s======\n", title,
+ " LIST OF MAPS ", title);
+
+ len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
+ "%-20s|%-20s|%-20s\n", "va", "phys", "size");
+ len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
+ "%s%s%s%s%s\n",
+ single_line, single_line, single_line,
+ single_line, single_line);
+ hlist_for_each_entry_safe(map, n, &fl->maps, hn) {
+ len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
+ "0x%-20lX|0x%-20llX|0x%-20zu\n\n",
+ map->va, map->phys,
+ map->size);
}
len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
- "\n%s\n",
- "LIST OF MAPS:");
+ "%-20s|%-20s|%-20s|%-20s\n",
+ "len", "refs",
+ "raddr", "uncached");
+ len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
+ "%s%s%s%s%s\n",
+ single_line, single_line, single_line,
+ single_line, single_line);
hlist_for_each_entry_safe(map, n, &fl->maps, hn) {
- len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
- "%s %pK %s %lx %s %llx\n",
- "map:", map,
- "map->va:", map->va,
- "map->phys:", map->phys);
+ len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
+ "%-20zu|%-20d|0x%-20lX|%-20d\n\n",
+ map->len, map->refs, map->raddr,
+ map->uncached);
}
len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
- "\n%s\n",
- "LIST OF PENDING SMQCONTEXTS:");
+ "%-20s|%-20s\n", "secure", "attr");
+ len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
+ "%s%s%s%s%s\n",
+ single_line, single_line, single_line,
+ single_line, single_line);
+ hlist_for_each_entry_safe(map, n, &fl->maps, hn) {
+ len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
+ "%-20d|0x%-20lX\n\n",
+ map->secure, map->attr);
+ }
+ len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
+ "\n%s %s %s\n", title,
+ " LIST OF PENDING SMQCONTEXTS ", title);
+
+ len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
+ "%-20s|%-10s|%-10s|%-10s|%-20s\n",
+ "sc", "pid", "tgid", "used", "ctxid");
+ len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
+ "%s%s%s%s%s\n", single_line, single_line,
+ single_line, single_line, single_line);
hlist_for_each_entry_safe(ictx, n, &fl->clst.pending, hn) {
len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
- "%s %pK %s %u %s %u %s %u\n",
- "smqcontext:", ictx,
- "sc:", ictx->sc,
- "tid:", ictx->pid,
- "handle", ictx->rpra->h);
+ "0x%-18X|%-10d|%-10d|%-10zu|0x%-20llX\n\n",
+ ictx->sc, ictx->pid, ictx->tgid,
+ ictx->used, ictx->ctxid);
}
+
len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
- "\n%s\n",
- "LIST OF INTERRUPTED SMQCONTEXTS:");
- hlist_for_each_entry_safe(ictx, n, &fl->clst.interrupted, hn) {
+ "\n%s %s %s\n", title,
+ " LIST OF INTERRUPTED SMQCONTEXTS ", title);
+
len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
- "%s %pK %s %u %s %u %s %u\n",
- "smqcontext:", ictx,
- "sc:", ictx->sc,
- "tid:", ictx->pid,
- "handle", ictx->rpra->h);
+ "%-20s|%-10s|%-10s|%-10s|%-20s\n",
+ "sc", "pid", "tgid", "used", "ctxid");
+ len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
+ "%s%s%s%s%s\n", single_line, single_line,
+ single_line, single_line, single_line);
+ hlist_for_each_entry_safe(ictx, n, &fl->clst.interrupted, hn) {
+ len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
+ "%-20u|%-20d|%-20d|%-20zu|0x%-20llX\n\n",
+ ictx->sc, ictx->pid, ictx->tgid,
+ ictx->used, ictx->ctxid);
}
spin_unlock(&fl->hlock);
}
@@ -3302,6 +3409,8 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp)
struct dentry *debugfs_file;
struct fastrpc_file *fl = NULL;
struct fastrpc_apps *me = &gfa;
+ char strpid[PID_SIZE];
+ int buf_size = 0;
/*
* Indicates the device node opened
@@ -3319,8 +3428,18 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp)
VERIFY(err, NULL != (fl = kzalloc(sizeof(*fl), GFP_KERNEL)));
if (err)
return err;
- debugfs_file = debugfs_create_file(current->comm, 0644, debugfs_root,
- fl, &debugfs_fops);
+ snprintf(strpid, PID_SIZE, "%d", current->pid);
+ buf_size = strlen(current->comm) + strlen("_") + strlen(strpid) + 1;
+ fl->debug_buf = kzalloc(buf_size, GFP_KERNEL);
+ if (fl->debug_buf != NULL) {
+ snprintf(fl->debug_buf, UL_SIZE, "%.10s%s%d",
+ current->comm, "_", current->pid);
+ debugfs_file = debugfs_create_file(fl->debug_buf, 0644,
+ debugfs_root, fl, &debugfs_fops);
+
+ if (debugfs_file != NULL)
+ fl->debugfs_file = debugfs_file;
+ }
context_list_ctor(&fl->clst);
spin_lock_init(&fl->hlock);
INIT_HLIST_HEAD(&fl->maps);
@@ -3336,8 +3455,6 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp)
fl->dev_minor = dev_minor;
fl->init_mem = NULL;
- if (debugfs_file != NULL)
- fl->debugfs_file = debugfs_file;
fl->qos_request = 0;
fl->refcount = 0;
filp->private_data = fl;
@@ -4226,8 +4343,8 @@ static int __init fastrpc_device_init(void)
struct device *secure_dev = NULL;
int err = 0, i;
+ debugfs_root = debugfs_create_dir("adsprpc", NULL);
memset(me, 0, sizeof(*me));
-
fastrpc_init(me);
me->dev = NULL;
me->glink = true;
@@ -4283,12 +4400,11 @@ static int __init fastrpc_device_init(void)
gcinfo[i].subsys,
&me->channel[i].nb);
}
-
me->client = msm_ion_client_create(DEVICE_NAME);
VERIFY(err, !IS_ERR_OR_NULL(me->client));
if (err)
goto device_create_bail;
- debugfs_root = debugfs_create_dir("adsprpc", NULL);
+
return 0;
device_create_bail:
for (i = 0; i < NUM_CHANNELS; i++) {
diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c
index 7f2fdd259f6d..a537cfb6aa23 100644
--- a/drivers/char/diag/diag_dci.c
+++ b/drivers/char/diag/diag_dci.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2019, 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
@@ -2070,9 +2070,9 @@ int diag_process_dci_transaction(unsigned char *buf, int len)
uint8_t *event_mask_ptr;
struct diag_dci_client_tbl *dci_entry = NULL;
- if (!temp) {
- pr_err("diag: Invalid buffer in %s\n", __func__);
- return -ENOMEM;
+ if (!temp || len < sizeof(int)) {
+ pr_err("diag: Invalid input in %s\n", __func__);
+ return -EINVAL;
}
/* This is Pkt request/response transaction */
@@ -2128,7 +2128,7 @@ int diag_process_dci_transaction(unsigned char *buf, int len)
count = 0; /* iterator for extracting log codes */
while (count < num_codes) {
- if (read_len >= USER_SPACE_DATA) {
+ if (read_len + sizeof(uint16_t) > len) {
pr_err("diag: dci: Invalid length for log type in %s",
__func__);
mutex_unlock(&driver->dci_mutex);
@@ -2242,7 +2242,7 @@ int diag_process_dci_transaction(unsigned char *buf, int len)
pr_debug("diag: head of dci event mask %pK\n", event_mask_ptr);
count = 0; /* iterator for extracting log codes */
while (count < num_codes) {
- if (read_len >= USER_SPACE_DATA) {
+ if (read_len + sizeof(int) > len) {
pr_err("diag: dci: Invalid length for event type in %s",
__func__);
mutex_unlock(&driver->dci_mutex);
diff --git a/drivers/char/diag/diag_dci.h b/drivers/char/diag/diag_dci.h
index 61eb3f540c39..e3c7cba7d9c8 100644
--- a/drivers/char/diag/diag_dci.h
+++ b/drivers/char/diag/diag_dci.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2016, 2019 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
@@ -27,7 +27,7 @@
#define DISABLE_LOG_MASK 0
#define MAX_EVENT_SIZE 512
#define DCI_CLIENT_INDEX_INVALID -1
-#define DCI_LOG_CON_MIN_LEN 14
+#define DCI_LOG_CON_MIN_LEN 16
#define DCI_EVENT_CON_MIN_LEN 16
#define EXT_HDR_LEN 8
diff --git a/drivers/gpu/msm/kgsl_drawobj.c b/drivers/gpu/msm/kgsl_drawobj.c
index 3dbaea4a0ccb..0226b681e92d 100644
--- a/drivers/gpu/msm/kgsl_drawobj.c
+++ b/drivers/gpu/msm/kgsl_drawobj.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, 2019, 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
@@ -201,8 +201,13 @@ static void drawobj_sync_func(struct kgsl_device *device,
trace_syncpoint_timestamp_expire(event->syncobj,
event->context, event->timestamp);
- drawobj_sync_expire(device, event);
- kgsl_context_put(event->context);
+ /*
+ * Put down the context ref count only if
+ * this thread successfully clears the pending bit mask.
+ */
+ if (drawobj_sync_expire(device, event))
+ kgsl_context_put(event->context);
+
kgsl_drawobj_put(&event->syncobj->base);
}
@@ -232,33 +237,24 @@ static void drawobj_destroy_sparse(struct kgsl_drawobj *drawobj)
static void drawobj_destroy_sync(struct kgsl_drawobj *drawobj)
{
struct kgsl_drawobj_sync *syncobj = SYNCOBJ(drawobj);
- unsigned long pending = 0;
unsigned int i;
/* Zap the canary timer */
del_timer_sync(&syncobj->timer);
/*
- * Copy off the pending list and clear each pending event atomically -
- * this will render any subsequent asynchronous callback harmless.
- * This marks each event for deletion. If any pending fence callbacks
- * run between now and the actual cancel, the associated structures
- * are kfreed only in the cancel call.
- */
- for_each_set_bit(i, &syncobj->pending, KGSL_MAX_SYNCPOINTS) {
- if (test_and_clear_bit(i, &syncobj->pending))
- __set_bit(i, &pending);
- }
-
- /*
* Clear all pending events - this will render any subsequent async
* callbacks harmless
*/
for (i = 0; i < syncobj->numsyncs; i++) {
struct kgsl_drawobj_sync_event *event = &syncobj->synclist[i];
- /* Don't do anything if the event has already expired */
- if (!test_bit(i, &pending))
+ /*
+ * Don't do anything if the event has already expired.
+ * If this thread clears the pending bit mask then it is
+ * responsible for doing context put.
+ */
+ if (!test_and_clear_bit(i, &syncobj->pending))
continue;
switch (event->type) {
@@ -266,6 +262,11 @@ static void drawobj_destroy_sync(struct kgsl_drawobj *drawobj)
kgsl_cancel_event(drawobj->device,
&event->context->events, event->timestamp,
drawobj_sync_func, event);
+ /*
+ * Do context put here to make sure the context is alive
+ * till this thread cancels kgsl event.
+ */
+ kgsl_context_put(event->context);
break;
case KGSL_CMD_SYNCPOINT_TYPE_FENCE:
kgsl_sync_fence_async_cancel(event->handle);
@@ -278,7 +279,7 @@ static void drawobj_destroy_sync(struct kgsl_drawobj *drawobj)
* If we cancelled an event, there's a good chance that the context is
* on a dispatcher queue, so schedule to get it removed.
*/
- if (!bitmap_empty(&pending, KGSL_MAX_SYNCPOINTS) &&
+ if (!bitmap_empty(&syncobj->pending, KGSL_MAX_SYNCPOINTS) &&
drawobj->device->ftbl->drawctxt_sched)
drawobj->device->ftbl->drawctxt_sched(drawobj->device,
drawobj->context);
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c
index 70f3e04bf9c5..7796aa34fd58 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c
@@ -438,17 +438,32 @@ static int32_t cam_eeprom_parse_memory_map(
else if (cmm_hdr->cmd_type == CAMERA_SENSOR_CMD_TYPE_WAIT)
validate_size = sizeof(struct cam_cmd_unconditional_wait);
- if (remain_buf_len < validate_size) {
+ if (remain_buf_len < validate_size ||
+ *num_map >= (MSM_EEPROM_MAX_MEM_MAP_CNT *
+ MSM_EEPROM_MEMORY_MAP_MAX_SIZE)) {
CAM_ERR(CAM_EEPROM, "not enough buffer");
return -EINVAL;
}
switch (cmm_hdr->cmd_type) {
case CAMERA_SENSOR_CMD_TYPE_I2C_RNDM_WR:
i2c_random_wr = (struct cam_cmd_i2c_random_wr *)cmd_buf;
+
+ if (i2c_random_wr->header.count == 0 ||
+ i2c_random_wr->header.count >= MSM_EEPROM_MAX_MEM_MAP_CNT ||
+ (size_t)*num_map >= ((MSM_EEPROM_MAX_MEM_MAP_CNT *
+ MSM_EEPROM_MEMORY_MAP_MAX_SIZE) -
+ i2c_random_wr->header.count)) {
+ CAM_ERR(CAM_EEPROM, "OOB Error");
+ return -EINVAL;
+ }
cmd_length_in_bytes = sizeof(struct cam_cmd_i2c_random_wr) +
((i2c_random_wr->header.count - 1) *
sizeof(struct i2c_random_wr_payload));
+ if (cmd_length_in_bytes > remain_buf_len) {
+ CAM_ERR(CAM_EEPROM, "Not enough buffer remaining");
+ return -EINVAL;
+ }
for (cnt = 0; cnt < (i2c_random_wr->header.count);
cnt++) {
map[*num_map + cnt].page.addr =
@@ -471,6 +486,11 @@ static int32_t cam_eeprom_parse_memory_map(
i2c_cont_rd = (struct cam_cmd_i2c_continuous_rd *)cmd_buf;
cmd_length_in_bytes = sizeof(struct cam_cmd_i2c_continuous_rd);
+ if (i2c_cont_rd->header.count >= U32_MAX - data->num_data) {
+ CAM_ERR(CAM_EEPROM,
+ "int overflow on eeprom memory block");
+ return -EINVAL;
+ }
map[*num_map].mem.addr = i2c_cont_rd->reg_addr;
map[*num_map].mem.addr_type = i2c_cont_rd->header.addr_type;
map[*num_map].mem.data_type = i2c_cont_rd->header.data_type;
diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c
index f1be1a7ddded..b255c6f1e209 100644
--- a/drivers/media/platform/msm/vidc/hfi_response_handler.c
+++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c
@@ -103,12 +103,22 @@ static enum msm_vidc_pixel_depth get_hal_pixel_depth(u32 hfi_bit_depth)
return MSM_VIDC_BIT_DEPTH_UNSUPPORTED;
}
+static inline int validate_pkt_size(u32 rem_size, u32 msg_size)
+{
+ if (rem_size < msg_size) {
+ dprintk(VIDC_ERR, "%s: bad_pkt_size: %d\n",
+ __func__, rem_size);
+ return false;
+ }
+ return true;
+}
+
static int hfi_process_sess_evt_seq_changed(u32 device_id,
struct hfi_msg_event_notify_packet *pkt,
struct msm_vidc_cb_info *info)
{
struct msm_vidc_cb_event event_notify = {0};
- int num_properties_changed;
+ u32 num_properties_changed, rem_size;
struct hfi_frame_size *frame_sz;
struct hfi_profile_level *profile_level;
struct hfi_bit_depth *pixel_depth;
@@ -121,11 +131,9 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
enum msm_vidc_pixel_depth luma_bit_depth, chroma_bit_depth;
struct hfi_colour_space *colour_info;
- if (sizeof(struct hfi_msg_event_notify_packet) > pkt->size) {
- dprintk(VIDC_ERR,
- "hal_process_session_init_done: bad_pkt_size\n");
+ if (!validate_pkt_size(pkt->size,
+ sizeof(struct hfi_msg_event_notify_packet)))
return -E2BIG;
- }
event_notify.device_id = device_id;
event_notify.session_id = (void *)(uintptr_t)pkt->session_id;
@@ -146,10 +154,18 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
if (num_properties_changed) {
data_ptr = (u8 *) &pkt->rg_ext_event_data[0];
+ rem_size = pkt->size - sizeof(struct
+ hfi_msg_event_notify_packet) + sizeof(u32);
do {
+ if (!validate_pkt_size(rem_size, sizeof(u32)))
+ return -E2BIG;
prop_id = (int) *((u32 *)data_ptr);
+ rem_size -= sizeof(u32);
switch (prop_id) {
case HFI_PROPERTY_PARAM_FRAME_SIZE:
+ if (!validate_pkt_size(rem_size, sizeof(struct
+ hfi_frame_size)))
+ return -E2BIG;
data_ptr = data_ptr + sizeof(u32);
frame_sz =
(struct hfi_frame_size *) data_ptr;
@@ -159,8 +175,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
frame_sz->height, frame_sz->width);
data_ptr +=
sizeof(struct hfi_frame_size);
+ rem_size -= sizeof(struct hfi_frame_size);
break;
case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT:
+ if (!validate_pkt_size(rem_size, sizeof(struct
+ hfi_profile_level)))
+ return -E2BIG;
data_ptr = data_ptr + sizeof(u32);
profile_level =
(struct hfi_profile_level *) data_ptr;
@@ -171,8 +191,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
profile_level->level);
data_ptr +=
sizeof(struct hfi_profile_level);
+ rem_size -= sizeof(struct hfi_profile_level);
break;
case HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH:
+ if (!validate_pkt_size(rem_size, sizeof(struct
+ hfi_bit_depth)))
+ return -E2BIG;
data_ptr = data_ptr + sizeof(u32);
pixel_depth = (struct hfi_bit_depth *) data_ptr;
/*
@@ -203,8 +227,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
event_notify.bit_depth, luma_bit_depth,
chroma_bit_depth);
data_ptr += sizeof(struct hfi_bit_depth);
+ rem_size -= sizeof(struct hfi_bit_depth);
break;
case HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT:
+ if (!validate_pkt_size(rem_size, sizeof(struct
+ hfi_pic_struct)))
+ return -E2BIG;
data_ptr = data_ptr + sizeof(u32);
pic_struct = (struct hfi_pic_struct *) data_ptr;
event_notify.pic_struct =
@@ -214,8 +242,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
pic_struct->progressive_only);
data_ptr +=
sizeof(struct hfi_pic_struct);
+ rem_size -= sizeof(struct hfi_pic_struct);
break;
case HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE:
+ if (!validate_pkt_size(rem_size, sizeof(struct
+ hfi_colour_space)))
+ return -E2BIG;
data_ptr = data_ptr + sizeof(u32);
colour_info =
(struct hfi_colour_space *) data_ptr;
@@ -226,8 +258,11 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
colour_info->colour_space);
data_ptr +=
sizeof(struct hfi_colour_space);
+ rem_size -= sizeof(struct hfi_colour_space);
break;
case HFI_PROPERTY_CONFIG_VDEC_ENTROPY:
+ if (!validate_pkt_size(rem_size, sizeof(u32)))
+ return -E2BIG;
data_ptr = data_ptr + sizeof(u32);
entropy_mode = *(u32 *)data_ptr;
event_notify.entropy_mode = entropy_mode;
@@ -235,8 +270,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
"Entropy Mode: 0x%x\n", entropy_mode);
data_ptr +=
sizeof(u32);
+ rem_size -= sizeof(u32);
break;
case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS:
+ if (!validate_pkt_size(rem_size, sizeof(struct
+ hfi_buffer_requirements)))
+ return -E2BIG;
data_ptr = data_ptr + sizeof(u32);
buf_req =
(struct hfi_buffer_requirements *)
@@ -248,8 +287,13 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
event_notify.capture_buf_count);
data_ptr +=
sizeof(struct hfi_buffer_requirements);
+ rem_size -=
+ sizeof(struct hfi_buffer_requirements);
break;
case HFI_INDEX_EXTRADATA_INPUT_CROP:
+ if (!validate_pkt_size(rem_size, sizeof(struct
+ hfi_index_extradata_input_crop_payload)))
+ return -E2BIG;
data_ptr = data_ptr + sizeof(u32);
crop_info = (struct
hfi_index_extradata_input_crop_payload *)
@@ -270,6 +314,8 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
data_ptr +=
sizeof(struct
hfi_index_extradata_input_crop_payload);
+ rem_size -= sizeof(struct
+ hfi_index_extradata_input_crop_payload);
break;
default:
dprintk(VIDC_ERR,
@@ -722,7 +768,7 @@ static inline void copy_cap_prop(
}
static int hfi_fill_codec_info(u8 *data_ptr,
- struct vidc_hal_sys_init_done *sys_init_done) {
+ struct vidc_hal_sys_init_done *sys_init_done, u32 rem_size) {
u32 i;
u32 codecs = 0, codec_count = 0, size = 0;
struct msm_vidc_capability *capability;
@@ -732,6 +778,9 @@ static int hfi_fill_codec_info(u8 *data_ptr,
if (prop_id == HFI_PROPERTY_PARAM_CODEC_SUPPORTED) {
struct hfi_codec_supported *prop;
+ if (!validate_pkt_size(rem_size - sizeof(u32),
+ sizeof(struct hfi_codec_supported)))
+ return -E2BIG;
data_ptr = data_ptr + sizeof(u32);
prop = (struct hfi_codec_supported *) data_ptr;
sys_init_done->dec_codec_supported =
@@ -739,6 +788,8 @@ static int hfi_fill_codec_info(u8 *data_ptr,
sys_init_done->enc_codec_supported =
prop->encoder_codec_supported;
size = sizeof(struct hfi_codec_supported) + sizeof(u32);
+ rem_size -=
+ sizeof(struct hfi_codec_supported) + sizeof(u32);
} else {
dprintk(VIDC_WARN,
"%s: prop_id %#x, expected codec_supported property\n",
@@ -779,14 +830,22 @@ static int hfi_fill_codec_info(u8 *data_ptr,
}
sys_init_done->codec_count = codec_count;
+ if (!validate_pkt_size(rem_size, sizeof(u32)))
+ return -E2BIG;
prop_id = *((u32 *)(orig_data_ptr + size));
if (prop_id == HFI_PROPERTY_PARAM_MAX_SESSIONS_SUPPORTED) {
- struct hfi_max_sessions_supported *prop =
- (struct hfi_max_sessions_supported *)
+ struct hfi_max_sessions_supported *prop;
+
+ if (!validate_pkt_size(rem_size - sizeof(u32), sizeof(struct
+ hfi_max_sessions_supported)))
+ return -E2BIG;
+ prop = (struct hfi_max_sessions_supported *)
(orig_data_ptr + size + sizeof(u32));
sys_init_done->max_sessions_supported = prop->max_sessions;
size += sizeof(struct hfi_max_sessions_supported) + sizeof(u32);
+ rem_size -=
+ sizeof(struct hfi_max_sessions_supported) + sizeof(u32);
dprintk(VIDC_DBG, "max_sessions_supported %d\n",
prop->max_sessions);
}
@@ -878,6 +937,21 @@ static enum vidc_status hfi_parse_init_done_properties(
u32 prop_id, next_offset;
u32 codecs = 0, domain = 0;
+#define VALIDATE_PROPERTY_STRUCTURE_SIZE(pkt_size, property_size) ({\
+ if (pkt_size < property_size) { \
+ status = VIDC_ERR_BAD_PARAM; \
+ break; \
+ } \
+})
+
+#define VALIDATE_PROPERTY_PAYLOAD_SIZE(pkt_size, payload_size, \
+ property_count) ({\
+ if (pkt_size/payload_size < property_count) { \
+ status = VIDC_ERR_BAD_PARAM; \
+ break; \
+ } \
+})
+
while (status == VIDC_ERR_NONE && num_properties &&
rem_bytes >= sizeof(u32)) {
@@ -891,6 +965,10 @@ static enum vidc_status hfi_parse_init_done_properties(
(struct hfi_codec_mask_supported *)
(data_ptr + next_offset);
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ sizeof(*prop));
+
codecs = prop->codecs;
domain = prop->video_domains;
next_offset += sizeof(struct hfi_codec_mask_supported);
@@ -903,11 +981,14 @@ static enum vidc_status hfi_parse_init_done_properties(
(struct hfi_capability_supported_info *)
(data_ptr + next_offset);
- if ((rem_bytes - next_offset) < prop->num_capabilities *
- sizeof(struct hfi_capability_supported)) {
- status = VIDC_ERR_BAD_PARAM;
- break;
- }
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ sizeof(*prop));
+ VALIDATE_PROPERTY_PAYLOAD_SIZE(rem_bytes -
+ next_offset - sizeof(u32),
+ sizeof(struct hfi_capability_supported),
+ prop->num_capabilities);
+
next_offset += sizeof(u32) +
prop->num_capabilities *
sizeof(struct hfi_capability_supported);
@@ -928,10 +1009,10 @@ static enum vidc_status hfi_parse_init_done_properties(
char *fmt_ptr;
struct hfi_uncompressed_plane_info *plane_info;
- if ((rem_bytes - next_offset) < sizeof(*prop)) {
- status = VIDC_ERR_BAD_PARAM;
- break;
- }
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ sizeof(*prop));
+
num_format_entries = prop->format_entries;
next_offset = sizeof(*prop);
fmt_ptr = (char *)&prop->rg_format_info[0];
@@ -942,11 +1023,10 @@ static enum vidc_status hfi_parse_init_done_properties(
plane_info =
(struct hfi_uncompressed_plane_info *) fmt_ptr;
- if ((rem_bytes - next_offset) <
- sizeof(*plane_info)) {
- status = VIDC_ERR_BAD_PARAM;
- break;
- }
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ sizeof(*plane_info));
+
bytes_to_skip = sizeof(*plane_info) -
sizeof(struct
hfi_uncompressed_plane_constraints) +
@@ -954,6 +1034,10 @@ static enum vidc_status hfi_parse_init_done_properties(
sizeof(struct
hfi_uncompressed_plane_constraints);
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ bytes_to_skip);
+
fmt_ptr += bytes_to_skip;
next_offset += bytes_to_skip;
num_format_entries--;
@@ -966,6 +1050,15 @@ static enum vidc_status hfi_parse_init_done_properties(
struct hfi_properties_supported *prop =
(struct hfi_properties_supported *)
(data_ptr + next_offset);
+
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ sizeof(*prop));
+ VALIDATE_PROPERTY_PAYLOAD_SIZE(rem_bytes -
+ next_offset - sizeof(*prop) +
+ sizeof(u32), sizeof(u32),
+ prop->num_properties);
+
next_offset += sizeof(*prop) - sizeof(u32)
+ prop->num_properties * sizeof(u32);
num_properties--;
@@ -977,6 +1070,15 @@ static enum vidc_status hfi_parse_init_done_properties(
(struct hfi_profile_level_supported *)
(data_ptr + next_offset);
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ sizeof(*prop));
+ VALIDATE_PROPERTY_PAYLOAD_SIZE(rem_bytes -
+ next_offset -
+ sizeof(u32),
+ sizeof(struct hfi_profile_level),
+ prop->profile_count);
+
next_offset += sizeof(u32) +
prop->profile_count *
sizeof(struct hfi_profile_level);
@@ -997,6 +1099,14 @@ static enum vidc_status hfi_parse_init_done_properties(
}
case HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SUPPORTED:
{
+ struct hfi_nal_stream_format_supported *prop =
+ (struct hfi_nal_stream_format_supported *)
+ (data_ptr + next_offset);
+
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ sizeof(*prop));
+
next_offset +=
sizeof(struct hfi_nal_stream_format_supported);
num_properties--;
@@ -1004,12 +1114,18 @@ static enum vidc_status hfi_parse_init_done_properties(
}
case HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SELECT:
{
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ sizeof(u32));
next_offset += sizeof(u32);
num_properties--;
break;
}
case HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH:
{
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ sizeof(struct hfi_intra_refresh));
next_offset +=
sizeof(struct hfi_intra_refresh);
num_properties--;
@@ -1017,6 +1133,9 @@ static enum vidc_status hfi_parse_init_done_properties(
}
case HFI_PROPERTY_TME_VERSION_SUPPORTED:
{
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ sizeof(u32));
capabilities->tme_version =
*((u32 *)(data_ptr + next_offset));
next_offset +=
@@ -1030,8 +1149,13 @@ static enum vidc_status hfi_parse_init_done_properties(
__func__, data_ptr, prop_id);
break;
}
- rem_bytes -= next_offset;
- data_ptr += next_offset;
+
+ if (rem_bytes > next_offset) {
+ rem_bytes -= next_offset;
+ data_ptr += next_offset;
+ } else {
+ rem_bytes = 0;
+ }
}
return status;
@@ -1042,7 +1166,8 @@ enum vidc_status hfi_process_sys_init_done_prop_read(
struct vidc_hal_sys_init_done *sys_init_done)
{
enum vidc_status status = VIDC_ERR_NONE;
- u32 rem_bytes, bytes_read, num_properties;
+ int bytes_read;
+ u32 rem_bytes, num_properties;
u8 *data_ptr;
if (!pkt || !sys_init_done) {
@@ -1050,6 +1175,11 @@ enum vidc_status hfi_process_sys_init_done_prop_read(
"hfi_msg_sys_init_done: Invalid input\n");
return VIDC_ERR_FAIL;
}
+ if (pkt->size < sizeof(struct hfi_msg_sys_init_done_packet)) {
+ dprintk(VIDC_ERR, "%s: bad_packet_size: %d\n",
+ __func__, pkt->size);
+ return VIDC_ERR_FAIL;
+ }
rem_bytes = pkt->size - sizeof(struct
hfi_msg_sys_init_done_packet) + sizeof(u32);
@@ -1077,7 +1207,9 @@ enum vidc_status hfi_process_sys_init_done_prop_read(
"Venus didn't set any properties in SYS_INIT_DONE");
return status;
}
- bytes_read = hfi_fill_codec_info(data_ptr, sys_init_done);
+ bytes_read = hfi_fill_codec_info(data_ptr, sys_init_done, rem_bytes);
+ if (bytes_read < 0)
+ return VIDC_ERR_FAIL;
data_ptr += bytes_read;
rem_bytes -= bytes_read;
num_properties--;
diff --git a/drivers/media/platform/msm/vidc_3x/hfi_response_handler.c b/drivers/media/platform/msm/vidc_3x/hfi_response_handler.c
index f8b5d1c086aa..a3b8cd23f180 100644
--- a/drivers/media/platform/msm/vidc_3x/hfi_response_handler.c
+++ b/drivers/media/platform/msm/vidc_3x/hfi_response_handler.c
@@ -100,12 +100,22 @@ static enum msm_vidc_pixel_depth get_hal_pixel_depth(u32 hfi_bit_depth)
return MSM_VIDC_BIT_DEPTH_UNSUPPORTED;
}
+static inline int validate_pkt_size(u32 rem_size, u32 msg_size)
+{
+ if (rem_size < msg_size) {
+ dprintk(VIDC_ERR, "%s: bad_pkt_size: %d\n",
+ __func__, rem_size);
+ return false;
+ }
+ return true;
+}
+
static int hfi_process_sess_evt_seq_changed(u32 device_id,
struct hfi_msg_event_notify_packet *pkt,
struct msm_vidc_cb_info *info)
{
struct msm_vidc_cb_event event_notify = {0};
- int num_properties_changed;
+ u32 num_properties_changed, rem_size;
struct hfi_frame_size *frame_sz;
struct hfi_profile_level *profile_level;
struct hfi_bit_depth *pixel_depth;
@@ -118,11 +128,9 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
/* Initialize pic_struct to unknown as default */
//event_notify.pic_struct = MSM_VIDC_PIC_STRUCT_UNKNOWN;
- if (sizeof(struct hfi_msg_event_notify_packet) > pkt->size) {
- dprintk(VIDC_ERR,
- "hal_process_session_init_done: bad_pkt_size\n");
+ if (!validate_pkt_size(pkt->size,
+ sizeof(struct hfi_msg_event_notify_packet)))
return -E2BIG;
- }
event_notify.device_id = device_id;
event_notify.session_id = (void *)(uintptr_t)pkt->session_id;
@@ -143,10 +151,18 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
if (num_properties_changed) {
data_ptr = (u8 *) &pkt->rg_ext_event_data[0];
+ rem_size = pkt->size - sizeof(struct
+ hfi_msg_event_notify_packet) + sizeof(u32);
do {
+ if (!validate_pkt_size(rem_size, sizeof(u32)))
+ return -E2BIG;
prop_id = (int) *((u32 *)data_ptr);
+ rem_size -= sizeof(u32);
switch (prop_id) {
case HFI_PROPERTY_PARAM_FRAME_SIZE:
+ if (!validate_pkt_size(rem_size, sizeof(struct
+ hfi_frame_size)))
+ return -E2BIG;
data_ptr = data_ptr + sizeof(u32);
frame_sz =
(struct hfi_frame_size *) data_ptr;
@@ -156,8 +172,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
frame_sz->height, frame_sz->width);
data_ptr +=
sizeof(struct hfi_frame_size);
+ rem_size -= sizeof(struct hfi_frame_size);
break;
case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT:
+ if (!validate_pkt_size(rem_size, sizeof(struct
+ hfi_profile_level)))
+ return -E2BIG;
data_ptr = data_ptr + sizeof(u32);
profile_level =
(struct hfi_profile_level *) data_ptr;
@@ -166,8 +186,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
profile_level->level);
data_ptr +=
sizeof(struct hfi_profile_level);
+ rem_size -= sizeof(struct hfi_profile_level);
break;
case HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH:
+ if (!validate_pkt_size(rem_size, sizeof(struct
+ hfi_bit_depth)))
+ return -E2BIG;
data_ptr = data_ptr + sizeof(u32);
pixel_depth = (struct hfi_bit_depth *) data_ptr;
/*
@@ -198,8 +222,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
event_notify.bit_depth, luma_bit_depth,
chroma_bit_depth);
data_ptr += sizeof(struct hfi_bit_depth);
+ rem_size -= sizeof(struct hfi_bit_depth);
break;
case HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT:
+ if (!validate_pkt_size(rem_size, sizeof(struct
+ hfi_pic_struct)))
+ return -E2BIG;
data_ptr = data_ptr + sizeof(u32);
pic_struct = (struct hfi_pic_struct *) data_ptr;
event_notify.pic_struct =
@@ -209,8 +237,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
pic_struct->progressive_only);
data_ptr +=
sizeof(struct hfi_pic_struct);
+ rem_size -= sizeof(struct hfi_pic_struct);
break;
case HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE:
+ if (!validate_pkt_size(rem_size, sizeof(struct
+ hfi_colour_space)))
+ return -E2BIG;
data_ptr = data_ptr + sizeof(u32);
colour_info =
(struct hfi_colour_space *) data_ptr;
@@ -221,6 +253,8 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
colour_info->colour_space);
data_ptr +=
sizeof(struct hfi_colour_space);
+ rem_size -= sizeof(struct hfi_colour_space);
+ break;
break;
default:
dprintk(VIDC_ERR,
@@ -579,7 +613,7 @@ static inline void copy_cap_prop(
}
static int hfi_fill_codec_info(u8 *data_ptr,
- struct vidc_hal_sys_init_done *sys_init_done) {
+ struct vidc_hal_sys_init_done *sys_init_done, u32 rem_size) {
u32 i;
u32 codecs = 0, codec_count = 0, size = 0;
struct msm_vidc_capability *capability;
@@ -589,6 +623,9 @@ static int hfi_fill_codec_info(u8 *data_ptr,
if (prop_id == HFI_PROPERTY_PARAM_CODEC_SUPPORTED) {
struct hfi_codec_supported *prop;
+ if (!validate_pkt_size(rem_size - sizeof(u32),
+ sizeof(struct hfi_codec_supported)))
+ return -E2BIG;
data_ptr = data_ptr + sizeof(u32);
prop = (struct hfi_codec_supported *) data_ptr;
sys_init_done->dec_codec_supported =
@@ -596,6 +633,8 @@ static int hfi_fill_codec_info(u8 *data_ptr,
sys_init_done->enc_codec_supported =
prop->encoder_codec_supported;
size = sizeof(struct hfi_codec_supported) + sizeof(u32);
+ rem_size -=
+ sizeof(struct hfi_codec_supported) + sizeof(u32);
} else {
dprintk(VIDC_WARN,
"%s: prop_id %#x, expected codec_supported property\n",
@@ -636,14 +675,22 @@ static int hfi_fill_codec_info(u8 *data_ptr,
}
sys_init_done->codec_count = codec_count;
+ if (!validate_pkt_size(rem_size, sizeof(u32)))
+ return -E2BIG;
prop_id = *((u32 *)(orig_data_ptr + size));
if (prop_id == HFI_PROPERTY_PARAM_MAX_SESSIONS_SUPPORTED) {
- struct hfi_max_sessions_supported *prop =
- (struct hfi_max_sessions_supported *)
+ struct hfi_max_sessions_supported *prop;
+
+ if (!validate_pkt_size(rem_size - sizeof(u32), sizeof(struct
+ hfi_max_sessions_supported)))
+ return -E2BIG;
+ prop = (struct hfi_max_sessions_supported *)
(orig_data_ptr + size + sizeof(u32));
sys_init_done->max_sessions_supported = prop->max_sessions;
size += sizeof(struct hfi_max_sessions_supported) + sizeof(u32);
+ rem_size -=
+ sizeof(struct hfi_max_sessions_supported) + sizeof(u32);
dprintk(VIDC_DBG, "max_sessions_supported %d\n",
prop->max_sessions);
}
@@ -798,6 +845,20 @@ static enum vidc_status hfi_parse_init_done_properties(
{
enum vidc_status status = VIDC_ERR_NONE;
u32 prop_id, next_offset;
+#define VALIDATE_PROPERTY_STRUCTURE_SIZE(pkt_size, property_size) ({\
+ if (pkt_size < property_size) { \
+ status = VIDC_ERR_BAD_PARAM; \
+ break; \
+ } \
+})
+
+#define VALIDATE_PROPERTY_PAYLOAD_SIZE(pkt_size, payload_size, \
+ property_count) ({\
+ if (pkt_size/payload_size < property_count) { \
+ status = VIDC_ERR_BAD_PARAM; \
+ break; \
+ } \
+})
while (status == VIDC_ERR_NONE && num_properties &&
rem_bytes >= sizeof(u32)) {
@@ -811,6 +872,9 @@ static enum vidc_status hfi_parse_init_done_properties(
struct hfi_codec_mask_supported *prop =
(struct hfi_codec_mask_supported *)
(data_ptr + next_offset);
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ sizeof(*prop));
codecs = prop->codecs;
domain = prop->video_domains;
@@ -824,11 +888,14 @@ static enum vidc_status hfi_parse_init_done_properties(
(struct hfi_capability_supported_info *)
(data_ptr + next_offset);
- if ((rem_bytes - next_offset) < prop->num_capabilities *
- sizeof(struct hfi_capability_supported)) {
- status = VIDC_ERR_BAD_PARAM;
- break;
- }
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ sizeof(*prop));
+ VALIDATE_PROPERTY_PAYLOAD_SIZE(rem_bytes -
+ next_offset - sizeof(u32),
+ sizeof(struct hfi_capability_supported),
+ prop->num_capabilities);
+
next_offset += sizeof(u32) +
prop->num_capabilities *
sizeof(struct hfi_capability_supported);
@@ -849,10 +916,10 @@ static enum vidc_status hfi_parse_init_done_properties(
char *fmt_ptr;
struct hfi_uncompressed_plane_info *plane_info;
- if ((rem_bytes - next_offset) < sizeof(*prop)) {
- status = VIDC_ERR_BAD_PARAM;
- break;
- }
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ sizeof(*prop));
+
num_format_entries = prop->format_entries;
next_offset = sizeof(*prop);
fmt_ptr = (char *)&prop->rg_format_info[0];
@@ -863,17 +930,19 @@ static enum vidc_status hfi_parse_init_done_properties(
plane_info =
(struct hfi_uncompressed_plane_info *) fmt_ptr;
- if ((rem_bytes - next_offset) <
- sizeof(*plane_info)) {
- status = VIDC_ERR_BAD_PARAM;
- break;
- }
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ sizeof(*plane_info));
+
bytes_to_skip = sizeof(*plane_info) -
sizeof(struct
hfi_uncompressed_plane_constraints) +
plane_info->num_planes *
sizeof(struct
hfi_uncompressed_plane_constraints);
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ bytes_to_skip);
fmt_ptr += bytes_to_skip;
next_offset += bytes_to_skip;
@@ -887,6 +956,13 @@ static enum vidc_status hfi_parse_init_done_properties(
struct hfi_properties_supported *prop =
(struct hfi_properties_supported *)
(data_ptr + next_offset);
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ sizeof(*prop));
+ VALIDATE_PROPERTY_PAYLOAD_SIZE(rem_bytes -
+ next_offset - sizeof(*prop) +
+ sizeof(u32), sizeof(u32),
+ prop->num_properties);
next_offset += sizeof(*prop) - sizeof(u32)
+ prop->num_properties * sizeof(u32);
num_properties--;
@@ -903,6 +979,9 @@ static enum vidc_status hfi_parse_init_done_properties(
(struct hfi_profile_level_supported *)
(data_ptr + next_offset);
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ sizeof(*prop));
ptr = (char *) &prop->rg_profile_level[0];
prof_count = prop->profile_count;
next_offset += sizeof(u32);
@@ -915,6 +994,9 @@ static enum vidc_status hfi_parse_init_done_properties(
}
while (prof_count) {
prof_level = (struct hfi_profile_level *)ptr;
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ sizeof(*prof_level));
capability.
profile_level.profile_level[count].profile
= prof_level->profile;
@@ -931,6 +1013,9 @@ static enum vidc_status hfi_parse_init_done_properties(
}
case HFI_PROPERTY_PARAM_INTERLACE_FORMAT_SUPPORTED:
{
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ sizeof(struct hfi_interlace_format_supported));
next_offset +=
sizeof(struct hfi_interlace_format_supported);
num_properties--;
@@ -938,6 +1023,9 @@ static enum vidc_status hfi_parse_init_done_properties(
}
case HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SUPPORTED:
{
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ sizeof(struct hfi_nal_stream_format_supported));
next_offset +=
sizeof(struct hfi_nal_stream_format_supported);
num_properties--;
@@ -945,18 +1033,27 @@ static enum vidc_status hfi_parse_init_done_properties(
}
case HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SELECT:
{
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ sizeof(u32));
next_offset += sizeof(u32);
num_properties--;
break;
}
case HFI_PROPERTY_PARAM_MAX_SEQUENCE_HEADER_SIZE:
{
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ sizeof(u32));
next_offset += sizeof(u32);
num_properties--;
break;
}
case HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH:
{
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ sizeof(struct hfi_intra_refresh));
next_offset +=
sizeof(struct hfi_intra_refresh);
num_properties--;
@@ -967,13 +1064,21 @@ static enum vidc_status hfi_parse_init_done_properties(
struct hfi_buffer_alloc_mode_supported *prop =
(struct hfi_buffer_alloc_mode_supported *)
(data_ptr + next_offset);
-
+ VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+ next_offset,
+ sizeof(*prop));
if (prop->num_entries >= 32) {
dprintk(VIDC_ERR,
"%s - num_entries: %d from f/w seems suspect\n",
__func__, prop->num_entries);
break;
}
+ VALIDATE_PROPERTY_PAYLOAD_SIZE(rem_bytes -
+ next_offset -
+ sizeof(struct hfi_buffer_alloc_mode_supported) +
+ sizeof(u32),
+ sizeof(u32),
+ prop->num_entries);
next_offset +=
sizeof(struct hfi_buffer_alloc_mode_supported) -
sizeof(u32) + prop->num_entries * sizeof(u32);
@@ -991,8 +1096,12 @@ static enum vidc_status hfi_parse_init_done_properties(
__func__, data_ptr, prop_id);
break;
}
+ if (rem_bytes > next_offset) {
rem_bytes -= next_offset;
data_ptr += next_offset;
+ } else {
+ rem_bytes = 0;
+ }
}
return status;
@@ -1003,7 +1112,8 @@ enum vidc_status hfi_process_sys_init_done_prop_read(
struct vidc_hal_sys_init_done *sys_init_done)
{
enum vidc_status status = VIDC_ERR_NONE;
- u32 rem_bytes, bytes_read, num_properties;
+ int bytes_read;
+ u32 rem_bytes, num_properties;
u8 *data_ptr;
u32 codecs = 0, domain = 0;
@@ -1012,6 +1122,11 @@ enum vidc_status hfi_process_sys_init_done_prop_read(
"hfi_msg_sys_init_done: Invalid input\n");
return VIDC_ERR_FAIL;
}
+ if (pkt->size < sizeof(struct hfi_msg_sys_init_done_packet)) {
+ dprintk(VIDC_ERR, "%s: bad packet size: %d\n",
+ __func__, pkt->size);
+ return VIDC_ERR_FAIL;
+ }
rem_bytes = pkt->size - sizeof(struct
hfi_msg_sys_init_done_packet) + sizeof(u32);
@@ -1039,7 +1154,9 @@ enum vidc_status hfi_process_sys_init_done_prop_read(
"Venus didn't set any properties in SYS_INIT_DONE");
return status;
}
- bytes_read = hfi_fill_codec_info(data_ptr, sys_init_done);
+ bytes_read = hfi_fill_codec_info(data_ptr, sys_init_done, rem_bytes);
+ if (bytes_read < 0)
+ return VIDC_ERR_FAIL;
data_ptr += bytes_read;
rem_bytes -= bytes_read;
num_properties--;
diff --git a/drivers/scsi/ufs/ufs-qcom-ice.c b/drivers/scsi/ufs/ufs-qcom-ice.c
index d4fe6eede3b4..a2b725706667 100644
--- a/drivers/scsi/ufs/ufs-qcom-ice.c
+++ b/drivers/scsi/ufs/ufs-qcom-ice.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2019, 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
@@ -226,14 +226,17 @@ int ufs_qcom_ice_init(struct ufs_qcom_host *qcom_host)
}
qcom_host->dbg_print_en |= UFS_QCOM_ICE_DEFAULT_DBG_PRINT_EN;
- ice_workqueue = alloc_workqueue("ice-set-key",
- WQ_MEM_RECLAIM | WQ_HIGHPRI, 0);
if (!ice_workqueue) {
- dev_err(ufs_dev, "%s: workqueue allocation failed.\n",
+ ice_workqueue = alloc_workqueue("ice-set-key",
+ WQ_MEM_RECLAIM | WQ_HIGHPRI, 0);
+ if (!ice_workqueue) {
+ dev_err(ufs_dev, "%s: workqueue allocation failed.\n",
__func__);
- goto out;
+ err = -ENOMEM;
+ goto out;
+ }
+ INIT_WORK(&qcom_host->ice_cfg_work, ufs_qcom_ice_cfg_work);
}
- INIT_WORK(&qcom_host->ice_cfg_work, ufs_qcom_ice_cfg_work);
out:
return err;
@@ -286,6 +289,17 @@ int ufs_qcom_ice_req_setup(struct ufs_qcom_host *qcom_host,
* propagate so it will be re-queued.
*/
if (err == -EAGAIN) {
+ if (!ice_workqueue) {
+ spin_unlock_irqrestore(
+ &qcom_host->ice_work_lock,
+ flags);
+
+ dev_err(qcom_host->hba->dev,
+ "%s: error %d workqueue NULL\n",
+ __func__, err);
+ return -EINVAL;
+ }
+
dev_dbg(qcom_host->hba->dev,
"%s: scheduling task for ice setup\n",
__func__);
@@ -405,6 +419,16 @@ int ufs_qcom_ice_cfg_start(struct ufs_qcom_host *qcom_host,
* propagate so it will be re-queued.
*/
if (err == -EAGAIN) {
+ if (!ice_workqueue) {
+ spin_unlock_irqrestore(
+ &qcom_host->ice_work_lock,
+ flags);
+
+ dev_err(qcom_host->hba->dev,
+ "%s: error %d workqueue NULL\n",
+ __func__, err);
+ return -EINVAL;
+ }
dev_dbg(qcom_host->hba->dev,
"%s: scheduling task for ice setup\n",
diff --git a/drivers/tty/serial/msm_geni_serial.c b/drivers/tty/serial/msm_geni_serial.c
index 0821084e9ab6..572fdabe8b9a 100644
--- a/drivers/tty/serial/msm_geni_serial.c
+++ b/drivers/tty/serial/msm_geni_serial.c
@@ -1936,7 +1936,7 @@ static void msm_geni_serial_set_termios(struct uart_port *uport,
break;
}
-
+ uport->status &= ~(UPSTAT_AUTOCTS);
/* stop bits */
if (termios->c_cflag & CSTOPB)
stop_bit_len = TX_STOP_BIT_LEN_2;
@@ -1944,8 +1944,10 @@ static void msm_geni_serial_set_termios(struct uart_port *uport,
stop_bit_len = TX_STOP_BIT_LEN_1;
/* flow control, clear the CTS_MASK bit if using flow control. */
- if (termios->c_cflag & CRTSCTS)
+ if (termios->c_cflag & CRTSCTS) {
tx_trans_cfg &= ~UART_CTS_MASK;
+ uport->status |= UPSTAT_AUTOCTS;
+ }
else
tx_trans_cfg |= UART_CTS_MASK;
/* status bits to ignore */
diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
index 578f8c33fb44..4c7ee3d0ba80 100644
--- a/fs/ext4/move_extent.c
+++ b/fs/ext4/move_extent.c
@@ -598,11 +598,14 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp, __u64 orig_blk,
return -EOPNOTSUPP;
}
- if (ext4_encrypted_inode(orig_inode) ||
- ext4_encrypted_inode(donor_inode)) {
- ext4_msg(orig_inode->i_sb, KERN_ERR,
- "Online defrag not supported for encrypted files");
- return -EOPNOTSUPP;
+ if (!fscrypt_using_hardware_encryption(orig_inode) ||
+ !fscrypt_using_hardware_encryption(donor_inode)) {
+ if (ext4_encrypted_inode(orig_inode) ||
+ ext4_encrypted_inode(donor_inode)) {
+ ext4_msg(orig_inode->i_sb, KERN_ERR,
+ "Online defrag not supported for encrypted files");
+ return -EOPNOTSUPP;
+ }
}
/* Protect orig and donor inodes against a truncate */