diff options
Diffstat (limited to 'drivers/gpu')
-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 | ||