From: Thomas Gleixner <tglx@linutronix.de>
To: LKML <linux-kernel@vger.kernel.org>
Cc: x86@kernel.org, Andy Lutomirski <luto@kernel.org>,
Dave Hansen <dave.hansen@linux.intel.com>,
Fenghua Yu <fenghua.yu@intel.com>,
Tony Luck <tony.luck@intel.com>,
Yu-cheng Yu <yu-cheng.yu@intel.com>
Subject: [patch 7/8] x86/fpu: Clean up the fpu__clear() variants
Date: Wed, 02 Jun 2021 11:55:50 +0200 [thread overview]
Message-ID: <20210602101619.066082349@linutronix.de> (raw)
In-Reply-To: <20210602095543.149814064@linutronix.de>
From: Andy Lutomirski <luto@kernel.org>
fpu__clear() currently resets both register state and kernel XSAVE buffer
state. It has two modes: one for all state (supervisor and user) and
another for user state only. fpu__clear_all() uses the "all state"
(user_only=0) mode, while a number of signal paths use the user_only=1
mode.
Make fpu__clear() work only for user state (user_only=1) and remove the
"all state" (user_only=0) code. Rename it to match so it can be used by
the signal paths.
Replace the "all state" (user_only=0) fpu__clear() functionality. Use the
TIF_NEED_FPU_LOAD functionality instead of making any actual hardware
registers changes in this path.
[ Changelog polished by Dave Hansen ]
Signed-off-by: Andy Lutomirski <luto@kernel.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/kernel/fpu/core.c | 62 ++++++++++++++++++++++++++++++---------------
1 file changed, 42 insertions(+), 20 deletions(-)
--- a/arch/x86/kernel/fpu/core.c
+++ b/arch/x86/kernel/fpu/core.c
@@ -354,45 +354,67 @@ static inline void copy_init_fpstate_to_
}
/*
- * Clear the FPU state back to init state.
- *
- * Called by sys_execve(), by the signal handler code and by various
- * error paths.
+ * Reset current's user FPU states to the init states. current's
+ * supervisor states, if any, are not modified by this function. The
+ * caller guarantees that the XSTATE header in memory is intact.
*/
-static void fpu__clear(struct fpu *fpu, bool user_only)
+void fpu__clear_user_states(struct fpu *fpu)
{
WARN_ON_FPU(fpu != ¤t->thread.fpu);
if (!static_cpu_has(X86_FEATURE_FPU)) {
- fpu__drop(fpu);
- fpu__initialize(fpu);
+ fpu__clear_all(fpu);
return;
}
fpregs_lock();
- if (user_only) {
- if (!fpregs_state_valid(fpu, smp_processor_id()) &&
- xfeatures_mask_supervisor())
- copy_kernel_to_xregs(&fpu->state.xsave,
- xfeatures_mask_supervisor());
- copy_init_fpstate_to_fpregs(xfeatures_mask_user());
- } else {
- copy_init_fpstate_to_fpregs(xfeatures_mask_all);
+ /*
+ * Ensure that current's supervisor states are loaded into
+ * their corresponding registers.
+ */
+ if (xfeatures_mask_supervisor() &&
+ !fpregs_state_valid(fpu, smp_processor_id())) {
+ copy_kernel_to_xregs(&fpu->state.xsave,
+ xfeatures_mask_supervisor());
}
+ /* Reset user states in registers. */
+ copy_init_fpstate_to_fpregs(xfeatures_mask_user());
+
+ /*
+ * Now all FPU registers have their desired values. Inform the
+ * FPU state machine that current's FPU registers are in the
+ * hardware registers.
+ */
fpregs_mark_activate();
+
fpregs_unlock();
}
-void fpu__clear_user_states(struct fpu *fpu)
-{
- fpu__clear(fpu, true);
-}
+/*
+ * Reset current's FPU registers (user and supervisor) to their INIT values.
+ * This is used by execve(); out of an abundance of caution, it completely
+ * wipes and resets the XSTATE buffer in memory.
+ *
+ * Note that XSAVE (unlike XSAVES) expects the XSTATE buffer in memory to
+ * be valid, so there are certain forms of corruption of the XSTATE buffer
+ * in memory that would survive initializing the FPU registers and XSAVEing
+ * them to memory.
+ */
void fpu__clear_all(struct fpu *fpu)
{
- fpu__clear(fpu, false);
+ fpregs_lock();
+ fpu__drop(fpu);
+ /*
+ * This does not change the actual hardware registers; when
+ * fpu__clear_all() returns, TIF_NEED_FPU_LOAD will be set, and a
+ * subsequent exit to user mode will reload the hardware registers
+ * from memory.
+ */
+ fpu__initialize(fpu);
+ fpregs_unlock();
}
/*
next prev parent reply other threads:[~2021-06-02 10:19 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-06-02 9:55 [patch 0/8] x86/fpu: Mop up XSAVES and related damage Thomas Gleixner
2021-06-02 9:55 ` [patch 1/8] selftests/x86: Test signal frame XSTATE header corruption handling Thomas Gleixner
2021-06-02 12:38 ` Borislav Petkov
2021-06-02 14:15 ` Thomas Gleixner
2021-06-03 13:16 ` Shuah Khan
2021-06-02 15:59 ` [patch V2 " Thomas Gleixner
2021-06-02 16:02 ` [patch V2a " Thomas Gleixner
2021-06-02 9:55 ` [patch 2/8] x86/fpu: Prevent state corruption in __fpu__restore_sig() Thomas Gleixner
2021-06-02 13:12 ` Borislav Petkov
2021-06-02 14:46 ` Thomas Gleixner
2021-06-02 15:58 ` [patch V2 " Thomas Gleixner
2021-06-02 9:55 ` [patch 3/8] x86/fpu: Invalidate FPU state after a failed XRSTOR from a user buffer Thomas Gleixner
2021-06-02 15:06 ` Borislav Petkov
2021-06-03 17:30 ` Andy Lutomirski
2021-06-03 19:28 ` Borislav Petkov
2021-06-02 9:55 ` [patch 4/8] x86/fpu: Limit xstate copy size in xstateregs_set() Thomas Gleixner
2021-06-02 17:44 ` Borislav Petkov
2021-06-02 9:55 ` [patch 5/8] x86/fpu: Sanitize xstateregs_set() Thomas Gleixner
2021-06-02 16:01 ` [patch V2 " Thomas Gleixner
2021-06-03 11:32 ` Borislav Petkov
2021-06-03 17:24 ` [patch " Andy Lutomirski
2021-06-02 9:55 ` [patch 6/8] x86/fpu: Add address range checks to copy_user_to_xstate() Thomas Gleixner
2021-06-02 9:55 ` Thomas Gleixner [this message]
2021-06-02 9:55 ` [patch 8/8] x86/fpu: Deduplicate copy_xxx_to_xstate() Thomas Gleixner
2021-06-03 16:56 ` Andy Lutomirski
2021-06-02 21:28 ` [patch 0/8] x86/fpu: Mop up XSAVES and related damage Yu, Yu-cheng
2021-06-04 14:05 ` Thomas Gleixner
2021-06-04 16:27 ` Yu, Yu-cheng
2021-06-04 17:46 ` Dave Hansen
2021-06-04 18:14 ` Thomas Gleixner
2021-06-04 22:04 ` Dave Hansen
2021-06-05 10:18 ` Thomas Gleixner
2021-06-05 11:56 ` Thomas Gleixner
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=20210602101619.066082349@linutronix.de \
--to=tglx@linutronix.de \
--cc=dave.hansen@linux.intel.com \
--cc=fenghua.yu@intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=luto@kernel.org \
--cc=tony.luck@intel.com \
--cc=x86@kernel.org \
--cc=yu-cheng.yu@intel.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome