From 2fb56f2cea56a83548751e33beda42415eedd3a9 Mon Sep 17 00:00:00 2001 From: Vedashree Vidwans Date: Fri, 10 Jan 2020 13:24:14 -0800 Subject: [PATCH] gpu: nvgpu: add bvec check for common.fifo input This patch adds boundary value check for common.fifo parameters as listed below. 1. nvgpu_channel_setup_bind() includes a condition to check that value of num_gpfifo_entries does not exceed 2^31. Otherwise prints message and returns error. 2. nvgpu_tsg_bind_channel() includes a condition to check if channel subctx had ASYNC id. If true, runqueue selector is set to 1 and 0 otherwise. This check is to be moved from devctl to common.fifo. Jira NVGPU-4817 Change-Id: Id1c9253945859c245e584b5c42b3285a6b620055 Signed-off-by: Vedashree Vidwans Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2278613 Tested-by: mobile promotions Reviewed-by: mobile promotions --- drivers/gpu/nvgpu/common/fifo/channel.c | 7 +++++++ drivers/gpu/nvgpu/common/fifo/tsg.c | 5 +++++ drivers/gpu/nvgpu/include/nvgpu/channel.h | 1 + drivers/gpu/nvgpu/include/nvgpu/tsg.h | 1 + userspace/units/fifo/channel/nvgpu-channel.c | 11 +++++++++-- userspace/units/fifo/tsg/nvgpu-tsg.c | 9 ++++++++- 6 files changed, 31 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/nvgpu/common/fifo/channel.c b/drivers/gpu/nvgpu/common/fifo/channel.c index 38de6c321..53f42b71f 100644 --- a/drivers/gpu/nvgpu/common/fifo/channel.c +++ b/drivers/gpu/nvgpu/common/fifo/channel.c @@ -2205,6 +2205,13 @@ static int channel_setup_bind_prechecks(struct nvgpu_channel *c, struct nvgpu_tsg *tsg; int err = 0; + if (args->num_gpfifo_entries > 0x80000000U) { + nvgpu_err(g, + "num_gpfifo_entries exceeds max limit of 2^31"); + err = -EINVAL; + goto fail; + } + /* an address space needs to have been bound at this point. */ if (!nvgpu_channel_as_bound(c)) { nvgpu_err(g, diff --git a/drivers/gpu/nvgpu/common/fifo/tsg.c b/drivers/gpu/nvgpu/common/fifo/tsg.c index 015480a32..934d29169 100644 --- a/drivers/gpu/nvgpu/common/fifo/tsg.c +++ b/drivers/gpu/nvgpu/common/fifo/tsg.c @@ -104,6 +104,11 @@ int nvgpu_tsg_bind_channel(struct nvgpu_tsg *tsg, struct nvgpu_channel *ch) return -EINVAL; } + /* Use runqueue selector 1 for all ASYNC ids */ + if (ch->subctx_id > CHANNEL_INFO_VEID0) { + ch->runqueue_sel = 1; + } + /* all the channel part of TSG should need to be same runlist_id */ if (tsg->runlist_id == NVGPU_INVALID_TSG_ID) { tsg->runlist_id = ch->runlist_id; diff --git a/drivers/gpu/nvgpu/include/nvgpu/channel.h b/drivers/gpu/nvgpu/include/nvgpu/channel.h index b028f1a58..2be19f29d 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/channel.h +++ b/drivers/gpu/nvgpu/include/nvgpu/channel.h @@ -1025,6 +1025,7 @@ struct nvgpu_channel *nvgpu_channel_open_new(struct gk20a *g, * @return 0 in case of success, < 0 in case of failure. * @retval -EINVAL if channel is not bound to an address space. * @retval -EINVAL if attempting to use kernel mode submit in a safety build. + * @retval -EINVAL if num_gpfifo_entries in #args is greater than 2^31. * @retval -EEXIST if gpfifo has already been allocated for this channel. * @retval -E2BIG if there is no space available to append channel to runlist. * @retval -ETIMEDOUT if runlist update timed out. diff --git a/drivers/gpu/nvgpu/include/nvgpu/tsg.h b/drivers/gpu/nvgpu/include/nvgpu/tsg.h index d09620f83..f5f63bdfc 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/tsg.h +++ b/drivers/gpu/nvgpu/include/nvgpu/tsg.h @@ -312,6 +312,7 @@ void nvgpu_tsg_disable(struct nvgpu_tsg *tsg); * * - Make sure channel is not already bound to a TSG. * - Make sure channel is not part of any runlists. + * - If channel had ASYNC subctx id, then set runqueue selector to 1. * - Set runlist id of TSG to channel's runlist_id if runlist_id of TSG * is set to #NVGPU_INVALID_TSG_ID. * - Call HAL to bind channel to TSG. diff --git a/userspace/units/fifo/channel/nvgpu-channel.c b/userspace/units/fifo/channel/nvgpu-channel.c index 6a9a0a778..0816e5e9b 100644 --- a/userspace/units/fifo/channel/nvgpu-channel.c +++ b/userspace/units/fifo/channel/nvgpu-channel.c @@ -629,7 +629,8 @@ done: #define F_CHANNEL_SETUP_BIND_USERMODE_POWER_REF_COUNT_FAIL BIT(8) #define F_CHANNEL_SETUP_BIND_NON_USERMODE_DETERMINISTIC BIT(9) #define F_CHANNEL_SETUP_BIND_USERMODE_OS_CH_USERMODE_BUF BIT(10) -#define F_CHANNEL_SETUP_BIND_LAST BIT(11) +#define F_CHANNEL_SETUP_GPFIFO_ENTRIES_OUT_OF_BOUND BIT(11) +#define F_CHANNEL_SETUP_BIND_LAST BIT(12) static const char *f_channel_setup_bind[] = { "no_as", @@ -719,7 +720,8 @@ int test_channel_setup_bind(struct unit_module *m, struct gk20a *g, void *vargs) F_CHANNEL_SETUP_BIND_USERMODE_TSGID_INVALID | F_CHANNEL_SETUP_BIND_USERMODE_POWER_REF_COUNT_FAIL | F_CHANNEL_SETUP_BIND_NON_USERMODE_DETERMINISTIC | - F_CHANNEL_SETUP_BIND_USERMODE_OS_CH_USERMODE_BUF; + F_CHANNEL_SETUP_BIND_USERMODE_OS_CH_USERMODE_BUF | + F_CHANNEL_SETUP_GPFIFO_ENTRIES_OUT_OF_BOUND; u32 prune = (u32)(F_CHANNEL_SETUP_BIND_USERMODE_SUPPORT_DETERMINISTIC) | fail; u32 runlist_id = NVGPU_INVALID_RUNLIST_ID; @@ -816,6 +818,10 @@ int test_channel_setup_bind(struct unit_module *m, struct gk20a *g, void *vargs) NVGPU_SETUP_BIND_FLAGS_USERMODE_SUPPORT; } + if (branches & F_CHANNEL_SETUP_GPFIFO_ENTRIES_OUT_OF_BOUND) { + bind_args.num_gpfifo_entries = -1; + } + ch->tsgid = branches & F_CHANNEL_SETUP_BIND_USERMODE_TSGID_INVALID ? NVGPU_INVALID_TSG_ID : tsgid_orig; @@ -850,6 +856,7 @@ int test_channel_setup_bind(struct unit_module *m, struct gk20a *g, void *vargs) unit_assert(nvgpu_atomic_read(&ch->bound) == false, goto done); g->os_channel.free_usermode_buffers = NULL; + bind_args.num_gpfifo_entries = 32; } else { unit_assert(err == 0, goto done); unit_assert(stub[0].chid == ch->chid, goto done); diff --git a/userspace/units/fifo/tsg/nvgpu-tsg.c b/userspace/units/fifo/tsg/nvgpu-tsg.c index 67d10b907..fb86d8af4 100644 --- a/userspace/units/fifo/tsg/nvgpu-tsg.c +++ b/userspace/units/fifo/tsg/nvgpu-tsg.c @@ -262,7 +262,8 @@ done: #define F_TSG_BIND_CHANNEL_BIND_HAL BIT(3) #define F_TSG_BIND_CHANNEL_BIND_HAL_ERR BIT(4) #define F_TSG_BIND_CHANNEL_ENG_METHOD_BUFFER BIT(5) -#define F_TSG_BIND_CHANNEL_LAST BIT(6) +#define F_TSG_BIND_CHANNEL_ASYNC_ID BIT(6) +#define F_TSG_BIND_CHANNEL_LAST BIT(7) static const char *f_tsg_bind[] = { "ch_bound", @@ -326,6 +327,12 @@ int test_tsg_bind_channel(struct unit_module *m, subtest_setup(branches); ch = chB; + if (branches & F_TSG_BIND_CHANNEL_ASYNC_ID) { + ch->subctx_id = CHANNEL_INFO_VEID0 + 1; + } else { + ch->subctx_id = 0U; + } + /* ch already bound */ if (branches & F_TSG_BIND_CHANNEL_CH_BOUND) { ch = chA;