diff --git a/drivers/gpu/nvgpu/hal/fifo/channel_gm20b_fusa.c b/drivers/gpu/nvgpu/hal/fifo/channel_gm20b_fusa.c index 568bd60d6..f0785ccae 100644 --- a/drivers/gpu/nvgpu/hal/fifo/channel_gm20b_fusa.c +++ b/drivers/gpu/nvgpu/hal/fifo/channel_gm20b_fusa.c @@ -54,6 +54,7 @@ void gm20b_channel_bind(struct nvgpu_channel *c) (nvgpu_readl(g, ccsr_channel_r(c->chid)) & ~ccsr_channel_enable_set_f(~U32(0U))) | ccsr_channel_enable_set_true_f()); + nvgpu_smp_wmb(); nvgpu_atomic_set(&c->bound, 1); } diff --git a/userspace/units/fifo/channel/gm20b/nvgpu-channel-gm20b.c b/userspace/units/fifo/channel/gm20b/nvgpu-channel-gm20b.c index 035f2f6a7..cae4da658 100644 --- a/userspace/units/fifo/channel/gm20b/nvgpu-channel-gm20b.c +++ b/userspace/units/fifo/channel/gm20b/nvgpu-channel-gm20b.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -36,6 +36,8 @@ #include #include +#include + #include "hal/fifo/channel_gm20b.h" #include @@ -63,6 +65,8 @@ int test_gm20b_channel_bind(struct unit_module *m, u32 runlist_id = NVGPU_INVALID_RUNLIST_ID; struct nvgpu_channel *ch; int ret = UNIT_FAIL; + u32 chid; + int err; ch = nvgpu_channel_open_new(g, runlist_id, privileged, getpid(), getpid()); @@ -80,6 +84,12 @@ int test_gm20b_channel_bind(struct unit_module *m, nvgpu_atomic_set(&ch->bound, 0); + chid = ch->chid; + ch->chid = U32_MAX; + err = EXPECT_BUG(gm20b_channel_bind(ch)); + ch->chid = chid; + assert(err != 0); + ret = UNIT_SUCCESS; done: if (ch) { @@ -96,6 +106,8 @@ int test_gm20b_channel_force_ctx_reload(struct unit_module *m, u32 runlist_id = NVGPU_INVALID_RUNLIST_ID; struct nvgpu_channel *ch; int ret = UNIT_FAIL; + u32 chid; + int err; ch = nvgpu_channel_open_new(g, runlist_id, privileged, getpid(), getpid()); @@ -106,6 +118,12 @@ int test_gm20b_channel_force_ctx_reload(struct unit_module *m, assert((nvgpu_readl(g, ccsr_channel_r(ch->chid)) & ccsr_channel_force_ctx_reload_true_f()) != 0); + chid = ch->chid; + ch->chid = U32_MAX; + err = EXPECT_BUG(gm20b_channel_force_ctx_reload(ch)); + ch->chid = chid; + assert(err != 0); + ret = UNIT_SUCCESS; done: if (ch) { diff --git a/userspace/units/fifo/channel/gm20b/nvgpu-channel-gm20b.h b/userspace/units/fifo/channel/gm20b/nvgpu-channel-gm20b.h index 86c1a04a6..ac6260d4f 100644 --- a/userspace/units/fifo/channel/gm20b/nvgpu-channel-gm20b.h +++ b/userspace/units/fifo/channel/gm20b/nvgpu-channel-gm20b.h @@ -51,6 +51,8 @@ struct gk20a; * - Check that ccsr_channel_inst_r and ccsr_channel_r have * been programmed. * - Check that ch->bound is set. + * - Check that BUG() occurs when passing invalid ch->chid + * (as ccsr_channel_inst_r computation overflows). * * Output: Returns PASS if all branches gave expected results. FAIL otherwise. */ @@ -75,6 +77,8 @@ int test_gm20b_channel_bind(struct unit_module *m, * - Write 0 to ccsr_channel_r. * - Call gm20b_channel_force_ctx_reload * - Check that ccsr_channel_force_ctx_reload_true_f is set in ccsr_channel_r. + * - Check that BUG() occurs when passing invalid ch->chid + * (as ccsr_channel_r computation overflows). * * Output: Returns PASS if all branches gave expected results. FAIL otherwise. */