Skip to content

Commit 03151c6

Browse files
nhoriguchitorvalds
authored andcommitted
mm/memory-failure: send SIGBUS(BUS_MCEERR_AR) only to current thread
Action Required memory error should happen only when a processor is about to access to a corrupted memory, so it's synchronous and only affects current process/thread. Recently commit 872e9a2 ("mm, memory_failure: don't send BUS_MCEERR_AO for action required error") fixed the issue that Action Required memory could unnecessarily send SIGBUS to the processes which share the error memory. But we still have another issue that we could send SIGBUS to a wrong thread. This is because collect_procs() and task_early_kill() fails to add the current process to "to-kill" list. So this patch is suggesting to fix it. With this fix, SIGBUS(BUS_MCEERR_AR) is never sent to non-current process/thread. Signed-off-by: Naoya Horiguchi <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Acked-by: Tony Luck <[email protected]> Acked-by: Pankaj Gupta <[email protected]> Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Linus Torvalds <[email protected]>
1 parent 4e018b4 commit 03151c6

File tree

1 file changed

+16
-7
lines changed

1 file changed

+16
-7
lines changed

mm/memory-failure.c

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -212,15 +212,13 @@ static int kill_proc(struct to_kill *tk, unsigned long pfn, int flags)
212212
short addr_lsb = tk->size_shift;
213213
int ret = 0;
214214

215-
if ((t->mm == current->mm) || !(flags & MF_ACTION_REQUIRED))
216-
pr_err("Memory failure: %#lx: Sending SIGBUS to %s:%d due to hardware memory corruption\n",
215+
pr_err("Memory failure: %#lx: Sending SIGBUS to %s:%d due to hardware memory corruption\n",
217216
pfn, t->comm, t->pid);
218217

219218
if (flags & MF_ACTION_REQUIRED) {
220-
if (t->mm == current->mm)
221-
ret = force_sig_mceerr(BUS_MCEERR_AR,
219+
WARN_ON_ONCE(t != current);
220+
ret = force_sig_mceerr(BUS_MCEERR_AR,
222221
(void __user *)tk->addr, addr_lsb);
223-
/* send no signal to non-current processes */
224222
} else {
225223
/*
226224
* 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)
419417
* to be signaled when some page under the process is hwpoisoned.
420418
* Return task_struct of the dedicated thread (main thread unless explicitly
421419
* specified) if the process is "early kill," and otherwise returns NULL.
420+
*
421+
* Note that the above is true for Action Optional case, but not for Action
422+
* Required case where SIGBUS should sent only to the current thread.
422423
*/
423424
static struct task_struct *task_early_kill(struct task_struct *tsk,
424425
int force_early)
425426
{
426427
if (!tsk->mm)
427428
return NULL;
428-
if (force_early)
429-
return tsk;
429+
if (force_early) {
430+
/*
431+
* Comparing ->mm here because current task might represent
432+
* a subthread, while tsk always points to the main thread.
433+
*/
434+
if (tsk->mm == current->mm)
435+
return current;
436+
else
437+
return NULL;
438+
}
430439
return find_early_kill_thread(tsk);
431440
}
432441

0 commit comments

Comments
 (0)