|
|
@@ -402,15 +402,31 @@ static void do_signal(struct pt_regs *regs)
|
|
|
asmlinkage void do_notify_resume(struct pt_regs *regs,
|
|
|
unsigned int thread_flags)
|
|
|
{
|
|
|
- if (thread_flags & _TIF_SIGPENDING)
|
|
|
- do_signal(regs);
|
|
|
-
|
|
|
- if (thread_flags & _TIF_NOTIFY_RESUME) {
|
|
|
- clear_thread_flag(TIF_NOTIFY_RESUME);
|
|
|
- tracehook_notify_resume(regs);
|
|
|
- }
|
|
|
-
|
|
|
- if (thread_flags & _TIF_FOREIGN_FPSTATE)
|
|
|
- fpsimd_restore_current_state();
|
|
|
+ /*
|
|
|
+ * The assembly code enters us with IRQs off, but it hasn't
|
|
|
+ * informed the tracing code of that for efficiency reasons.
|
|
|
+ * Update the trace code with the current status.
|
|
|
+ */
|
|
|
+ trace_hardirqs_off();
|
|
|
+ do {
|
|
|
+ if (thread_flags & _TIF_NEED_RESCHED) {
|
|
|
+ schedule();
|
|
|
+ } else {
|
|
|
+ local_irq_enable();
|
|
|
+
|
|
|
+ if (thread_flags & _TIF_SIGPENDING)
|
|
|
+ do_signal(regs);
|
|
|
+
|
|
|
+ if (thread_flags & _TIF_NOTIFY_RESUME) {
|
|
|
+ clear_thread_flag(TIF_NOTIFY_RESUME);
|
|
|
+ tracehook_notify_resume(regs);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (thread_flags & _TIF_FOREIGN_FPSTATE)
|
|
|
+ fpsimd_restore_current_state();
|
|
|
+ }
|
|
|
|
|
|
+ local_irq_disable();
|
|
|
+ thread_flags = READ_ONCE(current_thread_info()->flags);
|
|
|
+ } while (thread_flags & _TIF_WORK_MASK);
|
|
|
}
|