From: Janet Liu <janet....@spreadtrum.com> Now FPSIMD don't handle HOTPLUG_CPU. This introduces bug after cpu down/up process.
After cpu down/up process, the FPSMID hardware register is default value, not any process's fpsimd context. when CPU_DEAD set cpu's fpsimd_state to NULL, it will force to load the fpsimd context for the thread, to avoid the chance to skip to load the context. If process A is the last user process on CPU N before cpu down, and the first user process on the same CPU N after cpu up, A's fpsimd_state.cpu is the current cpu id, and per_cpu(fpsimd_last_state) points A's fpsimd_state, so kernel will not reload the context during it return to user space. Signed-off-by: Janet Liu <janet....@spreadtrum.com> Signed-off-by: Xiongshan An <xiongshan...@spreadtrum.com> Signed-off-by: Chunyan Zhang <chunyan.zh...@spreadtrum.com> --- arch/arm64/kernel/fpsimd.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c index 3dca156..35ef3a2 100644 --- a/arch/arm64/kernel/fpsimd.c +++ b/arch/arm64/kernel/fpsimd.c @@ -23,6 +23,7 @@ #include <linux/sched.h> #include <linux/signal.h> #include <linux/hardirq.h> +#include <linux/cpu.h> #include <asm/fpsimd.h> #include <asm/cputype.h> @@ -296,6 +297,36 @@ 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) +{ + int cpu = (long)hcpu; + + switch (action & ~CPU_TASKS_FROZEN) { + case CPU_DEAD: + per_cpu(fpsimd_last_state, cpu) = NULL; + break; + default: + 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. */ @@ -315,6 +346,7 @@ static int __init fpsimd_init(void) elf_hwcap |= HWCAP_ASIMD; fpsimd_pm_init(); + fpsimd_hotplug_init(); return 0; } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/