| .. | .. |
|---|
| 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 | } |
|---|