diff --git a/drivers/gpu/nvgpu/gk20a/regops_gk20a.c b/drivers/gpu/nvgpu/gk20a/regops_gk20a.c index a5595c158..232d01a7d 100644 --- a/drivers/gpu/nvgpu/gk20a/regops_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/regops_gk20a.c @@ -53,6 +53,31 @@ static inline bool linear_search(u32 offset, const u32 *list, int size) return false; } +/* + * In order to perform a context relative op the context has + * to be created already... which would imply that the + * context switch mechanism has already been put in place. + * So by the time we perform such an opertation it should always + * be possible to query for the appropriate context offsets, etc. + * + * But note: while the dbg_gpu bind requires the a channel fd, + * it doesn't require an allocated gr/compute obj at that point... + */ +static bool gr_context_info_available(struct gr_gk20a *gr) +{ + int err; + + nvgpu_mutex_acquire(&gr->ctx_mutex); + err = !gr->ctx_vars.golden_image_initialized; + nvgpu_mutex_release(&gr->ctx_mutex); + if (err) { + return false; + } + + return true; + +} + static bool validate_reg_ops(struct dbg_session_gk20a *dbg_s, u32 *ctx_rd_count, u32 *ctx_wr_count, struct nvgpu_dbg_reg_op *ops, @@ -91,7 +116,6 @@ int exec_regops_gk20a(struct dbg_session_gk20a *dbg_s, ok = validate_reg_ops(dbg_s, &ctx_rd_count, &ctx_wr_count, ops, num_ops); - if (!ok) { nvgpu_err(g, "invalid op(s)"); err = -EINVAL; @@ -99,6 +123,14 @@ int exec_regops_gk20a(struct dbg_session_gk20a *dbg_s, goto clean_up; } + /* be sure that ctx info is in place if there are ctx ops */ + if (ctx_wr_count | ctx_rd_count) { + if (!gr_context_info_available(&g->gr)) { + nvgpu_err(g, "gr context data not available"); + return -ENODEV; + } + } + for (i = 0; i < num_ops; i++) { /* if it isn't global then it is done in the ctx ops... */ if (ops[i].type != REGOP(TYPE_GLOBAL)) diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c b/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c index 1989a5cb4..eadf1f936 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c @@ -100,9 +100,6 @@ static int alloc_session(struct gk20a *g, struct dbg_session_gk20a_linux **_dbg_ return 0; } -static bool gr_context_info_available(struct dbg_session_gk20a *dbg_s, - struct gr_gk20a *gr); - static int gk20a_perfbuf_release_locked(struct gk20a *g, u64 offset); static int nvgpu_ioctl_channel_reg_ops(struct dbg_session_gk20a *dbg_s, @@ -870,13 +867,6 @@ static int nvgpu_ioctl_channel_reg_ops(struct dbg_session_gk20a *dbg_s, return -EINVAL; } - /* be sure that ctx info is in place */ - if (!g->is_virtual && - !gr_context_info_available(dbg_s, &g->gr)) { - nvgpu_err(g, "gr context data not available"); - return -ENODEV; - } - /* since exec_reg_ops sends methods to the ucode, it must take the * global gpu lock to protect against mixing methods from debug sessions * on other channels */ @@ -1653,29 +1643,6 @@ static void nvgpu_dbg_gpu_ioctl_get_timeout(struct dbg_session_gk20a *dbg_s, args->enable = NVGPU_DBG_GPU_IOCTL_TIMEOUT_DISABLE; } -/* In order to perform a context relative op the context has - * to be created already... which would imply that the - * context switch mechanism has already been put in place. - * So by the time we perform such an opertation it should always - * be possible to query for the appropriate context offsets, etc. - * - * But note: while the dbg_gpu bind requires the a channel fd, - * it doesn't require an allocated gr/compute obj at that point... - */ -static bool gr_context_info_available(struct dbg_session_gk20a *dbg_s, - struct gr_gk20a *gr) -{ - int err; - - nvgpu_mutex_acquire(&gr->ctx_mutex); - err = !gr->ctx_vars.golden_image_initialized; - nvgpu_mutex_release(&gr->ctx_mutex); - if (err) - return false; - return true; - -} - static int gk20a_perfbuf_release_locked(struct gk20a *g, u64 offset) { struct mm_gk20a *mm = &g->mm;