aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorMichael Ellerman <mpe@ellerman.id.au>2016-07-26 08:29:18 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2016-07-31 21:14:56 -0400
commita28e46f109c9637b2539b9995078d5df4f7f6c09 (patch)
tree954cdde1913d243e517596aab5718dfa65fcd800 /arch/powerpc
parent9e8066f398396d26010d9c6c3c2538ff25461ef8 (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.c27
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
155void apply_feature_fixups(void) 155static unsigned long __initdata saved_cpu_features;
156static unsigned int __initdata saved_mmu_features;
157#ifdef CONFIG_PPC64
158static unsigned long __initdata saved_firmware_features;
159#endif
160
161void __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
192static 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}
205late_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) \