aboutsummaryrefslogtreecommitdiffstats
path: root/fs/compat_ioctl.c
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2009-11-14 17:16:18 -0500
committerArnd Bergmann <arnd@arndb.de>2009-12-10 16:52:12 -0500
commit43c6e7b97f9ea0f4dec430dbafb6afa6ac711eb1 (patch)
treec85cec4232ba702d97adfe3b0db721fe2fe13a2c /fs/compat_ioctl.c
parent661f627da98c0647bcc002ef35e5441fb3ce667c (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.c211
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
120static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg) 120static 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
134static int rw_long(unsigned int fd, unsigned int cmd, unsigned long arg) 135static 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
160static int do_video_get_event(unsigned int fd, unsigned int cmd, unsigned long arg) 161static 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
191static int do_video_stillpicture(unsigned int fd, unsigned int cmd, unsigned long arg) 191static 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
223static int do_video_set_spu_palette(unsigned int fd, unsigned int cmd, unsigned long arg) 222static 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
298static int sg_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) 296static 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
397static int sg_grt_trans(unsigned int fd, unsigned int cmd, unsigned long arg) 394static 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
429static int ppp_sock_fprog_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) 426static 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
468static int ppp_gidle(unsigned int fd, unsigned int cmd, unsigned long arg) 465static 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
490static int ppp_scompress(unsigned int fd, unsigned int cmd, unsigned long arg) 486static 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
514static 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
544struct mtget32 { 510struct 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
560static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) 526static 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
616static int do_smb_getmountuid(unsigned int fd, unsigned int cmd, unsigned long arg) 573static 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
634static int ioc_settimeout(unsigned int fd, unsigned int cmd, unsigned long arg) 592static 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
694static int raw_ioctl(unsigned fd, unsigned cmd, unsigned long arg) 653static 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
747static int serial_struct_ioctl(unsigned fd, unsigned cmd, unsigned long arg) 703static 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
801static int do_usbdevfs_control(unsigned int fd, unsigned int cmd, unsigned long arg) 757static 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
824static int do_usbdevfs_bulk(unsigned int fd, unsigned int cmd, unsigned long arg) 780static 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
855static int do_usbdevfs_discsignal(unsigned int fd, unsigned int cmd, unsigned long arg) 811static 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
907static int do_i2c_rdwr_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) 861static 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
943static int do_i2c_smbus_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) 897static 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
975static int rtc_ioctl(unsigned fd, unsigned cmd, unsigned long arg) 928static 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
1004static int 956static int
1005lp_timeout_trans(unsigned int fd, unsigned int cmd, unsigned long arg) 957lp_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 */
1035static int compat_ioctl_preallocate(struct file *file, unsigned long arg) 987static 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)
1720static long do_ioctl_trans(int fd, unsigned int cmd, 1672static 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: