⬢ DragonFlyBSD Kernel Audit
DF-4036 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/drm/amd/powerplay/smumgr/polaris10_smumgr.c
+++ b/sys/dev/drm/amd/powerplay/smumgr/polaris10_smumgr.c
@@ -997,10 +997,12 @@
 
 	polaris10_get_sclk_range_table(hwmgr, &(smu_data->smc_state_table));
 
-	for (i = 0; i < dpm_table->sclk_table.count; i++) {
+	for (i = 0; i < dpm_table->sclk_table.count &&
+			i < SMU74_MAX_LEVELS_GRAPHICS; i++) {
 
 		result = polaris10_populate_single_graphic_level(hwmgr,
-				dpm_table->sclk_table.dpm_levels[i].value,
+				dpm_table->sclk_table.dpm_levels[i %
+					MAX_REGULAR_DPM_NUMBER].value,
 				&(smu_data->smc_state_table.GraphicsLevel[i]));
 		if (result)
 			return result;
@@ -1014,8 +1016,8 @@
 		smu_data->smc_state_table.GraphicsLevel[0].SclkSetting.SSc_En = 0;
 
 	smu_data->smc_state_table.GraphicsLevel[0].EnabledForActivity = 1;
-	smu_data->smc_state_table.GraphicsDpmLevelCount =
-			(uint8_t)dpm_table->sclk_table.count;
+	smu_data->smc_state_table.GraphicsDpmLevelCount = (uint8_t)min_t(uint32_t,
+			dpm_table->sclk_table.count, SMU74_MAX_LEVELS_GRAPHICS);
 	hw_data->dpm_level_enable_mask.sclk_dpm_enable_mask =
 			phm_get_dpm_level_enable_mask_value(&dpm_table->sclk_table);
 
@@ -1025,7 +1027,8 @@
 				"There must be 1 or more PCIE levels defined in PPTable.",
 				return -EINVAL);
 		max_entry = pcie_entry_cnt - 1;
-		for (i = 0; i < dpm_table->sclk_table.count; i++)
+		for (i = 0; i < dpm_table->sclk_table.count &&
+				i < SMU74_MAX_LEVELS_GRAPHICS; i++)
 			levels[i].pcieDpmLevel =
 					(uint8_t) ((i < max_entry) ? i : max_entry);
 	} else {
@@ -1050,7 +1053,8 @@
 						hightest_pcie_level_enabled;
 
 		/* set pcieDpmLevel to hightest_pcie_level_enabled */
-		for (i = 2; i < dpm_table->sclk_table.count; i++)
+		for (i = 2; i < dpm_table->sclk_table.count &&
+				i < SMU74_MAX_LEVELS_GRAPHICS; i++)
 			levels[i].pcieDpmLevel = hightest_pcie_level_enabled;
 
 		/* set pcieDpmLevel to lowest_pcie_level_enabled */
@@ -1135,14 +1139,18 @@
 			smu_data->smc_state_table.MemoryLevel;
 	uint32_t i;
 
-	for (i = 0; i < dpm_table->mclk_table.count; i++) {
-		PP_ASSERT_WITH_CODE((0 != dpm_table->mclk_table.dpm_levels[i].value),
+	for (i = 0; i < dpm_table->mclk_table.count &&
+			i < SMU74_MAX_LEVELS_MEMORY; i++) {
+		PP_ASSERT_WITH_CODE((0 != dpm_table->mclk_table.dpm_levels[i %
+					MAX_REGULAR_DPM_NUMBER].value),
 				"can not populate memory level as memory clock is zero",
 				return -EINVAL);
 		result = polaris10_populate_single_memory_level(hwmgr,
-				dpm_table->mclk_table.dpm_levels[i].value,
+				dpm_table->mclk_table.dpm_levels[i %
+					MAX_REGULAR_DPM_NUMBER].value,
 				&levels[i]);
-		if (i == dpm_table->mclk_table.count - 1) {
+		if (i == (uint32_t)min_t(uint32_t, dpm_table->mclk_table.count,
+					SMU74_MAX_LEVELS_MEMORY) - 1) {
 			levels[i].DisplayWatermark = PPSMC_DISPLAY_WATERMARK_HIGH;
 			levels[i].EnabledForActivity = 1;
 		}
@@ -1158,8 +1166,8 @@
 	levels[0].ActivityLevel = 0x1f;
 	CONVERT_FROM_HOST_TO_SMC_US(levels[0].ActivityLevel);
 
-	smu_data->smc_state_table.MemoryDpmLevelCount =
-			(uint8_t)dpm_table->mclk_table.count;
+	smu_data->smc_state_table.MemoryDpmLevelCount = (uint8_t)min_t(uint32_t,
+			dpm_table->mclk_table.count, SMU74_MAX_LEVELS_MEMORY);
 	hw_data->dpm_level_enable_mask.mclk_dpm_enable_mask =
 			phm_get_dpm_level_enable_mask_value(&dpm_table->mclk_table);
 
@@ -1366,11 +1374,15 @@
 	uint32_t i, j;
 	int result = 0;
 
-	for (i = 0; i < hw_data->dpm_table.sclk_table.count; i++) {
-		for (j = 0; j < hw_data->dpm_table.mclk_table.count; j++) {
+	for (i = 0; i < hw_data->dpm_table.sclk_table.count &&
+			i < SMU__NUM_SCLK_DPM_STATE; i++) {
+		for (j = 0; j < hw_data->dpm_table.mclk_table.count &&
+				j < SMU__NUM_MCLK_DPM_LEVELS; j++) {
 			result = polaris10_populate_memory_timing_parameters(hwmgr,
-					hw_data->dpm_table.sclk_table.dpm_levels[i].value,
-					hw_data->dpm_table.mclk_table.dpm_levels[j].value,
+					hw_data->dpm_table.sclk_table.dpm_levels[i %
+						MAX_REGULAR_DPM_NUMBER].value,
+					hw_data->dpm_table.mclk_table.dpm_levels[j %
+						MAX_REGULAR_DPM_NUMBER].value,
 					&arb_regs.entries[i][j]);
 			if (result == 0)
 				result = atomctrl_set_ac_timing_ai(hwmgr, hw_data->dpm_table.mclk_table.dpm_levels[j].value, j);