powerpc/kernel: Check features don't change after patching
authorMichael Ellerman <mpe@ellerman.id.au>
Tue, 26 Jul 2016 12:29:18 +0000 (22:29 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Mon, 1 Aug 2016 01:14:56 +0000 (11:14 +1000)
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>
arch/powerpc/lib/feature-fixups.c

index defb299..59c7cae 100644 (file)
@@ -152,10 +152,19 @@ static void do_final_fixups(void)
 #endif
 }
 
-void apply_feature_fixups(void)
+static unsigned long __initdata saved_cpu_features;
+static unsigned int __initdata saved_mmu_features;
+#ifdef CONFIG_PPC64
+static unsigned long __initdata saved_firmware_features;
+#endif
+
+void __init apply_feature_fixups(void)
 {
        struct cpu_spec *spec = *PTRRELOC(&cur_cpu_spec);
 
+       *PTRRELOC(&saved_cpu_features) = spec->cpu_features;
+       *PTRRELOC(&saved_mmu_features) = spec->mmu_features;
+
        /*
         * Apply the CPU-specific and firmware specific fixups to kernel text
         * (nop out sections not relevant to this CPU or this firmware).
@@ -173,12 +182,28 @@ void apply_feature_fixups(void)
                         PTRRELOC(&__stop___lwsync_fixup));
 
 #ifdef CONFIG_PPC64
+       saved_firmware_features = powerpc_firmware_features;
        do_feature_fixups(powerpc_firmware_features,
                          &__start___fw_ftr_fixup, &__stop___fw_ftr_fixup);
 #endif
        do_final_fixups();
 }
 
+static int __init check_features(void)
+{
+       WARN(saved_cpu_features != cur_cpu_spec->cpu_features,
+            "CPU features changed after feature patching!\n");
+       WARN(saved_mmu_features != cur_cpu_spec->mmu_features,
+            "MMU features changed after feature patching!\n");
+#ifdef CONFIG_PPC64
+       WARN(saved_firmware_features != powerpc_firmware_features,
+            "Firmware features changed after feature patching!\n");
+#endif
+
+       return 0;
+}
+late_initcall(check_features);
+
 #ifdef CONFIG_FTR_FIXUP_SELFTEST
 
 #define check(x)       \