blob: af6cd370b30f3e890e5edc9bdec864efb4f8b9b8 [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
John Stultz687258f2013-12-13 14:24:58 -080038#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
Rom Lemarchand827c8492013-12-13 14:24:55 -080044static 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
67static 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
90static int compat_get_ion_custom_data(
91 struct compat_ion_custom_data __user *data32,
92 struct ion_custom_data __user *data)
93{
John Stultze1d855b2013-12-13 19:26:33 -080094 compat_uint_t cmd;
95 compat_ulong_t arg;
Rom Lemarchand827c8492013-12-13 14:24:55 -080096 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
106long 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) {
John Stultz687258f2013-12-13 14:24:58 -0800114 case COMPAT_ION_IOC_ALLOC:
Rom Lemarchand827c8492013-12-13 14:24:55 -0800115 {
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;
John Stultz687258f2013-12-13 14:24:58 -0800128 ret = filp->f_op->unlocked_ioctl(filp, ION_IOC_ALLOC,
Rom Lemarchand827c8492013-12-13 14:24:55 -0800129 (unsigned long)data);
130 err = compat_put_ion_allocation_data(data32, data);
131 return ret ? ret : err;
132 }
John Stultz687258f2013-12-13 14:24:58 -0800133 case COMPAT_ION_IOC_FREE:
Rom Lemarchand827c8492013-12-13 14:24:55 -0800134 {
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
John Stultz687258f2013-12-13 14:24:58 -0800148 return filp->f_op->unlocked_ioctl(filp, ION_IOC_FREE,
Rom Lemarchand827c8492013-12-13 14:24:55 -0800149 (unsigned long)data);
150 }
John Stultz687258f2013-12-13 14:24:58 -0800151 case COMPAT_ION_IOC_CUSTOM: {
Rom Lemarchand827c8492013-12-13 14:24:55 -0800152 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
John Stultz687258f2013-12-13 14:24:58 -0800165 return filp->f_op->unlocked_ioctl(filp, ION_IOC_CUSTOM,
Rom Lemarchand827c8492013-12-13 14:24:55 -0800166 (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}