From ecfd675d9b8363e646785ec19492ebb2a52f30af Mon Sep 17 00:00:00 2001 From: Sagar Kamble Date: Tue, 23 Mar 2021 09:33:04 +0530 Subject: [PATCH] gpu: nvgpu: free pmu variables allocated in early_init on error in rtos_init On error in pmu_rtos_init, pmu state was freed partly. That lead to invalid access on subsequent nvgpu poweron. Free all pmu state in such case. Bug 200575409 Change-Id: I11166b55dbe00a225e811425d21500c3143a354c Signed-off-by: Sagar Kamble Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2503577 Tested-by: mobile promotions Reviewed-by: svc-mobile-coverity Reviewed-by: Alex Waterman Reviewed-by: Divya Singhatwaria Reviewed-by: Deepak Nibade Reviewed-by: mobile promotions GVS: Gerrit_Virtual_Submit --- drivers/gpu/nvgpu/common/pmu/pmu.c | 3 +++ drivers/gpu/nvgpu/common/pmu/pmu_rtos_init.c | 4 ++-- userspace/units/pmu/nvgpu-pmu.c | 10 +++++++++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/nvgpu/common/pmu/pmu.c b/drivers/gpu/nvgpu/common/pmu/pmu.c index b977db47f..bcf2351e5 100644 --- a/drivers/gpu/nvgpu/common/pmu/pmu.c +++ b/drivers/gpu/nvgpu/common/pmu/pmu.c @@ -150,6 +150,9 @@ void nvgpu_pmu_remove_support(struct gk20a *g, struct nvgpu_pmu *pmu) } #endif nvgpu_mutex_destroy(&pmu->isr_mutex); + if (g->ops.pmu.ecc_free != NULL) { + g->ops.pmu.ecc_free(g); + } nvgpu_kfree(g, g->pmu); g->pmu = NULL; } diff --git a/drivers/gpu/nvgpu/common/pmu/pmu_rtos_init.c b/drivers/gpu/nvgpu/common/pmu/pmu_rtos_init.c index df82400a6..15fd95285 100644 --- a/drivers/gpu/nvgpu/common/pmu/pmu_rtos_init.c +++ b/drivers/gpu/nvgpu/common/pmu/pmu_rtos_init.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2017-2021, 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"), @@ -208,7 +208,7 @@ static int pmu_sw_setup(struct gk20a *g, struct nvgpu_pmu *pmu ) pmu->sw_ready = true; exit: if (err != 0) { - remove_pmu_support(pmu); + nvgpu_pmu_remove_support(g, pmu); } return err; diff --git a/userspace/units/pmu/nvgpu-pmu.c b/userspace/units/pmu/nvgpu-pmu.c index 9c473cf4d..eba544500 100644 --- a/userspace/units/pmu/nvgpu-pmu.c +++ b/userspace/units/pmu/nvgpu-pmu.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2019-2021, 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"), @@ -360,14 +360,21 @@ int test_pmu_early_init(struct unit_module *m, unit_return_fail(m, "support_ls_pmu failed\n"); } + err = g->ops.pmu.ecc_init(g); + nvgpu_pmu_remove_support(g, g->pmu); + if (err != 0) { + unit_return_fail(m, "pmu ecc init failed\n"); + } + /* * case 7: Adding branch coverage * By setting g->ops.pmu.is_pmu_supported * to true */ g->support_ls_pmu = true; + g->ecc.initialized = false; g->ops.pmu.is_pmu_supported = stub_gv11b_is_pmu_supported; err = nvgpu_pmu_early_init(g); @@ -379,6 +386,7 @@ int test_pmu_early_init(struct unit_module *m, */ g->ops.pmu.ecc_init = NULL; + g->ops.pmu.ecc_free = NULL; err = nvgpu_pmu_early_init(g); nvgpu_pmu_remove_support(g, g->pmu);