diff options
Diffstat (limited to 'arch/sparc')
| -rw-r--r-- | arch/sparc/include/asm/sigcontext.h | 14 | ||||
| -rw-r--r-- | arch/sparc/kernel/Makefile | 1 | ||||
| -rw-r--r-- | arch/sparc/kernel/signal32.c | 184 | ||||
| -rw-r--r-- | arch/sparc/kernel/signal_32.c | 172 | ||||
| -rw-r--r-- | arch/sparc/kernel/signal_64.c | 108 | ||||
| -rw-r--r-- | arch/sparc/kernel/sigutil.h | 9 | ||||
| -rw-r--r-- | arch/sparc/kernel/sigutil_32.c | 120 | ||||
| -rw-r--r-- | arch/sparc/kernel/sigutil_64.c | 93 | ||||
| -rw-r--r-- | arch/sparc/kernel/sys32.S | 1 | ||||
| -rw-r--r-- | arch/sparc/kernel/systbls_32.S | 2 | ||||
| -rw-r--r-- | arch/sparc/kernel/systbls_64.S | 2 | 
11 files changed, 470 insertions, 236 deletions
| diff --git a/arch/sparc/include/asm/sigcontext.h b/arch/sparc/include/asm/sigcontext.h index a1607d180354..69914d748130 100644 --- a/arch/sparc/include/asm/sigcontext.h +++ b/arch/sparc/include/asm/sigcontext.h @@ -45,6 +45,19 @@ typedef struct {  	int			si_mask;  } __siginfo32_t; +#define __SIGC_MAXWIN	7 + +typedef struct { +	unsigned long locals[8]; +	unsigned long ins[8]; +} __siginfo_reg_window; + +typedef struct { +	int			wsaved; +	__siginfo_reg_window	reg_window[__SIGC_MAXWIN]; +	unsigned long		rwbuf_stkptrs[__SIGC_MAXWIN]; +} __siginfo_rwin_t; +  #ifdef CONFIG_SPARC64  typedef struct {  	unsigned   int si_float_regs [64]; @@ -73,6 +86,7 @@ struct sigcontext {  		unsigned long	ss_size;  	}			sigc_stack;  	unsigned long		sigc_mask; +	__siginfo_rwin_t *	sigc_rwin_save;  };  #else diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index b90b4a1d070a..cb85458f89d2 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile @@ -32,6 +32,7 @@ obj-$(CONFIG_SPARC32)   += sun4m_irq.o sun4c_irq.o sun4d_irq.o  obj-y                   += process_$(BITS).o  obj-y                   += signal_$(BITS).o +obj-y                   += sigutil_$(BITS).o  obj-$(CONFIG_SPARC32)   += ioport.o  obj-y                   += setup_$(BITS).o  obj-y                   += idprom.o diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c index 75fad425e249..1ba95aff5d59 100644 --- a/arch/sparc/kernel/signal32.c +++ b/arch/sparc/kernel/signal32.c @@ -29,6 +29,8 @@  #include <asm/visasm.h>  #include <asm/compat_signal.h> +#include "sigutil.h" +  #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))  /* This magic should be in g_upper[0] for all upper parts @@ -44,14 +46,14 @@ typedef struct {  struct signal_frame32 {  	struct sparc_stackf32	ss;  	__siginfo32_t		info; -	/* __siginfo_fpu32_t * */ u32 fpu_save; +	/* __siginfo_fpu_t * */ u32 fpu_save;  	unsigned int		insns[2];  	unsigned int		extramask[_COMPAT_NSIG_WORDS - 1];  	unsigned int		extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */  	/* Only valid if (info.si_regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */  	siginfo_extra_v8plus_t	v8plus; -	__siginfo_fpu_t		fpu_state; -}; +	/* __siginfo_rwin_t * */u32 rwin_save; +} __attribute__((aligned(8)));  typedef struct compat_siginfo{  	int si_signo; @@ -110,18 +112,14 @@ struct rt_signal_frame32 {  	compat_siginfo_t	info;  	struct pt_regs32	regs;  	compat_sigset_t		mask; -	/* __siginfo_fpu32_t * */ u32 fpu_save; +	/* __siginfo_fpu_t * */ u32 fpu_save;  	unsigned int		insns[2];  	stack_t32		stack;  	unsigned int		extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */  	/* Only valid if (regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */  	siginfo_extra_v8plus_t	v8plus; -	__siginfo_fpu_t		fpu_state; -}; - -/* Align macros */ -#define SF_ALIGNEDSZ  (((sizeof(struct signal_frame32) + 15) & (~15))) -#define RT_ALIGNEDSZ  (((sizeof(struct rt_signal_frame32) + 15) & (~15))) +	/* __siginfo_rwin_t * */u32 rwin_save; +} __attribute__((aligned(8)));  int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)  { @@ -192,30 +190,13 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)  	return 0;  } -static int restore_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) -{ -	unsigned long *fpregs = current_thread_info()->fpregs; -	unsigned long fprs; -	int err; -	 -	err = __get_user(fprs, &fpu->si_fprs); -	fprs_write(0); -	regs->tstate &= ~TSTATE_PEF; -	if (fprs & FPRS_DL) -		err |= copy_from_user(fpregs, &fpu->si_float_regs[0], (sizeof(unsigned int) * 32)); -	if (fprs & FPRS_DU) -		err |= copy_from_user(fpregs+16, &fpu->si_float_regs[32], (sizeof(unsigned int) * 32)); -	err |= __get_user(current_thread_info()->xfsr[0], &fpu->si_fsr); -	err |= __get_user(current_thread_info()->gsr[0], &fpu->si_gsr); -	current_thread_info()->fpsaved[0] |= fprs; -	return err; -} -  void do_sigreturn32(struct pt_regs *regs)  {  	struct signal_frame32 __user *sf; +	compat_uptr_t fpu_save; +	compat_uptr_t rwin_save;  	unsigned int psr; -	unsigned pc, npc, fpu_save; +	unsigned pc, npc;  	sigset_t set;  	unsigned seta[_COMPAT_NSIG_WORDS];  	int err, i; @@ -273,8 +254,13 @@ void do_sigreturn32(struct pt_regs *regs)  	pt_regs_clear_syscall(regs);  	err |= __get_user(fpu_save, &sf->fpu_save); -	if (fpu_save) -		err |= restore_fpu_state32(regs, &sf->fpu_state); +	if (!err && fpu_save) +		err |= restore_fpu_state(regs, compat_ptr(fpu_save)); +	err |= __get_user(rwin_save, &sf->rwin_save); +	if (!err && rwin_save) { +		if (restore_rwin_state(compat_ptr(rwin_save))) +			goto segv; +	}  	err |= __get_user(seta[0], &sf->info.si_mask);  	err |= copy_from_user(seta+1, &sf->extramask,  			      (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int)); @@ -300,7 +286,9 @@ segv:  asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)  {  	struct rt_signal_frame32 __user *sf; -	unsigned int psr, pc, npc, fpu_save, u_ss_sp; +	unsigned int psr, pc, npc, u_ss_sp; +	compat_uptr_t fpu_save; +	compat_uptr_t rwin_save;  	mm_segment_t old_fs;  	sigset_t set;  	compat_sigset_t seta; @@ -359,8 +347,8 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)  	pt_regs_clear_syscall(regs);  	err |= __get_user(fpu_save, &sf->fpu_save); -	if (fpu_save) -		err |= restore_fpu_state32(regs, &sf->fpu_state); +	if (!err && fpu_save) +		err |= restore_fpu_state(regs, compat_ptr(fpu_save));  	err |= copy_from_user(&seta, &sf->mask, sizeof(compat_sigset_t));  	err |= __get_user(u_ss_sp, &sf->stack.ss_sp);  	st.ss_sp = compat_ptr(u_ss_sp); @@ -376,6 +364,12 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)  	do_sigaltstack((stack_t __user *) &st, NULL, (unsigned long)sf);  	set_fs(old_fs); +	err |= __get_user(rwin_save, &sf->rwin_save); +	if (!err && rwin_save) { +		if (restore_rwin_state(compat_ptr(rwin_save))) +			goto segv; +	} +  	switch (_NSIG_WORDS) {  		case 4: set.sig[3] = seta.sig[6] + (((long)seta.sig[7]) << 32);  		case 3: set.sig[2] = seta.sig[4] + (((long)seta.sig[5]) << 32); @@ -433,26 +427,6 @@ static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, uns  	return (void __user *) sp;  } -static int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) -{ -	unsigned long *fpregs = current_thread_info()->fpregs; -	unsigned long fprs; -	int err = 0; -	 -	fprs = current_thread_info()->fpsaved[0]; -	if (fprs & FPRS_DL) -		err |= copy_to_user(&fpu->si_float_regs[0], fpregs, -				    (sizeof(unsigned int) * 32)); -	if (fprs & FPRS_DU) -		err |= copy_to_user(&fpu->si_float_regs[32], fpregs+16, -				    (sizeof(unsigned int) * 32)); -	err |= __put_user(current_thread_info()->xfsr[0], &fpu->si_fsr); -	err |= __put_user(current_thread_info()->gsr[0], &fpu->si_gsr); -	err |= __put_user(fprs, &fpu->si_fprs); - -	return err; -} -  /* The I-cache flush instruction only works in the primary ASI, which   * right now is the nucleus, aka. kernel space.   * @@ -515,18 +489,23 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,  			 int signo, sigset_t *oldset)  {  	struct signal_frame32 __user *sf; +	int i, err, wsaved; +	void __user *tail;  	int sigframe_size;  	u32 psr; -	int i, err;  	unsigned int seta[_COMPAT_NSIG_WORDS];  	/* 1. Make sure everything is clean */  	synchronize_user_stack();  	save_and_clear_fpu(); -	sigframe_size = SF_ALIGNEDSZ; -	if (!(current_thread_info()->fpsaved[0] & FPRS_FEF)) -		sigframe_size -= sizeof(__siginfo_fpu_t); +	wsaved = get_thread_wsaved(); + +	sigframe_size = sizeof(*sf); +	if (current_thread_info()->fpsaved[0] & FPRS_FEF) +		sigframe_size += sizeof(__siginfo_fpu_t); +	if (wsaved) +		sigframe_size += sizeof(__siginfo_rwin_t);  	sf = (struct signal_frame32 __user *)  		get_sigframe(&ka->sa, regs, sigframe_size); @@ -534,8 +513,7 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,  	if (invalid_frame_pointer(sf, sigframe_size))  		goto sigill; -	if (get_thread_wsaved() != 0) -		goto sigill; +	tail = (sf + 1);  	/* 2. Save the current process state */  	if (test_thread_flag(TIF_32BIT)) { @@ -560,11 +538,22 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,  			  &sf->v8plus.asi);  	if (psr & PSR_EF) { -		err |= save_fpu_state32(regs, &sf->fpu_state); -		err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save); +		__siginfo_fpu_t __user *fp = tail; +		tail += sizeof(*fp); +		err |= save_fpu_state(regs, fp); +		err |= __put_user((u64)fp, &sf->fpu_save);  	} else {  		err |= __put_user(0, &sf->fpu_save);  	} +	if (wsaved) { +		__siginfo_rwin_t __user *rwp = tail; +		tail += sizeof(*rwp); +		err |= save_rwin_state(wsaved, rwp); +		err |= __put_user((u64)rwp, &sf->rwin_save); +		set_thread_wsaved(0); +	} else { +		err |= __put_user(0, &sf->rwin_save); +	}  	switch (_NSIG_WORDS) {  	case 4: seta[7] = (oldset->sig[3] >> 32); @@ -580,10 +569,21 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,  	err |= __copy_to_user(sf->extramask, seta + 1,  			      (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int)); -	err |= copy_in_user((u32 __user *)sf, -			    (u32 __user *)(regs->u_regs[UREG_FP]), -			    sizeof(struct reg_window32)); -	 +	if (!wsaved) { +		err |= copy_in_user((u32 __user *)sf, +				    (u32 __user *)(regs->u_regs[UREG_FP]), +				    sizeof(struct reg_window32)); +	} else { +		struct reg_window *rp; + +		rp = ¤t_thread_info()->reg_window[wsaved - 1]; +		for (i = 0; i < 8; i++) +			err |= __put_user(rp->locals[i], &sf->ss.locals[i]); +		for (i = 0; i < 6; i++) +			err |= __put_user(rp->ins[i], &sf->ss.ins[i]); +		err |= __put_user(rp->ins[6], &sf->ss.fp); +		err |= __put_user(rp->ins[7], &sf->ss.callers_pc); +	}	  	if (err)  		goto sigsegv; @@ -613,7 +613,6 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,  		err |= __put_user(0x91d02010, &sf->insns[1]); /*t 0x10*/  		if (err)  			goto sigsegv; -  		flush_signal_insns(address);  	}  	return 0; @@ -632,18 +631,23 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,  			    siginfo_t *info)  {  	struct rt_signal_frame32 __user *sf; +	int i, err, wsaved; +	void __user *tail;  	int sigframe_size;  	u32 psr; -	int i, err;  	compat_sigset_t seta;  	/* 1. Make sure everything is clean */  	synchronize_user_stack();  	save_and_clear_fpu(); -	sigframe_size = RT_ALIGNEDSZ; -	if (!(current_thread_info()->fpsaved[0] & FPRS_FEF)) -		sigframe_size -= sizeof(__siginfo_fpu_t); +	wsaved = get_thread_wsaved(); + +	sigframe_size = sizeof(*sf); +	if (current_thread_info()->fpsaved[0] & FPRS_FEF) +		sigframe_size += sizeof(__siginfo_fpu_t); +	if (wsaved) +		sigframe_size += sizeof(__siginfo_rwin_t);  	sf = (struct rt_signal_frame32 __user *)  		get_sigframe(&ka->sa, regs, sigframe_size); @@ -651,8 +655,7 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,  	if (invalid_frame_pointer(sf, sigframe_size))  		goto sigill; -	if (get_thread_wsaved() != 0) -		goto sigill; +	tail = (sf + 1);  	/* 2. Save the current process state */  	if (test_thread_flag(TIF_32BIT)) { @@ -677,11 +680,22 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,  			  &sf->v8plus.asi);  	if (psr & PSR_EF) { -		err |= save_fpu_state32(regs, &sf->fpu_state); -		err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save); +		__siginfo_fpu_t __user *fp = tail; +		tail += sizeof(*fp); +		err |= save_fpu_state(regs, fp); +		err |= __put_user((u64)fp, &sf->fpu_save);  	} else {  		err |= __put_user(0, &sf->fpu_save);  	} +	if (wsaved) { +		__siginfo_rwin_t __user *rwp = tail; +		tail += sizeof(*rwp); +		err |= save_rwin_state(wsaved, rwp); +		err |= __put_user((u64)rwp, &sf->rwin_save); +		set_thread_wsaved(0); +	} else { +		err |= __put_user(0, &sf->rwin_save); +	}  	/* Update the siginfo structure.  */  	err |= copy_siginfo_to_user32(&sf->info, info); @@ -703,9 +717,21 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,  	}  	err |= __copy_to_user(&sf->mask, &seta, sizeof(compat_sigset_t)); -	err |= copy_in_user((u32 __user *)sf, -			    (u32 __user *)(regs->u_regs[UREG_FP]), -			    sizeof(struct reg_window32)); +	if (!wsaved) { +		err |= copy_in_user((u32 __user *)sf, +				    (u32 __user *)(regs->u_regs[UREG_FP]), +				    sizeof(struct reg_window32)); +	} else { +		struct reg_window *rp; + +		rp = ¤t_thread_info()->reg_window[wsaved - 1]; +		for (i = 0; i < 8; i++) +			err |= __put_user(rp->locals[i], &sf->ss.locals[i]); +		for (i = 0; i < 6; i++) +			err |= __put_user(rp->ins[i], &sf->ss.ins[i]); +		err |= __put_user(rp->ins[6], &sf->ss.fp); +		err |= __put_user(rp->ins[7], &sf->ss.callers_pc); +	}  	if (err)  		goto sigsegv; diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c index 5e5c5fd03783..04ede8f04add 100644 --- a/arch/sparc/kernel/signal_32.c +++ b/arch/sparc/kernel/signal_32.c @@ -26,6 +26,8 @@  #include <asm/pgtable.h>  #include <asm/cacheflush.h>	/* flush_sig_insns */ +#include "sigutil.h" +  #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))  extern void fpsave(unsigned long *fpregs, unsigned long *fsr, @@ -39,8 +41,8 @@ struct signal_frame {  	unsigned long		insns[2] __attribute__ ((aligned (8)));  	unsigned int		extramask[_NSIG_WORDS - 1];  	unsigned int		extra_size; /* Should be 0 */ -	__siginfo_fpu_t		fpu_state; -}; +	__siginfo_rwin_t __user	*rwin_save; +} __attribute__((aligned(8)));  struct rt_signal_frame {  	struct sparc_stackf	ss; @@ -51,8 +53,8 @@ struct rt_signal_frame {  	unsigned int		insns[2];  	stack_t			stack;  	unsigned int		extra_size; /* Should be 0 */ -	__siginfo_fpu_t		fpu_state; -}; +	__siginfo_rwin_t __user	*rwin_save; +} __attribute__((aligned(8)));  /* Align macros */  #define SF_ALIGNEDSZ  (((sizeof(struct signal_frame) + 7) & (~7))) @@ -79,43 +81,13 @@ asmlinkage int sys_sigsuspend(old_sigset_t set)  	return _sigpause_common(set);  } -static inline int -restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) -{ -	int err; -#ifdef CONFIG_SMP -	if (test_tsk_thread_flag(current, TIF_USEDFPU)) -		regs->psr &= ~PSR_EF; -#else -	if (current == last_task_used_math) { -		last_task_used_math = NULL; -		regs->psr &= ~PSR_EF; -	} -#endif -	set_used_math(); -	clear_tsk_thread_flag(current, TIF_USEDFPU); - -	if (!access_ok(VERIFY_READ, fpu, sizeof(*fpu))) -		return -EFAULT; - -	err = __copy_from_user(¤t->thread.float_regs[0], &fpu->si_float_regs[0], -			       (sizeof(unsigned long) * 32)); -	err |= __get_user(current->thread.fsr, &fpu->si_fsr); -	err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth); -	if (current->thread.fpqdepth != 0) -		err |= __copy_from_user(¤t->thread.fpqueue[0], -					&fpu->si_fpqueue[0], -					((sizeof(unsigned long) + -					(sizeof(unsigned long *)))*16)); -	return err; -} -  asmlinkage void do_sigreturn(struct pt_regs *regs)  {  	struct signal_frame __user *sf;  	unsigned long up_psr, pc, npc;  	sigset_t set;  	__siginfo_fpu_t __user *fpu_save; +	__siginfo_rwin_t __user *rwin_save;  	int err;  	/* Always make any pending restarted system calls return -EINTR */ @@ -150,9 +122,11 @@ asmlinkage void do_sigreturn(struct pt_regs *regs)  	pt_regs_clear_syscall(regs);  	err |= __get_user(fpu_save, &sf->fpu_save); -  	if (fpu_save)  		err |= restore_fpu_state(regs, fpu_save); +	err |= __get_user(rwin_save, &sf->rwin_save); +	if (rwin_save) +		err |= restore_rwin_state(rwin_save);  	/* This is pretty much atomic, no amount locking would prevent  	 * the races which exist anyways. @@ -180,6 +154,7 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)  	struct rt_signal_frame __user *sf;  	unsigned int psr, pc, npc;  	__siginfo_fpu_t __user *fpu_save; +	__siginfo_rwin_t __user *rwin_save;  	mm_segment_t old_fs;  	sigset_t set;  	stack_t st; @@ -207,8 +182,7 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)  	pt_regs_clear_syscall(regs);  	err |= __get_user(fpu_save, &sf->fpu_save); - -	if (fpu_save) +	if (!err && fpu_save)  		err |= restore_fpu_state(regs, fpu_save);  	err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t)); @@ -228,6 +202,12 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)  	do_sigaltstack((const stack_t __user *) &st, NULL, (unsigned long)sf);  	set_fs(old_fs); +	err |= __get_user(rwin_save, &sf->rwin_save); +	if (!err && rwin_save) { +		if (restore_rwin_state(rwin_save)) +			goto segv; +	} +  	sigdelsetmask(&set, ~_BLOCKABLE);  	spin_lock_irq(¤t->sighand->siglock);  	current->blocked = set; @@ -280,53 +260,23 @@ static inline void __user *get_sigframe(struct sigaction *sa, struct pt_regs *re  	return (void __user *) sp;  } -static inline int -save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) -{ -	int err = 0; -#ifdef CONFIG_SMP -	if (test_tsk_thread_flag(current, TIF_USEDFPU)) { -		put_psr(get_psr() | PSR_EF); -		fpsave(¤t->thread.float_regs[0], ¤t->thread.fsr, -		       ¤t->thread.fpqueue[0], ¤t->thread.fpqdepth); -		regs->psr &= ~(PSR_EF); -		clear_tsk_thread_flag(current, TIF_USEDFPU); -	} -#else -	if (current == last_task_used_math) { -		put_psr(get_psr() | PSR_EF); -		fpsave(¤t->thread.float_regs[0], ¤t->thread.fsr, -		       ¤t->thread.fpqueue[0], ¤t->thread.fpqdepth); -		last_task_used_math = NULL; -		regs->psr &= ~(PSR_EF); -	} -#endif -	err |= __copy_to_user(&fpu->si_float_regs[0], -			      ¤t->thread.float_regs[0], -			      (sizeof(unsigned long) * 32)); -	err |= __put_user(current->thread.fsr, &fpu->si_fsr); -	err |= __put_user(current->thread.fpqdepth, &fpu->si_fpqdepth); -	if (current->thread.fpqdepth != 0) -		err |= __copy_to_user(&fpu->si_fpqueue[0], -				      ¤t->thread.fpqueue[0], -				      ((sizeof(unsigned long) + -				      (sizeof(unsigned long *)))*16)); -	clear_used_math(); -	return err; -} -  static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs,  		       int signo, sigset_t *oldset)  {  	struct signal_frame __user *sf; -	int sigframe_size, err; +	int sigframe_size, err, wsaved; +	void __user *tail;  	/* 1. Make sure everything is clean */  	synchronize_user_stack(); -	sigframe_size = SF_ALIGNEDSZ; -	if (!used_math()) -		sigframe_size -= sizeof(__siginfo_fpu_t); +	wsaved = current_thread_info()->w_saved; + +	sigframe_size = sizeof(*sf); +	if (used_math()) +		sigframe_size += sizeof(__siginfo_fpu_t); +	if (wsaved) +		sigframe_size += sizeof(__siginfo_rwin_t);  	sf = (struct signal_frame __user *)  		get_sigframe(&ka->sa, regs, sigframe_size); @@ -334,8 +284,7 @@ static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs,  	if (invalid_frame_pointer(sf, sigframe_size))  		goto sigill_and_return; -	if (current_thread_info()->w_saved != 0) -		goto sigill_and_return; +	tail = sf + 1;  	/* 2. Save the current process state */  	err = __copy_to_user(&sf->info.si_regs, regs, sizeof(struct pt_regs)); @@ -343,17 +292,34 @@ static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs,  	err |= __put_user(0, &sf->extra_size);  	if (used_math()) { -		err |= save_fpu_state(regs, &sf->fpu_state); -		err |= __put_user(&sf->fpu_state, &sf->fpu_save); +		__siginfo_fpu_t __user *fp = tail; +		tail += sizeof(*fp); +		err |= save_fpu_state(regs, fp); +		err |= __put_user(fp, &sf->fpu_save);  	} else {  		err |= __put_user(0, &sf->fpu_save);  	} +	if (wsaved) { +		__siginfo_rwin_t __user *rwp = tail; +		tail += sizeof(*rwp); +		err |= save_rwin_state(wsaved, rwp); +		err |= __put_user(rwp, &sf->rwin_save); +	} else { +		err |= __put_user(0, &sf->rwin_save); +	}  	err |= __put_user(oldset->sig[0], &sf->info.si_mask);  	err |= __copy_to_user(sf->extramask, &oldset->sig[1],  			      (_NSIG_WORDS - 1) * sizeof(unsigned int)); -	err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP], -			      sizeof(struct reg_window32)); +	if (!wsaved) { +		err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP], +				      sizeof(struct reg_window32)); +	} else { +		struct reg_window32 *rp; + +		rp = ¤t_thread_info()->reg_window[wsaved - 1]; +		err |= __copy_to_user(sf, rp, sizeof(struct reg_window32)); +	}  	if (err)  		goto sigsegv; @@ -399,21 +365,24 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,  			  int signo, sigset_t *oldset, siginfo_t *info)  {  	struct rt_signal_frame __user *sf; -	int sigframe_size; +	int sigframe_size, wsaved; +	void __user *tail;  	unsigned int psr;  	int err;  	synchronize_user_stack(); -	sigframe_size = RT_ALIGNEDSZ; -	if (!used_math()) -		sigframe_size -= sizeof(__siginfo_fpu_t); +	wsaved = current_thread_info()->w_saved; +	sigframe_size = sizeof(*sf); +	if (used_math()) +		sigframe_size += sizeof(__siginfo_fpu_t); +	if (wsaved) +		sigframe_size += sizeof(__siginfo_rwin_t);  	sf = (struct rt_signal_frame __user *)  		get_sigframe(&ka->sa, regs, sigframe_size);  	if (invalid_frame_pointer(sf, sigframe_size))  		goto sigill; -	if (current_thread_info()->w_saved != 0) -		goto sigill; +	tail = sf + 1;  	err  = __put_user(regs->pc, &sf->regs.pc);  	err |= __put_user(regs->npc, &sf->regs.npc);  	err |= __put_user(regs->y, &sf->regs.y); @@ -425,11 +394,21 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,  	err |= __put_user(0, &sf->extra_size);  	if (psr & PSR_EF) { -		err |= save_fpu_state(regs, &sf->fpu_state); -		err |= __put_user(&sf->fpu_state, &sf->fpu_save); +		__siginfo_fpu_t *fp = tail; +		tail += sizeof(*fp); +		err |= save_fpu_state(regs, fp); +		err |= __put_user(fp, &sf->fpu_save);  	} else {  		err |= __put_user(0, &sf->fpu_save);  	} +	if (wsaved) { +		__siginfo_rwin_t *rwp = tail; +		tail += sizeof(*rwp); +		err |= save_rwin_state(wsaved, rwp); +		err |= __put_user(rwp, &sf->rwin_save); +	} else { +		err |= __put_user(0, &sf->rwin_save); +	}  	err |= __copy_to_user(&sf->mask, &oldset->sig[0], sizeof(sigset_t));  	/* Setup sigaltstack */ @@ -437,8 +416,15 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,  	err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags);  	err |= __put_user(current->sas_ss_size, &sf->stack.ss_size); -	err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP], -			      sizeof(struct reg_window32)); +	if (!wsaved) { +		err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP], +				      sizeof(struct reg_window32)); +	} else { +		struct reg_window32 *rp; + +		rp = ¤t_thread_info()->reg_window[wsaved - 1]; +		err |= __copy_to_user(sf, rp, sizeof(struct reg_window32)); +	}  	err |= copy_siginfo_to_user(&sf->info, info); diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c index 006fe4515886..47509df3b893 100644 --- a/arch/sparc/kernel/signal_64.c +++ b/arch/sparc/kernel/signal_64.c @@ -34,6 +34,7 @@  #include "entry.h"  #include "systbls.h" +#include "sigutil.h"  #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) @@ -236,7 +237,7 @@ struct rt_signal_frame {  	__siginfo_fpu_t __user	*fpu_save;  	stack_t			stack;  	sigset_t		mask; -	__siginfo_fpu_t		fpu_state; +	__siginfo_rwin_t	*rwin_save;  };  static long _sigpause_common(old_sigset_t set) @@ -266,33 +267,12 @@ asmlinkage long sys_sigsuspend(old_sigset_t set)  	return _sigpause_common(set);  } -static inline int -restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) -{ -	unsigned long *fpregs = current_thread_info()->fpregs; -	unsigned long fprs; -	int err; - -	err = __get_user(fprs, &fpu->si_fprs); -	fprs_write(0); -	regs->tstate &= ~TSTATE_PEF; -	if (fprs & FPRS_DL) -		err |= copy_from_user(fpregs, &fpu->si_float_regs[0], -		       	       (sizeof(unsigned int) * 32)); -	if (fprs & FPRS_DU) -		err |= copy_from_user(fpregs+16, &fpu->si_float_regs[32], -		       	       (sizeof(unsigned int) * 32)); -	err |= __get_user(current_thread_info()->xfsr[0], &fpu->si_fsr); -	err |= __get_user(current_thread_info()->gsr[0], &fpu->si_gsr); -	current_thread_info()->fpsaved[0] |= fprs; -	return err; -} -  void do_rt_sigreturn(struct pt_regs *regs)  {  	struct rt_signal_frame __user *sf;  	unsigned long tpc, tnpc, tstate;  	__siginfo_fpu_t __user *fpu_save; +	__siginfo_rwin_t __user *rwin_save;  	sigset_t set;  	int err; @@ -325,8 +305,8 @@ void do_rt_sigreturn(struct pt_regs *regs)  	regs->tstate |= (tstate & (TSTATE_ASI | TSTATE_ICC | TSTATE_XCC));  	err |= __get_user(fpu_save, &sf->fpu_save); -	if (fpu_save) -		err |= restore_fpu_state(regs, &sf->fpu_state); +	if (!err && fpu_save) +		err |= restore_fpu_state(regs, fpu_save);  	err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t));  	err |= do_sigaltstack(&sf->stack, NULL, (unsigned long)sf); @@ -334,6 +314,12 @@ void do_rt_sigreturn(struct pt_regs *regs)  	if (err)  		goto segv; +	err |= __get_user(rwin_save, &sf->rwin_save); +	if (!err && rwin_save) { +		if (restore_rwin_state(rwin_save)) +			goto segv; +	} +  	regs->tpc = tpc;  	regs->tnpc = tnpc; @@ -351,34 +337,13 @@ segv:  }  /* Checks if the fp is valid */ -static int invalid_frame_pointer(void __user *fp, int fplen) +static int invalid_frame_pointer(void __user *fp)  {  	if (((unsigned long) fp) & 15)  		return 1;  	return 0;  } -static inline int -save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) -{ -	unsigned long *fpregs = current_thread_info()->fpregs; -	unsigned long fprs; -	int err = 0; -	 -	fprs = current_thread_info()->fpsaved[0]; -	if (fprs & FPRS_DL) -		err |= copy_to_user(&fpu->si_float_regs[0], fpregs, -				    (sizeof(unsigned int) * 32)); -	if (fprs & FPRS_DU) -		err |= copy_to_user(&fpu->si_float_regs[32], fpregs+16, -				    (sizeof(unsigned int) * 32)); -	err |= __put_user(current_thread_info()->xfsr[0], &fpu->si_fsr); -	err |= __put_user(current_thread_info()->gsr[0], &fpu->si_gsr); -	err |= __put_user(fprs, &fpu->si_fprs); - -	return err; -} -  static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, unsigned long framesize)  {  	unsigned long sp = regs->u_regs[UREG_FP] + STACK_BIAS; @@ -414,34 +379,48 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,  	       int signo, sigset_t *oldset, siginfo_t *info)  {  	struct rt_signal_frame __user *sf; -	int sigframe_size, err; +	int wsaved, err, sf_size; +	void __user *tail;  	/* 1. Make sure everything is clean */  	synchronize_user_stack();  	save_and_clear_fpu(); -	sigframe_size = sizeof(struct rt_signal_frame); -	if (!(current_thread_info()->fpsaved[0] & FPRS_FEF)) -		sigframe_size -= sizeof(__siginfo_fpu_t); +	wsaved = get_thread_wsaved(); +	sf_size = sizeof(struct rt_signal_frame); +	if (current_thread_info()->fpsaved[0] & FPRS_FEF) +		sf_size += sizeof(__siginfo_fpu_t); +	if (wsaved) +		sf_size += sizeof(__siginfo_rwin_t);  	sf = (struct rt_signal_frame __user *) -		get_sigframe(ka, regs, sigframe_size); -	 -	if (invalid_frame_pointer (sf, sigframe_size)) -		goto sigill; +		get_sigframe(ka, regs, sf_size); -	if (get_thread_wsaved() != 0) +	if (invalid_frame_pointer (sf))  		goto sigill; +	tail = (sf + 1); +  	/* 2. Save the current process state */  	err = copy_to_user(&sf->regs, regs, sizeof (*regs));  	if (current_thread_info()->fpsaved[0] & FPRS_FEF) { -		err |= save_fpu_state(regs, &sf->fpu_state); -		err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save); +		__siginfo_fpu_t __user *fpu_save = tail; +		tail += sizeof(__siginfo_fpu_t); +		err |= save_fpu_state(regs, fpu_save); +		err |= __put_user((u64)fpu_save, &sf->fpu_save);  	} else {  		err |= __put_user(0, &sf->fpu_save);  	} +	if (wsaved) { +		__siginfo_rwin_t __user *rwin_save = tail; +		tail += sizeof(__siginfo_rwin_t); +		err |= save_rwin_state(wsaved, rwin_save); +		err |= __put_user((u64)rwin_save, &sf->rwin_save); +		set_thread_wsaved(0); +	} else { +		err |= __put_user(0, &sf->rwin_save); +	}  	/* Setup sigaltstack */  	err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp); @@ -450,10 +429,17 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,  	err |= copy_to_user(&sf->mask, oldset, sizeof(sigset_t)); -	err |= copy_in_user((u64 __user *)sf, -			    (u64 __user *)(regs->u_regs[UREG_FP]+STACK_BIAS), -			    sizeof(struct reg_window)); +	if (!wsaved) { +		err |= copy_in_user((u64 __user *)sf, +				    (u64 __user *)(regs->u_regs[UREG_FP] + +						   STACK_BIAS), +				    sizeof(struct reg_window)); +	} else { +		struct reg_window *rp; +		rp = ¤t_thread_info()->reg_window[wsaved - 1]; +		err |= copy_to_user(sf, rp, sizeof(struct reg_window)); +	}  	if (info)  		err |= copy_siginfo_to_user(&sf->info, info);  	else { diff --git a/arch/sparc/kernel/sigutil.h b/arch/sparc/kernel/sigutil.h new file mode 100644 index 000000000000..d223aa432bb6 --- /dev/null +++ b/arch/sparc/kernel/sigutil.h @@ -0,0 +1,9 @@ +#ifndef _SIGUTIL_H +#define _SIGUTIL_H + +int save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu); +int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu); +int save_rwin_state(int wsaved, __siginfo_rwin_t __user *rwin); +int restore_rwin_state(__siginfo_rwin_t __user *rp); + +#endif /* _SIGUTIL_H */ diff --git a/arch/sparc/kernel/sigutil_32.c b/arch/sparc/kernel/sigutil_32.c new file mode 100644 index 000000000000..35c7897b009a --- /dev/null +++ b/arch/sparc/kernel/sigutil_32.c @@ -0,0 +1,120 @@ +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/thread_info.h> +#include <linux/uaccess.h> +#include <linux/sched.h> + +#include <asm/sigcontext.h> +#include <asm/fpumacro.h> +#include <asm/ptrace.h> + +#include "sigutil.h" + +int save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) +{ +	int err = 0; +#ifdef CONFIG_SMP +	if (test_tsk_thread_flag(current, TIF_USEDFPU)) { +		put_psr(get_psr() | PSR_EF); +		fpsave(¤t->thread.float_regs[0], ¤t->thread.fsr, +		       ¤t->thread.fpqueue[0], ¤t->thread.fpqdepth); +		regs->psr &= ~(PSR_EF); +		clear_tsk_thread_flag(current, TIF_USEDFPU); +	} +#else +	if (current == last_task_used_math) { +		put_psr(get_psr() | PSR_EF); +		fpsave(¤t->thread.float_regs[0], ¤t->thread.fsr, +		       ¤t->thread.fpqueue[0], ¤t->thread.fpqdepth); +		last_task_used_math = NULL; +		regs->psr &= ~(PSR_EF); +	} +#endif +	err |= __copy_to_user(&fpu->si_float_regs[0], +			      ¤t->thread.float_regs[0], +			      (sizeof(unsigned long) * 32)); +	err |= __put_user(current->thread.fsr, &fpu->si_fsr); +	err |= __put_user(current->thread.fpqdepth, &fpu->si_fpqdepth); +	if (current->thread.fpqdepth != 0) +		err |= __copy_to_user(&fpu->si_fpqueue[0], +				      ¤t->thread.fpqueue[0], +				      ((sizeof(unsigned long) + +				      (sizeof(unsigned long *)))*16)); +	clear_used_math(); +	return err; +} + +int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) +{ +	int err; +#ifdef CONFIG_SMP +	if (test_tsk_thread_flag(current, TIF_USEDFPU)) +		regs->psr &= ~PSR_EF; +#else +	if (current == last_task_used_math) { +		last_task_used_math = NULL; +		regs->psr &= ~PSR_EF; +	} +#endif +	set_used_math(); +	clear_tsk_thread_flag(current, TIF_USEDFPU); + +	if (!access_ok(VERIFY_READ, fpu, sizeof(*fpu))) +		return -EFAULT; + +	err = __copy_from_user(¤t->thread.float_regs[0], &fpu->si_float_regs[0], +			       (sizeof(unsigned long) * 32)); +	err |= __get_user(current->thread.fsr, &fpu->si_fsr); +	err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth); +	if (current->thread.fpqdepth != 0) +		err |= __copy_from_user(¤t->thread.fpqueue[0], +					&fpu->si_fpqueue[0], +					((sizeof(unsigned long) + +					(sizeof(unsigned long *)))*16)); +	return err; +} + +int save_rwin_state(int wsaved, __siginfo_rwin_t __user *rwin) +{ +	int i, err = __put_user(wsaved, &rwin->wsaved); + +	for (i = 0; i < wsaved; i++) { +		struct reg_window32 *rp; +		unsigned long fp; + +		rp = ¤t_thread_info()->reg_window[i]; +		fp = current_thread_info()->rwbuf_stkptrs[i]; +		err |= copy_to_user(&rwin->reg_window[i], rp, +				    sizeof(struct reg_window32)); +		err |= __put_user(fp, &rwin->rwbuf_stkptrs[i]); +	} +	return err; +} + +int restore_rwin_state(__siginfo_rwin_t __user *rp) +{ +	struct thread_info *t = current_thread_info(); +	int i, wsaved, err; + +	__get_user(wsaved, &rp->wsaved); +	if (wsaved > NSWINS) +		return -EFAULT; + +	err = 0; +	for (i = 0; i < wsaved; i++) { +		err |= copy_from_user(&t->reg_window[i], +				      &rp->reg_window[i], +				      sizeof(struct reg_window32)); +		err |= __get_user(t->rwbuf_stkptrs[i], +				  &rp->rwbuf_stkptrs[i]); +	} +	if (err) +		return err; + +	t->w_saved = wsaved; +	synchronize_user_stack(); +	if (t->w_saved) +		return -EFAULT; +	return 0; + +} diff --git a/arch/sparc/kernel/sigutil_64.c b/arch/sparc/kernel/sigutil_64.c new file mode 100644 index 000000000000..e7dc508c38eb --- /dev/null +++ b/arch/sparc/kernel/sigutil_64.c @@ -0,0 +1,93 @@ +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/thread_info.h> +#include <linux/uaccess.h> + +#include <asm/sigcontext.h> +#include <asm/fpumacro.h> +#include <asm/ptrace.h> + +#include "sigutil.h" + +int save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) +{ +	unsigned long *fpregs = current_thread_info()->fpregs; +	unsigned long fprs; +	int err = 0; +	 +	fprs = current_thread_info()->fpsaved[0]; +	if (fprs & FPRS_DL) +		err |= copy_to_user(&fpu->si_float_regs[0], fpregs, +				    (sizeof(unsigned int) * 32)); +	if (fprs & FPRS_DU) +		err |= copy_to_user(&fpu->si_float_regs[32], fpregs+16, +				    (sizeof(unsigned int) * 32)); +	err |= __put_user(current_thread_info()->xfsr[0], &fpu->si_fsr); +	err |= __put_user(current_thread_info()->gsr[0], &fpu->si_gsr); +	err |= __put_user(fprs, &fpu->si_fprs); + +	return err; +} + +int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) +{ +	unsigned long *fpregs = current_thread_info()->fpregs; +	unsigned long fprs; +	int err; + +	err = __get_user(fprs, &fpu->si_fprs); +	fprs_write(0); +	regs->tstate &= ~TSTATE_PEF; +	if (fprs & FPRS_DL) +		err |= copy_from_user(fpregs, &fpu->si_float_regs[0], +		       	       (sizeof(unsigned int) * 32)); +	if (fprs & FPRS_DU) +		err |= copy_from_user(fpregs+16, &fpu->si_float_regs[32], +		       	       (sizeof(unsigned int) * 32)); +	err |= __get_user(current_thread_info()->xfsr[0], &fpu->si_fsr); +	err |= __get_user(current_thread_info()->gsr[0], &fpu->si_gsr); +	current_thread_info()->fpsaved[0] |= fprs; +	return err; +} + +int save_rwin_state(int wsaved, __siginfo_rwin_t __user *rwin) +{ +	int i, err = __put_user(wsaved, &rwin->wsaved); + +	for (i = 0; i < wsaved; i++) { +		struct reg_window *rp = ¤t_thread_info()->reg_window[i]; +		unsigned long fp = current_thread_info()->rwbuf_stkptrs[i]; + +		err |= copy_to_user(&rwin->reg_window[i], rp, +				    sizeof(struct reg_window)); +		err |= __put_user(fp, &rwin->rwbuf_stkptrs[i]); +	} +	return err; +} + +int restore_rwin_state(__siginfo_rwin_t __user *rp) +{ +	struct thread_info *t = current_thread_info(); +	int i, wsaved, err; + +	__get_user(wsaved, &rp->wsaved); +	if (wsaved > NSWINS) +		return -EFAULT; + +	err = 0; +	for (i = 0; i < wsaved; i++) { +		err |= copy_from_user(&t->reg_window[i], +				      &rp->reg_window[i], +				      sizeof(struct reg_window)); +		err |= __get_user(t->rwbuf_stkptrs[i], +				  &rp->rwbuf_stkptrs[i]); +	} +	if (err) +		return err; + +	set_thread_wsaved(wsaved); +	synchronize_user_stack(); +	if (get_thread_wsaved()) +		return -EFAULT; +	return 0; +} diff --git a/arch/sparc/kernel/sys32.S b/arch/sparc/kernel/sys32.S index 44e5faf1ad5f..d97f3eb72e06 100644 --- a/arch/sparc/kernel/sys32.S +++ b/arch/sparc/kernel/sys32.S @@ -81,7 +81,6 @@ SIGN2(sys32_fadvise64, compat_sys_fadvise64, %o0, %o4)  SIGN2(sys32_fadvise64_64, compat_sys_fadvise64_64, %o0, %o5)  SIGN2(sys32_bdflush, sys_bdflush, %o0, %o1)  SIGN1(sys32_mlockall, sys_mlockall, %o0) -SIGN1(sys32_nfsservctl, compat_sys_nfsservctl, %o0)  SIGN1(sys32_clock_nanosleep, compat_sys_clock_nanosleep, %o1)  SIGN1(sys32_timer_settime, compat_sys_timer_settime, %o1)  SIGN1(sys32_io_submit, compat_sys_io_submit, %o1) diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S index 6e492d59f6b1..09d8ec454450 100644 --- a/arch/sparc/kernel/systbls_32.S +++ b/arch/sparc/kernel/systbls_32.S @@ -67,7 +67,7 @@ sys_call_table:  /*235*/	.long sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys_mlockall  /*240*/	.long sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler  /*245*/	.long sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep -/*250*/	.long sys_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl +/*250*/	.long sys_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_ni_syscall  /*255*/	.long sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep  /*260*/	.long sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun  /*265*/	.long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S index f566518483b5..c9296ab0b1f4 100644 --- a/arch/sparc/kernel/systbls_64.S +++ b/arch/sparc/kernel/systbls_64.S @@ -145,7 +145,7 @@ sys_call_table:  	.word sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys_mlockall  /*240*/	.word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler  	.word sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep -/*250*/	.word sys_64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl +/*250*/	.word sys_64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nis_syscall  	.word sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep  /*260*/	.word sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun  	.word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy | 
