hc
2024-11-01 2f529f9b558ca1c1bd74be7437a84e4711743404
kernel/arch/arm/kernel/signal.c
....@@ -8,6 +8,7 @@
88 #include <linux/random.h>
99 #include <linux/signal.h>
1010 #include <linux/personality.h>
11
+#include <linux/irq_pipeline.h>
1112 #include <linux/uaccess.h>
1213 #include <linux/tracehook.h>
1314 #include <linux/uprobes.h>
....@@ -639,16 +640,36 @@
639640 return 0;
640641 }
641642
643
+static inline void do_retuser(void)
644
+{
645
+ unsigned int thread_flags;
646
+
647
+ if (dovetailing()) {
648
+ thread_flags = current_thread_info()->flags;
649
+ if (thread_flags & _TIF_RETUSER)
650
+ inband_retuser_notify();
651
+ }
652
+}
653
+
642654 asmlinkage int
643655 do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall)
644656 {
657
+ WARN_ON_ONCE(irq_pipeline_debug() &&
658
+ (irqs_disabled() || running_oob()));
659
+
645660 /*
646661 * The assembly code enters us with IRQs off, but it hasn't
647662 * informed the tracing code of that for efficiency reasons.
648663 * Update the trace code with the current status.
649664 */
650
- trace_hardirqs_off();
665
+ if (!irqs_pipelined())
666
+ trace_hardirqs_off();
651667 do {
668
+ if (irqs_pipelined()) {
669
+ local_irq_disable();
670
+ hard_cond_local_irq_enable();
671
+ }
672
+
652673 if (likely(thread_flags & _TIF_NEED_RESCHED)) {
653674 schedule();
654675 } else {
....@@ -658,6 +679,7 @@
658679 if (thread_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)) {
659680 int restart = do_signal(regs, syscall);
660681 if (unlikely(restart)) {
682
+ do_retuser();
661683 /*
662684 * Restart without handlers.
663685 * Deal with it without leaving
....@@ -672,10 +694,16 @@
672694 tracehook_notify_resume(regs);
673695 rseq_handle_notify_resume(NULL, regs);
674696 }
697
+ do_retuser();
675698 }
676
- local_irq_disable();
699
+ hard_local_irq_disable();
700
+
701
+ /* RETUSER might have switched oob */
702
+ if (!running_inband())
703
+ break;
704
+
677705 thread_flags = current_thread_info()->flags;
678
- } while (thread_flags & _TIF_WORK_MASK);
706
+ } while (inband_irq_pending() || (thread_flags & _TIF_WORK_MASK));
679707 return 0;
680708 }
681709