⬢ DragonFlyBSD Kernel Audit
DF-3645 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/drm/radeon/ci_dpm.c
+++ b/sys/dev/drm/radeon/ci_dpm.c
@@ -5666,6 +5666,8 @@ static int ci_parse_power_table(struct radeon_device *rdev)
 err_free_ps:
 	for (i = 0; i < rdev->pm.dpm.num_ps; i++)
 		kfree(rdev->pm.dpm.ps[i].ps_priv);
 	kfree(rdev->pm.dpm.ps);
+	rdev->pm.dpm.ps = NULL;
+	rdev->pm.dpm.num_ps = 0;
 	return ret;
 }
@@ -5703,6 +5705,10 @@ void ci_dpm_fini(struct radeon_device *rdev)
 	for (i = 0; i < rdev->pm.dpm.num_ps; i++) {
 		kfree(rdev->pm.dpm.ps[i].ps_priv);
 	}
 	kfree(rdev->pm.dpm.ps);
 	kfree(rdev->pm.dpm.priv);
+	rdev->pm.dpm.ps = NULL;
+	rdev->pm.dpm.num_ps = 0;
+	rdev->pm.dpm.priv = NULL;
 	kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries);
 	r600_free_extended_power_table(rdev);
 }
@@ -5762,21 +5768,25 @@ int ci_dpm_init(struct radeon_device *rdev)
 	ret = ci_get_vbios_boot_values(rdev, &pi->vbios_boot_state);
 	if (ret) {
 		kfree(rdev->pm.dpm.priv);
+		rdev->pm.dpm.priv = NULL;
 		return ret;
 	}
 
 	ret = r600_get_platform_caps(rdev);
 	if (ret) {
 		kfree(rdev->pm.dpm.priv);
+		rdev->pm.dpm.priv = NULL;
 		return ret;
 	}
 
 	ret = r600_parse_extended_power_table(rdev);
 	if (ret) {
 		kfree(rdev->pm.dpm.priv);
+		rdev->pm.dpm.priv = NULL;
 		return ret;
 	}
 
 	ret = ci_parse_power_table(rdev);
 	if (ret) {
 		kfree(rdev->pm.dpm.priv);
+		rdev->pm.dpm.priv = NULL;
 		r600_free_extended_power_table(rdev);
 		return ret;
 	}
--- a/sys/dev/drm/radeon/radeon_pm.c
+++ b/sys/dev/drm/radeon/radeon_pm.c
@@ -1445,7 +1445,11 @@ static int radeon_pm_init_dpm(struct radeon_device *rdev)
 	INIT_WORK(&rdev->pm.dpm.thermal.work, radeon_dpm_thermal_work_handler);
 	mutex_lock(&rdev->pm.mutex);
-	radeon_dpm_init(rdev);
+	ret = radeon_dpm_init(rdev);
+	if (ret) {
+		mutex_unlock(&rdev->pm.mutex);
+		goto dpm_failed;
+	}
 	rdev->pm.dpm.current_ps = rdev->pm.dpm.requested_ps = rdev->pm.dpm.boot_ps;