Use linux-libc-headers-2.6.31/udev-124
[vuplus_openvuplus_3.0] / meta-openvuplus / recipes-kernel / linux-libc-headers / linux-libc-headers-2.6.31 / 0001-implement-TIF_RESTORE_SIGMASK-support-and-enable-the.patch
diff --git a/meta-openvuplus/recipes-kernel/linux-libc-headers/linux-libc-headers-2.6.31/0001-implement-TIF_RESTORE_SIGMASK-support-and-enable-the.patch b/meta-openvuplus/recipes-kernel/linux-libc-headers/linux-libc-headers-2.6.31/0001-implement-TIF_RESTORE_SIGMASK-support-and-enable-the.patch
new file mode 100644 (file)
index 0000000..1dee314
--- /dev/null
@@ -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 &current->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(&current->sighand->siglock);
+-      saveset = current->blocked;
++      current->saved_sigmask = current->blocked;
+       siginitset(&current->blocked, mask);
+       recalc_sigpending();
+       spin_unlock_irq(&current->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(&current->sighand->siglock);
+-      saveset = current->blocked;
+-      current->blocked = newset;
+-      recalc_sigpending();
+-      spin_unlock_irq(&current->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 = &current->saved_sigmask;
++              else
++                      oldset = &current->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, &current->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(&current->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
+