aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2006-01-19 05:42:49 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-01-19 05:42:49 -0500
commit2d7d5f05111a9d913131a2764d8b20157f8f758d (patch)
tree792deb7a3b9f72894d16affff1569a15b35e428b
parentf7111ceb5266750db2a1d193b98fb6a3d9b5a56a (diff)
[SPARC]: Add support for *at(), ppoll, and pselect syscalls.
This also includes by necessity _TIF_RESTORE_SIGMASK support, which actually resulted in a lot of cleanups. The sparc signal handling code is quite a mess and I should clean it up some day. Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--arch/sparc/kernel/entry.S56
-rw-r--r--arch/sparc/kernel/rtrap.S9
-rw-r--r--arch/sparc/kernel/signal.c117
-rw-r--r--arch/sparc/kernel/sparc_ksyms.c2
-rw-r--r--arch/sparc/kernel/systbls.S10
-rw-r--r--arch/sparc64/kernel/entry.S23
-rw-r--r--arch/sparc64/kernel/rtrap.S33
-rw-r--r--arch/sparc64/kernel/signal.c151
-rw-r--r--arch/sparc64/kernel/signal32.c122
-rw-r--r--arch/sparc64/kernel/sparc64_ksyms.c4
-rw-r--r--arch/sparc64/kernel/systbls.S21
-rw-r--r--arch/sparc64/solaris/entry64.S2
-rw-r--r--include/asm-sparc/thread_info.h5
-rw-r--r--include/asm-sparc/unistd.h22
-rw-r--r--include/asm-sparc64/thread_info.h6
-rw-r--r--include/asm-sparc64/unistd.h23
16 files changed, 184 insertions, 422 deletions
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index 03ecb4e4614e..c51d08d218ef 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -1277,62 +1277,6 @@ sys_sigstack:
1277 mov %l5, %o7 1277 mov %l5, %o7
1278 1278
1279 .align 4 1279 .align 4
1280 .globl sys_sigpause
1281sys_sigpause:
1282 /* Note: %o0 already has correct value... */
1283 call do_sigpause
1284 add %sp, STACKFRAME_SZ, %o1
1285
1286 ld [%curptr + TI_FLAGS], %l5
1287 andcc %l5, _TIF_SYSCALL_TRACE, %g0
1288 be 1f
1289 nop
1290
1291 call syscall_trace
1292 nop
1293
12941:
1295 /* We are returning to a signal handler. */
1296 RESTORE_ALL
1297
1298 .align 4
1299 .globl sys_sigsuspend
1300sys_sigsuspend:
1301 call do_sigsuspend
1302 add %sp, STACKFRAME_SZ, %o0
1303
1304 ld [%curptr + TI_FLAGS], %l5
1305 andcc %l5, _TIF_SYSCALL_TRACE, %g0
1306 be 1f
1307 nop
1308
1309 call syscall_trace
1310 nop
1311
13121:
1313 /* We are returning to a signal handler. */
1314 RESTORE_ALL
1315
1316 .align 4
1317 .globl sys_rt_sigsuspend
1318sys_rt_sigsuspend:
1319 /* Note: %o0, %o1 already have correct value... */
1320 call do_rt_sigsuspend
1321 add %sp, STACKFRAME_SZ, %o2
1322
1323 ld [%curptr + TI_FLAGS], %l5
1324 andcc %l5, _TIF_SYSCALL_TRACE, %g0
1325 be 1f
1326 nop
1327
1328 call syscall_trace
1329 nop
1330
13311:
1332 /* We are returning to a signal handler. */
1333 RESTORE_ALL
1334
1335 .align 4
1336 .globl sys_sigreturn 1280 .globl sys_sigreturn
1337sys_sigreturn: 1281sys_sigreturn:
1338 call do_sigreturn 1282 call do_sigreturn
diff --git a/arch/sparc/kernel/rtrap.S b/arch/sparc/kernel/rtrap.S
index f7460d897e79..77ca6fd81253 100644
--- a/arch/sparc/kernel/rtrap.S
+++ b/arch/sparc/kernel/rtrap.S
@@ -68,15 +68,14 @@ ret_trap_lockless_ipi:
68 68
69 ld [%curptr + TI_FLAGS], %g2 69 ld [%curptr + TI_FLAGS], %g2
70signal_p: 70signal_p:
71 andcc %g2, (_TIF_NOTIFY_RESUME|_TIF_SIGPENDING), %g0 71 andcc %g2, (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK), %g0
72 bz,a ret_trap_continue 72 bz,a ret_trap_continue
73 ld [%sp + STACKFRAME_SZ + PT_PSR], %t_psr 73 ld [%sp + STACKFRAME_SZ + PT_PSR], %t_psr
74 74
75 clr %o0 75 mov %l5, %o1
76 mov %l5, %o2 76 mov %l6, %o2
77 mov %l6, %o3
78 call do_signal 77 call do_signal
79 add %sp, STACKFRAME_SZ, %o1 ! pt_regs ptr 78 add %sp, STACKFRAME_SZ, %o0 ! pt_regs ptr
80 79
81 /* Fall through. */ 80 /* Fall through. */
82 ld [%sp + STACKFRAME_SZ + PT_PSR], %t_psr 81 ld [%sp + STACKFRAME_SZ + PT_PSR], %t_psr
diff --git a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c
index 5f34d7dc2b89..0748d8147bbf 100644
--- a/arch/sparc/kernel/signal.c
+++ b/arch/sparc/kernel/signal.c
@@ -35,9 +35,6 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
35 void *fpqueue, unsigned long *fpqdepth); 35 void *fpqueue, unsigned long *fpqdepth);
36extern void fpload(unsigned long *fpregs, unsigned long *fsr); 36extern void fpload(unsigned long *fpregs, unsigned long *fsr);
37 37
38asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
39 unsigned long orig_o0, int restart_syscall);
40
41/* Signal frames: the original one (compatible with SunOS): 38/* Signal frames: the original one (compatible with SunOS):
42 * 39 *
43 * Set up a signal frame... Make the stack look the way SunOS 40 * Set up a signal frame... Make the stack look the way SunOS
@@ -95,98 +92,30 @@ struct rt_signal_frame {
95#define NF_ALIGNEDSZ (((sizeof(struct new_signal_frame) + 7) & (~7))) 92#define NF_ALIGNEDSZ (((sizeof(struct new_signal_frame) + 7) & (~7)))
96#define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame) + 7) & (~7))) 93#define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame) + 7) & (~7)))
97 94
98/* 95static int _sigpause_common(old_sigset_t set)
99 * atomically swap in the new signal mask, and wait for a signal.
100 * This is really tricky on the Sparc, watch out...
101 */
102asmlinkage void _sigpause_common(old_sigset_t set, struct pt_regs *regs)
103{ 96{
104 sigset_t saveset;
105
106 set &= _BLOCKABLE; 97 set &= _BLOCKABLE;
107 spin_lock_irq(&current->sighand->siglock); 98 spin_lock_irq(&current->sighand->siglock);
108 saveset = current->blocked; 99 current->saved_sigmask = current->blocked;
109 siginitset(&current->blocked, set); 100 siginitset(&current->blocked, set);
110 recalc_sigpending(); 101 recalc_sigpending();
111 spin_unlock_irq(&current->sighand->siglock); 102 spin_unlock_irq(&current->sighand->siglock);
112 103
113 regs->pc = regs->npc; 104 current->state = TASK_INTERRUPTIBLE;
114 regs->npc += 4; 105 schedule();
115 106 set_thread_flag(TIF_RESTORE_SIGMASK);
116 /* Condition codes and return value where set here for sigpause,
117 * and so got used by setup_frame, which again causes sigreturn()
118 * to return -EINTR.
119 */
120 while (1) {
121 current->state = TASK_INTERRUPTIBLE;
122 schedule();
123 /*
124 * Return -EINTR and set condition code here,
125 * so the interrupted system call actually returns
126 * these.
127 */
128 regs->psr |= PSR_C;
129 regs->u_regs[UREG_I0] = EINTR;
130 if (do_signal(&saveset, regs, 0, 0))
131 return;
132 }
133}
134 107
135asmlinkage void do_sigpause(unsigned int set, struct pt_regs *regs) 108 return -ERESTARTNOHAND;
136{
137 _sigpause_common(set, regs);
138} 109}
139 110
140asmlinkage void do_sigsuspend (struct pt_regs *regs) 111asmlinkage int sys_sigpause(unsigned int set)
141{ 112{
142 _sigpause_common(regs->u_regs[UREG_I0], regs); 113 return _sigpause_common(set);
143} 114}
144 115
145asmlinkage void do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize, 116asmlinkage int sys_sigsuspend(old_sigset_t set)
146 struct pt_regs *regs)
147{ 117{
148 sigset_t oldset, set; 118 return _sigpause_common(set);
149
150 /* XXX: Don't preclude handling different sized sigset_t's. */
151 if (sigsetsize != sizeof(sigset_t)) {
152 regs->psr |= PSR_C;
153 regs->u_regs[UREG_I0] = EINVAL;
154 return;
155 }
156
157 if (copy_from_user(&set, uset, sizeof(set))) {
158 regs->psr |= PSR_C;
159 regs->u_regs[UREG_I0] = EFAULT;
160 return;
161 }
162
163 sigdelsetmask(&set, ~_BLOCKABLE);
164 spin_lock_irq(&current->sighand->siglock);
165 oldset = current->blocked;
166 current->blocked = set;
167 recalc_sigpending();
168 spin_unlock_irq(&current->sighand->siglock);
169
170 regs->pc = regs->npc;
171 regs->npc += 4;
172
173 /* Condition codes and return value where set here for sigpause,
174 * and so got used by setup_frame, which again causes sigreturn()
175 * to return -EINTR.
176 */
177 while (1) {
178 current->state = TASK_INTERRUPTIBLE;
179 schedule();
180 /*
181 * Return -EINTR and set condition code here,
182 * so the interrupted system call actually returns
183 * these.
184 */
185 regs->psr |= PSR_C;
186 regs->u_regs[UREG_I0] = EINTR;
187 if (do_signal(&oldset, regs, 0, 0))
188 return;
189 }
190} 119}
191 120
192static inline int 121static inline int
@@ -1067,13 +996,13 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
1067 * want to handle. Thus you cannot kill init even with a SIGKILL even by 996 * want to handle. Thus you cannot kill init even with a SIGKILL even by
1068 * mistake. 997 * mistake.
1069 */ 998 */
1070asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, 999asmlinkage void do_signal(struct pt_regs * regs, unsigned long orig_i0, int restart_syscall)
1071 unsigned long orig_i0, int restart_syscall)
1072{ 1000{
1073 siginfo_t info; 1001 siginfo_t info;
1074 struct sparc_deliver_cookie cookie; 1002 struct sparc_deliver_cookie cookie;
1075 struct k_sigaction ka; 1003 struct k_sigaction ka;
1076 int signr; 1004 int signr;
1005 sigset_t *oldset;
1077 1006
1078 /* 1007 /*
1079 * XXX Disable svr4 signal handling until solaris emulation works. 1008 * XXX Disable svr4 signal handling until solaris emulation works.
@@ -1089,7 +1018,9 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
1089 cookie.restart_syscall = restart_syscall; 1018 cookie.restart_syscall = restart_syscall;
1090 cookie.orig_i0 = orig_i0; 1019 cookie.orig_i0 = orig_i0;
1091 1020
1092 if (!oldset) 1021 if (test_thread_flag(TIF_RESTORE_SIGMASK))
1022 oldset = &current->saved_sigmask;
1023 else
1093 oldset = &current->blocked; 1024 oldset = &current->blocked;
1094 1025
1095 signr = get_signal_to_deliver(&info, &ka, regs, &cookie); 1026 signr = get_signal_to_deliver(&info, &ka, regs, &cookie);
@@ -1098,7 +1029,14 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
1098 syscall_restart(cookie.orig_i0, regs, &ka.sa); 1029 syscall_restart(cookie.orig_i0, regs, &ka.sa);
1099 handle_signal(signr, &ka, &info, oldset, 1030 handle_signal(signr, &ka, &info, oldset,
1100 regs, svr4_signal); 1031 regs, svr4_signal);
1101 return 1; 1032 /* a signal was successfully delivered; the saved
1033 * sigmask will have been stored in the signal frame,
1034 * and will be restored by sigreturn, so we can simply
1035 * clear the TIF_RESTORE_SIGMASK flag.
1036 */
1037 if (test_thread_flag(TIF_RESTORE_SIGMASK))
1038 clear_thread_flag(TIF_RESTORE_SIGMASK);
1039 return;
1102 } 1040 }
1103 if (cookie.restart_syscall && 1041 if (cookie.restart_syscall &&
1104 (regs->u_regs[UREG_I0] == ERESTARTNOHAND || 1042 (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
@@ -1115,7 +1053,14 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
1115 regs->pc -= 4; 1053 regs->pc -= 4;
1116 regs->npc -= 4; 1054 regs->npc -= 4;
1117 } 1055 }
1118 return 0; 1056
1057 /* if there's no signal to deliver, we just put the saved sigmask
1058 * back
1059 */
1060 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
1061 clear_thread_flag(TIF_RESTORE_SIGMASK);
1062 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
1063 }
1119} 1064}
1120 1065
1121asmlinkage int 1066asmlinkage int
diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c
index 0b0d492c953b..19b25399d7e4 100644
--- a/arch/sparc/kernel/sparc_ksyms.c
+++ b/arch/sparc/kernel/sparc_ksyms.c
@@ -66,7 +66,6 @@ struct poll {
66 66
67extern int svr4_getcontext (svr4_ucontext_t *, struct pt_regs *); 67extern int svr4_getcontext (svr4_ucontext_t *, struct pt_regs *);
68extern int svr4_setcontext (svr4_ucontext_t *, struct pt_regs *); 68extern int svr4_setcontext (svr4_ucontext_t *, struct pt_regs *);
69void _sigpause_common (unsigned int set, struct pt_regs *);
70extern void (*__copy_1page)(void *, const void *); 69extern void (*__copy_1page)(void *, const void *);
71extern void __memmove(void *, const void *, __kernel_size_t); 70extern void __memmove(void *, const void *, __kernel_size_t);
72extern void (*bzero_1page)(void *); 71extern void (*bzero_1page)(void *);
@@ -227,7 +226,6 @@ EXPORT_SYMBOL(kunmap_atomic);
227/* Solaris/SunOS binary compatibility */ 226/* Solaris/SunOS binary compatibility */
228EXPORT_SYMBOL(svr4_setcontext); 227EXPORT_SYMBOL(svr4_setcontext);
229EXPORT_SYMBOL(svr4_getcontext); 228EXPORT_SYMBOL(svr4_getcontext);
230EXPORT_SYMBOL(_sigpause_common);
231 229
232EXPORT_SYMBOL(dump_thread); 230EXPORT_SYMBOL(dump_thread);
233 231
diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S
index e457a40838fc..6877ae4cd1d9 100644
--- a/arch/sparc/kernel/systbls.S
+++ b/arch/sparc/kernel/systbls.S
@@ -75,7 +75,10 @@ sys_call_table:
75/*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy 75/*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy
76/*270*/ .long sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink 76/*270*/ .long sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink
77/*275*/ .long sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid 77/*275*/ .long sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
78/*280*/ .long sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl 78/*280*/ .long sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl, sys_openat
79/*285*/ .long sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_newfstatat
80/*290*/ .long sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
81/*295*/ .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll
79 82
80#ifdef CONFIG_SUNOS_EMUL 83#ifdef CONFIG_SUNOS_EMUL
81 /* Now the SunOS syscall table. */ 84 /* Now the SunOS syscall table. */
@@ -181,6 +184,11 @@ sunos_sys_table:
181 .long sunos_nosys, sunos_nosys, sunos_nosys 184 .long sunos_nosys, sunos_nosys, sunos_nosys
182 .long sunos_nosys 185 .long sunos_nosys
183/*280*/ .long sunos_nosys, sunos_nosys, sunos_nosys 186/*280*/ .long sunos_nosys, sunos_nosys, sunos_nosys
187 .long sunos_nosys, sunos_nosys, sunos_nosys
188 .long sunos_nosys, sunos_nosys, sunos_nosys
184 .long sunos_nosys 189 .long sunos_nosys
190/*290*/ .long sunos_nosys, sunos_nosys, sunos_nosys
191 .long sunos_nosys, sunos_nosys, sunos_nosys
192 .long sunos_nosys, sunos_nosys, sunos_nosys
185 193
186#endif 194#endif
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
index 710002991888..e50e56e4ab61 100644
--- a/arch/sparc64/kernel/entry.S
+++ b/arch/sparc64/kernel/entry.S
@@ -1416,7 +1416,6 @@ execve_merge:
1416 add %sp, PTREGS_OFF, %o0 1416 add %sp, PTREGS_OFF, %o0
1417 1417
1418 .globl sys_pipe, sys_sigpause, sys_nis_syscall 1418 .globl sys_pipe, sys_sigpause, sys_nis_syscall
1419 .globl sys_sigsuspend, sys_rt_sigsuspend
1420 .globl sys_rt_sigreturn 1419 .globl sys_rt_sigreturn
1421 .globl sys_ptrace 1420 .globl sys_ptrace
1422 .globl sys_sigaltstack 1421 .globl sys_sigaltstack
@@ -1440,28 +1439,6 @@ sys32_sigaltstack:
1440 mov %i6, %o2 1439 mov %i6, %o2
1441#endif 1440#endif
1442 .align 32 1441 .align 32
1443sys_sigsuspend: add %sp, PTREGS_OFF, %o0
1444 call do_sigsuspend
1445 add %o7, 1f-.-4, %o7
1446 nop
1447sys_rt_sigsuspend: /* NOTE: %o0,%o1 have a correct value already */
1448 add %sp, PTREGS_OFF, %o2
1449 call do_rt_sigsuspend
1450 add %o7, 1f-.-4, %o7
1451 nop
1452#ifdef CONFIG_COMPAT
1453 .globl sys32_rt_sigsuspend
1454sys32_rt_sigsuspend: /* NOTE: %o0,%o1 have a correct value already */
1455 srl %o0, 0, %o0
1456 add %sp, PTREGS_OFF, %o2
1457 call do_rt_sigsuspend32
1458 add %o7, 1f-.-4, %o7
1459#endif
1460 /* NOTE: %o0 has a correct value already */
1461sys_sigpause: add %sp, PTREGS_OFF, %o1
1462 call do_sigpause
1463 add %o7, 1f-.-4, %o7
1464 nop
1465#ifdef CONFIG_COMPAT 1442#ifdef CONFIG_COMPAT
1466 .globl sys32_sigreturn 1443 .globl sys32_sigreturn
1467sys32_sigreturn: 1444sys32_sigreturn:
diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S
index 090dcca00d2a..b80eba0081ca 100644
--- a/arch/sparc64/kernel/rtrap.S
+++ b/arch/sparc64/kernel/rtrap.S
@@ -53,14 +53,13 @@ __handle_user_windows:
53 wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate 53 wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate
54 ldx [%g6 + TI_FLAGS], %l0 54 ldx [%g6 + TI_FLAGS], %l0
55 55
561: andcc %l0, (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING), %g0 561: andcc %l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0
57 be,pt %xcc, __handle_user_windows_continue 57 be,pt %xcc, __handle_user_windows_continue
58 nop 58 nop
59 clr %o0 59 mov %l5, %o1
60 mov %l5, %o2 60 mov %l6, %o2
61 mov %l6, %o3 61 add %sp, PTREGS_OFF, %o0
62 add %sp, PTREGS_OFF, %o1 62 mov %l0, %o3
63 mov %l0, %o4
64 63
65 call do_notify_resume 64 call do_notify_resume
66 wrpr %g0, RTRAP_PSTATE, %pstate 65 wrpr %g0, RTRAP_PSTATE, %pstate
@@ -96,15 +95,14 @@ __handle_perfctrs:
96 wrpr %g0, RTRAP_PSTATE, %pstate 95 wrpr %g0, RTRAP_PSTATE, %pstate
97 wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate 96 wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate
98 ldx [%g6 + TI_FLAGS], %l0 97 ldx [%g6 + TI_FLAGS], %l0
991: andcc %l0, (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING), %g0 981: andcc %l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0
100 99
101 be,pt %xcc, __handle_perfctrs_continue 100 be,pt %xcc, __handle_perfctrs_continue
102 sethi %hi(TSTATE_PEF), %o0 101 sethi %hi(TSTATE_PEF), %o0
103 clr %o0 102 mov %l5, %o1
104 mov %l5, %o2 103 mov %l6, %o2
105 mov %l6, %o3 104 add %sp, PTREGS_OFF, %o0
106 add %sp, PTREGS_OFF, %o1 105 mov %l0, %o3
107 mov %l0, %o4
108 call do_notify_resume 106 call do_notify_resume
109 107
110 wrpr %g0, RTRAP_PSTATE, %pstate 108 wrpr %g0, RTRAP_PSTATE, %pstate
@@ -129,11 +127,10 @@ __handle_userfpu:
129 ba,a,pt %xcc, __handle_userfpu_continue 127 ba,a,pt %xcc, __handle_userfpu_continue
130 128
131__handle_signal: 129__handle_signal:
132 clr %o0 130 mov %l5, %o1
133 mov %l5, %o2 131 mov %l6, %o2
134 mov %l6, %o3 132 add %sp, PTREGS_OFF, %o0
135 add %sp, PTREGS_OFF, %o1 133 mov %l0, %o3
136 mov %l0, %o4
137 call do_notify_resume 134 call do_notify_resume
138 wrpr %g0, RTRAP_PSTATE, %pstate 135 wrpr %g0, RTRAP_PSTATE, %pstate
139 wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate 136 wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate
@@ -200,7 +197,7 @@ __handle_preemption_continue:
200 andcc %l1, %o0, %g0 197 andcc %l1, %o0, %g0
201 andcc %l0, _TIF_NEED_RESCHED, %g0 198 andcc %l0, _TIF_NEED_RESCHED, %g0
202 bne,pn %xcc, __handle_preemption 199 bne,pn %xcc, __handle_preemption
203 andcc %l0, (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING), %g0 200 andcc %l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0
204 bne,pn %xcc, __handle_signal 201 bne,pn %xcc, __handle_signal
205__handle_signal_continue: 202__handle_signal_continue:
206 ldub [%g6 + TI_WSAVED], %o2 203 ldub [%g6 + TI_WSAVED], %o2
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c
index 60f5dfabb1e1..ca11a4c457d4 100644
--- a/arch/sparc64/kernel/signal.c
+++ b/arch/sparc64/kernel/signal.c
@@ -36,9 +36,6 @@
36 36
37#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 37#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
38 38
39static int do_signal(sigset_t *oldset, struct pt_regs * regs,
40 unsigned long orig_o0, int ret_from_syscall);
41
42/* {set, get}context() needed for 64-bit SparcLinux userland. */ 39/* {set, get}context() needed for 64-bit SparcLinux userland. */
43asmlinkage void sparc64_set_context(struct pt_regs *regs) 40asmlinkage void sparc64_set_context(struct pt_regs *regs)
44{ 41{
@@ -242,114 +239,29 @@ struct rt_signal_frame {
242/* Align macros */ 239/* Align macros */
243#define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame) + 7) & (~7))) 240#define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame) + 7) & (~7)))
244 241
245/* 242static long _sigpause_common(old_sigset_t set)
246 * atomically swap in the new signal mask, and wait for a signal.
247 * This is really tricky on the Sparc, watch out...
248 */
249asmlinkage void _sigpause_common(old_sigset_t set, struct pt_regs *regs)
250{ 243{
251 sigset_t saveset;
252
253#ifdef CONFIG_SPARC32_COMPAT
254 if (test_thread_flag(TIF_32BIT)) {
255 extern asmlinkage void _sigpause32_common(compat_old_sigset_t,
256 struct pt_regs *);
257 _sigpause32_common(set, regs);
258 return;
259 }
260#endif
261 set &= _BLOCKABLE; 244 set &= _BLOCKABLE;
262 spin_lock_irq(&current->sighand->siglock); 245 spin_lock_irq(&current->sighand->siglock);
263 saveset = current->blocked; 246 current->saved_sigmask = current->blocked;
264 siginitset(&current->blocked, set); 247 siginitset(&current->blocked, set);
265 recalc_sigpending(); 248 recalc_sigpending();
266 spin_unlock_irq(&current->sighand->siglock); 249 spin_unlock_irq(&current->sighand->siglock);
267
268 if (test_thread_flag(TIF_32BIT)) {
269 regs->tpc = (regs->tnpc & 0xffffffff);
270 regs->tnpc = (regs->tnpc + 4) & 0xffffffff;
271 } else {
272 regs->tpc = regs->tnpc;
273 regs->tnpc += 4;
274 }
275 250
276 /* Condition codes and return value where set here for sigpause, 251 current->state = TASK_INTERRUPTIBLE;
277 * and so got used by setup_frame, which again causes sigreturn() 252 schedule();
278 * to return -EINTR. 253 set_thread_flag(TIF_RESTORE_SIGMASK);
279 */ 254 return -ERESTARTNOHAND;
280 while (1) {
281 current->state = TASK_INTERRUPTIBLE;
282 schedule();
283 /*
284 * Return -EINTR and set condition code here,
285 * so the interrupted system call actually returns
286 * these.
287 */
288 regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY);
289 regs->u_regs[UREG_I0] = EINTR;
290 if (do_signal(&saveset, regs, 0, 0))
291 return;
292 }
293} 255}
294 256
295asmlinkage void do_sigpause(unsigned int set, struct pt_regs *regs) 257asmlinkage long sys_sigpause(unsigned int set)
296{ 258{
297 _sigpause_common(set, regs); 259 return _sigpause_common(set);
298} 260}
299 261
300asmlinkage void do_sigsuspend(struct pt_regs *regs) 262asmlinkage long sys_sigsuspend(old_sigset_t set)
301{ 263{
302 _sigpause_common(regs->u_regs[UREG_I0], regs); 264 return _sigpause_common(set);
303}
304
305asmlinkage void do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize, struct pt_regs *regs)
306{
307 sigset_t oldset, set;
308
309 /* XXX: Don't preclude handling different sized sigset_t's. */
310 if (sigsetsize != sizeof(sigset_t)) {
311 regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY);
312 regs->u_regs[UREG_I0] = EINVAL;
313 return;
314 }
315 if (copy_from_user(&set, uset, sizeof(set))) {
316 regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY);
317 regs->u_regs[UREG_I0] = EFAULT;
318 return;
319 }
320
321 sigdelsetmask(&set, ~_BLOCKABLE);
322 spin_lock_irq(&current->sighand->siglock);
323 oldset = current->blocked;
324 current->blocked = set;
325 recalc_sigpending();
326 spin_unlock_irq(&current->sighand->siglock);
327
328 if (test_thread_flag(TIF_32BIT)) {
329 regs->tpc = (regs->tnpc & 0xffffffff);
330 regs->tnpc = (regs->tnpc + 4) & 0xffffffff;
331 } else {
332 regs->tpc = regs->tnpc;
333 regs->tnpc += 4;
334 }
335
336 /* Condition codes and return value where set here for sigpause,
337 * and so got used by setup_frame, which again causes sigreturn()
338 * to return -EINTR.
339 */
340 while (1) {
341 current->state = TASK_INTERRUPTIBLE;
342 schedule();
343 /*
344 * Return -EINTR and set condition code here,
345 * so the interrupted system call actually returns
346 * these.
347 */
348 regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY);
349 regs->u_regs[UREG_I0] = EINTR;
350 if (do_signal(&oldset, regs, 0, 0))
351 return;
352 }
353} 265}
354 266
355static inline int 267static inline int
@@ -607,26 +519,29 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
607 * want to handle. Thus you cannot kill init even with a SIGKILL even by 519 * want to handle. Thus you cannot kill init even with a SIGKILL even by
608 * mistake. 520 * mistake.
609 */ 521 */
610static int do_signal(sigset_t *oldset, struct pt_regs * regs, 522static void do_signal(struct pt_regs *regs, unsigned long orig_i0, int restart_syscall)
611 unsigned long orig_i0, int restart_syscall)
612{ 523{
613 siginfo_t info; 524 siginfo_t info;
614 struct signal_deliver_cookie cookie; 525 struct signal_deliver_cookie cookie;
615 struct k_sigaction ka; 526 struct k_sigaction ka;
616 int signr; 527 int signr;
528 sigset_t *oldset;
617 529
618 cookie.restart_syscall = restart_syscall; 530 cookie.restart_syscall = restart_syscall;
619 cookie.orig_i0 = orig_i0; 531 cookie.orig_i0 = orig_i0;
620 532
621 if (!oldset) 533 if (test_thread_flag(TIF_RESTORE_SIGMASK))
534 oldset = &current->saved_sigmask;
535 else
622 oldset = &current->blocked; 536 oldset = &current->blocked;
623 537
624#ifdef CONFIG_SPARC32_COMPAT 538#ifdef CONFIG_SPARC32_COMPAT
625 if (test_thread_flag(TIF_32BIT)) { 539 if (test_thread_flag(TIF_32BIT)) {
626 extern int do_signal32(sigset_t *, struct pt_regs *, 540 extern void do_signal32(sigset_t *, struct pt_regs *,
627 unsigned long, int); 541 unsigned long, int);
628 return do_signal32(oldset, regs, orig_i0, 542 do_signal32(oldset, regs, orig_i0,
629 cookie.restart_syscall); 543 cookie.restart_syscall);
544 return;
630 } 545 }
631#endif 546#endif
632 547
@@ -635,7 +550,15 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs,
635 if (cookie.restart_syscall) 550 if (cookie.restart_syscall)
636 syscall_restart(orig_i0, regs, &ka.sa); 551 syscall_restart(orig_i0, regs, &ka.sa);
637 handle_signal(signr, &ka, &info, oldset, regs); 552 handle_signal(signr, &ka, &info, oldset, regs);
638 return 1; 553
554 /* a signal was successfully delivered; the saved
555 * sigmask will have been stored in the signal frame,
556 * and will be restored by sigreturn, so we can simply
557 * clear the TIF_RESTORE_SIGMASK flag.
558 */
559 if (test_thread_flag(TIF_RESTORE_SIGMASK))
560 clear_thread_flag(TIF_RESTORE_SIGMASK);
561 return;
639 } 562 }
640 if (cookie.restart_syscall && 563 if (cookie.restart_syscall &&
641 (regs->u_regs[UREG_I0] == ERESTARTNOHAND || 564 (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
@@ -652,15 +575,21 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs,
652 regs->tpc -= 4; 575 regs->tpc -= 4;
653 regs->tnpc -= 4; 576 regs->tnpc -= 4;
654 } 577 }
655 return 0; 578
579 /* if there's no signal to deliver, we just put the saved sigmask
580 * back
581 */
582 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
583 clear_thread_flag(TIF_RESTORE_SIGMASK);
584 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
585 }
656} 586}
657 587
658void do_notify_resume(sigset_t *oldset, struct pt_regs *regs, 588void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, int restart_syscall,
659 unsigned long orig_i0, int restart_syscall,
660 unsigned long thread_info_flags) 589 unsigned long thread_info_flags)
661{ 590{
662 if (thread_info_flags & _TIF_SIGPENDING) 591 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
663 do_signal(oldset, regs, orig_i0, restart_syscall); 592 do_signal(regs, orig_i0, restart_syscall);
664} 593}
665 594
666void ptrace_signal_deliver(struct pt_regs *regs, void *cookie) 595void ptrace_signal_deliver(struct pt_regs *regs, void *cookie)
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
index 009a86e5ded4..708ba9b42cda 100644
--- a/arch/sparc64/kernel/signal32.c
+++ b/arch/sparc64/kernel/signal32.c
@@ -32,9 +32,6 @@
32 32
33#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 33#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
34 34
35int do_signal32(sigset_t *oldset, struct pt_regs *regs,
36 unsigned long orig_o0, int ret_from_syscall);
37
38/* Signal frames: the original one (compatible with SunOS): 35/* Signal frames: the original one (compatible with SunOS):
39 * 36 *
40 * Set up a signal frame... Make the stack look the way SunOS 37 * Set up a signal frame... Make the stack look the way SunOS
@@ -226,102 +223,6 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
226 return 0; 223 return 0;
227} 224}
228 225
229/*
230 * atomically swap in the new signal mask, and wait for a signal.
231 * This is really tricky on the Sparc, watch out...
232 */
233asmlinkage void _sigpause32_common(compat_old_sigset_t set, struct pt_regs *regs)
234{
235 sigset_t saveset;
236
237 set &= _BLOCKABLE;
238 spin_lock_irq(&current->sighand->siglock);
239 saveset = current->blocked;
240 siginitset(&current->blocked, set);
241 recalc_sigpending();
242 spin_unlock_irq(&current->sighand->siglock);
243
244 regs->tpc = regs->tnpc;
245 regs->tnpc += 4;
246 if (test_thread_flag(TIF_32BIT)) {
247 regs->tpc &= 0xffffffff;
248 regs->tnpc &= 0xffffffff;
249 }
250
251 /* Condition codes and return value where set here for sigpause,
252 * and so got used by setup_frame, which again causes sigreturn()
253 * to return -EINTR.
254 */
255 while (1) {
256 current->state = TASK_INTERRUPTIBLE;
257 schedule();
258 /*
259 * Return -EINTR and set condition code here,
260 * so the interrupted system call actually returns
261 * these.
262 */
263 regs->tstate |= TSTATE_ICARRY;
264 regs->u_regs[UREG_I0] = EINTR;
265 if (do_signal32(&saveset, regs, 0, 0))
266 return;
267 }
268}
269
270asmlinkage void do_rt_sigsuspend32(u32 uset, size_t sigsetsize, struct pt_regs *regs)
271{
272 sigset_t oldset, set;
273 compat_sigset_t set32;
274
275 /* XXX: Don't preclude handling different sized sigset_t's. */
276 if (((compat_size_t)sigsetsize) != sizeof(sigset_t)) {
277 regs->tstate |= TSTATE_ICARRY;
278 regs->u_regs[UREG_I0] = EINVAL;
279 return;
280 }
281 if (copy_from_user(&set32, compat_ptr(uset), sizeof(set32))) {
282 regs->tstate |= TSTATE_ICARRY;
283 regs->u_regs[UREG_I0] = EFAULT;
284 return;
285 }
286 switch (_NSIG_WORDS) {
287 case 4: set.sig[3] = set32.sig[6] + (((long)set32.sig[7]) << 32);
288 case 3: set.sig[2] = set32.sig[4] + (((long)set32.sig[5]) << 32);
289 case 2: set.sig[1] = set32.sig[2] + (((long)set32.sig[3]) << 32);
290 case 1: set.sig[0] = set32.sig[0] + (((long)set32.sig[1]) << 32);
291 }
292 sigdelsetmask(&set, ~_BLOCKABLE);
293 spin_lock_irq(&current->sighand->siglock);
294 oldset = current->blocked;
295 current->blocked = set;
296 recalc_sigpending();
297 spin_unlock_irq(&current->sighand->siglock);
298
299 regs->tpc = regs->tnpc;
300 regs->tnpc += 4;
301 if (test_thread_flag(TIF_32BIT)) {
302 regs->tpc &= 0xffffffff;
303 regs->tnpc &= 0xffffffff;
304 }
305
306 /* Condition codes and return value where set here for sigpause,
307 * and so got used by setup_frame, which again causes sigreturn()
308 * to return -EINTR.
309 */
310 while (1) {
311 current->state = TASK_INTERRUPTIBLE;
312 schedule();
313 /*
314 * Return -EINTR and set condition code here,
315 * so the interrupted system call actually returns
316 * these.
317 */
318 regs->tstate |= TSTATE_ICARRY;
319 regs->u_regs[UREG_I0] = EINTR;
320 if (do_signal32(&oldset, regs, 0, 0))
321 return;
322 }
323}
324
325static int restore_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) 226static int restore_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
326{ 227{
327 unsigned long *fpregs = current_thread_info()->fpregs; 228 unsigned long *fpregs = current_thread_info()->fpregs;
@@ -1362,8 +1263,8 @@ static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs
1362 * want to handle. Thus you cannot kill init even with a SIGKILL even by 1263 * want to handle. Thus you cannot kill init even with a SIGKILL even by
1363 * mistake. 1264 * mistake.
1364 */ 1265 */
1365int do_signal32(sigset_t *oldset, struct pt_regs * regs, 1266void do_signal32(sigset_t *oldset, struct pt_regs * regs,
1366 unsigned long orig_i0, int restart_syscall) 1267 unsigned long orig_i0, int restart_syscall)
1367{ 1268{
1368 siginfo_t info; 1269 siginfo_t info;
1369 struct signal_deliver_cookie cookie; 1270 struct signal_deliver_cookie cookie;
@@ -1380,7 +1281,15 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs,
1380 syscall_restart32(orig_i0, regs, &ka.sa); 1281 syscall_restart32(orig_i0, regs, &ka.sa);
1381 handle_signal32(signr, &ka, &info, oldset, 1282 handle_signal32(signr, &ka, &info, oldset,
1382 regs, svr4_signal); 1283 regs, svr4_signal);
1383 return 1; 1284
1285 /* a signal was successfully delivered; the saved
1286 * sigmask will have been stored in the signal frame,
1287 * and will be restored by sigreturn, so we can simply
1288 * clear the TIF_RESTORE_SIGMASK flag.
1289 */
1290 if (test_thread_flag(TIF_RESTORE_SIGMASK))
1291 clear_thread_flag(TIF_RESTORE_SIGMASK);
1292 return;
1384 } 1293 }
1385 if (cookie.restart_syscall && 1294 if (cookie.restart_syscall &&
1386 (regs->u_regs[UREG_I0] == ERESTARTNOHAND || 1295 (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
@@ -1397,7 +1306,14 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs,
1397 regs->tpc -= 4; 1306 regs->tpc -= 4;
1398 regs->tnpc -= 4; 1307 regs->tnpc -= 4;
1399 } 1308 }
1400 return 0; 1309
1310 /* if there's no signal to deliver, we just put the saved sigmask
1311 * back
1312 */
1313 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
1314 clear_thread_flag(TIF_RESTORE_SIGMASK);
1315 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
1316 }
1401} 1317}
1402 1318
1403struct sigstack32 { 1319struct sigstack32 {
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
index d177d7e5c9d3..3c06bfb92a8c 100644
--- a/arch/sparc64/kernel/sparc64_ksyms.c
+++ b/arch/sparc64/kernel/sparc64_ksyms.c
@@ -69,7 +69,6 @@ struct poll {
69 69
70extern void die_if_kernel(char *str, struct pt_regs *regs); 70extern void die_if_kernel(char *str, struct pt_regs *regs);
71extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); 71extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
72void _sigpause_common (unsigned int set, struct pt_regs *);
73extern void *__bzero(void *, size_t); 72extern void *__bzero(void *, size_t);
74extern void *__memscan_zero(void *, size_t); 73extern void *__memscan_zero(void *, size_t);
75extern void *__memscan_generic(void *, int, size_t); 74extern void *__memscan_generic(void *, int, size_t);
@@ -236,9 +235,10 @@ EXPORT_SYMBOL(pci_dma_supported);
236/* I/O device mmaping on Sparc64. */ 235/* I/O device mmaping on Sparc64. */
237EXPORT_SYMBOL(io_remap_pfn_range); 236EXPORT_SYMBOL(io_remap_pfn_range);
238 237
238#ifdef CONFIG_COMPAT
239/* Solaris/SunOS binary compatibility */ 239/* Solaris/SunOS binary compatibility */
240EXPORT_SYMBOL(_sigpause_common);
241EXPORT_SYMBOL(verify_compat_iovec); 240EXPORT_SYMBOL(verify_compat_iovec);
241#endif
242 242
243EXPORT_SYMBOL(dump_fpu); 243EXPORT_SYMBOL(dump_fpu);
244EXPORT_SYMBOL(pte_alloc_one_kernel); 244EXPORT_SYMBOL(pte_alloc_one_kernel);
diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S
index 98d24bc00044..5ed1a17cd5b9 100644
--- a/arch/sparc64/kernel/systbls.S
+++ b/arch/sparc64/kernel/systbls.S
@@ -41,7 +41,7 @@ sys_call_table32:
41/*90*/ .word sys_dup2, sys_setfsuid, compat_sys_fcntl, sys32_select, sys_setfsgid 41/*90*/ .word sys_dup2, sys_setfsuid, compat_sys_fcntl, sys32_select, sys_setfsgid
42 .word sys_fsync, sys32_setpriority, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall 42 .word sys_fsync, sys32_setpriority, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
43/*100*/ .word sys32_getpriority, sys32_rt_sigreturn, sys32_rt_sigaction, sys32_rt_sigprocmask, sys32_rt_sigpending 43/*100*/ .word sys32_getpriority, sys32_rt_sigreturn, sys32_rt_sigaction, sys32_rt_sigprocmask, sys32_rt_sigpending
44 .word compat_sys_rt_sigtimedwait, sys32_rt_sigqueueinfo, sys32_rt_sigsuspend, sys_setresuid, sys_getresuid 44 .word compat_sys_rt_sigtimedwait, sys32_rt_sigqueueinfo, compat_sys_rt_sigsuspend, sys_setresuid, sys_getresuid
45/*110*/ .word sys_setresgid, sys_getresgid, sys_setregid, sys_nis_syscall, sys_nis_syscall 45/*110*/ .word sys_setresgid, sys_getresgid, sys_setregid, sys_nis_syscall, sys_nis_syscall
46 .word sys32_getgroups, sys32_gettimeofday, sys32_getrusage, sys_nis_syscall, sys_getcwd 46 .word sys32_getgroups, sys32_gettimeofday, sys32_getrusage, sys_nis_syscall, sys_getcwd
47/*120*/ .word compat_sys_readv, compat_sys_writev, sys32_settimeofday, sys32_fchown16, sys_fchmod 47/*120*/ .word compat_sys_readv, compat_sys_writev, sys32_settimeofday, sys32_fchown16, sys_fchmod
@@ -76,7 +76,10 @@ sys_call_table32:
76 .word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy 76 .word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy
77/*270*/ .word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink 77/*270*/ .word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink
78 .word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid 78 .word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid
79/*280*/ .word sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl 79/*280*/ .word sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl, compat_sys_openat
80 .word sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, compat_sys_newfstatat
81/*285*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
82 .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll
80 83
81#endif /* CONFIG_COMPAT */ 84#endif /* CONFIG_COMPAT */
82 85
@@ -142,7 +145,10 @@ sys_call_table:
142 .word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy 145 .word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy
143/*270*/ .word sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink 146/*270*/ .word sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink
144 .word sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid 147 .word sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
145/*280*/ .word sys_nis_syscall, sys_add_key, sys_request_key, sys_keyctl 148/*280*/ .word sys_nis_syscall, sys_add_key, sys_request_key, sys_keyctl, sys_openat
149 .word sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, compat_sys_newfstatat
150/*285*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
151 .word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll
146 152
147#if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \ 153#if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \
148 defined(CONFIG_SOLARIS_EMUL_MODULE) 154 defined(CONFIG_SOLARIS_EMUL_MODULE)
@@ -239,13 +245,20 @@ sunos_sys_table:
239/*250*/ .word sunos_nosys, sunos_nosys, sunos_nosys 245/*250*/ .word sunos_nosys, sunos_nosys, sunos_nosys
240 .word sunos_nosys, sunos_nosys, sunos_nosys 246 .word sunos_nosys, sunos_nosys, sunos_nosys
241 .word sunos_nosys, sunos_nosys, sunos_nosys 247 .word sunos_nosys, sunos_nosys, sunos_nosys
248 .word sunos_nosys
249/*260*/ .word sunos_nosys, sunos_nosys, sunos_nosys
242 .word sunos_nosys, sunos_nosys, sunos_nosys 250 .word sunos_nosys, sunos_nosys, sunos_nosys
243 .word sunos_nosys, sunos_nosys, sunos_nosys 251 .word sunos_nosys, sunos_nosys, sunos_nosys
252 .word sunos_nosys
253/*270*/ .word sunos_nosys, sunos_nosys, sunos_nosys
244 .word sunos_nosys, sunos_nosys, sunos_nosys 254 .word sunos_nosys, sunos_nosys, sunos_nosys
245 .word sunos_nosys, sunos_nosys, sunos_nosys 255 .word sunos_nosys, sunos_nosys, sunos_nosys
256 .word sunos_nosys
257/*280*/ .word sunos_nosys, sunos_nosys, sunos_nosys
246 .word sunos_nosys, sunos_nosys, sunos_nosys 258 .word sunos_nosys, sunos_nosys, sunos_nosys
247 .word sunos_nosys, sunos_nosys, sunos_nosys 259 .word sunos_nosys, sunos_nosys, sunos_nosys
260 .word sunos_nosys
261/*290*/ .word sunos_nosys, sunos_nosys, sunos_nosys
248 .word sunos_nosys, sunos_nosys, sunos_nosys 262 .word sunos_nosys, sunos_nosys, sunos_nosys
249 .word sunos_nosys, sunos_nosys, sunos_nosys 263 .word sunos_nosys, sunos_nosys, sunos_nosys
250 .word sunos_nosys
251#endif 264#endif
diff --git a/arch/sparc64/solaris/entry64.S b/arch/sparc64/solaris/entry64.S
index 4b6ae583c0a3..eb314ed23cdb 100644
--- a/arch/sparc64/solaris/entry64.S
+++ b/arch/sparc64/solaris/entry64.S
@@ -180,6 +180,8 @@ solaris_sigsuspend:
180 nop 180 nop
181 call sys_sigsuspend 181 call sys_sigsuspend
182 stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] 182 stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
183 b,pt %xcc, ret_from_solaris
184 nop
183 185
184 .globl solaris_getpid 186 .globl solaris_getpid
185solaris_getpid: 187solaris_getpid:
diff --git a/include/asm-sparc/thread_info.h b/include/asm-sparc/thread_info.h
index 65f060b040ab..91b9f5888c85 100644
--- a/include/asm-sparc/thread_info.h
+++ b/include/asm-sparc/thread_info.h
@@ -128,9 +128,10 @@ BTFIXUPDEF_CALL(void, free_thread_info, struct thread_info *)
128 * thread information flag bit numbers 128 * thread information flag bit numbers
129 */ 129 */
130#define TIF_SYSCALL_TRACE 0 /* syscall trace active */ 130#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
131#define TIF_NOTIFY_RESUME 1 /* resumption notification requested */ 131/* flag bit 1 is available */
132#define TIF_SIGPENDING 2 /* signal pending */ 132#define TIF_SIGPENDING 2 /* signal pending */
133#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ 133#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
134#define TIF_RESTORE_SIGMASK 4 /* restore signal mask in do_signal() */
134#define TIF_USEDFPU 8 /* FPU was used by this task 135#define TIF_USEDFPU 8 /* FPU was used by this task
135 * this quantum (SMP) */ 136 * this quantum (SMP) */
136#define TIF_POLLING_NRFLAG 9 /* true if poll_idle() is polling 137#define TIF_POLLING_NRFLAG 9 /* true if poll_idle() is polling
@@ -139,9 +140,9 @@ BTFIXUPDEF_CALL(void, free_thread_info, struct thread_info *)
139 140
140/* as above, but as bit values */ 141/* as above, but as bit values */
141#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) 142#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
142#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
143#define _TIF_SIGPENDING (1<<TIF_SIGPENDING) 143#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
144#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) 144#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
145#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
145#define _TIF_USEDFPU (1<<TIF_USEDFPU) 146#define _TIF_USEDFPU (1<<TIF_USEDFPU)
146#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) 147#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
147 148
diff --git a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h
index 58dba518239e..2ac64e65e336 100644
--- a/include/asm-sparc/unistd.h
+++ b/include/asm-sparc/unistd.h
@@ -300,11 +300,26 @@
300#define __NR_add_key 281 300#define __NR_add_key 281
301#define __NR_request_key 282 301#define __NR_request_key 282
302#define __NR_keyctl 283 302#define __NR_keyctl 283
303#define __NR_openat 284
304#define __NR_mkdirat 285
305#define __NR_mknodat 286
306#define __NR_fchownat 287
307#define __NR_futimesat 288
308#define __NR_newfstatat 289
309#define __NR_unlinkat 290
310#define __NR_renameat 291
311#define __NR_linkat 292
312#define __NR_symlinkat 293
313#define __NR_readlinkat 294
314#define __NR_fchmodat 295
315#define __NR_faccessat 296
316#define __NR_pselect6 297
317#define __NR_ppoll 298
303 318
304/* WARNING: You MAY NOT add syscall numbers larger than 283, since 319/* WARNING: You MAY NOT add syscall numbers larger than 298, since
305 * all of the syscall tables in the Sparc kernel are 320 * all of the syscall tables in the Sparc kernel are
306 * sized to have 283 entries (starting at zero). Therefore 321 * sized to have 298 entries (starting at zero). Therefore
307 * find a free slot in the 0-282 range. 322 * find a free slot in the 0-298 range.
308 */ 323 */
309 324
310#define _syscall0(type,name) \ 325#define _syscall0(type,name) \
@@ -458,6 +473,7 @@ return -1; \
458#define __ARCH_WANT_SYS_OLDUMOUNT 473#define __ARCH_WANT_SYS_OLDUMOUNT
459#define __ARCH_WANT_SYS_SIGPENDING 474#define __ARCH_WANT_SYS_SIGPENDING
460#define __ARCH_WANT_SYS_SIGPROCMASK 475#define __ARCH_WANT_SYS_SIGPROCMASK
476#define __ARCH_WANT_SYS_RT_SIGSUSPEND
461#endif 477#endif
462 478
463#ifdef __KERNEL_SYSCALLS__ 479#ifdef __KERNEL_SYSCALLS__
diff --git a/include/asm-sparc64/thread_info.h b/include/asm-sparc64/thread_info.h
index c94d8b3991bd..ac9d068aab4f 100644
--- a/include/asm-sparc64/thread_info.h
+++ b/include/asm-sparc64/thread_info.h
@@ -221,7 +221,7 @@ register struct thread_info *current_thread_info_reg asm("g6");
221 * nop 221 * nop
222 */ 222 */
223#define TIF_SYSCALL_TRACE 0 /* syscall trace active */ 223#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
224#define TIF_NOTIFY_RESUME 1 /* resumption notification requested */ 224#define TIF_RESTORE_SIGMASK 1 /* restore signal mask in do_signal() */
225#define TIF_SIGPENDING 2 /* signal pending */ 225#define TIF_SIGPENDING 2 /* signal pending */
226#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ 226#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
227#define TIF_PERFCTR 4 /* performance counters active */ 227#define TIF_PERFCTR 4 /* performance counters active */
@@ -241,7 +241,6 @@ register struct thread_info *current_thread_info_reg asm("g6");
241#define TIF_POLLING_NRFLAG 14 241#define TIF_POLLING_NRFLAG 14
242 242
243#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) 243#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
244#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
245#define _TIF_SIGPENDING (1<<TIF_SIGPENDING) 244#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
246#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) 245#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
247#define _TIF_PERFCTR (1<<TIF_PERFCTR) 246#define _TIF_PERFCTR (1<<TIF_PERFCTR)
@@ -250,11 +249,12 @@ register struct thread_info *current_thread_info_reg asm("g6");
250#define _TIF_32BIT (1<<TIF_32BIT) 249#define _TIF_32BIT (1<<TIF_32BIT)
251#define _TIF_SECCOMP (1<<TIF_SECCOMP) 250#define _TIF_SECCOMP (1<<TIF_SECCOMP)
252#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) 251#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
252#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
253#define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING) 253#define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING)
254#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) 254#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
255 255
256#define _TIF_USER_WORK_MASK ((0xff << TI_FLAG_WSAVED_SHIFT) | \ 256#define _TIF_USER_WORK_MASK ((0xff << TI_FLAG_WSAVED_SHIFT) | \
257 (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | \ 257 (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | \
258 _TIF_NEED_RESCHED | _TIF_PERFCTR)) 258 _TIF_NEED_RESCHED | _TIF_PERFCTR))
259 259
260#endif /* __KERNEL__ */ 260#endif /* __KERNEL__ */
diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h
index 51ec2879b881..84ac2bdb0902 100644
--- a/include/asm-sparc64/unistd.h
+++ b/include/asm-sparc64/unistd.h
@@ -302,11 +302,26 @@
302#define __NR_add_key 281 302#define __NR_add_key 281
303#define __NR_request_key 282 303#define __NR_request_key 282
304#define __NR_keyctl 283 304#define __NR_keyctl 283
305#define __NR_openat 284
306#define __NR_mkdirat 285
307#define __NR_mknodat 286
308#define __NR_fchownat 287
309#define __NR_futimesat 288
310#define __NR_newfstatat 289
311#define __NR_unlinkat 290
312#define __NR_renameat 291
313#define __NR_linkat 292
314#define __NR_symlinkat 293
315#define __NR_readlinkat 294
316#define __NR_fchmodat 295
317#define __NR_faccessat 296
318#define __NR_pselect6 297
319#define __NR_ppoll 298
305 320
306/* WARNING: You MAY NOT add syscall numbers larger than 283, since 321/* WARNING: You MAY NOT add syscall numbers larger than 298, since
307 * all of the syscall tables in the Sparc kernel are 322 * all of the syscall tables in the Sparc kernel are
308 * sized to have 283 entries (starting at zero). Therefore 323 * sized to have 298 entries (starting at zero). Therefore
309 * find a free slot in the 0-282 range. 324 * find a free slot in the 0-298 range.
310 */ 325 */
311 326
312#define _syscall0(type,name) \ 327#define _syscall0(type,name) \
@@ -501,6 +516,8 @@ asmlinkage long sys_rt_sigaction(int sig,
501#define __ARCH_WANT_SYS_OLDUMOUNT 516#define __ARCH_WANT_SYS_OLDUMOUNT
502#define __ARCH_WANT_SYS_SIGPENDING 517#define __ARCH_WANT_SYS_SIGPENDING
503#define __ARCH_WANT_SYS_SIGPROCMASK 518#define __ARCH_WANT_SYS_SIGPROCMASK
519#define __ARCH_WANT_SYS_RT_SIGSUSPEND
520#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
504#endif 521#endif
505 522
506/* 523/*