diff options
author | Anson Jacob <Anson.Jacob@amd.com> | 2021-03-01 14:25:44 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2021-04-09 16:41:21 -0400 |
commit | 54718747a6e1037317a8b3610c3be40621b2b75e (patch) | |
tree | 4373da5a31aa5a5140f1e7c9ddfa582beae2870b /drivers/gpu/drm/amd/display | |
parent | 3d223c5528a387f84ed8bdbed2ce05227be9afe0 (diff) |
drm/amd/display: Fix UBSAN: shift-out-of-bounds warning
[Why]
On NAVI14 CONFIG_UBSAN reported shift-out-of-bounds at
display_rq_dlg_calc_20v2.c:304:38
rq_param->misc.rq_c.blk256_height is 0 when chroma(*_c) is invalid.
dml_log2 returns -1023 for log2(0), although log2(0) is undefined.
Which ended up as:
rq_param->dlg.rq_c.swath_height = 1 << -1023
[How]
Fix applied on all dml versions.
1. Ensure dml_log2 is only called if the argument is greater than 0.
2. Subtract req128_l/req128_c from log2_swath_height_l/log2_swath_height_c
only when it is greater than 0.
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Anson Jacob <Anson.Jacob@amd.com>
Reviewed-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Solomon Chiu <solomon.chiu@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display')
5 files changed, 115 insertions, 25 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c index 72423dc425dc..799bae229e67 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c @@ -293,13 +293,31 @@ static void handle_det_buf_split(struct display_mode_lib *mode_lib, if (surf_linear) { log2_swath_height_l = 0; log2_swath_height_c = 0; - } else if (!surf_vert) { - log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l; - log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c; } else { - log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l; - log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c; + unsigned int swath_height_l; + unsigned int swath_height_c; + + if (!surf_vert) { + swath_height_l = rq_param->misc.rq_l.blk256_height; + swath_height_c = rq_param->misc.rq_c.blk256_height; + } else { + swath_height_l = rq_param->misc.rq_l.blk256_width; + swath_height_c = rq_param->misc.rq_c.blk256_width; + } + + if (swath_height_l > 0) + log2_swath_height_l = dml_log2(swath_height_l); + + if (req128_l && log2_swath_height_l > 0) + log2_swath_height_l -= 1; + + if (swath_height_c > 0) + log2_swath_height_c = dml_log2(swath_height_c); + + if (req128_c && log2_swath_height_c > 0) + log2_swath_height_c -= 1; } + rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l; rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c; diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c index 9c78446c3a9d..6a6d5970d1d5 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c @@ -293,13 +293,31 @@ static void handle_det_buf_split(struct display_mode_lib *mode_lib, if (surf_linear) { log2_swath_height_l = 0; log2_swath_height_c = 0; - } else if (!surf_vert) { - log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l; - log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c; } else { - log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l; - log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c; + unsigned int swath_height_l; + unsigned int swath_height_c; + + if (!surf_vert) { + swath_height_l = rq_param->misc.rq_l.blk256_height; + swath_height_c = rq_param->misc.rq_c.blk256_height; + } else { + swath_height_l = rq_param->misc.rq_l.blk256_width; + swath_height_c = rq_param->misc.rq_c.blk256_width; + } + + if (swath_height_l > 0) + log2_swath_height_l = dml_log2(swath_height_l); + + if (req128_l && log2_swath_height_l > 0) + log2_swath_height_l -= 1; + + if (swath_height_c > 0) + log2_swath_height_c = dml_log2(swath_height_c); + + if (req128_c && log2_swath_height_c > 0) + log2_swath_height_c -= 1; } + rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l; rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c; diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c index edd41d358291..dc1c81a6e377 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c @@ -277,13 +277,31 @@ static void handle_det_buf_split( if (surf_linear) { log2_swath_height_l = 0; log2_swath_height_c = 0; - } else if (!surf_vert) { - log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l; - log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c; } else { - log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l; - log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c; + unsigned int swath_height_l; + unsigned int swath_height_c; + + if (!surf_vert) { + swath_height_l = rq_param->misc.rq_l.blk256_height; + swath_height_c = rq_param->misc.rq_c.blk256_height; + } else { + swath_height_l = rq_param->misc.rq_l.blk256_width; + swath_height_c = rq_param->misc.rq_c.blk256_width; + } + + if (swath_height_l > 0) + log2_swath_height_l = dml_log2(swath_height_l); + + if (req128_l && log2_swath_height_l > 0) + log2_swath_height_l -= 1; + + if (swath_height_c > 0) + log2_swath_height_c = dml_log2(swath_height_c); + + if (req128_c && log2_swath_height_c > 0) + log2_swath_height_c -= 1; } + rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l; rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c; diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c index 0f14f205ebe5..04601a767a8f 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c @@ -237,13 +237,31 @@ static void handle_det_buf_split(struct display_mode_lib *mode_lib, if (surf_linear) { log2_swath_height_l = 0; log2_swath_height_c = 0; - } else if (!surf_vert) { - log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l; - log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c; } else { - log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l; - log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c; + unsigned int swath_height_l; + unsigned int swath_height_c; + + if (!surf_vert) { + swath_height_l = rq_param->misc.rq_l.blk256_height; + swath_height_c = rq_param->misc.rq_c.blk256_height; + } else { + swath_height_l = rq_param->misc.rq_l.blk256_width; + swath_height_c = rq_param->misc.rq_c.blk256_width; + } + + if (swath_height_l > 0) + log2_swath_height_l = dml_log2(swath_height_l); + + if (req128_l && log2_swath_height_l > 0) + log2_swath_height_l -= 1; + + if (swath_height_c > 0) + log2_swath_height_c = dml_log2(swath_height_c); + + if (req128_c && log2_swath_height_c > 0) + log2_swath_height_c -= 1; } + rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l; rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c; diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c index 4c3e9cc30167..414da64f5734 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c @@ -344,13 +344,31 @@ static void handle_det_buf_split( if (surf_linear) { log2_swath_height_l = 0; log2_swath_height_c = 0; - } else if (!surf_vert) { - log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l; - log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c; } else { - log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l; - log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c; + unsigned int swath_height_l; + unsigned int swath_height_c; + + if (!surf_vert) { + swath_height_l = rq_param->misc.rq_l.blk256_height; + swath_height_c = rq_param->misc.rq_c.blk256_height; + } else { + swath_height_l = rq_param->misc.rq_l.blk256_width; + swath_height_c = rq_param->misc.rq_c.blk256_width; + } + + if (swath_height_l > 0) + log2_swath_height_l = dml_log2(swath_height_l); + + if (req128_l && log2_swath_height_l > 0) + log2_swath_height_l -= 1; + + if (swath_height_c > 0) + log2_swath_height_c = dml_log2(swath_height_c); + + if (req128_c && log2_swath_height_c > 0) + log2_swath_height_c -= 1; } + rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l; rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c; |