Commit c8c19ebf authored by Jesse Zhang's avatar Jesse Zhang Committed by Alex Deucher
Browse files

drm/amd/pm: Fix negative array index read



Avoid using the negative values
for clk_idex as an index into an array pptable->DpmDescriptor.

V2: fix clk_index return check (Tim Huang)

Signed-off-by: default avatarJesse Zhang <Jesse.Zhang@amd.com>
Reviewed-by: default avatarTim Huang <Tim.Huang@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent f45ed399
Loading
Loading
Loading
Loading
+21 −6
Original line number Diff line number Diff line
@@ -1219,19 +1219,22 @@ static int navi10_get_current_clk_freq_by_table(struct smu_context *smu,
					   value);
}

static bool navi10_is_support_fine_grained_dpm(struct smu_context *smu, enum smu_clk_type clk_type)
static int navi10_is_support_fine_grained_dpm(struct smu_context *smu, enum smu_clk_type clk_type)
{
	PPTable_t *pptable = smu->smu_table.driver_pptable;
	DpmDescriptor_t *dpm_desc = NULL;
	uint32_t clk_index = 0;
	int clk_index = 0;

	clk_index = smu_cmn_to_asic_specific_index(smu,
						   CMN2ASIC_MAPPING_CLK,
						   clk_type);
	if (clk_index < 0)
		return clk_index;

	dpm_desc = &pptable->DpmDescriptor[clk_index];

	/* 0 - Fine grained DPM, 1 - Discrete DPM */
	return dpm_desc->SnapToDiscrete == 0;
	return dpm_desc->SnapToDiscrete == 0 ? 1 : 0;
}

static inline bool navi10_od_feature_is_supported(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_CAP cap)
@@ -1287,7 +1290,11 @@ static int navi10_emit_clk_levels(struct smu_context *smu,
		if (ret)
			return ret;

		if (!navi10_is_support_fine_grained_dpm(smu, clk_type)) {
		ret = navi10_is_support_fine_grained_dpm(smu, clk_type);
		if (ret < 0)
			return ret;

		if (!ret) {
			for (i = 0; i < count; i++) {
				ret = smu_v11_0_get_dpm_freq_by_index(smu,
								      clk_type, i, &value);
@@ -1496,7 +1503,11 @@ static int navi10_print_clk_levels(struct smu_context *smu,
		if (ret)
			return size;

		if (!navi10_is_support_fine_grained_dpm(smu, clk_type)) {
		ret = navi10_is_support_fine_grained_dpm(smu, clk_type);
		if (ret < 0)
			return ret;

		if (!ret) {
			for (i = 0; i < count; i++) {
				ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, i, &value);
				if (ret)
@@ -1665,7 +1676,11 @@ static int navi10_force_clk_levels(struct smu_context *smu,
	case SMU_UCLK:
	case SMU_FCLK:
		/* There is only 2 levels for fine grained DPM */
		if (navi10_is_support_fine_grained_dpm(smu, clk_type)) {
		ret = navi10_is_support_fine_grained_dpm(smu, clk_type);
		if (ret < 0)
			return ret;

		if (ret) {
			soft_max_level = (soft_max_level >= 1 ? 1 : 0);
			soft_min_level = (soft_min_level >= 1 ? 1 : 0);
		}