The intermediate calculation in the expression for hblank can exceed 32 bit signed range. This overflow can lead to negative values for hblank. Typecasting intermediate variable to higher precision. Cc: Hans Verkuil <hans.verkuil@xxxxxxxxx> Cc: Martin Bugge <marbugge@xxxxxxxxx> Signed-off-by: Prashant Laddha <prladdha@xxxxxxxxx> --- drivers/media/v4l2-core/v4l2-dv-timings.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c index 86e11d1..3e14dc4 100644 --- a/drivers/media/v4l2-core/v4l2-dv-timings.c +++ b/drivers/media/v4l2-core/v4l2-dv-timings.c @@ -25,6 +25,7 @@ #include <linux/videodev2.h> #include <linux/v4l2-dv-timings.h> #include <media/v4l2-dv-timings.h> +#include <linux/math64.h> MODULE_AUTHOR("Hans Verkuil"); MODULE_DESCRIPTION("V4L2 DV Timings Helper Functions"); @@ -572,16 +573,25 @@ bool v4l2_detect_gtf(unsigned frame_height, image_width = (image_width + GTF_CELL_GRAN/2) & ~(GTF_CELL_GRAN - 1); /* Horizontal */ - if (default_gtf) - h_blank = ((image_width * GTF_D_C_PRIME * hfreq) - - (image_width * GTF_D_M_PRIME * 1000) + - (hfreq * (100 - GTF_D_C_PRIME) + GTF_D_M_PRIME * 1000) / 2) / - (hfreq * (100 - GTF_D_C_PRIME) + GTF_D_M_PRIME * 1000); - else - h_blank = ((image_width * GTF_S_C_PRIME * hfreq) - - (image_width * GTF_S_M_PRIME * 1000) + - (hfreq * (100 - GTF_S_C_PRIME) + GTF_S_M_PRIME * 1000) / 2) / - (hfreq * (100 - GTF_S_C_PRIME) + GTF_S_M_PRIME * 1000); + if (default_gtf) { + u64 num; + u64 den; + + num = ((image_width * GTF_D_C_PRIME * (u64)hfreq) - + ((u64)image_width * GTF_D_M_PRIME * 1000)); + den = ((u64)hfreq * (100 - GTF_D_C_PRIME) + + GTF_D_M_PRIME * 1000); + h_blank = div_u64((num + (den >> 1)), den); + } else { + u64 num; + u64 den; + + num = ((image_width * GTF_S_C_PRIME * (u64)hfreq) - + ((u64)image_width * GTF_S_M_PRIME * 1000)); + den = ((u64)hfreq * (100 - GTF_S_C_PRIME) + + GTF_S_M_PRIME * 1000); + h_blank = div_u64((num + (den >> 1)), den); + } h_blank = ((h_blank + GTF_CELL_GRAN) / (2 * GTF_CELL_GRAN)) * (2 * GTF_CELL_GRAN); -- 1.9.1 -- 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