diff options
Diffstat (limited to 'arch/tile/kernel/intvec_64.S')
-rw-r--r-- | arch/tile/kernel/intvec_64.S | 38 |
1 files changed, 28 insertions, 10 deletions
diff --git a/arch/tile/kernel/intvec_64.S b/arch/tile/kernel/intvec_64.S index 49d9d6621682..30ae76e50c44 100644 --- a/arch/tile/kernel/intvec_64.S +++ b/arch/tile/kernel/intvec_64.S | |||
@@ -647,6 +647,20 @@ STD_ENTRY(interrupt_return) | |||
647 | FEEDBACK_REENTER(interrupt_return) | 647 | FEEDBACK_REENTER(interrupt_return) |
648 | 648 | ||
649 | /* | 649 | /* |
650 | * Use r33 to hold whether we have already loaded the callee-saves | ||
651 | * into ptregs. We don't want to do it twice in this loop, since | ||
652 | * then we'd clobber whatever changes are made by ptrace, etc. | ||
653 | */ | ||
654 | { | ||
655 | movei r33, 0 | ||
656 | move r32, sp | ||
657 | } | ||
658 | |||
659 | /* Get base of stack in r32. */ | ||
660 | EXTRACT_THREAD_INFO(r32) | ||
661 | |||
662 | .Lretry_work_pending: | ||
663 | /* | ||
650 | * Disable interrupts so as to make sure we don't | 664 | * Disable interrupts so as to make sure we don't |
651 | * miss an interrupt that sets any of the thread flags (like | 665 | * miss an interrupt that sets any of the thread flags (like |
652 | * need_resched or sigpending) between sampling and the iret. | 666 | * need_resched or sigpending) between sampling and the iret. |
@@ -656,9 +670,6 @@ STD_ENTRY(interrupt_return) | |||
656 | IRQ_DISABLE(r20, r21) | 670 | IRQ_DISABLE(r20, r21) |
657 | TRACE_IRQS_OFF /* Note: clobbers registers r0-r29 */ | 671 | TRACE_IRQS_OFF /* Note: clobbers registers r0-r29 */ |
658 | 672 | ||
659 | /* Get base of stack in r32; note r30/31 are used as arguments here. */ | ||
660 | GET_THREAD_INFO(r32) | ||
661 | |||
662 | 673 | ||
663 | /* Check to see if there is any work to do before returning to user. */ | 674 | /* Check to see if there is any work to do before returning to user. */ |
664 | { | 675 | { |
@@ -674,16 +685,18 @@ STD_ENTRY(interrupt_return) | |||
674 | 685 | ||
675 | /* | 686 | /* |
676 | * Make sure we have all the registers saved for signal | 687 | * Make sure we have all the registers saved for signal |
677 | * handling or single-step. Call out to C code to figure out | 688 | * handling or notify-resume. Call out to C code to figure out |
678 | * exactly what we need to do for each flag bit, then if | 689 | * exactly what we need to do for each flag bit, then if |
679 | * necessary, reload the flags and recheck. | 690 | * necessary, reload the flags and recheck. |
680 | */ | 691 | */ |
681 | push_extra_callee_saves r0 | ||
682 | { | 692 | { |
683 | PTREGS_PTR(r0, PTREGS_OFFSET_BASE) | 693 | PTREGS_PTR(r0, PTREGS_OFFSET_BASE) |
684 | jal do_work_pending | 694 | bnez r33, 1f |
685 | } | 695 | } |
686 | bnez r0, .Lresume_userspace | 696 | push_extra_callee_saves r0 |
697 | movei r33, 1 | ||
698 | 1: jal do_work_pending | ||
699 | bnez r0, .Lretry_work_pending | ||
687 | 700 | ||
688 | /* | 701 | /* |
689 | * In the NMI case we | 702 | * In the NMI case we |
@@ -968,11 +981,16 @@ handle_syscall: | |||
968 | shl16insli r20, r20, hw0(irq_stat + IRQ_CPUSTAT_SYSCALL_COUNT_OFFSET) | 981 | shl16insli r20, r20, hw0(irq_stat + IRQ_CPUSTAT_SYSCALL_COUNT_OFFSET) |
969 | add r20, r20, tp | 982 | add r20, r20, tp |
970 | ld4s r21, r20 | 983 | ld4s r21, r20 |
971 | addi r21, r21, 1 | 984 | { |
972 | st4 r20, r21 | 985 | addi r21, r21, 1 |
986 | move r31, sp | ||
987 | } | ||
988 | { | ||
989 | st4 r20, r21 | ||
990 | EXTRACT_THREAD_INFO(r31) | ||
991 | } | ||
973 | 992 | ||
974 | /* Trace syscalls, if requested. */ | 993 | /* Trace syscalls, if requested. */ |
975 | GET_THREAD_INFO(r31) | ||
976 | addi r31, r31, THREAD_INFO_FLAGS_OFFSET | 994 | addi r31, r31, THREAD_INFO_FLAGS_OFFSET |
977 | ld r30, r31 | 995 | ld r30, r31 |
978 | andi r30, r30, _TIF_SYSCALL_TRACE | 996 | andi r30, r30, _TIF_SYSCALL_TRACE |