pfn, t->comm, t->pid);
 
        if (flags & MF_ACTION_REQUIRED) {
-               WARN_ON_ONCE(t != current);
-               ret = force_sig_mceerr(BUS_MCEERR_AR,
+               if (t == current)
+                       ret = force_sig_mceerr(BUS_MCEERR_AR,
                                         (void __user *)tk->addr, addr_lsb);
+               else
+                       /* Signal other processes sharing the page if they have PF_MCE_EARLY set. */
+                       ret = send_sig_mceerr(BUS_MCEERR_AO, (void __user *)tk->addr,
+                               addr_lsb, t);
        } else {
                /*
                 * Don't use force here, it's convenient if the signal
  * Determine whether a given process is "early kill" process which expects
  * to be signaled when some page under the process is hwpoisoned.
  * Return task_struct of the dedicated thread (main thread unless explicitly
- * specified) if the process is "early kill," and otherwise returns NULL.
+ * specified) if the process is "early kill" and otherwise returns NULL.
  *
- * Note that the above is true for Action Optional case, but not for Action
- * Required case where SIGBUS should sent only to the current thread.
+ * Note that the above is true for Action Optional case. For Action Required
+ * case, it's only meaningful to the current thread which need to be signaled
+ * with SIGBUS, this error is Action Optional for other non current
+ * processes sharing the same error page,if the process is "early kill", the
+ * task_struct of the dedicated thread will also be returned.
  */
 static struct task_struct *task_early_kill(struct task_struct *tsk,
                                           int force_early)
 {
        if (!tsk->mm)
                return NULL;
-       if (force_early) {
-               /*
-                * Comparing ->mm here because current task might represent
-                * a subthread, while tsk always points to the main thread.
-                */
-               if (tsk->mm == current->mm)
-                       return current;
-               else
-                       return NULL;
-       }
+       /*
+        * Comparing ->mm here because current task might represent
+        * a subthread, while tsk always points to the main thread.
+        */
+       if (force_early && tsk->mm == current->mm)
+               return current;
+
        return find_early_kill_thread(tsk);
 }