⬢ DragonFlyBSD Kernel Audit
DF-3954 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/drm/radeon/kv_dpm.c b/sys/dev/drm/radeon/kv_dpm.c
index 1111111..2222222 100644
--- a/sys/dev/drm/radeon/kv_dpm.c
+++ b/sys/dev/drm/radeon/kv_dpm.c
@@ -2692,6 +2692,13 @@ static int kv_parse_power_table(struct radeon_device *rdev)
 			k++;
 		}
+		if (k == 0) {
+			/* A state with no usable clock entries would leave
+			 * ps->num_levels == 0 and later index
+			 * levels[num_levels - 1] == levels[0xFFFFFFFF]
+			 * (kv_set_valid_clock_range :1721/:1745,
+			 *  kv_dpm_get_sclk :2867).  Skip such states. */
+			DRM_ERROR("power state %d has no valid clock info entries\n", i);
+			continue;
+		}
 		kv_parse_pplib_non_clock_info(rdev, &rdev->pm.dpm.ps[i],
 					      non_clock_info,
 					      non_clock_info_array->ucEntrySize);
@@ -1718,6 +1725,10 @@ static void kv_set_valid_clock_range(struct radeon_device *rdev,
 	struct radeon_clock_voltage_dependency_table *table =
 		&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk;
 
+	if (new_ps->num_levels == 0)
+		return;
+
 	if (table && table->count) {
 		for (i = 0; i < pi->graphics_dpm_level_count; i++) {
 			if ((table->entries[i].clk >= new_ps->levels[0].sclk) ||
@@ -2878,6 +2889,10 @@ u32 kv_dpm_get_sclk(struct radeon_device *rdev, bool low)
 	struct kv_power_info *pi = kv_get_pi(rdev);
 	struct kv_ps *requested_state = kv_get_ps(&pi->requested_rps);
 
+	if (!requested_state || requested_state->num_levels == 0)
+		return pi->sys_info.bootup_sclk;
+
 	if (low)
 		return requested_state->levels[0].sclk;
 	else