diff options
author | Koen Kooi <koen@openembedded.org> | 2009-09-03 18:28:37 +0200 |
---|---|---|
committer | Koen Kooi <koen@openembedded.org> | 2009-09-03 18:28:37 +0200 |
commit | 19e6e8e30aaf2a791a657d752649865754963ce6 (patch) | |
tree | 6553a26bf9c2a67cc861568b91d365febb38290b | |
parent | 7b21597db945fef852e17e54c9d82dd727b6594e (diff) |
linux-omap: move ppoll patch to files/ and exchange it with the queued version
3 files changed, 429 insertions, 574 deletions
diff --git a/recipes/linux/files/0001-implement-TIF_RESTORE_SIGMASK-support-and-enable-the.patch b/recipes/linux/files/0001-implement-TIF_RESTORE_SIGMASK-support-and-enable-the.patch new file mode 100644 index 0000000000..1dee314700 --- /dev/null +++ b/recipes/linux/files/0001-implement-TIF_RESTORE_SIGMASK-support-and-enable-the.patch @@ -0,0 +1,429 @@ +Path: news.gmane.org!not-for-mail +From: Mikael Pettersson <mikpe@it.uu.se> +Newsgroups: gmane.linux.ports.arm.kernel +Subject: [PATCH][v3] ARM support for + TIF_RESTORE_SIGMASK/pselect6/ppoll/epoll_pwait +Date: Sat, 15 Aug 2009 13:09:28 +0200 (MEST) +Lines: 362 +Approved: news@gmane.org +Message-ID: <200908151109.n7FB9Sbs000150@pilspetsen.it.uu.se> +NNTP-Posting-Host: lo.gmane.org +Mime-Version: 1.0 +Content-Type: text/plain; charset="us-ascii" +Content-Transfer-Encoding: 7bit +X-Trace: ger.gmane.org 1250334940 22899 80.91.229.12 (15 Aug 2009 11:15:40 GMT) +X-Complaints-To: usenet@ger.gmane.org +NNTP-Posting-Date: Sat, 15 Aug 2009 11:15:40 +0000 (UTC) +To: linux-arm-kernel@lists.arm.linux.org.uk +Original-X-From: linux-arm-kernel-bounces+linux-arm-kernel=m.gmane.org@lists.arm.linux.org.uk Sat Aug 15 13:15:33 2009 +Return-path: <linux-arm-kernel-bounces+linux-arm-kernel=m.gmane.org@lists.arm.linux.org.uk> +Envelope-to: linux-arm-kernel@m.gmane.org +Original-Received: from zeniv.linux.org.uk ([195.92.253.2]) + by lo.gmane.org with esmtp (Exim 4.50) + id 1McHER-0000U2-PG + for linux-arm-kernel@m.gmane.org; Sat, 15 Aug 2009 13:15:31 +0200 +Original-Received: from [2002:4e20:1eda:1:201:3dff:fe00:156] (helo=lists.arm.linux.org.uk) + by ZenIV.linux.org.uk with esmtpsa (Exim 4.69 #1 (Red Hat Linux)) + id 1McH9u-0005LV-3W; Sat, 15 Aug 2009 11:10:57 +0000 +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=arm.linux.org.uk; s=lists; h=Date:Message-Id:From:To:Subject: + List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help: + List-Subscribe:MIME-Version:Content-Type: + Content-Transfer-Encoding; bh=RVq9hPAexlUcptd3h6j5nomOyoEIjcDWAP + VeJtlhsa4=; b=HAoqRMC9svNzKlR0f938E0cRlLoJZvG2aSun171woWZAClu/Ud + IYN0iD2vm4eF+kYQkTYD6PGFCMbNnugmZe6gCpS0QhijoKyOzRBdykQHJuOLQtLE + q9KJzp24cQ/vwsV2+O1OqcmIFboIg2L5JQaUuv0djS7OkdspH0ysmi1lg= +Original-Received: from [::1] (helo=lists.arm.linux.org.uk) + by lists.arm.linux.org.uk with esmtp (Exim 4.69) + (envelope-from <linux-arm-kernel-bounces@lists.arm.linux.org.uk>) + id 1McH9o-0002us-34; Sat, 15 Aug 2009 12:10:44 +0100 +Original-Received: from aun.it.uu.se ([130.238.12.36] ident=root) + by lists.arm.linux.org.uk with esmtps (TLSv1:AES256-SHA:256) + (Exim 4.69) (envelope-from <mikpe@user.it.uu.se>) id 1McH8h-0002uj-Ck + for linux-arm-kernel@lists.arm.linux.org.uk; + Sat, 15 Aug 2009 12:09:35 +0100 +Original-Received: from pilspetsen.it.uu.se (daemon@pilspetsen.it.uu.se [130.238.18.39]) + by aun.it.uu.se (8.13.6/8.13.6) with ESMTP id n7FB9S04005839 + for <linux-arm-kernel@lists.arm.linux.org.uk>; + Sat, 15 Aug 2009 13:09:28 +0200 (MEST) +Original-Received: (from mikpe@localhost) + by pilspetsen.it.uu.se (8.13.8+Sun/8.13.7) id n7FB9Sbs000150 + for linux-arm-kernel@lists.arm.linux.org.uk; + Sat, 15 Aug 2009 13:09:28 +0200 (MEST) +X-BeenThere: linux-arm-kernel@lists.arm.linux.org.uk +X-Mailman-Version: 2.1.9 +Precedence: list +List-Id: ARM Linux kernel discussions <linux-arm-kernel.lists.arm.linux.org.uk> +List-Unsubscribe: <http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel>, + <mailto:linux-arm-kernel-request@lists.arm.linux.org.uk?subject=unsubscribe> +List-Archive: <http://lists.arm.linux.org.uk/lurker/list/linux-arm-kernel.html> +List-Post: <mailto:linux-arm-kernel@lists.arm.linux.org.uk> +List-Help: <mailto:linux-arm-kernel-request@lists.arm.linux.org.uk?subject=help> +List-Subscribe: <http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel>, + <mailto:linux-arm-kernel-request@lists.arm.linux.org.uk?subject=subscribe> +Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=m.gmane.org@lists.arm.linux.org.uk +Xref: news.gmane.org gmane.linux.ports.arm.kernel:64340 +Archived-At: <http://permalink.gmane.org/gmane.linux.ports.arm.kernel/64340> + +This patch adds support for TIF_RESTORE_SIGMASK to ARM's signal handling, +which allows to hook up the pselect6, ppoll, and epoll_pwait syscalls on ARM. + +Tested here with eabi userspace and a test program with a deliberate race +between a child's exit and the parent's sigprocmask/select sequence. +Using sys_pselect6() instead of sigprocmask/select reliably prevents the race. + +The other arch's support for TIF_RESTORE_SIGMASK has evolved over time: + +In 2.6.16: +- add TIF_RESTORE_SIGMASK which parallels TIF_SIGPENDING +- test both when checking for pending signal [bad, changed later] +- reimplement sys_sigsuspend() to use current->saved_sigmask, + TIF_RESTORE_SIGMASK [changed later], and -ERESTARTNOHAND; + ditto for sys_rt_sigsuspend(), but drop private code and + use common code via __ARCH_WANT_SYS_RT_SIGSUSPEND; +- there are now no "extra" calls to do_signal() so its oldset + parameter is always ¤t->blocked so need not be passed, + also its return value is changed to void +- change handle_signal() to return 0/-errno +- change do_signal() to honor TIF_RESTORE_SIGMASK: + + get oldset from current->saved_sigmask if TIF_RESTORE_SIGMASK is set + + if handle_signal() was successful then clear TIF_RESTORE_SIGMASK + + if no signal was delivered and TIF_RESTORE_SIGMASK is set then + clear it and restore the sigmask +- hook up sys_pselect6() and sys_ppoll() + +In 2.6.19: +- hook up sys_epoll_pwait() + +In 2.6.26: +- allow archs to override how TIF_RESTORE_SIGMASK is implemented; + default set_restore_sigmask() sets both TIF_RESTORE_SIGMASK and + TIF_SIGPENDING; archs need now just test TIF_SIGPENDING again + when checking for pending signal work; some archs now implement + TIF_RESTORE_SIGMASK as a secondary/non-atomic thread flag bit +- call set_restore_sigmask() in sys_sigsuspend() instead of setting + TIF_RESTORE_SIGMASK + +In 2.6.29-rc: +- kill sys_pselect7() which no arch wanted + +So for 2.6.31-rc6/ARM this patch does the following: +- Add TIF_RESTORE_SIGMASK. Use the generic set_restore_sigmask() + which sets both TIF_SIGPENDING and TIF_RESTORE_SIGMASK, so + TIF_RESTORE_SIGMASK need not claim one of the scarce low thread + flags, and existing TIF_SIGPENDING and _TIF_WORK_MASK tests need + not be extended for TIF_RESTORE_SIGMASK. +- sys_sigsuspend() is reimplemented to use current->saved_sigmask and + set_restore_sigmask(), making it identical to most other archs. +- The private code for sys_rt_sigsuspend() is removed, instead generic + code supplies it via __ARCH_WANT_SYS_RT_SIGSUSPEND. +- sys_sigsuspend() and sys_rt_sigsuspend() no longer need a pt_regs + parameter, so their assembly code wrappers are removed. +- handle_signal() is changed to return 0 on success or -errno. +- The oldset parameter to do_signal() is now redundant and removed, + and the return value is now also redundant so it's changed to void. +- do_signal() is changed to honor TIF_RESTORE_SIGMASK: + + get oldset from current->saved_sigmask if TIF_RESTORE_SIGMASK is set + + if handle_signal() was successful then clear TIF_RESTORE_SIGMASK + + if no signal was delivered and TIF_RESTORE_SIGMASK is set then + clear it and restore the sigmask +- Hook up sys_pselect6, sys_ppoll, and sys_epoll_pwait. + +Signed-off-by: Mikael Pettersson +--- +Changes from previous versions: + +v2 (only posted as incremental diff against v1): +- moved sigmask restoration in no-signal-delivered case into + "if (syscall)" block for extra protection against exception + path also invoking do_signal() +v3 (this version): +- moved oldset initialisation into "if (signr > 0)" block, + as requested by Russell + + arch/arm/include/asm/thread_info.h | 2 + arch/arm/include/asm/unistd.h | 7 +-- + arch/arm/kernel/calls.S | 10 ++-- + arch/arm/kernel/entry-common.S | 10 ---- + arch/arm/kernel/signal.c | 86 +++++++++++++++---------------------- + 5 files changed, 48 insertions(+), 67 deletions(-) + +diff -rupN linux-2.6.31-rc6/arch/arm/include/asm/thread_info.h linux-2.6.31-rc6.arm-restore-sigmask-v3/arch/arm/include/asm/thread_info.h +--- linux-2.6.31-rc6/arch/arm/include/asm/thread_info.h 2009-08-14 11:11:10.000000000 +0200 ++++ linux-2.6.31-rc6.arm-restore-sigmask-v3/arch/arm/include/asm/thread_info.h 2009-08-14 11:26:44.000000000 +0200 +@@ -140,6 +140,7 @@ extern void vfp_sync_state(struct thread + #define TIF_USING_IWMMXT 17 + #define TIF_MEMDIE 18 + #define TIF_FREEZE 19 ++#define TIF_RESTORE_SIGMASK 20 + + #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) + #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) +@@ -147,6 +148,7 @@ extern void vfp_sync_state(struct thread + #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) + #define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT) + #define _TIF_FREEZE (1 << TIF_FREEZE) ++#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) + + /* + * Change these and you break ASM code in entry-common.S +diff -rupN linux-2.6.31-rc6/arch/arm/include/asm/unistd.h linux-2.6.31-rc6.arm-restore-sigmask-v3/arch/arm/include/asm/unistd.h +--- linux-2.6.31-rc6/arch/arm/include/asm/unistd.h 2009-08-14 11:11:10.000000000 +0200 ++++ linux-2.6.31-rc6.arm-restore-sigmask-v3/arch/arm/include/asm/unistd.h 2009-08-14 11:26:44.000000000 +0200 +@@ -360,8 +360,8 @@ + #define __NR_readlinkat (__NR_SYSCALL_BASE+332) + #define __NR_fchmodat (__NR_SYSCALL_BASE+333) + #define __NR_faccessat (__NR_SYSCALL_BASE+334) +- /* 335 for pselect6 */ +- /* 336 for ppoll */ ++#define __NR_pselect6 (__NR_SYSCALL_BASE+335) ++#define __NR_ppoll (__NR_SYSCALL_BASE+336) + #define __NR_unshare (__NR_SYSCALL_BASE+337) + #define __NR_set_robust_list (__NR_SYSCALL_BASE+338) + #define __NR_get_robust_list (__NR_SYSCALL_BASE+339) +@@ -372,7 +372,7 @@ + #define __NR_vmsplice (__NR_SYSCALL_BASE+343) + #define __NR_move_pages (__NR_SYSCALL_BASE+344) + #define __NR_getcpu (__NR_SYSCALL_BASE+345) +- /* 346 for epoll_pwait */ ++#define __NR_epoll_pwait (__NR_SYSCALL_BASE+346) + #define __NR_kexec_load (__NR_SYSCALL_BASE+347) + #define __NR_utimensat (__NR_SYSCALL_BASE+348) + #define __NR_signalfd (__NR_SYSCALL_BASE+349) +@@ -432,6 +432,7 @@ + #define __ARCH_WANT_SYS_SIGPENDING + #define __ARCH_WANT_SYS_SIGPROCMASK + #define __ARCH_WANT_SYS_RT_SIGACTION ++#define __ARCH_WANT_SYS_RT_SIGSUSPEND + + #if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT) + #define __ARCH_WANT_SYS_TIME +diff -rupN linux-2.6.31-rc6/arch/arm/kernel/calls.S linux-2.6.31-rc6.arm-restore-sigmask-v3/arch/arm/kernel/calls.S +--- linux-2.6.31-rc6/arch/arm/kernel/calls.S 2009-08-14 11:11:10.000000000 +0200 ++++ linux-2.6.31-rc6.arm-restore-sigmask-v3/arch/arm/kernel/calls.S 2009-08-14 11:26:44.000000000 +0200 +@@ -81,7 +81,7 @@ + CALL(sys_ni_syscall) /* was sys_ssetmask */ + /* 70 */ CALL(sys_setreuid16) + CALL(sys_setregid16) +- CALL(sys_sigsuspend_wrapper) ++ CALL(sys_sigsuspend) + CALL(sys_sigpending) + CALL(sys_sethostname) + /* 75 */ CALL(sys_setrlimit) +@@ -188,7 +188,7 @@ + CALL(sys_rt_sigpending) + CALL(sys_rt_sigtimedwait) + CALL(sys_rt_sigqueueinfo) +- CALL(sys_rt_sigsuspend_wrapper) ++ CALL(sys_rt_sigsuspend) + /* 180 */ CALL(ABI(sys_pread64, sys_oabi_pread64)) + CALL(ABI(sys_pwrite64, sys_oabi_pwrite64)) + CALL(sys_chown16) +@@ -344,8 +344,8 @@ + CALL(sys_readlinkat) + CALL(sys_fchmodat) + CALL(sys_faccessat) +-/* 335 */ CALL(sys_ni_syscall) /* eventually pselect6 */ +- CALL(sys_ni_syscall) /* eventually ppoll */ ++/* 335 */ CALL(sys_pselect6) ++ CALL(sys_ppoll) + CALL(sys_unshare) + CALL(sys_set_robust_list) + CALL(sys_get_robust_list) +@@ -355,7 +355,7 @@ + CALL(sys_vmsplice) + CALL(sys_move_pages) + /* 345 */ CALL(sys_getcpu) +- CALL(sys_ni_syscall) /* eventually epoll_pwait */ ++ CALL(sys_epoll_pwait) + CALL(sys_kexec_load) + CALL(sys_utimensat) + CALL(sys_signalfd) +diff -rupN linux-2.6.31-rc6/arch/arm/kernel/entry-common.S linux-2.6.31-rc6.arm-restore-sigmask-v3/arch/arm/kernel/entry-common.S +--- linux-2.6.31-rc6/arch/arm/kernel/entry-common.S 2009-08-14 11:11:10.000000000 +0200 ++++ linux-2.6.31-rc6.arm-restore-sigmask-v3/arch/arm/kernel/entry-common.S 2009-08-14 11:26:44.000000000 +0200 +@@ -373,16 +373,6 @@ sys_clone_wrapper: + b sys_clone + ENDPROC(sys_clone_wrapper) + +-sys_sigsuspend_wrapper: +- add r3, sp, #S_OFF +- b sys_sigsuspend +-ENDPROC(sys_sigsuspend_wrapper) +- +-sys_rt_sigsuspend_wrapper: +- add r2, sp, #S_OFF +- b sys_rt_sigsuspend +-ENDPROC(sys_rt_sigsuspend_wrapper) +- + sys_sigreturn_wrapper: + add r0, sp, #S_OFF + b sys_sigreturn +diff -rupN linux-2.6.31-rc6/arch/arm/kernel/signal.c linux-2.6.31-rc6.arm-restore-sigmask-v3/arch/arm/kernel/signal.c +--- linux-2.6.31-rc6/arch/arm/kernel/signal.c 2009-08-14 11:11:10.000000000 +0200 ++++ linux-2.6.31-rc6.arm-restore-sigmask-v3/arch/arm/kernel/signal.c 2009-08-14 11:26:44.000000000 +0200 +@@ -47,57 +47,22 @@ const unsigned long sigreturn_codes[7] = + MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN, + }; + +-static int do_signal(sigset_t *oldset, struct pt_regs * regs, int syscall); +- + /* + * atomically swap in the new signal mask, and wait for a signal. + */ +-asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask, struct pt_regs *regs) ++asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask) + { +- sigset_t saveset; +- + mask &= _BLOCKABLE; + spin_lock_irq(¤t->sighand->siglock); +- saveset = current->blocked; ++ current->saved_sigmask = current->blocked; + siginitset(¤t->blocked, mask); + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); +- regs->ARM_r0 = -EINTR; +- +- while (1) { +- current->state = TASK_INTERRUPTIBLE; +- schedule(); +- if (do_signal(&saveset, regs, 0)) +- return regs->ARM_r0; +- } +-} +- +-asmlinkage int +-sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs *regs) +-{ +- sigset_t saveset, newset; +- +- /* XXX: Don't preclude handling different sized sigset_t's. */ +- if (sigsetsize != sizeof(sigset_t)) +- return -EINVAL; +- +- if (copy_from_user(&newset, unewset, sizeof(newset))) +- return -EFAULT; +- sigdelsetmask(&newset, ~_BLOCKABLE); +- +- spin_lock_irq(¤t->sighand->siglock); +- saveset = current->blocked; +- current->blocked = newset; +- recalc_sigpending(); +- spin_unlock_irq(¤t->sighand->siglock); +- regs->ARM_r0 = -EINTR; + +- while (1) { +- current->state = TASK_INTERRUPTIBLE; +- schedule(); +- if (do_signal(&saveset, regs, 0)) +- return regs->ARM_r0; +- } ++ current->state = TASK_INTERRUPTIBLE; ++ schedule(); ++ set_restore_sigmask(); ++ return -ERESTARTNOHAND; + } + + asmlinkage int +@@ -545,7 +510,7 @@ static inline void setup_syscall_restart + /* + * OK, we're invoking a handler + */ +-static void ++static int + handle_signal(unsigned long sig, struct k_sigaction *ka, + siginfo_t *info, sigset_t *oldset, + struct pt_regs * regs, int syscall) +@@ -596,7 +561,7 @@ handle_signal(unsigned long sig, struct + + if (ret != 0) { + force_sigsegv(sig, tsk); +- return; ++ return ret; + } + + /* +@@ -610,6 +575,7 @@ handle_signal(unsigned long sig, struct + recalc_sigpending(); + spin_unlock_irq(&tsk->sighand->siglock); + ++ return 0; + } + + /* +@@ -621,7 +587,7 @@ handle_signal(unsigned long sig, struct + * the kernel can handle, and then we build all the user-level signal handling + * stack-frames in one go after that. + */ +-static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) ++static void do_signal(struct pt_regs *regs, int syscall) + { + struct k_sigaction ka; + siginfo_t info; +@@ -634,7 +600,7 @@ static int do_signal(sigset_t *oldset, s + * if so. + */ + if (!user_mode(regs)) +- return 0; ++ return; + + if (try_to_freeze()) + goto no_signal; +@@ -643,9 +609,24 @@ static int do_signal(sigset_t *oldset, s + + signr = get_signal_to_deliver(&info, &ka, regs, NULL); + if (signr > 0) { +- handle_signal(signr, &ka, &info, oldset, regs, syscall); ++ sigset_t *oldset; ++ ++ if (test_thread_flag(TIF_RESTORE_SIGMASK)) ++ oldset = ¤t->saved_sigmask; ++ else ++ oldset = ¤t->blocked; ++ if (handle_signal(signr, &ka, &info, oldset, regs, syscall) == 0) { ++ /* ++ * A signal was successfully delivered; the saved ++ * sigmask will have been stored in the signal frame, ++ * and will be restored by sigreturn, so we can simply ++ * clear the TIF_RESTORE_SIGMASK flag. ++ */ ++ if (test_thread_flag(TIF_RESTORE_SIGMASK)) ++ clear_thread_flag(TIF_RESTORE_SIGMASK); ++ } + single_step_set(current); +- return 1; ++ return; + } + + no_signal: +@@ -697,14 +678,21 @@ static int do_signal(sigset_t *oldset, s + regs->ARM_r0 == -ERESTARTNOINTR) { + setup_syscall_restart(regs); + } ++ ++ /* If there's no signal to deliver, we just put the saved sigmask ++ * back. ++ */ ++ if (test_thread_flag(TIF_RESTORE_SIGMASK)) { ++ clear_thread_flag(TIF_RESTORE_SIGMASK); ++ sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); ++ } + } + single_step_set(current); +- return 0; + } + + asmlinkage void + do_notify_resume(struct pt_regs *regs, unsigned int thread_flags, int syscall) + { + if (thread_flags & _TIF_SIGPENDING) +- do_signal(¤t->blocked, regs, syscall); ++ do_signal(regs, syscall); + } + +------------------------------------------------------------------- +List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel +FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php +Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php + diff --git a/recipes/linux/linux-omap-2.6.29/0001-implement-TIF_RESTORE_SIGMASK-support-and-enable-the.patch b/recipes/linux/linux-omap-2.6.29/0001-implement-TIF_RESTORE_SIGMASK-support-and-enable-the.patch deleted file mode 100644 index 7852f0afdb..0000000000 --- a/recipes/linux/linux-omap-2.6.29/0001-implement-TIF_RESTORE_SIGMASK-support-and-enable-the.patch +++ /dev/null @@ -1,287 +0,0 @@ -From 8a7643b09856f4f661403dcedbe0455b3cbeeea9 Mon Sep 17 00:00:00 2001 -From: Steven Newbury <s_j_newbury@yahoo.co.uk> -Date: Fri, 22 May 2009 14:25:40 +0200 -Subject: [PATCH] implement TIF_RESTORE_SIGMASK support and enable the related - syscalls: - -pselect6 -ppoll -epoll_pwait - -Based on http://www.spinics.net/lists/arm-kernel/msg38114.html ---- - arch/arm/include/asm/thread_info.h | 2 + - arch/arm/include/asm/unistd.h | 7 ++- - arch/arm/kernel/calls.S | 6 +- - arch/arm/kernel/signal.c | 90 +++++++++++++++--------------------- - 4 files changed, 46 insertions(+), 59 deletions(-) - -diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h -index 4f88482..2cf0917 100644 ---- a/arch/arm/include/asm/thread_info.h -+++ b/arch/arm/include/asm/thread_info.h -@@ -136,6 +136,7 @@ extern void vfp_sync_state(struct thread_info *thread); - #define TIF_SIGPENDING 0 - #define TIF_NEED_RESCHED 1 - #define TIF_SYSCALL_TRACE 8 -+#define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal */ - #define TIF_POLLING_NRFLAG 16 - #define TIF_USING_IWMMXT 17 - #define TIF_MEMDIE 18 -@@ -144,6 +145,7 @@ extern void vfp_sync_state(struct thread_info *thread); - #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) - #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) - #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) -+#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) - #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) - #define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT) - #define _TIF_FREEZE (1 << TIF_FREEZE) -diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h -index 94cc58e..cd1eaa0 100644 ---- a/arch/arm/include/asm/unistd.h -+++ b/arch/arm/include/asm/unistd.h -@@ -360,8 +360,8 @@ - #define __NR_readlinkat (__NR_SYSCALL_BASE+332) - #define __NR_fchmodat (__NR_SYSCALL_BASE+333) - #define __NR_faccessat (__NR_SYSCALL_BASE+334) -- /* 335 for pselect6 */ -- /* 336 for ppoll */ -+#define __NR_pselect6 (__NR_SYSCALL_BASE+335) -+#define __NR_ppoll (__NR_SYSCALL_BASE+336) - #define __NR_unshare (__NR_SYSCALL_BASE+337) - #define __NR_set_robust_list (__NR_SYSCALL_BASE+338) - #define __NR_get_robust_list (__NR_SYSCALL_BASE+339) -@@ -372,7 +372,7 @@ - #define __NR_vmsplice (__NR_SYSCALL_BASE+343) - #define __NR_move_pages (__NR_SYSCALL_BASE+344) - #define __NR_getcpu (__NR_SYSCALL_BASE+345) -- /* 346 for epoll_pwait */ -+#define __NR_epoll_pwait (__NR_SYSCALL_BASE+346) - #define __NR_kexec_load (__NR_SYSCALL_BASE+347) - #define __NR_utimensat (__NR_SYSCALL_BASE+348) - #define __NR_signalfd (__NR_SYSCALL_BASE+349) -@@ -430,6 +430,7 @@ - #define __ARCH_WANT_SYS_SIGPENDING - #define __ARCH_WANT_SYS_SIGPROCMASK - #define __ARCH_WANT_SYS_RT_SIGACTION -+#define __ARCH_WANT_SYS_RT_SIGSUSPEND - - #if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT) - #define __ARCH_WANT_SYS_TIME -diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S -index 1680e9e..534000d 100644 ---- a/arch/arm/kernel/calls.S -+++ b/arch/arm/kernel/calls.S -@@ -344,8 +344,8 @@ - CALL(sys_readlinkat) - CALL(sys_fchmodat) - CALL(sys_faccessat) --/* 335 */ CALL(sys_ni_syscall) /* eventually pselect6 */ -- CALL(sys_ni_syscall) /* eventually ppoll */ -+/* 335 */ CALL(sys_pselect6) -+ CALL(sys_ppoll) - CALL(sys_unshare) - CALL(sys_set_robust_list) - CALL(sys_get_robust_list) -@@ -355,7 +355,7 @@ - CALL(sys_vmsplice) - CALL(sys_move_pages) - /* 345 */ CALL(sys_getcpu) -- CALL(sys_ni_syscall) /* eventually epoll_pwait */ -+ CALL(sys_epoll_pwait) - CALL(sys_kexec_load) - CALL(sys_utimensat) - CALL(sys_signalfd) -diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c -index 80b8b5c..7645048 100644 ---- a/arch/arm/kernel/signal.c -+++ b/arch/arm/kernel/signal.c -@@ -47,57 +47,23 @@ const unsigned long sigreturn_codes[7] = { - MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN, - }; - --static int do_signal(sigset_t *oldset, struct pt_regs * regs, int syscall); -+static void do_signal(struct pt_regs * regs, int syscall); - - /* - * atomically swap in the new signal mask, and wait for a signal. - */ --asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask, struct pt_regs *regs) -+asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask) - { -- sigset_t saveset; -- - mask &= _BLOCKABLE; - spin_lock_irq(¤t->sighand->siglock); -- saveset = current->blocked; -+ current->saved_sigmask = current->blocked; - siginitset(¤t->blocked, mask); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); -- regs->ARM_r0 = -EINTR; -- -- while (1) { -- current->state = TASK_INTERRUPTIBLE; -- schedule(); -- if (do_signal(&saveset, regs, 0)) -- return regs->ARM_r0; -- } --} -- --asmlinkage int --sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs *regs) --{ -- sigset_t saveset, newset; -- -- /* XXX: Don't preclude handling different sized sigset_t's. */ -- if (sigsetsize != sizeof(sigset_t)) -- return -EINVAL; -- -- if (copy_from_user(&newset, unewset, sizeof(newset))) -- return -EFAULT; -- sigdelsetmask(&newset, ~_BLOCKABLE); -- -- spin_lock_irq(¤t->sighand->siglock); -- saveset = current->blocked; -- current->blocked = newset; -- recalc_sigpending(); -- spin_unlock_irq(¤t->sighand->siglock); -- regs->ARM_r0 = -EINTR; -- -- while (1) { -- current->state = TASK_INTERRUPTIBLE; -- schedule(); -- if (do_signal(&saveset, regs, 0)) -- return regs->ARM_r0; -- } -+ current->state = TASK_INTERRUPTIBLE; -+ schedule(); -+ set_thread_flag(TIF_RESTORE_SIGMASK); -+ return -ERESTARTNOHAND; - } - - asmlinkage int -@@ -290,7 +256,7 @@ asmlinkage int sys_sigreturn(struct pt_regs *regs) - - badframe: - force_sig(SIGSEGV, current); -- return 0; -+ return -EFAULT; - } - - asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) -@@ -325,7 +291,7 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) - - badframe: - force_sig(SIGSEGV, current); -- return 0; -+ return -EFAULT; - } - - static int -@@ -541,7 +507,7 @@ static inline void restart_syscall(struct pt_regs *regs) - /* - * OK, we're invoking a handler - */ --static void -+static int - handle_signal(unsigned long sig, struct k_sigaction *ka, - siginfo_t *info, sigset_t *oldset, - struct pt_regs * regs, int syscall) -@@ -592,7 +558,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, - - if (ret != 0) { - force_sigsegv(sig, tsk); -- return; -+ return ret; - } - - /* -@@ -606,6 +572,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, - recalc_sigpending(); - spin_unlock_irq(&tsk->sighand->siglock); - -+ return ret; - } - - /* -@@ -617,11 +584,12 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, - * the kernel can handle, and then we build all the user-level signal handling - * stack-frames in one go after that. - */ --static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) -+static void do_signal(struct pt_regs *regs, int syscall) - { - struct k_sigaction ka; - siginfo_t info; - int signr; -+ sigset_t *oldset; - - /* - * We want the common case to go fast, which -@@ -630,18 +598,29 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) - * if so. - */ - if (!user_mode(regs)) -- return 0; -+ return; - - if (try_to_freeze()) - goto no_signal; - - single_step_clear(current); - -+ if (test_thread_flag(TIF_RESTORE_SIGMASK)) -+ oldset = ¤t->saved_sigmask; -+ else -+ oldset = ¤t->blocked; -+ - signr = get_signal_to_deliver(&info, &ka, regs, NULL); - if (signr > 0) { -- handle_signal(signr, &ka, &info, oldset, regs, syscall); -+ if (handle_signal(signr, &ka, &info, oldset, regs, syscall) == 0) { -+ /* a signal was successfully delivered; the saved -+ * sigmask will have been stored in the signal frame, -+ * and will be restored by sigreturn, so we can simply -+ * clear the TIF_RESTORE_SIGMASK flag */ -+ clear_thread_flag(TIF_RESTORE_SIGMASK); -+ } - single_step_set(current); -- return 1; -+ return; - } - - no_signal: -@@ -665,7 +644,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) - usp = (u32 __user *)regs->ARM_sp; - - /* -- * Either we supports OABI only, or we have -+ * Either we support OABI only, or we have - * EABI with the OABI compat layer enabled. - * In the later case we don't know if user - * space is EABI or not, and if not we must -@@ -695,12 +674,17 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) - } - } - single_step_set(current); -- return 0; -+ /* if there's no signal to deliver, we just put the saved sigmask -+ back. */ -+ if (test_thread_flag(TIF_RESTORE_SIGMASK)) { -+ clear_thread_flag(TIF_RESTORE_SIGMASK); -+ sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); -+ } - } - - asmlinkage void - do_notify_resume(struct pt_regs *regs, unsigned int thread_flags, int syscall) - { -- if (thread_flags & _TIF_SIGPENDING) -- do_signal(¤t->blocked, regs, syscall); -+ if (thread_flags & (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK)) -+ do_signal(regs, syscall); - } --- -1.6.2.4 - diff --git a/recipes/linux/linux-omap-pm-2.6.29/0001-implement-TIF_RESTORE_SIGMASK-support-and-enable-the.patch b/recipes/linux/linux-omap-pm-2.6.29/0001-implement-TIF_RESTORE_SIGMASK-support-and-enable-the.patch deleted file mode 100644 index 7852f0afdb..0000000000 --- a/recipes/linux/linux-omap-pm-2.6.29/0001-implement-TIF_RESTORE_SIGMASK-support-and-enable-the.patch +++ /dev/null @@ -1,287 +0,0 @@ -From 8a7643b09856f4f661403dcedbe0455b3cbeeea9 Mon Sep 17 00:00:00 2001 -From: Steven Newbury <s_j_newbury@yahoo.co.uk> -Date: Fri, 22 May 2009 14:25:40 +0200 -Subject: [PATCH] implement TIF_RESTORE_SIGMASK support and enable the related - syscalls: - -pselect6 -ppoll -epoll_pwait - -Based on http://www.spinics.net/lists/arm-kernel/msg38114.html ---- - arch/arm/include/asm/thread_info.h | 2 + - arch/arm/include/asm/unistd.h | 7 ++- - arch/arm/kernel/calls.S | 6 +- - arch/arm/kernel/signal.c | 90 +++++++++++++++--------------------- - 4 files changed, 46 insertions(+), 59 deletions(-) - -diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h -index 4f88482..2cf0917 100644 ---- a/arch/arm/include/asm/thread_info.h -+++ b/arch/arm/include/asm/thread_info.h -@@ -136,6 +136,7 @@ extern void vfp_sync_state(struct thread_info *thread); - #define TIF_SIGPENDING 0 - #define TIF_NEED_RESCHED 1 - #define TIF_SYSCALL_TRACE 8 -+#define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal */ - #define TIF_POLLING_NRFLAG 16 - #define TIF_USING_IWMMXT 17 - #define TIF_MEMDIE 18 -@@ -144,6 +145,7 @@ extern void vfp_sync_state(struct thread_info *thread); - #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) - #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) - #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) -+#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) - #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) - #define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT) - #define _TIF_FREEZE (1 << TIF_FREEZE) -diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h -index 94cc58e..cd1eaa0 100644 ---- a/arch/arm/include/asm/unistd.h -+++ b/arch/arm/include/asm/unistd.h -@@ -360,8 +360,8 @@ - #define __NR_readlinkat (__NR_SYSCALL_BASE+332) - #define __NR_fchmodat (__NR_SYSCALL_BASE+333) - #define __NR_faccessat (__NR_SYSCALL_BASE+334) -- /* 335 for pselect6 */ -- /* 336 for ppoll */ -+#define __NR_pselect6 (__NR_SYSCALL_BASE+335) -+#define __NR_ppoll (__NR_SYSCALL_BASE+336) - #define __NR_unshare (__NR_SYSCALL_BASE+337) - #define __NR_set_robust_list (__NR_SYSCALL_BASE+338) - #define __NR_get_robust_list (__NR_SYSCALL_BASE+339) -@@ -372,7 +372,7 @@ - #define __NR_vmsplice (__NR_SYSCALL_BASE+343) - #define __NR_move_pages (__NR_SYSCALL_BASE+344) - #define __NR_getcpu (__NR_SYSCALL_BASE+345) -- /* 346 for epoll_pwait */ -+#define __NR_epoll_pwait (__NR_SYSCALL_BASE+346) - #define __NR_kexec_load (__NR_SYSCALL_BASE+347) - #define __NR_utimensat (__NR_SYSCALL_BASE+348) - #define __NR_signalfd (__NR_SYSCALL_BASE+349) -@@ -430,6 +430,7 @@ - #define __ARCH_WANT_SYS_SIGPENDING - #define __ARCH_WANT_SYS_SIGPROCMASK - #define __ARCH_WANT_SYS_RT_SIGACTION -+#define __ARCH_WANT_SYS_RT_SIGSUSPEND - - #if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT) - #define __ARCH_WANT_SYS_TIME -diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S -index 1680e9e..534000d 100644 ---- a/arch/arm/kernel/calls.S -+++ b/arch/arm/kernel/calls.S -@@ -344,8 +344,8 @@ - CALL(sys_readlinkat) - CALL(sys_fchmodat) - CALL(sys_faccessat) --/* 335 */ CALL(sys_ni_syscall) /* eventually pselect6 */ -- CALL(sys_ni_syscall) /* eventually ppoll */ -+/* 335 */ CALL(sys_pselect6) -+ CALL(sys_ppoll) - CALL(sys_unshare) - CALL(sys_set_robust_list) - CALL(sys_get_robust_list) -@@ -355,7 +355,7 @@ - CALL(sys_vmsplice) - CALL(sys_move_pages) - /* 345 */ CALL(sys_getcpu) -- CALL(sys_ni_syscall) /* eventually epoll_pwait */ -+ CALL(sys_epoll_pwait) - CALL(sys_kexec_load) - CALL(sys_utimensat) - CALL(sys_signalfd) -diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c -index 80b8b5c..7645048 100644 ---- a/arch/arm/kernel/signal.c -+++ b/arch/arm/kernel/signal.c -@@ -47,57 +47,23 @@ const unsigned long sigreturn_codes[7] = { - MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN, - }; - --static int do_signal(sigset_t *oldset, struct pt_regs * regs, int syscall); -+static void do_signal(struct pt_regs * regs, int syscall); - - /* - * atomically swap in the new signal mask, and wait for a signal. - */ --asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask, struct pt_regs *regs) -+asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask) - { -- sigset_t saveset; -- - mask &= _BLOCKABLE; - spin_lock_irq(¤t->sighand->siglock); -- saveset = current->blocked; -+ current->saved_sigmask = current->blocked; - siginitset(¤t->blocked, mask); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); -- regs->ARM_r0 = -EINTR; -- -- while (1) { -- current->state = TASK_INTERRUPTIBLE; -- schedule(); -- if (do_signal(&saveset, regs, 0)) -- return regs->ARM_r0; -- } --} -- --asmlinkage int --sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs *regs) --{ -- sigset_t saveset, newset; -- -- /* XXX: Don't preclude handling different sized sigset_t's. */ -- if (sigsetsize != sizeof(sigset_t)) -- return -EINVAL; -- -- if (copy_from_user(&newset, unewset, sizeof(newset))) -- return -EFAULT; -- sigdelsetmask(&newset, ~_BLOCKABLE); -- -- spin_lock_irq(¤t->sighand->siglock); -- saveset = current->blocked; -- current->blocked = newset; -- recalc_sigpending(); -- spin_unlock_irq(¤t->sighand->siglock); -- regs->ARM_r0 = -EINTR; -- -- while (1) { -- current->state = TASK_INTERRUPTIBLE; -- schedule(); -- if (do_signal(&saveset, regs, 0)) -- return regs->ARM_r0; -- } -+ current->state = TASK_INTERRUPTIBLE; -+ schedule(); -+ set_thread_flag(TIF_RESTORE_SIGMASK); -+ return -ERESTARTNOHAND; - } - - asmlinkage int -@@ -290,7 +256,7 @@ asmlinkage int sys_sigreturn(struct pt_regs *regs) - - badframe: - force_sig(SIGSEGV, current); -- return 0; -+ return -EFAULT; - } - - asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) -@@ -325,7 +291,7 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) - - badframe: - force_sig(SIGSEGV, current); -- return 0; -+ return -EFAULT; - } - - static int -@@ -541,7 +507,7 @@ static inline void restart_syscall(struct pt_regs *regs) - /* - * OK, we're invoking a handler - */ --static void -+static int - handle_signal(unsigned long sig, struct k_sigaction *ka, - siginfo_t *info, sigset_t *oldset, - struct pt_regs * regs, int syscall) -@@ -592,7 +558,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, - - if (ret != 0) { - force_sigsegv(sig, tsk); -- return; -+ return ret; - } - - /* -@@ -606,6 +572,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, - recalc_sigpending(); - spin_unlock_irq(&tsk->sighand->siglock); - -+ return ret; - } - - /* -@@ -617,11 +584,12 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, - * the kernel can handle, and then we build all the user-level signal handling - * stack-frames in one go after that. - */ --static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) -+static void do_signal(struct pt_regs *regs, int syscall) - { - struct k_sigaction ka; - siginfo_t info; - int signr; -+ sigset_t *oldset; - - /* - * We want the common case to go fast, which -@@ -630,18 +598,29 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) - * if so. - */ - if (!user_mode(regs)) -- return 0; -+ return; - - if (try_to_freeze()) - goto no_signal; - - single_step_clear(current); - -+ if (test_thread_flag(TIF_RESTORE_SIGMASK)) -+ oldset = ¤t->saved_sigmask; -+ else -+ oldset = ¤t->blocked; -+ - signr = get_signal_to_deliver(&info, &ka, regs, NULL); - if (signr > 0) { -- handle_signal(signr, &ka, &info, oldset, regs, syscall); -+ if (handle_signal(signr, &ka, &info, oldset, regs, syscall) == 0) { -+ /* a signal was successfully delivered; the saved -+ * sigmask will have been stored in the signal frame, -+ * and will be restored by sigreturn, so we can simply -+ * clear the TIF_RESTORE_SIGMASK flag */ -+ clear_thread_flag(TIF_RESTORE_SIGMASK); -+ } - single_step_set(current); -- return 1; -+ return; - } - - no_signal: -@@ -665,7 +644,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) - usp = (u32 __user *)regs->ARM_sp; - - /* -- * Either we supports OABI only, or we have -+ * Either we support OABI only, or we have - * EABI with the OABI compat layer enabled. - * In the later case we don't know if user - * space is EABI or not, and if not we must -@@ -695,12 +674,17 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) - } - } - single_step_set(current); -- return 0; -+ /* if there's no signal to deliver, we just put the saved sigmask -+ back. */ -+ if (test_thread_flag(TIF_RESTORE_SIGMASK)) { -+ clear_thread_flag(TIF_RESTORE_SIGMASK); -+ sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); -+ } - } - - asmlinkage void - do_notify_resume(struct pt_regs *regs, unsigned int thread_flags, int syscall) - { -- if (thread_flags & _TIF_SIGPENDING) -- do_signal(¤t->blocked, regs, syscall); -+ if (thread_flags & (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK)) -+ do_signal(regs, syscall); - } --- -1.6.2.4 - |