]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/amdgpu: validate and share PSP fw_pri_buf copies via psp_copy_fw
authorCandice Li <candice.li@amd.com>
Wed, 13 May 2026 10:13:30 +0000 (18:13 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 19 May 2026 15:53:16 +0000 (11:53 -0400)
Change psp_copy_fw from void to int: return -ENODEV when drm_dev_enter
fails, and -EINVAL when the image size is zero or larger than the
1 MiB PSP private buffer.

Replace open-coded memset/memcpy into fw_pri_buf with psp_copy_fw.

Signed-off-by: Candice Li <candice.li@amd.com>
Reviewed-by: Tao Zhou <tao.zhou1@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
drivers/gpu/drm/amd/amdgpu/psp_v11_0.c
drivers/gpu/drm/amd/amdgpu/psp_v12_0.c
drivers/gpu/drm/amd/amdgpu/psp_v13_0.c
drivers/gpu/drm/amd/amdgpu/psp_v13_0_4.c
drivers/gpu/drm/amd/amdgpu/psp_v14_0.c
drivers/gpu/drm/amd/amdgpu/psp_v3_1.c

index d525443e31f632e79f54ef7f30b442c6b7bd5a6b..665a2632379de2d95a37bb0a7e2024d1271ff6c5 100644 (file)
@@ -857,7 +857,11 @@ static int psp_load_toc(struct psp_context *psp,
        struct psp_gfx_cmd_resp *cmd = acquire_psp_cmd_buf(psp);
 
        /* Copy toc to psp firmware private buffer */
-       psp_copy_fw(psp, psp->toc.start_addr, psp->toc.size_bytes);
+       ret = psp_copy_fw(psp, psp->toc.start_addr, psp->toc.size_bytes);
+       if (ret) {
+               release_psp_cmd_buf(psp);
+               return ret;
+       }
 
        psp_prep_load_toc_cmd_buf(cmd, psp->fw_pri_mc_addr, psp->toc.size_bytes);
 
@@ -1173,8 +1177,11 @@ static int psp_rl_load(struct amdgpu_device *adev)
 
        cmd = acquire_psp_cmd_buf(psp);
 
-       memset(psp->fw_pri_buf, 0, PSP_1_MEG);
-       memcpy(psp->fw_pri_buf, psp->rl.start_addr, psp->rl.size_bytes);
+       ret = psp_copy_fw(psp, psp->rl.start_addr, psp->rl.size_bytes);
+       if (ret) {
+               release_psp_cmd_buf(psp);
+               return ret;
+       }
 
        cmd->cmd_id = GFX_CMD_ID_LOAD_IP_FW;
        cmd->cmd.cmd_load_ip_fw.fw_phy_addr_lo = lower_32_bits(psp->fw_pri_mc_addr);
@@ -1760,8 +1767,12 @@ int psp_ta_load(struct psp_context *psp, struct ta_context *context)
 
        cmd = acquire_psp_cmd_buf(psp);
 
-       psp_copy_fw(psp, context->bin_desc.start_addr,
-                   context->bin_desc.size_bytes);
+       ret = psp_copy_fw(psp, context->bin_desc.start_addr,
+                         context->bin_desc.size_bytes);
+       if (ret) {
+               release_psp_cmd_buf(psp);
+               return ret;
+       }
 
        if (amdgpu_virt_xgmi_migrate_enabled(psp->adev) &&
                context->mem_context.shared_bo)
@@ -4562,17 +4573,24 @@ fail:
        return count;
 }
 
-void psp_copy_fw(struct psp_context *psp, uint8_t *start_addr, uint32_t bin_size)
+int psp_copy_fw(struct psp_context *psp, uint8_t *start_addr, uint32_t bin_size)
 {
        int idx;
 
        if (!drm_dev_enter(adev_to_drm(psp->adev), &idx))
-               return;
+               return -ENODEV;
+
+       if (!bin_size || bin_size > PSP_1_MEG) {
+               dev_err(psp->adev->dev, "PSP firmware is invalid\n");
+               drm_dev_exit(idx);
+               return -EINVAL;
+       }
 
        memset(psp->fw_pri_buf, 0, PSP_1_MEG);
        memcpy(psp->fw_pri_buf, start_addr, bin_size);
 
        drm_dev_exit(idx);
+       return 0;
 }
 
 /**
index 4197179a770182b3c03fc6a424fcfdc22bdaa3dc..2d838b1b2b116cfd03a260018056c3fe06db4042 100644 (file)
@@ -638,7 +638,7 @@ int psp_get_fw_attestation_records_addr(struct psp_context *psp,
 int psp_update_fw_reservation(struct psp_context *psp);
 int psp_load_fw_list(struct psp_context *psp,
                     struct amdgpu_firmware_info **ucode_list, int ucode_count);
-void psp_copy_fw(struct psp_context *psp, uint8_t *start_addr, uint32_t bin_size);
+int psp_copy_fw(struct psp_context *psp, uint8_t *start_addr, uint32_t bin_size);
 
 int psp_spatial_partition(struct psp_context *psp, int mode);
 int psp_memory_partition(struct psp_context *psp, int mode);
index fb7aaf5ae05cfb4cf2905aa02013c39117e446de..479690c44f0d54375d0b87dba8168d253da7f413 100644 (file)
@@ -217,7 +217,9 @@ static int psp_v11_0_bootloader_load_component(struct psp_context   *psp,
                return ret;
 
        /* Copy PSP System Driver binary to memory */
-       psp_copy_fw(psp, bin_desc->start_addr, bin_desc->size_bytes);
+       ret = psp_copy_fw(psp, bin_desc->start_addr, bin_desc->size_bytes);
+       if (ret)
+               return ret;
 
        /* Provide the sys driver to bootloader */
        WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36,
@@ -263,7 +265,9 @@ static int psp_v11_0_bootloader_load_sos(struct psp_context *psp)
                return ret;
 
        /* Copy Secure OS binary to PSP memory */
-       psp_copy_fw(psp, psp->sos.start_addr, psp->sos.size_bytes);
+       ret = psp_copy_fw(psp, psp->sos.start_addr, psp->sos.size_bytes);
+       if (ret)
+               return ret;
 
        /* Provide the PSP secure OS to bootloader */
        WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36,
index c3cae29eeca1e5880561f5023a3881414070ef48..f823f042788d15b20e2e1577ce47ae22c8161128 100644 (file)
@@ -87,7 +87,9 @@ static int psp_v12_0_bootloader_load_sysdrv(struct psp_context *psp)
                return ret;
 
        /* Copy PSP System Driver binary to memory */
-       psp_copy_fw(psp, psp->sys.start_addr, psp->sys.size_bytes);
+       ret = psp_copy_fw(psp, psp->sys.start_addr, psp->sys.size_bytes);
+       if (ret)
+               return ret;
 
        /* Provide the sys driver to bootloader */
        WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36,
@@ -123,7 +125,9 @@ static int psp_v12_0_bootloader_load_sos(struct psp_context *psp)
                return ret;
 
        /* Copy Secure OS binary to PSP memory */
-       psp_copy_fw(psp, psp->sos.start_addr, psp->sos.size_bytes);
+       ret = psp_copy_fw(psp, psp->sos.start_addr, psp->sos.size_bytes);
+       if (ret)
+               return ret;
 
        /* Provide the PSP secure OS to bootloader */
        WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36,
index a0c84f81c0c9d51a16d430b11894e9e54ddc4458..00b4a34e6601f9ba03d890b071f42da6455ae6e4 100644 (file)
@@ -271,10 +271,9 @@ static int psp_v13_0_bootloader_load_component(struct psp_context          *psp,
        if (ret)
                return ret;
 
-       memset(psp->fw_pri_buf, 0, PSP_1_MEG);
-
-       /* Copy PSP KDB binary to memory */
-       memcpy(psp->fw_pri_buf, bin_desc->start_addr, bin_desc->size_bytes);
+       ret = psp_copy_fw(psp, bin_desc->start_addr, bin_desc->size_bytes);
+       if (ret)
+               return ret;
 
        /* Provide the PSP KDB to bootloader */
        WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_36,
@@ -353,10 +352,9 @@ static int psp_v13_0_bootloader_load_sos(struct psp_context *psp)
        if (ret)
                return ret;
 
-       memset(psp->fw_pri_buf, 0, PSP_1_MEG);
-
-       /* Copy Secure OS binary to PSP memory */
-       memcpy(psp->fw_pri_buf, psp->sos.start_addr, psp->sos.size_bytes);
+       ret = psp_copy_fw(psp, psp->sos.start_addr, psp->sos.size_bytes);
+       if (ret)
+               return ret;
 
        /* Provide the PSP secure OS to bootloader */
        WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_36,
index 5f39a2edcc9562776e877317b101830d75c6a82d..3d5e26b3fa00ac05f3e921dd2e1129f99411d383 100644 (file)
@@ -105,10 +105,9 @@ static int psp_v13_0_4_bootloader_load_component(struct psp_context        *psp,
        if (ret)
                return ret;
 
-       memset(psp->fw_pri_buf, 0, PSP_1_MEG);
-
-       /* Copy PSP KDB binary to memory */
-       memcpy(psp->fw_pri_buf, bin_desc->start_addr, bin_desc->size_bytes);
+       ret = psp_copy_fw(psp, bin_desc->start_addr, bin_desc->size_bytes);
+       if (ret)
+               return ret;
 
        /* Provide the PSP KDB to bootloader */
        WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_36,
@@ -168,10 +167,9 @@ static int psp_v13_0_4_bootloader_load_sos(struct psp_context *psp)
        if (ret)
                return ret;
 
-       memset(psp->fw_pri_buf, 0, PSP_1_MEG);
-
-       /* Copy Secure OS binary to PSP memory */
-       memcpy(psp->fw_pri_buf, psp->sos.start_addr, psp->sos.size_bytes);
+       ret = psp_copy_fw(psp, psp->sos.start_addr, psp->sos.size_bytes);
+       if (ret)
+               return ret;
 
        /* Provide the PSP secure OS to bootloader */
        WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_36,
index 38dfc5c19f2a7e90e7591583961e52446b9a3836..040a61aefa86693685a9d9018a8a1ded753c11c1 100644 (file)
@@ -140,10 +140,9 @@ static int psp_v14_0_bootloader_load_component(struct psp_context          *psp,
        if (ret)
                return ret;
 
-       memset(psp->fw_pri_buf, 0, PSP_1_MEG);
-
-       /* Copy PSP KDB binary to memory */
-       memcpy(psp->fw_pri_buf, bin_desc->start_addr, bin_desc->size_bytes);
+       ret = psp_copy_fw(psp, bin_desc->start_addr, bin_desc->size_bytes);
+       if (ret)
+               return ret;
 
        /* Provide the PSP KDB to bootloader */
        WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_36,
@@ -214,10 +213,9 @@ static int psp_v14_0_bootloader_load_sos(struct psp_context *psp)
        if (ret)
                return ret;
 
-       memset(psp->fw_pri_buf, 0, PSP_1_MEG);
-
-       /* Copy Secure OS binary to PSP memory */
-       memcpy(psp->fw_pri_buf, psp->sos.start_addr, psp->sos.size_bytes);
+       ret = psp_copy_fw(psp, psp->sos.start_addr, psp->sos.size_bytes);
+       if (ret)
+               return ret;
 
        /* Provide the PSP secure OS to bootloader */
        WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_36,
index f5030efc6c804a739ac074832d4c09438f0b00f0..24856c91c1351b6333d941aef15ff9e1ff84aed0 100644 (file)
@@ -96,7 +96,9 @@ static int psp_v3_1_bootloader_load_sysdrv(struct psp_context *psp)
                return ret;
 
        /* Copy PSP System Driver binary to memory */
-       psp_copy_fw(psp, psp->sys.start_addr, psp->sys.size_bytes);
+       ret = psp_copy_fw(psp, psp->sys.start_addr, psp->sys.size_bytes);
+       if (ret)
+               return ret;
 
        /* Provide the sys driver to bootloader */
        WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36,
@@ -135,7 +137,9 @@ static int psp_v3_1_bootloader_load_sos(struct psp_context *psp)
                return ret;
 
        /* Copy Secure OS binary to PSP memory */
-       psp_copy_fw(psp, psp->sos.start_addr, psp->sos.size_bytes);
+       ret = psp_copy_fw(psp, psp->sos.start_addr, psp->sos.size_bytes);
+       if (ret)
+               return ret;
 
        /* Provide the PSP secure OS to bootloader */
        WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36,