diff options
Diffstat (limited to 'arch/xtensa/kernel')
| -rw-r--r-- | arch/xtensa/kernel/Makefile | 2 | ||||
| -rw-r--r-- | arch/xtensa/kernel/entry.S | 6 | ||||
| -rw-r--r-- | arch/xtensa/kernel/init_task.c | 31 | ||||
| -rw-r--r-- | arch/xtensa/kernel/process.c | 9 | ||||
| -rw-r--r-- | arch/xtensa/kernel/signal.c | 77 | 
5 files changed, 35 insertions, 90 deletions
diff --git a/arch/xtensa/kernel/Makefile b/arch/xtensa/kernel/Makefile index 2d2728b3e86..59fc3fe1557 100644 --- a/arch/xtensa/kernel/Makefile +++ b/arch/xtensa/kernel/Makefile @@ -6,7 +6,7 @@ extra-y := head.o vmlinux.lds  obj-y := align.o entry.o irq.o coprocessor.o process.o ptrace.o \  	 setup.o signal.o syscall.o time.o traps.o vectors.o platform.o  \ -	 pci-dma.o init_task.o io.o +	 pci-dma.o io.o  obj-$(CONFIG_KGDB) += xtensa-stub.o  obj-$(CONFIG_PCI) += pci.o diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index 6223f3346b5..7e623607339 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S @@ -409,16 +409,16 @@ common_exception_return:  	l32i	a4, a2, TI_FLAGS  	_bbsi.l	a4, TIF_NEED_RESCHED, 3f +	_bbsi.l	a4, TIF_NOTIFY_RESUME, 2f  	_bbci.l	a4, TIF_SIGPENDING, 4f -	l32i	a4, a1, PT_DEPC +2:	l32i	a4, a1, PT_DEPC  	bgeui	a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 4f  	/* Call do_signal() */ -	movi	a4, do_signal	# int do_signal(struct pt_regs*, sigset_t*) +	movi	a4, do_notify_resume	# int do_notify_resume(struct pt_regs*)  	mov	a6, a1 -	movi	a7, 0  	callx4	a4  	j	1b diff --git a/arch/xtensa/kernel/init_task.c b/arch/xtensa/kernel/init_task.c deleted file mode 100644 index cd122fb7e48..00000000000 --- a/arch/xtensa/kernel/init_task.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * arch/xtensa/kernel/init_task.c - * - * Xtensa Processor version. - * - * This file is subject to the terms and conditions of the GNU General Public - * License.  See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2007 Tensilica Inc. - * - * Chris Zankel <chris@zankel.net> - */ - -#include <linux/mm.h> -#include <linux/fs.h> -#include <linux/init.h> -#include <linux/init_task.h> -#include <linux/module.h> -#include <linux/mqueue.h> - -#include <asm/uaccess.h> - -static struct signal_struct init_signals = INIT_SIGNALS(init_signals); -static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); -union thread_union init_thread_union __init_task_data = -	{ INIT_THREAD_INFO(init_task) }; - -struct task_struct init_task = INIT_TASK(init_task); - -EXPORT_SYMBOL(init_task); diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c index 6a2d6edf8f7..9b306e550e3 100644 --- a/arch/xtensa/kernel/process.c +++ b/arch/xtensa/kernel/process.c @@ -140,13 +140,16 @@ void flush_thread(void)  }  /* - * This is called before the thread is copied.  + * this gets called so that we can store coprocessor state into memory and + * copy the current task into the new thread.   */ -void prepare_to_copy(struct task_struct *tsk) +int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)  {  #if XTENSA_HAVE_COPROCESSORS -	coprocessor_flush_all(task_thread_info(tsk)); +	coprocessor_flush_all(task_thread_info(src));  #endif +	*dst = *src; +	return 0;  }  /* diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c index d78869a00b1..b9f8e5850d3 100644 --- a/arch/xtensa/kernel/signal.c +++ b/arch/xtensa/kernel/signal.c @@ -20,6 +20,7 @@  #include <linux/ptrace.h>  #include <linux/personality.h>  #include <linux/freezer.h> +#include <linux/tracehook.h>  #include <asm/ucontext.h>  #include <asm/uaccess.h> @@ -29,10 +30,6 @@  #define DEBUG_SIG  0 -#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) - -asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset); -  extern struct task_struct *coproc_owners[];  struct rt_sigframe @@ -248,6 +245,9 @@ asmlinkage long xtensa_rt_sigreturn(long a0, long a1, long a2, long a3,  	sigset_t set;  	int ret; +	/* Always make any pending restarted system calls return -EINTR */ +	current_thread_info()->restart_block.fn = do_no_restart_syscall; +  	if (regs->depc > 64)  		panic("rt_sigreturn in double exception!\n"); @@ -259,7 +259,6 @@ asmlinkage long xtensa_rt_sigreturn(long a0, long a1, long a2, long a3,  	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))  		goto badframe; -	sigdelsetmask(&set, ~_BLOCKABLE);  	set_current_blocked(&set);  	if (restore_sigcontext(regs, frame)) @@ -426,37 +425,6 @@ give_sigsegv:  	return -EFAULT;  } -/* - * Atomically swap in the new signal mask, and wait for a signal. - */ - -asmlinkage long xtensa_rt_sigsuspend(sigset_t __user *unewset,  -    				     size_t sigsetsize, -    				     long a2, long a3, long a4, long a5,  -				     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); -	saveset = current->blocked; -	set_current_blocked(&newset); - -	regs->areg[2] = -EINTR; -	while (1) { -		current->state = TASK_INTERRUPTIBLE; -		schedule(); -		if (do_signal(regs, &saveset)) -			return -EINTR; -	} -} -  asmlinkage long xtensa_sigaltstack(const stack_t __user *uss,   				   stack_t __user *uoss,      				   long a2, long a3, long a4, long a5, @@ -476,21 +444,12 @@ asmlinkage long xtensa_sigaltstack(const stack_t __user *uss,   * the kernel can handle, and then we build all the user-level signal handling   * stack-frames in one go after that.   */ -int do_signal(struct pt_regs *regs, sigset_t *oldset) +static void do_signal(struct pt_regs *regs)  {  	siginfo_t info;  	int signr;  	struct k_sigaction ka; -	if (!user_mode(regs)) -		return 0; - -	if (try_to_freeze()) -		goto no_signal; - -	if (!oldset) -		oldset = ¤t->blocked; -  	task_pt_regs(current)->icountlevel = 0;  	signr = get_signal_to_deliver(&info, &ka, regs, NULL); @@ -530,18 +489,17 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)  		/* Whee!  Actually deliver the signal.  */  		/* Set up the stack frame */ -		ret = setup_frame(signr, &ka, &info, oldset, regs); +		ret = setup_frame(signr, &ka, &info, sigmask_to_save(), regs);  		if (ret) -			return ret; +			return; -		block_sigmask(&ka, signr); +		signal_delivered(signr, info, ka, regs, 0);  		if (current->ptrace & PT_SINGLESTEP)  			task_pt_regs(current)->icountlevel = 1; -		return 1; +		return;  	} -no_signal:  	/* Did we come from a system call? */  	if ((signed) regs->syscall >= 0) {  		/* Restart the system call - no handlers present */ @@ -558,8 +516,23 @@ no_signal:  			break;  		}  	} + +	/* If there's no signal to deliver, we just restore the saved mask.  */ +	restore_saved_sigmask(); +  	if (current->ptrace & PT_SINGLESTEP)  		task_pt_regs(current)->icountlevel = 1; -	return 0; +	return;  } +void do_notify_resume(struct pt_regs *regs) +{ +	if (!user_mode(regs)) +		return; + +	if (test_thread_flag(TIF_SIGPENDING)) +		do_signal(regs); + +	if (test_and_clear_thread_flag(TIF_NOTIFY_RESUME)) +		tracehook_notify_resume(regs); +}  |