.. | .. |
---|
185 | 185 | COPY(sar); |
---|
186 | 186 | #undef COPY |
---|
187 | 187 | |
---|
188 | | - /* All registers were flushed to stack. Start with a prestine frame. */ |
---|
| 188 | + /* All registers were flushed to stack. Start with a pristine frame. */ |
---|
189 | 189 | |
---|
190 | 190 | regs->wmask = 1; |
---|
191 | 191 | regs->windowbase = 0; |
---|
192 | 192 | regs->windowstart = 1; |
---|
193 | 193 | |
---|
194 | | - regs->syscall = -1; /* disable syscall checks */ |
---|
| 194 | + regs->syscall = NO_SYSCALL; /* disable syscall checks */ |
---|
195 | 195 | |
---|
196 | 196 | /* For PS, restore only PS.CALLINC. |
---|
197 | 197 | * Assume that all other bits are either the same as for the signal |
---|
.. | .. |
---|
236 | 236 | * Do a signal return; undo the signal stack. |
---|
237 | 237 | */ |
---|
238 | 238 | |
---|
239 | | -asmlinkage long xtensa_rt_sigreturn(long a0, long a1, long a2, long a3, |
---|
240 | | - long a4, long a5, struct pt_regs *regs) |
---|
| 239 | +asmlinkage long xtensa_rt_sigreturn(void) |
---|
241 | 240 | { |
---|
| 241 | + struct pt_regs *regs = current_pt_regs(); |
---|
242 | 242 | struct rt_sigframe __user *frame; |
---|
243 | 243 | sigset_t set; |
---|
244 | 244 | int ret; |
---|
.. | .. |
---|
251 | 251 | |
---|
252 | 252 | frame = (struct rt_sigframe __user *) regs->areg[1]; |
---|
253 | 253 | |
---|
254 | | - if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) |
---|
| 254 | + if (!access_ok(frame, sizeof(*frame))) |
---|
255 | 255 | goto badframe; |
---|
256 | 256 | |
---|
257 | 257 | if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) |
---|
.. | .. |
---|
270 | 270 | return ret; |
---|
271 | 271 | |
---|
272 | 272 | badframe: |
---|
273 | | - force_sig(SIGSEGV, current); |
---|
| 273 | + force_sig(SIGSEGV); |
---|
274 | 274 | return 0; |
---|
275 | 275 | } |
---|
276 | 276 | |
---|
.. | .. |
---|
335 | 335 | { |
---|
336 | 336 | struct rt_sigframe *frame; |
---|
337 | 337 | int err = 0, sig = ksig->sig; |
---|
338 | | - unsigned long sp, ra, tp; |
---|
| 338 | + unsigned long sp, ra, tp, ps; |
---|
| 339 | + unsigned int base; |
---|
339 | 340 | |
---|
340 | 341 | sp = regs->areg[1]; |
---|
341 | 342 | |
---|
.. | .. |
---|
348 | 349 | if (regs->depc > 64) |
---|
349 | 350 | panic ("Double exception sys_sigreturn\n"); |
---|
350 | 351 | |
---|
351 | | - if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) { |
---|
| 352 | + if (!access_ok(frame, sizeof(*frame))) { |
---|
352 | 353 | return -EFAULT; |
---|
353 | 354 | } |
---|
354 | 355 | |
---|
.. | .. |
---|
385 | 386 | |
---|
386 | 387 | /* Set up registers for signal handler; preserve the threadptr */ |
---|
387 | 388 | tp = regs->threadptr; |
---|
| 389 | + ps = regs->ps; |
---|
388 | 390 | start_thread(regs, (unsigned long) ksig->ka.sa.sa_handler, |
---|
389 | 391 | (unsigned long) frame); |
---|
390 | 392 | |
---|
391 | | - /* Set up a stack frame for a call4 |
---|
392 | | - * Note: PS.CALLINC is set to one by start_thread |
---|
393 | | - */ |
---|
394 | | - regs->areg[4] = (((unsigned long) ra) & 0x3fffffff) | 0x40000000; |
---|
395 | | - regs->areg[6] = (unsigned long) sig; |
---|
396 | | - regs->areg[7] = (unsigned long) &frame->info; |
---|
397 | | - regs->areg[8] = (unsigned long) &frame->uc; |
---|
| 393 | + /* Set up a stack frame for a call4 if userspace uses windowed ABI */ |
---|
| 394 | + if (ps & PS_WOE_MASK) { |
---|
| 395 | + base = 4; |
---|
| 396 | + regs->areg[base] = |
---|
| 397 | + (((unsigned long) ra) & 0x3fffffff) | 0x40000000; |
---|
| 398 | + ps = (ps & ~(PS_CALLINC_MASK | PS_OWB_MASK)) | |
---|
| 399 | + (1 << PS_CALLINC_SHIFT); |
---|
| 400 | + } else { |
---|
| 401 | + base = 0; |
---|
| 402 | + regs->areg[base] = (unsigned long) ra; |
---|
| 403 | + } |
---|
| 404 | + regs->areg[base + 2] = (unsigned long) sig; |
---|
| 405 | + regs->areg[base + 3] = (unsigned long) &frame->info; |
---|
| 406 | + regs->areg[base + 4] = (unsigned long) &frame->uc; |
---|
398 | 407 | regs->threadptr = tp; |
---|
| 408 | + regs->ps = ps; |
---|
399 | 409 | |
---|
400 | 410 | pr_debug("SIG rt deliver (%s:%d): signal=%d sp=%p pc=%08lx\n", |
---|
401 | 411 | current->comm, current->pid, sig, frame, regs->pc); |
---|
.. | .. |
---|
423 | 433 | |
---|
424 | 434 | /* Are we from a system call? */ |
---|
425 | 435 | |
---|
426 | | - if ((signed)regs->syscall >= 0) { |
---|
| 436 | + if (regs->syscall != NO_SYSCALL) { |
---|
427 | 437 | |
---|
428 | 438 | /* If so, check system call restarting.. */ |
---|
429 | 439 | |
---|
.. | .. |
---|
438 | 448 | regs->areg[2] = -EINTR; |
---|
439 | 449 | break; |
---|
440 | 450 | } |
---|
441 | | - /* fallthrough */ |
---|
| 451 | + fallthrough; |
---|
442 | 452 | case -ERESTARTNOINTR: |
---|
443 | 453 | regs->areg[2] = regs->syscall; |
---|
444 | 454 | regs->pc -= 3; |
---|
.. | .. |
---|
455 | 465 | /* Set up the stack frame */ |
---|
456 | 466 | ret = setup_frame(&ksig, sigmask_to_save(), regs); |
---|
457 | 467 | signal_setup_done(ret, &ksig, 0); |
---|
458 | | - if (current->ptrace & PT_SINGLESTEP) |
---|
| 468 | + if (test_thread_flag(TIF_SINGLESTEP)) |
---|
459 | 469 | task_pt_regs(current)->icountlevel = 1; |
---|
460 | 470 | |
---|
461 | 471 | return; |
---|
462 | 472 | } |
---|
463 | 473 | |
---|
464 | 474 | /* Did we come from a system call? */ |
---|
465 | | - if ((signed) regs->syscall >= 0) { |
---|
| 475 | + if (regs->syscall != NO_SYSCALL) { |
---|
466 | 476 | /* Restart the system call - no handlers present */ |
---|
467 | 477 | switch (regs->areg[2]) { |
---|
468 | 478 | case -ERESTARTNOHAND: |
---|
.. | .. |
---|
481 | 491 | /* If there's no signal to deliver, we just restore the saved mask. */ |
---|
482 | 492 | restore_saved_sigmask(); |
---|
483 | 493 | |
---|
484 | | - if (current->ptrace & PT_SINGLESTEP) |
---|
| 494 | + if (test_thread_flag(TIF_SINGLESTEP)) |
---|
485 | 495 | task_pt_regs(current)->icountlevel = 1; |
---|
486 | 496 | return; |
---|
487 | 497 | } |
---|
488 | 498 | |
---|
489 | 499 | void do_notify_resume(struct pt_regs *regs) |
---|
490 | 500 | { |
---|
491 | | - if (test_thread_flag(TIF_SIGPENDING)) |
---|
| 501 | + if (test_thread_flag(TIF_SIGPENDING) || |
---|
| 502 | + test_thread_flag(TIF_NOTIFY_SIGNAL)) |
---|
492 | 503 | do_signal(regs); |
---|
493 | 504 | |
---|
494 | | - if (test_and_clear_thread_flag(TIF_NOTIFY_RESUME)) |
---|
| 505 | + if (test_thread_flag(TIF_NOTIFY_RESUME)) |
---|
495 | 506 | tracehook_notify_resume(regs); |
---|
496 | 507 | } |
---|