⬢ DragonFlyBSD Kernel Audit
DF-4004 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/drm/amd/powerplay/smumgr/fiji_smumgr.c	2026-09-17 12:25:48.762349856 +0000
+++ b/sys/dev/drm/amd/powerplay/smumgr/fiji_smumgr.c	2026-09-17 12:25:48.786349547 +0000
@@ -403,14 +403,14 @@
 				VOLTAGE_SCALE) << VDDCI_SHIFT;
 	else if (dep_table->entries[i-1].vddci) {
 		vddci = phm_find_closest_vddci(&(data->vddci_voltage_table),
-				(dep_table->entries[i].vddc -
+				(dep_table->entries[i - 1].vddc -
 						VDDC_VDDCI_DELTA));
 		*voltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT;
 	}
 
 	if (SMU7_VOLTAGE_CONTROL_NONE == data->mvdd_control)
 		*mvdd = data->vbios_boot_state.mvdd_bootup_value * VOLTAGE_SCALE;
-	else if (dep_table->entries[i].mvdd)
+	else if (dep_table->entries[i - 1].mvdd)
 		*mvdd = (uint32_t) dep_table->entries[i - 1].mvdd * VOLTAGE_SCALE;
 
 	return 0;
@@ -769,9 +769,11 @@
 	 * in split and merged mode
 	 */
 
-	for (count = 0; count < lookup_table->count; count++) {
+	for (count = 0; count < lookup_table->count &&
+			count < SMU73_MAX_LEVELS_VDDC; count++) {
 		index = phm_get_voltage_index(lookup_table,
-				data->vddc_voltage_table.entries[count].value);
+				data->vddc_voltage_table.entries[count %
+					PP_ATOMCTRL_MAX_VOLTAGE_ENTRIES].value);
 		table->BapmVddcVidLoSidd[count] =
 			convert_to_vid(lookup_table->entries[index].us_cac_low);
 		table->BapmVddcVidHiSidd[count] =
@@ -1023,9 +1025,11 @@
 			mid_pcie_level_enabled = 0,
 			count = 0;
 
-	for (i = 0; i < dpm_table->sclk_table.count; i++) {
+	for (i = 0; i < dpm_table->sclk_table.count &&
+			i < SMU73_MAX_LEVELS_GRAPHICS; i++) {
 		result = fiji_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,
 				&levels[i]);
 		if (result)
 			return result;
@@ -1039,11 +1043,11 @@
 	levels[0].EnabledForActivity = 1;
 
 	/* set highest level watermark to high */
-	levels[dpm_table->sclk_table.count - 1].DisplayWatermark =
+	levels[(dpm_table->sclk_table.count - 1) % SMU73_MAX_LEVELS_GRAPHICS].DisplayWatermark =
 			PPSMC_DISPLAY_WATERMARK_HIGH;
 
-	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, SMU73_MAX_LEVELS_GRAPHICS);
 	data->dpm_level_enable_mask.sclk_dpm_enable_mask =
 			phm_get_dpm_level_enable_mask_value(&dpm_table->sclk_table);
 
@@ -1052,7 +1056,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 < SMU73_MAX_LEVELS_GRAPHICS; i++)
 			levels[i].pcieDpmLevel =
 					(uint8_t) ((i < max_entry) ? i : max_entry);
 	} else {
@@ -1077,7 +1082,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 < SMU73_MAX_LEVELS_GRAPHICS; i++)
 			levels[i].pcieDpmLevel = hightest_pcie_level_enabled;
 
 		/* set pcieDpmLevel to lowest_pcie_level_enabled */
@@ -1235,12 +1241,15 @@
 			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 < SMU73_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 = fiji_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 (result)
 			return result;
@@ -1257,12 +1266,12 @@
 	levels[0].ActivityLevel = (uint16_t)data->mclk_dpm0_activity_target;
 	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, SMU73_MAX_LEVELS_MEMORY);
 	data->dpm_level_enable_mask.mclk_dpm_enable_mask =
 			phm_get_dpm_level_enable_mask_value(&dpm_table->mclk_table);
 	/* set highest level watermark to high */
-	levels[dpm_table->mclk_table.count - 1].DisplayWatermark =
+	levels[(dpm_table->mclk_table.count - 1) % SMU73_MAX_LEVELS_MEMORY].DisplayWatermark =
 			PPSMC_DISPLAY_WATERMARK_HIGH;
 
 	/* level count will send to smc once at init smc table and never change */
