⬢ DragonFlyBSD Kernel Audit
DF-4167 / fix.diff
← back to finding ↓ download raw
--- /home/maxx/dfbsd/dfbsd/sys/dev/drm/amd/display/dc/bios/bios_parser2.c	2026-06-29 12:51:18.000000000 +0000
+++ bp2_fix4167.c	2026-09-18 09:49:04.512579596 +0000
@@ -1226,8 +1226,14 @@
 
 	memset(info, 0, sizeof(*info));
 
+	if (!DATA_TABLES(smu_info))
+		return BP_RESULT_BADBIOSTABLE;
+
 	header = GET_IMAGE(struct atom_common_table_header,
 					DATA_TABLES(smu_info));
+	if (!header)
+		return BP_RESULT_BADBIOSTABLE;
+
 	get_atom_data_table_revision(header, &revision);
 
 	if (revision.minor == 2) {
@@ -1255,12 +1261,16 @@
 
 	 /* 27MHz for Vega10 & Vega12; 100MHz for Vega20 */
 	info->pll_info.crystal_frequency = dce_info->dce_refclk_10khz * 10;
-	/* Hardcode frequency if BIOS gives no DCE Ref Clk */
+	/* Hardcode frequency if BIOS gives no DCE Ref Clk.  The fallback
+	 * must not depend on the (optional) smu_info table revision: a zero
+	 * reference clock is later used as a divisor in the DCE clock-source
+	 * PLL math (dce_clock_source.c calculate_fb_and_fractional_fb_divider).
+	 */
 	if (info->pll_info.crystal_frequency == 0) {
-		if (revision.minor == 2)
-			info->pll_info.crystal_frequency = 27000;
-		else if (revision.minor == 3)
+		if (revision.minor == 3)
 			info->pll_info.crystal_frequency = 100000;
+		else
+			info->pll_info.crystal_frequency = 27000;
 	}
 	/*dp_phy_ref_clk is not correct for atom_display_controller_info_v4_2, but we don't use it*/
 	info->dp_phy_ref_clk     = dce_info->dpphy_refclk_10khz * 10;