drm/amd/ras: Fix SMU EEPROM record field decoding

The SMU EEPROM read paths pass byte-sized record field addresses
to mca_ipid_parse(), whose outputs are u32 pointers.

Writing through those widened pointers can clobber adjacent fields
and bytes beyond the record storage.

Parse the IPID values into local u32 temporaries instead, then
explicitly narrow the values when storing them in the EEPROM record.

Signed-off-by: Xiang Liu <xiang.liu@amd.com>
Reviewed-by: Stanley.Yang <Stanley.Yang@amd.com>
Reviewed-by: Tao Zhou <tao.zhou1@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Xiang Liu 2026-05-11 16:45:08 +08:00 committed by Alex Deucher
parent 4d695e66d7
commit b5fa84e805
2 changed files with 10 additions and 6 deletions

View File

@ -1051,6 +1051,7 @@ int amdgpu_ras_eeprom_read_idx(struct amdgpu_ras_eeprom_control *control,
uint64_t ts, end_idx;
int i, ret;
u64 mca, ipid;
u32 cu, mem_channel, mcumc_id;
if (!amdgpu_ras_smu_eeprom_supported(adev))
return 0;
@ -1079,9 +1080,10 @@ int amdgpu_ras_eeprom_read_idx(struct amdgpu_ras_eeprom_control *control,
record[i - rec_idx].err_type = AMDGPU_RAS_EEPROM_ERR_NON_RECOVERABLE;
adev->umc.ras->mca_ipid_parse(adev, ipid,
(uint32_t *)&(record[i - rec_idx].cu),
(uint32_t *)&(record[i - rec_idx].mem_channel),
(uint32_t *)&(record[i - rec_idx].mcumc_id), NULL);
&cu, &mem_channel, &mcumc_id, NULL);
record[i - rec_idx].cu = (u8)cu;
record[i - rec_idx].mem_channel = (u8)mem_channel;
record[i - rec_idx].mcumc_id = (u8)mcumc_id;
}
return 0;

View File

@ -270,6 +270,7 @@ int ras_fw_eeprom_read_idx(struct ras_core_context *ras_core,
struct ras_fw_eeprom_control *control = &ras_core->ras_fw_eeprom;
int i, ret, end_idx;
u64 mca, ipid, ts;
u32 cu, mem_channel, mcumc_id;
if (!ras_core->ras_umc.ip_func ||
!ras_core->ras_umc.ip_func->mca_ipid_parse)
@ -299,9 +300,10 @@ int ras_fw_eeprom_read_idx(struct ras_core_context *ras_core,
record_umc[i - rec_idx].err_type = RAS_EEPROM_ERR_NON_RECOVERABLE;
ras_core->ras_umc.ip_func->mca_ipid_parse(ras_core, ipid,
(uint32_t *)&(record_umc[i - rec_idx].cu),
(uint32_t *)&(record_umc[i - rec_idx].mem_channel),
(uint32_t *)&(record_umc[i - rec_idx].mcumc_id), NULL);
&cu, &mem_channel, &mcumc_id, NULL);
record_umc[i - rec_idx].cu = (u8)cu;
record_umc[i - rec_idx].mem_channel = (u8)mem_channel;
record_umc[i - rec_idx].mcumc_id = (u8)mcumc_id;
/* update bad channel bitmap */
if ((record_umc[i - rec_idx].mem_channel < BITS_PER_TYPE(control->bad_channel_bitmap)) &&