Commit b9e2f224 authored by Thomas Weißschuh's avatar Thomas Weißschuh Committed by Johannes Berg
Browse files

um: Re-evaluate thread flags repeatedly



The thread flags may change during their processing.
For example a task_work can queue a new signal to be sent.
This signal should be delivered before returning to usespace again.

Evaluate the flags repeatedly similar to other architectures.

Signed-off-by: default avatarThomas Weißschuh <thomas.weissschuh@linutronix.de>
Reviewed-by: default avatarNam Cao <namcao@linutronix.de>
Link: https://patch.msgid.link/20250704-uml-thread_flags-v1-1-0e293fd8d627@linutronix.de


Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent ac1ad16f
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -52,7 +52,11 @@ struct thread_info {
#define _TIF_NOTIFY_SIGNAL	(1 << TIF_NOTIFY_SIGNAL)
#define _TIF_MEMDIE		(1 << TIF_MEMDIE)
#define _TIF_SYSCALL_AUDIT	(1 << TIF_SYSCALL_AUDIT)
#define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
#define _TIF_SECCOMP		(1 << TIF_SECCOMP)
#define _TIF_SINGLESTEP		(1 << TIF_SINGLESTEP)

#define _TIF_WORK_MASK		(_TIF_NEED_RESCHED | _TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL | \
				 _TIF_NOTIFY_RESUME)

#endif
+12 −8
Original line number Diff line number Diff line
@@ -82,14 +82,18 @@ struct task_struct *__switch_to(struct task_struct *from, struct task_struct *to
void interrupt_end(void)
{
	struct pt_regs *regs = &current->thread.regs;
	unsigned long thread_flags;

	if (need_resched())
	thread_flags = read_thread_flags();
	while (thread_flags & _TIF_WORK_MASK) {
		if (thread_flags & _TIF_NEED_RESCHED)
			schedule();
	if (test_thread_flag(TIF_SIGPENDING) ||
	    test_thread_flag(TIF_NOTIFY_SIGNAL))
		if (thread_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
			do_signal(regs);
	if (test_thread_flag(TIF_NOTIFY_RESUME))
		if (thread_flags & _TIF_NOTIFY_RESUME)
			resume_user_mode_work(regs);
		thread_flags = read_thread_flags();
	}
}

int get_current_pid(void)