mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-04-20 13:24:00 +00:00
MIPS: kernel: signal: Prevent save/restore FPU context in user memory
EVA does not have FPU specific instructions for reading or writing FPU registers from userspace memory. Signed-off-by: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com> Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
This commit is contained in:
parent
c2d85bc104
commit
ca750649e0
1 changed files with 32 additions and 0 deletions
|
@ -6,6 +6,7 @@
|
||||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||||
* Copyright (C) 1994 - 2000 Ralf Baechle
|
* Copyright (C) 1994 - 2000 Ralf Baechle
|
||||||
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
|
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
|
||||||
|
* Copyright (C) 2014, Imagination Technologies Ltd.
|
||||||
*/
|
*/
|
||||||
#include <linux/cache.h>
|
#include <linux/cache.h>
|
||||||
#include <linux/context_tracking.h>
|
#include <linux/context_tracking.h>
|
||||||
|
@ -140,6 +141,7 @@ static int protected_save_fp_context(struct sigcontext __user *sc,
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
bool save_msa = cpu_has_msa && (used_math & USEDMATH_MSA);
|
bool save_msa = cpu_has_msa && (used_math & USEDMATH_MSA);
|
||||||
|
#ifndef CONFIG_EVA
|
||||||
while (1) {
|
while (1) {
|
||||||
lock_fpu_owner();
|
lock_fpu_owner();
|
||||||
if (is_fpu_owner()) {
|
if (is_fpu_owner()) {
|
||||||
|
@ -162,6 +164,17 @@ static int protected_save_fp_context(struct sigcontext __user *sc,
|
||||||
if (err)
|
if (err)
|
||||||
break; /* really bad sigcontext */
|
break; /* really bad sigcontext */
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
* EVA does not have FPU EVA instructions so saving fpu context directly
|
||||||
|
* does not work.
|
||||||
|
*/
|
||||||
|
disable_msa();
|
||||||
|
lose_fpu(1);
|
||||||
|
err = save_fp_context(sc); /* this might fail */
|
||||||
|
if (save_msa && !err)
|
||||||
|
err = copy_msa_to_sigcontext(sc);
|
||||||
|
#endif
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,6 +183,7 @@ static int protected_restore_fp_context(struct sigcontext __user *sc,
|
||||||
{
|
{
|
||||||
int err, tmp __maybe_unused;
|
int err, tmp __maybe_unused;
|
||||||
bool restore_msa = cpu_has_msa && (used_math & USEDMATH_MSA);
|
bool restore_msa = cpu_has_msa && (used_math & USEDMATH_MSA);
|
||||||
|
#ifndef CONFIG_EVA
|
||||||
while (1) {
|
while (1) {
|
||||||
lock_fpu_owner();
|
lock_fpu_owner();
|
||||||
if (is_fpu_owner()) {
|
if (is_fpu_owner()) {
|
||||||
|
@ -197,6 +211,17 @@ static int protected_restore_fp_context(struct sigcontext __user *sc,
|
||||||
if (err)
|
if (err)
|
||||||
break; /* really bad sigcontext */
|
break; /* really bad sigcontext */
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
* EVA does not have FPU EVA instructions so restoring fpu context
|
||||||
|
* directly does not work.
|
||||||
|
*/
|
||||||
|
enable_msa();
|
||||||
|
lose_fpu(0);
|
||||||
|
err = restore_fp_context(sc); /* this might fail */
|
||||||
|
if (restore_msa && !err)
|
||||||
|
err = copy_msa_from_sigcontext(sc);
|
||||||
|
#endif
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -685,6 +710,7 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused,
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
|
#ifndef CONFIG_EVA
|
||||||
static int smp_save_fp_context(struct sigcontext __user *sc)
|
static int smp_save_fp_context(struct sigcontext __user *sc)
|
||||||
{
|
{
|
||||||
return raw_cpu_has_fpu
|
return raw_cpu_has_fpu
|
||||||
|
@ -698,10 +724,12 @@ static int smp_restore_fp_context(struct sigcontext __user *sc)
|
||||||
? _restore_fp_context(sc)
|
? _restore_fp_context(sc)
|
||||||
: copy_fp_from_sigcontext(sc);
|
: copy_fp_from_sigcontext(sc);
|
||||||
}
|
}
|
||||||
|
#endif /* CONFIG_EVA */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int signal_setup(void)
|
static int signal_setup(void)
|
||||||
{
|
{
|
||||||
|
#ifndef CONFIG_EVA
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
/* For now just do the cpu_has_fpu check when the functions are invoked */
|
/* For now just do the cpu_has_fpu check when the functions are invoked */
|
||||||
save_fp_context = smp_save_fp_context;
|
save_fp_context = smp_save_fp_context;
|
||||||
|
@ -714,6 +742,10 @@ static int signal_setup(void)
|
||||||
save_fp_context = copy_fp_from_sigcontext;
|
save_fp_context = copy_fp_from_sigcontext;
|
||||||
restore_fp_context = copy_fp_to_sigcontext;
|
restore_fp_context = copy_fp_to_sigcontext;
|
||||||
}
|
}
|
||||||
|
#endif /* CONFIG_SMP */
|
||||||
|
#else
|
||||||
|
save_fp_context = copy_fp_from_sigcontext;;
|
||||||
|
restore_fp_context = copy_fp_to_sigcontext;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Add table
Reference in a new issue