diff options
author | Anton Blanchard <anton@samba.org> | 2011-11-14 07:54:47 -0500 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2011-11-15 22:47:54 -0500 |
commit | d715e433b7ad19c02fc4becf0d5e9a59f97925de (patch) | |
tree | 6c5ba4c3b21c4070b82a184f5eca26c9e6c8edf1 /arch/powerpc/lib | |
parent | 6d1e2c6c1a0b800473db4df8595c95745be548ea (diff) |
powerpc: Copy down exception vectors after feature fixups
kdump fails because we try to execute an HV only instruction. Feature
fixups are being applied after we copy the exception vectors down to 0
so they miss out on any updates.
We have always had this issue but it only became critical in v3.0
when we added CFAR support (breaks POWER5) and v3.1 when we added
POWERNV (breaks everyone).
Signed-off-by: Anton Blanchard <anton@samba.org>
Cc: <stable@kernel.org> [v3.0+]
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/lib')
-rw-r--r-- | arch/powerpc/lib/feature-fixups.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c index 0d08d0171392..7a8a7487cee8 100644 --- a/arch/powerpc/lib/feature-fixups.c +++ b/arch/powerpc/lib/feature-fixups.c | |||
@@ -18,6 +18,8 @@ | |||
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <asm/cputable.h> | 19 | #include <asm/cputable.h> |
20 | #include <asm/code-patching.h> | 20 | #include <asm/code-patching.h> |
21 | #include <asm/page.h> | ||
22 | #include <asm/sections.h> | ||
21 | 23 | ||
22 | 24 | ||
23 | struct fixup_entry { | 25 | struct fixup_entry { |
@@ -128,6 +130,27 @@ void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end) | |||
128 | } | 130 | } |
129 | } | 131 | } |
130 | 132 | ||
133 | void do_final_fixups(void) | ||
134 | { | ||
135 | #if defined(CONFIG_PPC64) && defined(CONFIG_RELOCATABLE) | ||
136 | int *src, *dest; | ||
137 | unsigned long length; | ||
138 | |||
139 | if (PHYSICAL_START == 0) | ||
140 | return; | ||
141 | |||
142 | src = (int *)(KERNELBASE + PHYSICAL_START); | ||
143 | dest = (int *)KERNELBASE; | ||
144 | length = (__end_interrupts - _stext) / sizeof(int); | ||
145 | |||
146 | while (length--) { | ||
147 | patch_instruction(dest, *src); | ||
148 | src++; | ||
149 | dest++; | ||
150 | } | ||
151 | #endif | ||
152 | } | ||
153 | |||
131 | #ifdef CONFIG_FTR_FIXUP_SELFTEST | 154 | #ifdef CONFIG_FTR_FIXUP_SELFTEST |
132 | 155 | ||
133 | #define check(x) \ | 156 | #define check(x) \ |