These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / arch / arm64 / kernel / fpsimd.c
index c31e59f..4c46c54 100644 (file)
@@ -17,6 +17,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <linux/cpu.h>
 #include <linux/cpu_pm.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -297,25 +298,49 @@ static void fpsimd_pm_init(void)
 static inline void fpsimd_pm_init(void) { }
 #endif /* CONFIG_CPU_PM */
 
+#ifdef CONFIG_HOTPLUG_CPU
+static int fpsimd_cpu_hotplug_notifier(struct notifier_block *nfb,
+                                      unsigned long action,
+                                      void *hcpu)
+{
+       unsigned int cpu = (long)hcpu;
+
+       switch (action) {
+       case CPU_DEAD:
+       case CPU_DEAD_FROZEN:
+               per_cpu(fpsimd_last_state, cpu) = NULL;
+               break;
+       }
+       return NOTIFY_OK;
+}
+
+static struct notifier_block fpsimd_cpu_hotplug_notifier_block = {
+       .notifier_call = fpsimd_cpu_hotplug_notifier,
+};
+
+static inline void fpsimd_hotplug_init(void)
+{
+       register_cpu_notifier(&fpsimd_cpu_hotplug_notifier_block);
+}
+
+#else
+static inline void fpsimd_hotplug_init(void) { }
+#endif
+
 /*
  * FP/SIMD support code initialisation.
  */
 static int __init fpsimd_init(void)
 {
-       u64 pfr = read_cpuid(ID_AA64PFR0_EL1);
-
-       if (pfr & (0xf << 16)) {
+       if (elf_hwcap & HWCAP_FP) {
+               fpsimd_pm_init();
+               fpsimd_hotplug_init();
+       } else {
                pr_notice("Floating-point is not implemented\n");
-               return 0;
        }
-       elf_hwcap |= HWCAP_FP;
 
-       if (pfr & (0xf << 20))
+       if (!(elf_hwcap & HWCAP_ASIMD))
                pr_notice("Advanced SIMD is not implemented\n");
-       else
-               elf_hwcap |= HWCAP_ASIMD;
-
-       fpsimd_pm_init();
 
        return 0;
 }