Merge tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso...
[linux-2.6-microblaze.git] / kernel / rseq.c
index 97ac20b..bda8175 100644 (file)
@@ -18,8 +18,9 @@
 #define CREATE_TRACE_POINTS
 #include <trace/events/rseq.h>
 
-#define RSEQ_CS_PREEMPT_MIGRATE_FLAGS (RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE | \
-                                      RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT)
+#define RSEQ_CS_NO_RESTART_FLAGS (RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT | \
+                                 RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL | \
+                                 RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE)
 
 /*
  *
@@ -175,23 +176,15 @@ static int rseq_need_restart(struct task_struct *t, u32 cs_flags)
        u32 flags, event_mask;
        int ret;
 
+       if (WARN_ON_ONCE(cs_flags & RSEQ_CS_NO_RESTART_FLAGS) || cs_flags)
+               return -EINVAL;
+
        /* Get thread flags. */
        ret = get_user(flags, &t->rseq->flags);
        if (ret)
                return ret;
 
-       /* Take critical section flags into account. */
-       flags |= cs_flags;
-
-       /*
-        * Restart on signal can only be inhibited when restart on
-        * preempt and restart on migrate are inhibited too. Otherwise,
-        * a preempted signal handler could fail to restart the prior
-        * execution context on sigreturn.
-        */
-       if (unlikely((flags & RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL) &&
-                    (flags & RSEQ_CS_PREEMPT_MIGRATE_FLAGS) !=
-                    RSEQ_CS_PREEMPT_MIGRATE_FLAGS))
+       if (WARN_ON_ONCE(flags & RSEQ_CS_NO_RESTART_FLAGS) || flags)
                return -EINVAL;
 
        /*
@@ -203,7 +196,7 @@ static int rseq_need_restart(struct task_struct *t, u32 cs_flags)
        t->rseq_event_mask = 0;
        preempt_enable();
 
-       return !!(event_mask & ~flags);
+       return !!event_mask;
 }
 
 static int clear_rseq_cs(struct task_struct *t)