diff options
Diffstat (limited to 'drivers/gpu/nvgpu/common/linux')
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c | 37 |
1 files changed, 31 insertions, 6 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c b/drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c index 88c8debf..4bb79375 100644 --- a/drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c +++ b/drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c | |||
@@ -429,15 +429,24 @@ static int nvgpu_gpu_ioctl_wait_for_pause(struct gk20a *g, | |||
429 | struct nvgpu_gpu_wait_pause_args *args) | 429 | struct nvgpu_gpu_wait_pause_args *args) |
430 | { | 430 | { |
431 | int err; | 431 | int err; |
432 | struct warpstate *w_state; | 432 | struct warpstate *ioctl_w_state; |
433 | u32 sm_count, size; | 433 | struct nvgpu_warpstate *w_state = NULL; |
434 | u32 sm_count, ioctl_size, size, sm_id; | ||
434 | 435 | ||
435 | sm_count = g->gr.gpc_count * g->gr.tpc_count; | 436 | sm_count = g->gr.gpc_count * g->gr.tpc_count; |
436 | size = sm_count * sizeof(struct warpstate); | 437 | |
437 | w_state = nvgpu_kzalloc(g, size); | 438 | ioctl_size = sm_count * sizeof(struct warpstate); |
438 | if (!w_state) | 439 | ioctl_w_state = nvgpu_kzalloc(g, ioctl_size); |
440 | if (!ioctl_w_state) | ||
439 | return -ENOMEM; | 441 | return -ENOMEM; |
440 | 442 | ||
443 | size = sm_count * sizeof(struct nvgpu_warpstate); | ||
444 | w_state = nvgpu_kzalloc(g, size); | ||
445 | if (!w_state) { | ||
446 | err = -ENOMEM; | ||
447 | goto out_free; | ||
448 | } | ||
449 | |||
441 | err = gk20a_busy(g); | 450 | err = gk20a_busy(g); |
442 | if (err) | 451 | if (err) |
443 | goto out_free; | 452 | goto out_free; |
@@ -445,8 +454,23 @@ static int nvgpu_gpu_ioctl_wait_for_pause(struct gk20a *g, | |||
445 | nvgpu_mutex_acquire(&g->dbg_sessions_lock); | 454 | nvgpu_mutex_acquire(&g->dbg_sessions_lock); |
446 | g->ops.gr.wait_for_pause(g, w_state); | 455 | g->ops.gr.wait_for_pause(g, w_state); |
447 | 456 | ||
457 | for (sm_id = 0; sm_id < g->gr.no_of_sm; sm_id++) { | ||
458 | ioctl_w_state[sm_id].valid_warps[0] = | ||
459 | w_state[sm_id].valid_warps[0]; | ||
460 | ioctl_w_state[sm_id].valid_warps[1] = | ||
461 | w_state[sm_id].valid_warps[1]; | ||
462 | ioctl_w_state[sm_id].trapped_warps[0] = | ||
463 | w_state[sm_id].trapped_warps[0]; | ||
464 | ioctl_w_state[sm_id].trapped_warps[1] = | ||
465 | w_state[sm_id].trapped_warps[1]; | ||
466 | ioctl_w_state[sm_id].paused_warps[0] = | ||
467 | w_state[sm_id].paused_warps[0]; | ||
468 | ioctl_w_state[sm_id].paused_warps[1] = | ||
469 | w_state[sm_id].paused_warps[1]; | ||
470 | } | ||
448 | /* Copy to user space - pointed by "args->pwarpstate" */ | 471 | /* Copy to user space - pointed by "args->pwarpstate" */ |
449 | if (copy_to_user((void __user *)(uintptr_t)args->pwarpstate, w_state, size)) { | 472 | if (copy_to_user((void __user *)(uintptr_t)args->pwarpstate, |
473 | w_state, ioctl_size)) { | ||
450 | gk20a_dbg_fn("copy_to_user failed!"); | 474 | gk20a_dbg_fn("copy_to_user failed!"); |
451 | err = -EFAULT; | 475 | err = -EFAULT; |
452 | } | 476 | } |
@@ -457,6 +481,7 @@ static int nvgpu_gpu_ioctl_wait_for_pause(struct gk20a *g, | |||
457 | 481 | ||
458 | out_free: | 482 | out_free: |
459 | nvgpu_kfree(g, w_state); | 483 | nvgpu_kfree(g, w_state); |
484 | nvgpu_kfree(g, ioctl_w_state); | ||
460 | 485 | ||
461 | return err; | 486 | return err; |
462 | } | 487 | } |