From: George Zhang <[email protected]>

If a plane reaches calculate_mcache_setting with a zero-area viewport,
calculate_mcache_setting exits early with num_mcaches == 0 and
mvmpg_width/height == 0. This will cause a divide-by-zero panic and can
also cause an underflow on num_mcaches.

Fix this by changing calculate_mcache_setting to bool and adding guards
after each calculate_mcache_row_bytes call. If num_mcaches or
mvmpg_width/height is zero, return a false. Callers will propagate the
failure as a rejected mode, which prevents the panic.

Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/5302

Reviewed-by: Sun peng (Leo) Li <[email protected]>
Reviewed-by: Dillon Varone <[email protected]>
Signed-off-by: George Zhang <[email protected]>
Signed-off-by: Fangzhi Zuo <[email protected]>
Tested-by: Dan Wheeler <[email protected]>
---
 .../src/dml2_core/dml2_core_dcn4_calcs.c      | 31 +++++++++++++++----
 1 file changed, 25 insertions(+), 6 deletions(-)

diff --git 
a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
 
b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
index fa78016b32fc..110ab26a6a39 100644
--- 
a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
+++ 
b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
@@ -2453,7 +2453,7 @@ static void calculate_mcache_row_bytes(
        DML_ASSERT(*p->num_mcaches > 0);
 }
 
-static void calculate_mcache_setting(
+static bool calculate_mcache_setting(
        struct dml2_core_internal_scratch *scratch,
        struct dml2_core_calcs_calculate_mcache_setting_params *p)
 {
@@ -2479,7 +2479,7 @@ static void calculate_mcache_setting(
        *p->lc_comb_mcache = 0;
 
        if (!p->dcc_enable)
-               return;
+               return true;
 
        l->is_dual_plane = dml_is_420(p->source_format) || p->source_format == 
dml2_rgbe_alpha;
 
@@ -2516,7 +2516,14 @@ static void calculate_mcache_setting(
        l->l_p.mvmpg_per_mcache_lb = &l->mvmpg_per_mcache_lb_l;
 
        calculate_mcache_row_bytes(scratch, &l->l_p);
-       DML_ASSERT(*p->num_mcaches_l > 0);
+       if (*p->num_mcaches_l == 0 ||
+           (p->surf_vert ? l->mvmpg_height_l : l->mvmpg_width_l) == 0) {
+               DML_LOG_VERBOSE("DML::%s: degenerate luma viewport 
(num_mcaches_l=%u mvmpg_%s_l=%u) — mode not supported\n",
+                       __func__, *p->num_mcaches_l,
+                       p->surf_vert ? "height" : "width",
+                       p->surf_vert ? l->mvmpg_height_l : l->mvmpg_width_l);
+               return false;
+       }
 
        if (l->is_dual_plane) {
                l->c_p.num_chans = p->num_chans;
@@ -2552,7 +2559,14 @@ static void calculate_mcache_setting(
                l->c_p.mvmpg_per_mcache_lb = &l->mvmpg_per_mcache_lb_c;
 
                calculate_mcache_row_bytes(scratch, &l->c_p);
-               DML_ASSERT(*p->num_mcaches_c > 0);
+               if (*p->num_mcaches_c == 0 ||
+                   (p->surf_vert ? l->mvmpg_height_c : l->mvmpg_width_c) == 0) 
{
+                       DML_LOG_VERBOSE("DML::%s: degenerate chroma viewport 
(num_mcaches_c=%u mvmpg_%s_c=%u) — mode not supported\n",
+                               __func__, *p->num_mcaches_c,
+                               p->surf_vert ? "height" : "width",
+                               p->surf_vert ? l->mvmpg_height_c : 
l->mvmpg_width_c);
+                       return false;
+               }
        }
 
        // Sharing for iMALL access
@@ -2662,6 +2676,7 @@ static void calculate_mcache_setting(
 
        *p->mcache_shift_granularity_l = l->mvmpg_access_width_l;
        *p->mcache_shift_granularity_c = l->mvmpg_access_width_c;
+       return true;
 }
 
 static void calculate_mall_bw_overhead_factor(
@@ -9490,7 +9505,10 @@ static bool dml_core_mode_support(struct 
dml2_core_calcs_mode_support_ex *in_out
                        calculate_mcache_setting_params->mall_comb_mcache_c = 
&mode_lib->ms.mall_comb_mcache_c[k];
                        calculate_mcache_setting_params->lc_comb_mcache = 
&mode_lib->ms.lc_comb_mcache[k];
 
-                       calculate_mcache_setting(&mode_lib->scratch, 
calculate_mcache_setting_params);
+                       if (!calculate_mcache_setting(&mode_lib->scratch, 
calculate_mcache_setting_params)) {
+                               mode_lib->ms.support.ModeSupport = false;
+                               return false;
+                       }
                }
 
                calculate_mall_bw_overhead_factor(
@@ -10969,7 +10987,8 @@ static bool dml_core_mode_programming(struct 
dml2_core_calcs_mode_programming_ex
                        calculate_mcache_setting_params->mall_comb_mcache_l = 
&mode_lib->mp.mall_comb_mcache_l[k];
                        calculate_mcache_setting_params->mall_comb_mcache_c = 
&mode_lib->mp.mall_comb_mcache_c[k];
                        calculate_mcache_setting_params->lc_comb_mcache = 
&mode_lib->mp.lc_comb_mcache[k];
-                       calculate_mcache_setting(&mode_lib->scratch, 
calculate_mcache_setting_params);
+                       if (!calculate_mcache_setting(&mode_lib->scratch, 
calculate_mcache_setting_params))
+                               return false;
                }
 
                calculate_mall_bw_overhead_factor(
-- 
2.53.0

Reply via email to