From: Leonid Yegoshin <Leonid.Yegoshin@xxxxxxxxxx> EVA does not have FPU specific instructions for reading or writing FPU registers from userspace memory. Signed-off-by: Leonid Yegoshin <Leonid.Yegoshin@xxxxxxxxxx> Signed-off-by: Markos Chandras <markos.chandras@xxxxxxxxxx> --- arch/mips/kernel/signal.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index 5199563..6f4937b 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c @@ -6,6 +6,7 @@ * Copyright (C) 1991, 1992 Linus Torvalds * Copyright (C) 1994 - 2000 Ralf Baechle * Copyright (C) 1999, 2000 Silicon Graphics, Inc. + * Copyright (C) 2014, Imagination Technologies Ltd. */ #include <linux/cache.h> #include <linux/context_tracking.h> @@ -69,6 +70,7 @@ struct rt_sigframe { static int protected_save_fp_context(struct sigcontext __user *sc) { int err; +#ifndef CONFIG_EVA while (1) { lock_fpu_owner(); err = own_fpu_inatomic(1); @@ -84,12 +86,21 @@ static int protected_save_fp_context(struct sigcontext __user *sc) if (err) break; /* really bad sigcontext */ } +#else + /* + * EVA does not have FPU EVA instructions so saving fpu context directly + * does not work. + */ + lose_fpu(1); + err = save_fp_context(sc); /* this might fail */ +#endif return err; } static int protected_restore_fp_context(struct sigcontext __user *sc) { int err, tmp __maybe_unused; +#ifndef CONFIG_EVA while (1) { lock_fpu_owner(); err = own_fpu_inatomic(0); @@ -105,6 +116,14 @@ static int protected_restore_fp_context(struct sigcontext __user *sc) if (err) break; /* really bad sigcontext */ } +#else + /* + * EVA does not have FPU EVA instructions so restoring fpu context + * directly does not work. + */ + lose_fpu(0); + err = restore_fp_context(sc); /* this might fail */ +#endif return err; } @@ -591,6 +610,7 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused, } #ifdef CONFIG_SMP +#ifndef CONFIG_EVA static int smp_save_fp_context(struct sigcontext __user *sc) { return raw_cpu_has_fpu @@ -604,10 +624,12 @@ static int smp_restore_fp_context(struct sigcontext __user *sc) ? _restore_fp_context(sc) : fpu_emulator_restore_context(sc); } +#endif /* CONFIG_EVA */ #endif static int signal_setup(void) { +#ifndef CONFIG_EVA #ifdef CONFIG_SMP /* For now just do the cpu_has_fpu check when the functions are invoked */ save_fp_context = smp_save_fp_context; @@ -620,6 +642,10 @@ static int signal_setup(void) save_fp_context = fpu_emulator_save_context; restore_fp_context = fpu_emulator_restore_context; } +#endif /* CONFIG_SMP */ +#else + save_fp_context = fpu_emulator_save_context; + restore_fp_context = fpu_emulator_restore_context; #endif return 0; -- 1.8.5.3