compat_ion.c revision 827c849e37b71cb6396d56096ad497748bbbe98f
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/ion/ion.h for the definition of these structs */ 25struct 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 38static int compat_get_ion_allocation_data( 39 struct compat_ion_allocation_data __user *data32, 40 struct ion_allocation_data __user *data) 41{ 42 compat_size_t s; 43 compat_uint_t u; 44 compat_int_t i; 45 int err; 46 47 err = get_user(s, &data32->len); 48 err |= put_user(s, &data->len); 49 err |= get_user(s, &data32->align); 50 err |= put_user(s, &data->align); 51 err |= get_user(u, &data32->heap_id_mask); 52 err |= put_user(u, &data->heap_id_mask); 53 err |= get_user(u, &data32->flags); 54 err |= put_user(u, &data->flags); 55 err |= get_user(i, &data32->handle); 56 err |= put_user(i, &data->handle); 57 58 return err; 59} 60 61static int compat_put_ion_allocation_data( 62 struct compat_ion_allocation_data __user *data32, 63 struct ion_allocation_data __user *data) 64{ 65 compat_size_t s; 66 compat_uint_t u; 67 compat_int_t i; 68 int err; 69 70 err = get_user(s, &data->len); 71 err |= put_user(s, &data32->len); 72 err |= get_user(s, &data->align); 73 err |= put_user(s, &data32->align); 74 err |= get_user(u, &data->heap_id_mask); 75 err |= put_user(u, &data32->heap_id_mask); 76 err |= get_user(u, &data->flags); 77 err |= put_user(u, &data32->flags); 78 err |= get_user(i, &data->handle); 79 err |= put_user(i, &data32->handle); 80 81 return err; 82} 83 84static int compat_get_ion_custom_data( 85 struct compat_ion_custom_data __user *data32, 86 struct ion_custom_data __user *data) 87{ 88 compat_uint_t cmd; 89 compat_ulong_t arg; 90 int err; 91 92 err = get_user(cmd, &data32->cmd); 93 err |= put_user(cmd, &data->cmd); 94 err |= get_user(arg, &data32->arg); 95 err |= put_user(arg, &data->arg); 96 97 return err; 98}; 99 100long compat_ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 101{ 102 long ret; 103 104 if (!filp->f_op || !filp->f_op->unlocked_ioctl) 105 return -ENOTTY; 106 107 switch (cmd) { 108 case ION_IOC_ALLOC: 109 { 110 struct compat_ion_allocation_data __user *data32; 111 struct ion_allocation_data __user *data; 112 int err; 113 114 data32 = compat_ptr(arg); 115 data = compat_alloc_user_space(sizeof(*data)); 116 if (data == NULL) 117 return -EFAULT; 118 119 err = compat_get_ion_allocation_data(data32, data); 120 if (err) 121 return err; 122 123 ret = filp->f_op->unlocked_ioctl(filp, cmd, 124 (unsigned long)data); 125 err = compat_put_ion_allocation_data(data32, data); 126 return ret ? ret : err; 127 } 128 case ION_IOC_FREE: 129 { 130 struct compat_ion_allocation_data __user *data32; 131 struct ion_allocation_data __user *data; 132 int err; 133 134 data32 = compat_ptr(arg); 135 data = compat_alloc_user_space(sizeof(*data)); 136 if (data == NULL) 137 return -EFAULT; 138 139 err = compat_get_ion_allocation_data(data32, data); 140 if (err) 141 return err; 142 143 return filp->f_op->unlocked_ioctl(filp, cmd, 144 (unsigned long)data); 145 } 146 case ION_IOC_CUSTOM: { 147 struct compat_ion_custom_data __user *data32; 148 struct ion_custom_data __user *data; 149 int err; 150 151 data32 = compat_ptr(arg); 152 data = compat_alloc_user_space(sizeof(*data)); 153 if (data == NULL) 154 return -EFAULT; 155 156 err = compat_get_ion_custom_data(data32, data); 157 if (err) 158 return err; 159 160 return filp->f_op->unlocked_ioctl(filp, cmd, 161 (unsigned long)data); 162 } 163 case ION_IOC_SHARE: 164 case ION_IOC_MAP: 165 case ION_IOC_IMPORT: 166 case ION_IOC_SYNC: 167 return filp->f_op->unlocked_ioctl(filp, cmd, 168 (unsigned long)compat_ptr(arg)); 169 default: 170 return -ENOIOCTLCMD; 171 } 172} 173