gpu: nvgpu: Fix NULL ptr deref during quiesce

g->fifo.runlists[] has size of g->fifo.max_runlists. During quiesce,
U32_MAX bitmask is passed to g->ops.runlist.write_state() HAL to
disable all the runlist. The Ga10b HAL implementation of
g->ops.runlist.write_state() references into runlists[] structure
for all the bits set in input runlist mask. For mask=U32_MAX,
there is NULL pointer dereference when runlist_id exceeds
g->fifo.max_runlists.
Add runlist_id boundary check before dereferencing the runlists[]
structure.

Update Gk20a HAL too with similar guard to make sure incorrect mask
doesn't get written to the register.

JIRA NVGPU-8102

Change-Id: Ic613aa38361b8b23d953c76d6924aba6bf6d5ea9
Signed-off-by: Tejal Kudav <tkudav@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2680847
Reviewed-by: Konsta Holtta <kholtta@nvidia.com>
Reviewed-by: svcacv <svcacv@nvidia.com>
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com>
Reviewed-by: Vaibhav Kachore <vkachore@nvidia.com>
Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com>
GVS: Gerrit_Virtual_Submit
This commit is contained in:
Tejal Kudav
2022-03-13 17:50:00 +00:00
committed by mobile promotions
parent a1ef716f9d
commit 15739c52e9
2 changed files with 2 additions and 2 deletions

View File

@@ -122,7 +122,7 @@ void ga10b_runlist_write_state(struct gk20a *g, u32 runlists_mask,
reg_val = runlist_sched_disable_runlist_enabled_v(); reg_val = runlist_sched_disable_runlist_enabled_v();
} }
while (runlists_mask != 0U) { while (runlists_mask != 0U && (runlist_id < g->fifo.max_runlists)) {
if ((runlists_mask & BIT32(runlist_id)) != 0U) { if ((runlists_mask & BIT32(runlist_id)) != 0U) {
runlist = g->fifo.runlists[runlist_id]; runlist = g->fifo.runlists[runlist_id];
nvgpu_runlist_writel(g, runlist, nvgpu_runlist_writel(g, runlist,

View File

@@ -96,7 +96,7 @@ void gk20a_runlist_write_state(struct gk20a *g, u32 runlists_mask,
u32 reg_mask = 0U; u32 reg_mask = 0U;
u32 i = 0U; u32 i = 0U;
while (runlists_mask != 0U) { while (runlists_mask != 0U && (i < g->fifo.max_runlists)) {
if ((runlists_mask & BIT32(i)) != 0U) { if ((runlists_mask & BIT32(i)) != 0U) {
reg_mask |= fifo_sched_disable_runlist_m(i); reg_mask |= fifo_sched_disable_runlist_m(i);
} }