diff options
| author | Krishnankutty Kolathappilly <kkolatha@codeaurora.org> | 2016-11-16 15:10:18 -0800 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-12-13 15:20:00 -0800 |
| commit | 7e4424a1b5f6a6536066cca7aac2c3a23fd39f6f (patch) | |
| tree | c985a1340e2c00bcd10ead48c23e891b02bfb03c | |
| parent | a80e267a8c0d61790c3d1d5f7181ebd1be39c438 (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.c | 14 | ||||
| -rw-r--r-- | drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.h | 1 |
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; |
