From 90568a2ce58c03f457bdd4fab6675cd327ed13fd Mon Sep 17 00:00:00 2001 From: David Nieto Date: Tue, 18 Apr 2017 21:56:09 -0700 Subject: gpu: nvgpu: allow bind to be interrupted This change solves two problems: (*) the possibility of a crash due to interrupting the gpu initialization following a bind (*) a IOVA memory leak that could prevent the GPU from binding after about 200 bind/unbind cycles A detailed list of fixes: - chek that arbiter is initialized before freeing it. - do not re-enable interrupts when MSI is enabled on unbind. - free the semaphore sea on unbind. - ensure we dont double load the vbios. - check return value of nvgpu_mutex_init for semaphores. - add corresponding nvgpu_mutex_destroy calls. bug 1816516 Change-Id: Ia8af73019e0e1183998855d55bb3eea09672a8b7 Signed-off-by: David Nieto Reviewed-on: http://git-master/r/1465302 Reviewed-by: Alex Waterman Reviewed-by: Thomas Fleury Reviewed-by: David Jarrett Reviewed-on: https://git-master.nvidia.com/r/1563019 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/gp106/bios_gp106.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/nvgpu/gp106') diff --git a/drivers/gpu/nvgpu/gp106/bios_gp106.c b/drivers/gpu/nvgpu/gp106/bios_gp106.c index f772e267..c728433f 100644 --- a/drivers/gpu/nvgpu/gp106/bios_gp106.c +++ b/drivers/gpu/nvgpu/gp106/bios_gp106.c @@ -177,6 +177,9 @@ int gp106_bios_init(struct gk20a *g) gk20a_dbg_fn(""); + if (g->bios_is_init) + return 0; + gk20a_dbg_info("reading bios from EEPROM"); g->bios.size = BIOS_SIZE; g->bios.data = nvgpu_vmalloc(g, BIOS_SIZE); @@ -195,12 +198,13 @@ int gp106_bios_init(struct gk20a *g) err = nvgpu_bios_parse_rom(g); if (err) - return err; + goto free_firmware; if (g->gpu_characteristics.vbios_version < g->vbios_min_version) { nvgpu_err(g, "unsupported VBIOS version %08x", g->gpu_characteristics.vbios_version); - return -EINVAL; + err = -EINVAL; + goto free_firmware; } /* WAR for HW2.5 RevA (INA3221 is missing) */ @@ -216,25 +220,37 @@ int gp106_bios_init(struct gk20a *g) d = debugfs_create_blob("bios", S_IRUGO, l->debugfs, &g->bios_blob); - if (!d) + if (!d) { + err = -EINVAL; nvgpu_err(g, "No debugfs?"); + goto free_firmware; + } #endif - gk20a_dbg_fn("done"); err = gp106_bios_devinit(g); if (err) { nvgpu_err(g, "devinit failed"); - return err; + goto free_debugfs; } if (nvgpu_is_enabled(g, NVGPU_PMU_RUN_PREOS)) { err = gp106_bios_preos(g); if (err) { nvgpu_err(g, "pre-os failed"); - return err; + goto free_debugfs; } } + g->bios_is_init = true; return 0; +free_debugfs: +#ifdef CONFIG_DEBUG_FS + debugfs_remove(d); +#endif +free_firmware: + if (g->bios.data) + nvgpu_vfree(g, g->bios.data); + return err; } + -- cgit v1.2.2