WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [linux-2.6.18-xen] x86_64: Add TIF_RESTORE_SIGMASK (from

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [linux-2.6.18-xen] x86_64: Add TIF_RESTORE_SIGMASK (from upstream Linux)
From: "Xen patchbot-linux-2.6.18-xen" <patchbot-linux-2.6.18-xen@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 09 Jan 2008 18:50:10 -0800
Delivery-date: Wed, 09 Jan 2008 18:50:19 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1199916724 0
# Node ID 748cd890ea7f56752311e519e80eece9d850c01a
# Parent  fedc10fba9f1d5ec0c72dbcbca87e508222b4c48
x86_64: Add TIF_RESTORE_SIGMASK (from upstream Linux)

We need TIF_RESTORE_SIGMASK in order to support ppoll() and pselect()
system calls. This patch originally came from Andi, and was based
heavily on David Howells' implementation of same on i386. I fixed a
typo which was causing do_signal() to use the wrong signal mask.

Signed-off-by: David Woodhouse <dwmw2@xxxxxxxxxxxxx>
Signed-off-by: Andi Kleen <ak@xxxxxxx>
---
 arch/x86_64/ia32/ia32_signal.c   |   32 +++++--------
 arch/x86_64/kernel/signal.c      |   92 ++++++++++++++++-----------------------
 include/asm-x86_64/signal.h      |    4 -
 include/asm-x86_64/thread_info.h |    2 
 include/asm-x86_64/unistd.h      |    1 
 5 files changed, 56 insertions(+), 75 deletions(-)

diff -r fedc10fba9f1 -r 748cd890ea7f arch/x86_64/ia32/ia32_signal.c
--- a/arch/x86_64/ia32/ia32_signal.c    Tue Jan 08 09:55:29 2008 +0000
+++ b/arch/x86_64/ia32/ia32_signal.c    Wed Jan 09 22:12:04 2008 +0000
@@ -113,25 +113,19 @@ int copy_siginfo_from_user32(siginfo_t *
 }
 
 asmlinkage long
-sys32_sigsuspend(int history0, int history1, old_sigset_t mask,
-                struct pt_regs *regs)
-{
-       sigset_t saveset;
-
+sys32_sigsuspend(int history0, int history1, old_sigset_t mask)
+{
        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->rax = -EINTR;
-       while (1) {
-               current->state = TASK_INTERRUPTIBLE;
-               schedule();
-               if (do_signal(regs, &saveset))
-                       return -EINTR;
-       }
+       current->state = TASK_INTERRUPTIBLE;
+       schedule();
+       set_thread_flag(TIF_RESTORE_SIGMASK);
+       return -ERESTARTNOHAND;
 }
 
 asmlinkage long
@@ -508,11 +502,11 @@ int ia32_setup_frame(int sig, struct k_s
                current->comm, current->pid, frame, regs->rip, frame->pretcode);
 #endif
 
-       return 1;
+       return 0;
 
 give_sigsegv:
        force_sigsegv(sig, current);
-       return 0;
+       return -EFAULT;
 }
 
 int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
@@ -595,7 +589,7 @@ int ia32_setup_rt_frame(int sig, struct 
        regs->ss = __USER32_DS; 
 
        set_fs(USER_DS);
-    regs->eflags &= ~TF_MASK;
+       regs->eflags &= ~TF_MASK;
     if (test_thread_flag(TIF_SINGLESTEP))
         ptrace_notify(SIGTRAP);
 
@@ -604,9 +598,9 @@ int ia32_setup_rt_frame(int sig, struct 
                current->comm, current->pid, frame, regs->rip, frame->pretcode);
 #endif
 
-       return 1;
+       return 0;
 
 give_sigsegv:
        force_sigsegv(sig, current);
-       return 0;
-}
+       return -EFAULT;
+}
diff -r fedc10fba9f1 -r 748cd890ea7f arch/x86_64/kernel/signal.c
--- a/arch/x86_64/kernel/signal.c       Tue Jan 08 09:55:29 2008 +0000
+++ b/arch/x86_64/kernel/signal.c       Wed Jan 09 22:12:04 2008 +0000
@@ -36,37 +36,6 @@ int ia32_setup_rt_frame(int sig, struct 
                sigset_t *set, struct pt_regs * regs); 
 int ia32_setup_frame(int sig, struct k_sigaction *ka,
             sigset_t *set, struct pt_regs * regs); 
-
-asmlinkage long
-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);
-#ifdef DEBUG_SIG
-       printk("rt_sigsuspend savset(%lx) newset(%lx) regs(%p) rip(%lx)\n",
-               saveset, newset, regs, regs->rip);
-#endif 
-       regs->rax = -EINTR;
-       while (1) {
-               current->state = TASK_INTERRUPTIBLE;
-               schedule();
-               if (do_signal(regs, &saveset))
-                       return -EINTR;
-       }
-}
 
 asmlinkage long
 sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
@@ -341,11 +310,11 @@ static int setup_rt_frame(int sig, struc
                current->comm, current->pid, frame, regs->rip, frame->pretcode);
 #endif
 
-       return 1;
+       return 0;
 
 give_sigsegv:
        force_sigsegv(sig, current);
-       return 0;
+       return -EFAULT;
 }
 
 /*
@@ -408,7 +377,7 @@ handle_signal(unsigned long sig, siginfo
 #endif
        ret = setup_rt_frame(sig, ka, info, oldset, regs);
 
-       if (ret) {
+       if (ret == 0) {
                spin_lock_irq(&current->sighand->siglock);
                sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
                if (!(ka->sa.sa_flags & SA_NODEFER))
@@ -425,11 +394,12 @@ handle_signal(unsigned long sig, siginfo
  * want to handle. Thus you cannot kill init even with a SIGKILL even by
  * mistake.
  */
