|
@@ -1547,6 +1547,9 @@ struct task_struct {
|
|
|
/* unserialized, strictly 'current' */
|
|
|
unsigned in_execve:1; /* bit to tell LSMs we're in execve */
|
|
|
unsigned in_iowait:1;
|
|
|
+#if !defined(TIF_RESTORE_SIGMASK)
|
|
|
+ unsigned restore_sigmask:1;
|
|
|
+#endif
|
|
|
#ifdef CONFIG_MEMCG
|
|
|
unsigned memcg_may_oom:1;
|
|
|
#ifndef CONFIG_SLOB
|
|
@@ -2680,6 +2683,66 @@ extern void sigqueue_free(struct sigqueue *);
|
|
|
extern int send_sigqueue(struct sigqueue *, struct task_struct *, int group);
|
|
|
extern int do_sigaction(int, struct k_sigaction *, struct k_sigaction *);
|
|
|
|
|
|
+#ifdef TIF_RESTORE_SIGMASK
|
|
|
+/*
|
|
|
+ * Legacy restore_sigmask accessors. These are inefficient on
|
|
|
+ * SMP architectures because they require atomic operations.
|
|
|
+ */
|
|
|
+
|
|
|
+/**
|
|
|
+ * set_restore_sigmask() - make sure saved_sigmask processing gets done
|
|
|
+ *
|
|
|
+ * This sets TIF_RESTORE_SIGMASK and ensures that the arch signal code
|
|
|
+ * will run before returning to user mode, to process the flag. For
|
|
|
+ * all callers, TIF_SIGPENDING is already set or it's no harm to set
|
|
|
+ * it. TIF_RESTORE_SIGMASK need not be in the set of bits that the
|
|
|
+ * arch code will notice on return to user mode, in case those bits
|
|
|
+ * are scarce. We set TIF_SIGPENDING here to ensure that the arch
|
|
|
+ * signal code always gets run when TIF_RESTORE_SIGMASK is set.
|
|
|
+ */
|
|
|
+static inline void set_restore_sigmask(void)
|
|
|
+{
|
|
|
+ set_thread_flag(TIF_RESTORE_SIGMASK);
|
|
|
+ WARN_ON(!test_thread_flag(TIF_SIGPENDING));
|
|
|
+}
|
|
|
+static inline void clear_restore_sigmask(void)
|
|
|
+{
|
|
|
+ clear_thread_flag(TIF_RESTORE_SIGMASK);
|
|
|
+}
|
|
|
+static inline bool test_restore_sigmask(void)
|
|
|
+{
|
|
|
+ return test_thread_flag(TIF_RESTORE_SIGMASK);
|
|
|
+}
|
|
|
+static inline bool test_and_clear_restore_sigmask(void)
|
|
|
+{
|
|
|
+ return test_and_clear_thread_flag(TIF_RESTORE_SIGMASK);
|
|
|
+}
|
|
|
+
|
|
|
+#else /* TIF_RESTORE_SIGMASK */
|
|
|
+
|
|
|
+/* Higher-quality implementation, used if TIF_RESTORE_SIGMASK doesn't exist. */
|
|
|
+static inline void set_restore_sigmask(void)
|
|
|
+{
|
|
|
+ current->restore_sigmask = true;
|
|
|
+ WARN_ON(!test_thread_flag(TIF_SIGPENDING));
|
|
|
+}
|
|
|
+static inline void clear_restore_sigmask(void)
|
|
|
+{
|
|
|
+ current->restore_sigmask = false;
|
|
|
+}
|
|
|
+static inline bool test_restore_sigmask(void)
|
|
|
+{
|
|
|
+ return current->restore_sigmask;
|
|
|
+}
|
|
|
+static inline bool test_and_clear_restore_sigmask(void)
|
|
|
+{
|
|
|
+ if (!current->restore_sigmask)
|
|
|
+ return false;
|
|
|
+ current->restore_sigmask = false;
|
|
|
+ return true;
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
static inline void restore_saved_sigmask(void)
|
|
|
{
|
|
|
if (test_and_clear_restore_sigmask())
|