summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
diff options
context:
space:
mode:
authorDeepak Nibade <dnibade@nvidia.com>2016-12-28 08:45:25 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2017-01-02 04:48:04 -0500
commit162c04ddcef7a5f345ffdd97dd4de9fbc6d201a7 (patch)
tree33a883bfc2b2e40f3ab61e14fc072f9c980eca8d /drivers/gpu/nvgpu/gk20a/gr_gk20a.c
parentafe77b34454746d3017076e55e166a5f83c7f0f6 (diff)
gpu: nvgpu: fix out-of-bound access on gr->gpc_tpc_count
Fix slab-out-of-bounds issue reported by KASAN [ 29.922710] BUG: KASAN: slab-out-of-bounds in gr_gk20a_init_fs_state+0x1bc/0x898 at addr ffffffc1a0988c04 ... [ 29.961820] INFO: Allocated in gr_gk20a_init_gr_config+0x380/0x1b20 age=374 cpu=5 pid=1 ... Out-of-bound access from [ 30.241943] [<ffffffc0007d2674>] gr_gk20a_init_fs_state+0x1bc/0x898 [ 30.248205] [<ffffffc000839a2c>] gr_gm20b_init_fs_state+0x4c/0x5c8 [ 30.254381] [<ffffffc000871670>] gr_gp10b_init_fs_state+0x160/0x3a8 [ 30.260643] [<ffffffc0007d70ec>] gk20a_init_gr_setup_hw+0x974/0x1530 [ 30.266991] [<ffffffc0007eac6c>] gk20a_init_gr_support+0x14c/0xeb0 [ 30.273164] [<ffffffc00079d9c8>] gk20a_pm_finalize_poweron+0x738/0xd10 [ 30.279684] [<ffffffc00079dfd0>] gk20a_pm_runtime_resume+0x30/0x58 Fix this by using a separate API gr_gk20a_get_tpc_count() which returns tpc count for a gpc and returns 0 if gpc index is greater than available gpcs Bug 200257557 Change-Id: I78856ca93c0381cb4bcef7a56a5210fa269cf3ac Signed-off-by: Deepak Nibade <dnibade@nvidia.com> Reviewed-on: http://git-master/r/1277692 GVS: Gerrit_Virtual_Submit Reviewed-by: Sami Kiminki <skiminki@nvidia.com> Reviewed-by: Konsta Holtta <kholtta@nvidia.com> Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/gr_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/gr_gk20a.c44
1 files changed, 27 insertions, 17 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
index bf279e9a..ceb3cb18 100644
--- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
@@ -1344,6 +1344,18 @@ static void gr_gk20a_program_sm_id_numbering(struct gk20a *g,
1344 gr_gpc0_tpc0_pe_cfg_smid_value_f(sm_id)); 1344 gr_gpc0_tpc0_pe_cfg_smid_value_f(sm_id));
1345} 1345}
1346 1346
1347/*
1348 * Return number of TPCs in a GPC
1349 * Return 0 if GPC index is invalid i.e. GPC is disabled
1350 */
1351static u32 gr_gk20a_get_tpc_count(struct gr_gk20a *gr, u32 gpc_index)
1352{
1353 if (gpc_index >= gr->gpc_count)
1354 return 0;
1355
1356 return gr->gpc_tpc_count[gpc_index];
1357}
1358
1347int gr_gk20a_init_fs_state(struct gk20a *g) 1359int gr_gk20a_init_fs_state(struct gk20a *g)
1348{ 1360{
1349 struct gr_gk20a *gr = &g->gr; 1361 struct gr_gk20a *gr = &g->gr;
@@ -1351,6 +1363,7 @@ int gr_gk20a_init_fs_state(struct gk20a *g)
1351 u32 sm_id = 0, gpc_id = 0; 1363 u32 sm_id = 0, gpc_id = 0;
1352 u32 tpc_per_gpc; 1364 u32 tpc_per_gpc;
1353 u32 fuse_tpc_mask; 1365 u32 fuse_tpc_mask;
1366 u32 reg_index;
1354 1367
1355 gk20a_dbg_fn(""); 1368 gk20a_dbg_fn("");
1356 1369
@@ -1367,25 +1380,22 @@ int gr_gk20a_init_fs_state(struct gk20a *g)
1367 g->ops.gr.program_active_tpc_counts(g, gpc_index); 1380 g->ops.gr.program_active_tpc_counts(g, gpc_index);
1368 } 1381 }
1369 1382
1370 for (tpc_index = 0, gpc_id = 0; 1383 for (reg_index = 0, gpc_id = 0;
1371 tpc_index < gr_pd_num_tpc_per_gpc__size_1_v(); 1384 reg_index < gr_pd_num_tpc_per_gpc__size_1_v();
1372 tpc_index++, gpc_id += 8) { 1385 reg_index++, gpc_id += 8) {
1373
1374 if (gpc_id >= gr->gpc_count)
1375 continue;
1376 1386
1377 tpc_per_gpc = 1387 tpc_per_gpc =
1378 gr_pd_num_tpc_per_gpc_count0_f(gr->gpc_tpc_count[gpc_id + 0]) | 1388 gr_pd_num_tpc_per_gpc_count0_f(gr_gk20a_get_tpc_count(gr, gpc_id + 0)) |
1379 gr_pd_num_tpc_per_gpc_count1_f(gr->gpc_tpc_count[gpc_id + 1]) | 1389 gr_pd_num_tpc_per_gpc_count1_f(gr_gk20a_get_tpc_count(gr, gpc_id + 1)) |
1380 gr_pd_num_tpc_per_gpc_count2_f(gr->gpc_tpc_count[gpc_id + 2]) | 1390 gr_pd_num_tpc_per_gpc_count2_f(gr_gk20a_get_tpc_count(gr, gpc_id + 2)) |
1381 gr_pd_num_tpc_per_gpc_count3_f(gr->gpc_tpc_count[gpc_id + 3]) | 1391 gr_pd_num_tpc_per_gpc_count3_f(gr_gk20a_get_tpc_count(gr, gpc_id + 3)) |
1382 gr_pd_num_tpc_per_gpc_count4_f(gr->gpc_tpc_count[gpc_id + 4]) | 1392 gr_pd_num_tpc_per_gpc_count4_f(gr_gk20a_get_tpc_count(gr, gpc_id + 4)) |
1383 gr_pd_num_tpc_per_gpc_count5_f(gr->gpc_tpc_count[gpc_id + 5]) | 1393 gr_pd_num_tpc_per_gpc_count5_f(gr_gk20a_get_tpc_count(gr, gpc_id + 5)) |
1384 gr_pd_num_tpc_per_gpc_count6_f(gr->gpc_tpc_count[gpc_id + 6]) | 1394 gr_pd_num_tpc_per_gpc_count6_f(gr_gk20a_get_tpc_count(gr, gpc_id + 6)) |
1385 gr_pd_num_tpc_per_gpc_count7_f(gr->gpc_tpc_count[gpc_id + 7]); 1395 gr_pd_num_tpc_per_gpc_count7_f(gr_gk20a_get_tpc_count(gr, gpc_id + 7));
1386 1396
1387 gk20a_writel(g, gr_pd_num_tpc_per_gpc_r(tpc_index), tpc_per_gpc); 1397 gk20a_writel(g, gr_pd_num_tpc_per_gpc_r(reg_index), tpc_per_gpc);
1388 gk20a_writel(g, gr_ds_num_tpc_per_gpc_r(tpc_index), tpc_per_gpc); 1398 gk20a_writel(g, gr_ds_num_tpc_per_gpc_r(reg_index), tpc_per_gpc);
1389 } 1399 }
1390 1400
1391 /* gr__setup_pd_mapping stubbed for gk20a */ 1401 /* gr__setup_pd_mapping stubbed for gk20a */