OSDN Git Service

Merge tag 'drm-next-2020-06-02' of git://anongit.freedesktop.org/drm/drm
[tomoyo/tomoyo-test1.git] / kernel / sched / core.c
index 9a2fbf9..0ae29fd 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/nospec.h>
 
 #include <linux/kcov.h>
+#include <linux/scs.h>
 
 #include <asm/switch_to.h>
 #include <asm/tlb.h>
@@ -2561,6 +2562,8 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags)
         *
         * Pairs with the LOCK+smp_mb__after_spinlock() on rq->lock in
         * __schedule().  See the comment for smp_mb__after_spinlock().
+        *
+        * A similar smb_rmb() lives in try_invoke_on_locked_down_task().
         */
        smp_rmb();
        if (p->on_rq && ttwu_remote(p, wake_flags))
@@ -2635,6 +2638,52 @@ out:
 }
 
 /**
+ * try_invoke_on_locked_down_task - Invoke a function on task in fixed state
+ * @p: Process for which the function is to be invoked.
+ * @func: Function to invoke.
+ * @arg: Argument to function.
+ *
+ * If the specified task can be quickly locked into a definite state
+ * (either sleeping or on a given runqueue), arrange to keep it in that
+ * state while invoking @func(@arg).  This function can use ->on_rq and
+ * task_curr() to work out what the state is, if required.  Given that
+ * @func can be invoked with a runqueue lock held, it had better be quite
+ * lightweight.
+ *
+ * Returns:
+ *     @false if the task slipped out from under the locks.
+ *     @true if the task was locked onto a runqueue or is sleeping.
+ *             However, @func can override this by returning @false.
+ */
+bool try_invoke_on_locked_down_task(struct task_struct *p, bool (*func)(struct task_struct *t, void *arg), void *arg)
+{
+       bool ret = false;
+       struct rq_flags rf;
+       struct rq *rq;
+
+       lockdep_assert_irqs_enabled();
+       raw_spin_lock_irq(&p->pi_lock);
+       if (p->on_rq) {
+               rq = __task_rq_lock(p, &rf);
+               if (task_rq(p) == rq)
+                       ret = func(p, arg);
+               rq_unlock(rq, &rf);
+       } else {
+               switch (p->state) {
+               case TASK_RUNNING:
+               case TASK_WAKING:
+                       break;
+               default:
+                       smp_rmb(); // See smp_rmb() comment in try_to_wake_up().
+                       if (!p->on_rq)
+                               ret = func(p, arg);
+               }
+       }
+       raw_spin_unlock_irq(&p->pi_lock);
+       return ret;
+}
+
+/**
  * wake_up_process - Wake up a specific process
  * @p: The process to be woken up.
  *
@@ -3877,6 +3926,9 @@ static inline void schedule_debug(struct task_struct *prev, bool preempt)
 #ifdef CONFIG_SCHED_STACK_END_CHECK
        if (task_stack_end_corrupted(prev))
                panic("corrupted stack end detected inside scheduler\n");
+
+       if (task_scs_end_corrupted(prev))
+               panic("corrupted shadow stack detected inside scheduler\n");
 #endif
 
 #ifdef CONFIG_DEBUG_ATOMIC_SLEEP
@@ -6040,6 +6092,7 @@ void init_idle(struct task_struct *idle, int cpu)
        idle->se.exec_start = sched_clock();
        idle->flags |= PF_IDLE;
 
+       scs_task_reset(idle);
        kasan_unpoison_task_stack(idle);
 
 #ifdef CONFIG_SMP