blob: ee3a7380e53b129ed04320940d6cae57cbbd4226 [file] [log] [blame]
Rom Lemarchand827c8492013-12-13 14:24:55 -08001/*
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
Colin Crossc3a2fe02013-12-13 14:24:57 -080024/* See drivers/staging/android/uapi/ion.h for the definition of these structs */
Rom Lemarchand827c8492013-12-13 14:24:55 -080025struct 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
33struct compat_ion_custom_data {
34 compat_uint_t cmd;
35 compat_ulong_t arg;
36};
37
Laura Abbott8666a872014-02-04 16:08:39 -080038struct compat_ion_handle_data {
39 compat_int_t handle;
40};
41
John Stultz687258f2013-12-13 14:24:58 -080042#define COMPAT_ION_IOC_ALLOC _IOWR(ION_IOC_MAGIC, 0, \
43 struct compat_ion_allocation_data)
Laura Abbott8666a872014-02-04 16:08:39 -080044#define COMPAT_ION_IOC_FREE _IOWR(ION_IOC_MAGIC, 1, \
45 struct compat_ion_handle_data)
John Stultz687258f2013-12-13 14:24:58 -080046#define COMPAT_ION_IOC_CUSTOM _IOWR(ION_IOC_MAGIC, 6, \
47 struct compat_ion_custom_data)
48
Rom Lemarchand827c8492013-12-13 14:24:55 -080049static int compat_get_ion_allocation_data(
50 struct compat_ion_allocation_data __user *data32,
51 struct ion_allocation_data __user *data)
52{
53 compat_size_t s;
54 compat_uint_t u;
55 compat_int_t i;
56 int err;
57
58 err = get_user(s, &data32->len);
59 err |= put_user(s, &data->len);
60 err |= get_user(s, &data32->align);
61 err |= put_user(s, &data->align);
62 err |= get_user(u, &data32->heap_id_mask);
63 err |= put_user(u, &data->heap_id_mask);
64 err |= get_user(u, &data32->flags);
65 err |= put_user(u, &data->flags);
66 err |= get_user(i, &data32->handle);
67 err |= put_user(i, &data->handle);
68
69 return err;
70}
71
Laura Abbott8666a872014-02-04 16:08:39 -080072static int compat_get_ion_handle_data(
73 struct compat_ion_handle_data __user *data32,
74 struct ion_handle_data __user *data)
75{
76 compat_int_t i;
77 int err;
78
79 err = get_user(i, &data32->handle);
80 err |= put_user(i, &data->handle);
81
82 return err;
83}
84
Rom Lemarchand827c8492013-12-13 14:24:55 -080085static int compat_put_ion_allocation_data(
86 struct compat_ion_allocation_data __user *data32,
87 struct ion_allocation_data __user *data)
88{
89 compat_size_t s;
90 compat_uint_t u;
91 compat_int_t i;
92 int err;
93
94 err = get_user(s, &data->len);
95 err |= put_user(s, &data32->len);
96 err |= get_user(s, &data->align);
97 err |= put_user(s, &data32->align);
98 err |= get_user(u, &data->heap_id_mask);
99 err |= put_user(u, &data32->heap_id_mask);
100 err |= get_user(u, &data->flags);
101 err |= put_user(u, &data32->flags);
102 err |= get_user(i, &data->handle);
103 err |= put_user(i, &data32->handle);
104
105 return err;
106}
107
108static int compat_get_ion_custom_data(
109 struct compat_ion_custom_data __user *data32,
110 struct ion_custom_data __user *data)
111{
John Stultze1d855b2013-12-13 19:26:33 -0800112 compat_uint_t cmd;
113 compat_ulong_t arg;
Rom Lemarchand827c8492013-12-13 14:24:55 -0800114 int err;
115
116 err = get_user(cmd, &data32->cmd);
117 err |= put_user(cmd, &data->cmd);
118 err |= get_user(arg, &data32->arg);
119 err |= put_user(arg, &data->arg);
120
121 return err;
122};
123
124long compat_ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
125{
126 long ret;
127
128 if (!filp->f_op || !filp->f_op->unlocked_ioctl)
129 return -ENOTTY;
130
131 switch (cmd) {
John Stultz687258f2013-12-13 14:24:58 -0800132 case COMPAT_ION_IOC_ALLOC:
Rom Lemarchand827c8492013-12-13 14:24:55 -0800133 {
134 struct compat_ion_allocation_data __user *data32;
135 struct ion_allocation_data __user *data;
136 int err;
137
138 data32 = compat_ptr(arg);
139 data = compat_alloc_user_space(sizeof(*data));
140 if (data == NULL)
141 return -EFAULT;
142
143 err = compat_get_ion_allocation_data(data32, data);
144 if (err)
145 return err;
John Stultz687258f2013-12-13 14:24:58 -0800146 ret = filp->f_op->unlocked_ioctl(filp, ION_IOC_ALLOC,
Rom Lemarchand827c8492013-12-13 14:24:55 -0800147 (unsigned long)data);
148 err = compat_put_ion_allocation_data(data32, data);
149 return ret ? ret : err;
150 }
John Stultz687258f2013-12-13 14:24:58 -0800151 case COMPAT_ION_IOC_FREE:
Rom Lemarchand827c8492013-12-13 14:24:55 -0800152 {
Laura Abbott8666a872014-02-04 16:08:39 -0800153 struct compat_ion_handle_data __user *data32;
154 struct ion_handle_data __user *data;
Rom Lemarchand827c8492013-12-13 14:24:55 -0800155 int err;
156
157 data32 = compat_ptr(arg);
158 data = compat_alloc_user_space(sizeof(*data));
159 if (data == NULL)
160 return -EFAULT;
161
Laura Abbott8666a872014-02-04 16:08:39 -0800162 err = compat_get_ion_handle_data(data32, data);
Rom Lemarchand827c8492013-12-13 14:24:55 -0800163 if (err)
164 return err;
165
John Stultz687258f2013-12-13 14:24:58 -0800166 return filp->f_op->unlocked_ioctl(filp, ION_IOC_FREE,
Rom Lemarchand827c8492013-12-13 14:24:55 -0800167 (unsigned long)data);
168 }
John Stultz687258f2013-12-13 14:24:58 -0800169 case COMPAT_ION_IOC_CUSTOM: {
Rom Lemarchand827c8492013-12-13 14:24:55 -0800170 struct compat_ion_custom_data __user *data32;
171 struct ion_custom_data __user *data;
172 int err;
173
174 data32 = compat_ptr(arg);
175 data = compat_alloc_user_space(sizeof(*data));
176 if (data == NULL)
177 return -EFAULT;
178
179 err = compat_get_ion_custom_data(data32, data);
180 if (err)
181 return err;
182
John Stultz687258f2013-12-13 14:24:58 -0800183 return filp->f_op->unlocked_ioctl(filp, ION_IOC_CUSTOM,
Rom Lemarchand827c8492013-12-13 14:24:55 -0800184 (unsigned long)data);
185 }
186 case ION_IOC_SHARE:
187 case ION_IOC_MAP:
188 case ION_IOC_IMPORT:
189 case ION_IOC_SYNC:
190 return filp->f_op->unlocked_ioctl(filp, cmd,
191 (unsigned long)compat_ptr(arg));
192 default:
193 return -ENOIOCTLCMD;
194 }
195}