summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAsad Kamal <asad.kamal@amd.com>2026-06-23 00:00:00 +0000
committerAlex Deucher <alexander.deucher@amd.com>2026-07-01 11:26:12 -0400
commit33d3ae96964cc27c112b79d93964f4c88e232136 (patch)
tree9c3167a081385a8017a76c4a61cac30cabedd60d
parentf14f99fffce215f7bb4d3400193da01a43086c7b (diff)
downloadlinux-stable-33d3ae96964cc27c112b79d93964f4c88e232136.tar.gz
linux-stable-33d3ae96964cc27c112b79d93964f4c88e232136.zip
drm/amdgpu/pm/powerplay: clamp Vega10 PP sub-table ucNumEntries
Same write-OOB and read-OOB as the Tonga fix, across seven Vega10 sub-table parsers: get_vddc_lookup_table(), get_mm_clock_voltage_table(), get_socclk/mclk/gfxclk/pixclk/dcefclk_voltage_dependency_table(). The GFXCLK table selects the correct record size per revision. Fixes: f83a9991648b ("drm/amd/powerplay: add Vega10 powerplay support (v5)") Signed-off-by: Asad Kamal <asad.kamal@amd.com> Reviewed-by: Lijo Lazar <lijo.lazar@amd.com> Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_processpptables.c138
1 files changed, 102 insertions, 36 deletions
diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_processpptables.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_processpptables.c
index 052d139584fd..d32c8166f703 100644
--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_processpptables.c
+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_processpptables.c
@@ -344,20 +344,28 @@ static int get_mm_clock_voltage_table(
const ATOM_Vega10_MM_Dependency_Table *mm_dependency_table)
{
uint32_t i;
+ uint32_t num_entries;
const ATOM_Vega10_MM_Dependency_Record *mm_dependency_record;
phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table;
PP_ASSERT_WITH_CODE((mm_dependency_table->ucNumEntries != 0),
"Invalid PowerPlay Table!", return -1);
- mm_table = kzalloc_flex(*mm_table, entries,
- mm_dependency_table->ucNumEntries);
+ num_entries = min_t(uint32_t, mm_dependency_table->ucNumEntries,
+ pp_entries_max(hwmgr, mm_dependency_table,
+ sizeof(*mm_dependency_table),
+ sizeof(ATOM_Vega10_MM_Dependency_Record)));
+ if (num_entries < mm_dependency_table->ucNumEntries)
+ pr_warn("amdgpu: Vega10 MM dependency table: clamping ucNumEntries %u -> %u\n",
+ mm_dependency_table->ucNumEntries, num_entries);
+
+ mm_table = kzalloc_flex(*mm_table, entries, num_entries);
if (!mm_table)
return -ENOMEM;
- mm_table->count = mm_dependency_table->ucNumEntries;
+ mm_table->count = num_entries;
- for (i = 0; i < mm_dependency_table->ucNumEntries; i++) {
+ for (i = 0; i < num_entries; i++) {
mm_dependency_record = &mm_dependency_table->entries[i];
mm_table->entries[i].vddcInd = mm_dependency_record->ucVddcInd;
mm_table->entries[i].samclock =
@@ -568,19 +576,27 @@ static int get_socclk_voltage_dependency_table(
const ATOM_Vega10_SOCCLK_Dependency_Table *clk_dep_table)
{
uint32_t i;
+ uint32_t num_entries;
phm_ppt_v1_clock_voltage_dependency_table *clk_table;
PP_ASSERT_WITH_CODE(clk_dep_table->ucNumEntries,
"Invalid PowerPlay Table!", return -1);
- clk_table = kzalloc_flex(*clk_table, entries,
- clk_dep_table->ucNumEntries);
+ num_entries = min_t(uint32_t, clk_dep_table->ucNumEntries,
+ pp_entries_max(hwmgr, clk_dep_table,
+ sizeof(*clk_dep_table),
+ sizeof(ATOM_Vega10_CLK_Dependency_Record)));
+ if (num_entries < clk_dep_table->ucNumEntries)
+ pr_warn("amdgpu: Vega10 SOCCLK dependency table: clamping ucNumEntries %u -> %u\n",
+ clk_dep_table->ucNumEntries, num_entries);
+
+ clk_table = kzalloc_flex(*clk_table, entries, num_entries);
if (!clk_table)
return -ENOMEM;
- clk_table->count = (uint32_t)clk_dep_table->ucNumEntries;
+ clk_table->count = num_entries;
- for (i = 0; i < clk_dep_table->ucNumEntries; i++) {
+ for (i = 0; i < num_entries; i++) {
clk_table->entries[i].vddInd =
clk_dep_table->entries[i].ucVddInd;
clk_table->entries[i].clk =
@@ -598,19 +614,27 @@ static int get_mclk_voltage_dependency_table(
const ATOM_Vega10_MCLK_Dependency_Table *mclk_dep_table)
{
uint32_t i;
+ uint32_t num_entries;
phm_ppt_v1_clock_voltage_dependency_table *mclk_table;
PP_ASSERT_WITH_CODE(mclk_dep_table->ucNumEntries,
"Invalid PowerPlay Table!", return -1);
- mclk_table = kzalloc_flex(*mclk_table, entries,
- mclk_dep_table->ucNumEntries);
+ num_entries = min_t(uint32_t, mclk_dep_table->ucNumEntries,
+ pp_entries_max(hwmgr, mclk_dep_table,
+ sizeof(*mclk_dep_table),
+ sizeof(ATOM_Vega10_MCLK_Dependency_Record)));
+ if (num_entries < mclk_dep_table->ucNumEntries)
+ pr_warn("amdgpu: Vega10 MCLK dependency table: clamping ucNumEntries %u -> %u\n",
+ mclk_dep_table->ucNumEntries, num_entries);
+
+ mclk_table = kzalloc_flex(*mclk_table, entries, num_entries);
if (!mclk_table)
return -ENOMEM;
- mclk_table->count = (uint32_t)mclk_dep_table->ucNumEntries;
+ mclk_table->count = num_entries;
- for (i = 0; i < mclk_dep_table->ucNumEntries; i++) {
+ for (i = 0; i < num_entries; i++) {
mclk_table->entries[i].vddInd =
mclk_dep_table->entries[i].ucVddInd;
mclk_table->entries[i].vddciInd =
@@ -633,6 +657,7 @@ static int get_gfxclk_voltage_dependency_table(
const ATOM_Vega10_GFXCLK_Dependency_Table *clk_dep_table)
{
uint32_t i;
+ uint32_t num_entries;
struct phm_ppt_v1_clock_voltage_dependency_table
*clk_table;
ATOM_Vega10_GFXCLK_Dependency_Record_V2 *patom_record_v2;
@@ -640,15 +665,34 @@ static int get_gfxclk_voltage_dependency_table(
PP_ASSERT_WITH_CODE((clk_dep_table->ucNumEntries != 0),
"Invalid PowerPlay Table!", return -1);
- clk_table = kzalloc_flex(*clk_table, entries,
- clk_dep_table->ucNumEntries);
+ if (clk_dep_table->ucRevId == 0) {
+ num_entries = min_t(uint32_t, clk_dep_table->ucNumEntries,
+ pp_entries_max(hwmgr, clk_dep_table,
+ sizeof(*clk_dep_table),
+ sizeof(ATOM_Vega10_GFXCLK_Dependency_Record)));
+ } else if (clk_dep_table->ucRevId == 1) {
+ num_entries = min_t(uint32_t, clk_dep_table->ucNumEntries,
+ pp_entries_max(hwmgr, clk_dep_table,
+ sizeof(*clk_dep_table),
+ sizeof(ATOM_Vega10_GFXCLK_Dependency_Record_V2)));
+ } else {
+ PP_ASSERT_WITH_CODE(false,
+ "Unsupported GFXClockDependencyTable Revision!",
+ return -EINVAL);
+ }
+
+ if (num_entries < clk_dep_table->ucNumEntries)
+ pr_warn("amdgpu: Vega10 GFXCLK dependency table: clamping ucNumEntries %u -> %u\n",
+ clk_dep_table->ucNumEntries, num_entries);
+
+ clk_table = kzalloc_flex(*clk_table, entries, num_entries);
if (!clk_table)
return -ENOMEM;
- clk_table->count = clk_dep_table->ucNumEntries;
+ clk_table->count = num_entries;
if (clk_dep_table->ucRevId == 0) {
- for (i = 0; i < clk_table->count; i++) {
+ for (i = 0; i < num_entries; i++) {
clk_table->entries[i].vddInd =
clk_dep_table->entries[i].ucVddInd;
clk_table->entries[i].clk =
@@ -661,9 +705,9 @@ static int get_gfxclk_voltage_dependency_table(
clk_table->entries[i].sclk_offset =
le16_to_cpu(clk_dep_table->entries[i].usAVFSOffset);
}
- } else if (clk_dep_table->ucRevId == 1) {
+ } else {
patom_record_v2 = (ATOM_Vega10_GFXCLK_Dependency_Record_V2 *)clk_dep_table->entries;
- for (i = 0; i < clk_table->count; i++) {
+ for (i = 0; i < num_entries; i++) {
clk_table->entries[i].vddInd =
patom_record_v2->ucVddInd;
clk_table->entries[i].clk =
@@ -677,11 +721,6 @@ static int get_gfxclk_voltage_dependency_table(
le16_to_cpu(patom_record_v2->usAVFSOffset);
patom_record_v2++;
}
- } else {
- kfree(clk_table);
- PP_ASSERT_WITH_CODE(false,
- "Unsupported GFXClockDependencyTable Revision!",
- return -EINVAL);
}
*pp_vega10_clk_dep_table = clk_table;
@@ -696,20 +735,28 @@ static int get_pix_clk_voltage_dependency_table(
const ATOM_Vega10_PIXCLK_Dependency_Table *clk_dep_table)
{
uint32_t i;
+ uint32_t num_entries;
struct phm_ppt_v1_clock_voltage_dependency_table
*clk_table;
PP_ASSERT_WITH_CODE((clk_dep_table->ucNumEntries != 0),
"Invalid PowerPlay Table!", return -1);
- clk_table = kzalloc_flex(*clk_table, entries,
- clk_dep_table->ucNumEntries);
+ num_entries = min_t(uint32_t, clk_dep_table->ucNumEntries,
+ pp_entries_max(hwmgr, clk_dep_table,
+ sizeof(*clk_dep_table),
+ sizeof(ATOM_Vega10_CLK_Dependency_Record)));
+ if (num_entries < clk_dep_table->ucNumEntries)
+ pr_warn("amdgpu: Vega10 PIXCLK dependency table: clamping ucNumEntries %u -> %u\n",
+ clk_dep_table->ucNumEntries, num_entries);
+
+ clk_table = kzalloc_flex(*clk_table, entries, num_entries);
if (!clk_table)
return -ENOMEM;
- clk_table->count = clk_dep_table->ucNumEntries;
+ clk_table->count = num_entries;
- for (i = 0; i < clk_table->count; i++) {
+ for (i = 0; i < num_entries; i++) {
clk_table->entries[i].vddInd =
clk_dep_table->entries[i].ucVddInd;
clk_table->entries[i].clk =
@@ -728,6 +775,7 @@ static int get_dcefclk_voltage_dependency_table(
const ATOM_Vega10_DCEFCLK_Dependency_Table *clk_dep_table)
{
uint32_t i;
+ uint32_t safe_entries;
uint8_t num_entries;
struct phm_ppt_v1_clock_voltage_dependency_table
*clk_table;
@@ -738,6 +786,14 @@ static int get_dcefclk_voltage_dependency_table(
PP_ASSERT_WITH_CODE((clk_dep_table->ucNumEntries != 0),
"Invalid PowerPlay Table!", return -1);
+ safe_entries = min_t(uint32_t, clk_dep_table->ucNumEntries,
+ pp_entries_max(hwmgr, clk_dep_table,
+ sizeof(*clk_dep_table),
+ sizeof(ATOM_Vega10_CLK_Dependency_Record)));
+ if (safe_entries < clk_dep_table->ucNumEntries)
+ pr_warn("amdgpu: Vega10 DCEFCLK dependency table: clamping ucNumEntries %u -> %u\n",
+ clk_dep_table->ucNumEntries, safe_entries);
+
/*
* workaround needed to add another DPM level for pioneer cards
* as VBIOS is locked down.
@@ -747,12 +803,12 @@ static int get_dcefclk_voltage_dependency_table(
dev_id = adev->pdev->device;
rev_id = adev->pdev->revision;
- if (dev_id == 0x6863 && rev_id == 0 &&
- clk_dep_table->entries[clk_dep_table->ucNumEntries - 1].ulClk < 90000)
- num_entries = clk_dep_table->ucNumEntries + 1 > NUM_DSPCLK_LEVELS ?
- NUM_DSPCLK_LEVELS : clk_dep_table->ucNumEntries + 1;
+ if (dev_id == 0x6863 && rev_id == 0 && safe_entries > 0 &&
+ clk_dep_table->entries[safe_entries - 1].ulClk < 90000)
+ num_entries = safe_entries + 1 > NUM_DSPCLK_LEVELS ?
+ NUM_DSPCLK_LEVELS : safe_entries + 1;
else
- num_entries = clk_dep_table->ucNumEntries;
+ num_entries = safe_entries;
clk_table = kzalloc_flex(*clk_table, entries, num_entries);
@@ -761,7 +817,7 @@ static int get_dcefclk_voltage_dependency_table(
clk_table->count = (uint32_t)num_entries;
- for (i = 0; i < clk_dep_table->ucNumEntries; i++) {
+ for (i = 0; i < safe_entries; i++) {
clk_table->entries[i].vddInd =
clk_dep_table->entries[i].ucVddInd;
clk_table->entries[i].clk =
@@ -1034,18 +1090,28 @@ static int get_vddc_lookup_table(
uint32_t max_levels)
{
uint32_t i;
+ uint32_t num_entries;
phm_ppt_v1_voltage_lookup_table *table;
PP_ASSERT_WITH_CODE((vddc_lookup_pp_tables->ucNumEntries != 0),
"Invalid SOC_VDDD Lookup Table!", return 1);
- table = kzalloc_flex(*table, entries, max_levels);
+ num_entries = min_t(uint32_t, vddc_lookup_pp_tables->ucNumEntries,
+ min_t(uint32_t, max_levels,
+ pp_entries_max(hwmgr, vddc_lookup_pp_tables,
+ sizeof(*vddc_lookup_pp_tables),
+ sizeof(ATOM_Vega10_Voltage_Lookup_Record))));
+ if (num_entries < vddc_lookup_pp_tables->ucNumEntries)
+ pr_warn("amdgpu: Vega10 VddcLookup table: clamping ucNumEntries %u -> %u\n",
+ vddc_lookup_pp_tables->ucNumEntries, num_entries);
+
+ table = kzalloc_flex(*table, entries, num_entries);
if (!table)
return -ENOMEM;
- table->count = vddc_lookup_pp_tables->ucNumEntries;
+ table->count = num_entries;
- for (i = 0; i < vddc_lookup_pp_tables->ucNumEntries; i++)
+ for (i = 0; i < num_entries; i++)
table->entries[i].us_vdd =
le16_to_cpu(vddc_lookup_pp_tables->entries[i].usVdd);