DragonFlyBSD Kernel Audit
DF-1334 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/drm/radeon/rv770_dpm.c b/sys/dev/drm/radeon/rv770_dpm.c
--- a/sys/dev/drm/radeon/rv770_dpm.c
+++ b/sys/dev/drm/radeon/rv770_dpm.c
@@ -278,16 +278,20 @@
 	a_d = (int)state->low.sclk * (100 - (int)pi->rlp) +
 		(int)state->medium.sclk * pi->lmp;
 
-	l[1] = (u8)(pi->lmp - (int)pi->lmp * a_n / a_d);
-	r[0] = (u8)(pi->rlp + (100 - (int)pi->rlp) * a_n / a_d);
+	if (a_d != 0) {
+		l[1] = (u8)(pi->lmp - (int)pi->lmp * a_n / a_d);
+		r[0] = (u8)(pi->rlp + (100 - (int)pi->rlp) * a_n / a_d);
+	}
 
 	a_n = (int)state->high.sclk * pi->lhp + (int)state->medium.sclk *
 		(R600_AH_DFLT - pi->rmp);
 	a_d = (int)state->medium.sclk * (100 - (int)pi->rmp) +
 		(int)state->high.sclk * pi->lhp;
 
-	l[2] = (u8)(pi->lhp - (int)pi->lhp * a_n / a_d);
-	r[1] = (u8)(pi->rmp + (100 - (int)pi->rmp) * a_n / a_d);
+	if (a_d != 0) {
+		l[2] = (u8)(pi->lhp - (int)pi->lhp * a_n / a_d);
+		r[1] = (u8)(pi->rmp + (100 - (int)pi->rmp) * a_n / a_d);
+	}
 
 	for (i = 0; i < (RV770_SMC_PERFORMANCE_LEVELS_PER_SWSTATE - 1); i++) {
 		a_t = CG_R(r[i] * pi->bsp / 200) | CG_L(l[i] * pi->bsp / 200);
@@ -545,8 +549,13 @@
 
 		if (radeon_atombios_get_asic_ss_info(rdev, &ss,
 						     ASIC_INTERNAL_ENGINE_SS, vco_freq)) {
-			u32 clk_s = reference_clock * 5 / (reference_divider * ss.rate);
-			u32 clk_v = ss.percentage * fbdiv / (clk_s * 10000);
+			u32 clk_s, clk_v;
+			if (reference_divider == 0 || ss.rate == 0)
+				goto out_no_ss;
+			clk_s = reference_clock * 5 / (reference_divider * ss.rate);
+			if (clk_s == 0)
+				goto out_no_ss;
+			clk_v = ss.percentage * fbdiv / (clk_s * 10000);
 
 			cg_spll_spread_spectrum &= ~CLKS_MASK;
 			cg_spll_spread_spectrum |= CLKS(clk_s);
@@ -557,6 +566,7 @@
 		}
 	}
 
+out_no_ss:
 	sclk->sclk_value = cpu_to_be32(engine_clock);
 	sclk->vCG_SPLL_FUNC_CNTL = cpu_to_be32(spll_func_cntl);
 	sclk->vCG_SPLL_FUNC_CNTL_2 = cpu_to_be32(spll_func_cntl_2);
@@ -1245,6 +1255,9 @@
 	radeon_atom_get_max_voltage(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, &max);
 	radeon_atom_get_voltage_step(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, &step);
 
+	if (step == 0)
+		return -EINVAL;
+
 	steps = (max - min) / step + 1;
 
 	if (steps > MAX_NO_VREG_STEPS)