linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Yu-cheng Yu <yu-cheng.yu@intel.com>
To: linux-kernel@vger.kernel.org, x86@kernel.org,
	"H. Peter Anvin" <hpa@zytor.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Ingo Molnar <mingo@redhat.com>,
	Dave Hansen <dave.hansen@linux.intel.com>,
	Tony Luck <tony.luck@intel.com>,
	Andy Lutomirski <luto@kernel.org>, Borislav Petkov <bp@alien8.de>,
	Rik van Riel <riel@surriel.com>,
	"Ravi V. Shankar" <ravi.v.shankar@intel.com>,
	Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
	Fenghua Yu <fenghua.yu@intel.com>,
	Peter Zijlstra <peterz@infradead.org>
Cc: Yu-cheng Yu <yu-cheng.yu@intel.com>
Subject: [PATCH v2 8/8] x86/fpu/xstate: Restore supervisor xstates for __fpu__restore_sig()
Date: Tue, 21 Jan 2020 12:18:43 -0800	[thread overview]
Message-ID: <20200121201843.12047-9-yu-cheng.yu@intel.com> (raw)
In-Reply-To: <20200121201843.12047-1-yu-cheng.yu@intel.com>

When returning from a signal, there is user state in a userspace memory
buffer and supervisor state in registers.  The in-kernel buffer has neither
valid user or supervisor state.  To restore both, save supervisor fpregs
first (and protect them across context switches), then restore it along
with user state.

This patch introduces saving and restoring of supervisor xstates for a
sigreturn in the following steps:

- Preserve supervisor register values by saving the whole fpu xstates.
  Saving the whole is necessary because doing XSAVES with a partial
  requested-feature bitmap (RFBM) changes xcomp_bv.  Since user xstates are
  to be restored from a user buffer, saved user xstates are discarded.

- Set TIF_NEED_FPU_LOAD, and do __fpu_invalidate_fpregs_state().
  This prevents a context switch from corrupting the saved xstates,
  and xstate is considered to be loaded again on return to userland.

- Under fpregs_lock(), restore user xstates (from the user buffer), and
  then supervisor xstates (from previously saved content).

- When both parts of the restoration succeed, mark fpregs as valid.

Signed-off-by: Yu-cheng Yu <yu-cheng.yu@intel.com>
Reviewed-by: Dave Hansen <dave.hansen@linux.intel.com>
---
 arch/x86/kernel/fpu/signal.c | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c
index e3781a4a52a8..0d3e06a772b0 100644
--- a/arch/x86/kernel/fpu/signal.c
+++ b/arch/x86/kernel/fpu/signal.c
@@ -327,14 +327,22 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size)
 	}
 
 	/*
-	 * The current state of the FPU registers does not matter. By setting
-	 * TIF_NEED_FPU_LOAD unconditionally it is ensured that the our xstate
-	 * is not modified on context switch and that the xstate is considered
+	 * Supervisor xstates are not modified by user space input, and
+	 * need to be saved and restored.  Save the whole because doing
+	 * partial XSAVES changes xcomp_bv.
+	 * By setting TIF_NEED_FPU_LOAD it is ensured that our xstate is
+	 * not modified on context switch and that the xstate is considered
 	 * to be loaded again on return to userland (overriding last_cpu avoids
 	 * the optimisation).
 	 */
-	set_thread_flag(TIF_NEED_FPU_LOAD);
+	fpregs_lock();
+	if (!test_thread_flag(TIF_NEED_FPU_LOAD)) {
+		if (xfeatures_mask_supervisor())
+			copy_xregs_to_kernel(&fpu->state.xsave);
+		set_thread_flag(TIF_NEED_FPU_LOAD);
+	}
 	__fpu_invalidate_fpregs_state(fpu);
+	fpregs_unlock();
 
 	if ((unsigned long)buf_fx % 64)
 		fx_only = 1;
@@ -360,6 +368,9 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size)
 		ret = copy_user_to_fpregs_zeroing(buf_fx, xfeatures_user, fx_only);
 		pagefault_enable();
 		if (!ret) {
+			if (xfeatures_mask_supervisor())
+				copy_kernel_to_xregs(&fpu->state.xsave,
+						     xfeatures_mask_supervisor());
 			fpregs_mark_activate();
 			fpregs_unlock();
 			return 0;
@@ -389,7 +400,12 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size)
 		fpregs_lock();
 		if (unlikely(init_bv))
 			copy_kernel_to_xregs(&init_fpstate.xsave, init_bv);
