aboutsummaryrefslogtreecommitdiffstats
path: root/arch/tile
diff options
context:
space:
mode:
authorRichard Weinberger <richard@nod.at>2013-10-07 09:01:08 -0400
committerRichard Weinberger <richard@sigma-star.at>2014-08-06 07:03:20 -0400
commitb3707c7ed013d36752272ca2f9ed20dc8aed92e4 (patch)
tree3b302c32a0ce9f30eda613994acb9e3f086dad9c /arch/tile
parentb46e848768acc458ba94feef162b8901592dbb9c (diff)
tile: Use get_signal() signal_setup_done()
Use the more generic functions get_signal() signal_setup_done() for signal delivery. Signed-off-by: Richard Weinberger <richard@nod.at> Acked-by: Chris Metcalf <cmetcalf@tilera.com>
Diffstat (limited to 'arch/tile')
-rw-r--r--arch/tile/include/asm/compat.h3
-rw-r--r--arch/tile/kernel/compat_signal.c29
-rw-r--r--arch/tile/kernel/signal.c54
3 files changed, 40 insertions, 46 deletions
diff --git a/arch/tile/include/asm/compat.h b/arch/tile/include/asm/compat.h
index ffd4493efc78..c14e36f008c8 100644
--- a/arch/tile/include/asm/compat.h
+++ b/arch/tile/include/asm/compat.h
@@ -267,8 +267,7 @@ static inline int is_compat_task(void)
267 return current_thread_info()->status & TS_COMPAT; 267 return current_thread_info()->status & TS_COMPAT;
268} 268}
269 269
270extern int compat_setup_rt_frame(int sig, struct k_sigaction *ka, 270extern int compat_setup_rt_frame(struct ksignal *ksig, sigset_t *set,
271 siginfo_t *info, sigset_t *set,
272 struct pt_regs *regs); 271 struct pt_regs *regs);
273 272
274/* Compat syscalls. */ 273/* Compat syscalls. */
diff --git a/arch/tile/kernel/compat_signal.c b/arch/tile/kernel/compat_signal.c
index 19c04b5ce408..8c5abf2e4794 100644
--- a/arch/tile/kernel/compat_signal.c
+++ b/arch/tile/kernel/compat_signal.c
@@ -190,18 +190,18 @@ static inline void __user *compat_get_sigframe(struct k_sigaction *ka,
190 return (void __user *) sp; 190 return (void __user *) sp;
191} 191}
192 192
193int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 193int compat_setup_rt_frame(struct ksignal *ksig, sigset_t *set,
194 sigset_t *set, struct pt_regs *regs) 194 struct pt_regs *regs)
195{ 195{
196 unsigned long restorer; 196 unsigned long restorer;
197 struct compat_rt_sigframe __user *frame; 197 struct compat_rt_sigframe __user *frame;
198 int err = 0; 198 int err = 0, sig = ksig->sig;
199 int usig; 199 int usig;
200 200
201 frame = compat_get_sigframe(ka, regs, sizeof(*frame)); 201 frame = compat_get_sigframe(&ksig->ka, regs, sizeof(*frame));
202 202
203 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 203 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
204 goto give_sigsegv; 204 goto err;
205 205
206 usig = current_thread_info()->exec_domain 206 usig = current_thread_info()->exec_domain
207 && current_thread_info()->exec_domain->signal_invmap 207 && current_thread_info()->exec_domain->signal_invmap
@@ -210,12 +210,12 @@ int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
210 : sig; 210 : sig;
211 211
212 /* Always write at least the signal number for the stack backtracer. */ 212 /* Always write at least the signal number for the stack backtracer. */
213 if (ka->sa.sa_flags & SA_SIGINFO) { 213 if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
214 /* At sigreturn time, restore the callee-save registers too. */ 214 /* At sigreturn time, restore the callee-save registers too. */
215 err |= copy_siginfo_to_user32(&frame->info, info); 215 err |= copy_siginfo_to_user32(&frame->info, &ksig->info);
216 regs->flags |= PT_FLAGS_RESTORE_REGS; 216 regs->flags |= PT_FLAGS_RESTORE_REGS;
217 } else { 217 } else {
218 err |= __put_user(info->si_signo, &frame->info.si_signo); 218 err |= __put_user(ksig->info.si_signo, &frame->info.si_signo);
219 } 219 }
220 220
221 /* Create the ucontext. */ 221 /* Create the ucontext. */
@@ -226,11 +226,11 @@ int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
226 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs); 226 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs);
227 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 227 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
228 if (err) 228 if (err)
229 goto give_sigsegv; 229 goto err;
230 230
231 restorer = VDSO_SYM(&__vdso_rt_sigreturn); 231 restorer = VDSO_SYM(&__vdso_rt_sigreturn);
232 if (ka->sa.sa_flags & SA_RESTORER) 232 if (ksig->ka.sa.sa_flags & SA_RESTORER)
233 restorer = ptr_to_compat_reg(ka->sa.sa_restorer); 233 restorer = ptr_to_compat_reg(ksig->ka.sa.sa_restorer);
234 234
235 /* 235 /*
236 * Set up registers for signal handler. 236 * Set up registers for signal handler.
@@ -239,7 +239,7 @@ int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
239 * We always pass siginfo and mcontext, regardless of SA_SIGINFO, 239 * We always pass siginfo and mcontext, regardless of SA_SIGINFO,
240 * since some things rely on this (e.g. glibc's debug/segfault.c). 240 * since some things rely on this (e.g. glibc's debug/segfault.c).
241 */ 241 */
242 regs->pc = ptr_to_compat_reg(ka->sa.sa_handler); 242 regs->pc = ptr_to_compat_reg(ksig->ka.sa.sa_handler);
243 regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */ 243 regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */
244 regs->sp = ptr_to_compat_reg(frame); 244 regs->sp = ptr_to_compat_reg(frame);
245 regs->lr = restorer; 245 regs->lr = restorer;
@@ -249,7 +249,8 @@ int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
249 regs->flags |= PT_FLAGS_CALLER_SAVES; 249 regs->flags |= PT_FLAGS_CALLER_SAVES;
250 return 0; 250 return 0;
251 251
252give_sigsegv: 252err:
253 signal_fault("bad setup frame", regs, frame, sig); 253 trace_unhandled_signal("bad sigreturn frame", regs,
254 (unsigned long)frame, SIGSEGV);
254 return -EFAULT; 255 return -EFAULT;
255} 256}
diff --git a/arch/tile/kernel/signal.c b/arch/tile/kernel/signal.c
index d1d026f01267..7c2fecc52177 100644
--- a/arch/tile/kernel/signal.c
+++ b/arch/tile/kernel/signal.c
@@ -153,18 +153,18 @@ static inline void __user *get_sigframe(struct k_sigaction *ka,
153 return (void __user *) sp; 153 return (void __user *) sp;
154} 154}
155 155
156static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 156static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
157 sigset_t *set, struct pt_regs *regs) 157 struct pt_regs *regs)
158{ 158{
159 unsigned long restorer; 159 unsigned long restorer;
160 struct rt_sigframe __user *frame; 160 struct rt_sigframe __user *frame;
161 int err = 0; 161 int err = 0, sig = ksig->sig;
162 int usig; 162 int usig;
163 163
164 frame = get_sigframe(ka, regs, sizeof(*frame)); 164 frame = get_sigframe(&ksig->ka, regs, sizeof(*frame));
165 165
166 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 166 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
167 goto give_sigsegv; 167 goto err;
168 168
169 usig = current_thread_info()->exec_domain 169 usig = current_thread_info()->exec_domain
170 && current_thread_info()->exec_domain->signal_invmap 170 && current_thread_info()->exec_domain->signal_invmap
@@ -173,12 +173,12 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
173 : sig; 173 : sig;
174 174
175 /* Always write at least the signal number for the stack backtracer. */ 175 /* Always write at least the signal number for the stack backtracer. */
176 if (ka->sa.sa_flags & SA_SIGINFO) { 176 if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
177 /* At sigreturn time, restore the callee-save registers too. */ 177 /* At sigreturn time, restore the callee-save registers too. */
178 err |= copy_siginfo_to_user(&frame->info, info); 178 err |= copy_siginfo_to_user(&frame->info, &ksig->info);
179 regs->flags |= PT_FLAGS_RESTORE_REGS; 179 regs->flags |= PT_FLAGS_RESTORE_REGS;
180 } else { 180 } else {
181 err |= __put_user(info->si_signo, &frame->info.si_signo); 181 err |= __put_user(ksig->info.si_signo, &frame->info.si_signo);
182 } 182 }
183 183
184 /* Create the ucontext. */ 184 /* Create the ucontext. */
@@ -189,11 +189,11 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
189 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs); 189 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs);
190 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 190 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
191 if (err) 191 if (err)
192 goto give_sigsegv; 192 goto err;
193 193
194 restorer = VDSO_SYM(&__vdso_rt_sigreturn); 194 restorer = VDSO_SYM(&__vdso_rt_sigreturn);
195 if (ka->sa.sa_flags & SA_RESTORER) 195 if (ksig->ka.sa.sa_flags & SA_RESTORER)
196 restorer = (unsigned long) ka->sa.sa_restorer; 196 restorer = (unsigned long) ksig->ka.sa.sa_restorer;
197 197
198 /* 198 /*
199 * Set up registers for signal handler. 199 * Set up registers for signal handler.
@@ -202,7 +202,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
202 * We always pass siginfo and mcontext, regardless of SA_SIGINFO, 202 * We always pass siginfo and mcontext, regardless of SA_SIGINFO,
203 * since some things rely on this (e.g. glibc's debug/segfault.c). 203 * since some things rely on this (e.g. glibc's debug/segfault.c).
204 */ 204 */
205 regs->pc = (unsigned long) ka->sa.sa_handler; 205 regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
206 regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */ 206 regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */
207 regs->sp = (unsigned long) frame; 207 regs->sp = (unsigned long) frame;
208 regs->lr = restorer; 208 regs->lr = restorer;
@@ -212,8 +212,9 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
212 regs->flags |= PT_FLAGS_CALLER_SAVES; 212 regs->flags |= PT_FLAGS_CALLER_SAVES;
213 return 0; 213 return 0;
214 214
215give_sigsegv: 215err:
216 signal_fault("bad setup frame", regs, frame, sig); 216 trace_unhandled_signal("bad sigreturn frame", regs,
217 (unsigned long)frame, SIGSEGV);
217 return -EFAULT; 218 return -EFAULT;
218} 219}
219 220
@@ -221,9 +222,7 @@ give_sigsegv:
221 * OK, we're invoking a handler 222 * OK, we're invoking a handler
222 */ 223 */
223 224
224static void handle_signal(unsigned long sig, siginfo_t *info, 225static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
225 struct k_sigaction *ka,
226 struct pt_regs *regs)
227{ 226{
228 sigset_t *oldset = sigmask_to_save(); 227 sigset_t *oldset = sigmask_to_save();
229 int ret; 228 int ret;
@@ -238,7 +237,7 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
238 break; 237 break;
239 238
240 case -ERESTARTSYS: 239 case -ERESTARTSYS:
241 if (!(ka->sa.sa_flags & SA_RESTART)) { 240 if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
242 regs->regs[0] = -EINTR; 241 regs->regs[0] = -EINTR;
243 break; 242 break;
244 } 243 }
@@ -254,14 +253,12 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
254 /* Set up the stack frame */ 253 /* Set up the stack frame */
255#ifdef CONFIG_COMPAT 254#ifdef CONFIG_COMPAT
256 if (is_compat_task()) 255 if (is_compat_task())
257 ret = compat_setup_rt_frame(sig, ka, info, oldset, regs); 256 ret = compat_setup_rt_frame(ksig, oldset, regs);
258 else 257 else
259#endif 258#endif
260 ret = setup_rt_frame(sig, ka, info, oldset, regs); 259 ret = setup_rt_frame(ksig, oldset, regs);
261 if (ret) 260
262 return; 261 signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
263 signal_delivered(sig, info, ka, regs,
264 test_thread_flag(TIF_SINGLESTEP));
265} 262}
266 263
267/* 264/*
@@ -271,9 +268,7 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
271 */ 268 */
272void do_signal(struct pt_regs *regs) 269void do_signal(struct pt_regs *regs)
273{ 270{
274 siginfo_t info; 271 struct ksignal ksig;
275 int signr;
276 struct k_sigaction ka;
277 272
278 /* 273 /*
279 * i386 will check if we're coming from kernel mode and bail out 274 * i386 will check if we're coming from kernel mode and bail out
@@ -282,10 +277,9 @@ void do_signal(struct pt_regs *regs)
282 * helpful, we can reinstate the check on "!user_mode(regs)". 277 * helpful, we can reinstate the check on "!user_mode(regs)".
283 */ 278 */
284 279
285 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 280 if (get_signal(&ksig)) {
286 if (signr > 0) {
287 /* Whee! Actually deliver the signal. */ 281 /* Whee! Actually deliver the signal. */
288 handle_signal(signr, &info, &ka, regs); 282 handle_signal(&ksig, regs);
289 goto done; 283 goto done;
290 } 284 }
291 285