diff options
author | Arnd Bergmann <arnd@arndb.de> | 2009-11-14 17:16:18 -0500 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2009-12-10 16:52:12 -0500 |
commit | 43c6e7b97f9ea0f4dec430dbafb6afa6ac711eb1 (patch) | |
tree | c85cec4232ba702d97adfe3b0db721fe2fe13a2c /fs/compat_ioctl.c | |
parent | 661f627da98c0647bcc002ef35e5441fb3ce667c (diff) |
compat_ioctl: pass compat pointer directly to handlers
Instead of having each handler call compat_ptr, we can now
convert the pointer once and pass that to each handler.
This saves a little bit of both source and object code size.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'fs/compat_ioctl.c')
-rw-r--r-- | fs/compat_ioctl.c | 211 |
1 files changed, 83 insertions, 128 deletions
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index b4873ae84ca1..ae1f1e699ad7 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c | |||
@@ -117,33 +117,34 @@ | |||
117 | #include <asm/fbio.h> | 117 | #include <asm/fbio.h> |
118 | #endif | 118 | #endif |
119 | 119 | ||
120 | static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg) | 120 | static int w_long(unsigned int fd, unsigned int cmd, |
121 | compat_ulong_t __user *argp) | ||
121 | { | 122 | { |
122 | mm_segment_t old_fs = get_fs(); | 123 | mm_segment_t old_fs = get_fs(); |
123 | int err; | 124 | int err; |
124 | unsigned long val; | 125 | unsigned long val; |
125 | 126 | ||
126 | set_fs (KERNEL_DS); | 127 | set_fs (KERNEL_DS); |
127 | err = sys_ioctl(fd, cmd, (unsigned long)&val); | 128 | err = sys_ioctl(fd, cmd, (unsigned long)&val); |
128 | set_fs (old_fs); | 129 | set_fs (old_fs); |
129 | if (!err && put_user(val, (u32 __user *)compat_ptr(arg))) | 130 | if (!err && put_user(val, argp)) |
130 | return -EFAULT; | 131 | return -EFAULT; |
131 | return err; | 132 | return err; |
132 | } | 133 | } |
133 | 134 | ||
134 | static int rw_long(unsigned int fd, unsigned int cmd, unsigned long arg) | 135 | static int rw_long(unsigned int fd, unsigned int cmd, |
136 | compat_ulong_t __user *argp) | ||
135 | { | 137 | { |
136 | mm_segment_t old_fs = get_fs(); | 138 | mm_segment_t old_fs = get_fs(); |
137 | u32 __user *argptr = compat_ptr(arg); | ||
138 | int err; | 139 | int err; |
139 | unsigned long val; | 140 | unsigned long val; |
140 | 141 | ||
141 | if(get_user(val, argptr)) | 142 | if(get_user(val, argp)) |
142 | return -EFAULT; | 143 | return -EFAULT; |
143 | set_fs (KERNEL_DS); | 144 | set_fs (KERNEL_DS); |
144 | err = sys_ioctl(fd, cmd, (unsigned long)&val); | 145 | err = sys_ioctl(fd, cmd, (unsigned long)&val); |
145 | set_fs (old_fs); | 146 | set_fs (old_fs); |
146 | if (!err && put_user(val, argptr)) | 147 | if (!err && put_user(val, argp)) |
147 | return -EFAULT; | 148 | return -EFAULT; |
148 | return err; | 149 | return err; |
149 | } | 150 | } |
@@ -157,7 +158,8 @@ struct compat_video_event { | |||
157 | } u; | 158 | } u; |
158 | }; | 159 | }; |
159 | 160 | ||
160 | static int do_video_get_event(unsigned int fd, unsigned int cmd, unsigned long arg) | 161 | static int do_video_get_event(unsigned int fd, unsigned int cmd, |
162 | struct compat_video_event __user *up) | ||
161 | { | 163 | { |
162 | struct video_event kevent; | 164 | struct video_event kevent; |
163 | mm_segment_t old_fs = get_fs(); | 165 | mm_segment_t old_fs = get_fs(); |
@@ -168,8 +170,6 @@ static int do_video_get_event(unsigned int fd, unsigned int cmd, unsigned long a | |||
168 | set_fs(old_fs); | 170 | set_fs(old_fs); |
169 | 171 | ||
170 | if (!err) { | 172 | if (!err) { |
171 | struct compat_video_event __user *up = compat_ptr(arg); | ||
172 | |||
173 | err = put_user(kevent.type, &up->type); | 173 | err = put_user(kevent.type, &up->type); |
174 | err |= put_user(kevent.timestamp, &up->timestamp); | 174 | err |= put_user(kevent.timestamp, &up->timestamp); |
175 | err |= put_user(kevent.u.size.w, &up->u.size.w); | 175 | err |= put_user(kevent.u.size.w, &up->u.size.w); |
@@ -188,15 +188,14 @@ struct compat_video_still_picture { | |||
188 | int32_t size; | 188 | int32_t size; |
189 | }; | 189 | }; |
190 | 190 | ||
191 | static int do_video_stillpicture(unsigned int fd, unsigned int cmd, unsigned long arg) | 191 | static int do_video_stillpicture(unsigned int fd, unsigned int cmd, |
192 | struct compat_video_still_picture __user *up) | ||
192 | { | 193 | { |
193 | struct compat_video_still_picture __user *up; | ||
194 | struct video_still_picture __user *up_native; | 194 | struct video_still_picture __user *up_native; |
195 | compat_uptr_t fp; | 195 | compat_uptr_t fp; |
196 | int32_t size; | 196 | int32_t size; |
197 | int err; | 197 | int err; |
198 | 198 | ||
199 | up = (struct compat_video_still_picture __user *) arg; | ||
200 | err = get_user(fp, &up->iFrame); | 199 | err = get_user(fp, &up->iFrame); |
201 | err |= get_user(size, &up->size); | 200 | err |= get_user(size, &up->size); |
202 | if (err) | 201 | if (err) |
@@ -220,14 +219,13 @@ struct compat_video_spu_palette { | |||
220 | compat_uptr_t palette; | 219 | compat_uptr_t palette; |
221 | }; | 220 | }; |
222 | 221 | ||
223 | static int do_video_set_spu_palette(unsigned int fd, unsigned int cmd, unsigned long arg) | 222 | static int do_video_set_spu_palette(unsigned int fd, unsigned int cmd, |
223 | struct compat_video_spu_palette __user *up) | ||
224 | { | 224 | { |
225 | struct compat_video_spu_palette __user *up; | ||
226 | struct video_spu_palette __user *up_native; | 225 | struct video_spu_palette __user *up_native; |
227 | compat_uptr_t palp; | 226 | compat_uptr_t palp; |
228 | int length, err; | 227 | int length, err; |
229 | 228 | ||
230 | up = (struct compat_video_spu_palette __user *) arg; | ||
231 | err = get_user(palp, &up->palette); | 229 | err = get_user(palp, &up->palette); |
232 | err |= get_user(length, &up->length); | 230 | err |= get_user(length, &up->length); |
233 | 231 | ||
@@ -295,16 +293,15 @@ static int sg_build_iovec(sg_io_hdr_t __user *sgio, void __user *dxferp, u16 iov | |||
295 | return 0; | 293 | return 0; |
296 | } | 294 | } |
297 | 295 | ||
298 | static int sg_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) | 296 | static int sg_ioctl_trans(unsigned int fd, unsigned int cmd, |
297 | sg_io_hdr32_t __user *sgio32) | ||
299 | { | 298 | { |
300 | sg_io_hdr_t __user *sgio; | 299 | sg_io_hdr_t __user *sgio; |
301 | sg_io_hdr32_t __user *sgio32; | ||
302 | u16 iovec_count; | 300 | u16 iovec_count; |
303 | u32 data; | 301 | u32 data; |
304 | void __user *dxferp; | 302 | void __user *dxferp; |
305 | int err; | 303 | int err; |
306 | 304 | ||
307 | sgio32 = compat_ptr(arg); | ||
308 | if (get_user(iovec_count, &sgio32->iovec_count)) | 305 | if (get_user(iovec_count, &sgio32->iovec_count)) |
309 | return -EFAULT; | 306 | return -EFAULT; |
310 | 307 | ||
@@ -394,11 +391,11 @@ struct compat_sg_req_info { /* used by SG_GET_REQUEST_TABLE ioctl() */ | |||
394 | int unused; | 391 | int unused; |
395 | }; | 392 | }; |
396 | 393 | ||
397 | static int sg_grt_trans(unsigned int fd, unsigned int cmd, unsigned long arg) | 394 | static int sg_grt_trans(unsigned int fd, unsigned int cmd, struct |
395 | compat_sg_req_info __user *o) | ||
398 | { | 396 | { |
399 | int err, i; | 397 | int err, i; |
400 | sg_req_info_t __user *r; | 398 | sg_req_info_t __user *r; |
401 | struct compat_sg_req_info __user *o = (void __user *)arg; | ||
402 | r = compat_alloc_user_space(sizeof(sg_req_info_t)*SG_MAX_QUEUE); | 399 | r = compat_alloc_user_space(sizeof(sg_req_info_t)*SG_MAX_QUEUE); |
403 | err = sys_ioctl(fd,cmd,(unsigned long)r); | 400 | err = sys_ioctl(fd,cmd,(unsigned long)r); |
404 | if (err < 0) | 401 | if (err < 0) |
@@ -426,9 +423,9 @@ struct sock_fprog32 { | |||
426 | #define PPPIOCSPASS32 _IOW('t', 71, struct sock_fprog32) | 423 | #define PPPIOCSPASS32 _IOW('t', 71, struct sock_fprog32) |
427 | #define PPPIOCSACTIVE32 _IOW('t', 70, struct sock_fprog32) | 424 | #define PPPIOCSACTIVE32 _IOW('t', 70, struct sock_fprog32) |
428 | 425 | ||
429 | static int ppp_sock_fprog_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) | 426 | static int ppp_sock_fprog_ioctl_trans(unsigned int fd, unsigned int cmd, |
427 | struct sock_fprog32 __user *u_fprog32) | ||
430 | { | 428 | { |
431 | struct sock_fprog32 __user *u_fprog32 = compat_ptr(arg); | ||
432 | struct sock_fprog __user *u_fprog64 = compat_alloc_user_space(sizeof(struct sock_fprog)); | 429 | struct sock_fprog __user *u_fprog64 = compat_alloc_user_space(sizeof(struct sock_fprog)); |
433 | void __user *fptr64; | 430 | void __user *fptr64; |
434 | u32 fptr32; | 431 | u32 fptr32; |
@@ -465,15 +462,14 @@ struct ppp_idle32 { | |||
465 | }; | 462 | }; |
466 | #define PPPIOCGIDLE32 _IOR('t', 63, struct ppp_idle32) | 463 | #define PPPIOCGIDLE32 _IOR('t', 63, struct ppp_idle32) |
467 | 464 | ||
468 | static int ppp_gidle(unsigned int fd, unsigned int cmd, unsigned long arg) | 465 | static int ppp_gidle(unsigned int fd, unsigned int cmd, |
466 | struct ppp_idle32 __user *idle32) | ||
469 | { | 467 | { |
470 | struct ppp_idle __user *idle; | 468 | struct ppp_idle __user *idle; |
471 | struct ppp_idle32 __user *idle32; | ||
472 | __kernel_time_t xmit, recv; | 469 | __kernel_time_t xmit, recv; |
473 | int err; | 470 | int err; |
474 | 471 | ||
475 | idle = compat_alloc_user_space(sizeof(*idle)); | 472 | idle = compat_alloc_user_space(sizeof(*idle)); |
476 | idle32 = compat_ptr(arg); | ||
477 | 473 | ||
478 | err = sys_ioctl(fd, PPPIOCGIDLE, (unsigned long) idle); | 474 | err = sys_ioctl(fd, PPPIOCGIDLE, (unsigned long) idle); |
479 | 475 | ||
@@ -487,15 +483,14 @@ static int ppp_gidle(unsigned int fd, unsigned int cmd, unsigned long arg) | |||
487 | return err; | 483 | return err; |
488 | } | 484 | } |
489 | 485 | ||
490 | static int ppp_scompress(unsigned int fd, unsigned int cmd, unsigned long arg) | 486 | static int ppp_scompress(unsigned int fd, unsigned int cmd, |
487 | struct ppp_option_data32 __user *odata32) | ||
491 | { | 488 | { |
492 | struct ppp_option_data __user *odata; | 489 | struct ppp_option_data __user *odata; |
493 | struct ppp_option_data32 __user *odata32; | ||
494 | __u32 data; | 490 | __u32 data; |
495 | void __user *datap; | 491 | void __user *datap; |
496 | 492 | ||
497 | odata = compat_alloc_user_space(sizeof(*odata)); | 493 | odata = compat_alloc_user_space(sizeof(*odata)); |
498 | odata32 = compat_ptr(arg); | ||
499 | 494 | ||
500 | if (get_user(data, &odata32->ptr)) | 495 | if (get_user(data, &odata32->ptr)) |
501 | return -EFAULT; | 496 | return -EFAULT; |
@@ -511,35 +506,6 @@ static int ppp_scompress(unsigned int fd, unsigned int cmd, unsigned long arg) | |||
511 | return sys_ioctl(fd, PPPIOCSCOMPRESS, (unsigned long) odata); | 506 | return sys_ioctl(fd, PPPIOCSCOMPRESS, (unsigned long) odata); |
512 | } | 507 | } |
513 | 508 | ||
514 | static int ppp_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) | ||
515 | { | ||
516 | int err; | ||
517 | |||
518 | switch (cmd) { | ||
519 | case PPPIOCGIDLE32: | ||
520 | err = ppp_gidle(fd, cmd, arg); | ||
521 | break; | ||
522 | |||
523 | case PPPIOCSCOMPRESS32: | ||
524 | err = ppp_scompress(fd, cmd, arg); | ||
525 | break; | ||
526 | |||
527 | default: | ||
528 | do { | ||
529 | static int count; | ||
530 | if (++count <= 20) | ||
531 | printk("ppp_ioctl: Unknown cmd fd(%d) " | ||
532 | "cmd(%08x) arg(%08x)\n", | ||
533 | (int)fd, (unsigned int)cmd, (unsigned int)arg); | ||
534 | } while(0); | ||
535 | err = -EINVAL; | ||
536 | break; | ||
537 | }; | ||
538 | |||
539 | return err; | ||
540 | } | ||
541 | |||
542 | |||
543 | #ifdef CONFIG_BLOCK | 509 | #ifdef CONFIG_BLOCK |
544 | struct mtget32 { | 510 | struct mtget32 { |
545 | compat_long_t mt_type; | 511 | compat_long_t mt_type; |
@@ -557,7 +523,7 @@ struct mtpos32 { | |||
557 | }; | 523 | }; |
558 | #define MTIOCPOS32 _IOR('m', 3, struct mtpos32) | 524 | #define MTIOCPOS32 _IOR('m', 3, struct mtpos32) |
559 | 525 | ||
560 | static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) | 526 | static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, void __user *argp) |
561 | { | 527 | { |
562 | mm_segment_t old_fs = get_fs(); | 528 | mm_segment_t old_fs = get_fs(); |
563 | struct mtget get; | 529 | struct mtget get; |
@@ -577,15 +543,6 @@ static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) | |||
577 | kcmd = MTIOCGET; | 543 | kcmd = MTIOCGET; |
578 | karg = &get; | 544 | karg = &get; |
579 | break; | 545 | break; |
580 | default: | ||
581 | do { | ||
582 | static int count; | ||
583 | if (++count <= 20) | ||
584 | printk("mt_ioctl: Unknown cmd fd(%d) " | ||
585 | "cmd(%08x) arg(%08x)\n", | ||
586 | (int)fd, (unsigned int)cmd, (unsigned int)arg); | ||
587 | } while(0); | ||
588 | return -EINVAL; | ||
589 | } | 546 | } |
590 | set_fs (KERNEL_DS); | 547 | set_fs (KERNEL_DS); |
591 | err = sys_ioctl (fd, kcmd, (unsigned long)karg); | 548 | err = sys_ioctl (fd, kcmd, (unsigned long)karg); |
@@ -594,11 +551,11 @@ static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) | |||
594 | return err; | 551 | return err; |
595 | switch (cmd) { | 552 | switch (cmd) { |
596 | case MTIOCPOS32: | 553 | case MTIOCPOS32: |
597 | upos32 = compat_ptr(arg); | 554 | upos32 = argp; |
598 | err = __put_user(pos.mt_blkno, &upos32->mt_blkno); | 555 | err = __put_user(pos.mt_blkno, &upos32->mt_blkno); |
599 | break; | 556 | break; |
600 | case MTIOCGET32: | 557 | case MTIOCGET32: |
601 | umget32 = compat_ptr(arg); | 558 | umget32 = argp; |
602 | err = __put_user(get.mt_type, &umget32->mt_type); | 559 | err = __put_user(get.mt_type, &umget32->mt_type); |
603 | err |= __put_user(get.mt_resid, &umget32->mt_resid); | 560 | err |= __put_user(get.mt_resid, &umget32->mt_resid); |
604 | err |= __put_user(get.mt_dsreg, &umget32->mt_dsreg); | 561 | err |= __put_user(get.mt_dsreg, &umget32->mt_dsreg); |
@@ -613,7 +570,8 @@ static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) | |||
613 | 570 | ||
614 | #endif /* CONFIG_BLOCK */ | 571 | #endif /* CONFIG_BLOCK */ |
615 | 572 | ||
616 | static int do_smb_getmountuid(unsigned int fd, unsigned int cmd, unsigned long arg) | 573 | static int do_smb_getmountuid(unsigned int fd, unsigned int cmd, |
574 | compat_uid_t __user *argp) | ||
617 | { | 575 | { |
618 | mm_segment_t old_fs = get_fs(); | 576 | mm_segment_t old_fs = get_fs(); |
619 | __kernel_uid_t kuid; | 577 | __kernel_uid_t kuid; |
@@ -626,14 +584,15 @@ static int do_smb_getmountuid(unsigned int fd, unsigned int cmd, unsigned long a | |||
626 | set_fs(old_fs); | 584 | set_fs(old_fs); |
627 | 585 | ||
628 | if (err >= 0) | 586 | if (err >= 0) |
629 | err = put_user(kuid, (compat_uid_t __user *)compat_ptr(arg)); | 587 | err = put_user(kuid, argp); |
630 | 588 | ||
631 | return err; | 589 | return err; |
632 | } | 590 | } |
633 | 591 | ||
634 | static int ioc_settimeout(unsigned int fd, unsigned int cmd, unsigned long arg) | 592 | static int ioc_settimeout(unsigned int fd, unsigned int cmd, |
593 | compat_ulong_t __user *argp) | ||
635 | { | 594 | { |
636 | return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, arg); | 595 | return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, argp); |
637 | } | 596 | } |
638 | 597 | ||
639 | /* Bluetooth ioctls */ | 598 | /* Bluetooth ioctls */ |
@@ -691,7 +650,8 @@ static int set_raw32_request(struct raw_config_request *req, struct raw32_config | |||
691 | return ret ? -EFAULT : 0; | 650 | return ret ? -EFAULT : 0; |
692 | } | 651 | } |
693 | 652 | ||
694 | static int raw_ioctl(unsigned fd, unsigned cmd, unsigned long arg) | 653 | static int raw_ioctl(unsigned fd, unsigned cmd, |
654 | struct raw32_config_request __user *user_req) | ||
695 | { | 655 | { |
696 | int ret; | 656 | int ret; |
697 | 657 | ||
@@ -699,7 +659,6 @@ static int raw_ioctl(unsigned fd, unsigned cmd, unsigned long arg) | |||
699 | case RAW_SETBIND: | 659 | case RAW_SETBIND: |
700 | case RAW_GETBIND: { | 660 | case RAW_GETBIND: { |
701 | struct raw_config_request req; | 661 | struct raw_config_request req; |
702 | struct raw32_config_request __user *user_req = compat_ptr(arg); | ||
703 | mm_segment_t oldfs = get_fs(); | 662 | mm_segment_t oldfs = get_fs(); |
704 | 663 | ||
705 | if ((ret = get_raw32_request(&req, user_req))) | 664 | if ((ret = get_raw32_request(&req, user_req))) |
@@ -714,9 +673,6 @@ static int raw_ioctl(unsigned fd, unsigned cmd, unsigned long arg) | |||
714 | } | 673 | } |
715 | break; | 674 | break; |
716 | } | 675 | } |
717 | default: | ||
718 | ret = sys_ioctl(fd, cmd, arg); | ||
719 | break; | ||
720 | } | 676 | } |
721 | return ret; | 677 | return ret; |
722 | } | 678 | } |
@@ -744,11 +700,11 @@ struct serial_struct32 { | |||
744 | compat_int_t reserved[1]; | 700 | compat_int_t reserved[1]; |
745 | }; | 701 | }; |
746 | 702 | ||
747 | static int serial_struct_ioctl(unsigned fd, unsigned cmd, unsigned long arg) | 703 | static int serial_struct_ioctl(unsigned fd, unsigned cmd, |
704 | struct serial_struct32 __user *ss32) | ||
748 | { | 705 | { |
749 | typedef struct serial_struct SS; | 706 | typedef struct serial_struct SS; |
750 | typedef struct serial_struct32 SS32; | 707 | typedef struct serial_struct32 SS32; |
751 | struct serial_struct32 __user *ss32 = compat_ptr(arg); | ||
752 | int err; | 708 | int err; |
753 | struct serial_struct ss; | 709 | struct serial_struct ss; |
754 | mm_segment_t oldseg = get_fs(); | 710 | mm_segment_t oldseg = get_fs(); |
@@ -798,9 +754,9 @@ struct usbdevfs_ctrltransfer32 { | |||
798 | 754 | ||
799 | #define USBDEVFS_CONTROL32 _IOWR('U', 0, struct usbdevfs_ctrltransfer32) | 755 | #define USBDEVFS_CONTROL32 _IOWR('U', 0, struct usbdevfs_ctrltransfer32) |
800 | 756 | ||
801 | static int do_usbdevfs_control(unsigned int fd, unsigned int cmd, unsigned long arg) | 757 | static int do_usbdevfs_control(unsigned int fd, unsigned int cmd, |
758 | struct usbdevfs_ctrltransfer32 __user *p32) | ||
802 | { | 759 | { |
803 | struct usbdevfs_ctrltransfer32 __user *p32 = compat_ptr(arg); | ||
804 | struct usbdevfs_ctrltransfer __user *p; | 760 | struct usbdevfs_ctrltransfer __user *p; |
805 | __u32 udata; | 761 | __u32 udata; |
806 | p = compat_alloc_user_space(sizeof(*p)); | 762 | p = compat_alloc_user_space(sizeof(*p)); |
@@ -821,9 +777,9 @@ struct usbdevfs_bulktransfer32 { | |||
821 | 777 | ||
822 | #define USBDEVFS_BULK32 _IOWR('U', 2, struct usbdevfs_bulktransfer32) | 778 | #define USBDEVFS_BULK32 _IOWR('U', 2, struct usbdevfs_bulktransfer32) |
823 | 779 | ||
824 | static int do_usbdevfs_bulk(unsigned int fd, unsigned int cmd, unsigned long arg) | 780 | static int do_usbdevfs_bulk(unsigned int fd, unsigned int cmd, |
781 | struct usbdevfs_bulktransfer32 __user *p32) | ||
825 | { | 782 | { |
826 | struct usbdevfs_bulktransfer32 __user *p32 = compat_ptr(arg); | ||
827 | struct usbdevfs_bulktransfer __user *p; | 783 | struct usbdevfs_bulktransfer __user *p; |
828 | compat_uint_t n; | 784 | compat_uint_t n; |
829 | compat_caddr_t addr; | 785 | compat_caddr_t addr; |
@@ -852,16 +808,14 @@ struct usbdevfs_disconnectsignal32 { | |||
852 | 808 | ||
853 | #define USBDEVFS_DISCSIGNAL32 _IOR('U', 14, struct usbdevfs_disconnectsignal32) | 809 | #define USBDEVFS_DISCSIGNAL32 _IOR('U', 14, struct usbdevfs_disconnectsignal32) |
854 | 810 | ||
855 | static int do_usbdevfs_discsignal(unsigned int fd, unsigned int cmd, unsigned long arg) | 811 | static int do_usbdevfs_discsignal(unsigned int fd, unsigned int cmd, |
812 | struct usbdevfs_disconnectsignal32 __user *udis) | ||
856 | { | 813 | { |
857 | struct usbdevfs_disconnectsignal kdis; | 814 | struct usbdevfs_disconnectsignal kdis; |
858 | struct usbdevfs_disconnectsignal32 __user *udis; | ||
859 | mm_segment_t old_fs; | 815 | mm_segment_t old_fs; |
860 | u32 uctx; | 816 | u32 uctx; |
861 | int err; | 817 | int err; |
862 | 818 | ||
863 | udis = compat_ptr(arg); | ||
864 | |||
865 | if (get_user(kdis.signr, &udis->signr) || | 819 | if (get_user(kdis.signr, &udis->signr) || |
866 | __get_user(uctx, &udis->context)) | 820 | __get_user(uctx, &udis->context)) |
867 | return -EFAULT; | 821 | return -EFAULT; |
@@ -904,9 +858,9 @@ struct i2c_rdwr_aligned { | |||
904 | struct i2c_msg msgs[0]; | 858 | struct i2c_msg msgs[0]; |
905 | }; | 859 | }; |
906 | 860 | ||
907 | static int do_i2c_rdwr_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) | 861 | static int do_i2c_rdwr_ioctl(unsigned int fd, unsigned int cmd, |
862 | struct i2c_rdwr_ioctl_data32 __user *udata) | ||
908 | { | 863 | { |
909 | struct i2c_rdwr_ioctl_data32 __user *udata = compat_ptr(arg); | ||
910 | struct i2c_rdwr_aligned __user *tdata; | 864 | struct i2c_rdwr_aligned __user *tdata; |
911 | struct i2c_msg __user *tmsgs; | 865 | struct i2c_msg __user *tmsgs; |
912 | struct i2c_msg32 __user *umsgs; | 866 | struct i2c_msg32 __user *umsgs; |
@@ -940,10 +894,10 @@ static int do_i2c_rdwr_ioctl(unsigned int fd, unsigned int cmd, unsigned long ar | |||
940 | return sys_ioctl(fd, cmd, (unsigned long)tdata); | 894 | return sys_ioctl(fd, cmd, (unsigned long)tdata); |
941 | } | 895 | } |
942 | 896 | ||
943 | static int do_i2c_smbus_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) | 897 | static int do_i2c_smbus_ioctl(unsigned int fd, unsigned int cmd, |
898 | struct i2c_smbus_ioctl_data32 __user *udata) | ||
944 | { | 899 | { |
945 | struct i2c_smbus_ioctl_data __user *tdata; | 900 | struct i2c_smbus_ioctl_data __user *tdata; |
946 | struct i2c_smbus_ioctl_data32 __user *udata; | ||
947 | compat_caddr_t datap; | 901 | compat_caddr_t datap; |
948 | 902 | ||
949 | tdata = compat_alloc_user_space(sizeof(*tdata)); | 903 | tdata = compat_alloc_user_space(sizeof(*tdata)); |
@@ -952,7 +906,6 @@ static int do_i2c_smbus_ioctl(unsigned int fd, unsigned int cmd, unsigned long a | |||
952 | if (!access_ok(VERIFY_WRITE, tdata, sizeof(*tdata))) | 906 | if (!access_ok(VERIFY_WRITE, tdata, sizeof(*tdata))) |
953 | return -EFAULT; | 907 | return -EFAULT; |
954 | 908 | ||
955 | udata = compat_ptr(arg); | ||
956 | if (!access_ok(VERIFY_READ, udata, sizeof(*udata))) | 909 | if (!access_ok(VERIFY_READ, udata, sizeof(*udata))) |
957 | return -EFAULT; | 910 | return -EFAULT; |
958 | 911 | ||
@@ -972,7 +925,7 @@ static int do_i2c_smbus_ioctl(unsigned int fd, unsigned int cmd, unsigned long a | |||
972 | #define RTC_EPOCH_READ32 _IOR('p', 0x0d, compat_ulong_t) | 925 | #define RTC_EPOCH_READ32 _IOR('p', 0x0d, compat_ulong_t) |
973 | #define RTC_EPOCH_SET32 _IOW('p', 0x0e, compat_ulong_t) | 926 | #define RTC_EPOCH_SET32 _IOW('p', 0x0e, compat_ulong_t) |
974 | 927 | ||
975 | static int rtc_ioctl(unsigned fd, unsigned cmd, unsigned long arg) | 928 | static int rtc_ioctl(unsigned fd, unsigned cmd, void __user *argp) |
976 | { | 929 | { |
977 | mm_segment_t oldfs = get_fs(); | 930 | mm_segment_t oldfs = get_fs(); |
978 | compat_ulong_t val32; | 931 | compat_ulong_t val32; |
@@ -990,21 +943,20 @@ static int rtc_ioctl(unsigned fd, unsigned cmd, unsigned long arg) | |||
990 | if (ret) | 943 | if (ret) |
991 | return ret; | 944 | return ret; |
992 | val32 = kval; | 945 | val32 = kval; |
993 | return put_user(val32, (unsigned int __user *)arg); | 946 | return put_user(val32, (unsigned int __user *)argp); |
994 | case RTC_IRQP_SET32: | 947 | case RTC_IRQP_SET32: |
995 | return sys_ioctl(fd, RTC_IRQP_SET, arg); | 948 | return sys_ioctl(fd, RTC_IRQP_SET, (unsigned long)argp); |
996 | case RTC_EPOCH_SET32: | 949 | case RTC_EPOCH_SET32: |
997 | return sys_ioctl(fd, RTC_EPOCH_SET, arg); | 950 | return sys_ioctl(fd, RTC_EPOCH_SET, (unsigned long)argp); |
998 | default: | ||
999 | /* unreached */ | ||
1000 | return -ENOIOCTLCMD; | ||
1001 | } | 951 | } |
952 | |||
953 | return -ENOIOCTLCMD; | ||
1002 | } | 954 | } |
1003 | 955 | ||
1004 | static int | 956 | static int |
1005 | lp_timeout_trans(unsigned int fd, unsigned int cmd, unsigned long arg) | 957 | lp_timeout_trans(unsigned int fd, unsigned int cmd, |
958 | struct compat_timeval __user *tc) | ||
1006 | { | 959 | { |
1007 | struct compat_timeval __user *tc = (struct compat_timeval __user *)arg; | ||
1008 | struct timeval __user *tn = compat_alloc_user_space(sizeof(struct timeval)); | 960 | struct timeval __user *tn = compat_alloc_user_space(sizeof(struct timeval)); |
1009 | struct timeval ts; | 961 | struct timeval ts; |
1010 | if (get_user(ts.tv_sec, &tc->tv_sec) || | 962 | if (get_user(ts.tv_sec, &tc->tv_sec) || |
@@ -1032,9 +984,9 @@ struct space_resv_32 { | |||
1032 | #define FS_IOC_RESVSP64_32 _IOW ('X', 42, struct space_resv_32) | 984 | #define FS_IOC_RESVSP64_32 _IOW ('X', 42, struct space_resv_32) |
1033 | 985 | ||
1034 | /* just account for different alignment */ | 986 | /* just account for different alignment */ |
1035 | static int compat_ioctl_preallocate(struct file *file, unsigned long arg) | 987 | static int compat_ioctl_preallocate(struct file *file, |
988 | struct space_resv_32 __user *p32) | ||
1036 | { | 989 | { |
1037 | struct space_resv_32 __user *p32 = compat_ptr(arg); | ||
1038 | struct space_resv __user *p = compat_alloc_user_space(sizeof(*p)); | 990 | struct space_resv __user *p = compat_alloc_user_space(sizeof(*p)); |
1039 | 991 | ||
1040 | if (copy_in_user(&p->l_type, &p32->l_type, sizeof(s16)) || | 992 | if (copy_in_user(&p->l_type, &p32->l_type, sizeof(s16)) || |
@@ -1720,69 +1672,72 @@ IGNORE_IOCTL(FBIOGCURSOR32) | |||
1720 | static long do_ioctl_trans(int fd, unsigned int cmd, | 1672 | static long do_ioctl_trans(int fd, unsigned int cmd, |
1721 | unsigned long arg, struct file *file) | 1673 | unsigned long arg, struct file *file) |
1722 | { | 1674 | { |
1675 | void __user *argp = compat_ptr(arg); | ||
1676 | |||
1723 | switch (cmd) { | 1677 | switch (cmd) { |
1724 | case PPPIOCGIDLE32: | 1678 | case PPPIOCGIDLE32: |
1679 | return ppp_gidle(fd, cmd, argp); | ||
1725 | case PPPIOCSCOMPRESS32: | 1680 | case PPPIOCSCOMPRESS32: |
1726 | return ppp_ioctl_trans(fd, cmd, arg); | 1681 | return ppp_scompress(fd, cmd, argp); |
1727 | case PPPIOCSPASS32: | 1682 | case PPPIOCSPASS32: |
1728 | case PPPIOCSACTIVE32: | 1683 | case PPPIOCSACTIVE32: |
1729 | return ppp_sock_fprog_ioctl_trans(fd, cmd, arg); | 1684 | return ppp_sock_fprog_ioctl_trans(fd, cmd, argp); |
1730 | #ifdef CONFIG_BLOCK | 1685 | #ifdef CONFIG_BLOCK |
1731 | case SG_IO: | 1686 | case SG_IO: |
1732 | return sg_ioctl_trans(fd, cmd, arg); | 1687 | return sg_ioctl_trans(fd, cmd, argp); |
1733 | case SG_GET_REQUEST_TABLE: | 1688 | case SG_GET_REQUEST_TABLE: |
1734 | return sg_grt_trans(fd, cmd, arg); | 1689 | return sg_grt_trans(fd, cmd, argp); |
1735 | case MTIOCGET32: | 1690 | case MTIOCGET32: |
1736 | case MTIOCPOS32: | 1691 | case MTIOCPOS32: |
1737 | return mt_ioctl_trans(fd, cmd, arg); | 1692 | return mt_ioctl_trans(fd, cmd, argp); |
1738 | /* Raw devices */ | 1693 | /* Raw devices */ |
1739 | case RAW_SETBIND: | 1694 | case RAW_SETBIND: |
1740 | case RAW_GETBIND: | 1695 | case RAW_GETBIND: |
1741 | return raw_ioctl(fd, cmd, arg); | 1696 | return raw_ioctl(fd, cmd, argp); |
1742 | #endif | 1697 | #endif |
1743 | #define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int) | 1698 | #define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int) |
1744 | case AUTOFS_IOC_SETTIMEOUT32: | 1699 | case AUTOFS_IOC_SETTIMEOUT32: |
1745 | return ioc_settimeout(fd, cmd, arg); | 1700 | return ioc_settimeout(fd, cmd, argp); |
1746 | /* One SMB ioctl needs translations. */ | 1701 | /* One SMB ioctl needs translations. */ |
1747 | #define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_uid_t) | 1702 | #define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_uid_t) |
1748 | case SMB_IOC_GETMOUNTUID_32: | 1703 | case SMB_IOC_GETMOUNTUID_32: |
1749 | return do_smb_getmountuid(fd, cmd, arg); | 1704 | return do_smb_getmountuid(fd, cmd, argp); |
1750 | /* Serial */ | 1705 | /* Serial */ |
1751 | case TIOCGSERIAL: | 1706 | case TIOCGSERIAL: |
1752 | case TIOCSSERIAL: | 1707 | case TIOCSSERIAL: |
1753 | return serial_struct_ioctl(fd, cmd, arg); | 1708 | return serial_struct_ioctl(fd, cmd, argp); |
1754 | /* Usbdevfs */ | 1709 | /* Usbdevfs */ |
1755 | case USBDEVFS_CONTROL32: | 1710 | case USBDEVFS_CONTROL32: |
1756 | return do_usbdevfs_control(fd, cmd, arg); | 1711 | return do_usbdevfs_control(fd, cmd, argp); |
1757 | case USBDEVFS_BULK32: | 1712 | case USBDEVFS_BULK32: |
1758 | return do_usbdevfs_bulk(fd, cmd, arg); | 1713 | return do_usbdevfs_bulk(fd, cmd, argp); |
1759 | case USBDEVFS_DISCSIGNAL32: | 1714 | case USBDEVFS_DISCSIGNAL32: |
1760 | return do_usbdevfs_discsignal(fd, cmd, arg); | 1715 | return do_usbdevfs_discsignal(fd, cmd, argp); |
1761 | /* i2c */ | 1716 | /* i2c */ |
1762 | case I2C_FUNCS: | 1717 | case I2C_FUNCS: |
1763 | return w_long(fd, cmd, arg); | 1718 | return w_long(fd, cmd, argp); |
1764 | case I2C_RDWR: | 1719 | case I2C_RDWR: |
1765 | return do_i2c_rdwr_ioctl(fd, cmd, arg); | 1720 | return do_i2c_rdwr_ioctl(fd, cmd, argp); |
1766 | case I2C_SMBUS: | 1721 | case I2C_SMBUS: |
1767 | return do_i2c_smbus_ioctl(fd, cmd, arg); | 1722 | return do_i2c_smbus_ioctl(fd, cmd, argp); |
1768 | /* Not implemented in the native kernel */ | 1723 | /* Not implemented in the native kernel */ |
1769 | case RTC_IRQP_READ32: | 1724 | case RTC_IRQP_READ32: |
1770 | case RTC_IRQP_SET32: | 1725 | case RTC_IRQP_SET32: |
1771 | case RTC_EPOCH_READ32: | 1726 | case RTC_EPOCH_READ32: |
1772 | case RTC_EPOCH_SET32: | 1727 | case RTC_EPOCH_SET32: |
1773 | return rtc_ioctl(fd, cmd, arg); | 1728 | return rtc_ioctl(fd, cmd, argp); |
1774 | 1729 | ||
1775 | /* dvb */ | 1730 | /* dvb */ |
1776 | case VIDEO_GET_EVENT: | 1731 | case VIDEO_GET_EVENT: |
1777 | return do_video_get_event(fd, cmd, arg); | 1732 | return do_video_get_event(fd, cmd, argp); |
1778 | case VIDEO_STILLPICTURE: | 1733 | case VIDEO_STILLPICTURE: |
1779 | return do_video_stillpicture(fd, cmd, arg); | 1734 | return do_video_stillpicture(fd, cmd, argp); |
1780 | case VIDEO_SET_SPU_PALETTE: | 1735 | case VIDEO_SET_SPU_PALETTE: |
1781 | return do_video_set_spu_palette(fd, cmd, arg); | 1736 | return do_video_set_spu_palette(fd, cmd, argp); |
1782 | 1737 | ||
1783 | /* lp */ | 1738 | /* lp */ |
1784 | case LPSETTIMEOUT: | 1739 | case LPSETTIMEOUT: |
1785 | return lp_timeout_trans(fd, cmd, arg); | 1740 | return lp_timeout_trans(fd, cmd, argp); |
1786 | } | 1741 | } |
1787 | 1742 | ||
1788 | /* | 1743 | /* |
@@ -1907,7 +1862,7 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, | |||
1907 | #if defined(CONFIG_IA64) || defined(CONFIG_X86_64) | 1862 | #if defined(CONFIG_IA64) || defined(CONFIG_X86_64) |
1908 | case FS_IOC_RESVSP_32: | 1863 | case FS_IOC_RESVSP_32: |
1909 | case FS_IOC_RESVSP64_32: | 1864 | case FS_IOC_RESVSP64_32: |
1910 | error = compat_ioctl_preallocate(filp, arg); | 1865 | error = compat_ioctl_preallocate(filp, compat_ptr(arg)); |
1911 | goto out_fput; | 1866 | goto out_fput; |
1912 | #else | 1867 | #else |
1913 | case FS_IOC_RESVSP: | 1868 | case FS_IOC_RESVSP: |