diff options
author | Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com> | 2013-10-30 10:35:11 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2013-12-05 00:04:39 -0500 |
commit | e22a22740c1ac23aaa10835f026b3549ee3e4e75 (patch) | |
tree | b9657323d8977882dab4d970316f88281466e9ed /arch/powerpc/kernel/cputable.c | |
parent | 0440705049b041d84268ea57f6e90e2f16618897 (diff) |
powerpc/book3s: Flush SLB/TLBs if we get SLB/TLB machine check errors on power7.
If we get a machine check exception due to SLB or TLB errors, then flush
SLBs/TLBs and reload SLBs to recover. We do this in real mode before turning
on MMU. Otherwise we would run into nested machine checks.
If we get a machine check when we are in guest, then just flush the
SLBs and continue. This patch handles errors for power7. The next
patch will handle errors for power8
Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel/cputable.c')
-rw-r--r-- | arch/powerpc/kernel/cputable.c | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 55d0f9c282b8..c54188bcdd9e 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c | |||
@@ -73,6 +73,7 @@ extern void __restore_cpu_power8(void); | |||
73 | extern void __restore_cpu_a2(void); | 73 | extern void __restore_cpu_a2(void); |
74 | extern void __flush_tlb_power7(unsigned long inval_selector); | 74 | extern void __flush_tlb_power7(unsigned long inval_selector); |
75 | extern void __flush_tlb_power8(unsigned long inval_selector); | 75 | extern void __flush_tlb_power8(unsigned long inval_selector); |
76 | extern long __machine_check_early_realmode_p7(struct pt_regs *regs); | ||
76 | #endif /* CONFIG_PPC64 */ | 77 | #endif /* CONFIG_PPC64 */ |
77 | #if defined(CONFIG_E500) | 78 | #if defined(CONFIG_E500) |
78 | extern void __setup_cpu_e5500(unsigned long offset, struct cpu_spec* spec); | 79 | extern void __setup_cpu_e5500(unsigned long offset, struct cpu_spec* spec); |
@@ -443,6 +444,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
443 | .cpu_setup = __setup_cpu_power7, | 444 | .cpu_setup = __setup_cpu_power7, |
444 | .cpu_restore = __restore_cpu_power7, | 445 | .cpu_restore = __restore_cpu_power7, |
445 | .flush_tlb = __flush_tlb_power7, | 446 | .flush_tlb = __flush_tlb_power7, |
447 | .machine_check_early = __machine_check_early_realmode_p7, | ||
446 | .platform = "power7", | 448 | .platform = "power7", |
447 | }, | 449 | }, |
448 | { /* 2.07-compliant processor, i.e. Power8 "architected" mode */ | 450 | { /* 2.07-compliant processor, i.e. Power8 "architected" mode */ |
@@ -479,6 +481,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
479 | .cpu_setup = __setup_cpu_power7, | 481 | .cpu_setup = __setup_cpu_power7, |
480 | .cpu_restore = __restore_cpu_power7, | 482 | .cpu_restore = __restore_cpu_power7, |
481 | .flush_tlb = __flush_tlb_power7, | 483 | .flush_tlb = __flush_tlb_power7, |
484 | .machine_check_early = __machine_check_early_realmode_p7, | ||
482 | .platform = "power7", | 485 | .platform = "power7", |
483 | }, | 486 | }, |
484 | { /* Power7+ */ | 487 | { /* Power7+ */ |
@@ -498,6 +501,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
498 | .cpu_setup = __setup_cpu_power7, | 501 | .cpu_setup = __setup_cpu_power7, |
499 | .cpu_restore = __restore_cpu_power7, | 502 | .cpu_restore = __restore_cpu_power7, |
500 | .flush_tlb = __flush_tlb_power7, | 503 | .flush_tlb = __flush_tlb_power7, |
504 | .machine_check_early = __machine_check_early_realmode_p7, | ||
501 | .platform = "power7+", | 505 | .platform = "power7+", |
502 | }, | 506 | }, |
503 | { /* Power8E */ | 507 | { /* Power8E */ |