Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fd3c3ed5 authored by Suresh Siddha's avatar Suresh Siddha Committed by Thomas Gleixner
Browse files

x86: fix fpu restore from sig return



If the task never used fpu, initialize the fpu before restoring the FP
state from the signal handler context. This will allocate the fpu
state, if the task never needed it before.

Reported-and-bisected-by: default avatarEric Sesterhenn <snakebyte@gmx.de>
Signed-off-by: default avatarSuresh Siddha <suresh.b.siddha@intel.com>
Tested-by: default avatarEric Sesterhenn <snakebyte@gmx.de>
Cc: Frederik Deweerdt <deweerdt@free.fr>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent 06461539
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -450,7 +450,6 @@ static inline int restore_i387_fsave(struct _fpstate_ia32 __user *buf)
{
	struct task_struct *tsk = current;

	clear_fpu(tsk);
	return __copy_from_user(&tsk->thread.xstate->fsave, buf,
				sizeof(struct i387_fsave_struct));
}
@@ -461,7 +460,6 @@ static int restore_i387_fxsave(struct _fpstate_ia32 __user *buf)
	struct user_i387_ia32_struct env;
	int err;

	clear_fpu(tsk);
	err = __copy_from_user(&tsk->thread.xstate->fxsave, &buf->_fxsr_env[0],
			       sizeof(struct i387_fxsave_struct));
	/* mxcsr reserved bits must be masked to zero for security reasons */
@@ -478,6 +476,16 @@ int restore_i387_ia32(struct _fpstate_ia32 __user *buf)
	int err;

	if (HAVE_HWFP) {
		struct task_struct *tsk = current;

		clear_fpu(tsk);

		if (!used_math()) {
			err = init_fpu(tsk);
			if (err)
				return err;
		}

		if (cpu_has_fxsr)
			err = restore_i387_fxsave(buf);
		else
+9 −1
Original line number Diff line number Diff line
@@ -175,7 +175,15 @@ static inline int save_i387(struct _fpstate __user *buf)
 */
static inline int restore_i387(struct _fpstate __user *buf)
{
	set_used_math();
	struct task_struct *tsk = current;
	int err;

	if (!used_math()) {
		err = init_fpu(tsk);
		if (err)
			return err;
	}

	if (!(task_thread_info(current)->status & TS_USEDFPU)) {
		clts();
		task_thread_info(current)->status |= TS_USEDFPU;