Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amdgpu: Optimize TA load/unload/invoke debugfs interfaces

1. Add a function pointer structure ta_funcs to psp context
2. Make the interfaces generic to all TAs
3. Leverage exisitng TA context and remove unused functions
4. Fix return code bugs

v2: Add comments for ta funcs macros and correct typo

Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: Candice Li <candice.li@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Candice Li and committed by
Alex Deucher
896b7add bf7d7772

+173 -109
+1 -37
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
··· 1071 1071 &mem_ctx->shared_buf); 1072 1072 } 1073 1073 1074 - static void psp_prep_ta_invoke_indirect_cmd_buf(struct psp_gfx_cmd_resp *cmd, 1075 - uint32_t ta_cmd_id, 1076 - struct ta_context *context) 1077 - { 1078 - cmd->cmd_id = GFX_CMD_ID_INVOKE_CMD; 1079 - cmd->cmd.cmd_invoke_cmd.session_id = context->session_id; 1080 - cmd->cmd.cmd_invoke_cmd.ta_cmd_id = ta_cmd_id; 1081 - 1082 - cmd->cmd.cmd_invoke_cmd.buf.num_desc = 1; 1083 - cmd->cmd.cmd_invoke_cmd.buf.total_size = context->mem_context.shared_mem_size; 1084 - cmd->cmd.cmd_invoke_cmd.buf.buf_desc[0].buf_size = context->mem_context.shared_mem_size; 1085 - cmd->cmd.cmd_invoke_cmd.buf.buf_desc[0].buf_phy_addr_lo = 1086 - lower_32_bits(context->mem_context.shared_mc_addr); 1087 - cmd->cmd.cmd_invoke_cmd.buf.buf_desc[0].buf_phy_addr_hi = 1088 - upper_32_bits(context->mem_context.shared_mc_addr); 1089 - } 1090 - 1091 - int psp_ta_invoke_indirect(struct psp_context *psp, 1092 - uint32_t ta_cmd_id, 1093 - struct ta_context *context) 1094 - { 1095 - int ret; 1096 - struct psp_gfx_cmd_resp *cmd = acquire_psp_cmd_buf(psp); 1097 - 1098 - psp_prep_ta_invoke_indirect_cmd_buf(cmd, ta_cmd_id, context); 1099 - 1100 - ret = psp_cmd_submit_buf(psp, NULL, cmd, 1101 - psp->fence_buf_mc_addr); 1102 - 1103 - context->resp_status = cmd->resp.status; 1104 - 1105 - release_psp_cmd_buf(psp); 1106 - 1107 - return ret; 1108 - } 1109 - 1110 1074 static void psp_prep_ta_invoke_cmd_buf(struct psp_gfx_cmd_resp *cmd, 1111 1075 uint32_t ta_cmd_id, 1112 1076 uint32_t session_id) ··· 1513 1549 return ret; 1514 1550 } 1515 1551 1516 - static int psp_ras_initialize(struct psp_context *psp) 1552 + int psp_ras_initialize(struct psp_context *psp) 1517 1553 { 1518 1554 int ret; 1519 1555 uint32_t boot_cfg = 0xFF;
+8 -4
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
··· 136 136 int (*vbflash_stat)(struct psp_context *psp); 137 137 }; 138 138 139 + struct ta_funcs { 140 + int (*fn_ta_initialize)(struct psp_context *psp); 141 + int (*fn_ta_invoke)(struct psp_context *psp, uint32_t ta_cmd_id); 142 + int (*fn_ta_terminate)(struct psp_context *psp); 143 + }; 144 + 139 145 #define AMDGPU_XGMI_MAX_CONNECTED_NODES 64 140 146 struct psp_xgmi_node_info { 141 147 uint64_t node_id; ··· 315 309 struct psp_gfx_cmd_resp *cmd; 316 310 317 311 const struct psp_funcs *funcs; 312 + const struct ta_funcs *ta_funcs; 318 313 319 314 /* firmware buffer */ 320 315 struct amdgpu_bo *fw_pri_bo; ··· 470 463 int psp_ta_invoke(struct psp_context *psp, 471 464 uint32_t ta_cmd_id, 472 465 struct ta_context *context); 473 - int psp_ta_invoke_indirect(struct psp_context *psp, 474 - uint32_t ta_cmd_id, 475 - struct ta_context *context); 476 466 477 467 int psp_xgmi_initialize(struct psp_context *psp, bool set_extended_data, bool load_ta); 478 468 int psp_xgmi_terminate(struct psp_context *psp); ··· 483 479 int psp_xgmi_set_topology_info(struct psp_context *psp, 484 480 int number_devices, 485 481 struct psp_xgmi_topology_info *topology); 486 - 482 + int psp_ras_initialize(struct psp_context *psp); 487 483 int psp_ras_invoke(struct psp_context *psp, uint32_t ta_cmd_id); 488 484 int psp_ras_enable_features(struct psp_context *psp, 489 485 union ta_ras_cmd_input *info, bool enable);
+159 -68
drivers/gpu/drm/amd/amdgpu/amdgpu_psp_ta.c
··· 41 41 return hdr->ucode_version; 42 42 } 43 43 44 - static void prep_ta_mem_context(struct psp_context *psp, 45 - struct ta_context *context, 44 + static int prep_ta_mem_context(struct ta_mem_context *mem_context, 46 45 uint8_t *shared_buf, 47 46 uint32_t shared_buf_len) 48 47 { 49 - context->mem_context.shared_mem_size = PAGE_ALIGN(shared_buf_len); 50 - psp_ta_init_shared_buf(psp, &context->mem_context); 48 + if (mem_context->shared_mem_size < shared_buf_len) 49 + return -EINVAL; 50 + memset(mem_context->shared_buf, 0, mem_context->shared_mem_size); 51 + memcpy((void *)mem_context->shared_buf, shared_buf, shared_buf_len); 51 52 52 - memcpy((void *)context->mem_context.shared_buf, shared_buf, shared_buf_len); 53 + return 0; 53 54 } 54 55 55 56 static bool is_ta_type_valid(enum ta_type_id ta_type) 56 57 { 57 - bool ret = false; 58 - 59 58 switch (ta_type) { 60 59 case TA_TYPE_RAS: 61 - ret = true; 60 + return true; 61 + default: 62 + return false; 63 + } 64 + } 65 + 66 + static const struct ta_funcs ras_ta_funcs = { 67 + .fn_ta_initialize = psp_ras_initialize, 68 + .fn_ta_invoke = psp_ras_invoke, 69 + .fn_ta_terminate = psp_ras_terminate 70 + }; 71 + 72 + static void set_ta_context_funcs(struct psp_context *psp, 73 + enum ta_type_id ta_type, 74 + struct ta_context **pcontext) 75 + { 76 + switch (ta_type) { 77 + case TA_TYPE_RAS: 78 + *pcontext = &psp->ras_context.context; 79 + psp->ta_funcs = &ras_ta_funcs; 62 80 break; 63 81 default: 64 82 break; 65 83 } 66 - 67 - return ret; 68 84 } 69 85 70 86 static const struct file_operations ta_load_debugfs_fops = { ··· 101 85 .owner = THIS_MODULE 102 86 }; 103 87 104 - 105 - /** 88 + /* 106 89 * DOC: AMDGPU TA debugfs interfaces 107 90 * 108 91 * Three debugfs interfaces can be opened by a program to ··· 126 111 * 127 112 * - For TA invoke debugfs interface: 128 113 * Transmit buffer: 114 + * - TA type (4bytes) 129 115 * - TA ID (4bytes) 130 116 * - TA CMD ID (4bytes) 131 - * - TA shard buf length (4bytes) 117 + * - TA shard buf length 118 + * (4bytes, value not beyond TA shared memory size) 132 119 * - TA shared buf 133 120 * Receive buffer: 134 121 * - TA shared buf 135 122 * 136 123 * - For TA unload debugfs interface: 137 124 * Transmit buffer: 125 + * - TA type (4bytes) 138 126 * - TA ID (4bytes) 139 127 */ 140 128 ··· 149 131 uint32_t copy_pos = 0; 150 132 int ret = 0; 151 133 152 - struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(fp)->i_private; 153 - struct psp_context *psp = &adev->psp; 154 - struct ta_context context = {0}; 134 + struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(fp)->i_private; 135 + struct psp_context *psp = &adev->psp; 136 + struct ta_context *context = NULL; 155 137 156 138 if (!buf) 157 139 return -EINVAL; 158 140 159 141 ret = copy_from_user((void *)&ta_type, &buf[copy_pos], sizeof(uint32_t)); 160 142 if (ret || (!is_ta_type_valid(ta_type))) 161 - return -EINVAL; 143 + return -EFAULT; 162 144 163 145 copy_pos += sizeof(uint32_t); 164 146 165 147 ret = copy_from_user((void *)&ta_bin_len, &buf[copy_pos], sizeof(uint32_t)); 166 148 if (ret) 167 - return -EINVAL; 149 + return -EFAULT; 168 150 169 151 copy_pos += sizeof(uint32_t); 170 152 171 153 ta_bin = kzalloc(ta_bin_len, GFP_KERNEL); 172 154 if (!ta_bin) 173 - ret = -ENOMEM; 155 + return -ENOMEM; 174 156 if (copy_from_user((void *)ta_bin, &buf[copy_pos], ta_bin_len)) { 175 157 ret = -EFAULT; 176 158 goto err_free_bin; 177 159 } 178 160 179 - ret = psp_ras_terminate(psp); 180 - if (ret) { 181 - dev_err(adev->dev, "Failed to unload embedded RAS TA\n"); 161 + /* Set TA context and functions */ 162 + set_ta_context_funcs(psp, ta_type, &context); 163 + 164 + if (!psp->ta_funcs || !psp->ta_funcs->fn_ta_terminate) { 165 + dev_err(adev->dev, "Unsupported function to terminate TA\n"); 166 + ret = -EOPNOTSUPP; 182 167 goto err_free_bin; 183 168 } 184 169 185 - context.ta_type = ta_type; 186 - context.ta_load_type = GFX_CMD_ID_LOAD_TA; 187 - context.bin_desc.fw_version = get_bin_version(ta_bin); 188 - context.bin_desc.size_bytes = ta_bin_len; 189 - context.bin_desc.start_addr = ta_bin; 170 + /* 171 + * Allocate TA shared buf in case shared buf was freed 172 + * due to loading TA failed before. 173 + */ 174 + if (!context->mem_context.shared_buf) { 175 + ret = psp_ta_init_shared_buf(psp, &context->mem_context); 176 + if (ret) { 177 + ret = -ENOMEM; 178 + goto err_free_bin; 179 + } 180 + } 190 181 191 - ret = psp_ta_load(psp, &context); 192 - 193 - if (ret || context.resp_status) { 194 - dev_err(adev->dev, "TA load via debugfs failed (%d) status %d\n", 195 - ret, context.resp_status); 182 + ret = psp_fn_ta_terminate(psp); 183 + if (ret || context->resp_status) { 184 + dev_err(adev->dev, 185 + "Failed to unload embedded TA (%d) and status (0x%X)\n", 186 + ret, context->resp_status); 196 187 if (!ret) 197 188 ret = -EINVAL; 198 - goto err_free_bin; 189 + goto err_free_ta_shared_buf; 199 190 } 200 191 201 - context.initialized = true; 202 - if (copy_to_user((char *)buf, (void *)&context.session_id, sizeof(uint32_t))) 192 + /* Prepare TA context for TA initialization */ 193 + context->ta_type = ta_type; 194 + context->bin_desc.fw_version = get_bin_version(ta_bin); 195 + context->bin_desc.size_bytes = ta_bin_len; 196 + context->bin_desc.start_addr = ta_bin; 197 + 198 + if (!psp->ta_funcs->fn_ta_initialize) { 199 + dev_err(adev->dev, "Unsupported function to initialize TA\n"); 200 + ret = -EOPNOTSUPP; 201 + goto err_free_ta_shared_buf; 202 + } 203 + 204 + ret = psp_fn_ta_initialize(psp); 205 + if (ret || context->resp_status) { 206 + dev_err(adev->dev, "Failed to load TA via debugfs (%d) and status (0x%X)\n", 207 + ret, context->resp_status); 208 + if (!ret) 209 + ret = -EINVAL; 210 + goto err_free_ta_shared_buf; 211 + } 212 + 213 + if (copy_to_user((char *)buf, (void *)&context->session_id, sizeof(uint32_t))) 203 214 ret = -EFAULT; 204 215 216 + err_free_ta_shared_buf: 217 + /* Only free TA shared buf when returns error code */ 218 + if (ret && context->mem_context.shared_buf) 219 + psp_ta_free_shared_buf(&context->mem_context); 205 220 err_free_bin: 206 221 kfree(ta_bin); 207 222 ··· 243 192 244 193 static ssize_t ta_if_unload_debugfs_write(struct file *fp, const char *buf, size_t len, loff_t *off) 245 194 { 246 - uint32_t ta_id = 0; 247 - int ret = 0; 195 + uint32_t ta_type = 0; 196 + uint32_t ta_id = 0; 197 + uint32_t copy_pos = 0; 198 + int ret = 0; 248 199 249 - struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(fp)->i_private; 250 - struct psp_context *psp = &adev->psp; 251 - struct ta_context context = {0}; 200 + struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(fp)->i_private; 201 + struct psp_context *psp = &adev->psp; 202 + struct ta_context *context = NULL; 252 203 253 204 if (!buf) 254 205 return -EINVAL; 255 206 256 - ret = copy_from_user((void *)&ta_id, buf, sizeof(uint32_t)); 207 + ret = copy_from_user((void *)&ta_type, &buf[copy_pos], sizeof(uint32_t)); 208 + if (ret || (!is_ta_type_valid(ta_type))) 209 + return -EFAULT; 210 + 211 + copy_pos += sizeof(uint32_t); 212 + 213 + ret = copy_from_user((void *)&ta_id, &buf[copy_pos], sizeof(uint32_t)); 257 214 if (ret) 258 - return -EINVAL; 215 + return -EFAULT; 259 216 260 - context.session_id = ta_id; 217 + set_ta_context_funcs(psp, ta_type, &context); 218 + context->session_id = ta_id; 261 219 262 - ret = psp_ta_unload(psp, &context); 263 - if (!ret) 264 - context.initialized = false; 220 + if (!psp->ta_funcs || !psp->ta_funcs->fn_ta_terminate) { 221 + dev_err(adev->dev, "Unsupported function to terminate TA\n"); 222 + return -EOPNOTSUPP; 223 + } 224 + 225 + ret = psp_fn_ta_terminate(psp); 226 + if (ret || context->resp_status) { 227 + dev_err(adev->dev, "Failed to unload TA via debugfs (%d) and status (0x%X)\n", 228 + ret, context->resp_status); 229 + if (!ret) 230 + ret = -EINVAL; 231 + } 232 + 233 + if (context->mem_context.shared_buf) 234 + psp_ta_free_shared_buf(&context->mem_context); 265 235 266 236 return ret; 267 237 } 268 238 269 239 static ssize_t ta_if_invoke_debugfs_write(struct file *fp, const char *buf, size_t len, loff_t *off) 270 240 { 241 + uint32_t ta_type = 0; 271 242 uint32_t ta_id = 0; 272 243 uint32_t cmd_id = 0; 273 244 uint32_t shared_buf_len = 0; 274 - uint8_t *shared_buf = NULL; 245 + uint8_t *shared_buf = NULL; 275 246 uint32_t copy_pos = 0; 276 247 int ret = 0; 277 248 278 - struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(fp)->i_private; 279 - struct psp_context *psp = &adev->psp; 280 - struct ta_context context = {0}; 249 + struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(fp)->i_private; 250 + struct psp_context *psp = &adev->psp; 251 + struct ta_context *context = NULL; 281 252 282 253 if (!buf) 283 254 return -EINVAL; 284 255 256 + ret = copy_from_user((void *)&ta_type, &buf[copy_pos], sizeof(uint32_t)); 257 + if (ret) 258 + return -EFAULT; 259 + copy_pos += sizeof(uint32_t); 260 + 285 261 ret = copy_from_user((void *)&ta_id, &buf[copy_pos], sizeof(uint32_t)); 286 262 if (ret) 287 - return -EINVAL; 263 + return -EFAULT; 288 264 copy_pos += sizeof(uint32_t); 289 265 290 266 ret = copy_from_user((void *)&cmd_id, &buf[copy_pos], sizeof(uint32_t)); 291 267 if (ret) 292 - return -EINVAL; 268 + return -EFAULT; 293 269 copy_pos += sizeof(uint32_t); 294 270 295 271 ret = copy_from_user((void *)&shared_buf_len, &buf[copy_pos], sizeof(uint32_t)); 296 272 if (ret) 297 - return -EINVAL; 273 + return -EFAULT; 298 274 copy_pos += sizeof(uint32_t); 299 275 300 276 shared_buf = kzalloc(shared_buf_len, GFP_KERNEL); ··· 332 254 goto err_free_shared_buf; 333 255 } 334 256 335 - context.session_id = ta_id; 257 + set_ta_context_funcs(psp, ta_type, &context); 336 258 337 - prep_ta_mem_context(psp, &context, shared_buf, shared_buf_len); 338 - 339 - ret = psp_ta_invoke_indirect(psp, cmd_id, &context); 340 - 341 - if (ret || context.resp_status) { 342 - dev_err(adev->dev, "TA invoke via debugfs failed (%d) status %d\n", 343 - ret, context.resp_status); 344 - if (!ret) 345 - ret = -EINVAL; 346 - goto err_free_ta_shared_buf; 259 + if (!context->initialized) { 260 + dev_err(adev->dev, "TA is not initialized\n"); 261 + ret = -EINVAL; 262 + goto err_free_shared_buf; 347 263 } 348 264 349 - if (copy_to_user((char *)buf, context.mem_context.shared_buf, shared_buf_len)) 350 - ret = -EFAULT; 265 + if (!psp->ta_funcs || !psp->ta_funcs->fn_ta_invoke) { 266 + dev_err(adev->dev, "Unsupported function to invoke TA\n"); 267 + ret = -EOPNOTSUPP; 268 + goto err_free_shared_buf; 269 + } 351 270 352 - err_free_ta_shared_buf: 353 - psp_ta_free_shared_buf(&context.mem_context); 271 + context->session_id = ta_id; 272 + 273 + ret = prep_ta_mem_context(&context->mem_context, shared_buf, shared_buf_len); 274 + if (ret) 275 + goto err_free_shared_buf; 276 + 277 + ret = psp_fn_ta_invoke(psp, cmd_id); 278 + if (ret || context->resp_status) { 279 + dev_err(adev->dev, "Failed to invoke TA via debugfs (%d) and status (0x%X)\n", 280 + ret, context->resp_status); 281 + if (!ret) { 282 + ret = -EINVAL; 283 + goto err_free_shared_buf; 284 + } 285 + } 286 + 287 + if (copy_to_user((char *)buf, context->mem_context.shared_buf, shared_buf_len)) 288 + ret = -EFAULT; 354 289 355 290 err_free_shared_buf: 356 291 kfree(shared_buf);
+5
drivers/gpu/drm/amd/amdgpu/amdgpu_psp_ta.h
··· 24 24 #ifndef __AMDGPU_PSP_TA_H__ 25 25 #define __AMDGPU_PSP_TA_H__ 26 26 27 + /* Calling set_ta_context_funcs is required before using the following macros */ 28 + #define psp_fn_ta_initialize(psp) ((psp)->ta_funcs->fn_ta_initialize((psp))) 29 + #define psp_fn_ta_invoke(psp, ta_cmd_id) ((psp)->ta_funcs->fn_ta_invoke((psp), (ta_cmd_id))) 30 + #define psp_fn_ta_terminate(psp) ((psp)->ta_funcs->fn_ta_terminate((psp))) 31 + 27 32 void amdgpu_ta_if_debugfs_init(struct amdgpu_device *adev); 28 33 29 34 #endif