From dd02f06aa96ab4590da12704366450a2d4753d3c Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 13 Feb 2007 00:50:57 +0000 Subject: [MIPS] signal: Fix warnings in o32 compat code. Signed-off-by: Ralf Baechle --- arch/mips/kernel/signal32.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c index 183fc7e55f3..1b9262d3fd2 100644 --- a/arch/mips/kernel/signal32.c +++ b/arch/mips/kernel/signal32.c @@ -139,8 +139,20 @@ struct ucontext32 { sigset_t32 uc_sigmask; /* mask last for extensibility */ }; +/* + * Horribly complicated - with the bloody RM9000 workarounds enabled + * the signal trampolines is moving to the end of the structure so we can + * increase the alignment without breaking software compatibility. + */ #if ICACHE_REFILLS_WORKAROUND_WAR == 0 +struct sigframe32 { + u32 sf_ass[4]; /* argument save space for o32 */ + u32 sf_code[2]; /* signal trampoline */ + struct sigcontext32 sf_sc; + sigset_t sf_mask; +}; + struct rt_sigframe32 { u32 rs_ass[4]; /* argument save space for o32 */ u32 rs_code[2]; /* signal trampoline */ @@ -150,6 +162,14 @@ struct rt_sigframe32 { #else /* ICACHE_REFILLS_WORKAROUND_WAR */ +struct sigframe32 { + u32 sf_ass[4]; /* argument save space for o32 */ + u32 sf_pad[2]; + struct sigcontext32 sf_sc; /* hw context */ + sigset_t sf_mask; + u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */ +}; + struct rt_sigframe32 { u32 rs_ass[4]; /* argument save space for o32 */ u32 rs_pad[2]; @@ -493,10 +513,10 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from) asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs) { - struct sigframe __user *frame; + struct sigframe32 __user *frame; sigset_t blocked; - frame = (struct sigframe __user *) regs.regs[29]; + frame = (struct sigframe32 __user *) regs.regs[29]; if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) goto badframe; if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked))) @@ -581,7 +601,7 @@ badframe: int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs, int signr, sigset_t *set) { - struct sigframe __user *frame; + struct sigframe32 __user *frame; int err = 0; frame = get_sigframe(ka, regs, sizeof(*frame)); -- cgit v1.2.3 From 205d84aaea380bbd1cc1079d44086cd50c2c2dad Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 13 Feb 2007 01:28:09 +0000 Subject: [MIPS] signal: Move {restore,setup}_sigcontext prototypes to their user Signed-off-by: Ralf Baechle --- arch/mips/kernel/signal-common.h | 6 ------ arch/mips/kernel/signal_n32.c | 4 ++++ 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/signal-common.h b/arch/mips/kernel/signal-common.h index 9a8abd67ec5..d9a832f67e8 100644 --- a/arch/mips/kernel/signal-common.h +++ b/arch/mips/kernel/signal-common.h @@ -45,12 +45,6 @@ struct sigframe { #endif /* !ICACHE_REFILLS_WORKAROUND_WAR */ -/* - * handle hardware context - */ -extern int setup_sigcontext(struct pt_regs *, struct sigcontext __user *); -extern int restore_sigcontext(struct pt_regs *, struct sigcontext __user *); - /* * Determine which stack to use.. */ diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c index 57456e6a0c6..b17ef04691e 100644 --- a/arch/mips/kernel/signal_n32.c +++ b/arch/mips/kernel/signal_n32.c @@ -49,6 +49,10 @@ #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) +extern int setup_sigcontext(struct pt_regs *, struct sigcontext __user *); +extern int restore_sigcontext(struct pt_regs *, struct sigcontext __user *); + + /* IRIX compatible stack_t */ typedef struct sigaltstack32 { s32 ss_sp; -- cgit v1.2.3 From 66680583461d7cae281cef63c050c9b6371e3286 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 13 Feb 2007 01:31:48 +0000 Subject: [MIPS] signal: Move sigframe definition for native O32/N64 into signal.c Signed-off-by: Ralf Baechle --- arch/mips/kernel/signal-common.h | 26 -------------------------- arch/mips/kernel/signal.c | 20 ++++++++++++++++++++ 2 files changed, 20 insertions(+), 26 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/signal-common.h b/arch/mips/kernel/signal-common.h index d9a832f67e8..b95e542ace2 100644 --- a/arch/mips/kernel/signal-common.h +++ b/arch/mips/kernel/signal-common.h @@ -19,32 +19,6 @@ # define DEBUGP(fmt, args...) #endif -/* - * Horribly complicated - with the bloody RM9000 workarounds enabled - * the signal trampolines is moving to the end of the structure so we can - * increase the alignment without breaking software compatibility. - */ -#if ICACHE_REFILLS_WORKAROUND_WAR == 0 - -struct sigframe { - u32 sf_ass[4]; /* argument save space for o32 */ - u32 sf_code[2]; /* signal trampoline */ - struct sigcontext sf_sc; - sigset_t sf_mask; -}; - -#else /* ICACHE_REFILLS_WORKAROUND_WAR */ - -struct sigframe { - u32 sf_ass[4]; /* argument save space for o32 */ - u32 sf_pad[2]; - struct sigcontext sf_sc; /* hw context */ - sigset_t sf_mask; - u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */ -}; - -#endif /* !ICACHE_REFILLS_WORKAROUND_WAR */ - /* * Determine which stack to use.. */ diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index 54398af2371..e7b04928cae 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c @@ -36,8 +36,20 @@ #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) +/* + * Horribly complicated - with the bloody RM9000 workarounds enabled + * the signal trampolines is moving to the end of the structure so we can + * increase the alignment without breaking software compatibility. + */ #if ICACHE_REFILLS_WORKAROUND_WAR == 0 +struct sigframe { + u32 sf_ass[4]; /* argument save space for o32 */ + u32 sf_code[2]; /* signal trampoline */ + struct sigcontext sf_sc; + sigset_t sf_mask; +}; + struct rt_sigframe { u32 rs_ass[4]; /* argument save space for o32 */ u32 rs_code[2]; /* signal trampoline */ @@ -47,6 +59,14 @@ struct rt_sigframe { #else +struct sigframe { + u32 sf_ass[4]; /* argument save space for o32 */ + u32 sf_pad[2]; + struct sigcontext sf_sc; /* hw context */ + sigset_t sf_mask; + u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */ +}; + struct rt_sigframe { u32 rs_ass[4]; /* argument save space for o32 */ u32 rs_pad[2]; -- cgit v1.2.3 From 24c556e99ec8a61ce1fbc75bee61dc19edf2c4df Mon Sep 17 00:00:00 2001 From: Franck Bui-Huu Date: Fri, 9 Feb 2007 16:07:37 +0100 Subject: [MIPS] signals: make common _BLOCKABLE macro Signed-off-by: Franck Bui-Huu Signed-off-by: Ralf Baechle --- arch/mips/kernel/signal-common.h | 2 ++ arch/mips/kernel/signal.c | 2 -- arch/mips/kernel/signal32.c | 2 -- arch/mips/kernel/signal_n32.c | 2 -- 4 files changed, 2 insertions(+), 6 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/signal-common.h b/arch/mips/kernel/signal-common.h index b95e542ace2..fdbdbdc65b5 100644 --- a/arch/mips/kernel/signal-common.h +++ b/arch/mips/kernel/signal-common.h @@ -19,6 +19,8 @@ # define DEBUGP(fmt, args...) #endif +#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) + /* * Determine which stack to use.. */ diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index e7b04928cae..b2e9ab1bb10 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c @@ -34,8 +34,6 @@ #include "signal-common.h" -#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) - /* * Horribly complicated - with the bloody RM9000 workarounds enabled * the signal trampolines is moving to the end of the structure so we can diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c index 1b9262d3fd2..db00c333bff 100644 --- a/arch/mips/kernel/signal32.c +++ b/arch/mips/kernel/signal32.c @@ -104,8 +104,6 @@ typedef struct compat_siginfo { #define __NR_O32_rt_sigreturn 4193 #define __NR_O32_restart_syscall 4253 -#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) - /* 32-bit compatibility types */ #define _NSIG_BPW32 32 diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c index b17ef04691e..1a5f248faf3 100644 --- a/arch/mips/kernel/signal_n32.c +++ b/arch/mips/kernel/signal_n32.c @@ -47,8 +47,6 @@ #define __NR_N32_rt_sigreturn 6211 #define __NR_N32_restart_syscall 6214 -#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) - extern int setup_sigcontext(struct pt_regs *, struct sigcontext __user *); extern int restore_sigcontext(struct pt_regs *, struct sigcontext __user *); -- cgit v1.2.3 From 7da8a581f5ec0ecac5f0afc9ec26ce13b780d48d Mon Sep 17 00:00:00 2001 From: Franck Bui-Huu Date: Tue, 13 Feb 2007 14:50:18 +0100 Subject: [MIPS] Make entry.S a little more readable. When CONFIG_PREEMPT is not set, it also moves one branch instruction from ret_from_irq() to ret_from_exception(). Therefore we favour the return from irq case which should be more common than the other one. Signed-off-by: Franck Bui-Huu Acked-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/kernel/entry.S | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S index f10b6a19f8b..0b78fcbf044 100644 --- a/arch/mips/kernel/entry.S +++ b/arch/mips/kernel/entry.S @@ -21,24 +21,21 @@ #endif #ifndef CONFIG_PREEMPT - .macro preempt_stop - local_irq_disable - .endm #define resume_kernel restore_all +#else +#define __ret_from_irq ret_from_exception #endif .text .align 5 -FEXPORT(ret_from_irq) - LONG_S s0, TI_REGS($28) -#ifdef CONFIG_PREEMPT -FEXPORT(ret_from_exception) -#else - b _ret_from_irq +#ifndef CONFIG_PREEMPT FEXPORT(ret_from_exception) - preempt_stop + local_irq_disable # preempt stop + b __ret_from_irq #endif -FEXPORT(_ret_from_irq) +FEXPORT(ret_from_irq) + LONG_S s0, TI_REGS($28) +FEXPORT(__ret_from_irq) LONG_L t0, PT_STATUS(sp) # returning to kernel mode? andi t0, t0, KU_USER beqz t0, resume_kernel -- cgit v1.2.3 From 431dc8040354db65e4f8d4d4e21ae4fab41f5bc3 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 13 Feb 2007 00:05:11 +0000 Subject: [MIPS] Fix sigset_t endianess swapping issues in 32-bit compat code. Signed-off-by: Ralf Baechle --- arch/mips/kernel/linux32.c | 47 ++++++++++++++++++++++++++++++++++++++++++ arch/mips/kernel/scall64-64.S | 2 +- arch/mips/kernel/scall64-n32.S | 2 +- arch/mips/kernel/signal32.c | 11 ++++++---- arch/mips/kernel/signal_n32.c | 7 ++++--- 5 files changed, 60 insertions(+), 9 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index ca7ad78f4de..fc4dd6c9dd8 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c @@ -39,6 +39,7 @@ #include #include +#include #include #include #include @@ -736,3 +737,49 @@ _sys32_clone(nabi_no_regargs struct pt_regs regs) return do_fork(clone_flags, newsp, ®s, 0, parent_tidptr, child_tidptr); } + +/* + * Implement the event wait interface for the eventpoll file. It is the kernel + * part of the user space epoll_pwait(2). + */ +asmlinkage long compat_sys_epoll_pwait(int epfd, + struct epoll_event __user *events, int maxevents, int timeout, + const compat_sigset_t __user *sigmask, size_t sigsetsize) +{ + int error; + sigset_t ksigmask, sigsaved; + + /* + * If the caller wants a certain signal mask to be set during the wait, + * we apply it here. + */ + if (sigmask) { + if (sigsetsize != sizeof(sigset_t)) + return -EINVAL; + if (!access_ok(VERIFY_READ, sigmask, sizeof(ksigmask))) + return -EFAULT; + if (__copy_conv_sigset_from_user(&ksigmask, sigmask)) + return -EFAULT; + sigdelsetmask(&ksigmask, sigmask(SIGKILL) | sigmask(SIGSTOP)); + sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved); + } + + error = sys_epoll_wait(epfd, events, maxevents, timeout); + + /* + * If we changed the signal mask, we need to restore the original one. + * In case we've got a signal while waiting, we do not restore the + * signal mask yet, and we allow do_signal() to deliver the signal on + * the way back to userspace, before the signal mask is restored. + */ + if (sigmask) { + if (error == -EINTR) { + memcpy(¤t->saved_sigmask, &sigsaved, + sizeof(sigsaved)); + set_thread_flag(TIF_RESTORE_SIGMASK); + } else + sigprocmask(SIG_SETMASK, &sigsaved, NULL); + } + + return error; +} diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index e569b846e9a..10e9a18630a 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S @@ -470,4 +470,4 @@ sys_call_table: PTR sys_get_robust_list PTR sys_kexec_load /* 5270 */ PTR sys_getcpu - PTR sys_epoll_pwait + PTR compat_sys_epoll_pwait diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index ee8802b5975..2ceda4644a4 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -396,4 +396,4 @@ EXPORT(sysn32_call_table) PTR compat_sys_get_robust_list PTR compat_sys_kexec_load PTR sys_getcpu - PTR sys_epoll_pwait + PTR compat_sys_epoll_pwait diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c index db00c333bff..c28cb21514c 100644 --- a/arch/mips/kernel/signal32.c +++ b/arch/mips/kernel/signal32.c @@ -8,6 +8,7 @@ * Copyright (C) 1999, 2000 Silicon Graphics, Inc. */ #include +#include #include #include #include @@ -24,6 +25,7 @@ #include #include +#include #include #include #include @@ -517,7 +519,7 @@ asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs) frame = (struct sigframe32 __user *) regs.regs[29]; if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) goto badframe; - if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked))) + if (__copy_conv_sigset_from_user(&blocked, &frame->sf_mask)) goto badframe; sigdelsetmask(&blocked, ~_BLOCKABLE); @@ -554,7 +556,7 @@ asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) frame = (struct rt_sigframe32 __user *) regs.regs[29]; if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) goto badframe; - if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set))) + if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask)) goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); @@ -609,7 +611,8 @@ int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs, err |= install_sigtramp(frame->sf_code, __NR_O32_sigreturn); err |= setup_sigcontext32(regs, &frame->sf_sc); - err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set)); + err |= __copy_conv_sigset_to_user(&frame->sf_mask, set); + if (err) goto give_sigsegv; @@ -668,7 +671,7 @@ int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs, err |= __put_user(current->sas_ss_size, &frame->rs_uc.uc_stack.ss_size); err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext); - err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set)); + err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set); if (err) goto give_sigsegv; diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c index 1a5f248faf3..7ca2a078841 100644 --- a/arch/mips/kernel/signal_n32.c +++ b/arch/mips/kernel/signal_n32.c @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -63,7 +64,7 @@ struct ucontextn32 { s32 uc_link; stack32_t uc_stack; struct sigcontext uc_mcontext; - sigset_t uc_sigmask; /* mask last for extensibility */ + compat_sigset_t uc_sigmask; /* mask last for extensibility */ }; #if ICACHE_REFILLS_WORKAROUND_WAR == 0 @@ -129,7 +130,7 @@ asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) frame = (struct rt_sigframe_n32 __user *) regs.regs[29]; if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) goto badframe; - if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set))) + if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask)) goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); @@ -195,7 +196,7 @@ int setup_rt_frame_n32(struct k_sigaction * ka, err |= __put_user(current->sas_ss_size, &frame->rs_uc.uc_stack.ss_size); err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext); - err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set)); + err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set); if (err) goto give_sigsegv; -- cgit v1.2.3