Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] Clean up mtrr compat ioctl code

Handle 32-bit mtrr ioctls in the mtrr driver instead of the ia32
compatability layer.

Signed-off-by: Brian Gerst <bgerst@didntduck.org>
Cc: Andi Kleen <ak@muc.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Brian Gerst and committed by
Linus Torvalds
c5311781 daedb82d

+109 -143
+76 -47
arch/i386/kernel/cpu/mtrr/if.c
··· 149 149 return -EINVAL; 150 150 } 151 151 152 - static int 153 - mtrr_ioctl(struct inode *inode, struct file *file, 154 - unsigned int cmd, unsigned long __arg) 152 + static long 153 + mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg) 155 154 { 156 - int err; 155 + int err = 0; 157 156 mtrr_type type; 158 157 struct mtrr_sentry sentry; 159 158 struct mtrr_gentry gentry; 160 159 void __user *arg = (void __user *) __arg; 160 + 161 + switch (cmd) { 162 + case MTRRIOC_ADD_ENTRY: 163 + case MTRRIOC_SET_ENTRY: 164 + case MTRRIOC_DEL_ENTRY: 165 + case MTRRIOC_KILL_ENTRY: 166 + case MTRRIOC_ADD_PAGE_ENTRY: 167 + case MTRRIOC_SET_PAGE_ENTRY: 168 + case MTRRIOC_DEL_PAGE_ENTRY: 169 + case MTRRIOC_KILL_PAGE_ENTRY: 170 + if (copy_from_user(&sentry, arg, sizeof sentry)) 171 + return -EFAULT; 172 + break; 173 + case MTRRIOC_GET_ENTRY: 174 + case MTRRIOC_GET_PAGE_ENTRY: 175 + if (copy_from_user(&gentry, arg, sizeof gentry)) 176 + return -EFAULT; 177 + break; 178 + #ifdef CONFIG_COMPAT 179 + case MTRRIOC32_ADD_ENTRY: 180 + case MTRRIOC32_SET_ENTRY: 181 + case MTRRIOC32_DEL_ENTRY: 182 + case MTRRIOC32_KILL_ENTRY: 183 + case MTRRIOC32_ADD_PAGE_ENTRY: 184 + case MTRRIOC32_SET_PAGE_ENTRY: 185 + case MTRRIOC32_DEL_PAGE_ENTRY: 186 + case MTRRIOC32_KILL_PAGE_ENTRY: { 187 + struct mtrr_sentry32 __user *s32 = (struct mtrr_sentry32 __user *)__arg; 188 + err = get_user(sentry.base, &s32->base); 189 + err |= get_user(sentry.size, &s32->size); 190 + err |= get_user(sentry.type, &s32->type); 191 + if (err) 192 + return err; 193 + break; 194 + } 195 + case MTRRIOC32_GET_ENTRY: 196 + case MTRRIOC32_GET_PAGE_ENTRY: { 197 + struct mtrr_gentry32 __user *g32 = (struct mtrr_gentry32 __user *)__arg; 198 + err = get_user(gentry.regnum, &g32->regnum); 199 + err |= get_user(gentry.base, &g32->base); 200 + err |= get_user(gentry.size, &g32->size); 201 + err |= get_user(gentry.type, &g32->type); 202 + if (err) 203 + return err; 204 + break; 205 + } 206 + #endif 207 + } 161 208 162 209 switch (cmd) { 163 210 default: ··· 212 165 case MTRRIOC_ADD_ENTRY: 213 166 if (!capable(CAP_SYS_ADMIN)) 214 167 return -EPERM; 215 - if (copy_from_user(&sentry, arg, sizeof sentry)) 216 - return -EFAULT; 217 168 err = 218 169 mtrr_file_add(sentry.base, sentry.size, sentry.type, 1, 219 170 file, 0); 220 - if (err < 0) 221 - return err; 222 171 break; 223 172 case MTRRIOC_SET_ENTRY: 224 173 if (!capable(CAP_SYS_ADMIN)) 225 174 return -EPERM; 226 - if (copy_from_user(&sentry, arg, sizeof sentry)) 227 - return -EFAULT; 228 175 err = mtrr_add(sentry.base, sentry.size, sentry.type, 0); 229 - if (err < 0) 230 - return err; 231 176 break; 232 177 case MTRRIOC_DEL_ENTRY: 233 178 if (!capable(CAP_SYS_ADMIN)) 234 179 return -EPERM; 235 - if (copy_from_user(&sentry, arg, sizeof sentry)) 236 - return -EFAULT; 237 180 err = mtrr_file_del(sentry.base, sentry.size, file, 0); 238 - if (err < 0) 239 - return err; 240 181 break; 241 182 case MTRRIOC_KILL_ENTRY: 242 183 if (!capable(CAP_SYS_ADMIN)) 243 184 return -EPERM; 244 - if (copy_from_user(&sentry, arg, sizeof sentry)) 245 - return -EFAULT; 246 185 err = mtrr_del(-1, sentry.base, sentry.size); 247 - if (err < 0) 248 - return err; 249 186 break; 250 187 case MTRRIOC_GET_ENTRY: 251 - if (copy_from_user(&gentry, arg, sizeof gentry)) 252 - return -EFAULT; 253 188 if (gentry.regnum >= num_var_ranges) 254 189 return -EINVAL; 255 190 mtrr_if->get(gentry.regnum, &gentry.base, &gentry.size, &type); ··· 246 217 gentry.type = type; 247 218 } 248 219 249 - if (copy_to_user(arg, &gentry, sizeof gentry)) 250 - return -EFAULT; 251 220 break; 252 221 case MTRRIOC_ADD_PAGE_ENTRY: 253 222 if (!capable(CAP_SYS_ADMIN)) 254 223 return -EPERM; 255 - if (copy_from_user(&sentry, arg, sizeof sentry)) 256 - return -EFAULT; 257 224 err = 258 225 mtrr_file_add(sentry.base, sentry.size, sentry.type, 1, 259 226 file, 1); 260 - if (err < 0) 261 - return err; 262 227 break; 263 228 case MTRRIOC_SET_PAGE_ENTRY: 264 229 if (!capable(CAP_SYS_ADMIN)) 265 230 return -EPERM; 266 - if (copy_from_user(&sentry, arg, sizeof sentry)) 267 - return -EFAULT; 268 231 err = mtrr_add_page(sentry.base, sentry.size, sentry.type, 0); 269 - if (err < 0) 270 - return err; 271 232 break; 272 233 case MTRRIOC_DEL_PAGE_ENTRY: 273 234 if (!capable(CAP_SYS_ADMIN)) 274 235 return -EPERM; 275 - if (copy_from_user(&sentry, arg, sizeof sentry)) 276 - return -EFAULT; 277 236 err = mtrr_file_del(sentry.base, sentry.size, file, 1); 278 - if (err < 0) 279 - return err; 280 237 break; 281 238 case MTRRIOC_KILL_PAGE_ENTRY: 282 239 if (!capable(CAP_SYS_ADMIN)) 283 240 return -EPERM; 284 - if (copy_from_user(&sentry, arg, sizeof sentry)) 285 - return -EFAULT; 286 241 err = mtrr_del_page(-1, sentry.base, sentry.size); 287 - if (err < 0) 288 - return err; 289 242 break; 290 243 case MTRRIOC_GET_PAGE_ENTRY: 291 - if (copy_from_user(&gentry, arg, sizeof gentry)) 292 - return -EFAULT; 293 244 if (gentry.regnum >= num_var_ranges) 294 245 return -EINVAL; 295 246 mtrr_if->get(gentry.regnum, &gentry.base, &gentry.size, &type); 296 247 gentry.type = type; 297 - 298 - if (copy_to_user(arg, &gentry, sizeof gentry)) 299 - return -EFAULT; 300 248 break; 301 249 } 302 - return 0; 250 + 251 + if (err) 252 + return err; 253 + 254 + switch(cmd) { 255 + case MTRRIOC_GET_ENTRY: 256 + case MTRRIOC_GET_PAGE_ENTRY: 257 + if (copy_to_user(arg, &gentry, sizeof gentry)) 258 + err = -EFAULT; 259 + break; 260 + #ifdef CONFIG_COMPAT 261 + case MTRRIOC32_GET_ENTRY: 262 + case MTRRIOC32_GET_PAGE_ENTRY: { 263 + struct mtrr_gentry32 __user *g32 = (struct mtrr_gentry32 __user *)__arg; 264 + err = put_user(gentry.base, &g32->base); 265 + err |= put_user(gentry.size, &g32->size); 266 + err |= put_user(gentry.regnum, &g32->regnum); 267 + err |= put_user(gentry.type, &g32->type); 268 + break; 269 + } 270 + #endif 271 + } 272 + return err; 303 273 } 304 274 305 275 static int ··· 338 310 .read = seq_read, 339 311 .llseek = seq_lseek, 340 312 .write = mtrr_write, 341 - .ioctl = mtrr_ioctl, 313 + .unlocked_ioctl = mtrr_ioctl, 314 + .compat_ioctl = mtrr_ioctl, 342 315 .release = mtrr_close, 343 316 }; 344 317
-96
arch/x86_64/ia32/ia32_ioctl.c
··· 12 12 #define INCLUDES 13 13 #include <linux/syscalls.h> 14 14 #include "compat_ioctl.c" 15 - #include <asm/mtrr.h> 16 15 #include <asm/ia32.h> 17 16 18 17 #define CODE ··· 84 85 return sys_ioctl(fd,cmd,arg); 85 86 } 86 87 87 - /* /proc/mtrr ioctls */ 88 - 89 - 90 - struct mtrr_sentry32 91 - { 92 - compat_ulong_t base; /* Base address */ 93 - compat_uint_t size; /* Size of region */ 94 - compat_uint_t type; /* Type of region */ 95 - }; 96 - 97 - struct mtrr_gentry32 98 - { 99 - compat_ulong_t regnum; /* Register number */ 100 - compat_uint_t base; /* Base address */ 101 - compat_uint_t size; /* Size of region */ 102 - compat_uint_t type; /* Type of region */ 103 - }; 104 - 105 - #define MTRR_IOCTL_BASE 'M' 106 - 107 - #define MTRRIOC32_ADD_ENTRY _IOW(MTRR_IOCTL_BASE, 0, struct mtrr_sentry32) 108 - #define MTRRIOC32_SET_ENTRY _IOW(MTRR_IOCTL_BASE, 1, struct mtrr_sentry32) 109 - #define MTRRIOC32_DEL_ENTRY _IOW(MTRR_IOCTL_BASE, 2, struct mtrr_sentry32) 110 - #define MTRRIOC32_GET_ENTRY _IOWR(MTRR_IOCTL_BASE, 3, struct mtrr_gentry32) 111 - #define MTRRIOC32_KILL_ENTRY _IOW(MTRR_IOCTL_BASE, 4, struct mtrr_sentry32) 112 - #define MTRRIOC32_ADD_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 5, struct mtrr_sentry32) 113 - #define MTRRIOC32_SET_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 6, struct mtrr_sentry32) 114 - #define MTRRIOC32_DEL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 7, struct mtrr_sentry32) 115 - #define MTRRIOC32_GET_PAGE_ENTRY _IOWR(MTRR_IOCTL_BASE, 8, struct mtrr_gentry32) 116 - #define MTRRIOC32_KILL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 9, struct mtrr_sentry32) 117 - 118 - 119 - static int mtrr_ioctl32(unsigned int fd, unsigned int cmd, unsigned long arg) 120 - { 121 - struct mtrr_gentry g; 122 - struct mtrr_sentry s; 123 - int get = 0, err = 0; 124 - struct mtrr_gentry32 __user *g32 = (struct mtrr_gentry32 __user *)arg; 125 - mm_segment_t oldfs = get_fs(); 126 - 127 - switch (cmd) { 128 - #define SET(x) case MTRRIOC32_ ## x ## _ENTRY: cmd = MTRRIOC_ ## x ## _ENTRY; break 129 - #define GET(x) case MTRRIOC32_ ## x ## _ENTRY: cmd = MTRRIOC_ ## x ## _ENTRY; get=1; break 130 - SET(ADD); 131 - SET(SET); 132 - SET(DEL); 133 - GET(GET); 134 - SET(KILL); 135 - SET(ADD_PAGE); 136 - SET(SET_PAGE); 137 - SET(DEL_PAGE); 138 - GET(GET_PAGE); 139 - SET(KILL_PAGE); 140 - } 141 - 142 - if (get) { 143 - err = get_user(g.regnum, &g32->regnum); 144 - err |= get_user(g.base, &g32->base); 145 - err |= get_user(g.size, &g32->size); 146 - err |= get_user(g.type, &g32->type); 147 - 148 - arg = (unsigned long)&g; 149 - } else { 150 - struct mtrr_sentry32 __user *s32 = (struct mtrr_sentry32 __user *)arg; 151 - err = get_user(s.base, &s32->base); 152 - err |= get_user(s.size, &s32->size); 153 - err |= get_user(s.type, &s32->type); 154 - 155 - arg = (unsigned long)&s; 156 - } 157 - if (err) return err; 158 - 159 - set_fs(KERNEL_DS); 160 - err = sys_ioctl(fd, cmd, arg); 161 - set_fs(oldfs); 162 - 163 - if (!err && get) { 164 - err = put_user(g.base, &g32->base); 165 - err |= put_user(g.size, &g32->size); 166 - err |= put_user(g.regnum, &g32->regnum); 167 - err |= put_user(g.type, &g32->type); 168 - } 169 - return err; 170 - } 171 88 172 89 #define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl_trans_handler_t)(handler) }, 173 90 #define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd,sys_ioctl) ··· 108 193 HANDLE_IOCTL(RTC_EPOCH_READ32, rtc32_ioctl) 109 194 HANDLE_IOCTL(RTC_EPOCH_SET32, rtc32_ioctl) 110 195 /* take care of sizeof(sizeof()) breakage */ 111 - /* mtrr */ 112 - HANDLE_IOCTL(MTRRIOC32_ADD_ENTRY, mtrr_ioctl32) 113 - HANDLE_IOCTL(MTRRIOC32_SET_ENTRY, mtrr_ioctl32) 114 - HANDLE_IOCTL(MTRRIOC32_DEL_ENTRY, mtrr_ioctl32) 115 - HANDLE_IOCTL(MTRRIOC32_GET_ENTRY, mtrr_ioctl32) 116 - HANDLE_IOCTL(MTRRIOC32_KILL_ENTRY, mtrr_ioctl32) 117 - HANDLE_IOCTL(MTRRIOC32_ADD_PAGE_ENTRY, mtrr_ioctl32) 118 - HANDLE_IOCTL(MTRRIOC32_SET_PAGE_ENTRY, mtrr_ioctl32) 119 - HANDLE_IOCTL(MTRRIOC32_DEL_PAGE_ENTRY, mtrr_ioctl32) 120 - HANDLE_IOCTL(MTRRIOC32_GET_PAGE_ENTRY, mtrr_ioctl32) 121 - HANDLE_IOCTL(MTRRIOC32_KILL_PAGE_ENTRY, mtrr_ioctl32) 122 196 }; 123 197 124 198 int ioctl_table_size = ARRAY_SIZE(ioctl_start);
+33
include/asm-x86_64/mtrr.h
··· 25 25 26 26 #include <linux/config.h> 27 27 #include <linux/ioctl.h> 28 + #include <linux/compat.h> 28 29 29 30 #define MTRR_IOCTL_BASE 'M' 30 31 ··· 105 104 # endif 106 105 107 106 #endif 107 + 108 + #ifdef CONFIG_COMPAT 109 + 110 + struct mtrr_sentry32 111 + { 112 + compat_ulong_t base; /* Base address */ 113 + compat_uint_t size; /* Size of region */ 114 + compat_uint_t type; /* Type of region */ 115 + }; 116 + 117 + struct mtrr_gentry32 118 + { 119 + compat_ulong_t regnum; /* Register number */ 120 + compat_uint_t base; /* Base address */ 121 + compat_uint_t size; /* Size of region */ 122 + compat_uint_t type; /* Type of region */ 123 + }; 124 + 125 + #define MTRR_IOCTL_BASE 'M' 126 + 127 + #define MTRRIOC32_ADD_ENTRY _IOW(MTRR_IOCTL_BASE, 0, struct mtrr_sentry32) 128 + #define MTRRIOC32_SET_ENTRY _IOW(MTRR_IOCTL_BASE, 1, struct mtrr_sentry32) 129 + #define MTRRIOC32_DEL_ENTRY _IOW(MTRR_IOCTL_BASE, 2, struct mtrr_sentry32) 130 + #define MTRRIOC32_GET_ENTRY _IOWR(MTRR_IOCTL_BASE, 3, struct mtrr_gentry32) 131 + #define MTRRIOC32_KILL_ENTRY _IOW(MTRR_IOCTL_BASE, 4, struct mtrr_sentry32) 132 + #define MTRRIOC32_ADD_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 5, struct mtrr_sentry32) 133 + #define MTRRIOC32_SET_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 6, struct mtrr_sentry32) 134 + #define MTRRIOC32_DEL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 7, struct mtrr_sentry32) 135 + #define MTRRIOC32_GET_PAGE_ENTRY _IOWR(MTRR_IOCTL_BASE, 8, struct mtrr_gentry32) 136 + #define MTRRIOC32_KILL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 9, struct mtrr_sentry32) 137 + 138 + #endif /* CONFIG_COMPAT */ 108 139 109 140 #endif /* _LINUX_MTRR_H */