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

Configure Feed

Select the types of activity you want to include in your feed.

drm/amdgpu: validate userq buffer virtual address and size

It needs to validate the userq object virtual address to
determine whether it is residented in a valid vm mapping.

Signed-off-by: Prike Liang <Prike.Liang@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Prike Liang and committed by
Alex Deucher
9e46b8bb 4ba48fc3

+58
+40
drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
··· 44 44 return userq_ip_mask; 45 45 } 46 46 47 + int amdgpu_userq_input_va_validate(struct amdgpu_vm *vm, u64 addr, 48 + u64 expected_size) 49 + { 50 + struct amdgpu_bo_va_mapping *va_map; 51 + u64 user_addr; 52 + u64 size; 53 + int r = 0; 54 + 55 + user_addr = (addr & AMDGPU_GMC_HOLE_MASK) >> AMDGPU_GPU_PAGE_SHIFT; 56 + size = expected_size >> AMDGPU_GPU_PAGE_SHIFT; 57 + 58 + r = amdgpu_bo_reserve(vm->root.bo, false); 59 + if (r) 60 + return r; 61 + 62 + va_map = amdgpu_vm_bo_lookup_mapping(vm, user_addr); 63 + if (!va_map) { 64 + r = -EINVAL; 65 + goto out_err; 66 + } 67 + /* Only validate the userq whether resident in the VM mapping range */ 68 + if (user_addr >= va_map->start && 69 + va_map->last - user_addr + 1 >= size) { 70 + amdgpu_bo_unreserve(vm->root.bo); 71 + return 0; 72 + } 73 + 74 + out_err: 75 + amdgpu_bo_unreserve(vm->root.bo); 76 + return r; 77 + } 78 + 47 79 static int 48 80 amdgpu_userq_unmap_helper(struct amdgpu_userq_mgr *uq_mgr, 49 81 struct amdgpu_usermode_queue *queue) ··· 458 426 if (!queue) { 459 427 drm_file_err(uq_mgr->file, "Failed to allocate memory for queue\n"); 460 428 r = -ENOMEM; 429 + goto unlock; 430 + } 431 + 432 + /* Validate the userq virtual address.*/ 433 + if (amdgpu_userq_input_va_validate(&fpriv->vm, args->in.queue_va, args->in.queue_size) || 434 + amdgpu_userq_input_va_validate(&fpriv->vm, args->in.rptr_va, AMDGPU_GPU_PAGE_SIZE) || 435 + amdgpu_userq_input_va_validate(&fpriv->vm, args->in.wptr_va, AMDGPU_GPU_PAGE_SIZE)) { 436 + kfree(queue); 461 437 goto unlock; 462 438 } 463 439 queue->doorbell_handle = args->in.doorbell_handle;
+2
drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
··· 137 137 int amdgpu_userq_start_sched_for_enforce_isolation(struct amdgpu_device *adev, 138 138 u32 idx); 139 139 140 + int amdgpu_userq_input_va_validate(struct amdgpu_vm *vm, u64 addr, 141 + u64 expected_size); 140 142 #endif
+16
drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
··· 254 254 struct amdgpu_mqd *mqd_hw_default = &adev->mqds[queue->queue_type]; 255 255 struct drm_amdgpu_userq_in *mqd_user = args_in; 256 256 struct amdgpu_mqd_prop *userq_props; 257 + struct amdgpu_gfx_shadow_info shadow_info; 257 258 int r; 258 259 259 260 /* Structure to initialize MQD for userqueue using generic MQD init function */ ··· 280 279 userq_props->doorbell_index = queue->doorbell_index; 281 280 userq_props->fence_address = queue->fence_drv->gpu_addr; 282 281 282 + if (adev->gfx.funcs->get_gfx_shadow_info) 283 + adev->gfx.funcs->get_gfx_shadow_info(adev, &shadow_info, true); 283 284 if (queue->queue_type == AMDGPU_HW_IP_COMPUTE) { 284 285 struct drm_amdgpu_userq_mqd_compute_gfx11 *compute_mqd; 285 286 ··· 297 294 r = -ENOMEM; 298 295 goto free_mqd; 299 296 } 297 + 298 + if (amdgpu_userq_input_va_validate(queue->vm, compute_mqd->eop_va, 299 + max_t(u32, PAGE_SIZE, AMDGPU_GPU_PAGE_SIZE))) 300 + goto free_mqd; 300 301 301 302 userq_props->eop_gpu_addr = compute_mqd->eop_va; 302 303 userq_props->hqd_pipe_priority = AMDGPU_GFX_PIPE_PRIO_NORMAL; ··· 329 322 userq_props->csa_addr = mqd_gfx_v11->csa_va; 330 323 userq_props->tmz_queue = 331 324 mqd_user->flags & AMDGPU_USERQ_CREATE_FLAGS_QUEUE_SECURE; 325 + 326 + if (amdgpu_userq_input_va_validate(queue->vm, mqd_gfx_v11->shadow_va, 327 + shadow_info.shadow_size)) 328 + goto free_mqd; 329 + 332 330 kfree(mqd_gfx_v11); 333 331 } else if (queue->queue_type == AMDGPU_HW_IP_DMA) { 334 332 struct drm_amdgpu_userq_mqd_sdma_gfx11 *mqd_sdma_v11; ··· 350 338 r = -ENOMEM; 351 339 goto free_mqd; 352 340 } 341 + 342 + if (amdgpu_userq_input_va_validate(queue->vm, mqd_sdma_v11->csa_va, 343 + shadow_info.csa_size)) 344 + goto free_mqd; 353 345 354 346 userq_props->csa_addr = mqd_sdma_v11->csa_va; 355 347 kfree(mqd_sdma_v11);