Add address sanity check for uniras

Signed-off-by: Ce Sun <[email protected]>
---
 .../gpu/drm/amd/ras/ras_mgr/amdgpu_ras_cmd.c  |  3 ---
 .../gpu/drm/amd/ras/ras_mgr/amdgpu_ras_sys.c  | 18 +++++++++++++++
 drivers/gpu/drm/amd/ras/ras_mgr/ras_sys.h     |  3 +++
 drivers/gpu/drm/amd/ras/rascore/ras.h         |  2 ++
 drivers/gpu/drm/amd/ras/rascore/ras_core.c    | 10 ++++++++
 drivers/gpu/drm/amd/ras/rascore/ras_umc.c     | 23 +++++++++++++++----
 drivers/gpu/drm/amd/ras/rascore/ras_umc.h     |  2 ++
 7 files changed, 54 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_cmd.c 
b/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_cmd.c
index 658bf3fdb66b..bfbfdffbfbe6 100644
--- a/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_cmd.c
+++ b/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_cmd.c
@@ -30,9 +30,6 @@
 #include "amdgpu_ras_mgr.h"
 #include "amdgpu_virt_ras_cmd.h"
 
-/* inject address is 52 bits */
-#define        RAS_UMC_INJECT_ADDR_LIMIT       (0x1ULL << 52)
-
 #define AMDGPU_RAS_TYPE_RASCORE  0x1
 #define AMDGPU_RAS_TYPE_AMDGPU   0x2
 #define AMDGPU_RAS_TYPE_VF       0x3
diff --git a/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_sys.c 
b/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_sys.c
index 7d728e523604..eb840f0861fe 100644
--- a/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_sys.c
+++ b/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_sys.c
@@ -266,6 +266,23 @@ static int amdgpu_ras_sys_put_gpu_mem(struct 
ras_core_context *ras_core,
 
        return 0;
 }
