From b4b98aba0225c8f32887ef4781d23accebef08d9 Mon Sep 17 00:00:00 2001 From: Divya Date: Thu, 17 Nov 2022 12:53:03 +0000 Subject: [PATCH] gpu: nvgpu: reorder elpg and elpg_ms flags check - In rmmod path, gr struct is freed first and then info_mem_destroy is called which calls elpg_ms protected call. This in turn waits for gr init where gr struct is accessed. This could lead to NULL access. - move elpg and elpg_ms flag check before checking pg initialized and gr wait conditions to avoid the NULL access issue. Bug 3848290 Change-Id: I088d89d7876405cc7abedb777884b442726e992f Signed-off-by: Divya Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2811131 Reviewed-by: svcacv Reviewed-by: svc-mobile-coverity Reviewed-by: svc-mobile-cert Reviewed-by: Sagar Kamble Reviewed-by: Mahantesh Kumbar GVS: Gerrit_Virtual_Submit --- .../gpu/nvgpu/common/power_features/pg/pg.c | 33 ++++++++++++------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/nvgpu/common/power_features/pg/pg.c b/drivers/gpu/nvgpu/common/power_features/pg/pg.c index 68b54a577..94162193b 100644 --- a/drivers/gpu/nvgpu/common/power_features/pg/pg.c +++ b/drivers/gpu/nvgpu/common/power_features/pg/pg.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2019-2022, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -129,13 +129,19 @@ int nvgpu_pg_elpg_ms_enable(struct gk20a *g) return 0; } - if (g->pmu->pg->initialized) { + /* + * If elpg and elpg_ms flags are set to true + * and pg is initialized then only we wait + * for gr init. In rmmod path, the gr struct + * could be freed earlier. In order to avoid + * NULL access for gr, we check for these + * conditions then proceed further. + */ + if ((g->elpg_enabled) && (g->elpg_ms_enabled) && + (g->pmu->pg->initialized)) { g->ops.gr.init.wait_initialized(g); - nvgpu_mutex_acquire(&g->cg_pg_lock); - if ((g->elpg_enabled) && (g->elpg_ms_enabled)) { - err = nvgpu_pmu_enable_elpg_ms(g); - } + err = nvgpu_pmu_enable_elpg_ms(g); nvgpu_mutex_release(&g->cg_pg_lock); } #endif @@ -152,14 +158,17 @@ int nvgpu_pg_elpg_ms_disable(struct gk20a *g) return 0; } - if (g->pmu->pg->initialized) { - g->ops.gr.init.wait_initialized(g); - - nvgpu_mutex_acquire(&g->cg_pg_lock); - if ((g->elpg_enabled) && (g->elpg_ms_enabled)) { + /* + * If elpg and elpg_ms flags are set to true + * then only we check further conditions. + */ + if ((g->elpg_enabled) && (g->elpg_ms_enabled)) { + if (g->pmu->pg->initialized) { + g->ops.gr.init.wait_initialized(g); + nvgpu_mutex_acquire(&g->cg_pg_lock); err = nvgpu_pmu_disable_elpg_ms(g); + nvgpu_mutex_release(&g->cg_pg_lock); } - nvgpu_mutex_release(&g->cg_pg_lock); } #endif return err;