[PATCH 066/109] drm/amd/ras: harden error handling and fix resource/lock issues
Alex Deucher <[email protected]>
| Newsgroups | org.freedesktop.lists.amd-gfx |
|---|---|
| Message-ID | <[email protected]> |
From: YiPeng Chai <[email protected]> Harden error handling and fix resource/lock issues. Signed-off-by: YiPeng Chai <[email protected]> Reviewed-by: Hawking Zhang <[email protected]> Signed-off-by: Alex Deucher <[email protected]> --- drivers/gpu/drm/amd/ras/core/eeprom_fw.c | 19 +++++++++++++------ drivers/gpu/drm/amd/ras/core/ras_mp1.c | 2 +- drivers/gpu/drm/amd/ras/core/ras_umc.c | 11 ++++++++--- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/amd/ras/core/eeprom_fw.c b/drivers/gpu/drm/amd/ras/core/eeprom_fw.c index f7fb2dd7afe72..5f86ff54d9ed7 100644 --- a/drivers/gpu/drm/amd/ras/core/eeprom_fw.c +++ b/drivers/gpu/drm/amd/ras/core/eeprom_fw.c @@ -36,10 +36,11 @@ static int fw_eeprom_reset_ras_table(struct ras_core_context *ras_core) mutex_lock(&ctl->record_lock); res = ras_mp1_reset_ras_table(ras_core, &erase_res); if (res || erase_res) { - RAS_DEV_WARN(ras_core->dev, "RAS EEPROM reset failed, res:%d result:%d", - res, erase_res); + RAS_DEV_WARN(ras_core->dev, + "RAS EEPROM reset failed, res:%d result:%d\n", res, erase_res); if (!res) res = -EIO; + goto out; } ctl->record_count = 0; @@ -51,6 +52,8 @@ static int fw_eeprom_reset_ras_table(struct ras_core_context *ras_core) ctl->rma_status = 0; ctl->bad_channel_bitmap = 0; +out: + mutex_unlock(&ctl->record_lock); return res; } @@ -73,6 +76,11 @@ static int fw_eeprom_sync_data(struct ras_core_context *ras_core, RAS_DEV_ERR(ras_core->dev, "EEPROM ECC error count mismatch!\n"); ret = -EFAULT; goto out; + } else if (fw_err_rec_num > MAX_EEPROM_ERR_RECORD_NUM) { + RAS_DEV_ERR(ras_core->dev, + "Invalid EEPROM error count:0x%x\n", fw_err_rec_num); + ret = -EOVERFLOW; + goto out; } for (idx = ctl->record_count; @@ -141,9 +149,6 @@ static int fw_eeprom_sw_init(struct ras_core_context *ras_core, if (!ctl) return -ENOMEM; - mgr->ras_eeprom = ctl; - memset(ctl, 0, sizeof(*ctl)); - ctl->eeprom_ip_version = param->eeprom_ip_version; ctl->records = kzalloc(sizeof(*ctl->records) * MAX_EEPROM_ERR_RECORD_NUM, GFP_KERNEL); if (!ctl->records) { @@ -154,10 +159,12 @@ static int fw_eeprom_sw_init(struct ras_core_context *ras_core, ctl->max_record_count = MAX_EEPROM_ERR_RECORD_NUM; mutex_init(&ctl->record_lock); + mgr->ras_eeprom = ctl; + return 0; out: - kfree(ctl->records); + kfree(ctl); return ret; } diff --git a/drivers/gpu/drm/amd/ras/core/ras_mp1.c b/drivers/gpu/drm/amd/ras/core/ras_mp1.c index 34578806ef3c0..2452448806f65 100644 --- a/drivers/gpu/drm/amd/ras/core/ras_mp1.c +++ b/drivers/gpu/drm/amd/ras/core/ras_mp1.c @@ -148,7 +148,7 @@ int ras_mp1_get_record_count(struct ras_core_context *ras_core, u32 *count) int ret; if (!count || !mp1->ip_func || !mp1->ip_func->get_record_count) - return 0; + return -EOPNOTSUPP; mutex_lock(&mp1->op_mutex); ret = mp1->ip_func->get_record_count(ras_core, count); diff --git a/drivers/gpu/drm/amd/ras/core/ras_umc.c b/drivers/gpu/drm/amd/ras/core/ras_umc.c index 0e6a341f0729a..3558d4633a4e7 100644 --- a/drivers/gpu/drm/amd/ras/core/ras_umc.c +++ b/drivers/gpu/drm/amd/ras/core/ras_umc.c @@ -488,6 +488,7 @@ static int ras_umc_log_record(struct ras_core_context *ras_core, struct eeprom_umc_record *record) { struct eeprom_umc_record *rec; + int ret; rec = kzalloc(sizeof(*rec), GFP_KERNEL); if (!rec) @@ -495,7 +496,11 @@ static int ras_umc_log_record(struct ras_core_context *ras_core, memcpy(rec, record, sizeof(*rec)); - return ras_umc_log_ecc(ras_core, rec->cur_nps_retired_row_pfn, rec); + ret = ras_umc_log_ecc(ras_core, rec->cur_nps_retired_row_pfn, rec); + if (ret) + kfree(rec); + + return ret; } /* alloc/realloc bps array */ @@ -537,7 +542,7 @@ static int ras_umc_update_eeprom_rom_data(struct ras_core_context *ras_core, /* update bad channel bitmap */ if (bps->mem_channel < BITS_PER_TYPE(data->umc_channel_bitmap)) - data->umc_channel_bitmap |= 1 << bps->mem_channel; + data->umc_channel_bitmap |= 0x1ULL << bps->mem_channel; return 0; } @@ -585,7 +590,7 @@ static int ras_umc_update_eeprom_ram_data(struct ras_core_context *ras_core, /* update bad channel bitmap */ if (bps->mem_channel < BITS_PER_TYPE(data->umc_channel_bitmap)) - data->umc_channel_bitmap |= 1 << bps->mem_channel; + data->umc_channel_bitmap |= 0x1ULL << bps->mem_channel; return 0; } -- 2.55.0