diff options
author | Graeme Gregory <dp@xora.org.uk> | 2009-09-15 10:49:50 +0100 |
---|---|---|
committer | Graeme Gregory <dp@xora.org.uk> | 2009-09-15 10:49:50 +0100 |
commit | f111ae953c303d608d1b3b7c945a11c03e0a620e (patch) | |
tree | cafc0432a5d83862f4a4f7f4529ae9d76687fd81 /recipes/linux-libc-headers/linux-libc-headers-2.6.31 | |
parent | fbe1669439e632589ddf843137761aebb76f1549 (diff) |
linux-libc-headers_2.6.31.bb : add newest kernel headers, this has the
0001-implement-TIF_RESTORE_SIGMASK-support-and-enable-the.patch enabled
which is getting to be needed for udev.
DEF_PREF = -1 for now as I havent tested this properly yet
Diffstat (limited to 'recipes/linux-libc-headers/linux-libc-headers-2.6.31')
-rw-r--r-- | recipes/linux-libc-headers/linux-libc-headers-2.6.31/0001-implement-TIF_RESTORE_SIGMASK-support-and-enable-the.patch | 429 |
1 files changed, 429 insertions, 0 deletions
diff --git a/recipes/linux-libc-headers/linux-libc-headers-2.6.31/0001-implement-TIF_RESTORE_SIGMASK-support-and-enable-the.patch b/recipes/linux-libc-headers/linux-libc-headers-2.6.31/0001-implement-TIF_RESTORE_SIGMASK-support-and-enable-the.patch new file mode 100644 index 0000000000..1dee314700 --- /dev/null +++ b/recipes/linux-libc-headers/linux-libc-headers-2.6.31/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 + |