From 0a1e7c6b0905a6e3dcdcd483565fb5cb6f6bdd38 Mon Sep 17 00:00:00 2001 From: Sachit Kadle Date: Thu, 15 Sep 2016 01:01:57 -0700 Subject: gpu: nvgpu: correct gpfifo size calculation This change fixes up the calculation of gpfifo entries, to be allocated depending on the ioctl used: 1) For the legacy ALLOC_GPFIFO ioctl, we preserve the calculation of gpfifo entries within the kernel. 2) For the new ALLOC_GPFIFO_EX ioctl, we assume that userspace has pre-calculated power-of-2 value. We process this value un-modified and only verify that it is a valid power-of-2. Bug 1795076 Change-Id: I8d2ddfdae40b02fe6b81e63dfd8857ad514a3dfd Signed-off-by: Sachit Kadle Reviewed-on: http://git-master/r/1220968 (cherry picked from commit c42396d9836e9b7ec73e0728f0c502b63aff70db) Reviewed-on: http://git-master/r/1223937 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index b846054d..6d4b4f60 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c @@ -1701,9 +1701,7 @@ int gk20a_alloc_channel_gpfifo(struct channel_gk20a *c, u32 gpfifo_size; int err = 0; - /* Kernel can insert one extra gpfifo entry before user submitted gpfifos - and another one after, for internal usage. Triple the requested size. */ - gpfifo_size = roundup_pow_of_two(args->num_entries * 3); + gpfifo_size = args->num_entries; if (args->flags & NVGPU_ALLOC_GPFIFO_FLAGS_VPR_ENABLED) c->vpr = true; @@ -3404,6 +3402,10 @@ long gk20a_channel_ioctl(struct file *filp, gk20a_idle(dev); break; case NVGPU_IOCTL_CHANNEL_ALLOC_GPFIFO_EX: + { + struct nvgpu_alloc_gpfifo_ex_args *alloc_gpfifo_ex_args = + (struct nvgpu_alloc_gpfifo_ex_args *)buf; + err = gk20a_busy(dev); if (err) { dev_err(dev, @@ -3411,10 +3413,16 @@ long gk20a_channel_ioctl(struct file *filp, __func__, cmd); break; } + + if (!is_power_of_2(alloc_gpfifo_ex_args->num_entries)) { + err = -EINVAL; + break; + } err = gk20a_alloc_channel_gpfifo(ch, (struct nvgpu_alloc_gpfifo_ex_args *)buf); gk20a_idle(dev); break; + } case NVGPU_IOCTL_CHANNEL_ALLOC_GPFIFO: { struct nvgpu_alloc_gpfifo_ex_args alloc_gpfifo_ex_args; @@ -3432,8 +3440,13 @@ long gk20a_channel_ioctl(struct file *filp, /* prepare new args structure */ memset(&alloc_gpfifo_ex_args, 0, sizeof(struct nvgpu_alloc_gpfifo_ex_args)); - alloc_gpfifo_ex_args.num_entries = - alloc_gpfifo_args->num_entries; + /* + * Kernel can insert one extra gpfifo entry before user + * submitted gpfifos and another one after, for internal usage. + * Triple the requested size. + */ + alloc_gpfifo_ex_args.num_entries = roundup_pow_of_two( + alloc_gpfifo_args->num_entries * 3); alloc_gpfifo_ex_args.flags = alloc_gpfifo_args->flags; err = gk20a_alloc_channel_gpfifo(ch, &alloc_gpfifo_ex_args); -- cgit v1.2.2