diff mbox series

[5/7] gpu: ipu-v3: image-convert: bail on invalid tile sizes

Message ID 20190814115444.13024-5-p.zabel@pengutronix.de (mailing list archive)
State New, archived
Headers show
Series [1/7] gpu: ipu-v3: image-convert: fix output seam valid interval | expand

Commit Message

Philipp Zabel Aug. 14, 2019, 11:54 a.m. UTC
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 <p.zabel@pengutronix.de>
---
 drivers/gpu/ipu-v3/ipu-image-convert.c | 27 +++++++++++++++++++++++---
 1 file changed, 24 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/drivers/gpu/ipu-v3/ipu-image-convert.c b/drivers/gpu/ipu-v3/ipu-image-convert.c
index ccf11b654b58..ace831c54ed7 100644
--- a/drivers/gpu/ipu-v3/ipu-image-convert.c
+++ b/drivers/gpu/ipu-v3/ipu-image-convert.c
@@ -834,13 +834,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;
@@ -870,7 +878,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;
 }
 
 /*
@@ -2081,7 +2099,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;