⬢ DragonFlyBSD Kernel Audit
DF-3858 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
+++ b/sys/dev/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
@@ -1323,10 +1323,21 @@
 			&(data->dpm_table.gfx_table);
 	struct vega20_single_dpm_table *golden_sclk_table =
 			&(data->golden_dpm_table.gfx_table);
-	int value = sclk_table->dpm_levels[sclk_table->count - 1].value;
-	int golden_value = golden_sclk_table->dpm_levels
+	int value, golden_value;
+
+	/* DF-3858: zero/empty tables must not reach the count-1 reads below. */
+	if (sclk_table->count == 0 || golden_sclk_table->count == 0)
+		return 0;
+
+	value = sclk_table->dpm_levels[sclk_table->count - 1].value;
+	golden_value = golden_sclk_table->dpm_levels
 			[golden_sclk_table->count - 1].value;
 
+	/* DF-3858: zero golden clock (VBIOS bootup_sclk_in10khz == 0 with
+	 * DPM_GFXCLK disabled) must not reach DIV_ROUND_UP. */
+	if (!golden_value)
+		return 0;
+
 	/* od percentage */
 	value -= golden_value;
 	value = DIV_ROUND_UP(value * 100, golden_value);
@@ -1369,10 +1380,20 @@
 			&(data->dpm_table.mem_table);
 	struct vega20_single_dpm_table *golden_mclk_table =
 			&(data->golden_dpm_table.mem_table);
-	int value = mclk_table->dpm_levels[mclk_table->count - 1].value;
-	int golden_value = golden_mclk_table->dpm_levels
+	int value, golden_value;
+
+	/* DF-3858: zero/empty tables must not reach the count-1 reads below. */
+	if (mclk_table->count == 0 || golden_mclk_table->count == 0)
+		return 0;
+
+	value = mclk_table->dpm_levels[mclk_table->count - 1].value;
+	golden_value = golden_mclk_table->dpm_levels
 			[golden_mclk_table->count - 1].value;
 
+	/* DF-3858: zero golden clock must not reach DIV_ROUND_UP. */
+	if (!golden_value)
+		return 0;
+
 	/* od percentage */
 	value -= golden_value;
 	value = DIV_ROUND_UP(value * 100, golden_value);