Commit 13d3344e authored by Jesse Zhang's avatar Jesse Zhang Committed by Tengda Wu
Browse files

drm/amd/pm: Fix negative array index read

stable inclusion
from stable-v6.6.50
commit 4711b1347cb9f0c3083da6d87c624d75f9bd1d50
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IAU9MO
CVE: CVE-2024-46821

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=4711b1347cb9f0c3083da6d87c624d75f9bd1d50



--------------------------------

[ Upstream commit c8c19ebf7c0b202a6a2d37a52ca112432723db5f ]

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>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Fixes: c49b1b59 ("drm/amd/powerplay: change sysfs pp_dpm_xxx format for navi10")
Signed-off-by: default avatarTengda Wu <wutengda2@huawei.com>
parent 91ff8f4b
Loading
Loading
Loading
Loading
+21 −6
Original line number Diff line number Diff line
@@ -1222,19 +1222,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)
@@ -1290,7 +1293,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);
@@ -1499,7 +1506,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)
@@ -1668,7 +1679,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);
		}