diff options
author | Konsta Holtta <kholtta@nvidia.com> | 2015-03-09 07:51:20 -0400 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2015-04-04 22:00:21 -0400 |
commit | d86fc5414beb6758d0b04ec78dd6589411dda66d (patch) | |
tree | 6b5effff1b812f417fa3b761089a9f9fc2516da9 /drivers/gpu/nvgpu/gk20a | |
parent | f7d7b601ed7e4f592c9ce82708e69b16f1c28eec (diff) |
gpu: nvgpu: use vmalloc for temp gpfifo in submit
Use vmalloc instead of kzalloc for the temporary gpfifo buffer copied
from userspace in the ioctl when submitting gpfifos. The data may be too
big for kzalloc, and it doesn't need to be physically contiguous.
Bug 1617747
Bug 200081843
Change-Id: I66a43d17eb13a2783bc1f0598a38abbf330b2ba6
Signed-off-by: Konsta Holtta <kholtta@nvidia.com>
Reviewed-on: http://git-master/r/715207
Reviewed-by: Sami Kiminki <skiminki@nvidia.com>
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index 9a0800d1..feb80adf 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/file.h> | 25 | #include <linux/file.h> |
26 | #include <linux/anon_inodes.h> | 26 | #include <linux/anon_inodes.h> |
27 | #include <linux/dma-buf.h> | 27 | #include <linux/dma-buf.h> |
28 | #include <linux/vmalloc.h> | ||
28 | 29 | ||
29 | #include "debug_gk20a.h" | 30 | #include "debug_gk20a.h" |
30 | 31 | ||
@@ -2200,7 +2201,7 @@ static int gk20a_ioctl_channel_submit_gpfifo( | |||
2200 | struct nvgpu_submit_gpfifo_args *args) | 2201 | struct nvgpu_submit_gpfifo_args *args) |
2201 | { | 2202 | { |
2202 | struct gk20a_fence *fence_out; | 2203 | struct gk20a_fence *fence_out; |
2203 | void *gpfifo; | 2204 | void *gpfifo = NULL; |
2204 | u32 size; | 2205 | u32 size; |
2205 | int ret = 0; | 2206 | int ret = 0; |
2206 | 2207 | ||
@@ -2209,16 +2210,20 @@ static int gk20a_ioctl_channel_submit_gpfifo( | |||
2209 | if (ch->has_timedout) | 2210 | if (ch->has_timedout) |
2210 | return -ETIMEDOUT; | 2211 | return -ETIMEDOUT; |
2211 | 2212 | ||
2213 | /* zero-sized submits are allowed, since they can be used for | ||
2214 | * synchronization; we might still wait and do an increment */ | ||
2212 | size = args->num_entries * sizeof(struct nvgpu_gpfifo); | 2215 | size = args->num_entries * sizeof(struct nvgpu_gpfifo); |
2216 | if (size) { | ||
2217 | gpfifo = vmalloc(size); | ||
2218 | if (!gpfifo) | ||
2219 | return -ENOMEM; | ||
2213 | 2220 | ||
2214 | gpfifo = kzalloc(size, GFP_KERNEL); | 2221 | if (copy_from_user(gpfifo, |
2215 | if (!gpfifo) | 2222 | (void __user *)(uintptr_t)args->gpfifo, |
2216 | return -ENOMEM; | 2223 | size)) { |
2217 | 2224 | ret = -EINVAL; | |
2218 | if (copy_from_user(gpfifo, | 2225 | goto clean_up; |
2219 | (void __user *)(uintptr_t)args->gpfifo, size)) { | 2226 | } |
2220 | ret = -EINVAL; | ||
2221 | goto clean_up; | ||
2222 | } | 2227 | } |
2223 | 2228 | ||
2224 | ret = gk20a_submit_channel_gpfifo(ch, gpfifo, args->num_entries, | 2229 | ret = gk20a_submit_channel_gpfifo(ch, gpfifo, args->num_entries, |
@@ -2244,7 +2249,7 @@ static int gk20a_ioctl_channel_submit_gpfifo( | |||
2244 | gk20a_fence_put(fence_out); | 2249 | gk20a_fence_put(fence_out); |
2245 | 2250 | ||
2246 | clean_up: | 2251 | clean_up: |
2247 | kfree(gpfifo); | 2252 | vfree(gpfifo); |
2248 | return ret; | 2253 | return ret; |
2249 | } | 2254 | } |
2250 | 2255 | ||