]> Pileus Git - ~andy/linux/blob - drivers/staging/android/ion/compat_ion.c
ion: Fix compat support to use proper compat ioctl numbers
[~andy/linux] / drivers / staging / android / ion / compat_ion.c
1 /*
2  * drivers/staging/android/ion/compat_ion.c
3  *
4  * Copyright (C) 2013 Google, Inc.
5  *
6  * This software is licensed under the terms of the GNU General Public
7  * License version 2, as published by the Free Software Foundation, and
8  * may be copied, distributed, and modified under those terms.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  */
16
17 #include <linux/compat.h>
18 #include <linux/fs.h>
19 #include <linux/uaccess.h>
20
21 #include "ion.h"
22 #include "compat_ion.h"
23
24 /* See drivers/staging/android/uapi/ion.h for the definition of these structs */
25 struct compat_ion_allocation_data {
26         compat_size_t len;
27         compat_size_t align;
28         compat_uint_t heap_id_mask;
29         compat_uint_t flags;
30         compat_int_t handle;
31 };
32
33 struct compat_ion_custom_data {
34         compat_uint_t cmd;
35         compat_ulong_t arg;
36 };
37
38 #define COMPAT_ION_IOC_ALLOC    _IOWR(ION_IOC_MAGIC, 0, \
39                                       struct compat_ion_allocation_data)
40 #define COMPAT_ION_IOC_FREE     _IOWR(ION_IOC_MAGIC, 1, struct ion_handle_data)
41 #define COMPAT_ION_IOC_CUSTOM   _IOWR(ION_IOC_MAGIC, 6, \
42                                       struct compat_ion_custom_data)
43
44 static int compat_get_ion_allocation_data(
45                         struct compat_ion_allocation_data __user *data32,
46                         struct ion_allocation_data __user *data)
47 {
48         compat_size_t s;
49         compat_uint_t u;
50         compat_int_t i;
51         int err;
52
53         err = get_user(s, &data32->len);
54         err |= put_user(s, &data->len);
55         err |= get_user(s, &data32->align);
56         err |= put_user(s, &data->align);
57         err |= get_user(u, &data32->heap_id_mask);
58         err |= put_user(u, &data->heap_id_mask);
59         err |= get_user(u, &data32->flags);
60         err |= put_user(u, &data->flags);
61         err |= get_user(i, &data32->handle);
62         err |= put_user(i, &data->handle);
63
64         return err;
65 }
66
67 static int compat_put_ion_allocation_data(
68                         struct compat_ion_allocation_data __user *data32,
69                         struct ion_allocation_data __user *data)
70 {
71         compat_size_t s;
72         compat_uint_t u;
73         compat_int_t i;
74         int err;
75
76         err = get_user(s, &data->len);
77         err |= put_user(s, &data32->len);
78         err |= get_user(s, &data->align);
79         err |= put_user(s, &data32->align);
80         err |= get_user(u, &data->heap_id_mask);
81         err |= put_user(u, &data32->heap_id_mask);
82         err |= get_user(u, &data->flags);
83         err |= put_user(u, &data32->flags);
84         err |= get_user(i, &data->handle);
85         err |= put_user(i, &data32->handle);
86
87         return err;
88 }
89
90 static int compat_get_ion_custom_data(
91                         struct compat_ion_custom_data __user *data32,
92                         struct ion_custom_data __user *data)
93 {
94         compat_uint_t cmd;
95         compat_ulong_t arg;
96         int err;
97
98         err = get_user(cmd, &data32->cmd);
99         err |= put_user(cmd, &data->cmd);
100         err |= get_user(arg, &data32->arg);
101         err |= put_user(arg, &data->arg);
102
103         return err;
104 };
105
106 long compat_ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
107 {
108         long ret;
109
110         if (!filp->f_op || !filp->f_op->unlocked_ioctl)
111                 return -ENOTTY;
112
113         switch (cmd) {
114         case COMPAT_ION_IOC_ALLOC:
115         {
116                 struct compat_ion_allocation_data __user *data32;
117                 struct ion_allocation_data __user *data;
118                 int err;
119
120                 data32 = compat_ptr(arg);
121                 data = compat_alloc_user_space(sizeof(*data));
122                 if (data == NULL)
123                         return -EFAULT;
124
125                 err = compat_get_ion_allocation_data(data32, data);
126                 if (err)
127                         return err;
128                 ret = filp->f_op->unlocked_ioctl(filp, ION_IOC_ALLOC,
129                                                         (unsigned long)data);
130                 err = compat_put_ion_allocation_data(data32, data);
131                 return ret ? ret : err;
132         }
133         case COMPAT_ION_IOC_FREE:
134         {
135                 struct compat_ion_allocation_data __user *data32;
136                 struct ion_allocation_data __user *data;
137                 int err;
138
139                 data32 = compat_ptr(arg);
140                 data = compat_alloc_user_space(sizeof(*data));
141                 if (data == NULL)
142                         return -EFAULT;
143
144                 err = compat_get_ion_allocation_data(data32, data);
145                 if (err)
146                         return err;
147
148                 return filp->f_op->unlocked_ioctl(filp, ION_IOC_FREE,
149                                                         (unsigned long)data);
150         }
151         case COMPAT_ION_IOC_CUSTOM: {
152                 struct compat_ion_custom_data __user *data32;
153                 struct ion_custom_data __user *data;
154                 int err;
155
156                 data32 = compat_ptr(arg);
157                 data = compat_alloc_user_space(sizeof(*data));
158                 if (data == NULL)
159                         return -EFAULT;
160
161                 err = compat_get_ion_custom_data(data32, data);
162                 if (err)
163                         return err;
164
165                 return filp->f_op->unlocked_ioctl(filp, ION_IOC_CUSTOM,
166                                                         (unsigned long)data);
167         }
168         case ION_IOC_SHARE:
169         case ION_IOC_MAP:
170         case ION_IOC_IMPORT:
171         case ION_IOC_SYNC:
172                 return filp->f_op->unlocked_ioctl(filp, cmd,
173                                                 (unsigned long)compat_ptr(arg));
174         default:
175                 return -ENOIOCTLCMD;
176         }
177 }