Commit c9bc9f50 authored by Prashant Laddha's avatar Prashant Laddha Committed by Mauro Carvalho Chehab

[media] v4l2-dv-timings: fix overflow in gtf timings calculation

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: Martin Bugge <marbugge@cisco.com>
Signed-off-by: default avatarPrashant Laddha <prladdha@cisco.com>
[hans.verkuil@cisco.com: made the denominator u32, since that's what div_u64 expects]
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent ed1bc664
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/videodev2.h> #include <linux/videodev2.h>
#include <linux/v4l2-dv-timings.h> #include <linux/v4l2-dv-timings.h>
#include <media/v4l2-dv-timings.h> #include <media/v4l2-dv-timings.h>
#include <linux/math64.h>
MODULE_AUTHOR("Hans Verkuil"); MODULE_AUTHOR("Hans Verkuil");
MODULE_DESCRIPTION("V4L2 DV Timings Helper Functions"); MODULE_DESCRIPTION("V4L2 DV Timings Helper Functions");
...@@ -554,16 +555,23 @@ bool v4l2_detect_gtf(unsigned frame_height, ...@@ -554,16 +555,23 @@ bool v4l2_detect_gtf(unsigned frame_height,
image_width = (image_width + GTF_CELL_GRAN/2) & ~(GTF_CELL_GRAN - 1); image_width = (image_width + GTF_CELL_GRAN/2) & ~(GTF_CELL_GRAN - 1);
/* Horizontal */ /* Horizontal */
if (default_gtf) if (default_gtf) {
h_blank = ((image_width * GTF_D_C_PRIME * hfreq) - u64 num;
(image_width * GTF_D_M_PRIME * 1000) + u32 den;
(hfreq * (100 - GTF_D_C_PRIME) + GTF_D_M_PRIME * 1000) / 2) /
(hfreq * (100 - GTF_D_C_PRIME) + GTF_D_M_PRIME * 1000); num = ((image_width * GTF_D_C_PRIME * (u64)hfreq) -
else ((u64)image_width * GTF_D_M_PRIME * 1000));
h_blank = ((image_width * GTF_S_C_PRIME * hfreq) - den = hfreq * (100 - GTF_D_C_PRIME) + GTF_D_M_PRIME * 1000;
(image_width * GTF_S_M_PRIME * 1000) + h_blank = div_u64((num + (den >> 1)), den);
(hfreq * (100 - GTF_S_C_PRIME) + GTF_S_M_PRIME * 1000) / 2) / } else {
(hfreq * (100 - GTF_S_C_PRIME) + GTF_S_M_PRIME * 1000); u64 num;
u32 den;
num = ((image_width * GTF_S_C_PRIME * (u64)hfreq) -
((u64)image_width * GTF_S_M_PRIME * 1000));
den = 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)) * h_blank = ((h_blank + GTF_CELL_GRAN) / (2 * GTF_CELL_GRAN)) *
(2 * GTF_CELL_GRAN); (2 * GTF_CELL_GRAN);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment