Commit c79bd89282136a4516e842fa542d6abf902ddeac
Exists in
master
and in
7 other branches
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6: sparc: Prevent no-handler signal syscall restart recursion. sparc: Don't mask signal when we can't setup signal frame. sparc64: Fix race in signal instruction flushing. sparc64: Support RAW perf events.
Showing 4 changed files Side-by-side Diff
arch/sparc/kernel/perf_event.c
... | ... | @@ -1038,6 +1038,7 @@ |
1038 | 1038 | if (atomic_read(&nmi_active) < 0) |
1039 | 1039 | return -ENODEV; |
1040 | 1040 | |
1041 | + pmap = NULL; | |
1041 | 1042 | if (attr->type == PERF_TYPE_HARDWARE) { |
1042 | 1043 | if (attr->config >= sparc_pmu->max_events) |
1043 | 1044 | return -EINVAL; |
1044 | 1045 | |
... | ... | @@ -1046,9 +1047,18 @@ |
1046 | 1047 | pmap = sparc_map_cache_event(attr->config); |
1047 | 1048 | if (IS_ERR(pmap)) |
1048 | 1049 | return PTR_ERR(pmap); |
1049 | - } else | |
1050 | + } else if (attr->type != PERF_TYPE_RAW) | |
1050 | 1051 | return -EOPNOTSUPP; |
1051 | 1052 | |
1053 | + if (pmap) { | |
1054 | + hwc->event_base = perf_event_encode(pmap); | |
1055 | + } else { | |
1056 | + /* User gives us "(encoding << 16) | pic_mask" for | |
1057 | + * PERF_TYPE_RAW events. | |
1058 | + */ | |
1059 | + hwc->event_base = attr->config; | |
1060 | + } | |
1061 | + | |
1052 | 1062 | /* We save the enable bits in the config_base. */ |
1053 | 1063 | hwc->config_base = sparc_pmu->irq_bit; |
1054 | 1064 | if (!attr->exclude_user) |
... | ... | @@ -1057,8 +1067,6 @@ |
1057 | 1067 | hwc->config_base |= PCR_STRACE; |
1058 | 1068 | if (!attr->exclude_hv) |
1059 | 1069 | hwc->config_base |= sparc_pmu->hv_bit; |
1060 | - | |
1061 | - hwc->event_base = perf_event_encode(pmap); | |
1062 | 1070 | |
1063 | 1071 | n = 0; |
1064 | 1072 | if (event->group_leader != event) { |
arch/sparc/kernel/signal32.c
... | ... | @@ -453,9 +453,67 @@ |
453 | 453 | return err; |
454 | 454 | } |
455 | 455 | |
456 | -static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, | |
457 | - int signo, sigset_t *oldset) | |
456 | +/* The I-cache flush instruction only works in the primary ASI, which | |
457 | + * right now is the nucleus, aka. kernel space. | |
458 | + * | |
459 | + * Therefore we have to kick the instructions out using the kernel | |
460 | + * side linear mapping of the physical address backing the user | |
461 | + * instructions. | |
462 | + */ | |
463 | +static void flush_signal_insns(unsigned long address) | |
458 | 464 | { |
465 | + unsigned long pstate, paddr; | |
466 | + pte_t *ptep, pte; | |
467 | + pgd_t *pgdp; | |
468 | + pud_t *pudp; | |
469 | + pmd_t *pmdp; | |
470 | + | |
471 | + /* Commit all stores of the instructions we are about to flush. */ | |
472 | + wmb(); | |
473 | + | |
474 | + /* Disable cross-call reception. In this way even a very wide | |
475 | + * munmap() on another cpu can't tear down the page table | |
476 | + * hierarchy from underneath us, since that can't complete | |
477 | + * until the IPI tlb flush returns. | |
478 | + */ | |
479 | + | |
480 | + __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate)); | |
481 | + __asm__ __volatile__("wrpr %0, %1, %%pstate" | |
482 | + : : "r" (pstate), "i" (PSTATE_IE)); | |
483 | + | |
484 | + pgdp = pgd_offset(current->mm, address); | |
485 | + if (pgd_none(*pgdp)) | |
486 | + goto out_irqs_on; | |
487 | + pudp = pud_offset(pgdp, address); | |
488 | + if (pud_none(*pudp)) | |
489 | + goto out_irqs_on; | |
490 | + pmdp = pmd_offset(pudp, address); | |
491 | + if (pmd_none(*pmdp)) | |
492 | + goto out_irqs_on; | |
493 | + | |
494 | + ptep = pte_offset_map(pmdp, address); | |
495 | + pte = *ptep; | |
496 | + if (!pte_present(pte)) | |
497 | + goto out_unmap; | |
498 | + | |
499 | + paddr = (unsigned long) page_address(pte_page(pte)); | |
500 | + | |
501 | + __asm__ __volatile__("flush %0 + %1" | |
502 | + : /* no outputs */ | |
503 | + : "r" (paddr), | |
504 | + "r" (address & (PAGE_SIZE - 1)) | |
505 | + : "memory"); | |
506 | + | |
507 | +out_unmap: | |
508 | + pte_unmap(ptep); | |
509 | +out_irqs_on: | |
510 | + __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate)); | |
511 | + | |
512 | +} | |
513 | + | |
514 | +static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, | |
515 | + int signo, sigset_t *oldset) | |
516 | +{ | |
459 | 517 | struct signal_frame32 __user *sf; |
460 | 518 | int sigframe_size; |
461 | 519 | u32 psr; |
462 | 520 | |
... | ... | @@ -547,13 +605,7 @@ |
547 | 605 | if (ka->ka_restorer) { |
548 | 606 | regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; |
549 | 607 | } else { |
550 | - /* Flush instruction space. */ | |
551 | 608 | unsigned long address = ((unsigned long)&(sf->insns[0])); |
552 | - pgd_t *pgdp = pgd_offset(current->mm, address); | |
553 | - pud_t *pudp = pud_offset(pgdp, address); | |
554 | - pmd_t *pmdp = pmd_offset(pudp, address); | |
555 | - pte_t *ptep; | |
556 | - pte_t pte; | |
557 | 609 | |
558 | 610 | regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2); |
559 | 611 | |
560 | 612 | |
561 | 613 | |
562 | 614 | |
563 | 615 | |
... | ... | @@ -562,34 +614,22 @@ |
562 | 614 | if (err) |
563 | 615 | goto sigsegv; |
564 | 616 | |
565 | - preempt_disable(); | |
566 | - ptep = pte_offset_map(pmdp, address); | |
567 | - pte = *ptep; | |
568 | - if (pte_present(pte)) { | |
569 | - unsigned long page = (unsigned long) | |
570 | - page_address(pte_page(pte)); | |
571 | - | |
572 | - wmb(); | |
573 | - __asm__ __volatile__("flush %0 + %1" | |
574 | - : /* no outputs */ | |
575 | - : "r" (page), | |
576 | - "r" (address & (PAGE_SIZE - 1)) | |
577 | - : "memory"); | |
578 | - } | |
579 | - pte_unmap(ptep); | |
580 | - preempt_enable(); | |
617 | + flush_signal_insns(address); | |
581 | 618 | } |
582 | - return; | |
619 | + return 0; | |
583 | 620 | |
584 | 621 | sigill: |
585 | 622 | do_exit(SIGILL); |
623 | + return -EINVAL; | |
624 | + | |
586 | 625 | sigsegv: |
587 | 626 | force_sigsegv(signo, current); |
627 | + return -EFAULT; | |
588 | 628 | } |
589 | 629 | |
590 | -static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, | |
591 | - unsigned long signr, sigset_t *oldset, | |
592 | - siginfo_t *info) | |
630 | +static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, | |
631 | + unsigned long signr, sigset_t *oldset, | |
632 | + siginfo_t *info) | |
593 | 633 | { |
594 | 634 | struct rt_signal_frame32 __user *sf; |
595 | 635 | int sigframe_size; |
596 | 636 | |
... | ... | @@ -687,12 +727,7 @@ |
687 | 727 | if (ka->ka_restorer) |
688 | 728 | regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; |
689 | 729 | else { |
690 | - /* Flush instruction space. */ | |
691 | 730 | unsigned long address = ((unsigned long)&(sf->insns[0])); |
692 | - pgd_t *pgdp = pgd_offset(current->mm, address); | |
693 | - pud_t *pudp = pud_offset(pgdp, address); | |
694 | - pmd_t *pmdp = pmd_offset(pudp, address); | |
695 | - pte_t *ptep; | |
696 | 731 | |
697 | 732 | regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2); |
698 | 733 | |
699 | 734 | |
700 | 735 | |
701 | 736 | |
702 | 737 | |
703 | 738 | |
704 | 739 | |
705 | 740 | |
706 | 741 | |
707 | 742 | |
... | ... | @@ -704,45 +739,43 @@ |
704 | 739 | if (err) |
705 | 740 | goto sigsegv; |
706 | 741 | |
707 | - preempt_disable(); | |
708 | - ptep = pte_offset_map(pmdp, address); | |
709 | - if (pte_present(*ptep)) { | |
710 | - unsigned long page = (unsigned long) | |
711 | - page_address(pte_page(*ptep)); | |
712 | - | |
713 | - wmb(); | |
714 | - __asm__ __volatile__("flush %0 + %1" | |
715 | - : /* no outputs */ | |
716 | - : "r" (page), | |
717 | - "r" (address & (PAGE_SIZE - 1)) | |
718 | - : "memory"); | |
719 | - } | |
720 | - pte_unmap(ptep); | |
721 | - preempt_enable(); | |
742 | + flush_signal_insns(address); | |
722 | 743 | } |
723 | - return; | |
744 | + return 0; | |
724 | 745 | |
725 | 746 | sigill: |
726 | 747 | do_exit(SIGILL); |
748 | + return -EINVAL; | |
749 | + | |
727 | 750 | sigsegv: |
728 | 751 | force_sigsegv(signr, current); |
752 | + return -EFAULT; | |
729 | 753 | } |
730 | 754 | |
731 | -static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka, | |
732 | - siginfo_t *info, | |
733 | - sigset_t *oldset, struct pt_regs *regs) | |
755 | +static inline int handle_signal32(unsigned long signr, struct k_sigaction *ka, | |
756 | + siginfo_t *info, | |
757 | + sigset_t *oldset, struct pt_regs *regs) | |
734 | 758 | { |
759 | + int err; | |
760 | + | |
735 | 761 | if (ka->sa.sa_flags & SA_SIGINFO) |
736 | - setup_rt_frame32(ka, regs, signr, oldset, info); | |
762 | + err = setup_rt_frame32(ka, regs, signr, oldset, info); | |
737 | 763 | else |
738 | - setup_frame32(ka, regs, signr, oldset); | |
764 | + err = setup_frame32(ka, regs, signr, oldset); | |
739 | 765 | |
766 | + if (err) | |
767 | + return err; | |
768 | + | |
740 | 769 | spin_lock_irq(¤t->sighand->siglock); |
741 | 770 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
742 | 771 | if (!(ka->sa.sa_flags & SA_NOMASK)) |
743 | 772 | sigaddset(¤t->blocked,signr); |
744 | 773 | recalc_sigpending(); |
745 | 774 | spin_unlock_irq(¤t->sighand->siglock); |
775 | + | |
776 | + tracehook_signal_handler(signr, info, ka, regs, 0); | |
777 | + | |
778 | + return 0; | |
746 | 779 | } |
747 | 780 | |
748 | 781 | static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs, |
... | ... | @@ -789,16 +822,14 @@ |
789 | 822 | if (signr > 0) { |
790 | 823 | if (restart_syscall) |
791 | 824 | syscall_restart32(orig_i0, regs, &ka.sa); |
792 | - handle_signal32(signr, &ka, &info, oldset, regs); | |
793 | - | |
794 | - /* A signal was successfully delivered; the saved | |
795 | - * sigmask will have been stored in the signal frame, | |
796 | - * and will be restored by sigreturn, so we can simply | |
797 | - * clear the TS_RESTORE_SIGMASK flag. | |
798 | - */ | |
799 | - current_thread_info()->status &= ~TS_RESTORE_SIGMASK; | |
800 | - | |
801 | - tracehook_signal_handler(signr, &info, &ka, regs, 0); | |
825 | + if (handle_signal32(signr, &ka, &info, oldset, regs) == 0) { | |
826 | + /* A signal was successfully delivered; the saved | |
827 | + * sigmask will have been stored in the signal frame, | |
828 | + * and will be restored by sigreturn, so we can simply | |
829 | + * clear the TS_RESTORE_SIGMASK flag. | |
830 | + */ | |
831 | + current_thread_info()->status &= ~TS_RESTORE_SIGMASK; | |
832 | + } | |
802 | 833 | return; |
803 | 834 | } |
804 | 835 | if (restart_syscall && |
805 | 836 | |
... | ... | @@ -809,12 +840,14 @@ |
809 | 840 | regs->u_regs[UREG_I0] = orig_i0; |
810 | 841 | regs->tpc -= 4; |
811 | 842 | regs->tnpc -= 4; |
843 | + pt_regs_clear_syscall(regs); | |
812 | 844 | } |
813 | 845 | if (restart_syscall && |
814 | 846 | regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { |
815 | 847 | regs->u_regs[UREG_G1] = __NR_restart_syscall; |
816 | 848 | regs->tpc -= 4; |
817 | 849 | regs->tnpc -= 4; |
850 | + pt_regs_clear_syscall(regs); | |
818 | 851 | } |
819 | 852 | |
820 | 853 | /* If there's no signal to deliver, we just put the saved sigmask |
arch/sparc/kernel/signal_32.c
... | ... | @@ -315,8 +315,8 @@ |
315 | 315 | return err; |
316 | 316 | } |
317 | 317 | |
318 | -static void setup_frame(struct k_sigaction *ka, struct pt_regs *regs, | |
319 | - int signo, sigset_t *oldset) | |
318 | +static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs, | |
319 | + int signo, sigset_t *oldset) | |
320 | 320 | { |
321 | 321 | struct signal_frame __user *sf; |
322 | 322 | int sigframe_size, err; |
323 | 323 | |
324 | 324 | |
325 | 325 | |
... | ... | @@ -384,16 +384,19 @@ |
384 | 384 | /* Flush instruction space. */ |
385 | 385 | flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0])); |
386 | 386 | } |
387 | - return; | |
387 | + return 0; | |
388 | 388 | |
389 | 389 | sigill_and_return: |
390 | 390 | do_exit(SIGILL); |
391 | + return -EINVAL; | |
392 | + | |
391 | 393 | sigsegv: |
392 | 394 | force_sigsegv(signo, current); |
395 | + return -EFAULT; | |
393 | 396 | } |
394 | 397 | |
395 | -static void setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, | |
396 | - int signo, sigset_t *oldset, siginfo_t *info) | |
398 | +static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, | |
399 | + int signo, sigset_t *oldset, siginfo_t *info) | |
397 | 400 | { |
398 | 401 | struct rt_signal_frame __user *sf; |
399 | 402 | int sigframe_size; |
400 | 403 | |
401 | 404 | |
402 | 405 | |
403 | 406 | |
404 | 407 | |
405 | 408 | |
406 | 409 | |
407 | 410 | |
... | ... | @@ -466,29 +469,41 @@ |
466 | 469 | /* Flush instruction space. */ |
467 | 470 | flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0])); |
468 | 471 | } |
469 | - return; | |
472 | + return 0; | |
470 | 473 | |
471 | 474 | sigill: |
472 | 475 | do_exit(SIGILL); |
476 | + return -EINVAL; | |
477 | + | |
473 | 478 | sigsegv: |
474 | 479 | force_sigsegv(signo, current); |
480 | + return -EFAULT; | |
475 | 481 | } |
476 | 482 | |
477 | -static inline void | |
483 | +static inline int | |
478 | 484 | handle_signal(unsigned long signr, struct k_sigaction *ka, |
479 | 485 | siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) |
480 | 486 | { |
487 | + int err; | |
488 | + | |
481 | 489 | if (ka->sa.sa_flags & SA_SIGINFO) |
482 | - setup_rt_frame(ka, regs, signr, oldset, info); | |
490 | + err = setup_rt_frame(ka, regs, signr, oldset, info); | |
483 | 491 | else |
484 | - setup_frame(ka, regs, signr, oldset); | |
492 | + err = setup_frame(ka, regs, signr, oldset); | |
485 | 493 | |
494 | + if (err) | |
495 | + return err; | |
496 | + | |
486 | 497 | spin_lock_irq(¤t->sighand->siglock); |
487 | 498 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
488 | 499 | if (!(ka->sa.sa_flags & SA_NOMASK)) |
489 | 500 | sigaddset(¤t->blocked, signr); |
490 | 501 | recalc_sigpending(); |
491 | 502 | spin_unlock_irq(¤t->sighand->siglock); |
503 | + | |
504 | + tracehook_signal_handler(signr, info, ka, regs, 0); | |
505 | + | |
506 | + return 0; | |
492 | 507 | } |
493 | 508 | |
494 | 509 | static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, |
... | ... | @@ -546,17 +561,15 @@ |
546 | 561 | if (signr > 0) { |
547 | 562 | if (restart_syscall) |
548 | 563 | syscall_restart(orig_i0, regs, &ka.sa); |
549 | - handle_signal(signr, &ka, &info, oldset, regs); | |
550 | - | |
551 | - /* a signal was successfully delivered; the saved | |
552 | - * sigmask will have been stored in the signal frame, | |
553 | - * and will be restored by sigreturn, so we can simply | |
554 | - * clear the TIF_RESTORE_SIGMASK flag. | |
555 | - */ | |
556 | - if (test_thread_flag(TIF_RESTORE_SIGMASK)) | |
557 | - clear_thread_flag(TIF_RESTORE_SIGMASK); | |
558 | - | |
559 | - tracehook_signal_handler(signr, &info, &ka, regs, 0); | |
564 | + if (handle_signal(signr, &ka, &info, oldset, regs) == 0) { | |
565 | + /* a signal was successfully delivered; the saved | |
566 | + * sigmask will have been stored in the signal frame, | |
567 | + * and will be restored by sigreturn, so we can simply | |
568 | + * clear the TIF_RESTORE_SIGMASK flag. | |
569 | + */ | |
570 | + if (test_thread_flag(TIF_RESTORE_SIGMASK)) | |
571 | + clear_thread_flag(TIF_RESTORE_SIGMASK); | |
572 | + } | |
560 | 573 | return; |
561 | 574 | } |
562 | 575 | if (restart_syscall && |
563 | 576 | |
... | ... | @@ -567,12 +580,14 @@ |
567 | 580 | regs->u_regs[UREG_I0] = orig_i0; |
568 | 581 | regs->pc -= 4; |
569 | 582 | regs->npc -= 4; |
583 | + pt_regs_clear_syscall(regs); | |
570 | 584 | } |
571 | 585 | if (restart_syscall && |
572 | 586 | regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { |
573 | 587 | regs->u_regs[UREG_G1] = __NR_restart_syscall; |
574 | 588 | regs->pc -= 4; |
575 | 589 | regs->npc -= 4; |
590 | + pt_regs_clear_syscall(regs); | |
576 | 591 | } |
577 | 592 | |
578 | 593 | /* if there's no signal to deliver, we just put the saved sigmask |
arch/sparc/kernel/signal_64.c
... | ... | @@ -409,7 +409,7 @@ |
409 | 409 | return (void __user *) sp; |
410 | 410 | } |
411 | 411 | |
412 | -static inline void | |
412 | +static inline int | |
413 | 413 | setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, |
414 | 414 | int signo, sigset_t *oldset, siginfo_t *info) |
415 | 415 | { |
416 | 416 | |
417 | 417 | |
418 | 418 | |
419 | 419 | |
420 | 420 | |
... | ... | @@ -483,26 +483,37 @@ |
483 | 483 | } |
484 | 484 | /* 4. return to kernel instructions */ |
485 | 485 | regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; |
486 | - return; | |
486 | + return 0; | |
487 | 487 | |
488 | 488 | sigill: |
489 | 489 | do_exit(SIGILL); |
490 | + return -EINVAL; | |
491 | + | |
490 | 492 | sigsegv: |
491 | 493 | force_sigsegv(signo, current); |
494 | + return -EFAULT; | |
492 | 495 | } |
493 | 496 | |
494 | -static inline void handle_signal(unsigned long signr, struct k_sigaction *ka, | |
495 | - siginfo_t *info, | |
496 | - sigset_t *oldset, struct pt_regs *regs) | |
497 | +static inline int handle_signal(unsigned long signr, struct k_sigaction *ka, | |
498 | + siginfo_t *info, | |
499 | + sigset_t *oldset, struct pt_regs *regs) | |
497 | 500 | { |
498 | - setup_rt_frame(ka, regs, signr, oldset, | |
499 | - (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL); | |
501 | + int err; | |
502 | + | |
503 | + err = setup_rt_frame(ka, regs, signr, oldset, | |
504 | + (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL); | |
505 | + if (err) | |
506 | + return err; | |
500 | 507 | spin_lock_irq(¤t->sighand->siglock); |
501 | 508 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
502 | 509 | if (!(ka->sa.sa_flags & SA_NOMASK)) |
503 | 510 | sigaddset(¤t->blocked,signr); |
504 | 511 | recalc_sigpending(); |
505 | 512 | spin_unlock_irq(¤t->sighand->siglock); |
513 | + | |
514 | + tracehook_signal_handler(signr, info, ka, regs, 0); | |
515 | + | |
516 | + return 0; | |
506 | 517 | } |
507 | 518 | |
508 | 519 | static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, |
... | ... | @@ -571,16 +582,14 @@ |
571 | 582 | if (signr > 0) { |
572 | 583 | if (restart_syscall) |
573 | 584 | syscall_restart(orig_i0, regs, &ka.sa); |
574 | - handle_signal(signr, &ka, &info, oldset, regs); | |
575 | - | |
576 | - /* A signal was successfully delivered; the saved | |
577 | - * sigmask will have been stored in the signal frame, | |
578 | - * and will be restored by sigreturn, so we can simply | |
579 | - * clear the TS_RESTORE_SIGMASK flag. | |
580 | - */ | |
581 | - current_thread_info()->status &= ~TS_RESTORE_SIGMASK; | |
582 | - | |
583 | - tracehook_signal_handler(signr, &info, &ka, regs, 0); | |
585 | + if (handle_signal(signr, &ka, &info, oldset, regs) == 0) { | |
586 | + /* A signal was successfully delivered; the saved | |
587 | + * sigmask will have been stored in the signal frame, | |
588 | + * and will be restored by sigreturn, so we can simply | |
589 | + * clear the TS_RESTORE_SIGMASK flag. | |
590 | + */ | |
591 | + current_thread_info()->status &= ~TS_RESTORE_SIGMASK; | |
592 | + } | |
584 | 593 | return; |
585 | 594 | } |
586 | 595 | if (restart_syscall && |
587 | 596 | |
... | ... | @@ -591,12 +600,14 @@ |
591 | 600 | regs->u_regs[UREG_I0] = orig_i0; |
592 | 601 | regs->tpc -= 4; |
593 | 602 | regs->tnpc -= 4; |
603 | + pt_regs_clear_syscall(regs); | |
594 | 604 | } |
595 | 605 | if (restart_syscall && |
596 | 606 | regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { |
597 | 607 | regs->u_regs[UREG_G1] = __NR_restart_syscall; |
598 | 608 | regs->tpc -= 4; |
599 | 609 | regs->tnpc -= 4; |
610 | + pt_regs_clear_syscall(regs); | |
600 | 611 | } |
601 | 612 | |
602 | 613 | /* If there's no signal to deliver, we just put the saved sigmask |