From 5fb8b650cc1170f5e7a0f1a4ab3bb2042c007102 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Tue, 13 Aug 2019 14:39:50 +0200 Subject: gpu: ipu-v3: image-convert: bail on invalid tile sizes If we managed to create tiles sized 0x0 because of a bug in the seam calculation, return with an error message instead of letting the driver run into a division by zero later. Also check for tile sizes that are larger than supported by the hardware. Signed-off-by: Philipp Zabel --- drivers/gpu/ipu-v3/ipu-image-convert.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/ipu-v3') diff --git a/drivers/gpu/ipu-v3/ipu-image-convert.c b/drivers/gpu/ipu-v3/ipu-image-convert.c index a3375eec35ce..699c9b45683c 100644 --- a/drivers/gpu/ipu-v3/ipu-image-convert.c +++ b/drivers/gpu/ipu-v3/ipu-image-convert.c @@ -836,13 +836,21 @@ static void find_seams(struct ipu_image_convert_ctx *ctx, in_bottom, flipped_out_top, out_bottom); } -static void calc_tile_dimensions(struct ipu_image_convert_ctx *ctx, - struct ipu_image_convert_image *image) +static int calc_tile_dimensions(struct ipu_image_convert_ctx *ctx, + struct ipu_image_convert_image *image) { struct ipu_image_convert_chan *chan = ctx->chan; struct ipu_image_convert_priv *priv = chan->priv; + unsigned int max_width = 1024; + unsigned int max_height = 1024; unsigned int i; + if (image->type == IMAGE_CONVERT_IN) { + /* Up to 4096x4096 input tile size */ + max_width <<= ctx->downsize_coeff_h; + max_height <<= ctx->downsize_coeff_v; + } + for (i = 0; i < ctx->num_tiles; i++) { struct ipu_image_tile *tile; const unsigned int row = i / image->num_cols; @@ -872,7 +880,17 @@ static void calc_tile_dimensions(struct ipu_image_convert_ctx *ctx, image->type == IMAGE_CONVERT_IN ? "Input" : "Output", row, col, tile->width, tile->height, tile->left, tile->top); + + if (!tile->width || tile->width > max_width || + !tile->height || tile->height > max_height) { + dev_err(priv->ipu->dev, "invalid %s tile size: %ux%u\n", + image->type == IMAGE_CONVERT_IN ? "input" : + "output", tile->width, tile->height); + return -EINVAL; + } } + + return 0; } /* @@ -2083,7 +2101,10 @@ ipu_image_convert_prepare(struct ipu_soc *ipu, enum ipu_ic_task ic_task, find_seams(ctx, s_image, d_image); - calc_tile_dimensions(ctx, s_image); + ret = calc_tile_dimensions(ctx, s_image); + if (ret) + goto out_free; + ret = calc_tile_offsets(ctx, s_image); if (ret) goto out_free; -- cgit v1.2.3