From 8618135d6ef4065cd3cf9956056b1a1a589a95ec Mon Sep 17 00:00:00 2001 From: Divya Singhatwaria Date: Fri, 31 May 2019 14:38:01 +0530 Subject: [PATCH] gpu: nvgpu: Protect elpg_stat access - Protect the access of pmu->pg->elpg_stat using g->can_elpg protection - Also, in pg public functions keep a check for if lspmu and pg features are enabled. JIRA NVGPU-3573 Change-Id: If4f25d4ab9df5e3e7257aaa9ed1e6d1fb9e431cf Signed-off-by: Divya Singhatwaria Reviewed-on: https://git-master.nvidia.com/r/2128351 Reviewed-by: Alex Waterman Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/gr/gr_falcon.c | 6 +++--- drivers/gpu/nvgpu/common/pmu/pg/pmu_pg.c | 22 +++++++++++++++++--- drivers/gpu/nvgpu/common/pmu/pmu_debug.c | 5 ++++- drivers/gpu/nvgpu/include/nvgpu/pmu/pmu_pg.h | 6 +++--- drivers/gpu/nvgpu/os/linux/debug_pmu.c | 7 ++++++- 5 files changed, 35 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/nvgpu/common/gr/gr_falcon.c b/drivers/gpu/nvgpu/common/gr/gr_falcon.c index d48049919..6f0726788 100644 --- a/drivers/gpu/nvgpu/common/gr/gr_falcon.c +++ b/drivers/gpu/nvgpu/common/gr/gr_falcon.c @@ -102,8 +102,8 @@ int nvgpu_gr_falcon_bind_fecs_elpg(struct gk20a *g) return err; } - if (nvgpu_pmu_pg_buf_get_cpu_va(pmu) == NULL) { - err = nvgpu_dma_alloc_map_sys(vm, size, nvgpu_pmu_pg_buf(pmu)); + if (nvgpu_pmu_pg_buf_get_cpu_va(g, pmu) == NULL) { + err = nvgpu_dma_alloc_map_sys(vm, size, nvgpu_pmu_pg_buf(g, pmu)); if (err != 0) { nvgpu_err(g, "failed to allocate memory"); return -ENOMEM; @@ -120,7 +120,7 @@ int nvgpu_gr_falcon_bind_fecs_elpg(struct gk20a *g) return err; } - data = u64_lo32(nvgpu_pmu_pg_buf_get_gpu_va(pmu) >> 8); + data = u64_lo32(nvgpu_pmu_pg_buf_get_gpu_va(g, pmu) >> 8); err = g->ops.gr.falcon.ctrl_ctxsw(g, NVGPU_GR_FALCON_METHOD_REGLIST_SET_VIRTUAL_ADDRESS, data, NULL); if (err != 0) { diff --git a/drivers/gpu/nvgpu/common/pmu/pg/pmu_pg.c b/drivers/gpu/nvgpu/common/pmu/pg/pmu_pg.c index f40f2ad5b..6dc6d81ed 100644 --- a/drivers/gpu/nvgpu/common/pmu/pg/pmu_pg.c +++ b/drivers/gpu/nvgpu/common/pmu/pg/pmu_pg.c @@ -974,6 +974,10 @@ int nvgpu_pmu_pg_init(struct gk20a *g, struct nvgpu_pmu *pmu, int err = 0; u32 ver = g->params.gpu_arch + g->params.gpu_impl; + if (!g->support_ls_pmu || !g->can_elpg) { + return 0; + } + if (*pg_p != NULL) { /* skip alloc/reinit for unrailgate sequence */ nvgpu_pmu_dbg(g, "skip lsfm init for unrailgate sequence"); @@ -1096,17 +1100,29 @@ bool nvgpu_pmu_is_lpwr_feature_supported(struct gk20a *g, u32 feature_id) return pmu->pg->is_lpwr_feature_supported(g, feature_id); } -u64 nvgpu_pmu_pg_buf_get_gpu_va(struct nvgpu_pmu *pmu) +u64 nvgpu_pmu_pg_buf_get_gpu_va(struct gk20a *g, struct nvgpu_pmu *pmu) { + if (!is_pg_supported(g, pmu->pg)) { + return 0; + } + return pmu->pg->pg_buf.gpu_va; } -struct nvgpu_mem *nvgpu_pmu_pg_buf(struct nvgpu_pmu *pmu) +struct nvgpu_mem *nvgpu_pmu_pg_buf(struct gk20a *g, struct nvgpu_pmu *pmu) { + if (!is_pg_supported(g, pmu->pg)) { + return NULL; + } + return &pmu->pg->pg_buf; } -void *nvgpu_pmu_pg_buf_get_cpu_va(struct nvgpu_pmu *pmu) +void *nvgpu_pmu_pg_buf_get_cpu_va(struct gk20a *g, struct nvgpu_pmu *pmu) { + if (!is_pg_supported(g, pmu->pg)) { + return NULL; + } + return pmu->pg->pg_buf.cpu_va; } diff --git a/drivers/gpu/nvgpu/common/pmu/pmu_debug.c b/drivers/gpu/nvgpu/common/pmu/pmu_debug.c index e67d639a1..ca5d9a285 100644 --- a/drivers/gpu/nvgpu/common/pmu/pmu_debug.c +++ b/drivers/gpu/nvgpu/common/pmu/pmu_debug.c @@ -109,7 +109,10 @@ void nvgpu_pmu_dump_falcon_stats(struct nvgpu_pmu *pmu) print_pmu_trace(pmu); nvgpu_err(g, "pmu state: %d", nvgpu_pmu_get_fw_state(g, pmu)); - nvgpu_err(g, "elpg state: %d", pmu->pg->elpg_stat); + + if (g->can_elpg) { + nvgpu_err(g, "elpg state: %d", pmu->pg->elpg_stat); + } /* PMU may crash due to FECS crash. Dump FECS status */ g->ops.gr.falcon.dump_stats(g); diff --git a/drivers/gpu/nvgpu/include/nvgpu/pmu/pmu_pg.h b/drivers/gpu/nvgpu/include/nvgpu/pmu/pmu_pg.h index d721a1583..a2cf29728 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/pmu/pmu_pg.h +++ b/drivers/gpu/nvgpu/include/nvgpu/pmu/pmu_pg.h @@ -141,8 +141,8 @@ int nvgpu_pmu_elpg_statistics(struct gk20a *g, u32 pg_engine_id, void nvgpu_pmu_save_zbc(struct gk20a *g, u32 entries); bool nvgpu_pmu_is_lpwr_feature_supported(struct gk20a *g, u32 feature_id); -u64 nvgpu_pmu_pg_buf_get_gpu_va(struct nvgpu_pmu *pmu); -struct nvgpu_mem *nvgpu_pmu_pg_buf(struct nvgpu_pmu *pmu); -void *nvgpu_pmu_pg_buf_get_cpu_va(struct nvgpu_pmu *pmu); +u64 nvgpu_pmu_pg_buf_get_gpu_va(struct gk20a *g, struct nvgpu_pmu *pmu); +struct nvgpu_mem *nvgpu_pmu_pg_buf(struct gk20a *g, struct nvgpu_pmu *pmu); +void *nvgpu_pmu_pg_buf_get_cpu_va(struct gk20a *g, struct nvgpu_pmu *pmu); #endif /* NVGPU_PMU_PG_H */ diff --git a/drivers/gpu/nvgpu/os/linux/debug_pmu.c b/drivers/gpu/nvgpu/os/linux/debug_pmu.c index 6017bd859..8e2f91bf9 100644 --- a/drivers/gpu/nvgpu/os/linux/debug_pmu.c +++ b/drivers/gpu/nvgpu/os/linux/debug_pmu.c @@ -29,6 +29,10 @@ static int lpwr_debug_show(struct seq_file *s, void *data) struct gk20a *g = s->private; struct nvgpu_pmu *pmu = g->pmu; + if (!g->can_elpg) { + return 0; + } + if (pmu->pg->engines_feature_list && pmu->pg->engines_feature_list(g, PMU_PG_ELPG_ENGINE_ID_GRAPHICS) != @@ -45,12 +49,13 @@ static int lpwr_debug_show(struct seq_file *s, void *data) g->pmu->pg->elpg_stat, g->mscg_enabled, g->pmu->pg->mscg_stat, g->pmu->pg->mscg_transition_state); - } else + } else { seq_printf(s, "ELPG Enabled: %u\n" "ELPG ref count: %u\n" "ELPG state: %u\n", g->elpg_enabled, g->pmu->pg->elpg_refcnt, g->pmu->pg->elpg_stat); + } return 0;