diff options
author | Michael Ellerman <mpe@ellerman.id.au> | 2016-07-26 08:29:18 -0400 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2016-07-31 21:14:56 -0400 |
commit | a28e46f109c9637b2539b9995078d5df4f7f6c09 (patch) | |
tree | 954cdde1913d243e517596aab5718dfa65fcd800 /arch/powerpc | |
parent | 9e8066f398396d26010d9c6c3c2538ff25461ef8 (diff) |
powerpc/kernel: Check features don't change after patching
Early in boot we binary patch some sections of code based on the CPU and
MMU feature bits. But it is a one-time patching, there is no facility
for repatching the code later if the set of features change.
It is a major bug if the set of features changes after we've done the
code patching - so add a check for it.
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/lib/feature-fixups.c | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c index defb2998b818..59c7caee05b2 100644 --- a/arch/powerpc/lib/feature-fixups.c +++ b/arch/powerpc/lib/feature-fixups.c | |||
@@ -152,10 +152,19 @@ static void do_final_fixups(void) | |||
152 | #endif | 152 | #endif |
153 | } | 153 | } |
154 | 154 | ||
155 | void apply_feature_fixups(void) | 155 | static unsigned long __initdata saved_cpu_features; |
156 | static unsigned int __initdata saved_mmu_features; | ||
157 | #ifdef CONFIG_PPC64 | ||
158 | static unsigned long __initdata saved_firmware_features; | ||
159 | #endif | ||
160 | |||
161 | void __init apply_feature_fixups(void) | ||
156 | { | 162 | { |
157 | struct cpu_spec *spec = *PTRRELOC(&cur_cpu_spec); | 163 | struct cpu_spec *spec = *PTRRELOC(&cur_cpu_spec); |
158 | 164 | ||
165 | *PTRRELOC(&saved_cpu_features) = spec->cpu_features; | ||
166 | *PTRRELOC(&saved_mmu_features) = spec->mmu_features; | ||
167 | |||
159 | /* | 168 | /* |
160 | * Apply the CPU-specific and firmware specific fixups to kernel text | 169 | * Apply the CPU-specific and firmware specific fixups to kernel text |
161 | * (nop out sections not relevant to this CPU or this firmware). | 170 | * (nop out sections not relevant to this CPU or this firmware). |
@@ -173,12 +182,28 @@ void apply_feature_fixups(void) | |||
173 | PTRRELOC(&__stop___lwsync_fixup)); | 182 | PTRRELOC(&__stop___lwsync_fixup)); |
174 | 183 | ||
175 | #ifdef CONFIG_PPC64 | 184 | #ifdef CONFIG_PPC64 |
185 | saved_firmware_features = powerpc_firmware_features; | ||
176 | do_feature_fixups(powerpc_firmware_features, | 186 | do_feature_fixups(powerpc_firmware_features, |
177 | &__start___fw_ftr_fixup, &__stop___fw_ftr_fixup); | 187 | &__start___fw_ftr_fixup, &__stop___fw_ftr_fixup); |
178 | #endif | 188 | #endif |
179 | do_final_fixups(); | 189 | do_final_fixups(); |
180 | } | 190 | } |
181 | 191 | ||
192 | static int __init check_features(void) | ||
193 | { | ||
194 | WARN(saved_cpu_features != cur_cpu_spec->cpu_features, | ||
195 | "CPU features changed after feature patching!\n"); | ||
196 | WARN(saved_mmu_features != cur_cpu_spec->mmu_features, | ||
197 | "MMU features changed after feature patching!\n"); | ||
198 | #ifdef CONFIG_PPC64 | ||
199 | WARN(saved_firmware_features != powerpc_firmware_features, | ||
200 | "Firmware features changed after feature patching!\n"); | ||
201 | #endif | ||
202 | |||
203 | return 0; | ||
204 | } | ||
205 | late_initcall(check_features); | ||
206 | |||
182 | #ifdef CONFIG_FTR_FIXUP_SELFTEST | 207 | #ifdef CONFIG_FTR_FIXUP_SELFTEST |
183 | 208 | ||
184 | #define check(x) \ | 209 | #define check(x) \ |