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 <[email protected]>
Reviewed-by: Lijo Lazar <[email protected]>
---
 .../powerplay/hwmgr/vega10_processpptables.c  | 133 ++++++++++++++----
 1 file changed, 102 insertions(+), 31 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 3be616af327e..34646a562f3b 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,29 @@ 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(struct_size(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(struct_size(mm_table, entries, num_entries),
                           GFP_KERNEL);
        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 +577,28 @@ 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(struct_size(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(struct_size(clk_table, entries, num_entries),
                            GFP_KERNEL);
        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 +616,28 @@ 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(struct_size(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(struct_size(mclk_table, entries, num_entries),
                            GFP_KERNEL);
        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 +660,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 +668,35 @@ static int get_gfxclk_voltage_dependency_table(
        PP_ASSERT_WITH_CODE((clk_dep_table->ucNumEntries != 0),
                        "Invalid PowerPlay Table!", return -1);
 
-       clk_table = kzalloc(struct_size(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(struct_size(clk_table, entries, num_entries),
                            GFP_KERNEL);
        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 +709,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 +725,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 +739,29 @@ 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(struct_size(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(struct_size(clk_table, entries, num_entries),
                            GFP_KERNEL);
        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 +780,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 +791,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 +808,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(struct_size(clk_table, entries, num_entries),
@@ -762,7 +823,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 =
@@ -1036,18 +1097,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(struct_size(table, entries, max_levels), GFP_KERNEL);
+       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(struct_size(table, entries, num_entries), GFP_KERNEL);
        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);
 
-- 
2.46.0

Reply via email to