AMD General

Reviewed-by: Hawking Zhang <[email protected]>

Regards,
Hawking
-----Original Message-----
From: amd-gfx <[email protected]> On Behalf Of Stanley.Yang
Sent: Wednesday, July 8, 2026 8:04 PM
To: [email protected]
Cc: Zhang, Hawking <[email protected]>; Russell, Kent 
<[email protected]>; Yang, Stanley <[email protected]>
Subject: [PATCH V3 1/1] drm/amdgpu/ras: only check bad page for address-based 
UMC injection

UMC error injection on MI300 series is dispatched by the RAS TA using the 
injection method; only the "coherent" methods are address based, the 
single-shot/persistent/ac-parity ones ignore the address.

The debugfs control path validated the injection address against the bad page 
list for every UMC injection. On uniras (SMU v13+) devices the address is now 
validated by the ras_mgr inject handler, so the legacy debugfs bad page check 
only runs on the legacy RAS path; other ASICs keep injecting by address.

In the ras_mgr handler an injection is treated as non address-based only when 
userspace passes the U64_MAX sentinel address and the method is a non-address 
method. In that case the address is cleared to 0 and the bad page / range 
validation is skipped; otherwise the injection address is validated as before.

Changed from V1:
        move address based checking to uniras layer

Changed from V2:
        Check umc injection address setting flag,
        simplify non address based injection judgment


Signed-off-by: Stanley.Yang <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c       | 10 ++-
 .../gpu/drm/amd/ras/ras_mgr/amdgpu_ras_cmd.c  | 83 +++++++++++++++----
 2 files changed, 73 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
index af48dd2ebd16..f280a312b0a7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
@@ -606,8 +606,14 @@ static ssize_t amdgpu_ras_debugfs_ctrl_write(struct file 
*f,
                ret = amdgpu_ras_feature_enable(adev, &data.head, 1);
                break;
        case 2:
-               /* umc ce/ue error injection for a bad page is not allowed */
-               if (data.head.block == AMDGPU_RAS_BLOCK__UMC)
+               /*
+                * UMC ce/ue error injection for a bad page is not allowed. For
+                * uniras (SMU v13+) devices the injection address is validated 
by
+                * the ras_mgr inject handler, so only run the legacy bad page
+                * check for the legacy RAS path.
+                */
+               if (data.head.block == AMDGPU_RAS_BLOCK__UMC &&
+                   !amdgpu_uniras_enabled(adev))
                        ret = amdgpu_ras_check_bad_page(adev, 
data.inject.address);
                if (ret == -EINVAL) {
                        dev_warn(adev->dev, "RAS WARN: input address 0x%llx is 
invalid.", 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 bfbfdffbfbe6..c2285fde8b3c 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
@@ -82,6 +82,43 @@ static uint64_t local_addr_to_xgmi_global_addr(struct 
ras_core_context *ras_core
        return (addr + xgmi->physical_node_id * xgmi->node_segment_size);  }

+/*
+ * UMC error injection is dispatched by the RAS TA using the injection
+method
+ * carried in struct ras_cmd_inject_error_req. Only the "coherent"
+methods
+ * program an explicit injection address and are therefore
+address-based; the
+ * single-shot, persistent and ac-parity methods ignore the address.
+ *
+ * Keep these values in sync with the RAS TA.
+ */
+enum umc_inject_method {
+       UMC_METHOD_COHERENT             = 0,
+       UMC_METHOD_SINGLE_SHOT          = 1,
+       UMC_METHOD_PERSISTENT           = 2,
+       UMC_METHOD_PERSISTENT_DISABLE   = 3,
+       UMC_METHOD_COHERENT_NO_DETECTION        = 4,
+       UMC_METHOD_COHERENT_WR          = 5,
+       UMC_METHOD_SINGLE_SHOT_WR               = 6,
+       UMC_METHOD_PERSISTENT_WR                = 7,
+       UMC_METHOD_SINGLE_SHOT_CLEAN    = 8,
+};
+
+/*
+ * Return true when @method does not program an explicit injection address.
+ * Only the coherent methods are address-based; every other method
+ignores the
+ * address, so userspace signals them by setting the address to U64_MAX.
+ */
+static bool amdgpu_ras_mgr_is_non_address_injection(u64 method) {
+       switch (method) {
+       case UMC_METHOD_COHERENT:
+       case UMC_METHOD_COHERENT_NO_DETECTION:
+       case UMC_METHOD_COHERENT_WR:
+               return false;
+       default:
+               return true;
+       }
+}
+
 static int amdgpu_ras_inject_error(struct ras_core_context *ras_core,
                        struct ras_cmd_ctx *cmd, void *data)  { @@ -91,25 
+128,35 @@ static int amdgpu_ras_inject_error(struct ras_core_context *ras_core,
        int ret = RAS_CMD__ERROR_GENERIC;

        if (req->block_id == RAS_BLOCK_ID__UMC) {
-               if (amdgpu_ras_mgr_check_retired_addr(adev, req->address)) {
-                       RAS_DEV_WARN(ras_core->dev,
-                               "RAS WARN: inject: 0x%llx has already been 
marked as bad!\n",
-                               req->address);
-                       return RAS_CMD__ERROR_ACCESS_DENIED;
-               }
-
-               if ((req->address >= adev->gmc.mc_vram_size &&
-                       adev->gmc.mc_vram_size) ||
-                       (req->address >= RAS_UMC_INJECT_ADDR_LIMIT)) {
-                       RAS_DEV_WARN(adev, "RAS WARN: input address 0x%llx is 
invalid.",
+               /*
+                * Only address-based UMC injections carry an explicit injection
+                * address that has to be validated. A non address-based method
+                * ignores the address, and userspace flags such an injection by
+                * setting the address to U64_MAX. When both the sentinel and 
the
+                * method agree, clear the address so the RAS TA ignores it and
+                * skip the validation; otherwise validate the injection 
address.
+                */
+               if (req->address == U64_MAX && 
amdgpu_ras_mgr_is_non_address_injection(req->method)) {
+                       req->address = 0x0;
+               } else {
+                       if (amdgpu_ras_mgr_check_retired_addr(adev, 
req->address)) {
+                               RAS_DEV_WARN(ras_core->dev,
+                                       "RAS WARN: inject: 0x%llx has already 
been marked as bad!\n",
                                        req->address);
-                       return RAS_CMD__ERROR_INVALID_INPUT_DATA;
-               }
-
-               /* Calculate XGMI relative offset */
-               if (adev->gmc.xgmi.num_physical_nodes > 1 &&
-                       req->block_id != RAS_BLOCK_ID__GFX) {
-                       req->address = local_addr_to_xgmi_global_addr(ras_core, 
req->address);
+                               return RAS_CMD__ERROR_ACCESS_DENIED;
+                       }
+
+                       if ((req->address >= adev->gmc.mc_vram_size &&
+                               adev->gmc.mc_vram_size) ||
+                               (req->address >= RAS_UMC_INJECT_ADDR_LIMIT)) {
+                               RAS_DEV_WARN(adev, "RAS WARN: input address 
0x%llx is invalid.",
+                                               req->address);
+                               return RAS_CMD__ERROR_INVALID_INPUT_DATA;
+                       }
+
+                       /* Calculate XGMI relative offset */
+                       if (adev->gmc.xgmi.num_physical_nodes > 1)
+                               req->address = 
local_addr_to_xgmi_global_addr(ras_core,
+req->address);
                }
        }

--
2.43.0

Reply via email to