Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 63746be5 authored by Sylwester Nawrocki's avatar Sylwester Nawrocki Committed by Mauro Carvalho Chehab
Browse files

[media] s5p-fimc: Correct memory allocation for VIDIOC_CREATE_BUFS



The commit 3b4c34aa
"s5p-fimc: Add support for VIDIOC_PREPARE_BUF/CREATE_BUFS ioctls"
added a handler for VIDIOC_CREATE_BUFS ioctl, but the queue_setup
callback wasn't updated to properly interpret the pixel format.
In this situation memory corruption may happen with VIDIOC_CREATE_BUFS
ioctl. Update the queue_setup op to fix this.

Signed-off-by: default avatarSylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: default avatarKyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent e985dbf7
Loading
Loading
Loading
Loading
+20 −11
Original line number Diff line number Diff line
@@ -246,28 +246,37 @@ int fimc_capture_resume(struct fimc_dev *fimc)

}

static unsigned int get_plane_size(struct fimc_frame *fr, unsigned int plane)
{
	if (!fr || plane >= fr->fmt->memplanes)
		return 0;
	return fr->f_width * fr->f_height * fr->fmt->depth[plane] / 8;
}

static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt,
		       unsigned int *num_buffers, unsigned int *num_planes,
		       unsigned int sizes[], void *allocators[])
{
	const struct v4l2_pix_format_mplane *pixm = NULL;
	struct fimc_ctx *ctx = vq->drv_priv;
	struct fimc_fmt *fmt = ctx->d_frame.fmt;
	struct fimc_frame *frame = &ctx->d_frame;
	struct fimc_fmt *fmt = frame->fmt;
	unsigned long wh;
	int i;

	if (!fmt)
	if (pfmt) {
		pixm = &pfmt->fmt.pix_mp;
		fmt = fimc_find_format(&pixm->pixelformat, NULL,
				       FMT_FLAGS_CAM | FMT_FLAGS_M2M, -1);
		wh = pixm->width * pixm->height;
	} else {
		wh = frame->f_width * frame->f_height;
	}

	if (fmt == NULL)
		return -EINVAL;

	*num_planes = fmt->memplanes;

	for (i = 0; i < fmt->memplanes; i++) {
		sizes[i] = get_plane_size(&ctx->d_frame, i);
		unsigned int size = (wh * fmt->depth[i]) / 8;
		if (pixm)
			sizes[i] = max(size, pixm->plane_fmt[i].sizeimage);
		else
			sizes[i] = size;
		allocators[i] = ctx->fimc_dev->alloc_ctx;
	}

+2 −2
Original line number Diff line number Diff line
@@ -1048,14 +1048,14 @@ static int fimc_m2m_g_fmt_mplane(struct file *file, void *fh,
 * @mask: the color flags to match
 * @index: offset in the fimc_formats array, ignored if negative
 */
struct fimc_fmt *fimc_find_format(u32 *pixelformat, u32 *mbus_code,
struct fimc_fmt *fimc_find_format(const u32 *pixelformat, const u32 *mbus_code,
				  unsigned int mask, int index)
{
	struct fimc_fmt *fmt, *def_fmt = NULL;
	unsigned int i;
	int id = 0;

	if (index >= ARRAY_SIZE(fimc_formats))
	if (index >= (int)ARRAY_SIZE(fimc_formats))
		return NULL;

	for (i = 0; i < ARRAY_SIZE(fimc_formats); ++i) {
+1 −1
Original line number Diff line number Diff line
@@ -718,7 +718,7 @@ void fimc_alpha_ctrl_update(struct fimc_ctx *ctx);
int fimc_fill_format(struct fimc_frame *frame, struct v4l2_format *f);
void fimc_adjust_mplane_format(struct fimc_fmt *fmt, u32 width, u32 height,
			       struct v4l2_pix_format_mplane *pix);
struct fimc_fmt *fimc_find_format(u32 *pixelformat, u32 *mbus_code,
struct fimc_fmt *fimc_find_format(const u32 *pixelformat, const u32 *mbus_code,
				  unsigned int mask, int index);

int fimc_check_scaler_ratio(struct fimc_ctx *ctx, int sw, int sh,