linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Thomas Gleixner <tglx@linutronix.de>
To: LKML <linux-kernel@vger.kernel.org>
Cc: 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>,
	Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
	Borislav Petkov <bp@suse.de>,
	Peter Zijlstra <peterz@infradead.org>,
	Kan Liang <kan.liang@linux.intel.com>
Subject: [patch V3 47/66] x86/fpu: Clean up the fpu__clear() variants
Date: Fri, 18 Jun 2021 16:19:10 +0200	[thread overview]
Message-ID: <20210618143449.733176003@linutronix.de> (raw)
In-Reply-To: 20210618141823.161158090@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.

Instead of invoking fpu__initialize() just memcpy() init_fpstate into the
tasks FPU state because that has already the correct format and in case of
PKRU also contains the default PKRU value. Move the actual PKRU write out
into flush_thread() where it belongs and where it will end up anyway when
PKRU and XSTATE have been distangled.

For bisectability a workaround is required which stores the PKRU value in
the xstate memory until PKRU is distangled from XSTATE for context
switching and return to user.

[ Dave Hansen: Polished changelog ]
[ tglx: Fixed the PKRU fallout ]

Signed-off-by: Andy Lutomirski <luto@kernel.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/kernel/fpu/core.c |  111 ++++++++++++++++++++++++++++++---------------
 arch/x86/kernel/process.c  |   10 ++++
 2 files changed, 85 insertions(+), 36 deletions(-)

--- a/arch/x86/kernel/fpu/core.c
+++ b/arch/x86/kernel/fpu/core.c
@@ -260,19 +260,6 @@ int fpu_clone(struct task_struct *dst)
 }
 
 /*
- * Activate the current task's in-memory FPU context,
- * if it has not been used before:
- */
-static void fpu__initialize(struct fpu *fpu)
-{
-	WARN_ON_FPU(fpu != &current->thread.fpu);
-
-	set_thread_flag(TIF_NEED_FPU_LOAD);
-	fpstate_init(&fpu->state);
-	trace_x86_fpu_init_state(fpu);
-}
-
-/*
  * Drops current FPU state: deactivates the fpregs and
  * the fpstate. NOTE: it still leaves previous contents
  * in the fpregs in the eager-FPU case.
@@ -314,47 +301,99 @@ static inline void load_fpregs_from_init
 	pkru_write_default();
 }
 
+static inline unsigned int init_fpstate_copy_size(void)
+{
+	if (!use_xsave())
+		return fpu_kernel_xstate_size;
+
+	/* XSAVE(S) just needs the legacy and the xstate header part */
+	return sizeof(init_fpstate.xsave);
+}
+
+/* Temporary workaround. Will be removed once PKRU and XSTATE are distangled. */
+static inline void pkru_set_default_in_xstate(struct xregs_state *xsave)
+{
+	struct pkru_state *pk;
+
+	if (!cpu_feature_enabled(X86_FEATURE_OSPKE))
+		return;
+	/*
+	 * Force XFEATURE_PKRU to be set in the header otherwise
+	 * get_xsave_addr() does not work and it also needs to be set to
+	 * make XRSTOR(S) load it.
+	 */
+	xsave->header.xfeatures |= XFEATURE_MASK_PKRU;
+	pk = get_xsave_addr(xsave, XFEATURE_PKRU);
+	pk->pkru = pkru_get_init_value();
+}
+
 /*
- * Clear the FPU state back to init state.
- *
- * Called by sys_execve(), by the signal handler code and by various
- * error paths.
+ * Reset current->fpu memory state to the init values.
  */
