blob: 1c89ed5c2e04cb0e8abe8a7b8852ef87ba8b7c0d [file] [log] [blame]
Shrenuj Bansala419c792016-10-20 14:05:11 -07001/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14#include <linux/fs.h>
15#include <linux/file.h>
16#include <linux/uaccess.h>
17#include <asm/ioctl.h>
18
19#include "kgsl.h"
20#include "kgsl_compat.h"
21#include "kgsl_device.h"
22#include "kgsl_sync.h"
23
24static long
25kgsl_ioctl_device_getproperty_compat(struct kgsl_device_private *dev_priv,
26 unsigned int cmd, void *data)
27{
28 struct kgsl_device_getproperty_compat *param32 = data;
29 struct kgsl_device_getproperty param;
30
31 param.type = param32->type;
32 param.value = compat_ptr(param32->value);
33 param.sizebytes = (size_t)param32->sizebytes;
34
35 return kgsl_ioctl_device_getproperty(dev_priv, cmd, &param);
36}
37
38static long
39kgsl_ioctl_device_setproperty_compat(struct kgsl_device_private *dev_priv,
40 unsigned int cmd, void *data)
41{
42 struct kgsl_device_getproperty_compat *param32 = data;
43 struct kgsl_device_getproperty param;
44
45 param.type = param32->type;
46 param.value = compat_ptr(param32->value);
47 param.sizebytes = (size_t)param32->sizebytes;
48
49 return kgsl_ioctl_device_setproperty(dev_priv, cmd, &param);
50}
51
52static long
53kgsl_ioctl_submit_commands_compat(struct kgsl_device_private *dev_priv,
54 unsigned int cmd, void *data)
55{
56 int result;
57 struct kgsl_submit_commands_compat *param32 = data;
58 struct kgsl_submit_commands param;
59
60 param.context_id = param32->context_id;
61 param.flags = param32->flags;
62 param.cmdlist = compat_ptr(param32->cmdlist);
63 param.numcmds = param32->numcmds;
64 param.synclist = compat_ptr(param32->synclist);
65 param.numsyncs = param32->numsyncs;
66 param.timestamp = param32->timestamp;
67
68 result = kgsl_ioctl_submit_commands(dev_priv, cmd, &param);
69
70 param32->timestamp = param.timestamp;
71
72 return result;
73}
74
75static long
76kgsl_ioctl_rb_issueibcmds_compat(struct kgsl_device_private *dev_priv,
77 unsigned int cmd, void *data)
78{
79 int result;
80 struct kgsl_ringbuffer_issueibcmds_compat *param32 = data;
81 struct kgsl_ringbuffer_issueibcmds param;
82
83 param.drawctxt_id = param32->drawctxt_id;
84 param.flags = param32->flags;
85 param.ibdesc_addr = (unsigned long)param32->ibdesc_addr;
86 param.numibs = param32->numibs;
87 param.timestamp = param32->timestamp;
88
89 result = kgsl_ioctl_rb_issueibcmds(dev_priv, cmd, &param);
90
91 param32->timestamp = param.timestamp;
92
93 return result;
94}
95
96static long kgsl_ioctl_cmdstream_freememontimestamp_ctxtid_compat(
97 struct kgsl_device_private
98 *dev_priv, unsigned int cmd,
99 void *data)
100{
101 struct kgsl_cmdstream_freememontimestamp_ctxtid_compat *param32 = data;
102 struct kgsl_cmdstream_freememontimestamp_ctxtid param;
103
104 param.context_id = param32->context_id;
105 param.gpuaddr = (unsigned long)param32->gpuaddr;
106 param.type = param32->type;
107 param.timestamp = param32->timestamp;
108
109 return kgsl_ioctl_cmdstream_freememontimestamp_ctxtid(dev_priv, cmd,
110 &param);
111}
112
113static long kgsl_ioctl_sharedmem_free_compat(struct kgsl_device_private
114 *dev_priv, unsigned int cmd,
115 void *data)
116{
117 struct kgsl_sharedmem_free_compat *param32 = data;
118 struct kgsl_sharedmem_free param;
119
120 param.gpuaddr = (unsigned long)param32->gpuaddr;
121
122 return kgsl_ioctl_sharedmem_free(dev_priv, cmd, &param);
123}
124
125static long kgsl_ioctl_map_user_mem_compat(struct kgsl_device_private
126 *dev_priv, unsigned int cmd,
127 void *data)
128{
129 int result = 0;
130 struct kgsl_map_user_mem_compat *param32 = data;
131 struct kgsl_map_user_mem param;
132
133 param.fd = param32->fd;
134 param.gpuaddr = (unsigned long)param32->gpuaddr;
135 param.len = (size_t)param32->len;
136 param.offset = (size_t)param32->offset;
137 param.hostptr = (unsigned long)param32->hostptr;
138 param.memtype = param32->memtype;
139 param.flags = param32->flags;
140
141 result = kgsl_ioctl_map_user_mem(dev_priv, cmd, &param);
142
143 param32->gpuaddr = gpuaddr_to_compat(param.gpuaddr);
144 param32->flags = param.flags;
145 return result;
146}
147
148static long
149kgsl_ioctl_gpumem_sync_cache_compat(struct kgsl_device_private *dev_priv,
150 unsigned int cmd, void *data)
151{
152 struct kgsl_gpumem_sync_cache_compat *param32 = data;
153 struct kgsl_gpumem_sync_cache param;
154
155 param.gpuaddr = (unsigned long)param32->gpuaddr;
156 param.id = param32->id;
157 param.op = param32->op;
158 param.offset = (size_t)param32->offset;
159 param.length = (size_t)param32->length;
160
161 return kgsl_ioctl_gpumem_sync_cache(dev_priv, cmd, &param);
162}
163
164static long
165kgsl_ioctl_gpumem_sync_cache_bulk_compat(struct kgsl_device_private *dev_priv,
166 unsigned int cmd, void *data)
167{
168 struct kgsl_gpumem_sync_cache_bulk_compat *param32 = data;
169 struct kgsl_gpumem_sync_cache_bulk param;
170
171 param.id_list = to_user_ptr(param32->id_list);
172 param.count = param32->count;
173 param.op = param32->op;
174
175 return kgsl_ioctl_gpumem_sync_cache_bulk(dev_priv, cmd, &param);
176}
177
178static long
179kgsl_ioctl_sharedmem_flush_cache_compat(struct kgsl_device_private *dev_priv,
180 unsigned int cmd, void *data)
181{
182 struct kgsl_sharedmem_free_compat *param32 = data;
183 struct kgsl_sharedmem_free param;
184
185 param.gpuaddr = (unsigned long)param32->gpuaddr;
186
187 return kgsl_ioctl_sharedmem_flush_cache(dev_priv, cmd, &param);
188}
189
190static long
191kgsl_ioctl_gpumem_alloc_compat(struct kgsl_device_private *dev_priv,
192 unsigned int cmd, void *data)
193{
194 int result = 0;
195 struct kgsl_gpumem_alloc_compat *param32 = data;
196 struct kgsl_gpumem_alloc param;
197
198 param.gpuaddr = (unsigned long)param32->gpuaddr;
199 param.size = (size_t)param32->size;
200 param.flags = param32->flags;
201
202 /*
203 * Since this is a 32 bit application the page aligned size is expected
204 * to fit inside of 32 bits - check for overflow and return error if so
205 */
206 if (PAGE_ALIGN(param.size) >= UINT_MAX)
207 return -EINVAL;
208
209 result = kgsl_ioctl_gpumem_alloc(dev_priv, cmd, &param);
210
211 param32->gpuaddr = gpuaddr_to_compat(param.gpuaddr);
212 param32->size = sizet_to_compat(param.size);
213 param32->flags = param.flags;
214
215 return result;
216}
217
218static long
219kgsl_ioctl_gpumem_alloc_id_compat(struct kgsl_device_private *dev_priv,
220 unsigned int cmd, void *data)
221{
222 int result = 0;
223 struct kgsl_gpumem_alloc_id_compat *param32 = data;
224 struct kgsl_gpumem_alloc_id param;
225
226 param.id = param32->id;
227 param.flags = param32->flags;
228 param.size = (size_t)param32->size;
229 param.mmapsize = (size_t)param32->mmapsize;
230 param.gpuaddr = (unsigned long)param32->gpuaddr;
231
232 /*
233 * Since this is a 32 bit application the page aligned size is expected
234 * to fit inside of 32 bits - check for overflow and return error if so
235 */
236 if (PAGE_ALIGN(param.size) >= UINT_MAX)
237 return -EINVAL;
238
239 result = kgsl_ioctl_gpumem_alloc_id(dev_priv, cmd, &param);
240
241 param32->id = param.id;
242 param32->flags = param.flags;
243 param32->size = sizet_to_compat(param.size);
244 param32->mmapsize = sizet_to_compat(param.mmapsize);
245 param32->gpuaddr = gpuaddr_to_compat(param.gpuaddr);
246
247 return result;
248}
249
250static long
251kgsl_ioctl_gpumem_get_info_compat(struct kgsl_device_private *dev_priv,
252 unsigned int cmd, void *data)
253{
254 int result = 0;
255 struct kgsl_gpumem_get_info_compat *param32 = data;
256 struct kgsl_gpumem_get_info param;
257
258 param.gpuaddr = (unsigned long)param32->gpuaddr;
259 param.id = param32->id;
260 param.flags = param32->flags;
261 param.size = (size_t)param32->size;
262 param.mmapsize = (size_t)param32->mmapsize;
263 param.useraddr = (unsigned long)param32->useraddr;
264
265 result = kgsl_ioctl_gpumem_get_info(dev_priv, cmd, &param);
266
267 param32->gpuaddr = gpuaddr_to_compat(param.gpuaddr);
268 param32->id = param.id;
269 param32->flags = param.flags;
270 param32->size = sizet_to_compat(param.size);
271 param32->mmapsize = sizet_to_compat(param.mmapsize);
272 param32->useraddr = (compat_ulong_t)param.useraddr;
273
274 return result;
275}
276
277static long kgsl_ioctl_timestamp_event_compat(struct kgsl_device_private
278 *dev_priv, unsigned int cmd, void *data)
279{
280 struct kgsl_timestamp_event_compat *param32 = data;
281 struct kgsl_timestamp_event param;
282
283 param.type = param32->type;
284 param.timestamp = param32->timestamp;
285 param.context_id = param32->context_id;
286 param.priv = compat_ptr(param32->priv);
287 param.len = (size_t)param32->len;
288
289 return kgsl_ioctl_timestamp_event(dev_priv, cmd, &param);
290}
291
292
293static const struct kgsl_ioctl kgsl_compat_ioctl_funcs[] = {
294 KGSL_IOCTL_FUNC(IOCTL_KGSL_DEVICE_GETPROPERTY_COMPAT,
295 kgsl_ioctl_device_getproperty_compat),
296 /* IOCTL_KGSL_DEVICE_WAITTIMESTAMP is no longer supported */
297 KGSL_IOCTL_FUNC(IOCTL_KGSL_DEVICE_WAITTIMESTAMP_CTXTID,
298 kgsl_ioctl_device_waittimestamp_ctxtid),
299 KGSL_IOCTL_FUNC(IOCTL_KGSL_RINGBUFFER_ISSUEIBCMDS_COMPAT,
300 kgsl_ioctl_rb_issueibcmds_compat),
301 KGSL_IOCTL_FUNC(IOCTL_KGSL_SUBMIT_COMMANDS_COMPAT,
302 kgsl_ioctl_submit_commands_compat),
303 /* IOCTL_KGSL_CMDSTREAM_READTIMESTAMP is no longer supported */
304 KGSL_IOCTL_FUNC(IOCTL_KGSL_CMDSTREAM_READTIMESTAMP_CTXTID,
305 kgsl_ioctl_cmdstream_readtimestamp_ctxtid),
306 /* IOCTL_KGSL_CMDSTREAM_FREEMEMONTIMESTAMP is no longer supported */
307 KGSL_IOCTL_FUNC(IOCTL_KGSL_CMDSTREAM_FREEMEMONTIMESTAMP_CTXTID_COMPAT,
308 kgsl_ioctl_cmdstream_freememontimestamp_ctxtid_compat),
309 KGSL_IOCTL_FUNC(IOCTL_KGSL_DRAWCTXT_CREATE,
310 kgsl_ioctl_drawctxt_create),
311 KGSL_IOCTL_FUNC(IOCTL_KGSL_DRAWCTXT_DESTROY,
312 kgsl_ioctl_drawctxt_destroy),
313 KGSL_IOCTL_FUNC(IOCTL_KGSL_MAP_USER_MEM_COMPAT,
314 kgsl_ioctl_map_user_mem_compat),
315 KGSL_IOCTL_FUNC(IOCTL_KGSL_SHAREDMEM_FREE_COMPAT,
316 kgsl_ioctl_sharedmem_free_compat),
317 KGSL_IOCTL_FUNC(IOCTL_KGSL_SHAREDMEM_FLUSH_CACHE_COMPAT,
318 kgsl_ioctl_sharedmem_flush_cache_compat),
319 KGSL_IOCTL_FUNC(IOCTL_KGSL_GPUMEM_ALLOC_COMPAT,
320 kgsl_ioctl_gpumem_alloc_compat),
321 KGSL_IOCTL_FUNC(IOCTL_KGSL_TIMESTAMP_EVENT_COMPAT,
322 kgsl_ioctl_timestamp_event_compat),
323 KGSL_IOCTL_FUNC(IOCTL_KGSL_SETPROPERTY_COMPAT,
324 kgsl_ioctl_device_setproperty_compat),
325 KGSL_IOCTL_FUNC(IOCTL_KGSL_GPUMEM_ALLOC_ID_COMPAT,
326 kgsl_ioctl_gpumem_alloc_id_compat),
327 KGSL_IOCTL_FUNC(IOCTL_KGSL_GPUMEM_FREE_ID,
328 kgsl_ioctl_gpumem_free_id),
329 KGSL_IOCTL_FUNC(IOCTL_KGSL_GPUMEM_GET_INFO_COMPAT,
330 kgsl_ioctl_gpumem_get_info_compat),
331 KGSL_IOCTL_FUNC(IOCTL_KGSL_GPUMEM_SYNC_CACHE_COMPAT,
332 kgsl_ioctl_gpumem_sync_cache_compat),
333 KGSL_IOCTL_FUNC(IOCTL_KGSL_GPUMEM_SYNC_CACHE_BULK_COMPAT,
334 kgsl_ioctl_gpumem_sync_cache_bulk_compat),
335 KGSL_IOCTL_FUNC(IOCTL_KGSL_SYNCSOURCE_CREATE,
336 kgsl_ioctl_syncsource_create),
337 KGSL_IOCTL_FUNC(IOCTL_KGSL_SYNCSOURCE_DESTROY,
338 kgsl_ioctl_syncsource_destroy),
339 KGSL_IOCTL_FUNC(IOCTL_KGSL_SYNCSOURCE_CREATE_FENCE,
340 kgsl_ioctl_syncsource_create_fence),
341 KGSL_IOCTL_FUNC(IOCTL_KGSL_SYNCSOURCE_SIGNAL_FENCE,
342 kgsl_ioctl_syncsource_signal_fence),
343 KGSL_IOCTL_FUNC(IOCTL_KGSL_GPUOBJ_ALLOC,
344 kgsl_ioctl_gpuobj_alloc),
345 KGSL_IOCTL_FUNC(IOCTL_KGSL_GPUOBJ_FREE,
346 kgsl_ioctl_gpuobj_free),
347 KGSL_IOCTL_FUNC(IOCTL_KGSL_GPUOBJ_INFO,
348 kgsl_ioctl_gpuobj_info),
349 KGSL_IOCTL_FUNC(IOCTL_KGSL_GPUOBJ_IMPORT,
350 kgsl_ioctl_gpuobj_import),
351 KGSL_IOCTL_FUNC(IOCTL_KGSL_GPUOBJ_SYNC,
352 kgsl_ioctl_gpuobj_sync),
353 KGSL_IOCTL_FUNC(IOCTL_KGSL_GPU_COMMAND,
354 kgsl_ioctl_gpu_command),
355 KGSL_IOCTL_FUNC(IOCTL_KGSL_GPUOBJ_SET_INFO,
356 kgsl_ioctl_gpuobj_set_info),
357 KGSL_IOCTL_FUNC(IOCTL_KGSL_SPARSE_PHYS_ALLOC,
358 kgsl_ioctl_sparse_phys_alloc),
359 KGSL_IOCTL_FUNC(IOCTL_KGSL_SPARSE_PHYS_FREE,
360 kgsl_ioctl_sparse_phys_free),
361 KGSL_IOCTL_FUNC(IOCTL_KGSL_SPARSE_VIRT_ALLOC,
362 kgsl_ioctl_sparse_virt_alloc),
363 KGSL_IOCTL_FUNC(IOCTL_KGSL_SPARSE_VIRT_FREE,
364 kgsl_ioctl_sparse_virt_free),
365 KGSL_IOCTL_FUNC(IOCTL_KGSL_SPARSE_BIND,
366 kgsl_ioctl_sparse_bind),
Tarun Karra2b8b3632016-11-14 16:38:27 -0800367 KGSL_IOCTL_FUNC(IOCTL_KGSL_GPU_SPARSE_COMMAND,
368 kgsl_ioctl_gpu_sparse_command),
Shrenuj Bansala419c792016-10-20 14:05:11 -0700369};
370
371long kgsl_compat_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
372{
373 struct kgsl_device_private *dev_priv = filep->private_data;
374 struct kgsl_device *device = dev_priv->device;
375
376 long ret = kgsl_ioctl_helper(filep, cmd, arg, kgsl_compat_ioctl_funcs,
377 ARRAY_SIZE(kgsl_compat_ioctl_funcs));
378
379 /*
380 * If the command was unrecognized in the generic core, try the device
381 * specific function
382 */
383
384 if (ret == -ENOIOCTLCMD) {
385 if (device->ftbl->compat_ioctl != NULL)
386 return device->ftbl->compat_ioctl(dev_priv, cmd, arg);
387
388 KGSL_DRV_INFO(device, "invalid ioctl code 0x%08X\n", cmd);
389 }
390
391 return ret;
392}