Skip to content

Commit

Permalink
powerpc: Copy down exception vectors after feature fixups
Browse files Browse the repository at this point in the history
commit d715e43 upstream.

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>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Anton Blanchard authored and Greg Kroah-Hartman committed Nov 21, 2011
1 parent fed5954 commit 3549966
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 2 deletions.
2 changes: 1 addition & 1 deletion arch/powerpc/include/asm/sections.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

#ifdef __powerpc64__

extern char _end[];
extern char __end_interrupts[];

static inline int in_kernel_text(unsigned long addr)
{
Expand Down
1 change: 1 addition & 0 deletions arch/powerpc/include/asm/synch.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
extern unsigned int __start___lwsync_fixup, __stop___lwsync_fixup;
extern void do_lwsync_fixups(unsigned long value, void *fixup_start,
void *fixup_end);
extern void do_final_fixups(void);

static inline void eieio(void)
{
Expand Down
1 change: 0 additions & 1 deletion arch/powerpc/kernel/kvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@ static void kvm_patch_ins_b(u32 *inst, int addr)
/* On relocatable kernels interrupts handlers and our code
can be in different regions, so we don't patch them */

extern u32 __end_interrupts;
if ((ulong)inst < (ulong)&__end_interrupts)
return;
#endif
Expand Down
2 changes: 2 additions & 0 deletions arch/powerpc/kernel/setup_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ notrace unsigned long __init early_init(unsigned long dt_ptr)
PTRRELOC(&__start___lwsync_fixup),
PTRRELOC(&__stop___lwsync_fixup));

do_final_fixups();

return KERNELBASE + offset;
}

Expand Down
1 change: 1 addition & 0 deletions arch/powerpc/kernel/setup_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,7 @@ void __init setup_system(void)
&__start___fw_ftr_fixup, &__stop___fw_ftr_fixup);
do_lwsync_fixups(cur_cpu_spec->cpu_features,
&__start___lwsync_fixup, &__stop___lwsync_fixup);
do_final_fixups();

/*
* Unflatten the device-tree passed by prom_init or kexec
Expand Down
23 changes: 23 additions & 0 deletions arch/powerpc/lib/feature-fixups.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#include <linux/init.h>
#include <asm/cputable.h>
#include <asm/code-patching.h>
#include <asm/page.h>
#include <asm/sections.h>


struct fixup_entry {
Expand Down Expand Up @@ -128,6 +130,27 @@ void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end)
}
}

void do_final_fixups(void)
{
#if defined(CONFIG_PPC64) && defined(CONFIG_RELOCATABLE)
int *src, *dest;
unsigned long length;

if (PHYSICAL_START == 0)
return;

src = (int *)(KERNELBASE + PHYSICAL_START);
dest = (int *)KERNELBASE;
length = (__end_interrupts - _stext) / sizeof(int);

while (length--) {
patch_instruction(dest, *src);
src++;
dest++;
}
#endif
}

#ifdef CONFIG_FTR_FIXUP_SELFTEST

#define check(x) \
Expand Down

0 comments on commit 3549966

Please sign in to comment.