[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-3.1-testing] ppoll/pselect x86/64 support.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1199964739 0 # Node ID 2dbeb8df89e2860471c4c360e5a2c97092effdde # Parent 0f30524c7408eb05446943279db61052695b1766 ppoll/pselect x86/64 support. x86_64: Add ppoll/pselect syscalls (from upstream Linux) Needed TIF_RESTORE_SIGMASK first Signed-off-by: Andi Kleen <ak@xxxxxxx> linux-2.6.18-xen changeset: 376:353802ec1caf399143e48713a04cedd37a106347 linux-2.6.18-xen date: Wed Jan 09 22:12:32 2008 +0000 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> linux-2.6.18-xen changeset: 375:748cd890ea7f56752311e519e80eece9d850c01a linux-2.6.18-xen date: Wed Jan 09 22:12:04 2008 +0000 --- patches/linux-2.6.18/linux-2.6.18-xen-375-748cd890ea7f | 233 +++++++++++++++++ patches/linux-2.6.18/linux-2.6.18-xen-376-353802ec1caf | 34 ++ patches/linux-2.6.18/series | 2 3 files changed, 269 insertions(+) diff -r 0f30524c7408 -r 2dbeb8df89e2 patches/linux-2.6.18/linux-2.6.18-xen-375-748cd890ea7f --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/linux-2.6.18/linux-2.6.18-xen-375-748cd890ea7f Thu Jan 10 11:32:19 2008 +0000 @@ -0,0 +1,294 @@ +# 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> + +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(¤t->sighand->siglock); +- saveset = current->blocked; ++ current->saved_sigmask = current->blocked; + siginitset(¤t->blocked, mask); + recalc_sigpending(); + spin_unlock_irq(¤t->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(¤t->sighand->siglock); +- saveset = current->blocked; +- current->blocked = newset; +- recalc_sigpending(); +- spin_unlock_irq(¤t->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(¤t->sighand->siglock); + sigorsets(¤t->blocked,¤t->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 = ¤t->saved_sigmask; ++ else + oldset = ¤t->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, ¤t->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 + diff -r 0f30524c7408 -r 2dbeb8df89e2 patches/linux-2.6.18/linux-2.6.18-xen-376-353802ec1caf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/linux-2.6.18/linux-2.6.18-xen-376-353802ec1caf Thu Jan 10 11:32:19 2008 +0000 @@ -0,0 +1,40 @@ +# HG changeset patch +# User Keir Fraser <keir.fraser@xxxxxxxxxx> +# Date 1199916752 0 +# Node ID 353802ec1caf399143e48713a04cedd37a106347 +# Parent 748cd890ea7f56752311e519e80eece9d850c01a +x86_64: Add ppoll/pselect syscalls (from upstream Linux) + +Needed TIF_RESTORE_SIGMASK first + +Signed-off-by: Andi Kleen <ak@xxxxxxx> + +diff -r 748cd890ea7f -r 353802ec1caf arch/x86_64/ia32/ia32entry.S +--- a/arch/x86_64/ia32/ia32entry.S Wed Jan 09 22:12:04 2008 +0000 ++++ b/arch/x86_64/ia32/ia32entry.S Wed Jan 09 22:12:32 2008 +0000 +@@ -703,8 +703,8 @@ ia32_sys_call_table: + .quad sys_readlinkat /* 305 */ + .quad sys_fchmodat + .quad sys_faccessat +- .quad quiet_ni_syscall /* pselect6 for now */ +- .quad quiet_ni_syscall /* ppoll for now */ ++ .quad compat_sys_pselect6 ++ .quad compat_sys_ppoll + .quad sys_unshare /* 310 */ + .quad compat_sys_set_robust_list + .quad compat_sys_get_robust_list +diff -r 748cd890ea7f -r 353802ec1caf include/asm-x86_64/unistd.h +--- a/include/asm-x86_64/unistd.h Wed Jan 09 22:12:04 2008 +0000 ++++ b/include/asm-x86_64/unistd.h Wed Jan 09 22:12:32 2008 +0000 +@@ -600,9 +600,9 @@ __SYSCALL(__NR_fchmodat, sys_fchmodat) + #define __NR_faccessat 269 + __SYSCALL(__NR_faccessat, sys_faccessat) + #define __NR_pselect6 270 +-__SYSCALL(__NR_pselect6, sys_ni_syscall) /* for now */ ++__SYSCALL(__NR_pselect6, sys_pselect6) + #define __NR_ppoll 271 +-__SYSCALL(__NR_ppoll, sys_ni_syscall) /* for now */ ++__SYSCALL(__NR_ppoll, sys_ppoll) + #define __NR_unshare 272 + __SYSCALL(__NR_unshare, sys_unshare) + #define __NR_set_robust_list 273 diff -r 0f30524c7408 -r 2dbeb8df89e2 patches/linux-2.6.18/series --- a/patches/linux-2.6.18/series Thu Jan 10 11:28:03 2008 +0000 +++ b/patches/linux-2.6.18/series Thu Jan 10 11:32:19 2008 +0000 @@ -22,3 +22,5 @@ allow-i386-crash-kernels-to-handle-x86_6 allow-i386-crash-kernels-to-handle-x86_64-dumps.patch allow-i386-crash-kernels-to-handle-x86_64-dumps-fix.patch git-5ee7737379b1d7f0c977c0f1661fbaf01a8d4721.patch +linux-2.6.18-xen-375-748cd890ea7f +linux-2.6.18-xen-376-353802ec1caf _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |