Skip to content

Commit a86b9ec

Browse files
maheshsalgregkh
authored andcommitted
powerpc/book3s/mce: Move add_taint() later in virtual mode
commit d93b0ac01a9ce276ec39644be47001873d3d183c upstream. machine_check_early() gets called in real mode. The very first time when add_taint() is called, it prints a warning which ends up calling opal call (that uses OPAL_CALL wrapper) for writing it to console. If we get a very first machine check while we are in opal we are doomed. OPAL_CALL overwrites the PACASAVEDMSR in r13 and in this case when we are done with MCE handling the original opal call will use this new MSR on it's way back to opal_return. This usually leads to unexpected behaviour or the kernel to panic. Instead move the add_taint() call later in the virtual mode where it is safe to call. This is broken with current FW level. We got lucky so far for not getting very first MCE hit while in OPAL. But easily reproducible on Mambo. Fixes: 27ea2c4 ("powerpc: Set the correct kernel taint on machine check errors.") Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent f3ffc64 commit a86b9ec

2 files changed

Lines changed: 4 additions & 2 deletions

File tree

arch/powerpc/kernel/mce.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,8 @@ static void machine_check_process_queued_event(struct irq_work *work)
204204
{
205205
int index;
206206

207+
add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE);
208+
207209
/*
208210
* For now just print it to console.
209211
* TODO: log this error event to FSP or nvram.

arch/powerpc/kernel/traps.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,6 @@ long machine_check_early(struct pt_regs *regs)
297297

298298
__this_cpu_inc(irq_stat.mce_exceptions);
299299

300-
add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE);
301-
302300
if (cur_cpu_spec && cur_cpu_spec->machine_check_early)
303301
handled = cur_cpu_spec->machine_check_early(regs);
304302
return handled;
@@ -704,6 +702,8 @@ void machine_check_exception(struct pt_regs *regs)
704702

705703
__this_cpu_inc(irq_stat.mce_exceptions);
706704

705+
add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE);
706+
707707
/* See if any machine dependent calls. In theory, we would want
708708
* to call the CPU first, and call the ppc_md. one if the CPU
709709
* one returns a positive number. However there is existing code

0 commit comments

Comments
 (0)