From: Martin Schwidefsky - audit all 32 bit pointer accesses and make them use compat_ioctl(), because of the necessary conversion on s390 - introduce ULONG_IOCTL() which is used instead of COMPATIBLE_IOCTL() for all ioctls that have their argument encoded in 'arg' instead of the memory pointed to by arg. Same reason as above. - remove most #ifdefs in : They don't make any sense if the respective handlers in fs/compat_ioctl.c are not disabled as well and they are potentially harmful (the CONFIG_BLK_DEV_DM e.g. was insufficient). - comment out COMPATIBLE_IOCTL(SIOCSIFBR) and COMPATIBLE_IOCTL(SIOCGIFBR), they appear to require a handler - implement copy_in_user for s390, as needed for many handlers in fs/compat_ioctl.c - get rid of all duplicate stuff in arch/s390/kernel/compat_ioctl.c that is also in fs/compat_ioctl.c --- arch/s390/kernel/compat_ioctl.c | 891 +--------------------------------------- arch/s390/lib/uaccess.S | 35 + arch/s390/lib/uaccess64.S | 35 + fs/compat_ioctl.c | 480 +++++++++++---------- include/asm-s390/uaccess.h | 23 - include/linux/compat_ioctl.h | 104 ++-- 6 files changed, 425 insertions(+), 1143 deletions(-) diff -puN arch/s390/kernel/compat_ioctl.c~s390-10-32-bit-ioctl-emulation-fixes arch/s390/kernel/compat_ioctl.c --- 25/arch/s390/kernel/compat_ioctl.c~s390-10-32-bit-ioctl-emulation-fixes 2004-01-09 10:58:33.000000000 -0800 +++ 25-akpm/arch/s390/kernel/compat_ioctl.c 2004-01-09 10:58:33.000000000 -0800 @@ -2,818 +2,46 @@ * ioctl32.c: Conversion between 32bit and 64bit native ioctls. * * S390 version - * Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation + * Copyright (C) 2000-2003 IBM Deutschland Entwicklung GmbH, IBM Corporation * Author(s): Gerhard Tonn (ton@de.ibm.com) + * Arnd Bergmann (arndb@de.ibm.com) * - * Heavily inspired by the 32-bit Sparc compat code which is + * Original implementation from 32-bit Sparc compat code which is * Copyright (C) 2000 Silicon Graphics, Inc. * Written by Ulf Carlsson (ulfc@engr.sgi.com) - * */ -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - +#include "compat_linux.h" +#define INCLUDES +#define CODE +#include "../../../fs/compat_ioctl.c" #include -#include #include -#include "compat_linux.h" - -long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg); - -struct hd_geometry32 { - unsigned char heads; - unsigned char sectors; - unsigned short cylinders; - __u32 start; -}; - -static inline int hd_geometry_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg, - struct file *f) -{ - struct hd_geometry32 *hg32 = (struct hd_geometry32 *) A(arg); - struct hd_geometry hg; - int ret; - mm_segment_t old_fs = get_fs(); - - set_fs (KERNEL_DS); - ret = sys_ioctl (fd, cmd, (long)&hg); - set_fs (old_fs); - - if (ret) - return ret; - - ret = put_user (hg.heads, &(hg32->heads)); - ret |= __put_user (hg.sectors, &(hg32->sectors)); - ret |= __put_user (hg.cylinders, &(hg32->cylinders)); - ret |= __put_user (hg.start, &(hg32->start)); - - return ret; -} - -#define EXT2_IOC32_GETFLAGS _IOR('f', 1, int) -#define EXT2_IOC32_SETFLAGS _IOW('f', 2, int) -#define EXT2_IOC32_GETVERSION _IOR('v', 1, int) -#define EXT2_IOC32_SETVERSION _IOW('v', 2, int) - -struct ifmap32 { - unsigned int mem_start; - unsigned int mem_end; - unsigned short base_addr; - unsigned char irq; - unsigned char dma; - unsigned char port; -}; - -struct ifreq32 { -#define IFHWADDRLEN 6 -#define IFNAMSIZ 16 - union { - char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */ - } ifr_ifrn; - union { - struct sockaddr ifru_addr; - struct sockaddr ifru_dstaddr; - struct sockaddr ifru_broadaddr; - struct sockaddr ifru_netmask; - struct sockaddr ifru_hwaddr; - short ifru_flags; - int ifru_ivalue; - int ifru_mtu; - struct ifmap32 ifru_map; - char ifru_slave[IFNAMSIZ]; /* Just fits the size */ - char ifru_newname[IFNAMSIZ]; - __u32 ifru_data; - } ifr_ifru; -}; - -struct ifconf32 { - int ifc_len; /* size of buffer */ - __u32 ifcbuf; -}; - -static int dev_ifname32(unsigned int fd, unsigned int cmd, - unsigned long arg, struct file *f) -{ - struct ireq32 *uir32 = (struct ireq32 *) A(arg); - struct net_device *dev; - struct ifreq32 ifr32; - - if (copy_from_user(&ifr32, uir32, sizeof(struct ifreq32))) - return -EFAULT; - - read_lock(&dev_base_lock); - dev = __dev_get_by_index(ifr32.ifr_ifindex); - if (!dev) { - read_unlock(&dev_base_lock); - return -ENODEV; - } - - strcpy(ifr32.ifr_name, dev->name); - read_unlock(&dev_base_lock); - - if (copy_to_user(uir32, &ifr32, sizeof(struct ifreq32))) - return -EFAULT; - - return 0; -} - -static int dev_ifconf(unsigned int fd, unsigned int cmd, - unsigned long arg, struct file *f) -{ - struct ioconf32 *uifc32 = (struct ioconf32 *) A(arg); - struct ifconf32 ifc32; - struct ifconf ifc; - struct ifreq32 *ifr32; - struct ifreq *ifr; - mm_segment_t old_fs; - int len; - int err; - - if (copy_from_user(&ifc32, uifc32, sizeof(struct ifconf32))) - return -EFAULT; - - if(ifc32.ifcbuf == 0) { - ifc32.ifc_len = 0; - ifc.ifc_len = 0; - ifc.ifc_buf = NULL; - } else { - ifc.ifc_len = ((ifc32.ifc_len / sizeof (struct ifreq32))) * - sizeof (struct ifreq); - ifc.ifc_buf = kmalloc (ifc.ifc_len, GFP_KERNEL); - if (!ifc.ifc_buf) - return -ENOMEM; - } - ifr = ifc.ifc_req; - ifr32 = (struct ifreq32 *) A(ifc32.ifcbuf); - len = ifc32.ifc_len / sizeof (struct ifreq32); - while (len--) { - if (copy_from_user(ifr++, ifr32++, sizeof (struct ifreq32))) { - err = -EFAULT; - goto out; - } - } - - old_fs = get_fs(); - set_fs (KERNEL_DS); - err = sys_ioctl (fd, SIOCGIFCONF, (unsigned long)&ifc); - set_fs (old_fs); - if (err) - goto out; - - ifr = ifc.ifc_req; - ifr32 = (struct ifreq32 *) A(ifc32.ifcbuf); - len = ifc.ifc_len / sizeof (struct ifreq); - ifc32.ifc_len = len * sizeof (struct ifreq32); - - while (len--) { - if (copy_to_user(ifr32++, ifr++, sizeof (struct ifreq32))) { - err = -EFAULT; - goto out; - } - } - - if (copy_to_user(uifc32, &ifc32, sizeof(struct ifconf32))) { - err = -EFAULT; - goto out; - } -out: - if(ifc.ifc_buf != NULL) - kfree (ifc.ifc_buf); - return err; -} - -static int bond_ioctl(unsigned int fd, unsigned int cmd, - unsigned long arg, struct file *f) -{ - struct ifreq ifr; - mm_segment_t old_fs; - int err, len; - u32 data; - - if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32))) - return -EFAULT; - ifr.ifr_data = (__kernel_caddr_t)get_zeroed_page(GFP_KERNEL); - if (!ifr.ifr_data) - return -EAGAIN; - - switch (cmd) { - case SIOCBONDENSLAVE: - case SIOCBONDRELEASE: - case SIOCBONDSETHWADDR: - case SIOCBONDCHANGEACTIVE: - len = IFNAMSIZ * sizeof(char); - break; - case SIOCBONDSLAVEINFOQUERY: - len = sizeof(struct ifslave); - break; - case SIOCBONDINFOQUERY: - len = sizeof(struct ifbond); - break; - default: - err = -EINVAL; - goto out; - }; - - __get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data)); - if (copy_from_user(ifr.ifr_data, (char *)A(data), len)) { - err = -EFAULT; - goto out; - } - - old_fs = get_fs(); - set_fs (KERNEL_DS); - err = sys_ioctl (fd, cmd, (unsigned long)&ifr); - set_fs (old_fs); - if (!err) { - len = copy_to_user((char *)A(data), ifr.ifr_data, len); - if (len) - err = -EFAULT; - } - -out: - free_page((unsigned long)ifr.ifr_data); - return err; -} - -static int dev_ifsioc(unsigned int fd, unsigned int cmd, - unsigned long arg, struct file *f) +static int do_ioctl32_pointer(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *f) { - struct ifreq32 *uifr = (struct ifreq32 *) A(arg); - struct ifreq ifr; - mm_segment_t old_fs; - int err; - - switch (cmd) { - case SIOCSIFMAP: - err = copy_from_user(&ifr, uifr, sizeof(ifr.ifr_name)); - err |= __get_user(ifr.ifr_map.mem_start, &(uifr->ifr_ifru.ifru_map.mem_start)); - err |= __get_user(ifr.ifr_map.mem_end, &(uifr->ifr_ifru.ifru_map.mem_end)); - err |= __get_user(ifr.ifr_map.base_addr, &(uifr->ifr_ifru.ifru_map.base_addr)); - err |= __get_user(ifr.ifr_map.irq, &(uifr->ifr_ifru.ifru_map.irq)); - err |= __get_user(ifr.ifr_map.dma, &(uifr->ifr_ifru.ifru_map.dma)); - err |= __get_user(ifr.ifr_map.port, &(uifr->ifr_ifru.ifru_map.port)); - if (err) - return -EFAULT; - break; - default: - if (copy_from_user(&ifr, uifr, sizeof(struct ifreq32))) - return -EFAULT; - break; - } - old_fs = get_fs(); - set_fs (KERNEL_DS); - err = sys_ioctl (fd, cmd, (unsigned long)&ifr); - set_fs (old_fs); - if (!err) { - switch (cmd) { - case SIOCGIFFLAGS: - case SIOCGIFMETRIC: - case SIOCGIFMTU: - case SIOCGIFMEM: - case SIOCGIFHWADDR: - case SIOCGIFINDEX: - case SIOCGIFADDR: - case SIOCGIFBRDADDR: - case SIOCGIFDSTADDR: - case SIOCGIFNETMASK: - case SIOCGIFTXQLEN: - if (copy_to_user(uifr, &ifr, sizeof(struct ifreq32))) - return -EFAULT; - break; - case SIOCGIFMAP: - err = copy_to_user(uifr, &ifr, sizeof(ifr.ifr_name)); - err |= __put_user(ifr.ifr_map.mem_start, &(uifr->ifr_ifru.ifru_map.mem_start)); - err |= __put_user(ifr.ifr_map.mem_end, &(uifr->ifr_ifru.ifru_map.mem_end)); - err |= __put_user(ifr.ifr_map.base_addr, &(uifr->ifr_ifru.ifru_map.base_addr)); - err |= __put_user(ifr.ifr_map.irq, &(uifr->ifr_ifru.ifru_map.irq)); - err |= __put_user(ifr.ifr_map.dma, &(uifr->ifr_ifru.ifru_map.dma)); - err |= __put_user(ifr.ifr_map.port, &(uifr->ifr_ifru.ifru_map.port)); - if (err) - err = -EFAULT; - break; - } - } - return err; + return sys_ioctl(fd, cmd, (unsigned long)compat_ptr(arg)); } -struct rtentry32 -{ - unsigned int rt_pad1; - struct sockaddr rt_dst; /* target address */ - struct sockaddr rt_gateway; /* gateway addr (RTF_GATEWAY) */ - struct sockaddr rt_genmask; /* target network mask (IP) */ - unsigned short rt_flags; - short rt_pad2; - unsigned int rt_pad3; - unsigned int rt_pad4; - short rt_metric; /* +1 for binary compatibility! */ - unsigned int rt_dev; /* forcing the device at add */ - unsigned int rt_mtu; /* per route MTU/Window */ -#ifndef __KERNEL__ -#define rt_mss rt_mtu /* Compatibility :-( */ -#endif - unsigned int rt_window; /* Window clamping */ - unsigned short rt_irtt; /* Initial RTT */ -}; - -static int routing_ioctl(unsigned int fd, unsigned int cmd, - unsigned long arg, struct file *f) +static int do_ioctl32_ulong(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *f) { - struct rtentry32 *ur = (struct rtentry32 *) A(arg); - struct rtentry r; - char devname[16]; - u32 rtdev; - int ret; - mm_segment_t old_fs = get_fs(); - - ret = copy_from_user (&r.rt_dst, &(ur->rt_dst), 3 * sizeof(struct sockaddr)); - ret |= __get_user (r.rt_flags, &(ur->rt_flags)); - ret |= __get_user (r.rt_metric, &(ur->rt_metric)); - ret |= __get_user (r.rt_mtu, &(ur->rt_mtu)); - ret |= __get_user (r.rt_window, &(ur->rt_window)); - ret |= __get_user (r.rt_irtt, &(ur->rt_irtt)); - ret |= __get_user (rtdev, &(ur->rt_dev)); - if (rtdev) { - ret |= copy_from_user (devname, (char *) A(rtdev), 15); - r.rt_dev = devname; devname[15] = 0; - } else - r.rt_dev = 0; - if (ret) - return -EFAULT; - set_fs (KERNEL_DS); - ret = sys_ioctl (fd, cmd, (long)&r); - set_fs (old_fs); - return ret; -} - -static int do_ext2_ioctl(unsigned int fd, unsigned int cmd, - unsigned long arg, struct file *f) -{ - /* These are just misnamed, they actually get/put from/to user an int */ - switch (cmd) { - case EXT2_IOC32_GETFLAGS: cmd = EXT2_IOC_GETFLAGS; break; - case EXT2_IOC32_SETFLAGS: cmd = EXT2_IOC_SETFLAGS; break; - case EXT2_IOC32_GETVERSION: cmd = EXT2_IOC_GETVERSION; break; - case EXT2_IOC32_SETVERSION: cmd = EXT2_IOC_SETVERSION; break; - } return sys_ioctl(fd, cmd, arg); } +#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL((cmd),(ioctl_trans_handler_t)do_ioctl32_pointer) +#define ULONG_IOCTL(cmd) HANDLE_IOCTL((cmd),(ioctl_trans_handler_t)do_ioctl32_ulong) +#define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl_trans_handler_t)(handler), NULL }, -struct loop_info32 { - int lo_number; /* ioctl r/o */ - compat_dev_t lo_device; /* ioctl r/o */ - unsigned int lo_inode; /* ioctl r/o */ - compat_dev_t lo_rdevice; /* ioctl r/o */ - int lo_offset; - int lo_encrypt_type; - int lo_encrypt_key_size; /* ioctl w/o */ - int lo_flags; /* ioctl r/o */ - char lo_name[LO_NAME_SIZE]; - unsigned char lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */ - unsigned int lo_init[2]; - char reserved[4]; -}; - -static int loop_status(unsigned int fd, unsigned int cmd, - unsigned long arg, struct file *f) -{ - mm_segment_t old_fs = get_fs(); - struct loop_info l; - int err = -EINVAL; - - switch(cmd) { - case LOOP_SET_STATUS: - err = get_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number); - err |= __get_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device); - err |= __get_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode); - err |= __get_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice); - err |= __copy_from_user((char *)&l.lo_offset, (char *)&((struct loop_info32 *)arg)->lo_offset, - 8 + (unsigned long)l.lo_init - (unsigned long)&l.lo_offset); - if (err) { - err = -EFAULT; - } else { - set_fs (KERNEL_DS); - err = sys_ioctl (fd, cmd, (unsigned long)&l); - set_fs (old_fs); - } - break; - case LOOP_GET_STATUS: - set_fs (KERNEL_DS); - err = sys_ioctl (fd, cmd, (unsigned long)&l); - set_fs (old_fs); - if (!err) { - err = put_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number); - err |= __put_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device); - err |= __put_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode); - err |= __put_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice); - err |= __copy_to_user((char *)&((struct loop_info32 *)arg)->lo_offset, - (char *)&l.lo_offset, (unsigned long)l.lo_init - (unsigned long)&l.lo_offset); - if (err) - err = -EFAULT; - } - break; - default: { - static int count = 0; - if (++count <= 20) - printk("%s: Unknown loop ioctl cmd, fd(%d) " - "cmd(%08x) arg(%08lx)\n", - __FUNCTION__, fd, cmd, arg); - } - } - return err; -} - - -struct blkpg_ioctl_arg32 { - int op; - int flags; - int datalen; - u32 data; -}; - -static int blkpg_ioctl_trans(unsigned int fd, unsigned int cmd, - unsigned long uarg, struct file *f) -{ - struct blkpg_ioctl_arg a; - struct blkpg_partition p; - struct blkpg_ioctl_arg32 *arg = (void*)A(uarg); - int err; - mm_segment_t old_fs = get_fs(); - - err = get_user(a.op, &arg->op); - err |= __get_user(a.flags, &arg->flags); - err |= __get_user(a.datalen, &arg->datalen); - err |= __get_user((long)a.data, &arg->data); - if (err) return err; - switch (a.op) { - case BLKPG_ADD_PARTITION: - case BLKPG_DEL_PARTITION: - if (a.datalen < sizeof(struct blkpg_partition)) - return -EINVAL; - if (copy_from_user(&p, a.data, sizeof(struct blkpg_partition))) - return -EFAULT; - a.data = &p; - set_fs (KERNEL_DS); - err = sys_ioctl(fd, cmd, (unsigned long)&a); - set_fs (old_fs); - default: - return -EINVAL; - } - return err; -} - - -typedef struct ica_z90_status_t { - int totalcount; - int leedslitecount; - int leeds2count; - int requestqWaitCount; - int pendingqWaitCount; - int totalOpenCount; - int cryptoDomain; - unsigned char status[64]; - unsigned char qdepth[64]; -} ica_z90_status; - -typedef struct _ica_rsa_modexpo { - char *inputdata; - unsigned int inputdatalength; - char *outputdata; - unsigned int outputdatalength; - char *b_key; - char *n_modulus; -} ica_rsa_modexpo_t; - -typedef struct _ica_rsa_modexpo_32 { - u32 inputdata; - u32 inputdatalength; - u32 outputdata; - u32 outputdatalength; - u32 b_key; - u32 n_modulus; -} ica_rsa_modexpo_32_t; - -typedef struct _ica_rsa_modexpo_crt { - char *inputdata; - unsigned int inputdatalength; - char *outputdata; - unsigned int outputdatalength; - char *bp_key; - char *bq_key; - char *np_prime; - char *nq_prime; - char *u_mult_inv; -} ica_rsa_modexpo_crt_t; - -typedef struct _ica_rsa_modexpo_crt_32 { - u32 inputdata; - u32 inputdatalength; - u32 outputdata; - u32 outputdatalength; - u32 bp_key; - u32 bq_key; - u32 np_prime; - u32 nq_prime; - u32 u_mult_inv; -} ica_rsa_modexpo_crt_32_t; - -#define ICA_IOCTL_MAGIC 'z' -#define ICARSAMODEXPO _IOC(_IOC_READ|_IOC_WRITE, ICA_IOCTL_MAGIC, 0x05, 0) -#define ICARSACRT _IOC(_IOC_READ|_IOC_WRITE, ICA_IOCTL_MAGIC, 0x06, 0) -#define ICARSAMODMULT _IOC(_IOC_READ|_IOC_WRITE, ICA_IOCTL_MAGIC, 0x07, 0) -#define ICAZ90STATUS _IOC(_IOC_READ, ICA_IOCTL_MAGIC, 0x10, sizeof(ica_z90_status)) -#define ICAZ90QUIESCE _IOC(_IOC_NONE, ICA_IOCTL_MAGIC, 0x11, 0) -#define ICAZ90HARDRESET _IOC(_IOC_NONE, ICA_IOCTL_MAGIC, 0x12, 0) -#define ICAZ90HARDERROR _IOC(_IOC_NONE, ICA_IOCTL_MAGIC, 0x13, 0) - -static int do_rsa_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *f) -{ - mm_segment_t old_fs = get_fs(); - int err = 0; - ica_rsa_modexpo_t rsa; - ica_rsa_modexpo_32_t *rsa32 = (ica_rsa_modexpo_32_t *)arg; - u32 inputdata, outputdata, b_key, n_modulus; - - memset (&rsa, 0, sizeof(rsa)); - - err |= __get_user (inputdata, &rsa32->inputdata); - err |= __get_user (rsa.inputdatalength, &rsa32->inputdatalength); - err |= __get_user (outputdata, &rsa32->outputdata); - err |= __get_user (rsa.outputdatalength, &rsa32->outputdatalength); - err |= __get_user (b_key, &rsa32->b_key); - err |= __get_user (n_modulus, &rsa32->n_modulus); - if (err) - return -EFAULT; - - rsa.inputdata = (char *)kmalloc(rsa.inputdatalength, GFP_KERNEL); - if (!rsa.inputdata) { - err = -ENOMEM; - goto cleanup; - } - if (copy_from_user(rsa.inputdata, (char *)(u64)(inputdata & 0x7fffffff), - rsa.inputdatalength)) { - err = -EFAULT; - goto cleanup; - } - - rsa.outputdata = (char *)kmalloc(rsa.outputdatalength, GFP_KERNEL); - if (!rsa.outputdata) { - err = -ENOMEM; - goto cleanup; - } - - rsa.b_key = (char *)kmalloc(rsa.inputdatalength, GFP_KERNEL); - if (!rsa.b_key) { - err = -ENOMEM; - goto cleanup; - } - if (copy_from_user(rsa.b_key, (char *)(u64)(b_key & 0x7fffffff), - rsa.inputdatalength)) { - err = -EFAULT; - goto cleanup; - } - - rsa.n_modulus = (char *)kmalloc(rsa.inputdatalength, GFP_KERNEL); - if (!rsa.n_modulus) { - err = -ENOMEM; - goto cleanup; - } - if (copy_from_user(rsa.n_modulus, (char *)(u64)(n_modulus & 0x7fffffff), - rsa.inputdatalength)) { - err = -EFAULT; - goto cleanup; - } - - set_fs(KERNEL_DS); - err = sys_ioctl(fd, cmd, (unsigned long)&rsa); - set_fs(old_fs); - if (err < 0) - goto cleanup; - - if (copy_to_user((char *)(u64)(outputdata & 0x7fffffff), rsa.outputdata, - rsa.outputdatalength)) - err = -EFAULT; - -cleanup: - if (rsa.inputdata) - kfree(rsa.inputdata); - if (rsa.outputdata) - kfree(rsa.outputdata); - if (rsa.b_key) - kfree(rsa.b_key); - if (rsa.n_modulus) - kfree(rsa.n_modulus); - - return err; -} - -static int do_rsa_crt_ioctl(unsigned int fd, unsigned int cmd, - unsigned long arg, struct file *f) -{ - mm_segment_t old_fs = get_fs(); - int err = 0; - ica_rsa_modexpo_crt_t rsa; - ica_rsa_modexpo_crt_32_t *rsa32 = (ica_rsa_modexpo_crt_32_t *)arg; - u32 inputdata, outputdata, bp_key, bq_key, np_prime, nq_prime, u_mult_inv; - - memset (&rsa, 0, sizeof(rsa)); - - err |= __get_user (inputdata, &rsa32->inputdata); - err |= __get_user (rsa.inputdatalength, &rsa32->inputdatalength); - err |= __get_user (outputdata, &rsa32->outputdata); - err |= __get_user (rsa.outputdatalength, &rsa32->outputdatalength); - err |= __get_user (bp_key, &rsa32->bp_key); - err |= __get_user (bq_key, &rsa32->bq_key); - err |= __get_user (np_prime, &rsa32->np_prime); - err |= __get_user (nq_prime, &rsa32->nq_prime); - err |= __get_user (u_mult_inv, &rsa32->u_mult_inv); - if (err) - return -EFAULT; - - rsa.inputdata = (char *)kmalloc(rsa.inputdatalength, GFP_KERNEL); - if (!rsa.inputdata) { - err = -ENOMEM; - goto cleanup; - } - if (copy_from_user(rsa.inputdata, (char *)(u64)(inputdata & 0x7fffffff), - rsa.inputdatalength)) { - err = -EFAULT; - goto cleanup; - } - - rsa.outputdata = (char *)kmalloc(rsa.outputdatalength, GFP_KERNEL); - if (!rsa.outputdata) { - err = -ENOMEM; - goto cleanup; - } - - rsa.bp_key = (char *)kmalloc(rsa.inputdatalength/2 + 8, GFP_KERNEL); - if (!rsa.bp_key) { - err = -ENOMEM; - goto cleanup; - } - if (copy_from_user(rsa.bp_key, (char *)(u64)(bp_key & 0x7fffffff), - rsa.inputdatalength/2 + 8)) { - err = -EFAULT; - goto cleanup; - } - - rsa.bq_key = (char *)kmalloc(rsa.inputdatalength/2, GFP_KERNEL); - if (!rsa.bq_key) { - err = -ENOMEM; - goto cleanup; - } - if (copy_from_user(rsa.bq_key, (char *)(u64)(bq_key & 0x7fffffff), - rsa.inputdatalength/2)) { - err = -EFAULT; - goto cleanup; - } - - rsa.np_prime = (char *)kmalloc(rsa.inputdatalength/2 + 8, GFP_KERNEL); - if (!rsa.np_prime) { - err = -ENOMEM; - goto cleanup; - } - if (copy_from_user(rsa.np_prime, (char *)(u64)(np_prime & 0x7fffffff), - rsa.inputdatalength/2 + 8)) { - err = -EFAULT; - goto cleanup; - } - - rsa.nq_prime = (char *)kmalloc(rsa.inputdatalength/2, GFP_KERNEL); - if (!rsa.nq_prime) { - err = -ENOMEM; - goto cleanup; - } - if (copy_from_user(rsa.nq_prime, (char *)(u64)(nq_prime & 0x7fffffff), - rsa.inputdatalength/2)) { - err = -EFAULT; - goto cleanup; - } - - rsa.u_mult_inv = (char *)kmalloc(rsa.inputdatalength/2 + 8, GFP_KERNEL); - if (!rsa.u_mult_inv) { - err = -ENOMEM; - goto cleanup; - } - if (copy_from_user(rsa.u_mult_inv, (char *)(u64)(u_mult_inv & 0x7fffffff), - rsa.inputdatalength/2 + 8)) { - err = -EFAULT; - goto cleanup; - } - - set_fs(KERNEL_DS); - err = sys_ioctl(fd, cmd, (unsigned long)&rsa); - set_fs(old_fs); - if (err < 0) - goto cleanup; - - if (copy_to_user((char *)(u64)(outputdata & 0x7fffffff), rsa.outputdata, - rsa.outputdatalength)) - err = -EFAULT; - -cleanup: - if (rsa.inputdata) - kfree(rsa.inputdata); - if (rsa.outputdata) - kfree(rsa.outputdata); - if (rsa.bp_key) - kfree(rsa.bp_key); - if (rsa.bq_key) - kfree(rsa.bq_key); - if (rsa.np_prime) - kfree(rsa.np_prime); - if (rsa.nq_prime) - kfree(rsa.nq_prime); - if (rsa.u_mult_inv) - kfree(rsa.u_mult_inv); - - return err; -} - -static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg, - struct file *f) -{ - mm_segment_t old_fs = get_fs(); - int err; - unsigned long val; - - set_fs (KERNEL_DS); - err = sys_ioctl(fd, cmd, (unsigned long)&val); - set_fs (old_fs); - if (!err && put_user((unsigned int) val, (u32 *)arg)) - return -EFAULT; - return err; -} - -int siocdevprivate_ioctl(unsigned int fd, unsigned int cmd, - unsigned long arg, struct file *f) -{ - /* siocdevprivate cannot be emulated properly */ - return -EINVAL; -} - -#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL((cmd), NULL) -#define HANDLE_IOCTL(cmd,handler) { (cmd), (handler), NULL }, -#define IOCTL_TABLE_START \ - struct ioctl_trans ioctl_start[] = { -#define IOCTL_TABLE_END \ - }; - -IOCTL_TABLE_START +struct ioctl_trans ioctl_start[] = { +/* architecture independent ioctls */ #include +#define DECLARES +#include "../../../fs/compat_ioctl.c" +/* s390 only ioctls */ +#if defined(CONFIG_DASD) || defined(CONFIG_DASD_MODULE) COMPATIBLE_IOCTL(DASDAPIVER) COMPATIBLE_IOCTL(BIODASDDISABLE) COMPATIBLE_IOCTL(BIODASDENABLE) @@ -822,83 +50,18 @@ COMPATIBLE_IOCTL(BIODASDRLSE) COMPATIBLE_IOCTL(BIODASDSLCK) COMPATIBLE_IOCTL(BIODASDINFO) COMPATIBLE_IOCTL(BIODASDFMT) +#endif +#if defined(CONFIG_S390_TAPE) || defined(CONFIG_S390_TAPE_MODULE) COMPATIBLE_IOCTL(TAPE390_DISPLAY) -COMPATIBLE_IOCTL(BLKRASET) -COMPATIBLE_IOCTL(BLKFRASET) -COMPATIBLE_IOCTL(BLKBSZGET) -COMPATIBLE_IOCTL(BLKGETSIZE64) - -HANDLE_IOCTL(HDIO_GETGEO, hd_geometry_ioctl) +#endif +/* This one should be architecture independent */ COMPATIBLE_IOCTL(TCSBRKP) +/* s390 doesn't need handlers here */ COMPATIBLE_IOCTL(TIOCGSERIAL) COMPATIBLE_IOCTL(TIOCSSERIAL) - -COMPATIBLE_IOCTL(SIOCGSTAMP) - -HANDLE_IOCTL(SIOCGIFNAME, dev_ifname32) -HANDLE_IOCTL(SIOCGIFCONF, dev_ifconf) -HANDLE_IOCTL(SIOCGIFFLAGS, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFFLAGS, dev_ifsioc) -HANDLE_IOCTL(SIOCGIFMETRIC, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFMETRIC, dev_ifsioc) -HANDLE_IOCTL(SIOCGIFMTU, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFMTU, dev_ifsioc) -HANDLE_IOCTL(SIOCGIFMEM, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFMEM, dev_ifsioc) -HANDLE_IOCTL(SIOCGIFHWADDR, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFHWADDR, dev_ifsioc) -HANDLE_IOCTL(SIOCADDMULTI, dev_ifsioc) -HANDLE_IOCTL(SIOCDELMULTI, dev_ifsioc) -HANDLE_IOCTL(SIOCGIFINDEX, dev_ifsioc) -HANDLE_IOCTL(SIOCGIFMAP, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFMAP, dev_ifsioc) -HANDLE_IOCTL(SIOCGIFADDR, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFADDR, dev_ifsioc) -HANDLE_IOCTL(SIOCGIFBRDADDR, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFBRDADDR, dev_ifsioc) -HANDLE_IOCTL(SIOCGIFDSTADDR, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFDSTADDR, dev_ifsioc) -HANDLE_IOCTL(SIOCGIFNETMASK, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFNETMASK, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFPFLAGS, dev_ifsioc) -HANDLE_IOCTL(SIOCGIFPFLAGS, dev_ifsioc) -HANDLE_IOCTL(SIOCGIFTXQLEN, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFTXQLEN, dev_ifsioc) -HANDLE_IOCTL(SIOCADDRT, routing_ioctl) -HANDLE_IOCTL(SIOCDELRT, routing_ioctl) -HANDLE_IOCTL(SIOCBONDENSLAVE, bond_ioctl) -HANDLE_IOCTL(SIOCBONDRELEASE, bond_ioctl) -HANDLE_IOCTL(SIOCBONDSETHWADDR, bond_ioctl) -HANDLE_IOCTL(SIOCBONDSLAVEINFOQUERY, bond_ioctl) -HANDLE_IOCTL(SIOCBONDINFOQUERY, bond_ioctl) -HANDLE_IOCTL(SIOCBONDCHANGEACTIVE, bond_ioctl) - -HANDLE_IOCTL(EXT2_IOC32_GETFLAGS, do_ext2_ioctl) -HANDLE_IOCTL(EXT2_IOC32_SETFLAGS, do_ext2_ioctl) -HANDLE_IOCTL(EXT2_IOC32_GETVERSION, do_ext2_ioctl) -HANDLE_IOCTL(EXT2_IOC32_SETVERSION, do_ext2_ioctl) - -HANDLE_IOCTL(LOOP_SET_STATUS, loop_status) -HANDLE_IOCTL(LOOP_GET_STATUS, loop_status) - -HANDLE_IOCTL(ICARSAMODEXPO, do_rsa_ioctl) -HANDLE_IOCTL(ICARSACRT, do_rsa_crt_ioctl) -HANDLE_IOCTL(ICARSAMODMULT, do_rsa_ioctl) - -COMPATIBLE_IOCTL(ICAZ90STATUS) -COMPATIBLE_IOCTL(ICAZ90QUIESCE) -COMPATIBLE_IOCTL(ICAZ90HARDRESET) -COMPATIBLE_IOCTL(ICAZ90HARDERROR) - -HANDLE_IOCTL(BLKRAGET, w_long) -HANDLE_IOCTL(BLKGETSIZE, w_long) -HANDLE_IOCTL(BLKFRAGET, w_long) -HANDLE_IOCTL(BLKSECTGET, w_long) -HANDLE_IOCTL(BLKPG, blkpg_ioctl_trans) - -IOCTL_TABLE_END +}; int ioctl_table_size = ARRAY_SIZE(ioctl_start); diff -puN arch/s390/lib/uaccess64.S~s390-10-32-bit-ioctl-emulation-fixes arch/s390/lib/uaccess64.S --- 25/arch/s390/lib/uaccess64.S~s390-10-32-bit-ioctl-emulation-fixes 2004-01-09 10:58:33.000000000 -0800 +++ 25-akpm/arch/s390/lib/uaccess64.S 2004-01-09 10:58:33.000000000 -0800 @@ -73,6 +73,41 @@ __copy_to_user_asm: .align 4 .text + .globl __copy_in_user_asm +__copy_in_user_asm: + stmg %r6,%r15,48(%r15) + lgr %r5,%r3 + lgr %r7,%r5 + lgr %r6,%r2 + cpya 6,4 # ar6 = ar4 + sacf 512 +0: mvcle %r4,%r6,0 + jo 0b +1: sacf 0 + lgr %r2,%r7 + lmg %r6,%r15,48(%r15) + br %r14 +2: lghi %r1,-4096 + lgr %r5,%r4 + slgr %r5,%r1 # %r5 = %r4 + 4096 + ngr %r5,%r1 # %r5 = (%r4 + 4096) & -4096 + slgr %r5,%r4 # %r5 = #bytes to next user page boundary + clgr %r7,%r5 # copy crosses next page boundary ? + jnh 1b # no, the current page fauled + # The page after the current user page might have faulted. + # We cant't find out which page because the program check handler + # might have callled schedule, destroying all lowcore information. + # We retry with the shortened length. +3: mvcle %r4,%r6,0 + jo 3b + j 1b + .section __ex_table,"a" + .quad 0b,2b + .quad 3b,1b + .previous + + .align 4 + .text .globl __clear_user_asm __clear_user_asm: lgr %r4,%r2 diff -puN arch/s390/lib/uaccess.S~s390-10-32-bit-ioctl-emulation-fixes arch/s390/lib/uaccess.S --- 25/arch/s390/lib/uaccess.S~s390-10-32-bit-ioctl-emulation-fixes 2004-01-09 10:58:33.000000000 -0800 +++ 25-akpm/arch/s390/lib/uaccess.S 2004-01-09 10:58:33.000000000 -0800 @@ -73,6 +73,41 @@ __copy_to_user_asm: .align 4 .text + .globl __copy_in_user_asm +__copy_in_user_asm: + stm %r6,%r15,24(%r15) + lr %r5,%r3 + lr %r7,%r3 + lr %r6,%r2 + cpya 6,4 # ar6 = ar4 + sacf 512 +0: mvcle %r4,%r6,0 + jo 0b +1: sacf 0 + lr %r2,%r7 + lm %r6,%r15,24(%r15) + br %r14 +2: lhi %r1,-4096 + lr %r5,%r4 + slr %r5,%r1 # %r5 = %r4 + 4096 + nr %r5,%r1 # %r5 = (%r4 + 4096) & -4096 + slr %r5,%r4 # %r5 = #bytes to next user page boundary + clr %r7,%r5 # copy crosses next page boundary ? + jnh 1b # no, the current page fauled + # The page after the current user page might have faulted. + # We cant't find out which page because the program check handler + # might have callled schedule, destroying all lowcore information. + # We retry with the shortened length. +3: mvcle %r4,%r6,0 + jo 3b + j 1b + .section __ex_table,"a" + .long 0b,2b + .long 3b,1b + .previous + + .align 4 + .text .globl __clear_user_asm __clear_user_asm: lr %r4,%r2 diff -puN fs/compat_ioctl.c~s390-10-32-bit-ioctl-emulation-fixes fs/compat_ioctl.c --- 25/fs/compat_ioctl.c~s390-10-32-bit-ioctl-emulation-fixes 2004-01-09 10:58:33.000000000 -0800 +++ 25-akpm/fs/compat_ioctl.c 2004-01-09 10:58:33.000000000 -0800 @@ -161,9 +161,9 @@ static int do_ext2_ioctl(unsigned int fd case EXT2_IOC32_GETVERSION: cmd = EXT2_IOC_GETVERSION; break; case EXT2_IOC32_SETVERSION: cmd = EXT2_IOC_SETVERSION; break; } - return sys_ioctl(fd, cmd, arg); + return sys_ioctl(fd, cmd, (unsigned long)compat_ptr(arg)); } - + struct video_tuner32 { compat_int_t tuner; char name[32]; @@ -215,7 +215,7 @@ static int get_video_buffer32(struct vid if(get_user(tmp, &up->base)) return -EFAULT; - kp->base = (void *) ((unsigned long)tmp); + kp->base = compat_ptr(tmp); __get_user(kp->height, &up->height); __get_user(kp->width, &up->width); __get_user(kp->depth, &up->depth); @@ -339,7 +339,7 @@ static int do_video_ioctl(unsigned int f unsigned long vx; } karg; mm_segment_t old_fs = get_fs(); - void *up = (void *)arg; + void *up = compat_ptr(arg); int err = 0; /* First, convert the command. */ @@ -407,7 +407,7 @@ out: static int do_siocgstamp(unsigned int fd, unsigned int cmd, unsigned long arg) { - struct compat_timeval *up = (struct compat_timeval *)arg; + struct compat_timeval *up = compat_ptr(arg); struct timeval ktv; mm_segment_t old_fs = get_fs(); int err; @@ -466,7 +466,7 @@ static int dev_ifname32(unsigned int fd, struct ifreq32 ifr32; int err; - if (copy_from_user(&ifr32, (struct ifreq32 *)arg, sizeof(struct ifreq32))) + if (copy_from_user(&ifr32, compat_ptr(arg), sizeof(ifr32))) return -EFAULT; dev = dev_get_by_index(ifr32.ifr_ifindex); @@ -476,7 +476,7 @@ static int dev_ifname32(unsigned int fd, strlcpy(ifr32.ifr_name, dev->name, sizeof(ifr32.ifr_name)); dev_put(dev); - err = copy_to_user((struct ifreq32 *)arg, &ifr32, sizeof(struct ifreq32)); + err = copy_to_user(compat_ptr(arg), &ifr32, sizeof(ifr32)); return (err ? -EFAULT : 0); } #endif @@ -491,7 +491,7 @@ static int dev_ifconf(unsigned int fd, u unsigned int i, j; int err; - if (copy_from_user(&ifc32, (struct ifconf32 *)arg, sizeof(struct ifconf32))) + if (copy_from_user(&ifc32, compat_ptr(arg), sizeof(struct ifconf32))) return -EFAULT; if(ifc32.ifcbuf == 0) { @@ -501,6 +501,7 @@ static int dev_ifconf(unsigned int fd, u } else { ifc.ifc_len = ((ifc32.ifc_len / sizeof (struct ifreq32)) + 1) * sizeof (struct ifreq); + /* should the size be limited? -arnd */ ifc.ifc_buf = kmalloc (ifc.ifc_len, GFP_KERNEL); if (!ifc.ifc_buf) return -ENOMEM; @@ -546,7 +547,7 @@ static int dev_ifconf(unsigned int fd, u else ifc32.ifc_len = i - sizeof (struct ifreq32); } - if (copy_to_user((struct ifconf32 *)arg, &ifc32, sizeof(struct ifconf32))) + if (copy_to_user(compat_ptr(arg), &ifc32, sizeof(struct ifconf32))) err = -EFAULT; } } @@ -563,7 +564,7 @@ static int ethtool_ioctl(unsigned int fd void *datap; ifr = compat_alloc_user_space(sizeof(*ifr)); - ifr32 = (struct ifreq32 *) arg; + ifr32 = compat_ptr(arg); if (copy_in_user(&ifr->ifr_name, &ifr32->ifr_name, IFNAMSIZ)) return -EFAULT; @@ -571,18 +572,18 @@ static int ethtool_ioctl(unsigned int fd if (get_user(data, &ifr32->ifr_ifru.ifru_data)) return -EFAULT; - datap = (void *) (unsigned long) data; + datap = compat_ptr(data); if (put_user(datap, &ifr->ifr_ifru.ifru_data)) return -EFAULT; return sys_ioctl(fd, cmd, (unsigned long) ifr); } -static int bond_ioctl(unsigned long fd, unsigned int cmd, unsigned long arg) +static int bond_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) { struct ifreq kifr; struct ifreq *uifr; - struct ifreq32 *ifr32 = (struct ifreq32 *) arg; + struct ifreq32 *ifr32 = compat_ptr(arg); mm_segment_t old_fs; int err; u32 data; @@ -624,7 +625,7 @@ static int bond_ioctl(unsigned long fd, int siocdevprivate_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) { struct ifreq *u_ifreq64; - struct ifreq32 *u_ifreq32 = (struct ifreq32 *) arg; + struct ifreq32 *u_ifreq32 = compat_ptr(arg); char tmp_buf[IFNAMSIZ]; void *data64; u32 data32; @@ -650,23 +651,27 @@ int siocdevprivate_ioctl(unsigned int fd static int dev_ifsioc(unsigned int fd, unsigned int cmd, unsigned long arg) { struct ifreq ifr; + struct ifreq32 *uifr32; + struct ifmap32 *uifmap32; mm_segment_t old_fs; int err; + uifr32 = compat_ptr(arg); + uifmap32 = &uifr32->ifr_ifru.ifru_map; switch (cmd) { case SIOCSIFMAP: - err = copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(ifr.ifr_name)); - err |= __get_user(ifr.ifr_map.mem_start, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_start)); - err |= __get_user(ifr.ifr_map.mem_end, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_end)); - err |= __get_user(ifr.ifr_map.base_addr, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.base_addr)); - err |= __get_user(ifr.ifr_map.irq, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.irq)); - err |= __get_user(ifr.ifr_map.dma, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.dma)); - err |= __get_user(ifr.ifr_map.port, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.port)); + err = copy_from_user(&ifr, uifr32, sizeof(ifr.ifr_name)); + err |= __get_user(ifr.ifr_map.mem_start, &uifmap32->mem_start); + err |= __get_user(ifr.ifr_map.mem_end, &uifmap32->mem_end); + err |= __get_user(ifr.ifr_map.base_addr, &uifmap32->base_addr); + err |= __get_user(ifr.ifr_map.irq, &uifmap32->irq); + err |= __get_user(ifr.ifr_map.dma, &uifmap32->dma); + err |= __get_user(ifr.ifr_map.port, &uifmap32->port); if (err) return -EFAULT; break; default: - if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32))) + if (copy_from_user(&ifr, uifr32, sizeof(*uifr32))) return -EFAULT; break; } @@ -687,17 +692,17 @@ static int dev_ifsioc(unsigned int fd, u case SIOCGIFDSTADDR: case SIOCGIFNETMASK: case SIOCGIFTXQLEN: - if (copy_to_user((struct ifreq32 *)arg, &ifr, sizeof(struct ifreq32))) + if (copy_to_user(uifr32, &ifr, sizeof(*uifr32))) return -EFAULT; break; case SIOCGIFMAP: - err = copy_to_user((struct ifreq32 *)arg, &ifr, sizeof(ifr.ifr_name)); - err |= __put_user(ifr.ifr_map.mem_start, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_start)); - err |= __put_user(ifr.ifr_map.mem_end, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_end)); - err |= __put_user(ifr.ifr_map.base_addr, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.base_addr)); - err |= __put_user(ifr.ifr_map.irq, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.irq)); - err |= __put_user(ifr.ifr_map.dma, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.dma)); - err |= __put_user(ifr.ifr_map.port, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.port)); + err = copy_to_user(uifr32, &ifr, sizeof(ifr.ifr_name)); + err |= __put_user(ifr.ifr_map.mem_start, &uifmap32->mem_start); + err |= __put_user(ifr.ifr_map.mem_end, &uifmap32->mem_end); + err |= __put_user(ifr.ifr_map.base_addr, &uifmap32->base_addr); + err |= __put_user(ifr.ifr_map.irq, &uifmap32->irq); + err |= __put_user(ifr.ifr_map.dma, &uifmap32->dma); + err |= __put_user(ifr.ifr_map.port, &uifmap32->port); if (err) err = -EFAULT; break; @@ -751,25 +756,28 @@ static int routing_ioctl(unsigned int fd struct socket *mysock = sockfd_lookup(fd, &ret); if (mysock && mysock->sk && mysock->sk->sk_family == AF_INET6) { /* ipv6 */ - ret = copy_from_user (&r6.rtmsg_dst, &(((struct in6_rtmsg32 *)arg)->rtmsg_dst), + struct in6_rtmsg32 *ur6 = compat_ptr(arg); + ret = copy_from_user (&r6.rtmsg_dst, &(ur6->rtmsg_dst), 3 * sizeof(struct in6_addr)); - ret |= __get_user (r6.rtmsg_type, &(((struct in6_rtmsg32 *)arg)->rtmsg_type)); - ret |= __get_user (r6.rtmsg_dst_len, &(((struct in6_rtmsg32 *)arg)->rtmsg_dst_len)); - ret |= __get_user (r6.rtmsg_src_len, &(((struct in6_rtmsg32 *)arg)->rtmsg_src_len)); - ret |= __get_user (r6.rtmsg_metric, &(((struct in6_rtmsg32 *)arg)->rtmsg_metric)); - ret |= __get_user (r6.rtmsg_info, &(((struct in6_rtmsg32 *)arg)->rtmsg_info)); - ret |= __get_user (r6.rtmsg_flags, &(((struct in6_rtmsg32 *)arg)->rtmsg_flags)); - ret |= __get_user (r6.rtmsg_ifindex, &(((struct in6_rtmsg32 *)arg)->rtmsg_ifindex)); + ret |= __get_user (r6.rtmsg_type, &(ur6->rtmsg_type)); + ret |= __get_user (r6.rtmsg_dst_len, &(ur6->rtmsg_dst_len)); + ret |= __get_user (r6.rtmsg_src_len, &(ur6->rtmsg_src_len)); + ret |= __get_user (r6.rtmsg_metric, &(ur6->rtmsg_metric)); + ret |= __get_user (r6.rtmsg_info, &(ur6->rtmsg_info)); + ret |= __get_user (r6.rtmsg_flags, &(ur6->rtmsg_flags)); + ret |= __get_user (r6.rtmsg_ifindex, &(ur6->rtmsg_ifindex)); r = (void *) &r6; } else { /* ipv4 */ - ret = copy_from_user (&r4.rt_dst, &(((struct rtentry32 *)arg)->rt_dst), 3 * sizeof(struct sockaddr)); - ret |= __get_user (r4.rt_flags, &(((struct rtentry32 *)arg)->rt_flags)); - ret |= __get_user (r4.rt_metric, &(((struct rtentry32 *)arg)->rt_metric)); - ret |= __get_user (r4.rt_mtu, &(((struct rtentry32 *)arg)->rt_mtu)); - ret |= __get_user (r4.rt_window, &(((struct rtentry32 *)arg)->rt_window)); - ret |= __get_user (r4.rt_irtt, &(((struct rtentry32 *)arg)->rt_irtt)); - ret |= __get_user (rtdev, &(((struct rtentry32 *)arg)->rt_dev)); + struct rtentry32 *ur4 = compat_ptr(arg); + ret = copy_from_user (&r4.rt_dst, &(ur4->rt_dst), + 3 * sizeof(struct sockaddr)); + ret |= __get_user (r4.rt_flags, &(ur4->rt_flags)); + ret |= __get_user (r4.rt_metric, &(ur4->rt_metric)); + ret |= __get_user (r4.rt_mtu, &(ur4->rt_mtu)); + ret |= __get_user (r4.rt_window, &(ur4->rt_window)); + ret |= __get_user (r4.rt_irtt, &(ur4->rt_irtt)); + ret |= __get_user (rtdev, &(ur4->rt_dev)); if (rtdev) { ret |= copy_from_user (devname, compat_ptr(rtdev), 15); r4.rt_dev = devname; devname[15] = 0; @@ -783,7 +791,7 @@ static int routing_ioctl(unsigned int fd return -EFAULT; set_fs (KERNEL_DS); - ret = sys_ioctl (fd, cmd, (long) r); + ret = sys_ioctl (fd, cmd, (unsigned long) r); set_fs (old_fs); if (mysock) @@ -803,14 +811,16 @@ static int hdio_getgeo(unsigned int fd, { mm_segment_t old_fs = get_fs(); struct hd_geometry geo; + struct hd_geometry32 *ugeo; int err; set_fs (KERNEL_DS); err = sys_ioctl(fd, HDIO_GETGEO, (unsigned long)&geo); set_fs (old_fs); + ugeo = compat_ptr(arg); if (!err) { - err = copy_to_user ((struct hd_geometry32 *)arg, &geo, 4); - err |= __put_user (geo.start, &(((struct hd_geometry32 *)arg)->start)); + err = copy_to_user (ugeo, &geo, 4); + err |= __put_user (geo.start, &ugeo->start); } return err ? -EFAULT : 0; } @@ -848,7 +858,7 @@ static int do_cmap_ptr(__u16 **ptr64, __ if (get_user(data, ptr32)) return -EFAULT; - datap = (void *) (unsigned long) data; + datap = compat_ptr(data); if (put_user(datap, ptr64)) return -EFAULT; return 0; @@ -861,7 +871,7 @@ static int fb_getput_cmap(unsigned int f int err; cmap = compat_alloc_user_space(sizeof(*cmap)); - cmap32 = (struct fb_cmap32 *) arg; + cmap32 = compat_ptr(arg); if (copy_in_user(&cmap->start, &cmap32->start, 2 * sizeof(__u32))) return -EFAULT; @@ -921,7 +931,7 @@ static int fb_get_fscreeninfo(unsigned i struct fb_fix_screeninfo32 *fix32; int err; - fix32 = (struct fb_fix_screeninfo32 *) arg; + fix32 = compat_ptr(arg); old_fs = get_fs(); set_fs(KERNEL_DS); @@ -975,7 +985,7 @@ static int hdio_ioctl_trans(unsigned int set_fs(old_fs); if(error == 0) { - uvp = (unsigned int *)arg; + uvp = compat_ptr(arg); if(put_user(kval, uvp)) error = -EFAULT; } @@ -1025,12 +1035,12 @@ static int sg_build_iovec(sg_io_hdr_t *s if (get_user(base, &iov32[i].iov_base) || get_user(len, &iov32[i].iov_len) || - put_user((void *)(unsigned long)base, &iov[i].iov_base) || + put_user(compat_ptr(base), &iov[i].iov_base) || put_user(len, &iov[i].iov_len)) return -EFAULT; } - sgio->dxferp = iov; + sgio->dxferp = iov; /* FIXME: dereferencing user pointer? */ return 0; } @@ -1043,7 +1053,7 @@ static int sg_ioctl_trans(unsigned int f void *dxferp; int err; - sgio32 = (sg_io_hdr32_t *) arg; + sgio32 = compat_ptr(arg); if (get_user(iovec_count, &sgio32->iovec_count)) return -EFAULT; @@ -1070,7 +1080,7 @@ static int sg_ioctl_trans(unsigned int f if (get_user(data, &sgio32->dxferp)) return -EFAULT; - dxferp = (void *) (unsigned long) data; + dxferp = compat_ptr(data); if (iovec_count) { if (sg_build_iovec(sgio, dxferp, iovec_count)) return -EFAULT; @@ -1084,11 +1094,11 @@ static int sg_ioctl_trans(unsigned int f if (get_user(data, &sgio32->cmdp)) return -EFAULT; - cmdp = (unsigned char *) (unsigned long) data; + cmdp = compat_ptr(data); if (get_user(data, &sgio32->sbp)) return -EFAULT; - sbp = (unsigned char *) (unsigned long) data; + sbp = compat_ptr(data); if (put_user(cmdp, &sgio->cmdp) || put_user(sbp, &sgio->sbp)) @@ -1101,7 +1111,7 @@ static int sg_ioctl_trans(unsigned int f if (get_user(data, &sgio32->usr_ptr)) return -EFAULT; - if (put_user((void *)(unsigned long)data, &sgio->usr_ptr)) + if (put_user(compat_ptr(data), &sgio->usr_ptr)) return -EFAULT; if (copy_in_user(&sgio->status, &sgio32->status, @@ -1140,7 +1150,7 @@ struct sock_fprog32 { static int ppp_sock_fprog_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) { - struct sock_fprog32 *u_fprog32 = (struct sock_fprog32 *) arg; + struct sock_fprog32 *u_fprog32 = compat_ptr(arg); struct sock_fprog *u_fprog64 = compat_alloc_user_space(sizeof(struct sock_fprog)); void *fptr64; u32 fptr32; @@ -1185,7 +1195,7 @@ static int ppp_gidle(unsigned int fd, un int err; idle = compat_alloc_user_space(sizeof(*idle)); - idle32 = (struct ppp_idle32 *) arg; + idle32 = compat_ptr(arg); err = sys_ioctl(fd, PPPIOCGIDLE, (unsigned long) idle); @@ -1207,12 +1217,12 @@ static int ppp_scompress(unsigned int fd void *datap; odata = compat_alloc_user_space(sizeof(*odata)); - odata32 = (struct ppp_option_data32 *) arg; + odata32 = compat_ptr(arg); if (get_user(data, &odata32->ptr)) return -EFAULT; - datap = (void *) (unsigned long) data; + datap = compat_ptr(data); if (put_user(datap, &odata->ptr)) return -EFAULT; @@ -1296,8 +1306,11 @@ static int mt_ioctl_trans(unsigned int f { mm_segment_t old_fs = get_fs(); struct mtconfiginfo info; + struct mtconfiginfo32 *uinfo32; struct mtget get; + struct mtget32 *umget32; struct mtpos pos; + struct mtpos32 *upos32; unsigned long kcmd; void *karg; int err = 0; @@ -1318,15 +1331,17 @@ static int mt_ioctl_trans(unsigned int f case MTIOCSETCONFIG32: kcmd = MTIOCSETCONFIG; karg = &info; - err = __get_user(info.mt_type, &((struct mtconfiginfo32 *)arg)->mt_type); - err |= __get_user(info.ifc_type, &((struct mtconfiginfo32 *)arg)->ifc_type); - err |= __get_user(info.irqnr, &((struct mtconfiginfo32 *)arg)->irqnr); - err |= __get_user(info.dmanr, &((struct mtconfiginfo32 *)arg)->dmanr); - err |= __get_user(info.port, &((struct mtconfiginfo32 *)arg)->port); - err |= __get_user(info.debug, &((struct mtconfiginfo32 *)arg)->debug); - err |= __copy_from_user((char *)&info.debug + sizeof(info.debug), - (char *)&((struct mtconfiginfo32 *)arg)->debug - + sizeof(((struct mtconfiginfo32 *)arg)->debug), sizeof(__u32)); + uinfo32 = compat_ptr(arg); + err = __get_user(info.mt_type, &uinfo32->mt_type); + err |= __get_user(info.ifc_type, &uinfo32->ifc_type); + err |= __get_user(info.irqnr, &uinfo32->irqnr); + err |= __get_user(info.dmanr, &uinfo32->dmanr); + err |= __get_user(info.port, &uinfo32->port); + err |= __get_user(info.debug, &uinfo32->debug); + err |= __copy_from_user((char *)&info.debug + + sizeof(info.debug), + (char *)&uinfo32->debug + + sizeof(uinfo32->debug), sizeof(__u32)); if (err) return -EFAULT; break; @@ -1347,26 +1362,29 @@ static int mt_ioctl_trans(unsigned int f return err; switch (cmd) { case MTIOCPOS32: - err = __put_user(pos.mt_blkno, &((struct mtpos32 *)arg)->mt_blkno); + upos32 = compat_ptr(arg); + err = __put_user(pos.mt_blkno, &upos32->mt_blkno); break; case MTIOCGET32: - err = __put_user(get.mt_type, &((struct mtget32 *)arg)->mt_type); - err |= __put_user(get.mt_resid, &((struct mtget32 *)arg)->mt_resid); - err |= __put_user(get.mt_dsreg, &((struct mtget32 *)arg)->mt_dsreg); - err |= __put_user(get.mt_gstat, &((struct mtget32 *)arg)->mt_gstat); - err |= __put_user(get.mt_erreg, &((struct mtget32 *)arg)->mt_erreg); - err |= __put_user(get.mt_fileno, &((struct mtget32 *)arg)->mt_fileno); - err |= __put_user(get.mt_blkno, &((struct mtget32 *)arg)->mt_blkno); + umget32 = compat_ptr(arg); + err = __put_user(get.mt_type, &umget32->mt_type); + err |= __put_user(get.mt_resid, &umget32->mt_resid); + err |= __put_user(get.mt_dsreg, &umget32->mt_dsreg); + err |= __put_user(get.mt_gstat, &umget32->mt_gstat); + err |= __put_user(get.mt_erreg, &umget32->mt_erreg); + err |= __put_user(get.mt_fileno, &umget32->mt_fileno); + err |= __put_user(get.mt_blkno, &umget32->mt_blkno); break; case MTIOCGETCONFIG32: - err = __put_user(info.mt_type, &((struct mtconfiginfo32 *)arg)->mt_type); - err |= __put_user(info.ifc_type, &((struct mtconfiginfo32 *)arg)->ifc_type); - err |= __put_user(info.irqnr, &((struct mtconfiginfo32 *)arg)->irqnr); - err |= __put_user(info.dmanr, &((struct mtconfiginfo32 *)arg)->dmanr); - err |= __put_user(info.port, &((struct mtconfiginfo32 *)arg)->port); - err |= __put_user(info.debug, &((struct mtconfiginfo32 *)arg)->debug); - err |= __copy_to_user((char *)&((struct mtconfiginfo32 *)arg)->debug - + sizeof(((struct mtconfiginfo32 *)arg)->debug), + uinfo32 = compat_ptr(arg); + err = __put_user(info.mt_type, &uinfo32->mt_type); + err |= __put_user(info.ifc_type, &uinfo32->ifc_type); + err |= __put_user(info.irqnr, &uinfo32->irqnr); + err |= __put_user(info.dmanr, &uinfo32->dmanr); + err |= __put_user(info.port, &uinfo32->port); + err |= __put_user(info.debug, &uinfo32->debug); + err |= __copy_to_user((char *)&uinfo32->debug + + sizeof(uinfo32->debug), (char *)&info.debug + sizeof(info.debug), sizeof(__u32)); break; case MTIOCSETCONFIG32: @@ -1402,7 +1420,7 @@ static int cdrom_do_read_audio(unsigned void *datap; cdread_audio = compat_alloc_user_space(sizeof(*cdread_audio)); - cdread_audio32 = (struct cdrom_read_audio32 *) arg; + cdread_audio32 = compat_ptr(arg); if (copy_in_user(&cdread_audio->addr, &cdread_audio32->addr, @@ -1412,7 +1430,7 @@ static int cdrom_do_read_audio(unsigned if (get_user(data, &cdread_audio32->buf)) return -EFAULT; - datap = (void *) (unsigned long) data; + datap = compat_ptr(data); if (put_user(datap, &cdread_audio->buf)) return -EFAULT; @@ -1426,7 +1444,7 @@ static int __cgc_do_ptr(void **ptr64, __ if (get_user(data, ptr32)) return -EFAULT; - datap = (void *) (unsigned long) data; + datap = compat_ptr(data); if (put_user(datap, ptr64)) return -EFAULT; @@ -1440,7 +1458,7 @@ static int cdrom_do_generic_command(unsi unsigned char dir; cgc = compat_alloc_user_space(sizeof(*cgc)); - cgc32 = (struct cdrom_generic_command32 *) arg; + cgc32 = compat_ptr(arg); if (copy_in_user(&cgc->cmd, &cgc32->cmd, sizeof(cgc->cmd)) || __cgc_do_ptr((void **) &cgc->buffer, &cgc32->buffer) || @@ -1510,16 +1528,18 @@ static int loop_status(unsigned int fd, { mm_segment_t old_fs = get_fs(); struct loop_info l; + struct loop_info32 *ul; int err = -EINVAL; + ul = compat_ptr(arg); switch(cmd) { case LOOP_SET_STATUS: - err = get_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number); - err |= __get_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device); - err |= __get_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode); - err |= __get_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice); - err |= __copy_from_user((char *)&l.lo_offset, (char *)&((struct loop_info32 *)arg)->lo_offset, - 8 + (unsigned long)l.lo_init - (unsigned long)&l.lo_offset); + err = get_user(l.lo_number, &ul->lo_number); + err |= __get_user(l.lo_device, &ul->lo_device); + err |= __get_user(l.lo_inode, &ul->lo_inode); + err |= __get_user(l.lo_rdevice, &ul->lo_rdevice); + err |= __copy_from_user(&l.lo_offset, &ul->lo_offset, + 8 + (unsigned long)l.lo_init - (unsigned long)&l.lo_offset); if (err) { err = -EFAULT; } else { @@ -1533,12 +1553,12 @@ static int loop_status(unsigned int fd, err = sys_ioctl (fd, cmd, (unsigned long)&l); set_fs (old_fs); if (!err) { - err = put_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number); - err |= __put_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device); - err |= __put_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode); - err |= __put_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice); - err |= __copy_to_user((char *)&((struct loop_info32 *)arg)->lo_offset, - (char *)&l.lo_offset, (unsigned long)l.lo_init - (unsigned long)&l.lo_offset); + err = put_user(l.lo_number, &ul->lo_number); + err |= __put_user(l.lo_device, &ul->lo_device); + err |= __put_user(l.lo_inode, &ul->lo_inode); + err |= __put_user(l.lo_rdevice, &ul->lo_rdevice); + err |= __copy_to_user(&ul->lo_offset, &l.lo_offset, + (unsigned long)l.lo_init - (unsigned long)&l.lo_offset); if (err) err = -EFAULT; } @@ -1588,10 +1608,11 @@ struct consolefontdesc32 { compat_caddr_t chardata; /* font data in expanded form */ }; -static int do_fontx_ioctl(unsigned int fd, int cmd, struct consolefontdesc32 *user_cfd, struct file *file) +static int do_fontx_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { struct consolefontdesc cfdarg; struct console_font_op op; + struct consolefontdesc32 *user_cfd = compat_ptr(arg); int i, perm; perm = vt_check(file); @@ -1643,9 +1664,10 @@ struct console_font_op32 { compat_caddr_t data; /* font data with height fixed to 32 */ }; -static int do_kdfontop_ioctl(unsigned int fd, unsigned int cmd, struct console_font_op32 *fontop, struct file *file) +static int do_kdfontop_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { struct console_font_op op; + struct console_font_op32 *fontop = compat_ptr(arg); int perm = vt_check(file), i; struct vt_struct *vt; @@ -1671,9 +1693,10 @@ struct unimapdesc32 { compat_caddr_t entries; }; -static int do_unimap_ioctl(unsigned int fd, unsigned int cmd, struct unimapdesc32 *user_ud, struct file *file) +static int do_unimap_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { struct unimapdesc32 tmp; + struct unimapdesc32 *user_ud = compat_ptr(arg); int perm = vt_check(file); if (perm < 0) return perm; @@ -1704,7 +1727,7 @@ static int do_smb_getmountuid(unsigned i set_fs(old_fs); if (err >= 0) - err = put_user(kuid, (compat_uid_t *)arg); + err = put_user(kuid, (compat_uid_t *)compat_ptr(arg)); return err; } @@ -1773,12 +1796,12 @@ static int do_atm_iobuf(unsigned int fd, int len, err; iobuf = compat_alloc_user_space(sizeof(*iobuf)); - iobuf32 = (struct atm_iobuf32 *) arg; + iobuf32 = compat_ptr(arg); if (get_user(len, &iobuf32->length) || get_user(data, &iobuf32->buffer)) return -EFAULT; - datap = (void *) (unsigned long) data; + datap = compat_ptr(data); if (put_user(len, &iobuf->length) || put_user(datap, &iobuf->buffer)) return -EFAULT; @@ -1803,12 +1826,12 @@ static int do_atmif_sioc(unsigned int fd int err; sioc = compat_alloc_user_space(sizeof(*sioc)); - sioc32 = (struct atmif_sioc32 *) arg; + sioc32 = compat_ptr(arg); if (copy_in_user(&sioc->number, &sioc32->number, 2 * sizeof(int)) || get_user(data, &sioc32->arg)) return -EFAULT; - datap = (void *) (unsigned long) data; + datap = compat_ptr(data); if (put_user(datap, &sioc->arg)) return -EFAULT; @@ -1891,25 +1914,32 @@ struct blkpg_ioctl_arg32 { compat_int_t datalen; compat_caddr_t data; }; - -static int blkpg_ioctl_trans(unsigned int fd, unsigned int cmd, struct blkpg_ioctl_arg32 *arg) + +static int blkpg_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) { struct blkpg_ioctl_arg a; + struct blkpg_ioctl_arg32 *ua32; struct blkpg_partition p; + struct blkpg_partition *up32; + compat_caddr_t udata; int err; mm_segment_t old_fs = get_fs(); - err = get_user(a.op, &arg->op); - err |= __get_user(a.flags, &arg->flags); - err |= __get_user(a.datalen, &arg->datalen); - err |= __get_user((long)a.data, &arg->data); - if (err) return err; + ua32 = compat_ptr(arg); + err = get_user(a.op, &ua32->op); + err |= __get_user(a.flags, &ua32->flags); + err |= __get_user(a.datalen, &ua32->datalen); + err |= __get_user(udata, &ua32->data); + up32 = compat_ptr(udata); + if (err) + return err; + switch (a.op) { case BLKPG_ADD_PARTITION: case BLKPG_DEL_PARTITION: if (a.datalen < sizeof(struct blkpg_partition)) return -EINVAL; - if (copy_from_user(&p, a.data, sizeof(struct blkpg_partition))) + if (copy_from_user(&p, up32, sizeof(struct blkpg_partition))) return -EFAULT; a.data = &p; set_fs (KERNEL_DS); @@ -1933,18 +1963,18 @@ static int ioc_settimeout(unsigned int f static int do_blkbszget(unsigned int fd, unsigned int cmd, unsigned long arg) { - return sys_ioctl(fd, BLKBSZGET, arg); + return sys_ioctl(fd, BLKBSZGET, (unsigned long)compat_ptr(arg)); } static int do_blkbszset(unsigned int fd, unsigned int cmd, unsigned long arg) { - return sys_ioctl(fd, BLKBSZSET, arg); + return sys_ioctl(fd, BLKBSZSET, (unsigned long)compat_ptr(arg)); } static int do_blkgetsize64(unsigned int fd, unsigned int cmd, unsigned long arg) { - return sys_ioctl(fd, BLKGETSIZE64, arg); + return sys_ioctl(fd, BLKGETSIZE64, (unsigned long)compat_ptr(arg)); } /* Bluetooth ioctls */ @@ -2081,23 +2111,25 @@ static int fd_ioctl_trans(unsigned int f case FDDEFPRM32: case FDGETPRM32: { + struct floppy_struct32 *uf; struct floppy_struct *f; + uf = compat_ptr(arg); f = karg = kmalloc(sizeof(struct floppy_struct), GFP_KERNEL); if (!karg) return -ENOMEM; if (cmd == FDGETPRM32) break; - err = __get_user(f->size, &((struct floppy_struct32 *)arg)->size); - err |= __get_user(f->sect, &((struct floppy_struct32 *)arg)->sect); - err |= __get_user(f->head, &((struct floppy_struct32 *)arg)->head); - err |= __get_user(f->track, &((struct floppy_struct32 *)arg)->track); - err |= __get_user(f->stretch, &((struct floppy_struct32 *)arg)->stretch); - err |= __get_user(f->gap, &((struct floppy_struct32 *)arg)->gap); - err |= __get_user(f->rate, &((struct floppy_struct32 *)arg)->rate); - err |= __get_user(f->spec1, &((struct floppy_struct32 *)arg)->spec1); - err |= __get_user(f->fmt_gap, &((struct floppy_struct32 *)arg)->fmt_gap); - err |= __get_user((u64)f->name, &((struct floppy_struct32 *)arg)->name); + err = __get_user(f->size, &uf->size); + err |= __get_user(f->sect, &uf->sect); + err |= __get_user(f->head, &uf->head); + err |= __get_user(f->track, &uf->track); + err |= __get_user(f->stretch, &uf->stretch); + err |= __get_user(f->gap, &uf->gap); + err |= __get_user(f->rate, &uf->rate); + err |= __get_user(f->spec1, &uf->spec1); + err |= __get_user(f->fmt_gap, &uf->fmt_gap); + err |= __get_user((u64)f->name, &uf->name); if (err) { err = -EFAULT; goto out; @@ -2107,32 +2139,34 @@ static int fd_ioctl_trans(unsigned int f case FDSETDRVPRM32: case FDGETDRVPRM32: { + struct floppy_drive_params32 *uf; struct floppy_drive_params *f; + uf = compat_ptr(arg); f = karg = kmalloc(sizeof(struct floppy_drive_params), GFP_KERNEL); if (!karg) return -ENOMEM; if (cmd == FDGETDRVPRM32) break; - err = __get_user(f->cmos, &((struct floppy_drive_params32 *)arg)->cmos); - err |= __get_user(f->max_dtr, &((struct floppy_drive_params32 *)arg)->max_dtr); - err |= __get_user(f->hlt, &((struct floppy_drive_params32 *)arg)->hlt); - err |= __get_user(f->hut, &((struct floppy_drive_params32 *)arg)->hut); - err |= __get_user(f->srt, &((struct floppy_drive_params32 *)arg)->srt); - err |= __get_user(f->spinup, &((struct floppy_drive_params32 *)arg)->spinup); - err |= __get_user(f->spindown, &((struct floppy_drive_params32 *)arg)->spindown); - err |= __get_user(f->spindown_offset, &((struct floppy_drive_params32 *)arg)->spindown_offset); - err |= __get_user(f->select_delay, &((struct floppy_drive_params32 *)arg)->select_delay); - err |= __get_user(f->rps, &((struct floppy_drive_params32 *)arg)->rps); - err |= __get_user(f->tracks, &((struct floppy_drive_params32 *)arg)->tracks); - err |= __get_user(f->timeout, &((struct floppy_drive_params32 *)arg)->timeout); - err |= __get_user(f->interleave_sect, &((struct floppy_drive_params32 *)arg)->interleave_sect); - err |= __copy_from_user(&f->max_errors, &((struct floppy_drive_params32 *)arg)->max_errors, sizeof(f->max_errors)); - err |= __get_user(f->flags, &((struct floppy_drive_params32 *)arg)->flags); - err |= __get_user(f->read_track, &((struct floppy_drive_params32 *)arg)->read_track); - err |= __copy_from_user(f->autodetect, ((struct floppy_drive_params32 *)arg)->autodetect, sizeof(f->autodetect)); - err |= __get_user(f->checkfreq, &((struct floppy_drive_params32 *)arg)->checkfreq); - err |= __get_user(f->native_format, &((struct floppy_drive_params32 *)arg)->native_format); + err = __get_user(f->cmos, &uf->cmos); + err |= __get_user(f->max_dtr, &uf->max_dtr); + err |= __get_user(f->hlt, &uf->hlt); + err |= __get_user(f->hut, &uf->hut); + err |= __get_user(f->srt, &uf->srt); + err |= __get_user(f->spinup, &uf->spinup); + err |= __get_user(f->spindown, &uf->spindown); + err |= __get_user(f->spindown_offset, &uf->spindown_offset); + err |= __get_user(f->select_delay, &uf->select_delay); + err |= __get_user(f->rps, &uf->rps); + err |= __get_user(f->tracks, &uf->tracks); + err |= __get_user(f->timeout, &uf->timeout); + err |= __get_user(f->interleave_sect, &uf->interleave_sect); + err |= __copy_from_user(&f->max_errors, &uf->max_errors, sizeof(f->max_errors)); + err |= __get_user(f->flags, &uf->flags); + err |= __get_user(f->read_track, &uf->read_track); + err |= __copy_from_user(f->autodetect, uf->autodetect, sizeof(f->autodetect)); + err |= __get_user(f->checkfreq, &uf->checkfreq); + err |= __get_user(f->native_format, &uf->native_format); if (err) { err = -EFAULT; goto out; @@ -2177,83 +2211,90 @@ static int fd_ioctl_trans(unsigned int f err |= __put_user(f->rate, &((struct floppy_struct32 *)arg)->rate); err |= __put_user(f->spec1, &((struct floppy_struct32 *)arg)->spec1); err |= __put_user(f->fmt_gap, &((struct floppy_struct32 *)arg)->fmt_gap); - err |= __put_user((u64)f->name, &((struct floppy_struct32 *)arg)->name); + err |= __put_user((u64)f->name, (compat_caddr_t*)&((struct floppy_struct32 *)arg)->name); break; } case FDGETDRVPRM32: { + struct floppy_drive_params32 *uf; struct floppy_drive_params *f = karg; - err = __put_user(f->cmos, &((struct floppy_drive_params32 *)arg)->cmos); - err |= __put_user(f->max_dtr, &((struct floppy_drive_params32 *)arg)->max_dtr); - err |= __put_user(f->hlt, &((struct floppy_drive_params32 *)arg)->hlt); - err |= __put_user(f->hut, &((struct floppy_drive_params32 *)arg)->hut); - err |= __put_user(f->srt, &((struct floppy_drive_params32 *)arg)->srt); - err |= __put_user(f->spinup, &((struct floppy_drive_params32 *)arg)->spinup); - err |= __put_user(f->spindown, &((struct floppy_drive_params32 *)arg)->spindown); - err |= __put_user(f->spindown_offset, &((struct floppy_drive_params32 *)arg)->spindown_offset); - err |= __put_user(f->select_delay, &((struct floppy_drive_params32 *)arg)->select_delay); - err |= __put_user(f->rps, &((struct floppy_drive_params32 *)arg)->rps); - err |= __put_user(f->tracks, &((struct floppy_drive_params32 *)arg)->tracks); - err |= __put_user(f->timeout, &((struct floppy_drive_params32 *)arg)->timeout); - err |= __put_user(f->interleave_sect, &((struct floppy_drive_params32 *)arg)->interleave_sect); - err |= __copy_to_user(&((struct floppy_drive_params32 *)arg)->max_errors, &f->max_errors, sizeof(f->max_errors)); - err |= __put_user(f->flags, &((struct floppy_drive_params32 *)arg)->flags); - err |= __put_user(f->read_track, &((struct floppy_drive_params32 *)arg)->read_track); - err |= __copy_to_user(((struct floppy_drive_params32 *)arg)->autodetect, f->autodetect, sizeof(f->autodetect)); - err |= __put_user(f->checkfreq, &((struct floppy_drive_params32 *)arg)->checkfreq); - err |= __put_user(f->native_format, &((struct floppy_drive_params32 *)arg)->native_format); + uf = compat_ptr(arg); + err = __put_user(f->cmos, &uf->cmos); + err |= __put_user(f->max_dtr, &uf->max_dtr); + err |= __put_user(f->hlt, &uf->hlt); + err |= __put_user(f->hut, &uf->hut); + err |= __put_user(f->srt, &uf->srt); + err |= __put_user(f->spinup, &uf->spinup); + err |= __put_user(f->spindown, &uf->spindown); + err |= __put_user(f->spindown_offset, &uf->spindown_offset); + err |= __put_user(f->select_delay, &uf->select_delay); + err |= __put_user(f->rps, &uf->rps); + err |= __put_user(f->tracks, &uf->tracks); + err |= __put_user(f->timeout, &uf->timeout); + err |= __put_user(f->interleave_sect, &uf->interleave_sect); + err |= __copy_to_user(&uf->max_errors, &f->max_errors, sizeof(f->max_errors)); + err |= __put_user(f->flags, &uf->flags); + err |= __put_user(f->read_track, &uf->read_track); + err |= __copy_to_user(uf->autodetect, f->autodetect, sizeof(f->autodetect)); + err |= __put_user(f->checkfreq, &uf->checkfreq); + err |= __put_user(f->native_format, &uf->native_format); break; } case FDGETDRVSTAT32: case FDPOLLDRVSTAT32: { + struct floppy_drive_struct32 *uf; struct floppy_drive_struct *f = karg; - err = __put_user(f->flags, &((struct floppy_drive_struct32 *)arg)->flags); - err |= __put_user(f->spinup_date, &((struct floppy_drive_struct32 *)arg)->spinup_date); - err |= __put_user(f->select_date, &((struct floppy_drive_struct32 *)arg)->select_date); - err |= __put_user(f->first_read_date, &((struct floppy_drive_struct32 *)arg)->first_read_date); - err |= __put_user(f->probed_format, &((struct floppy_drive_struct32 *)arg)->probed_format); - err |= __put_user(f->track, &((struct floppy_drive_struct32 *)arg)->track); - err |= __put_user(f->maxblock, &((struct floppy_drive_struct32 *)arg)->maxblock); - err |= __put_user(f->maxtrack, &((struct floppy_drive_struct32 *)arg)->maxtrack); - err |= __put_user(f->generation, &((struct floppy_drive_struct32 *)arg)->generation); - err |= __put_user(f->keep_data, &((struct floppy_drive_struct32 *)arg)->keep_data); - err |= __put_user(f->fd_ref, &((struct floppy_drive_struct32 *)arg)->fd_ref); - err |= __put_user(f->fd_device, &((struct floppy_drive_struct32 *)arg)->fd_device); - err |= __put_user(f->last_checked, &((struct floppy_drive_struct32 *)arg)->last_checked); - err |= __put_user((u64)f->dmabuf, &((struct floppy_drive_struct32 *)arg)->dmabuf); - err |= __put_user((u64)f->bufblocks, &((struct floppy_drive_struct32 *)arg)->bufblocks); + uf = compat_ptr(arg); + err = __put_user(f->flags, &uf->flags); + err |= __put_user(f->spinup_date, &uf->spinup_date); + err |= __put_user(f->select_date, &uf->select_date); + err |= __put_user(f->first_read_date, &uf->first_read_date); + err |= __put_user(f->probed_format, &uf->probed_format); + err |= __put_user(f->track, &uf->track); + err |= __put_user(f->maxblock, &uf->maxblock); + err |= __put_user(f->maxtrack, &uf->maxtrack); + err |= __put_user(f->generation, &uf->generation); + err |= __put_user(f->keep_data, &uf->keep_data); + err |= __put_user(f->fd_ref, &uf->fd_ref); + err |= __put_user(f->fd_device, &uf->fd_device); + err |= __put_user(f->last_checked, &uf->last_checked); + err |= __put_user((u64)f->dmabuf, &uf->dmabuf); + err |= __put_user((u64)f->bufblocks, &uf->bufblocks); break; } case FDGETFDCSTAT32: { + struct floppy_fdc_state32 *uf; struct floppy_fdc_state *f = karg; - err = __put_user(f->spec1, &((struct floppy_fdc_state32 *)arg)->spec1); - err |= __put_user(f->spec2, &((struct floppy_fdc_state32 *)arg)->spec2); - err |= __put_user(f->dtr, &((struct floppy_fdc_state32 *)arg)->dtr); - err |= __put_user(f->version, &((struct floppy_fdc_state32 *)arg)->version); - err |= __put_user(f->dor, &((struct floppy_fdc_state32 *)arg)->dor); - err |= __put_user(f->address, &((struct floppy_fdc_state32 *)arg)->address); - err |= __copy_to_user((char *)&((struct floppy_fdc_state32 *)arg)->address - + sizeof(((struct floppy_fdc_state32 *)arg)->address), + uf = compat_ptr(arg); + err = __put_user(f->spec1, &uf->spec1); + err |= __put_user(f->spec2, &uf->spec2); + err |= __put_user(f->dtr, &uf->dtr); + err |= __put_user(f->version, &uf->version); + err |= __put_user(f->dor, &uf->dor); + err |= __put_user(f->address, &uf->address); + err |= __copy_to_user((char *)&uf->address + sizeof(uf->address), (char *)&f->address + sizeof(f->address), sizeof(int)); - err |= __put_user(f->driver_version, &((struct floppy_fdc_state32 *)arg)->driver_version); - err |= __copy_to_user(((struct floppy_fdc_state32 *)arg)->track, f->track, sizeof(f->track)); + err |= __put_user(f->driver_version, &uf->driver_version); + err |= __copy_to_user(uf->track, f->track, sizeof(f->track)); break; } case FDWERRORGET32: { + struct floppy_write_errors32 *uf; struct floppy_write_errors *f = karg; - err = __put_user(f->write_errors, &((struct floppy_write_errors32 *)arg)->write_errors); - err |= __put_user(f->first_error_sector, &((struct floppy_write_errors32 *)arg)->first_error_sector); - err |= __put_user(f->first_error_generation, &((struct floppy_write_errors32 *)arg)->first_error_generation); - err |= __put_user(f->last_error_sector, &((struct floppy_write_errors32 *)arg)->last_error_sector); - err |= __put_user(f->last_error_generation, &((struct floppy_write_errors32 *)arg)->last_error_generation); - err |= __put_user(f->badness, &((struct floppy_write_errors32 *)arg)->badness); + uf = compat_ptr(arg); + err = __put_user(f->write_errors, &uf->write_errors); + err |= __put_user(f->first_error_sector, &uf->first_error_sector); + err |= __put_user(f->first_error_generation, &uf->first_error_generation); + err |= __put_user(f->last_error_sector, &uf->last_error_sector); + err |= __put_user(f->last_error_generation, &uf->last_error_generation); + err |= __put_user(f->badness, &uf->badness); break; } default: @@ -2278,7 +2319,7 @@ struct mtd_oob_buf32 { static int mtd_rw_oob(unsigned int fd, unsigned int cmd, unsigned long arg) { struct mtd_oob_buf *buf = compat_alloc_user_space(sizeof(*buf)); - struct mtd_oob_buf32 *buf32 = (struct mtd_oob_buf32 *) arg; + struct mtd_oob_buf32 *buf32 = compat_ptr(arg); u32 data; char *datap; unsigned int real_cmd; @@ -2291,7 +2332,7 @@ static int mtd_rw_oob(unsigned int fd, u 2 * sizeof(u32)) || get_user(data, &buf32->ptr)) return -EFAULT; - datap = (void *) (unsigned long) data; + datap = compat_ptr(data); if (put_user(datap, &buf->ptr)) return -EFAULT; @@ -2325,7 +2366,7 @@ put_dirent32 (struct dirent *d, struct c return ret; } -static int vfat_ioctl32(unsigned fd, unsigned cmd, void *ptr) +static int vfat_ioctl32(unsigned fd, unsigned cmd, unsigned long arg) { int ret; mm_segment_t oldfs = get_fs(); @@ -2345,8 +2386,8 @@ static int vfat_ioctl32(unsigned fd, uns ret = sys_ioctl(fd,cmd,(unsigned long)&d); set_fs(oldfs); if (ret >= 0) { - ret |= put_dirent32(&d[0], (struct compat_dirent *)ptr); - ret |= put_dirent32(&d[1], ((struct compat_dirent *)ptr) + 1); + ret |= put_dirent32(&d[0], (struct compat_dirent *)compat_ptr(arg)); + ret |= put_dirent32(&d[1], ((struct compat_dirent *)compat_ptr(arg)) + 1); } return ret; } @@ -2406,7 +2447,7 @@ static int set_raw32_request(struct raw_ return ret; } -static int raw_ioctl(unsigned fd, unsigned cmd, void *ptr) +static int raw_ioctl(unsigned fd, unsigned cmd, unsigned long arg) { int ret; @@ -2414,7 +2455,7 @@ static int raw_ioctl(unsigned fd, unsign case RAW_SETBIND: case RAW_GETBIND: { struct raw_config_request req; - struct raw32_config_request *user_req = ptr; + struct raw32_config_request *user_req = compat_ptr(arg); mm_segment_t oldfs = get_fs(); if ((ret = get_raw32_request(&req, user_req))) @@ -2430,7 +2471,7 @@ static int raw_ioctl(unsigned fd, unsign break; } default: - ret = sys_ioctl(fd,cmd,(unsigned long)ptr); + ret = sys_ioctl(fd, cmd, arg); break; } return ret; @@ -2454,14 +2495,15 @@ struct serial_struct32 { compat_uint_t iomem_base; unsigned short iomem_reg_shift; unsigned int port_high; + /* compat_ulong_t iomap_base FIXME */ compat_int_t reserved[1]; }; -static int serial_struct_ioctl(unsigned fd, unsigned cmd, void *ptr) +static int serial_struct_ioctl(unsigned fd, unsigned cmd, unsigned long arg) { typedef struct serial_struct SS; typedef struct serial_struct32 SS32; - struct serial_struct32 *ss32 = ptr; + struct serial_struct32 *ss32 = compat_ptr(arg); int err; struct serial_struct ss; mm_segment_t oldseg = get_fs(); @@ -2515,7 +2557,7 @@ static int do_usbdevfs_control(unsigned void *uptr, *kptr; int err; - uctrl = (struct usbdevfs_ctrltransfer32 *) arg; + uctrl = compat_ptr(arg); if (copy_from_user(&kctrl, uctrl, (sizeof(struct usbdevfs_ctrltransfer32) - @@ -2576,7 +2618,7 @@ static int do_usbdevfs_bulk(unsigned int void *uptr, *kptr; int err; - ubulk = (struct usbdevfs_bulktransfer32 *) arg; + ubulk = compat_ptr(arg); if (get_user(kbulk.ep, &ubulk->ep) || get_user(kbulk.len, &ubulk->len) || @@ -2771,7 +2813,7 @@ static int do_usbdevfs_urb(unsigned int unsigned int buflen; int err; - uurb = (struct usbdevfs_urb32 *) arg; + uurb = compat_ptr(arg); err = -ENOMEM; kurb = kmalloc(sizeof(struct usbdevfs_urb) + @@ -2836,7 +2878,7 @@ static int do_usbdevfs_reapurb(unsigned set_fs(old_fs); if (err >= 0 && - put_user((u32)(u64)kptr, (u32 *)arg)) + put_user((u32)(u64)kptr, (u32 *)compat_ptr(arg))) err = -EFAULT; return err; @@ -2857,13 +2899,13 @@ static int do_usbdevfs_discsignal(unsign u32 uctx; int err; - udis = (struct usbdevfs_disconnectsignal32 *) arg; + udis = compat_ptr(arg); if (get_user(kdis.signr, &udis->signr) || __get_user(uctx, &udis->context)) return -EFAULT; - kdis.context = (void *) (long)uctx; + kdis.context = compat_ptr(uctx); old_fs = get_fs(); set_fs(KERNEL_DS); diff -puN include/asm-s390/uaccess.h~s390-10-32-bit-ioctl-emulation-fixes include/asm-s390/uaccess.h --- 25/include/asm-s390/uaccess.h~s390-10-32-bit-ioctl-emulation-fixes 2004-01-09 10:58:33.000000000 -0800 +++ 25-akpm/include/asm-s390/uaccess.h 2004-01-09 10:58:33.000000000 -0800 @@ -389,6 +389,26 @@ extern long __copy_from_user_asm(void *t err; \ }) +extern long __copy_in_user_asm(const void *from, long n, void *to); + +#define __copy_in_user(to, from, n) \ +({ \ + __copy_in_user_asm(from, n, to); \ +}) + +#define copy_in_user(to, from, n) \ +({ \ + long err = 0; \ + __typeof__(n) __n = (n); \ + might_sleep(); \ + if (__access_ok(from,__n) && __access_ok(to,__n)) { \ + err = __copy_in_user_asm(from, __n, to); \ + } \ + else \ + err = __n; \ + err; \ +}) + /* * Copy a null terminated string from userspace. */ @@ -594,5 +614,4 @@ clear_user(void *to, unsigned long n) return n; } - -#endif /* _S390_UACCESS_H */ +#endif /* __S390_UACCESS_H */ diff -puN include/linux/compat_ioctl.h~s390-10-32-bit-ioctl-emulation-fixes include/linux/compat_ioctl.h --- 25/include/linux/compat_ioctl.h~s390-10-32-bit-ioctl-emulation-fixes 2004-01-09 10:58:33.000000000 -0800 +++ 25-akpm/include/linux/compat_ioctl.h 2004-01-09 10:59:14.000000000 -0800 @@ -2,6 +2,14 @@ * compatible types passed or none at all... Please include * only stuff that is compatible on *all architectures*. */ +#ifndef COMPATIBLE_IOCTL /* pointer to compatible structure or no argument */ +#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL((cmd),(ioctl_trans_handler_t)sys_ioctl) +#endif + +#ifndef ULONG_IOCTL /* argument is an unsigned long integer, not a pointer */ +#define ULONG_IOCTL(cmd) HANDLE_IOCTL((cmd),(ioctl_trans_handler_t)sys_ioctl) +#endif + /* Big T */ COMPATIBLE_IOCTL(TCGETA) COMPATIBLE_IOCTL(TCSETA) @@ -35,18 +43,16 @@ COMPATIBLE_IOCTL(TIOCSTI) COMPATIBLE_IOCTL(TIOCOUTQ) COMPATIBLE_IOCTL(TIOCSPGRP) COMPATIBLE_IOCTL(TIOCGPGRP) -COMPATIBLE_IOCTL(TIOCSCTTY) +ULONG_IOCTL(TIOCSCTTY) COMPATIBLE_IOCTL(TIOCGPTN) COMPATIBLE_IOCTL(TIOCSPTLCK) COMPATIBLE_IOCTL(TIOCSERGETLSR) -#ifdef CONFIG_FB /* Big F */ COMPATIBLE_IOCTL(FBIOGET_VSCREENINFO) COMPATIBLE_IOCTL(FBIOPUT_VSCREENINFO) COMPATIBLE_IOCTL(FBIOPAN_DISPLAY) COMPATIBLE_IOCTL(FBIOGET_CON2FBMAP) COMPATIBLE_IOCTL(FBIOPUT_CON2FBMAP) -#endif /* Little f */ COMPATIBLE_IOCTL(FIOCLEX) COMPATIBLE_IOCTL(FIONCLEX) @@ -68,7 +74,6 @@ COMPATIBLE_IOCTL(HDIO_SET_MULTCOUNT) COMPATIBLE_IOCTL(HDIO_DRIVE_CMD) COMPATIBLE_IOCTL(HDIO_SET_PIO_MODE) COMPATIBLE_IOCTL(HDIO_SET_NICE) -#ifdef CONFIG_BLK_DEV_FD /* 0x02 -- Floppy ioctls */ COMPATIBLE_IOCTL(FDMSGON) COMPATIBLE_IOCTL(FDMSGOFF) @@ -86,7 +91,6 @@ COMPATIBLE_IOCTL(FDRESET) COMPATIBLE_IOCTL(FDTWADDLE) COMPATIBLE_IOCTL(FDFMTTRK) COMPATIBLE_IOCTL(FDRAWCMD) -#endif /* 0x12 */ COMPATIBLE_IOCTL(BLKROSET) COMPATIBLE_IOCTL(BLKROGET) @@ -94,8 +98,8 @@ COMPATIBLE_IOCTL(BLKRRPART) COMPATIBLE_IOCTL(BLKFLSBUF) COMPATIBLE_IOCTL(BLKSECTSET) COMPATIBLE_IOCTL(BLKSSZGET) -COMPATIBLE_IOCTL(BLKRASET) -COMPATIBLE_IOCTL(BLKFRASET) +ULONG_IOCTL(BLKRASET) +ULONG_IOCTL(BLKFRASET) /* RAID */ COMPATIBLE_IOCTL(RAID_VERSION) COMPATIBLE_IOCTL(GET_ARRAY_INFO) @@ -104,20 +108,19 @@ COMPATIBLE_IOCTL(PRINT_RAID_DEBUG) COMPATIBLE_IOCTL(RAID_AUTORUN) COMPATIBLE_IOCTL(CLEAR_ARRAY) COMPATIBLE_IOCTL(ADD_NEW_DISK) -COMPATIBLE_IOCTL(HOT_REMOVE_DISK) +ULONG_IOCTL(HOT_REMOVE_DISK) COMPATIBLE_IOCTL(SET_ARRAY_INFO) COMPATIBLE_IOCTL(SET_DISK_INFO) COMPATIBLE_IOCTL(WRITE_RAID_INFO) COMPATIBLE_IOCTL(UNPROTECT_ARRAY) COMPATIBLE_IOCTL(PROTECT_ARRAY) -COMPATIBLE_IOCTL(HOT_ADD_DISK) -COMPATIBLE_IOCTL(SET_DISK_FAULTY) +ULONG_IOCTL(HOT_ADD_DISK) +ULONG_IOCTL(SET_DISK_FAULTY) COMPATIBLE_IOCTL(RUN_ARRAY) -COMPATIBLE_IOCTL(START_ARRAY) +ULONG_IOCTL(START_ARRAY) COMPATIBLE_IOCTL(STOP_ARRAY) COMPATIBLE_IOCTL(STOP_ARRAY_RO) COMPATIBLE_IOCTL(RESTART_ARRAY_RW) -#ifdef CONFIG_BLK_DEV_DM /* DM */ #ifdef CONFIG_DM_IOCTL_V4 COMPATIBLE_IOCTL(DM_VERSION) @@ -145,21 +148,20 @@ COMPATIBLE_IOCTL(DM_DEV_STATUS) COMPATIBLE_IOCTL(DM_TARGET_STATUS) COMPATIBLE_IOCTL(DM_TARGET_WAIT) #endif -#endif /* Big K */ COMPATIBLE_IOCTL(PIO_FONT) COMPATIBLE_IOCTL(GIO_FONT) -COMPATIBLE_IOCTL(KDSIGACCEPT) +ULONG_IOCTL(KDSIGACCEPT) COMPATIBLE_IOCTL(KDGETKEYCODE) COMPATIBLE_IOCTL(KDSETKEYCODE) -COMPATIBLE_IOCTL(KIOCSOUND) -COMPATIBLE_IOCTL(KDMKTONE) +ULONG_IOCTL(KIOCSOUND) +ULONG_IOCTL(KDMKTONE) COMPATIBLE_IOCTL(KDGKBTYPE) -COMPATIBLE_IOCTL(KDSETMODE) +ULONG_IOCTL(KDSETMODE) COMPATIBLE_IOCTL(KDGETMODE) -COMPATIBLE_IOCTL(KDSKBMODE) +ULONG_IOCTL(KDSKBMODE) COMPATIBLE_IOCTL(KDGKBMODE) -COMPATIBLE_IOCTL(KDSKBMETA) +ULONG_IOCTL(KDSKBMETA) COMPATIBLE_IOCTL(KDGKBMETA) COMPATIBLE_IOCTL(KDGKBENT) COMPATIBLE_IOCTL(KDSKBENT) @@ -169,9 +171,9 @@ COMPATIBLE_IOCTL(KDGKBDIACR) COMPATIBLE_IOCTL(KDSKBDIACR) COMPATIBLE_IOCTL(KDKBDREP) COMPATIBLE_IOCTL(KDGKBLED) -COMPATIBLE_IOCTL(KDSKBLED) +ULONG_IOCTL(KDSKBLED) COMPATIBLE_IOCTL(KDGETLED) -COMPATIBLE_IOCTL(KDSETLED) +ULONG_IOCTL(KDSETLED) COMPATIBLE_IOCTL(GIO_SCRNMAP) COMPATIBLE_IOCTL(PIO_SCRNMAP) COMPATIBLE_IOCTL(GIO_UNISCRNMAP) @@ -198,15 +200,14 @@ COMPATIBLE_IOCTL(VT_SETMODE) COMPATIBLE_IOCTL(VT_GETMODE) COMPATIBLE_IOCTL(VT_GETSTATE) COMPATIBLE_IOCTL(VT_OPENQRY) -COMPATIBLE_IOCTL(VT_ACTIVATE) -COMPATIBLE_IOCTL(VT_WAITACTIVE) -COMPATIBLE_IOCTL(VT_RELDISP) -COMPATIBLE_IOCTL(VT_DISALLOCATE) +ULONG_IOCTL(VT_ACTIVATE) +ULONG_IOCTL(VT_WAITACTIVE) +ULONG_IOCTL(VT_RELDISP) +ULONG_IOCTL(VT_DISALLOCATE) COMPATIBLE_IOCTL(VT_RESIZE) COMPATIBLE_IOCTL(VT_RESIZEX) COMPATIBLE_IOCTL(VT_LOCKSWITCH) COMPATIBLE_IOCTL(VT_UNLOCKSWITCH) -#if defined(CONFIG_VIDEO_DEV) || defined(CONFIG_VIDEO_DEV_MODULE) /* Little v */ /* Little v, the video4linux ioctls (conflict?) */ COMPATIBLE_IOCTL(VIDIOCGCAP) @@ -233,7 +234,6 @@ COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCP COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+5, int)) COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+6, int)) COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+7, int)) -#endif /* Little p (/dev/rtc, /dev/envctrl, etc.) */ COMPATIBLE_IOCTL(RTC_AIE_ON) COMPATIBLE_IOCTL(RTC_AIE_OFF) @@ -261,8 +261,10 @@ COMPATIBLE_IOCTL(SIOCSIFLINK) COMPATIBLE_IOCTL(SIOCSIFENCAP) COMPATIBLE_IOCTL(SIOCGIFENCAP) COMPATIBLE_IOCTL(SIOCSIFNAME) +/* FIXME: not compatible COMPATIBLE_IOCTL(SIOCSIFBR) COMPATIBLE_IOCTL(SIOCGIFBR) +*/ COMPATIBLE_IOCTL(SIOCSARP) COMPATIBLE_IOCTL(SIOCGARP) COMPATIBLE_IOCTL(SIOCDARP) @@ -280,7 +282,7 @@ COMPATIBLE_IOCTL(SIOCSIFVLAN) COMPATIBLE_IOCTL(SG_SET_TIMEOUT) COMPATIBLE_IOCTL(SG_GET_TIMEOUT) COMPATIBLE_IOCTL(SG_EMULATED_HOST) -COMPATIBLE_IOCTL(SG_SET_TRANSFORM) +ULONG_IOCTL(SG_SET_TRANSFORM) COMPATIBLE_IOCTL(SG_GET_TRANSFORM) COMPATIBLE_IOCTL(SG_SET_RESERVED_SIZE) COMPATIBLE_IOCTL(SG_GET_RESERVED_SIZE) @@ -300,7 +302,6 @@ COMPATIBLE_IOCTL(SG_SCSI_RESET) COMPATIBLE_IOCTL(SG_GET_REQUEST_TABLE) COMPATIBLE_IOCTL(SG_SET_KEEP_ORPHAN) COMPATIBLE_IOCTL(SG_GET_KEEP_ORPHAN) -#if defined(CONFIG_PPP) || defined(CONFIG_PPP_MODULE) /* PPP stuff */ COMPATIBLE_IOCTL(PPPIOCGFLAGS) COMPATIBLE_IOCTL(PPPIOCSFLAGS) @@ -334,7 +335,6 @@ COMPATIBLE_IOCTL(PPPIOCGCHAN) /* PPPOX */ COMPATIBLE_IOCTL(PPPOEIOCSFWD) COMPATIBLE_IOCTL(PPPOEIOCDFWD) -#endif /* LP */ COMPATIBLE_IOCTL(LPGETSTATUS) /* CDROM stuff */ @@ -349,7 +349,7 @@ COMPATIBLE_IOCTL(CDROMSTART) COMPATIBLE_IOCTL(CDROMEJECT) COMPATIBLE_IOCTL(CDROMVOLCTRL) COMPATIBLE_IOCTL(CDROMSUBCHNL) -COMPATIBLE_IOCTL(CDROMEJECT_SW) +ULONG_IOCTL(CDROMEJECT_SW) COMPATIBLE_IOCTL(CDROMMULTISESSION) COMPATIBLE_IOCTL(CDROM_GET_MCN) COMPATIBLE_IOCTL(CDROMRESET) @@ -357,16 +357,16 @@ COMPATIBLE_IOCTL(CDROMVOLREAD) COMPATIBLE_IOCTL(CDROMSEEK) COMPATIBLE_IOCTL(CDROMPLAYBLK) COMPATIBLE_IOCTL(CDROMCLOSETRAY) -COMPATIBLE_IOCTL(CDROM_SET_OPTIONS) -COMPATIBLE_IOCTL(CDROM_CLEAR_OPTIONS) -COMPATIBLE_IOCTL(CDROM_SELECT_SPEED) -COMPATIBLE_IOCTL(CDROM_SELECT_DISC) -COMPATIBLE_IOCTL(CDROM_MEDIA_CHANGED) -COMPATIBLE_IOCTL(CDROM_DRIVE_STATUS) +ULONG_IOCTL(CDROM_SET_OPTIONS) +ULONG_IOCTL(CDROM_CLEAR_OPTIONS) +ULONG_IOCTL(CDROM_SELECT_SPEED) +ULONG_IOCTL(CDROM_SELECT_DISC) +ULONG_IOCTL(CDROM_MEDIA_CHANGED) +ULONG_IOCTL(CDROM_DRIVE_STATUS) COMPATIBLE_IOCTL(CDROM_DISC_STATUS) COMPATIBLE_IOCTL(CDROM_CHANGER_NSLOTS) -COMPATIBLE_IOCTL(CDROM_LOCKDOOR) -COMPATIBLE_IOCTL(CDROM_DEBUG) +ULONG_IOCTL(CDROM_LOCKDOOR) +ULONG_IOCTL(CDROM_DEBUG) COMPATIBLE_IOCTL(CDROM_GET_CAPABILITY) /* Ignore cdrom.h about these next 5 ioctls, they absolutely do * not take a struct cdrom_read, instead they take a struct cdrom_msf @@ -382,13 +382,12 @@ COMPATIBLE_IOCTL(DVD_READ_STRUCT) COMPATIBLE_IOCTL(DVD_WRITE_STRUCT) COMPATIBLE_IOCTL(DVD_AUTH) /* Big L */ -COMPATIBLE_IOCTL(LOOP_SET_FD) +ULONG_IOCTL(LOOP_SET_FD) COMPATIBLE_IOCTL(LOOP_CLR_FD) COMPATIBLE_IOCTL(LOOP_GET_STATUS64) COMPATIBLE_IOCTL(LOOP_SET_STATUS64) /* Big A */ /* sparc only */ -#if defined(CONFIG_SOUND) || defined (CONFIG_SOUND_MODULE) /* Big Q for sound/OSS */ COMPATIBLE_IOCTL(SNDCTL_SEQ_RESET) COMPATIBLE_IOCTL(SNDCTL_SEQ_SYNC) @@ -543,10 +542,9 @@ COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE5) COMPATIBLE_IOCTL(SOUND_MIXER_GETLEVELS) COMPATIBLE_IOCTL(SOUND_MIXER_SETLEVELS) COMPATIBLE_IOCTL(OSS_GETVERSION) -#endif /* AUTOFS */ -COMPATIBLE_IOCTL(AUTOFS_IOC_READY) -COMPATIBLE_IOCTL(AUTOFS_IOC_FAIL) +ULONG_IOCTL(AUTOFS_IOC_READY) +ULONG_IOCTL(AUTOFS_IOC_FAIL) COMPATIBLE_IOCTL(AUTOFS_IOC_CATATONIC) COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOVER) COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE) @@ -573,7 +571,6 @@ COMPATIBLE_IOCTL(NCP_IOC_GETCHARSETS) COMPATIBLE_IOCTL(NCP_IOC_SETCHARSETS) COMPATIBLE_IOCTL(NCP_IOC_GETDENTRYTTL) COMPATIBLE_IOCTL(NCP_IOC_SETDENTRYTTL) -#if defined(CONFIG_ATM) || defined(CONFIG_ATM_MODULE) /* Little a */ COMPATIBLE_IOCTL(ATMSIGD_CTRL) COMPATIBLE_IOCTL(ATMARPD_CTRL) @@ -590,7 +587,6 @@ COMPATIBLE_IOCTL(ATMTCP_CREATE) COMPATIBLE_IOCTL(ATMTCP_REMOVE) COMPATIBLE_IOCTL(ATMMPC_CTRL) COMPATIBLE_IOCTL(ATMMPC_DATA) -#endif /* Big W */ /* WIOC_GETSUPPORT not yet implemented -E */ COMPATIBLE_IOCTL(WDIOC_GETSTATUS) @@ -605,7 +601,6 @@ COMPATIBLE_IOCTL(RNDGETPOOL) COMPATIBLE_IOCTL(RNDADDENTROPY) COMPATIBLE_IOCTL(RNDZAPENTCNT) COMPATIBLE_IOCTL(RNDCLEARPOOL) -#if defined(CONFIG_BT) || defined(CONFIG_BT_MODULE) /* Bluetooth ioctls */ COMPATIBLE_IOCTL(HCIDEVUP) COMPATIBLE_IOCTL(HCIDEVDOWN) @@ -636,8 +631,6 @@ COMPATIBLE_IOCTL(BNEPCONNADD) COMPATIBLE_IOCTL(BNEPCONNDEL) COMPATIBLE_IOCTL(BNEPGETCONNLIST) COMPATIBLE_IOCTL(BNEPGETCONNINFO) -#endif -#ifdef CONFIG_PCI /* Misc. */ COMPATIBLE_IOCTL(0x41545900) /* ATYIO_CLKR */ COMPATIBLE_IOCTL(0x41545901) /* ATYIO_CLKW */ @@ -645,8 +638,6 @@ COMPATIBLE_IOCTL(PCIIOC_CONTROLLER) COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_IO) COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_MEM) COMPATIBLE_IOCTL(PCIIOC_WRITE_COMBINE) -#endif -#if defined(CONFIG_USB) || defined(CONFIG_USB_MODULE) /* USB */ COMPATIBLE_IOCTL(USBDEVFS_RESETEP) COMPATIBLE_IOCTL(USBDEVFS_SETINTERFACE) @@ -659,8 +650,6 @@ COMPATIBLE_IOCTL(USBDEVFS_CONNECTINFO) COMPATIBLE_IOCTL(USBDEVFS_HUB_PORTINFO) COMPATIBLE_IOCTL(USBDEVFS_RESET) COMPATIBLE_IOCTL(USBDEVFS_CLEAR_HALT) -#endif -#if defined(CONFIG_MTD) || defined(CONFIG_MTD_MODULE) /* MTD */ COMPATIBLE_IOCTL(MEMGETINFO) COMPATIBLE_IOCTL(MEMERASE) @@ -668,16 +657,15 @@ COMPATIBLE_IOCTL(MEMLOCK) COMPATIBLE_IOCTL(MEMUNLOCK) COMPATIBLE_IOCTL(MEMGETREGIONCOUNT) COMPATIBLE_IOCTL(MEMGETREGIONINFO) -#endif /* NBD */ -COMPATIBLE_IOCTL(NBD_SET_SOCK) -COMPATIBLE_IOCTL(NBD_SET_BLKSIZE) -COMPATIBLE_IOCTL(NBD_SET_SIZE) +ULONG_IOCTL(NBD_SET_SOCK) +ULONG_IOCTL(NBD_SET_BLKSIZE) +ULONG_IOCTL(NBD_SET_SIZE) COMPATIBLE_IOCTL(NBD_DO_IT) COMPATIBLE_IOCTL(NBD_CLEAR_SOCK) COMPATIBLE_IOCTL(NBD_CLEAR_QUE) COMPATIBLE_IOCTL(NBD_PRINT_DEBUG) -COMPATIBLE_IOCTL(NBD_SET_SIZE_BLOCKS) +ULONG_IOCTL(NBD_SET_SIZE_BLOCKS) COMPATIBLE_IOCTL(NBD_DISCONNECT) /* i2c */ COMPATIBLE_IOCTL(I2C_SLAVE) _