diff --git a/arch/s390/include/asm/bug.h b/arch/s390/include/asm/bug.h index efb74fd5156e8f14590e012260dc6f568b627d3f..b1066b9fb5f89f84cb80fbfa38218ccca2c0ea0a 100644 --- a/arch/s390/include/asm/bug.h +++ b/arch/s390/include/asm/bug.h @@ -52,6 +52,10 @@ unreachable(); \ } while (0) +#define __WARN() do { \ + __EMIT_BUG(BUGFLAG_WARNING); \ +} while (0) + #define WARN_ON(x) ({ \ int __ret_warn_on = !!(x); \ if (__builtin_constant_p(__ret_warn_on)) { \ diff --git a/arch/s390/include/asm/sigp.h b/arch/s390/include/asm/sigp.h index ec403d4304f81c64d2fa2818187ba9731ef49944..f72d611f7e13d7dc0e4856e30ba3e55bb0c4c8f9 100644 --- a/arch/s390/include/asm/sigp.h +++ b/arch/s390/include/asm/sigp.h @@ -15,11 +15,19 @@ #ifndef __SIGP__ #define __SIGP__ -#include -#include +#include /* get real cpu address from logical cpu number */ -extern volatile int __cpu_logical_map[]; +extern int __cpu_logical_map[]; + +static inline int cpu_logical_map(int cpu) +{ +#ifdef CONFIG_SMP + return __cpu_logical_map[cpu]; +#else + return stap(); +#endif +} typedef enum { @@ -79,7 +87,7 @@ signal_processor(__u16 cpu_addr, sigp_order_code order_code) " ipm %0\n" " srl %0,28\n" : "=d" (ccode) - : "d" (reg1), "d" (__cpu_logical_map[cpu_addr]), + : "d" (reg1), "d" (cpu_logical_map(cpu_addr)), "a" (order_code) : "cc" , "memory"); return ccode; } @@ -98,7 +106,7 @@ signal_processor_p(__u32 parameter, __u16 cpu_addr, sigp_order_code order_code) " ipm %0\n" " srl %0,28\n" : "=d" (ccode) - : "d" (reg1), "d" (__cpu_logical_map[cpu_addr]), + : "d" (reg1), "d" (cpu_logical_map(cpu_addr)), "a" (order_code) : "cc" , "memory"); return ccode; } @@ -118,7 +126,7 @@ signal_processor_ps(__u32 *statusptr, __u32 parameter, __u16 cpu_addr, " ipm %0\n" " srl %0,28\n" : "=d" (ccode), "+d" (reg1) - : "d" (__cpu_logical_map[cpu_addr]), "a" (order_code) + : "d" (cpu_logical_map(cpu_addr)), "a" (order_code) : "cc" , "memory"); *statusptr = reg1; return ccode; diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h index 07eb61b2fb3a7f1b4e47bc1d5b180d7bddef0dc3..66069e7368423753d2239788cca0e7045300fe01 100644 --- a/arch/s390/include/asm/thread_info.h +++ b/arch/s390/include/asm/thread_info.h @@ -93,13 +93,12 @@ static inline struct thread_info *current_thread_info(void) #define TIF_SYSCALL_AUDIT 9 /* syscall auditing active */ #define TIF_SECCOMP 10 /* secure computing */ #define TIF_SYSCALL_TRACEPOINT 11 /* syscall tracepoint instrumentation */ -#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ -#define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling +#define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */ -#define TIF_31BIT 18 /* 32bit process */ -#define TIF_MEMDIE 19 -#define TIF_RESTORE_SIGMASK 20 /* restore signal mask in do_signal() */ -#define TIF_FREEZE 21 /* thread is freezing for suspend */ +#define TIF_31BIT 17 /* 32bit process */ +#define TIF_MEMDIE 18 +#define TIF_RESTORE_SIGMASK 19 /* restore signal mask in do_signal() */ +#define TIF_FREEZE 20 /* thread is freezing for suspend */ #define _TIF_NOTIFY_RESUME (1<> PAGE_SHIFT); -out: - return error; + return -EINVAL; + a.addr = (unsigned long) compat_ptr(a.addr); + return sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, + a.offset >> PAGE_SHIFT); } -asmlinkage long -sys32_mmap2(struct mmap_arg_struct_emu31 __user *arg) +asmlinkage long sys32_mmap2(struct mmap_arg_struct_emu31 __user *arg) { struct mmap_arg_struct_emu31 a; - int error = -EFAULT; if (copy_from_user(&a, arg, sizeof(a))) - goto out; - error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset); -out: - return error; + return -EFAULT; + a.addr = (unsigned long) compat_ptr(a.addr); + return sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset); } asmlinkage long sys32_read(unsigned int fd, char __user * buf, size_t count) diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index faeaccc7d7d98ddffccdfa83b41d92b341df57d5..30de2d0e52bb421e41efabd67cdbc677bb7e5539 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -1853,12 +1853,3 @@ sys32_execve_wrapper: llgtr %r3,%r3 # compat_uptr_t * llgtr %r4,%r4 # compat_uptr_t * jg sys32_execve # branch to system call - - .globl compat_sys_recvmmsg_wrapper -compat_sys_recvmmsg_wrapper: - lgfr %r2,%r2 # int - llgtr %r3,%r3 # struct compat_mmsghdr * - llgfr %r4,%r4 # unsigned int - llgfr %r5,%r5 # unsigned int - llgtr %r6,%r6 # struct compat_timespec * - jg compat_sys_recvmmsg diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 5417eb57271aed29ac041f948a27d20a9f42a25e..00b6d1d292f2a6efecf23d5abde930f89f68878b 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@ -153,8 +153,6 @@ void exit_thread(void) void flush_thread(void) { - clear_used_math(); - clear_tsk_thread_flag(current, TIF_USEDFPU); } void release_thread(struct task_struct *dead_task) @@ -217,6 +215,7 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp, p->thread.mm_segment = get_fs(); /* Don't copy debug registers */ memset(&p->thread.per_info, 0, sizeof(p->thread.per_info)); + clear_tsk_thread_flag(p, TIF_SINGLE_STEP); /* Initialize per thread user and system timer values */ ti = task_thread_info(p); ti->user_timer = 0; diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 13815d39f7dd2c757590c416298c71176f795f81..7cf46423441940a975de0c60cdbca6a736018921 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -65,6 +65,7 @@ FixPerRegisters(struct task_struct *task) { struct pt_regs *regs; per_struct *per_info; + per_cr_words cr_words; regs = task_pt_regs(task); per_info = (per_struct *) &task->thread.per_info; @@ -98,6 +99,13 @@ FixPerRegisters(struct task_struct *task) per_info->control_regs.bits.storage_alt_space_ctl = 1; else per_info->control_regs.bits.storage_alt_space_ctl = 0; + + if (task == current) { + __ctl_store(cr_words, 9, 11); + if (memcmp(&cr_words, &per_info->control_regs.words, + sizeof(cr_words)) != 0) + __ctl_load(per_info->control_regs.words, 9, 11); + } } void user_enable_single_step(struct task_struct *task) diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 0663287fa1b30f2c45d5cb24da59acf15608e914..8d8957b38ab3679210b036ab8343ce9852eda10f 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -87,7 +87,6 @@ unsigned long elf_hwcap = 0; char elf_platform[ELF_PLATFORM_SIZE]; struct mem_chunk __initdata memory_chunk[MEMORY_CHUNKS]; -volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */ int __initdata memory_end_set; unsigned long __initdata memory_end; @@ -124,12 +123,6 @@ void __cpuinit cpu_init(void) */ get_cpu_id(&S390_lowcore.cpu_id); - /* - * Force FPU initialization: - */ - clear_thread_flag(TIF_USEDFPU); - clear_used_math(); - atomic_inc(&init_mm.mm_count); current->active_mm = &init_mm; BUG_ON(current->mm); @@ -855,7 +848,6 @@ setup_arch(char **cmdline_p) setup_lowcore(); cpu_init(); - __cpu_logical_map[0] = stap(); s390_init_cpu_topology(); /* diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index 6b4fef877f9d0ccf0fd28ea654b9553ab3b70df9..1675c48b9145289bb2adbd82a102ae3d76cb8376 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c @@ -499,19 +499,11 @@ void do_signal(struct pt_regs *regs) if (test_thread_flag(TIF_RESTORE_SIGMASK)) clear_thread_flag(TIF_RESTORE_SIGMASK); - /* - * If we would have taken a single-step trap - * for a normal instruction, act like we took - * one for the handler setup. - */ - if (current->thread.per_info.single_step) - set_thread_flag(TIF_SINGLE_STEP); - /* * Let tracing know that we've done the handler setup. */ tracehook_signal_handler(signr, &info, &ka, regs, - test_thread_flag(TIF_SINGLE_STEP)); + current->thread.per_info.single_step); } return; } diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 93e52039321b1f6bcb2a89c335c3c9b4ef1c1104..76a6fdd46c451a8571636ce75cda725ace39cfbb 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -52,6 +52,9 @@ #include #include "entry.h" +/* logical cpu to cpu address */ +int __cpu_logical_map[NR_CPUS]; + static struct task_struct *current_set[NR_CPUS]; static u8 smp_cpu_type; @@ -717,6 +720,12 @@ void __init smp_cpus_done(unsigned int max_cpus) { } +void __init smp_setup_processor_id(void) +{ + S390_lowcore.cpu_nr = 0; + __cpu_logical_map[0] = stap(); +} + /* * the frequency of the profiling timer can be changed * by writing a multiplier value into /proc/profile. diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index 4f292c936872dbed56e0f82cc57184809c3b4321..30eca070d4268953d209b54394c99806afced91e 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -340,4 +340,3 @@ SYSCALL(sys_preadv,sys_preadv,compat_sys_preadv_wrapper) SYSCALL(sys_pwritev,sys_pwritev,compat_sys_pwritev_wrapper) SYSCALL(sys_rt_tgsigqueueinfo,sys_rt_tgsigqueueinfo,compat_sys_rt_tgsigqueueinfo_wrapper) /* 330 */ SYSCALL(sys_perf_event_open,sys_perf_event_open,sys_perf_event_open_wrapper) -SYSCALL(sys_recvmmsg,sys_recvmmsg,compat_sys_recvmmsg_wrapper) diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c index 3c72c9cf22b68f8f40a6b68d0da1972b9c112bf1..14ef6f05e4324b94f7146f0207e9203aa9a62df5 100644 --- a/arch/s390/kernel/topology.c +++ b/arch/s390/kernel/topology.c @@ -114,7 +114,7 @@ static void add_cpus_to_core(struct tl_cpu *tl_cpu, struct core_info *core) rcpu = CPU_BITS - 1 - cpu + tl_cpu->origin; for_each_present_cpu(lcpu) { - if (__cpu_logical_map[lcpu] == rcpu) { + if (cpu_logical_map(lcpu) == rcpu) { cpu_set(lcpu, core->mask); smp_cpu_polarization[lcpu] = tl_cpu->pp; } diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c index 10754a3756684900ea1570cc1c21b5d6bc800240..cff327f109a84b524e52d9fbea24c0ff2f12c325 100644 --- a/arch/s390/lib/spinlock.c +++ b/arch/s390/lib/spinlock.c @@ -34,7 +34,7 @@ static inline void _raw_yield_cpu(int cpu) { if (MACHINE_HAS_DIAG9C) asm volatile("diag %0,0,0x9c" - : : "d" (__cpu_logical_map[cpu])); + : : "d" (cpu_logical_map(cpu))); else _raw_yield(); } diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c index f4558ccf02b9cd266ad005cb2925a2dfa5d7ea89..869efbaed3eadf76db6c90de2bd75550fb630bf6 100644 --- a/arch/s390/mm/mmap.c +++ b/arch/s390/mm/mmap.c @@ -40,7 +40,7 @@ static inline unsigned long mmap_base(void) { - unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur; + unsigned long gap = rlimit(RLIMIT_STACK); if (gap < MIN_GAP) gap = MIN_GAP; @@ -61,7 +61,7 @@ static inline int mmap_is_legacy(void) #endif return sysctl_legacy_va_layout || (current->personality & ADDR_COMPAT_LAYOUT) || - current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY; + rlimit(RLIMIT_STACK) == RLIM_INFINITY; } #ifndef CONFIG_64BIT diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 5819dc02a143652402d1ae63ddea9add07582f4d..1c500c462225c7e2795369a185167b3c5735760d 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -2844,13 +2845,16 @@ static int dasd_symm_io(struct dasd_device *device, void __user *argp) rc = -EFAULT; if (copy_from_user(&usrparm, argp, sizeof(usrparm))) goto out; -#ifndef CONFIG_64BIT - /* Make sure pointers are sane even on 31 bit. */ - if ((usrparm.psf_data >> 32) != 0 || (usrparm.rssd_result >> 32) != 0) { + if (is_compat_task() || sizeof(long) == 4) { + /* Make sure pointers are sane even on 31 bit. */ rc = -EINVAL; - goto out; + if ((usrparm.psf_data >> 32) != 0) + goto out; + if ((usrparm.rssd_result >> 32) != 0) + goto out; + usrparm.psf_data &= 0x7fffffffULL; + usrparm.rssd_result &= 0x7fffffffULL; } -#endif /* alloc I/O data area */ psf_data = kzalloc(usrparm.psf_data_len, GFP_KERNEL | GFP_DMA); rssd_result = kzalloc(usrparm.rssd_result_len, GFP_KERNEL | GFP_DMA); diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c index 478bcdb90b6fbb29b9afbc1a66e267c2200bd530..fc7b30b4a2558c867e2369e0d5c08d28fa54ab2e 100644 --- a/drivers/s390/block/dasd_ioctl.c +++ b/drivers/s390/block/dasd_ioctl.c @@ -17,7 +17,7 @@ #include #include #include - +#include #include #include #include @@ -358,9 +358,8 @@ dasd_ioctl_set_ro(struct block_device *bdev, void __user *argp) } static int dasd_ioctl_readall_cmb(struct dasd_block *block, unsigned int cmd, - unsigned long arg) + struct cmbdata __user *argp) { - struct cmbdata __user *argp = (void __user *) arg; size_t size = _IOC_SIZE(cmd); struct cmbdata data; int ret; @@ -376,7 +375,12 @@ dasd_do_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { struct dasd_block *block = bdev->bd_disk->private_data; - void __user *argp = (void __user *)arg; + void __user *argp; + + if (is_compat_task()) + argp = compat_ptr(arg); + else + argp = (void __user *)arg; if (!block) return -ENODEV; @@ -414,7 +418,7 @@ dasd_do_ioctl(struct block_device *bdev, fmode_t mode, case BIODASDCMFDISABLE: return disable_cmf(block->base->cdev); case BIODASDREADALLCMB: - return dasd_ioctl_readall_cmb(block, cmd, arg); + return dasd_ioctl_readall_cmb(block, cmd, argp); default: /* if the discipline has an ioctl method try it. */ if (block->base->discipline->ioctl) { diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 9d61683b56337a11410692399854b00724f719d5..59ec073724bff327327d1cc8f27108e14254a572 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c @@ -1036,22 +1036,6 @@ static void tty3215_flush_buffer(struct tty_struct *tty) tty_wakeup(tty); } -/* - * Currently we don't have any io controls for 3215 ttys - */ -static int tty3215_ioctl(struct tty_struct *tty, struct file * file, - unsigned int cmd, unsigned long arg) -{ - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - - switch (cmd) { - default: - return -ENOIOCTLCMD; - } - return 0; -} - /* * Disable reading from a 3215 tty */ @@ -1117,7 +1101,6 @@ static const struct tty_operations tty3215_ops = { .write_room = tty3215_write_room, .chars_in_buffer = tty3215_chars_in_buffer, .flush_buffer = tty3215_flush_buffer, - .ioctl = tty3215_ioctl, .throttle = tty3215_throttle, .unthrottle = tty3215_unthrottle, .stop = tty3215_stop, diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c index 247b2b934728bacbcc4974ec04c3939fbc5c4764..31c59b0d6df0c1509a191ece52a77c3ba4f6e0ae 100644 --- a/drivers/s390/char/fs3270.c +++ b/drivers/s390/char/fs3270.c @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -322,6 +323,7 @@ fs3270_write(struct file *filp, const char __user *data, size_t count, loff_t *o static long fs3270_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { + char __user *argp; struct fs3270 *fp; struct raw3270_iocb iocb; int rc; @@ -329,6 +331,10 @@ fs3270_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) fp = filp->private_data; if (!fp) return -ENODEV; + if (is_compat_task()) + argp = compat_ptr(arg); + else + argp = (char __user *)arg; rc = 0; mutex_lock(&fs3270_mutex); switch (cmd) { @@ -339,10 +345,10 @@ fs3270_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) fp->write_command = arg; break; case TUBGETI: - rc = put_user(fp->read_command, (char __user *) arg); + rc = put_user(fp->read_command, argp); break; case TUBGETO: - rc = put_user(fp->write_command,(char __user *) arg); + rc = put_user(fp->write_command, argp); break; case TUBGETMOD: iocb.model = fp->view.model; @@ -351,8 +357,7 @@ fs3270_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) iocb.pf_cnt = 24; iocb.re_cnt = 20; iocb.map = 0; - if (copy_to_user((char __user *) arg, &iocb, - sizeof(struct raw3270_iocb))) + if (copy_to_user(argp, &iocb, sizeof(struct raw3270_iocb))) rc = -EFAULT; break; } @@ -511,8 +516,8 @@ static const struct file_operations fs3270_fops = { .write = fs3270_write, /* write */ .unlocked_ioctl = fs3270_ioctl, /* ioctl */ .compat_ioctl = fs3270_ioctl, /* ioctl */ - .open = fs3270_open, /* open */ - .release = fs3270_close, /* release */ + .open = fs3270_open, /* open */ + .release = fs3270_close, /* release */ }; /* diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c index 96816149368a94ad396a86a2d6622c14d01ae04a..8d3d720737da20879f1ac85b1f9da6a7432e99cd 100644 --- a/drivers/s390/char/tape_block.c +++ b/drivers/s390/char/tape_block.c @@ -46,8 +46,6 @@ */ static int tapeblock_open(struct block_device *, fmode_t); static int tapeblock_release(struct gendisk *, fmode_t); -static int tapeblock_ioctl(struct block_device *, fmode_t, unsigned int, - unsigned long); static int tapeblock_medium_changed(struct gendisk *); static int tapeblock_revalidate_disk(struct gendisk *); @@ -55,7 +53,6 @@ static const struct block_device_operations tapeblock_fops = { .owner = THIS_MODULE, .open = tapeblock_open, .release = tapeblock_release, - .ioctl = tapeblock_ioctl, .media_changed = tapeblock_medium_changed, .revalidate_disk = tapeblock_revalidate_disk, }; @@ -415,42 +412,6 @@ tapeblock_release(struct gendisk *disk, fmode_t mode) return 0; } -/* - * Support of some generic block device IOCTLs. - */ -static int -tapeblock_ioctl( - struct block_device * bdev, - fmode_t mode, - unsigned int command, - unsigned long arg -) { - int rc; - int minor; - struct gendisk *disk = bdev->bd_disk; - struct tape_device *device; - - rc = 0; - BUG_ON(!disk); - device = disk->private_data; - BUG_ON(!device); - minor = MINOR(bdev->bd_dev); - - DBF_LH(6, "tapeblock_ioctl(0x%0x)\n", command); - DBF_LH(6, "device = %d:%d\n", tapeblock_major, minor); - - switch (command) { - /* Refuse some IOCTL calls without complaining (mount). */ - case 0x5310: /* CDROMMULTISESSION */ - rc = -EINVAL; - break; - default: - rc = -EINVAL; - } - - return rc; -} - /* * Initialize block device frontend. */ diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c index 2125ec7d95f0231223d5351b3e0daa7423f2594b..539045acaad42875e03f7225f0249b55251c8e30 100644 --- a/drivers/s390/char/tape_char.c +++ b/drivers/s390/char/tape_char.c @@ -18,6 +18,7 @@ #include #include #include +#include #include @@ -37,8 +38,9 @@ static ssize_t tapechar_write(struct file *, const char __user *, size_t, loff_t static int tapechar_open(struct inode *,struct file *); static int tapechar_release(struct inode *,struct file *); static long tapechar_ioctl(struct file *, unsigned int, unsigned long); -static long tapechar_compat_ioctl(struct file *, unsigned int, - unsigned long); +#ifdef CONFIG_COMPAT +static long tapechar_compat_ioctl(struct file *, unsigned int, unsigned long); +#endif static const struct file_operations tape_fops = { @@ -46,7 +48,9 @@ static const struct file_operations tape_fops = .read = tapechar_read, .write = tapechar_write, .unlocked_ioctl = tapechar_ioctl, +#ifdef CONFIG_COMPAT .compat_ioctl = tapechar_compat_ioctl, +#endif .open = tapechar_open, .release = tapechar_release, }; @@ -457,15 +461,22 @@ tapechar_ioctl(struct file *filp, unsigned int no, unsigned long data) return rc; } +#ifdef CONFIG_COMPAT static long tapechar_compat_ioctl(struct file *filp, unsigned int no, unsigned long data) { struct tape_device *device = filp->private_data; int rval = -ENOIOCTLCMD; + unsigned long argp; + /* The 'arg' argument of any ioctl function may only be used for + * pointers because of the compat pointer conversion. + * Consider this when adding new ioctls. + */ + argp = (unsigned long) compat_ptr(data); if (device->discipline->ioctl_fn) { mutex_lock(&device->mutex); - rval = device->discipline->ioctl_fn(device, no, data); + rval = device->discipline->ioctl_fn(device, no, argp); mutex_unlock(&device->mutex); if (rval == -EINVAL) rval = -ENOIOCTLCMD; @@ -473,6 +484,7 @@ tapechar_compat_ioctl(struct file *filp, unsigned int no, unsigned long data) return rval; } +#endif /* CONFIG_COMPAT */ /* * Initialize character device frontend. diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c index a6087cec55b463fc0237e1fe1774d010a69d038e..921dcda77676b1e94f6e857c695a8d36737c9c5c 100644 --- a/drivers/s390/char/vmcp.c +++ b/drivers/s390/char/vmcp.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -139,21 +140,26 @@ vmcp_write(struct file *file, const char __user *buff, size_t count, static long vmcp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct vmcp_session *session; + int __user *argp; int temp; session = (struct vmcp_session *)file->private_data; + if (is_compat_task()) + argp = compat_ptr(arg); + else + argp = (int __user *)arg; if (mutex_lock_interruptible(&session->mutex)) return -ERESTARTSYS; switch (cmd) { case VMCP_GETCODE: temp = session->resp_code; mutex_unlock(&session->mutex); - return put_user(temp, (int __user *)arg); + return put_user(temp, argp); case VMCP_SETBUF: free_pages((unsigned long)session->response, get_order(session->bufsize)); session->response=NULL; - temp = get_user(session->bufsize, (int __user *)arg); + temp = get_user(session->bufsize, argp); if (get_order(session->bufsize) > 8) { session->bufsize = PAGE_SIZE; temp = -EINVAL; @@ -163,7 +169,7 @@ static long vmcp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case VMCP_GETSIZE: temp = session->resp_size; mutex_unlock(&session->mutex); - return put_user(temp, (int __user *)arg); + return put_user(temp, argp); default: mutex_unlock(&session->mutex); return -ENOIOCTLCMD; diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c index cc5144b6f9d9c590f56bdb9112774130f23f97ed..c84ac9443079fb2b616f72c2bc56479528e03aed 100644 --- a/drivers/s390/cio/chsc_sch.c +++ b/drivers/s390/cio/chsc_sch.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -770,24 +771,30 @@ static int chsc_ioctl_dcal(void __user *user_dcal) static long chsc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { + void __user *argp; + CHSC_MSG(2, "chsc_ioctl called, cmd=%x\n", cmd); + if (is_compat_task()) + argp = compat_ptr(arg); + else + argp = (void __user *)arg; switch (cmd) { case CHSC_START: - return chsc_ioctl_start((void __user *)arg); + return chsc_ioctl_start(argp); case CHSC_INFO_CHANNEL_PATH: - return chsc_ioctl_info_channel_path((void __user *)arg); + return chsc_ioctl_info_channel_path(argp); case CHSC_INFO_CU: - return chsc_ioctl_info_cu((void __user *)arg); + return chsc_ioctl_info_cu(argp); case CHSC_INFO_SCH_CU: - return chsc_ioctl_info_sch_cu((void __user *)arg); + return chsc_ioctl_info_sch_cu(argp); case CHSC_INFO_CI: - return chsc_ioctl_conf_info((void __user *)arg); + return chsc_ioctl_conf_info(argp); case CHSC_INFO_CCL: - return chsc_ioctl_conf_comp_list((void __user *)arg); + return chsc_ioctl_conf_comp_list(argp); case CHSC_INFO_CPD: - return chsc_ioctl_chpd((void __user *)arg); + return chsc_ioctl_chpd(argp); case CHSC_INFO_DCAL: - return chsc_ioctl_dcal((void __user *)arg); + return chsc_ioctl_dcal(argp); default: /* unknown ioctl number */ return -ENOIOCTLCMD; } diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c index 0d4d18bdd45ca26ab685fa112eb752be5a3ded5f..c68be24e27d97cab0d2f80482fd5c9c51be0c60f 100644 --- a/drivers/s390/crypto/zcrypt_api.c +++ b/drivers/s390/crypto/zcrypt_api.c @@ -393,10 +393,12 @@ static long zcrypt_rsa_crt(struct ica_rsa_modexpo_crt *crt) * u_mult_inv > 128 bytes. */ if (copied == 0) { - int len; + unsigned int len; spin_unlock_bh(&zcrypt_device_lock); /* len is max 256 / 2 - 120 = 8 */ len = crt->inputdatalength / 2 - 120; + if (len > sizeof(z1)) + return -EFAULT; z1 = z2 = z3 = 0; if (copy_from_user(&z1, crt->np_prime, len) || copy_from_user(&z2, crt->bp_key, len) ||