@@ -1430,7 +1439,10 @@
 	struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table =
 			table_info->mm_dep_table;
 
-	table->VceLevelCount = (uint8_t)(mm_table->count);
+	if (mm_table == NULL)
+		return -EINVAL;
+	table->VceLevelCount = (uint8_t)min_t(uint32_t, mm_table->count,
+			SMU73_MAX_LEVELS_VCE);
 	table->VceBootLevel = 0;
 
 	for (count = 0; count < table->VceLevelCount; count++) {
@@ -1469,7 +1481,10 @@
 	struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table =
 			table_info->mm_dep_table;
 
-	table->AcpLevelCount = (uint8_t)(mm_table->count);
+	if (mm_table == NULL)
+		return -EINVAL;
+	table->AcpLevelCount = (uint8_t)min_t(uint32_t, mm_table->count,
+			SMU73_MAX_LEVELS_ACP);
 	table->AcpBootLevel = 0;
 
 	for (count = 0; count < table->AcpLevelCount; count++) {
@@ -1534,11 +1549,15 @@
 	uint32_t i, j;
 	int result = 0;
 
-	for (i = 0; i < data->dpm_table.sclk_table.count; i++) {
-		for (j = 0; j < data->dpm_table.mclk_table.count; j++) {
+	for (i = 0; i < data->dpm_table.sclk_table.count &&
+			i < SMU__NUM_SCLK_DPM_STATE; i++) {
+		for (j = 0; j < data->dpm_table.mclk_table.count &&
+				j < SMU__NUM_MCLK_DPM_LEVELS; j++) {
 			result = fiji_populate_memory_timing_parameters(hwmgr,
-					data->dpm_table.sclk_table.dpm_levels[i].value,
-					data->dpm_table.mclk_table.dpm_levels[j].value,
+					data->dpm_table.sclk_table.dpm_levels[i %
+						MAX_REGULAR_DPM_NUMBER].value,
+					data->dpm_table.mclk_table.dpm_levels[j %
+						MAX_REGULAR_DPM_NUMBER].value,
 					&arb_regs.entries[i][j]);
 			if (result)
 				break;
@@ -1566,7 +1585,10 @@
 	struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table =
 			table_info->mm_dep_table;
 
-	table->UvdLevelCount = (uint8_t)(mm_table->count);
+	if (mm_table == NULL)
+		return -EINVAL;
+	table->UvdLevelCount = (uint8_t)min_t(uint32_t, mm_table->count,
+			SMU73_MAX_LEVELS_UVD);
 	table->UvdBootLevel = 0;
 
 	for (count = 0; count < table->UvdLevelCount; count++) {
@@ -1703,7 +1725,7 @@
 	smu_data->smc_state_table.ClockStretcherAmount = stretch_amount;
 
 	/* Populate Sclk_CKS_masterEn0_7 and Sclk_voltageOffset */
-	for (i = 0; i < sclk_table->count; i++) {
+	for (i = 0; i < sclk_table->count && i < 8; i++) {
 		smu_data->smc_state_table.Sclk_CKS_masterEn0_7 |=
 				sclk_table->entries[i].cks_enable << i;
 		volt_without_cks = (uint32_t)((14041 *
@@ -1715,7 +1737,7 @@
 		if (volt_without_cks >= volt_with_cks)
 			volt_offset = (uint8_t)(((volt_without_cks - volt_with_cks +
 					sclk_table->entries[i].cks_voffset) * 100 / 625) + 1);
-		smu_data->smc_state_table.Sclk_voltageOffset[i] = volt_offset;
+		smu_data->smc_state_table.Sclk_voltageOffset[i % 8] = volt_offset;
 	}
 
 	PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_CKS_ENABLE,
@@ -1789,7 +1811,8 @@
 		/* Loop through each SCLK and check the frequency
 		 * to see if it lies within the frequency for clock stretcher.
 		 */
-		for (j = 0; j < smu_data->smc_state_table.GraphicsDpmLevelCount; j++) {
+		for (j = 0; j < smu_data->smc_state_table.GraphicsDpmLevelCount &&
+				j < SMU73_MAX_LEVELS_GRAPHICS; j++) {
 			cks_setting = 0;
 			clock_freq = PP_SMC_TO_HOST_UL(
 					smu_data->smc_state_table.GraphicsLevel[j].SclkFrequency);