diff options
Diffstat (limited to 'mm')
-rw-r--r-- | mm/memory-failure.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 848de82cd547..47b8ccb1fb9b 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -212,15 +212,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: Sending SIGBUS to %s:%d due to hardware memory corruption\n", + pr_err("Memory failure: %#lx: Sending SIGBUS to %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); - /* send no signal to non-current processes */ } else { /* * Don't use force here, it's convenient if the signal @@ -419,14 +417,25 @@ 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) { 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; + } return find_early_kill_thread(tsk); } |