From 03e4c49f847f23c62900424f65a62f76de5a7151 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 23 Jan 2009 16:40:23 +0100 Subject: [PATCH 1/5] [S390] personality: fix personality loss on execve Use the personality() macro to mask out all bits that are not relevant for the personality type. The personality field contains bits for other things as well, so without masking out the not relevalent bits the comparison won't do what is expected. Reported-by: Andreas Krebbel Signed-off-by: Heiko Carstens --- arch/s390/include/asm/elf.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/s390/include/asm/elf.h b/arch/s390/include/asm/elf.h index d480f39d65e6..74d0bbb7d955 100644 --- a/arch/s390/include/asm/elf.h +++ b/arch/s390/include/asm/elf.h @@ -172,14 +172,14 @@ extern char elf_platform[]; #ifndef __s390x__ #define SET_PERSONALITY(ex) set_personality(PER_LINUX) #else /* __s390x__ */ -#define SET_PERSONALITY(ex) \ -do { \ - if (current->personality != PER_LINUX32) \ - set_personality(PER_LINUX); \ - if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ - set_thread_flag(TIF_31BIT); \ - else \ - clear_thread_flag(TIF_31BIT); \ +#define SET_PERSONALITY(ex) \ +do { \ + if (personality(current->personality) != PER_LINUX32) \ + set_personality(PER_LINUX); \ + if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ + set_thread_flag(TIF_31BIT); \ + else \ + clear_thread_flag(TIF_31BIT); \ } while (0) #endif /* __s390x__ */ From e9a4e9d563ea643d305b5fe83031d7deca311db3 Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Fri, 23 Jan 2009 16:40:24 +0100 Subject: [PATCH 2/5] [S390] fix compat sigaltstack syscall table entry When 31 bit user space programs call sigaltstack on a 64 bit Linux OS, the system call returns -1 with errno=EFAULT. The 31 bit pointer passed to the system call is extended to 64 bit, but the high order bits are not set to zero. The kernel detects the invalid user space pointer and returns -EFAULT. To solve the problem, sys32_sigaltstack_wrapper() instead of sys32_sigaltstack() has to be called. The wrapper function sets the high order bits to zero. Signed-off-by: Michael Holzheu Signed-off-by: Heiko Carstens --- arch/s390/kernel/syscalls.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index 76d16e0140bb..3e18d8a5e614 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -194,7 +194,7 @@ SYSCALL(sys_chown16,sys_ni_syscall,sys32_chown16_wrapper) /* old chown16 syscall SYSCALL(sys_getcwd,sys_getcwd,sys32_getcwd_wrapper) SYSCALL(sys_capget,sys_capget,sys32_capget_wrapper) SYSCALL(sys_capset,sys_capset,sys32_capset_wrapper) /* 185 */ -SYSCALL(sys_sigaltstack,sys_sigaltstack,sys32_sigaltstack) +SYSCALL(sys_sigaltstack,sys_sigaltstack,sys32_sigaltstack_wrapper) SYSCALL(sys_sendfile,sys_sendfile64,sys32_sendfile_wrapper) NI_SYSCALL /* streams1 */ NI_SYSCALL /* streams2 */ From f9a2f797fcde5a4aa818bd3ca8584fd1197e9c15 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 23 Jan 2009 16:40:25 +0100 Subject: [PATCH 3/5] [S390] cputime: fix lowcore initialization on cpu hotplug On (initial) cpu hotplug the lowcore values for user_timer and system_timer don't get initialized like they would get on each process schedule. On initial start of secondary cpus this leads to the situation where per thread user/system_timer values are larger than the corresponding contents of the lowcore. When later calculating time spent in user/system context the result can be negative. So for cpu hotplug we should manually initialize lowcore values. Fixes this bug: Kernel BUG at 000ec080 [verbose debug info unavailable] fixpoint divide exception: 0009 [#1] PREEMPT SMP Modules linked in: CPU: 10 Not tainted 2.6.28 #4 Process sysctl (pid: 975, task: 3fa752e0, ksp: 3fbebca0) Krnl PSW : 070c1000 800ec080 (show_stat+0x390/0x5fc) R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:0 CC:1 PM:0 Krnl GPRS: 7fffffff fefc7ce5 3faec080 003879ae 00000001 01388000 7fffffff 01388000 00000000 00000000 0049ad50 3fbebcf8 01388000 002f51a8 800ec1fe 3fbebcf8 Krnl Code: 800ec076: 9001b188 stm %r0,%r1,392(%r11) 800ec07a: 9801b0c0 lm %r0,%r1,192(%r11) 800ec07e: 1d05 dr %r0,%r5 >800ec080: 9001b0c0 stm %r0,%r1,192(%r11) 800ec084: 5860b0c4 l %r6,196(%r11) 800ec088: 1806 lr %r0,%r6 800ec08a: 8c800001 srdl %r8,1 800ec08e: 1d87 dr %r8,%r7 Call Trace: ([<00000000000ec1ee>] show_stat+0x4fe/0x5fc) [<00000000000c13e8>] seq_read+0xc4/0x3ac [<00000000000e4796>] proc_reg_read+0x6e/0x9c [<00000000000a6a44>] vfs_read+0x78/0x100 [<00000000000a6ba8>] sys_read+0x40/0x80 [<00000000000234a8>] sysc_do_restart+0x1a/0x1e Signed-off-by: Heiko Carstens --- arch/s390/kernel/vtime.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index 2fb36e462194..ecf0304e61c1 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c @@ -516,8 +516,12 @@ EXPORT_SYMBOL(del_virt_timer); */ void init_cpu_vtimer(void) { + struct thread_info *ti = current_thread_info(); struct vtimer_queue *vq; + S390_lowcore.user_timer = ti->user_timer; + S390_lowcore.system_timer = ti->system_timer; + /* kick the virtual timer */ asm volatile ("STCK %0" : "=m" (S390_lowcore.last_update_clock)); asm volatile ("STPT %0" : "=m" (S390_lowcore.last_update_timer)); From 179cb81aa1e9dc5444f678a6dd4dbb90c60322e1 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 23 Jan 2009 16:40:26 +0100 Subject: [PATCH 4/5] [S390] etr/stp: fix possible deadlock Precreate stop_machine threads in case the machine supports ETR/STP. Otherwise we might deadlock if a time sync operation gets scheduled and the creation of stop_machine threads would cause disk I/O. This is just the minimal fix. The real fix would be to only precreate stop_machine threads if ETR/STP is actually used. But that would be a rather large and complicated patch. Signed-off-by: Heiko Carstens --- arch/s390/kernel/time.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index d649600df5b9..fc468cae4460 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -399,8 +399,10 @@ static struct workqueue_struct *time_sync_wq; static void __init time_init_wq(void) { - if (!time_sync_wq) - time_sync_wq = create_singlethread_workqueue("timesync"); + if (time_sync_wq) + return; + time_sync_wq = create_singlethread_workqueue("timesync"); + stop_machine_create(); } /* From e34a6280419a24297e6603075ac5af6ce9f13562 Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Fri, 23 Jan 2009 16:40:27 +0100 Subject: [PATCH 5/5] [S390] Add missing compat system call wrappers. Add wrapper functions for the following compat system calls: * readahead * sendfile64 * tkill * tgkill * keyctl This ensures that the high order bits of the parameter registers are correctly sign extended. Signed-off-by: Michael Holzheu Signed-off-by: Heiko Carstens --- arch/s390/kernel/compat_wrapper.S | 38 +++++++++++++++++++++++++++++++ arch/s390/kernel/syscalls.S | 10 ++++---- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 6035cd20c7a7..62c706eb0de6 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -1767,3 +1767,41 @@ sys_dup3_wrapper: sys_epoll_create1_wrapper: lgfr %r2,%r2 # int jg sys_epoll_create1 # branch to system call + + .globl sys32_readahead_wrapper +sys32_readahead_wrapper: + lgfr %r2,%r2 # int + llgfr %r3,%r3 # u32 + llgfr %r4,%r4 # u32 + lgfr %r5,%r5 # s32 + jg sys32_readahead # branch to system call + + .globl sys32_sendfile64_wrapper +sys32_sendfile64_wrapper: + lgfr %r2,%r2 # int + lgfr %r3,%r3 # int + llgtr %r4,%r4 # compat_loff_t * + lgfr %r5,%r5 # s32 + jg sys32_sendfile64 # branch to system call + + .globl sys_tkill_wrapper +sys_tkill_wrapper: + lgfr %r2,%r2 # pid_t + lgfr %r3,%r3 # int + jg sys_tkill # branch to system call + + .globl sys_tgkill_wrapper +sys_tgkill_wrapper: + lgfr %r2,%r2 # pid_t + lgfr %r3,%r3 # pid_t + lgfr %r4,%r4 # int + jg sys_tgkill # branch to system call + + .globl compat_sys_keyctl_wrapper +compat_sys_keyctl_wrapper: + llgfr %r2,%r2 # u32 + llgfr %r3,%r3 # u32 + llgfr %r4,%r4 # u32 + llgfr %r5,%r5 # u32 + llgfr %r6,%r6 # u32 + jg compat_sys_keyctl # branch to system call diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index 3e18d8a5e614..fe5b25a988ab 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -230,8 +230,8 @@ SYSCALL(sys_mincore,sys_mincore,sys32_mincore_wrapper) SYSCALL(sys_madvise,sys_madvise,sys32_madvise_wrapper) SYSCALL(sys_getdents64,sys_getdents64,sys32_getdents64_wrapper) /* 220 */ SYSCALL(sys_fcntl64,sys_ni_syscall,compat_sys_fcntl64_wrapper) -SYSCALL(sys_readahead,sys_readahead,sys32_readahead) -SYSCALL(sys_sendfile64,sys_ni_syscall,sys32_sendfile64) +SYSCALL(sys_readahead,sys_readahead,sys32_readahead_wrapper) +SYSCALL(sys_sendfile64,sys_ni_syscall,sys32_sendfile64_wrapper) SYSCALL(sys_setxattr,sys_setxattr,sys32_setxattr_wrapper) SYSCALL(sys_lsetxattr,sys_lsetxattr,sys32_lsetxattr_wrapper) /* 225 */ SYSCALL(sys_fsetxattr,sys_fsetxattr,sys32_fsetxattr_wrapper) @@ -245,11 +245,11 @@ SYSCALL(sys_removexattr,sys_removexattr,sys32_removexattr_wrapper) SYSCALL(sys_lremovexattr,sys_lremovexattr,sys32_lremovexattr_wrapper) SYSCALL(sys_fremovexattr,sys_fremovexattr,sys32_fremovexattr_wrapper) /* 235 */ SYSCALL(sys_gettid,sys_gettid,sys_gettid) -SYSCALL(sys_tkill,sys_tkill,sys_tkill) +SYSCALL(sys_tkill,sys_tkill,sys_tkill_wrapper) SYSCALL(sys_futex,sys_futex,compat_sys_futex_wrapper) SYSCALL(sys_sched_setaffinity,sys_sched_setaffinity,sys32_sched_setaffinity_wrapper) SYSCALL(sys_sched_getaffinity,sys_sched_getaffinity,sys32_sched_getaffinity_wrapper) /* 240 */ -SYSCALL(sys_tgkill,sys_tgkill,sys_tgkill) +SYSCALL(sys_tgkill,sys_tgkill,sys_tgkill_wrapper) NI_SYSCALL /* reserved for TUX */ SYSCALL(sys_io_setup,sys_io_setup,sys32_io_setup_wrapper) SYSCALL(sys_io_destroy,sys_io_destroy,sys32_io_destroy_wrapper) @@ -288,7 +288,7 @@ SYSCALL(sys_mq_getsetattr,sys_mq_getsetattr,compat_sys_mq_getsetattr_wrapper) SYSCALL(sys_kexec_load,sys_kexec_load,compat_sys_kexec_load_wrapper) SYSCALL(sys_add_key,sys_add_key,compat_sys_add_key_wrapper) SYSCALL(sys_request_key,sys_request_key,compat_sys_request_key_wrapper) -SYSCALL(sys_keyctl,sys_keyctl,compat_sys_keyctl) /* 280 */ +SYSCALL(sys_keyctl,sys_keyctl,compat_sys_keyctl_wrapper) /* 280 */ SYSCALL(sys_waitid,sys_waitid,compat_sys_waitid_wrapper) SYSCALL(sys_ioprio_set,sys_ioprio_set,sys_ioprio_set_wrapper) SYSCALL(sys_ioprio_get,sys_ioprio_get,sys_ioprio_get_wrapper)