aboutsummaryrefslogtreecommitdiffstats
path: root/arch/frv/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/frv/kernel/signal.c')
-rw-r--r--arch/frv/kernel/signal.c112
1 files changed, 42 insertions, 70 deletions
diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c
index d822700d4f15..dc3d59de0870 100644
--- a/arch/frv/kernel/signal.c
+++ b/arch/frv/kernel/signal.c
@@ -158,19 +158,10 @@ static int setup_sigcontext(struct sigcontext __user *sc, unsigned long mask)
158/* 158/*
159 * Determine which stack to use.. 159 * Determine which stack to use..
160 */ 160 */
161static inline void __user *get_sigframe(struct k_sigaction *ka, 161static inline void __user *get_sigframe(struct ksignal *ksig,
162 size_t frame_size) 162 size_t frame_size)
163{ 163{
164 unsigned long sp; 164 unsigned long sp = sigsp(__frame->sp, ksig);
165
166 /* Default to using normal stack */
167 sp = __frame->sp;
168
169 /* This is the X/Open sanctioned signal stack switching. */
170 if (ka->sa.sa_flags & SA_ONSTACK) {
171 if (! sas_ss_flags(sp))
172 sp = current->sas_ss_sp + current->sas_ss_size;
173 }
174 165
175 return (void __user *) ((sp - frame_size) & ~7UL); 166 return (void __user *) ((sp - frame_size) & ~7UL);
176 167
@@ -180,17 +171,17 @@ static inline void __user *get_sigframe(struct k_sigaction *ka,
180/* 171/*
181 * 172 *
182 */ 173 */
183static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set) 174static int setup_frame(struct ksignal *ksig, sigset_t *set)
184{ 175{
185 struct sigframe __user *frame; 176 struct sigframe __user *frame;
186 int rsig; 177 int rsig, sig = ksig->sig;
187 178
188 set_fs(USER_DS); 179 set_fs(USER_DS);
189 180
190 frame = get_sigframe(ka, sizeof(*frame)); 181 frame = get_sigframe(ksig, sizeof(*frame));
191 182
192 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 183 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
193 goto give_sigsegv; 184 return -EFAULT;
194 185
195 rsig = sig; 186 rsig = sig;
196 if (sig < 32 && 187 if (sig < 32 &&
@@ -199,22 +190,22 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
199 rsig = __current_thread_info->exec_domain->signal_invmap[sig]; 190 rsig = __current_thread_info->exec_domain->signal_invmap[sig];
200 191
201 if (__put_user(rsig, &frame->sig) < 0) 192 if (__put_user(rsig, &frame->sig) < 0)
202 goto give_sigsegv; 193 return -EFAULT;
203 194
204 if (setup_sigcontext(&frame->sc, set->sig[0])) 195 if (setup_sigcontext(&frame->sc, set->sig[0]))
205 goto give_sigsegv; 196 return -EFAULT;
206 197
207 if (_NSIG_WORDS > 1) { 198 if (_NSIG_WORDS > 1) {
208 if (__copy_to_user(frame->extramask, &set->sig[1], 199 if (__copy_to_user(frame->extramask, &set->sig[1],
209 sizeof(frame->extramask))) 200 sizeof(frame->extramask)))
210 goto give_sigsegv; 201 return -EFAULT;
211 } 202 }
212 203
213 /* Set up to return from userspace. If provided, use a stub 204 /* Set up to return from userspace. If provided, use a stub
214 * already in userspace. */ 205 * already in userspace. */
215 if (ka->sa.sa_flags & SA_RESTORER) { 206 if (ksig->ka.sa.sa_flags & SA_RESTORER) {
216 if (__put_user(ka->sa.sa_restorer, &frame->pretcode) < 0) 207 if (__put_user(ksig->ka.sa.sa_restorer, &frame->pretcode) < 0)
217 goto give_sigsegv; 208 return -EFAULT;
218 } 209 }
219 else { 210 else {
220 /* Set up the following code on the stack: 211 /* Set up the following code on the stack:
@@ -224,7 +215,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
224 if (__put_user((__sigrestore_t)frame->retcode, &frame->pretcode) || 215 if (__put_user((__sigrestore_t)frame->retcode, &frame->pretcode) ||
225 __put_user(0x8efc0000|__NR_sigreturn, &frame->retcode[0]) || 216 __put_user(0x8efc0000|__NR_sigreturn, &frame->retcode[0]) ||
226 __put_user(0xc0700000, &frame->retcode[1])) 217 __put_user(0xc0700000, &frame->retcode[1]))
227 goto give_sigsegv; 218 return -EFAULT;
228 219
229 flush_icache_range((unsigned long) frame->retcode, 220 flush_icache_range((unsigned long) frame->retcode,
230 (unsigned long) (frame->retcode + 2)); 221 (unsigned long) (frame->retcode + 2));
@@ -233,14 +224,14 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
233 /* Set up registers for the signal handler */ 224 /* Set up registers for the signal handler */
234 if (current->personality & FDPIC_FUNCPTRS) { 225 if (current->personality & FDPIC_FUNCPTRS) {
235 struct fdpic_func_descriptor __user *funcptr = 226 struct fdpic_func_descriptor __user *funcptr =
236 (struct fdpic_func_descriptor __user *) ka->sa.sa_handler; 227 (struct fdpic_func_descriptor __user *) ksig->ka.sa.sa_handler;
237 struct fdpic_func_descriptor desc; 228 struct fdpic_func_descriptor desc;
238 if (copy_from_user(&desc, funcptr, sizeof(desc))) 229 if (copy_from_user(&desc, funcptr, sizeof(desc)))
239 goto give_sigsegv; 230 return -EFAULT;
240 __frame->pc = desc.text; 231 __frame->pc = desc.text;
241 __frame->gr15 = desc.GOT; 232 __frame->gr15 = desc.GOT;
242 } else { 233 } else {
243 __frame->pc = (unsigned long) ka->sa.sa_handler; 234 __frame->pc = (unsigned long) ksig->ka.sa.sa_handler;
244 __frame->gr15 = 0; 235 __frame->gr15 = 0;
245 } 236 }
246 237
@@ -255,29 +246,23 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
255#endif 246#endif
256 247
257 return 0; 248 return 0;
258
259give_sigsegv:
260 force_sigsegv(sig, current);
261 return -EFAULT;
262
263} /* end setup_frame() */ 249} /* end setup_frame() */
264 250
265/*****************************************************************************/ 251/*****************************************************************************/
266/* 252/*
267 * 253 *
268 */ 254 */
269static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 255static int setup_rt_frame(struct ksignal *ksig, sigset_t *set)
270 sigset_t *set)
271{ 256{
272 struct rt_sigframe __user *frame; 257 struct rt_sigframe __user *frame;
273 int rsig; 258 int rsig, sig = ksig->sig;
274 259
275 set_fs(USER_DS); 260 set_fs(USER_DS);
276 261
277 frame = get_sigframe(ka, sizeof(*frame)); 262 frame = get_sigframe(ksig, sizeof(*frame));
278 263
279 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 264 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
280 goto give_sigsegv; 265 return -EFAULT;
281 266
282 rsig = sig; 267 rsig = sig;
283 if (sig < 32 && 268 if (sig < 32 &&
@@ -288,28 +273,28 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
288 if (__put_user(rsig, &frame->sig) || 273 if (__put_user(rsig, &frame->sig) ||
289 __put_user(&frame->info, &frame->pinfo) || 274 __put_user(&frame->info, &frame->pinfo) ||
290 __put_user(&frame->uc, &frame->puc)) 275 __put_user(&frame->uc, &frame->puc))
291 goto give_sigsegv; 276 return -EFAULT;
292 277
293 if (copy_siginfo_to_user(&frame->info, info)) 278 if (copy_siginfo_to_user(&frame->info, &ksig->info))
294 goto give_sigsegv; 279 return -EFAULT;
295 280
296 /* Create the ucontext. */ 281 /* Create the ucontext. */
297 if (__put_user(0, &frame->uc.uc_flags) || 282 if (__put_user(0, &frame->uc.uc_flags) ||
298 __put_user(NULL, &frame->uc.uc_link) || 283 __put_user(NULL, &frame->uc.uc_link) ||
299 __save_altstack(&frame->uc.uc_stack, __frame->sp)) 284 __save_altstack(&frame->uc.uc_stack, __frame->sp))
300 goto give_sigsegv; 285 return -EFAULT;
301 286
302 if (setup_sigcontext(&frame->uc.uc_mcontext, set->sig[0])) 287 if (setup_sigcontext(&frame->uc.uc_mcontext, set->sig[0]))
303 goto give_sigsegv; 288 return -EFAULT;
304 289
305 if (__copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set))) 290 if (__copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)))
306 goto give_sigsegv; 291 return -EFAULT;
307 292
308 /* Set up to return from userspace. If provided, use a stub 293 /* Set up to return from userspace. If provided, use a stub
309 * already in userspace. */ 294 * already in userspace. */
310 if (ka->sa.sa_flags & SA_RESTORER) { 295 if (ksig->ka.sa.sa_flags & SA_RESTORER) {
311 if (__put_user(ka->sa.sa_restorer, &frame->pretcode)) 296 if (__put_user(ksig->ka.sa.sa_restorer, &frame->pretcode))
312 goto give_sigsegv; 297 return -EFAULT;
313 } 298 }
314 else { 299 else {
315 /* Set up the following code on the stack: 300 /* Set up the following code on the stack:
@@ -319,7 +304,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
319 if (__put_user((__sigrestore_t)frame->retcode, &frame->pretcode) || 304 if (__put_user((__sigrestore_t)frame->retcode, &frame->pretcode) ||
320 __put_user(0x8efc0000|__NR_rt_sigreturn, &frame->retcode[0]) || 305 __put_user(0x8efc0000|__NR_rt_sigreturn, &frame->retcode[0]) ||
321 __put_user(0xc0700000, &frame->retcode[1])) 306 __put_user(0xc0700000, &frame->retcode[1]))
322 goto give_sigsegv; 307 return -EFAULT;
323 308
324 flush_icache_range((unsigned long) frame->retcode, 309 flush_icache_range((unsigned long) frame->retcode,
325 (unsigned long) (frame->retcode + 2)); 310 (unsigned long) (frame->retcode + 2));
@@ -328,14 +313,14 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
328 /* Set up registers for signal handler */ 313 /* Set up registers for signal handler */
329 if (current->personality & FDPIC_FUNCPTRS) { 314 if (current->personality & FDPIC_FUNCPTRS) {
330 struct fdpic_func_descriptor __user *funcptr = 315 struct fdpic_func_descriptor __user *funcptr =
331 (struct fdpic_func_descriptor __user *) ka->sa.sa_handler; 316 (struct fdpic_func_descriptor __user *) ksig->ka.sa.sa_handler;
332 struct fdpic_func_descriptor desc; 317 struct fdpic_func_descriptor desc;
333 if (copy_from_user(&desc, funcptr, sizeof(desc))) 318 if (copy_from_user(&desc, funcptr, sizeof(desc)))
334 goto give_sigsegv; 319 return -EFAULT;
335 __frame->pc = desc.text; 320 __frame->pc = desc.text;
336 __frame->gr15 = desc.GOT; 321 __frame->gr15 = desc.GOT;
337 } else { 322 } else {
338 __frame->pc = (unsigned long) ka->sa.sa_handler; 323 __frame->pc = (unsigned long) ksig->ka.sa.sa_handler;
339 __frame->gr15 = 0; 324 __frame->gr15 = 0;
340 } 325 }
341 326
@@ -349,21 +334,15 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
349 sig, current->comm, current->pid, frame, __frame->pc, 334 sig, current->comm, current->pid, frame, __frame->pc,
350 frame->pretcode); 335 frame->pretcode);
351#endif 336#endif
352
353 return 0; 337 return 0;
354 338
355give_sigsegv:
356 force_sigsegv(sig, current);
357 return -EFAULT;
358
359} /* end setup_rt_frame() */ 339} /* end setup_rt_frame() */
360 340
361/*****************************************************************************/ 341/*****************************************************************************/
362/* 342/*
363 * OK, we're invoking a handler 343 * OK, we're invoking a handler
364 */ 344 */
365static void handle_signal(unsigned long sig, siginfo_t *info, 345static void handle_signal(struct ksignal *ksig)
366 struct k_sigaction *ka)
367{ 346{
368 sigset_t *oldset = sigmask_to_save(); 347 sigset_t *oldset = sigmask_to_save();
369 int ret; 348 int ret;
@@ -378,7 +357,7 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
378 break; 357 break;
379 358
380 case -ERESTARTSYS: 359 case -ERESTARTSYS:
381 if (!(ka->sa.sa_flags & SA_RESTART)) { 360 if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
382 __frame->gr8 = -EINTR; 361 __frame->gr8 = -EINTR;
383 break; 362 break;
384 } 363 }
@@ -392,16 +371,12 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
392 } 371 }
393 372
394 /* Set up the stack frame */ 373 /* Set up the stack frame */
395 if (ka->sa.sa_flags & SA_SIGINFO) 374 if (ksig->ka.sa.sa_flags & SA_SIGINFO)
396 ret = setup_rt_frame(sig, ka, info, oldset); 375 ret = setup_rt_frame(ksig, oldset);
397 else 376 else
398 ret = setup_frame(sig, ka, oldset); 377 ret = setup_frame(ksig, oldset);
399
400 if (ret)
401 return;
402 378
403 signal_delivered(sig, info, ka, __frame, 379 signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
404 test_thread_flag(TIF_SINGLESTEP));
405} /* end handle_signal() */ 380} /* end handle_signal() */
406 381
407/*****************************************************************************/ 382/*****************************************************************************/
@@ -412,13 +387,10 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
412 */ 387 */
413static void do_signal(void) 388static void do_signal(void)
414{ 389{
415 struct k_sigaction ka; 390 struct ksignal ksig;
416 siginfo_t info;
417 int signr;
418 391
419 signr = get_signal_to_deliver(&info, &ka, __frame, NULL); 392 if (get_signal(&ksig)) {
420 if (signr > 0) { 393 handle_signal(&ksig);
421 handle_signal(signr, &info, &ka);
422 return; 394 return;
423 } 395 }
424 396