-int do_signal(struct pt_regs *regs, sigset_t *oldset)
+static void do_signal(struct pt_regs *regs)
 {
        struct k_sigaction ka;
        siginfo_t info;
        int signr;
+       sigset_t *oldset;
 
        /*
         * We want the common case to go fast, which
@@ -438,9 +408,11 @@ int do_signal(struct pt_regs *regs, sigs
         * if so.
         */
        if (!user_mode(regs))
-               return 1;
-
-       if (!oldset)
+               return;
+
+       if (test_thread_flag(TIF_RESTORE_SIGMASK))
+               oldset = &current->saved_sigmask;
+       else
                oldset = &current->blocked;
 
        signr = get_signal_to_deliver(&info, &ka, regs, NULL);
@@ -454,30 +426,46 @@ int do_signal(struct pt_regs *regs, sigs
                        set_debugreg(current->thread.debugreg7, 7);
 
                /* Whee!  Actually deliver the signal.  */
-               return handle_signal(signr, &info, &ka, oldset, regs);
+               if (handle_signal(signr, &info, &ka, oldset, regs) == 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);
+               }
+               return;
        }
 
        /* Did we come from a system call? */
        if ((long)regs->orig_rax >= 0) {
                /* Restart the system call - no handlers present */
                long res = regs->rax;
-               if (res == -ERESTARTNOHAND ||
-                   res == -ERESTARTSYS ||
-                   res == -ERESTARTNOINTR) {
+               switch (res) {
+               case -ERESTARTNOHAND:
+               case -ERESTARTSYS:
+               case -ERESTARTNOINTR:
                        regs->rax = regs->orig_rax;
                        regs->rip -= 2;
-               }
-               if (regs->rax == (unsigned long)-ERESTART_RESTARTBLOCK) {
+                       break;
+               case -ERESTART_RESTARTBLOCK:
                        regs->rax = test_thread_flag(TIF_IA32) ?
                                        __NR_ia32_restart_syscall :
                                        __NR_restart_syscall;
                        regs->rip -= 2;
-               }
-       }
-       return 0;
-}
-
-void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, __u32 
thread_info_flags)
+                       break;
+               }
+       }
+
+       /* 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);
+       }
+}
+
+void
+do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
 {
 #ifdef DEBUG_SIG
        printk("do_notify_resume flags:%x rip:%lx rsp:%lx caller:%lx 
pending:%lx\n",
@@ -491,8 +479,8 @@ void do_notify_resume(struct pt_regs *re
        }
 
        /* deal with pending signal delivery */
-       if (thread_info_flags & _TIF_SIGPENDING)
-               do_signal(regs,oldset);
+       if (thread_info_flags & (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK))
+               do_signal(regs);
 }
 
 void signal_fault(struct pt_regs *regs, void __user *frame, char *where)
diff -r fedc10fba9f1 -r 748cd890ea7f include/asm-x86_64/signal.h
--- a/include/asm-x86_64/signal.h       Tue Jan 08 09:55:29 2008 +0000
+++ b/include/asm-x86_64/signal.h       Wed Jan 09 22:12:04 2008 +0000
@@ -22,10 +22,6 @@ typedef struct {
 typedef struct {
        unsigned long sig[_NSIG_WORDS];
 } sigset_t;
-
-
-struct pt_regs; 
-asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
 
 
 #else
diff -r fedc10fba9f1 -r 748cd890ea7f include/asm-x86_64/thread_info.h
--- a/include/asm-x86_64/thread_info.h  Tue Jan 08 09:55:29 2008 +0000
+++ b/include/asm-x86_64/thread_info.h  Wed Jan 09 22:12:04 2008 +0000
@@ -114,6 +114,7 @@ static inline struct thread_info *stack_
 #define TIF_IRET               5       /* force IRET */
 #define TIF_SYSCALL_AUDIT      7       /* syscall auditing active */
 #define TIF_SECCOMP            8       /* secure computing */
+#define TIF_RESTORE_SIGMASK    9       /* restore signal mask in do_signal */
 /* 16 free */
 #define TIF_IA32               17      /* 32bit process */ 
 #define TIF_FORK               18      /* ret_from_fork */
@@ -128,6 +129,7 @@ static inline struct thread_info *stack_
 #define _TIF_IRET              (1<<TIF_IRET)
 #define _TIF_SYSCALL_AUDIT     (1<<TIF_SYSCALL_AUDIT)
 #define _TIF_SECCOMP           (1<<TIF_SECCOMP)
+#define _TIF_RESTORE_SIGMASK   (1<<TIF_RESTORE_SIGMASK)
 #define _TIF_IA32              (1<<TIF_IA32)
 #define _TIF_FORK              (1<<TIF_FORK)
 #define _TIF_ABI_PENDING       (1<<TIF_ABI_PENDING)
diff -r fedc10fba9f1 -r 748cd890ea7f include/asm-x86_64/unistd.h
--- a/include/asm-x86_64/unistd.h       Tue Jan 08 09:55:29 2008 +0000
+++ b/include/asm-x86_64/unistd.h       Wed Jan 09 22:12:04 2008 +0000
@@ -658,6 +658,7 @@ do { \
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
+#define __ARCH_WANT_SYS_RT_SIGSUSPEND
 #define __ARCH_WANT_SYS_TIME
 #define __ARCH_WANT_COMPAT_SYS_TIME
 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [linux-2.6.18-xen] x86_64: Add TIF_RESTORE_SIGMASK (from upstream Linux), Xen patchbot-linux-2.6.18-xen <=