Skip to content

Commit

Permalink
drm: Use u64 for intermediate dotclock calculations
Browse files Browse the repository at this point in the history
We have reached the era where monitor bandwidths now exceed 31bits in
frequency calculations, though as we stored them in kHz units we are
safe from overflow in the modelines for some time.

[   48.723720] UBSAN: Undefined behaviour in ../drivers/gpu/drm/drm_modes.c:325:49
[   48.726943] signed integer overflow:
[   48.728503] 2240 * 1000000 cannot be represented in type 'int'

Reported-by: Martin Liška <marxin.liska@gmail.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98372
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/20161021141540.26837-1-chris@chris-wilson.co.uk
  • Loading branch information
Chris Wilson authored and Daniel Vetter committed Oct 21, 2016
1 parent 93ca7e0 commit 8a5bbf3
Showing 1 changed file with 6 additions and 2 deletions.
8 changes: 6 additions & 2 deletions drivers/gpu/drm/drm_modes.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, int hdisplay,
unsigned int vfieldrate, hperiod;
int hdisplay_rnd, hmargin, vdisplay_rnd, vmargin, vsync;
int interlace;
u64 tmp;

/* allocate the drm_display_mode structure. If failure, we will
* return directly
Expand Down Expand Up @@ -322,8 +323,11 @@ struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, int hdisplay,
drm_mode->vsync_end = drm_mode->vsync_start + vsync;
}
/* 15/13. Find pixel clock frequency (kHz for xf86) */
drm_mode->clock = drm_mode->htotal * HV_FACTOR * 1000 / hperiod;
drm_mode->clock -= drm_mode->clock % CVT_CLOCK_STEP;
tmp = drm_mode->htotal; /* perform intermediate calcs in u64 */
tmp *= HV_FACTOR * 1000;
do_div(tmp, hperiod);
tmp -= drm_mode->clock % CVT_CLOCK_STEP;
drm_mode->clock = tmp;
/* 18/16. Find actual vertical frame frequency */
/* ignore - just set the mode flag for interlaced */
if (interlaced) {
Expand Down

0 comments on commit 8a5bbf3

Please sign in to comment.