diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 521773c4ac295597ad93805d0520b80b0973f699..5517300eff8e1c42f0260b3aa75391b463d70315 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -215,15 +215,13 @@ static int kill_proc(struct to_kill *tk, unsigned long pfn, int flags) short addr_lsb = tk->size_shift; int ret = 0; - if ((t->mm == current->mm) || !(flags & MF_ACTION_REQUIRED)) - pr_err("Memory failure: %#lx: Killing %s:%d due to hardware memory corruption\n", + pr_err("Memory failure: %#lx: Killing %s:%d due to hardware memory corruption\n", pfn, t->comm, t->pid); if (flags & MF_ACTION_REQUIRED) { - if (t->mm == current->mm) - ret = force_sig_mceerr(BUS_MCEERR_AR, + WARN_ON_ONCE(t != current); + ret = force_sig_mceerr(BUS_MCEERR_AR, (void __user *)tk->addr, addr_lsb, current); - /* send no signal to non-current processes */ } else { /* * Don't use force here, it's convenient if the signal @@ -421,6 +419,9 @@ static struct task_struct *find_early_kill_thread(struct task_struct *tsk) * 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. + * + * 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. */ static struct task_struct *task_early_kill(struct task_struct *tsk, int force_early) @@ -428,8 +429,16 @@ static struct task_struct *task_early_kill(struct task_struct *tsk, struct task_struct *t; if (!tsk->mm) return NULL; - if (force_early) - return tsk; + 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; + } t = find_early_kill_thread(tsk); if (t) return t;