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>
This commit is contained in:
Deepak Nibade
2016-12-28 19:15:25 +05:30
committed by mobile promotions
parent afe77b3445
commit 162c04ddce

View File

@@ -1344,6 +1344,18 @@ static void gr_gk20a_program_sm_id_numbering(struct gk20a *g,
gr_gpc0_tpc0_pe_cfg_smid_value_f(sm_id));
}
/*
* Return number of TPCs in a GPC
* Return 0 if GPC index is invalid i.e. GPC is disabled
*/
static u32 gr_gk20a_get_tpc_count(struct gr_gk20a *gr, u32 gpc_index)
{
if (gpc_index >= gr->gpc_count)
return 0;
return gr->gpc_tpc_count[gpc_index];
}
int gr_gk20a_init_fs_state(struct gk20a *g)
{
struct gr_gk20a *gr = &g->gr;
@@ -1351,6 +1363,7 @@ int gr_gk20a_init_fs_state(struct gk20a *g)
u32 sm_id = 0, gpc_id = 0;
u32 tpc_per_gpc;
u32 fuse_tpc_mask;
u32 reg_index;
gk20a_dbg_fn("");
@@ -1367,25 +1380,22 @@ int gr_gk20a_init_fs_state(struct gk20a *g)
g->ops.gr.program_active_tpc_counts(g, gpc_index);
}
for (tpc_index = 0, gpc_id = 0;
tpc_index < gr_pd_num_tpc_per_gpc__size_1_v();
tpc_index++, gpc_id += 8) {
if (gpc_id >= gr->gpc_count)
continue;
for (reg_index = 0, gpc_id = 0;
reg_index < gr_pd_num_tpc_per_gpc__size_1_v();
reg_index++, gpc_id += 8) {
tpc_per_gpc =
gr_pd_num_tpc_per_gpc_count0_f(gr->gpc_tpc_count[gpc_id + 0]) |
gr_pd_num_tpc_per_gpc_count1_f(gr->gpc_tpc_count[gpc_id + 1]) |
gr_pd_num_tpc_per_gpc_count2_f(gr->gpc_tpc_count[gpc_id + 2]) |
gr_pd_num_tpc_per_gpc_count3_f(gr->gpc_tpc_count[gpc_id + 3]) |
gr_pd_num_tpc_per_gpc_count4_f(gr->gpc_tpc_count[gpc_id + 4]) |
gr_pd_num_tpc_per_gpc_count5_f(gr->gpc_tpc_count[gpc_id + 5]) |
gr_pd_num_tpc_per_gpc_count6_f(gr->gpc_tpc_count[gpc_id + 6]) |
gr_pd_num_tpc_per_gpc_count7_f(gr->gpc_tpc_count[gpc_id + 7]);
gr_pd_num_tpc_per_gpc_count0_f(gr_gk20a_get_tpc_count(gr, gpc_id + 0)) |
gr_pd_num_tpc_per_gpc_count1_f(gr_gk20a_get_tpc_count(gr, gpc_id + 1)) |
gr_pd_num_tpc_per_gpc_count2_f(gr_gk20a_get_tpc_count(gr, gpc_id + 2)) |
gr_pd_num_tpc_per_gpc_count3_f(gr_gk20a_get_tpc_count(gr, gpc_id + 3)) |
gr_pd_num_tpc_per_gpc_count4_f(gr_gk20a_get_tpc_count(gr, gpc_id + 4)) |
gr_pd_num_tpc_per_gpc_count5_f(gr_gk20a_get_tpc_count(gr, gpc_id + 5)) |
gr_pd_num_tpc_per_gpc_count6_f(gr_gk20a_get_tpc_count(gr, gpc_id + 6)) |
gr_pd_num_tpc_per_gpc_count7_f(gr_gk20a_get_tpc_count(gr, gpc_id + 7));
gk20a_writel(g, gr_pd_num_tpc_per_gpc_r(tpc_index), tpc_per_gpc);
gk20a_writel(g, gr_ds_num_tpc_per_gpc_r(tpc_index), tpc_per_gpc);
gk20a_writel(g, gr_pd_num_tpc_per_gpc_r(reg_index), tpc_per_gpc);
gk20a_writel(g, gr_ds_num_tpc_per_gpc_r(reg_index), tpc_per_gpc);
}
/* gr__setup_pd_mapping stubbed for gk20a */