summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKrishnankutty Kolathappilly <kkolatha@codeaurora.org>2016-11-16 15:10:18 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2016-12-13 15:20:00 -0800
commit7e4424a1b5f6a6536066cca7aac2c3a23fd39f6f (patch)
treec985a1340e2c00bcd10ead48c23e891b02bfb03c
parenta80e267a8c0d61790c3d1d5f7181ebd1be39c438 (diff)
msm: camera: Synchronize jpeg ISR and userspace call
This will fix the race between jpeg dma ISR and userspace call. Without this fix jpeg dma may randomly crash due to invalid pointer access. Change-Id: I559ae08b9a46d5d3c35f8be509976a25faa967f9 CRs-Fixed: 1083323 Signed-off-by: Krishnankutty Kolathappilly <kkolatha@codeaurora.org>
-rw-r--r--drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c14
-rw-r--r--drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.h1
2 files changed, 12 insertions, 3 deletions
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c b/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c
index 3301fc446193..4b4846907d0f 100644
--- a/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c
+++ b/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c
@@ -537,6 +537,7 @@ static int msm_jpegdma_open(struct file *file)
if (!ctx)
return -ENOMEM;
+ mutex_init(&ctx->lock);
ctx->jdma_device = device;
dev_dbg(ctx->jdma_device->dev, "Jpeg v4l2 dma open\n");
/* Set ctx defaults */
@@ -835,12 +836,13 @@ static int msm_jpegdma_qbuf(struct file *file, void *fh,
int ret;
msm_jpegdma_cast_long_to_buff_ptr(buf->m.userptr, &up_buff);
-
+ mutex_lock(&ctx->lock);
if (!access_ok(VERIFY_READ, up_buff,
sizeof(struct msm_jpeg_dma_buff)) ||
get_user(kp_buff.fd, &up_buff->fd) ||
get_user(kp_buff.offset, &up_buff->offset)) {
dev_err(ctx->jdma_device->dev, "Error getting user data\n");
+ mutex_unlock(&ctx->lock);
return -EFAULT;
}
@@ -849,6 +851,7 @@ static int msm_jpegdma_qbuf(struct file *file, void *fh,
put_user(kp_buff.fd, &up_buff->fd) ||
put_user(kp_buff.offset, &up_buff->offset)) {
dev_err(ctx->jdma_device->dev, "Error putting user data\n");
+ mutex_unlock(&ctx->lock);
return -EFAULT;
}
@@ -871,7 +874,7 @@ static int msm_jpegdma_qbuf(struct file *file, void *fh,
ret = v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
if (ret < 0)
dev_err(ctx->jdma_device->dev, "QBuf fail\n");
-
+ mutex_unlock(&ctx->lock);
return ret;
}
@@ -1032,10 +1035,11 @@ static int msm_jpegdma_s_crop(struct file *file, void *fh,
if (crop->c.height % formats[ctx->format_idx].v_align)
return -EINVAL;
+ mutex_lock(&ctx->lock);
ctx->crop = crop->c;
if (atomic_read(&ctx->active))
ret = msm_jpegdma_update_hw_config(ctx);
-
+ mutex_unlock(&ctx->lock);
return ret;
}
@@ -1240,12 +1244,14 @@ void msm_jpegdma_isr_processing_done(struct msm_jpegdma_device *dma)
ctx = v4l2_m2m_get_curr_priv(dma->m2m_dev);
if (ctx) {
+ mutex_lock(&ctx->lock);
ctx->plane_idx++;
if (ctx->plane_idx >= formats[ctx->format_idx].num_planes) {
src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
if (src_buf == NULL || dst_buf == NULL) {
dev_err(ctx->jdma_device->dev, "Error, buffer list empty\n");
+ mutex_unlock(&ctx->lock);
mutex_unlock(&dma->lock);
return;
}
@@ -1261,11 +1267,13 @@ void msm_jpegdma_isr_processing_done(struct msm_jpegdma_device *dma)
src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
if (src_buf == NULL || dst_buf == NULL) {
dev_err(ctx->jdma_device->dev, "Error, buffer list empty\n");
+ mutex_unlock(&ctx->lock);
mutex_unlock(&dma->lock);
return;
}
msm_jpegdma_process_buffers(ctx, src_buf, dst_buf);
}
+ mutex_unlock(&ctx->lock);
}
mutex_unlock(&dma->lock);
}
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.h b/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.h
index 6a1205daf1d2..4911ce3aa5bd 100644
--- a/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.h
+++ b/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.h
@@ -254,6 +254,7 @@ struct msm_jpegdma_buf_handle {
* @format_idx: Current format index.
*/
struct jpegdma_ctx {
+ struct mutex lock;
struct msm_jpegdma_device *jdma_device;
atomic_t active;
struct completion completion;