summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gp106
diff options
context:
space:
mode:
authorDavid Nieto <dmartineznie@nvidia.com>2017-04-19 00:56:09 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2017-09-22 18:47:01 -0400
commit90568a2ce58c03f457bdd4fab6675cd327ed13fd (patch)
tree4095b7599083ac478dbfbb522f1abcc585dc2801 /drivers/gpu/nvgpu/gp106
parent7134e9e852116f86745cd23312bbfba34100bf6d (diff)
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 <dmartineznie@nvidia.com> Reviewed-on: http://git-master/r/1465302 Reviewed-by: Alex Waterman <alexw@nvidia.com> Reviewed-by: Thomas Fleury <tfleury@nvidia.com> Reviewed-by: David Jarrett <djarrett@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1563019 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gp106')
-rw-r--r--drivers/gpu/nvgpu/gp106/bios_gp106.c28
1 files changed, 22 insertions, 6 deletions
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)
177 177
178 gk20a_dbg_fn(""); 178 gk20a_dbg_fn("");
179 179
180 if (g->bios_is_init)
181 return 0;
182
180 gk20a_dbg_info("reading bios from EEPROM"); 183 gk20a_dbg_info("reading bios from EEPROM");
181 g->bios.size = BIOS_SIZE; 184 g->bios.size = BIOS_SIZE;
182 g->bios.data = nvgpu_vmalloc(g, BIOS_SIZE); 185 g->bios.data = nvgpu_vmalloc(g, BIOS_SIZE);
@@ -195,12 +198,13 @@ int gp106_bios_init(struct gk20a *g)
195 198
196 err = nvgpu_bios_parse_rom(g); 199 err = nvgpu_bios_parse_rom(g);
197 if (err) 200 if (err)
198 return err; 201 goto free_firmware;
199 202
200 if (g->gpu_characteristics.vbios_version < g->vbios_min_version) { 203 if (g->gpu_characteristics.vbios_version < g->vbios_min_version) {
201 nvgpu_err(g, "unsupported VBIOS version %08x", 204 nvgpu_err(g, "unsupported VBIOS version %08x",
202 g->gpu_characteristics.vbios_version); 205 g->gpu_characteristics.vbios_version);
203 return -EINVAL; 206 err = -EINVAL;
207 goto free_firmware;
204 } 208 }
205 209
206 /* WAR for HW2.5 RevA (INA3221 is missing) */ 210 /* WAR for HW2.5 RevA (INA3221 is missing) */
@@ -216,25 +220,37 @@ int gp106_bios_init(struct gk20a *g)
216 220
217 d = debugfs_create_blob("bios", S_IRUGO, l->debugfs, 221 d = debugfs_create_blob("bios", S_IRUGO, l->debugfs,
218 &g->bios_blob); 222 &g->bios_blob);
219 if (!d) 223 if (!d) {
224 err = -EINVAL;
220 nvgpu_err(g, "No debugfs?"); 225 nvgpu_err(g, "No debugfs?");
226 goto free_firmware;
227 }
221#endif 228#endif
222
223 gk20a_dbg_fn("done"); 229 gk20a_dbg_fn("done");
224 230
225 err = gp106_bios_devinit(g); 231 err = gp106_bios_devinit(g);
226 if (err) { 232 if (err) {
227 nvgpu_err(g, "devinit failed"); 233 nvgpu_err(g, "devinit failed");
228 return err; 234 goto free_debugfs;
229 } 235 }
230 236
231 if (nvgpu_is_enabled(g, NVGPU_PMU_RUN_PREOS)) { 237 if (nvgpu_is_enabled(g, NVGPU_PMU_RUN_PREOS)) {
232 err = gp106_bios_preos(g); 238 err = gp106_bios_preos(g);
233 if (err) { 239 if (err) {
234 nvgpu_err(g, "pre-os failed"); 240 nvgpu_err(g, "pre-os failed");
235 return err; 241 goto free_debugfs;
236 } 242 }
237 } 243 }
244 g->bios_is_init = true;
238 245
239 return 0; 246 return 0;
247free_debugfs:
248#ifdef CONFIG_DEBUG_FS
249 debugfs_remove(d);
250#endif
251free_firmware:
252 if (g->bios.data)
253 nvgpu_vfree(g, g->bios.data);
254 return err;
240} 255}
256