summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/alpha/kernel/entry.S10
-rw-r--r--arch/alpha/kernel/signal.c27
2 files changed, 20 insertions, 17 deletions
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S
index 802108b15be..0c30ccea929 100644
--- a/arch/alpha/kernel/entry.S
+++ b/arch/alpha/kernel/entry.S
@@ -390,15 +390,9 @@ $work_notifysig:
bsr $1, do_switch_stack
mov $sp, $17
mov $5, $18
- mov $19, $9 /* save old syscall number */
- mov $20, $10 /* save old a3 */
- and $5, _TIF_SIGPENDING, $2
- cmovne $2, 0, $9 /* we don't want double syscall restarts */
- jsr $26, do_notify_resume
- mov $9, $19
- mov $10, $20
+ jsr $26, do_work_pending
bsr $1, undo_switch_stack
- br ret_to_user
+ br restore_all
.end work_pending
/*
diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c
index a8c97d42ec8..235a8677eca 100644
--- a/arch/alpha/kernel/signal.c
+++ b/arch/alpha/kernel/signal.c
@@ -568,15 +568,24 @@ do_signal(struct pt_regs * regs, struct switch_stack * sw,
}
void
-do_notify_resume(struct pt_regs *regs, struct switch_stack *sw,
- unsigned long thread_info_flags,
+do_work_pending(struct pt_regs *regs, struct switch_stack *sw,
+ unsigned long thread_flags,
unsigned long r0, unsigned long r19)
{
- if (thread_info_flags & _TIF_SIGPENDING)
- do_signal(regs, sw, r0, r19);
-
- if (thread_info_flags & _TIF_NOTIFY_RESUME) {
- clear_thread_flag(TIF_NOTIFY_RESUME);
- tracehook_notify_resume(regs);
- }
+ do {
+ if (thread_flags & _TIF_NEED_RESCHED) {
+ schedule();
+ } else {
+ local_irq_enable();
+ if (thread_flags & _TIF_SIGPENDING) {
+ do_signal(regs, sw, r0, r19);
+ r0 = 0;
+ } else {
+ clear_thread_flag(TIF_NOTIFY_RESUME);
+ tracehook_notify_resume(regs);
+ }
+ }
+ local_irq_disable();
+ thread_flags = current_thread_info()->flags;
+ } while (thread_flags & _TIF_WORK_MASK);
}