diff options
author | Deepak Nibade <dnibade@nvidia.com> | 2016-12-28 08:45:25 -0500 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2017-01-02 04:48:04 -0500 |
commit | 162c04ddcef7a5f345ffdd97dd4de9fbc6d201a7 (patch) | |
tree | 33a883bfc2b2e40f3ab61e14fc072f9c980eca8d | |
parent | afe77b34454746d3017076e55e166a5f83c7f0f6 (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>
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 44 |
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 | */ | ||
1351 | static 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 | |||
1347 | int gr_gk20a_init_fs_state(struct gk20a *g) | 1359 | int 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 */ |