From: Oleg Nesterov <oleg@redhat.com>
To: Al Viro <viro@ZenIV.linux.org.uk>,
Andrew Morton <akpm@linux-foundation.org>,
Fenghua Yu <fenghua.yu@intel.com>,
Linus Torvalds <torvalds@linux-foundation.org>,
Suresh Siddha <suresh.b.siddha@intel.com>
Cc: Bean Anderson <bean@azulsystems.com>,
"H. Peter Anvin" <hpa@zytor.com>, Ingo Molnar <mingo@redhat.com>,
Thomas Gleixner <tglx@linutronix.de>,
x86@kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH 2/5] x86, fpu: don't drop_fpu() in __restore_xstate_sig() if use_eager_fpu()
Date: Sun, 24 Aug 2014 21:47:36 +0200 [thread overview]
Message-ID: <20140824194736.GA27441@redhat.com> (raw)
In-Reply-To: <20140824194700.GA27281@redhat.com>
__restore_xstate_sig() calls math_state_restore() with preemption
enabled, not good. But this is minor, the main problem is that this
drop_fpu/set_used_math/math_state_restore sequence creates the nasty
"use_eager_fpu() && !used_math()" special case which complicates other
FPU paths.
Change __restore_xstate_sig() to switch to swapper's fpu state, copy
the user state to the thread's fpu state, and switch fpu->state back
after sanitize_restored_xstate().
Without use_eager_fpu() fpu->state is null in between but this is fine
because in this case we rely on clear_used_math()/set_used_math(), so
this doesn't differ from !fpu_allocated() case.
Note: with or without this patch, perhaps it makes sense to send SEGV
if __copy_from_user() fails.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
arch/x86/kernel/xsave.c | 36 ++++++++++++++++++++++--------------
1 files changed, 22 insertions(+), 14 deletions(-)
diff --git a/arch/x86/kernel/xsave.c b/arch/x86/kernel/xsave.c
index 74d4129..51be404 100644
--- a/arch/x86/kernel/xsave.c
+++ b/arch/x86/kernel/xsave.c
@@ -325,6 +325,22 @@ static inline int restore_user_xstate(void __user *buf, u64 xbv, int fx_only)
return frstor_user(buf);
}
+static void switch_fpu_xstate(struct task_struct *tsk, union thread_xstate *xstate)
+{
+ preempt_disable();
+ __drop_fpu(tsk);
+ tsk->thread.fpu_counter = 0;
+ tsk->thread.fpu.state = xstate;
+ /* use_eager_fpu() => xstate != NULL */
+ if (use_eager_fpu())
+ math_state_restore();
+ else if (xstate)
+ set_used_math();
+ else
+ clear_used_math();
+ preempt_enable();
+}
+
int __restore_xstate_sig(void __user *buf, void __user *buf_fx, int size)
{
int ia32_fxstate = (buf != buf_fx);
@@ -377,28 +393,20 @@ int __restore_xstate_sig(void __user *buf, void __user *buf_fx, int size)
union thread_xstate *xstate = tsk->thread.fpu.state;
struct user_i387_ia32_struct env;
int err = 0;
-
/*
- * Drop the current fpu which clears used_math(). This ensures
- * that any context-switch during the copy of the new state,
- * avoids the intermediate state from getting restored/saved.
- * Thus avoiding the new restored state from getting corrupted.
- * We will be ready to restore/save the state only after
- * set_used_math() is again set.
+ * Ensure that that any context-switch during the copy of
+ * the new state, avoids the intermediate state from getting
+ * restored/saved.
*/
- drop_fpu(tsk);
-
+ switch_fpu_xstate(tsk, init_task.thread.fpu.state);
if (__copy_from_user(&xstate->xsave, buf_fx, state_size) ||
__copy_from_user(&env, buf, sizeof(env))) {
+ fpu_finit(&tsk->thread.fpu);
err = -1;
} else {
sanitize_restored_xstate(xstate, &env, xstate_bv, fx_only);
- set_used_math();
}
-
- if (use_eager_fpu())
- math_state_restore();
-
+ switch_fpu_xstate(tsk, xstate);
return err;
} else {
/*
--
1.5.5.1
next prev parent reply other threads:[~2014-08-24 19:50 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-08-22 17:11 [PATCH 0/1] x86, fpu: shift drop_init_fpu() from save_xstate_sig() to handle_signal() Oleg Nesterov
2014-08-22 17:12 ` [PATCH 1/1] " Oleg Nesterov
2014-08-24 19:47 ` [PATCH 0/5] x86, fpu: make use_eager_fpu() more eager Oleg Nesterov
2014-08-24 19:47 ` [PATCH 1/5] x86, fpu: change sanitize_restored_xstate() and convert_to_fxsr() to accept thread_xstate Oleg Nesterov
2014-08-24 19:47 ` Oleg Nesterov [this message]
2014-08-24 20:05 ` [PATCH 2/5] x86, fpu: don't drop_fpu() in __restore_xstate_sig() if use_eager_fpu() Linus Torvalds
2014-08-25 14:26 ` Oleg Nesterov
2014-08-25 14:41 ` Oleg Nesterov
2014-08-25 16:27 ` Linus Torvalds
2014-08-25 17:09 ` Oleg Nesterov
2014-08-25 17:26 ` Linus Torvalds
2014-08-25 17:39 ` Oleg Nesterov
2014-08-27 17:02 ` Oleg Nesterov
2014-08-24 19:47 ` [PATCH 3/5] x86, fpu: don't drop_fpu() in exit_thread() " Oleg Nesterov
2014-08-24 19:47 ` [PATCH 4/5] x86, fpu: shift init_fpu() from eager_fpu_init() to eager_fpu_init_bp() Oleg Nesterov
2014-08-24 19:47 ` [PATCH 5/5] x86, fpu: sanitize the usage of use_eager_fpu() in switch_fpu_prepare() Oleg Nesterov
2014-08-25 18:08 ` [PATCH] x86, fpu: __restore_xstate_sig()->math_state_restore() needs preempt_disable() Oleg Nesterov
2014-09-02 5:01 ` Suresh Siddha
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140824194736.GA27441@redhat.com \
--to=oleg@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=bean@azulsystems.com \
--cc=fenghua.yu@intel.com \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=suresh.b.siddha@intel.com \
--cc=tglx@linutronix.de \
--cc=torvalds@linux-foundation.org \
--cc=viro@ZenIV.linux.org.uk \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.