From 162c04ddcef7a5f345ffdd97dd4de9fbc6d201a7 Mon Sep 17 00:00:00 2001 From: Deepak Nibade Date: Wed, 28 Dec 2016 19:15:25 +0530 Subject: 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] [] gr_gk20a_init_fs_state+0x1bc/0x898 [ 30.248205] [] gr_gm20b_init_fs_state+0x4c/0x5c8 [ 30.254381] [] gr_gp10b_init_fs_state+0x160/0x3a8 [ 30.260643] [] gk20a_init_gr_setup_hw+0x974/0x1530 [ 30.266991] [] gk20a_init_gr_support+0x14c/0xeb0 [ 30.273164] [] gk20a_pm_finalize_poweron+0x738/0xd10 [ 30.279684] [] 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 Reviewed-on: http://git-master/r/1277692 GVS: Gerrit_Virtual_Submit Reviewed-by: Sami Kiminki Reviewed-by: Konsta Holtta Reviewed-by: Bharat Nihalani --- drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 44 +++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 17 deletions(-) (limited to 'drivers/gpu/nvgpu/gk20a') 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, 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]); - - 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); + 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(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 */ -- cgit v1.2.2