From: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
Subject: powerpc/book3s: Introduce a early machine check hook in cpu_spec
Git-commit: 4c703416efc0a23f83a282b9240bb92fbd9e0be9
Patch-mainline: v3.14-rc1
References: bnc#878240 

    This patch adds the early machine check function pointer in cputable for
    CPU specific early machine check handling. The early machine handle routine
    will be called in real mode to handle SLB and TLB errors. We can not reuse
    the existing machine_check hook because it is always invoked in kernel
    virtual mode and we would already be in trouble if we get SLB or TLB errors.
    This patch just sets up a mechanism to invoke CPU specific handler. The
    subsequent patches will populate the function pointer.
    
Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
Acked-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Acked-by: Torsten Duwe <duwe@suse.de>

 arch/powerpc/include/asm/cputable.h | 7 +++++++
 arch/powerpc/kernel/traps.c         | 7 +++++--
 2 files changed, 12 insertions(+), 2 deletions(-)
Index: linux-3.12-SLE12/arch/powerpc/include/asm/cputable.h
===================================================================
--- linux-3.12-SLE12.orig/arch/powerpc/include/asm/cputable.h
+++ linux-3.12-SLE12/arch/powerpc/include/asm/cputable.h
@@ -90,6 +90,13 @@ struct cpu_spec {
 	 * if the error is fatal, 1 if it was fully recovered and 0 to
 	 * pass up (not CPU originated) */
 	int		(*machine_check)(struct pt_regs *regs);
+
+	/*
+	 * Processor specific early machine check handler which is
+	 * called in real mode to handle SLB and TLB errors.
+	 */
+	long		(*machine_check_early)(struct pt_regs *regs);
+
 	/*
 	 * Processor specific routine to flush tlbs.
 	 */
Index: linux-3.12-SLE12/arch/powerpc/kernel/traps.c
===================================================================
--- linux-3.12-SLE12.orig/arch/powerpc/kernel/traps.c
+++ linux-3.12-SLE12/arch/powerpc/kernel/traps.c
@@ -293,8 +293,11 @@ void system_reset_exception(struct pt_re
  */
 long machine_check_early(struct pt_regs *regs)
 {
-	/* TODO: handle/decode machine check reason */
-	return 0;
+	long handled = 0;
+
+	if (cur_cpu_spec && cur_cpu_spec->machine_check_early)
+		handled = cur_cpu_spec->machine_check_early(regs);
+	return handled;
 }
 
 #endif
