From: Hans Verkuil <hans.verkuil@xxxxxxxxx> Add proper locking to the file operations, allowing for the removal of the V4L2_FL_LOCK_ALL_FOPS flag. Signed-off-by: Hans Verkuil <hans.verkuil@xxxxxxxxx> --- drivers/media/video/s5p-fimc/fimc-m2m.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/drivers/media/video/s5p-fimc/fimc-m2m.c b/drivers/media/video/s5p-fimc/fimc-m2m.c index 4c58e05..1074397 100644 --- a/drivers/media/video/s5p-fimc/fimc-m2m.c +++ b/drivers/media/video/s5p-fimc/fimc-m2m.c @@ -660,6 +660,11 @@ static int fimc_m2m_open(struct file *file) v4l2_fh_init(&ctx->fh, fimc->m2m.vfd); ctx->fimc_dev = fimc; + if (mutex_lock_interruptible(&fimc->lock)) { + kfree(ctx); + return -ERESTARTSYS; + } + /* Default color format */ ctx->s_frame.fmt = fimc_get_format(0); ctx->d_frame.fmt = fimc_get_format(0); @@ -687,6 +692,7 @@ static int fimc_m2m_open(struct file *file) if (fimc->m2m.refcnt++ == 0) set_bit(ST_M2M_RUN, &fimc->state); + mutex_unlock(&fimc->lock); return 0; error_c: @@ -695,6 +701,7 @@ error_fh: v4l2_fh_del(&ctx->fh); v4l2_fh_exit(&ctx->fh); kfree(ctx); + mutex_unlock(&fimc->lock); return ret; } @@ -706,6 +713,7 @@ static int fimc_m2m_release(struct file *file) dbg("pid: %d, state: 0x%lx, refcnt= %d", task_pid_nr(current), fimc->state, fimc->m2m.refcnt); + mutex_lock(&fimc->lock); v4l2_m2m_ctx_release(ctx->m2m_ctx); fimc_ctrls_delete(ctx); v4l2_fh_del(&ctx->fh); @@ -713,6 +721,7 @@ static int fimc_m2m_release(struct file *file) if (--fimc->m2m.refcnt <= 0) clear_bit(ST_M2M_RUN, &fimc->state); + mutex_unlock(&fimc->lock); kfree(ctx); return 0; } @@ -721,16 +730,27 @@ static unsigned int fimc_m2m_poll(struct file *file, struct poll_table_struct *wait) { struct fimc_ctx *ctx = fh_to_ctx(file->private_data); + struct fimc_dev *fimc = ctx->fimc_dev; + unsigned int res; - return v4l2_m2m_poll(file, ctx->m2m_ctx, wait); + mutex_lock(&fimc->lock); + res = v4l2_m2m_poll(file, ctx->m2m_ctx, wait); + mutex_unlock(&fimc->lock); + return res; } static int fimc_m2m_mmap(struct file *file, struct vm_area_struct *vma) { struct fimc_ctx *ctx = fh_to_ctx(file->private_data); + struct fimc_dev *fimc = ctx->fimc_dev; + int ret; - return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma); + if (mutex_lock_interruptible(&fimc->lock)) + return -ERESTARTSYS; + ret = v4l2_m2m_mmap(file, ctx->m2m_ctx, vma); + mutex_unlock(&fimc->lock); + return ret; } static const struct v4l2_file_operations fimc_m2m_fops = { @@ -772,10 +792,6 @@ int fimc_register_m2m_device(struct fimc_dev *fimc, vfd->minor = -1; vfd->release = video_device_release; vfd->lock = &fimc->lock; - /* Locking in file operations other than ioctl should be done - by the driver, not the V4L2 core. - This driver needs auditing so that this flag can be removed. */ - set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags); snprintf(vfd->name, sizeof(vfd->name), "fimc.%d.m2m", fimc->id); video_set_drvdata(vfd, fimc); -- 1.7.10 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html