diff options
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/include/asm/sections.h | 2 | ||||
-rw-r--r-- | arch/powerpc/include/asm/synch.h | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/kvm.c | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/setup_32.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/setup_64.c | 1 | ||||
-rw-r--r-- | arch/powerpc/lib/feature-fixups.c | 23 |
6 files changed, 28 insertions, 2 deletions
diff --git a/arch/powerpc/include/asm/sections.h b/arch/powerpc/include/asm/sections.h index 6fbce725c710..a0f358d4a00c 100644 --- a/arch/powerpc/include/asm/sections.h +++ b/arch/powerpc/include/asm/sections.h | |||
@@ -8,7 +8,7 @@ | |||
8 | 8 | ||
9 | #ifdef __powerpc64__ | 9 | #ifdef __powerpc64__ |
10 | 10 | ||
11 | extern char _end[]; | 11 | extern char __end_interrupts[]; |
12 | 12 | ||
13 | static inline int in_kernel_text(unsigned long addr) | 13 | static inline int in_kernel_text(unsigned long addr) |
14 | { | 14 | { |
diff --git a/arch/powerpc/include/asm/synch.h b/arch/powerpc/include/asm/synch.h index d7cab44643c5..87878c68d1c2 100644 --- a/arch/powerpc/include/asm/synch.h +++ b/arch/powerpc/include/asm/synch.h | |||
@@ -13,6 +13,7 @@ | |||
13 | extern unsigned int __start___lwsync_fixup, __stop___lwsync_fixup; | 13 | extern unsigned int __start___lwsync_fixup, __stop___lwsync_fixup; |
14 | extern void do_lwsync_fixups(unsigned long value, void *fixup_start, | 14 | extern void do_lwsync_fixups(unsigned long value, void *fixup_start, |
15 | void *fixup_end); | 15 | void *fixup_end); |
16 | extern void do_final_fixups(void); | ||
16 | 17 | ||
17 | static inline void eieio(void) | 18 | static inline void eieio(void) |
18 | { | 19 | { |
diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c index 35f27646c4ff..2985338d0e10 100644 --- a/arch/powerpc/kernel/kvm.c +++ b/arch/powerpc/kernel/kvm.c | |||
@@ -132,7 +132,6 @@ static void kvm_patch_ins_b(u32 *inst, int addr) | |||
132 | /* On relocatable kernels interrupts handlers and our code | 132 | /* On relocatable kernels interrupts handlers and our code |
133 | can be in different regions, so we don't patch them */ | 133 | can be in different regions, so we don't patch them */ |
134 | 134 | ||
135 | extern u32 __end_interrupts; | ||
136 | if ((ulong)inst < (ulong)&__end_interrupts) | 135 | if ((ulong)inst < (ulong)&__end_interrupts) |
137 | return; | 136 | return; |
138 | #endif | 137 | #endif |
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index c1ce86357ecb..ac7610815113 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c | |||
@@ -107,6 +107,8 @@ notrace unsigned long __init early_init(unsigned long dt_ptr) | |||
107 | PTRRELOC(&__start___lwsync_fixup), | 107 | PTRRELOC(&__start___lwsync_fixup), |
108 | PTRRELOC(&__stop___lwsync_fixup)); | 108 | PTRRELOC(&__stop___lwsync_fixup)); |
109 | 109 | ||
110 | do_final_fixups(); | ||
111 | |||
110 | return KERNELBASE + offset; | 112 | return KERNELBASE + offset; |
111 | } | 113 | } |
112 | 114 | ||
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 1a9dea80a69b..fb9bb46e7e88 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
@@ -359,6 +359,7 @@ void __init setup_system(void) | |||
359 | &__start___fw_ftr_fixup, &__stop___fw_ftr_fixup); | 359 | &__start___fw_ftr_fixup, &__stop___fw_ftr_fixup); |
360 | do_lwsync_fixups(cur_cpu_spec->cpu_features, | 360 | do_lwsync_fixups(cur_cpu_spec->cpu_features, |
361 | &__start___lwsync_fixup, &__stop___lwsync_fixup); | 361 | &__start___lwsync_fixup, &__stop___lwsync_fixup); |
362 | do_final_fixups(); | ||
362 | 363 | ||
363 | /* | 364 | /* |
364 | * Unflatten the device-tree passed by prom_init or kexec | 365 | * Unflatten the device-tree passed by prom_init or kexec |
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) \ |