-		ret = copy_kernel_to_xregs_err(&fpu->state.xsave, xfeatures_user);
+		/*
+		 * Restore previously saved supervisor xstates along with
+		 * copied-in user xstates.
+		 */
+		ret = copy_kernel_to_xregs_err(&fpu->state.xsave,
+					       xfeatures_user | xfeatures_mask_supervisor());
 
 	} else if (use_fxsr()) {
 		ret = __copy_from_user(&fpu->state.fxsave, buf_fx, state_size);
-- 
2.21.0


  parent reply	other threads:[~2020-01-21 20:20 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-01-21 20:18 [PATCH v2 0/8] Support XSAVES supervisor states Yu-cheng Yu
2020-01-21 20:18 ` [PATCH v2 1/8] x86/fpu/xstate: Define new macros for supervisor and user xstates Yu-cheng Yu
2020-02-20 11:47   ` Borislav Petkov
2020-02-20 20:23     ` Yu-cheng Yu
2020-01-21 20:18 ` [PATCH v2 2/8] x86/fpu/xstate: Separate user and supervisor xfeatures mask Yu-cheng Yu
2020-02-21 10:34   ` Borislav Petkov
2020-01-21 20:18 ` [PATCH v2 3/8] x86/fpu/xstate: Introduce XSAVES supervisor states Yu-cheng Yu
2020-01-21 20:18 ` [PATCH v2 4/8] x86/fpu/xstate: Define new functions for clearing fpregs and xstates Yu-cheng Yu
2020-02-21 14:04   ` Borislav Petkov
2020-01-21 20:18 ` [PATCH v2 5/8] x86/fpu/xstate: Rename validate_xstate_header() to validate_xstate_header_from_user() Yu-cheng Yu
2020-02-21 14:13   ` Borislav Petkov
2020-01-21 20:18 ` [PATCH v2 6/8] x86/fpu/xstate: Update sanitize_restored_xstate() for supervisor xstates Yu-cheng Yu
2020-02-21 14:30   ` Borislav Petkov
2020-01-21 20:18 ` [PATCH v2 7/8] x86/fpu/xstate: Update copy_kernel_to_xregs_err() for XSAVES supervisor states Yu-cheng Yu
2020-01-21 20:18 ` Yu-cheng Yu [this message]
2020-02-21 17:58   ` [PATCH v2 8/8] x86/fpu/xstate: Restore supervisor xstates for __fpu__restore_sig() Borislav Petkov
2020-02-27 22:52     ` Yu-cheng Yu
2020-02-28 12:17       ` Borislav Petkov
2020-02-28 12:51         ` Sebastian Andrzej Siewior
2020-02-28 15:53         ` Yu-cheng Yu
2020-02-28 16:23           ` Borislav Petkov
2020-02-28 16:20             ` Yu-cheng Yu
2020-02-28 16:50               ` Sebastian Andrzej Siewior
2020-02-28 16:54                 ` Yu-cheng Yu
2020-02-28 17:22               ` Borislav Petkov
2020-02-28 18:11                 ` Yu-cheng Yu
2020-02-28 18:31                   ` Borislav Petkov
2020-02-28 21:22                     ` Yu-cheng Yu
2020-02-28 21:47                       ` Borislav Petkov
2020-02-28 22:13                         ` Yu-cheng Yu
2020-02-29 14:36                           ` Borislav Petkov
2020-03-02 18:09                             ` Yu-cheng Yu
2020-03-04 18:18                               ` Yu-cheng Yu
2020-03-06 20:50                                 ` Borislav Petkov
2020-03-10 20:36                                   ` Yu-cheng Yu
2020-03-10 21:16                                     ` 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=20200121201843.12047-9-yu-cheng.yu@intel.com \
    --to=yu-cheng.yu@intel.com \
    --cc=bigeasy@linutronix.de \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=fenghua.yu@intel.com \
    --cc=hpa@zytor.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=ravi.v.shankar@intel.com \
    --cc=riel@surriel.com \
    --cc=tglx@linutronix.de \
    --cc=tony.luck@intel.com \
    --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 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).