+static int amdgpu_ras_sys_check_address_sanity(struct ras_core_context 
*ras_core,
+                                               uint64_t addr)
+{
+       struct amdgpu_device *adev = (struct amdgpu_device *)ras_core->dev;
+
+       if ((addr >= adev->gmc.mc_vram_size &&
+           adev->gmc.mc_vram_size) ||
+           (addr >= RAS_UMC_INJECT_ADDR_LIMIT))
+               return -EINVAL;
+
+       if (addr >= adev->gmc.real_vram_size) {
+               RAS_DEV_WARN(ras_core->dev, "Recorded address out of range: 
0x%llx!\n", addr);
+               return -EINVAL;
+       }
+
+       return 0;
+}
 
 const struct ras_sys_func amdgpu_ras_sys_fn = {
        .ras_notifier = amdgpu_ras_sys_event_notifier,
@@ -277,4 +294,5 @@ const struct ras_sys_func amdgpu_ras_sys_fn = {
        .detect_ras_interrupt = amdgpu_ras_sys_detect_ras_interrupt,
        .get_gpu_mem = amdgpu_ras_sys_get_gpu_mem,
        .put_gpu_mem = amdgpu_ras_sys_put_gpu_mem,
+       .check_address_sanity = amdgpu_ras_sys_check_address_sanity,
 };
diff --git a/drivers/gpu/drm/amd/ras/ras_mgr/ras_sys.h 
b/drivers/gpu/drm/amd/ras/ras_mgr/ras_sys.h
index f34dda7ce87b..2775c7bf41b7 100644
--- a/drivers/gpu/drm/amd/ras/ras_mgr/ras_sys.h
+++ b/drivers/gpu/drm/amd/ras/ras_mgr/ras_sys.h
@@ -30,6 +30,9 @@
 #include <linux/mempool.h>
 #include "amdgpu.h"
 
+/* inject address is 52 bits */
+#define RAS_UMC_INJECT_ADDR_LIMIT       (0x1ULL << 52)
+
 #define RAS_DEV_ERR(device, fmt, ...)                                          
     \
        do {                                                                    
  \
                if (device)                                                     
        \
diff --git a/drivers/gpu/drm/amd/ras/rascore/ras.h 
b/drivers/gpu/drm/amd/ras/rascore/ras.h
index c059fcebaf00..5869bad978b0 100644
--- a/drivers/gpu/drm/amd/ras/rascore/ras.h
+++ b/drivers/gpu/drm/amd/ras/rascore/ras.h
@@ -231,6 +231,7 @@ struct ras_sys_func {
                enum gpu_mem_type mem_type, struct gpu_mem_block *gpu_mem);
        int (*put_gpu_mem)(struct ras_core_context *ras_core,
                enum gpu_mem_type mem_type, struct gpu_mem_block *gpu_mem);
+       int (*check_address_sanity)(struct ras_core_context *ras_core, uint64_t 
addr);
 };
 
 struct ras_ecc_count {
@@ -398,4 +399,5 @@ int ras_core_get_device_system_info(struct ras_core_context 
*ras_core,
                struct device_system_info *dev_info);
 int ras_core_convert_soc_pa_to_cur_nps_pages(struct ras_core_context *ras_core,
                uint64_t soc_pa, uint64_t *page_pfn, uint32_t max_pages);
+int ras_core_check_address_sanity(struct ras_core_context *ras_core, uint64_t 
addr);
 #endif
diff --git a/drivers/gpu/drm/amd/ras/rascore/ras_core.c 
b/drivers/gpu/drm/amd/ras/rascore/ras_core.c
index ad6fffaa42de..61d100b074b9 100644
--- a/drivers/gpu/drm/amd/ras/rascore/ras_core.c
+++ b/drivers/gpu/drm/amd/ras/rascore/ras_core.c
@@ -676,3 +676,13 @@ int ras_core_convert_soc_pa_to_cur_nps_pages(struct 
ras_core_context *ras_core,
 
        return count;
 }
+
+int ras_core_check_address_sanity(struct ras_core_context *ras_core,
+               uint64_t addr)
+{
+       if (ras_core && ras_core->sys_fn &&
+               ras_core->sys_fn->check_address_sanity)
+               return ras_core->sys_fn->check_address_sanity(ras_core, addr);
+
+       return 0;
+}
diff --git a/drivers/gpu/drm/amd/ras/rascore/ras_umc.c 
b/drivers/gpu/drm/amd/ras/rascore/ras_umc.c
index e5971c3dd7da..f56d37d09044 100644
--- a/drivers/gpu/drm/amd/ras/rascore/ras_umc.c
+++ b/drivers/gpu/drm/amd/ras/rascore/ras_umc.c
@@ -406,7 +406,7 @@ static int ras_umc_update_eeprom_ram_data(struct 
ras_core_context *ras_core,
        struct ras_umc *ras_umc = &ras_core->ras_umc;
        struct eeprom_store_record *data = &ras_umc->umc_err_data.ram_data;
        uint64_t page_pfn[16];
-       int count = 0, j;
+       int count = 0, i, j;
 
        if (!data->space_left &&
                ras_umc_realloc_err_data_space(ras_core, data, 256)) {
@@ -418,10 +418,23 @@ static int ras_umc_update_eeprom_ram_data(struct 
ras_core_context *ras_core,
                                        bps, bps->cur_nps, page_pfn, 
ARRAY_SIZE(page_pfn));
        if (count > 0) {
                for (j = 0; j < count; j++) {
+                       if (ras_core_check_address_sanity(ras_core,
+                               page_pfn[j] << AMDGPU_GPU_PAGE_SHIFT)) {
+
+                               for (i = 0; i < data->count; i++)
+                                       if (page_pfn[j] == 
data->bps[i].cur_nps_retired_row_pfn)
+                                               break;
+                               data->bps[data->count].cur_nps_retired_row_pfn 
= U64_MAX;
+                               data->count++;
+                               data->space_left--;
+                               continue;
+                       }
+
                        bps->cur_nps_retired_row_pfn = page_pfn[j];
                        memcpy(&data->bps[data->count], bps, 
sizeof(*data->bps));
                        data->count++;
                        data->space_left--;
+                       data->bad_page_num++;
                }
        } else {
                RAS_DEV_ERR(ras_core->dev, "Failed to convert record to nps 
pages!");
@@ -521,7 +534,8 @@ static int ras_umc_save_bad_pages(struct ras_core_context 
*ras_core)
 {
        struct ras_umc *ras_umc = &ras_core->ras_umc;
        struct eeprom_store_record *data = &ras_umc->umc_err_data.rom_data;
-       uint32_t eeprom_record_num;
+       struct eeprom_store_record *ram_data = &ras_umc->umc_err_data.ram_data;
+       uint32_t eeprom_record_num, logical_count = 0;
        int save_count;
        int ret = 0;
 
@@ -534,6 +548,7 @@ static int ras_umc_save_bad_pages(struct ras_core_context 
*ras_core)
                eeprom_record_num = ras_eeprom_get_record_count(ras_core);
        mutex_lock(&ras_umc->umc_lock);
        save_count = data->count - eeprom_record_num;
+       logical_count = ram_data->bad_page_num - ram_data->ras_num_bad_pages;
        /* only new entries are saved */
        if (save_count > 0) {
                if (ras_fw_eeprom_supported(ras_core))
@@ -547,8 +562,8 @@ static int ras_umc_save_bad_pages(struct ras_core_context 
*ras_core)
                        ret = -EIO;
                        goto exit;
                }
-
-               RAS_DEV_INFO(ras_core->dev, "Saved %d pages to EEPROM 
table.\n", save_count);
+               ram_data->ras_num_bad_pages = ram_data->bad_page_num;
+               RAS_DEV_INFO(ras_core->dev, "Saved %d pages to EEPROM 
table.\n", logical_count);
        }
 
 exit:
diff --git a/drivers/gpu/drm/amd/ras/rascore/ras_umc.h 
b/drivers/gpu/drm/amd/ras/rascore/ras_umc.h
index 237525b46b9b..ad12796a048f 100644
--- a/drivers/gpu/drm/amd/ras/rascore/ras_umc.h
+++ b/drivers/gpu/drm/amd/ras/rascore/ras_umc.h
@@ -119,6 +119,8 @@ struct eeprom_store_record {
        int count;
        /* the space can place new entries */
        int space_left;
+       int bad_page_num;
+       int ras_num_bad_pages;
 };
 
 struct ras_umc_err_data {
-- 
2.34.1

Reply via email to