-static void fpu__clear(struct fpu *fpu, bool user_only)
+static void fpu_reset_fpstate(void)
+{
+	struct fpu *fpu= &current->thread.fpu;
+
+	fpregs_lock();
+	fpu__drop(fpu);
+	/*
+	 * This does not change the actual hardware registers. It just
+	 * resets the memory image and sets TIF_NEED_FPU_LOAD so a
+	 * subsequent return to usermode will reload the registers from the
+	 * tasks memory image.
+	 *
+	 * Do not use fpstate_init() here. Just copy init_fpstate which has
+	 * the correct content already except for PKRU.
+	 */
+	memcpy(&fpu->state, &init_fpstate, init_fpstate_copy_size());
+	pkru_set_default_in_xstate(&fpu->state.xsave);
+	set_thread_flag(TIF_NEED_FPU_LOAD);
+	fpregs_unlock();
+}
+
+/*
+ * 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.
+ */
+void fpu__clear_user_states(struct fpu *fpu)
 {
 	WARN_ON_FPU(fpu != &current->thread.fpu);
 
+	fpregs_lock();
 	if (!static_cpu_has(X86_FEATURE_FPU)) {
-		fpu__drop(fpu);
-		fpu__initialize(fpu);
+		fpu_reset_fpstate();
+		fpregs_unlock();
 		return;
 	}
 
-	fpregs_lock();
-
-	if (user_only) {
-		if (!fpregs_state_valid(fpu, smp_processor_id()) &&
-		    xfeatures_mask_supervisor())
-			os_xrstor(&fpu->state.xsave, xfeatures_mask_supervisor());
-		load_fpregs_from_init_fpstate(xfeatures_mask_user());
-	} else {
-		load_fpregs_from_init_fpstate(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())) {
+		os_xrstor(&fpu->state.xsave, xfeatures_mask_supervisor());
 	}
 
+	/* Reset user states in registers. */
+	load_fpregs_from_init_fpstate(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. The memory image does not need to be updated because
+	 * any operation relying on it has to save the registers first when
+	 * currents FPU is marked active.
+	 */
 	fpregs_mark_activate();
 	fpregs_unlock();
 }
 
-void fpu__clear_user_states(struct fpu *fpu)
-{
-	fpu__clear(fpu, true);
-}
-
 void fpu_flush_thread(void)
 {
-	fpu__clear(&current->thread.fpu, false);
+	fpu_reset_fpstate();
 }
-
 /*
  * Load FPU context before returning to userspace.
  */
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -198,6 +198,15 @@ int copy_thread(unsigned long clone_flag
 	return ret;
 }
 
+static void pkru_flush_thread(void)
+{
+	/*
+	 * If PKRU is enabled the default PKRU value has to be loaded into
+	 * the hardware right here (similar to context switch).
+	 */
+	pkru_write_default();
+}
+
 void flush_thread(void)
 {
 	struct task_struct *tsk = current;
@@ -206,6 +215,7 @@ void flush_thread(void)
 	memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
 
 	fpu_flush_thread();
+	pkru_flush_thread();
 }
 
 void disable_TSC(void)


  parent reply	other threads:[~2021-06-18 15:26 UTC|newest]

Thread overview: 133+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-18 14:18 [patch V3 00/66] x86/fpu: Spring cleaning and PKRU sanitizing Thomas Gleixner
2021-06-18 14:18 ` [patch V3 01/66] x86/fpu: x86/fpu: Preserve supervisor states in sanitize_restored_user_xstate() Thomas Gleixner
2021-06-19  8:34   ` Borislav Petkov
2021-06-22 11:45   ` [tip: x86/urgent] " tip-bot2 for Thomas Gleixner
2021-06-18 14:18 ` [patch V3 02/66] x86/fpu: Make init_fpstate correct with optimized XSAVE Thomas Gleixner
2021-06-18 20:41   ` Thomas Gleixner
2021-06-18 20:44     ` Borislav Petkov
2021-06-22 11:45   ` [tip: x86/urgent] " tip-bot2 for Thomas Gleixner
2021-06-18 14:18 ` [patch V3 03/66] x86/fpu: Fix copy_xstate_to_kernel() gap handling Thomas Gleixner
2021-06-19  9:41   ` Borislav Petkov
2021-06-18 14:18 ` [patch V3 04/66] x86/pkeys: Revert a5eff7259790 ("x86/pkeys: Add PKRU value to init_fpstate") Thomas Gleixner
2021-06-18 14:18 ` [patch V3 05/66] x86/fpu: Mark various FPU states __ro_after_init Thomas Gleixner
2021-06-18 14:18 ` [patch V3 06/66] x86/fpu: Make xfeatures_mask_all __ro_after_init Thomas Gleixner
2021-06-20  8:44   ` Borislav Petkov
2021-06-18 14:18 ` [patch V3 07/66] x86/fpu: Get rid of fpu__get_supported_xfeatures_mask() Thomas Gleixner
2021-06-20  9:02   ` Borislav Petkov
2021-06-18 14:18 ` [patch V3 08/66] x86/fpu: Remove unused get_xsave_field_ptr() Thomas Gleixner
2021-06-18 14:18 ` [patch V3 09/66] x86/fpu: Move inlines where they belong Thomas Gleixner
2021-06-18 14:18 ` [patch V3 10/66] x86/fpu: Limit xstate copy size in xstateregs_set() Thomas Gleixner
2021-06-18 14:18 ` [patch V3 11/66] x86/fpu: Sanitize xstateregs_set() Thomas Gleixner
2021-06-20 21:30   ` Borislav Petkov
2021-06-18 14:18 ` [patch V3 12/66] x86/fpu: Reject invalid MXCSR values in copy_kernel_to_xstate() Thomas Gleixner
2021-06-21 10:00   ` Borislav Petkov
2021-06-18 14:18 ` [patch V3 13/66] x86/fpu: Simplify PTRACE_GETREGS code Thomas Gleixner
2021-06-18 14:18 ` [patch V3 14/66] x86/fpu: Rewrite xfpregs_set() Thomas Gleixner
2021-06-21 10:20   ` Borislav Petkov
2021-06-18 14:18 ` [patch V3 15/66] x86/fpu: Fail ptrace() requests that try to set invalid MXCSR values Thomas Gleixner
2021-06-21 10:17   ` Thomas Gleixner
2021-06-18 14:18 ` [patch V3 16/66] x86/fpu: Clean up fpregs_set() Thomas Gleixner
2021-06-21 12:05   ` Borislav Petkov
2021-06-18 14:18 ` [patch V3 17/66] x86/fpu: Make copy_xstate_to_kernel() usable for [x]fpregs_get() Thomas Gleixner
2021-06-21 12:32   ` Borislav Petkov
2021-06-18 14:18 ` [patch V3 18/66] x86/fpu: Use copy_xstate_to_uabi_buf() in xfpregs_get() Thomas Gleixner
2021-06-18 14:18 ` [patch V3 19/66] x86/fpu: Use copy_xstate_to_uabi_buf() in fpregs_get() Thomas Gleixner
2021-06-18 14:18 ` [patch V3 20/66] x86/fpu: Remove fpstate_sanitize_xstate() Thomas Gleixner
2021-06-18 14:18 ` [patch V3 21/66] x86/fpu/regset: Move fpu__read_begin() into regset Thomas Gleixner
2021-06-21 13:26   ` Borislav Petkov
2021-06-18 14:18 ` [patch V3 22/66] x86/fpu: Move fpu__write_begin() to regset Thomas Gleixner
2021-06-21 15:30   ` Borislav Petkov
2021-06-21 20:15     ` Thomas Gleixner
2021-06-18 14:18 ` [patch V3 23/66] x86/fpu: Get rid of using_compacted_format() Thomas Gleixner
2021-06-18 14:18 ` [patch V3 24/66] x86/kvm: Avoid looking up PKRU in XSAVE buffer Thomas Gleixner
2021-06-18 14:18 ` [patch V3 25/66] x86/fpu: Cleanup arch_set_user_pkey_access() Thomas Gleixner
2021-06-18 14:18 ` [patch V3 26/66] x86/fpu: Get rid of copy_supervisor_to_kernel() Thomas Gleixner
2021-06-18 14:18 ` [patch V3 27/66] x86/fpu: Rename copy_xregs_to_kernel() and copy_kernel_to_xregs() Thomas Gleixner
2021-06-21 18:00   ` Borislav Petkov
2021-06-18 14:18 ` [patch V3 28/66] x86/fpu: Rename copy_user_to_xregs() and copy_xregs_to_user() Thomas Gleixner
2021-06-21 19:44   ` Borislav Petkov
2021-06-18 14:18 ` [patch V3 29/66] x86/fpu: Rename fxregs related copy functions Thomas Gleixner
2021-06-21 23:00   ` Borislav Petkov
2021-06-18 14:18 ` [patch V3 30/66] x86/fpu: Rename fregs " Thomas Gleixner
2021-06-22  9:31   ` Borislav Petkov
2021-06-18 14:18 ` [patch V3 31/66] x86/fpu: Rename xstate copy functions which are related to UABI Thomas Gleixner
2021-06-22  9:38   ` Borislav Petkov
2021-06-18 14:18 ` [patch V3 32/66] x86/fpu: Deduplicate copy_uabi_from_user/kernel_to_xstate() Thomas Gleixner
2021-06-22 10:09   ` Borislav Petkov
2021-06-18 14:18 ` [patch V3 33/66] x86/fpu: Rename copy_fpregs_to_fpstate() to save_fpregs_to_fpstate() Thomas Gleixner
2021-06-22 10:16   ` Borislav Petkov
2021-06-18 14:18 ` [patch V3 34/66] x86/fpu: Get rid of the FNSAVE optimization Thomas Gleixner
2021-06-22 10:36   ` Borislav Petkov
2021-06-18 14:18 ` [patch V3 35/66] x86/fpu: Rename copy_kernel_to_fpregs() to restore_fpregs_from_kernel() Thomas Gleixner
2021-06-22 10:46   ` Borislav Petkov
2021-06-18 14:18 ` [patch V3 36/66] x86/fpu: Rename initstate copy functions Thomas Gleixner
2021-06-22 10:48   ` Borislav Petkov
2021-06-18 14:19 ` [patch V3 37/66] x86/fpu: Rename "dynamic" XSTATEs to "independent" Thomas Gleixner
2021-06-22 11:05   ` Borislav Petkov
2021-06-18 14:19 ` [patch V3 38/66] x86/fpu/xstate: Sanitize handling of independent features Thomas Gleixner
2021-06-21 20:42   ` Liang, Kan
2021-06-22 11:32   ` Borislav Petkov
2021-06-18 14:19 ` [patch V3 39/66] x86/pkeys: Move read_pkru() and write_pkru() Thomas Gleixner
2021-06-18 14:19 ` [patch V3 40/66] x86/fpu: Rename and sanitize fpu__save/copy() Thomas Gleixner
2021-06-22 13:51   ` Borislav Petkov
2021-06-18 14:19 ` [patch V3 41/66] x86/cpu: Sanitize X86_FEATURE_OSPKE Thomas Gleixner
2021-06-22 14:15   ` Borislav Petkov
2021-06-18 14:19 ` [patch V3 42/66] x86/pkru: Provide pkru_get_init_value() Thomas Gleixner
2021-06-18 14:19 ` [patch V3 43/66] x86/pkru: Provide pkru_write_default() Thomas Gleixner
2021-06-22 14:30   ` Borislav Petkov
2021-06-18 14:19 ` [patch V3 44/66] x86/cpu: Write the default PKRU value when enabling PKE Thomas Gleixner
2021-06-18 14:19 ` [patch V3 45/66] x86/fpu: Use pkru_write_default() in copy_init_fpstate_to_fpregs() Thomas Gleixner
2021-06-18 14:19 ` [patch V3 46/66] x86/fpu: Rename fpu__clear_all() to fpu_flush_thread() Thomas Gleixner
2021-06-22 14:40   ` Borislav Petkov
2021-06-18 14:19 ` Thomas Gleixner [this message]
2021-06-22 15:38   ` [patch V3 47/66] x86/fpu: Clean up the fpu__clear() variants Borislav Petkov
2021-06-18 14:19 ` [patch V3 48/66] x86/fpu: Rename __fpregs_load_activate() to fpregs_restore_userregs() Thomas Gleixner
2021-06-22 15:40   ` Borislav Petkov
2021-06-18 14:19 ` [patch V3 49/66] x86/fpu: Move FXSAVE_LEAK quirk info __copy_kernel_to_fpregs() Thomas Gleixner
2021-06-22 15:58   ` Borislav Petkov
2021-06-18 14:19 ` [patch V3 50/66] x86/fpu: Rename xfeatures_mask_user() to xfeatures_mask_uabi() Thomas Gleixner
2021-06-22 16:02   ` Borislav Petkov
2021-06-18 14:19 ` [patch V3 51/66] x86/fpu: Dont restore PKRU in fpregs_restore_userspace() Thomas Gleixner
2021-06-22 16:08   ` Borislav Petkov
2021-06-18 14:19 ` [patch V3 52/66] x86/fpu: Add PKRU storage outside of task XSAVE buffer Thomas Gleixner
2021-06-22 16:55   ` Borislav Petkov
2021-06-18 14:19 ` [patch V3 53/66] x86/fpu: Hook up PKRU into ptrace() Thomas Gleixner
2021-06-22 17:01   ` Borislav Petkov
2021-06-18 14:19 ` [patch V3 54/66] x86/fpu: Mask PKRU from kernel XRSTOR[S] operations Thomas Gleixner
2021-06-22 17:07   ` Borislav Petkov
2021-06-18 14:19 ` [patch V3 55/66] x86/fpu: Remove PKRU handling from switch_fpu_finish() Thomas Gleixner
2021-06-22 17:08   ` Borislav Petkov
2021-06-18 14:19 ` [patch V3 56/66] x86/fpu: Dont store PKRU in xstate in fpu_reset_fpstate() Thomas Gleixner
2021-06-22 17:10   ` Borislav Petkov
2021-06-18 14:19 ` [patch V3 57/66] x86/pkru: Remove xstate fiddling from write_pkru() Thomas Gleixner
2021-06-22 17:15   ` Borislav Petkov
2021-06-18 14:19 ` [patch V3 58/66] x86/fpu: Mark init_fpstate __ro_after_init Thomas Gleixner
2021-06-18 14:19 ` [patch V3 59/66] x86/fpu/signal: Move initial checks into fpu__sig_restore() Thomas Gleixner
2021-06-22 17:35   ` Borislav Petkov
2021-06-22 18:38     ` Thomas Gleixner
2021-06-22 18:43       ` Thomas Gleixner
2021-06-18 14:19 ` [patch V3 60/66] x86/fpu/signal: Remove the legacy alignment check Thomas Gleixner
2021-06-22 17:40   ` Borislav Petkov
2021-06-18 14:19 ` [patch V3 61/66] x86/fpu/signal: Sanitize the xstate check on sigframe Thomas Gleixner
2021-06-18 21:02   ` Andrew Cooper
2021-06-18 23:49     ` Thomas Gleixner
2021-06-22 19:10   ` Borislav Petkov
2021-06-18 14:19 ` [patch V3 62/66] x86/fpu/signal: Sanitize copy_user_to_fpregs_zeroing() Thomas Gleixner
2021-06-23  7:51   ` Borislav Petkov
2021-06-18 14:19 ` [patch V3 63/66] x86/fpu/signal: Split out the direct restore code Thomas Gleixner
2021-06-23  8:10   ` Borislav Petkov
2021-06-18 14:19 ` [patch V3 64/66] x86/fpu: Return proper error codes from user access functions Thomas Gleixner
2021-06-23  8:30   ` Borislav Petkov
2021-06-23 10:56     ` Thomas Gleixner
2021-06-18 14:19 ` [patch V3 65/66] x86/fpu/signal: Handle #PF in the direct restore path Thomas Gleixner
2021-06-23  8:45   ` Borislav Petkov
2021-06-18 14:19 ` [patch V3 66/66] x86/fpu/signal: Let xrstor handle the features to init Thomas Gleixner
2021-06-23  8:56   ` Borislav Petkov
2021-06-21 16:15 ` [patch V3 00/66] x86/fpu: Spring cleaning and PKRU sanitizing Yu, Yu-cheng
2021-06-21 21:53 ` Fenghua Yu
2021-06-21 22:22 ` Bae, Chang Seok
2021-06-22 20:02   ` Bae, Chang Seok
2021-06-24  0:06     ` Bae, Chang Seok
2021-06-22  1:59 ` Oliver Sang
2021-06-22  9:08   ` Thomas Gleixner
2021-06-22 18:56 ` Dey, Megha

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=20210618143449.733176003@linutronix.de \
    --to=tglx@linutronix.de \
    --cc=bigeasy@linutronix.de \
    --cc=bp@suse.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=fenghua.yu@intel.com \
    --cc=kan.liang@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=peterz@infradead.org \
    --cc=tony.luck@intel.com \
    --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;
as well as URLs for NNTP newsgroup(s).