All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, tglx@linutronix.de, bp@alien8.de,
	luto@kernel.org
Cc: hpa@zytor.com, dave.hansen@intel.com, tony.luck@intel.com,
	ak@linux.intel.com, ravi.v.shankar@intel.com,
	chang.seok.bae@intel.com, Sasha Levin <sashal@kernel.org>
Subject: [PATCH v12 11/18] x86/fsgsbase/64: Use FSGSBASE in switch_to() if available
Date: Mon, 11 May 2020 00:53:04 -0400	[thread overview]
Message-ID: <20200511045311.4785-12-sashal@kernel.org> (raw)
In-Reply-To: <20200511045311.4785-1-sashal@kernel.org>

From: Andy Lutomirski <luto@kernel.org>

With the new FSGSBASE instructions, FS/GS base can be efficiently read
and written in __switch_to(). Use that capability to preserve the full
state.

This will enable user code to do whatever it wants with the new
instructions without any kernel-induced gotchas.  (There can still be
architectural gotchas: movl %gs,%eax; movl %eax,%gs may change GS base
if WRGSBASE was used, but users are expected to read the CPU manual
before doing things like that.)

This is a considerable speedup. It seems to save about 100 cycles per
context switch compared to the baseline 4.6-rc1 behavior on a Skylake
laptop.

[ chang: 5~10% performance improvements were seen by a context switch
  benchmark that ran threads with different FS/GS base values (to the
  baseline 4.16). ]

Signed-off-by: Andy Lutomirski <luto@kernel.org>
Signed-off-by: Chang S. Bae <chang.seok.bae@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Reviewed-by: Tony Luck <tony.luck@intel.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
---
 arch/x86/kernel/process_64.c | 34 ++++++++++++++++++++++++++++------
 1 file changed, 28 insertions(+), 6 deletions(-)

diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index aaa65f284b9b9..e066750be89a0 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -199,8 +199,18 @@ static __always_inline void save_fsgs(struct task_struct *task)
 {
 	savesegment(fs, task->thread.fsindex);
 	savesegment(gs, task->thread.gsindex);
-	save_base_legacy(task, task->thread.fsindex, FS);
-	save_base_legacy(task, task->thread.gsindex, GS);
+	if (static_cpu_has(X86_FEATURE_FSGSBASE)) {
+		/*
+		 * If FSGSBASE is enabled, we can't make any useful guesses
+		 * about the base, and user code expects us to save the current
+		 * value.  Fortunately, reading the base directly is efficient.
+		 */
+		task->thread.fsbase = rdfsbase();
+		task->thread.gsbase = x86_gsbase_read_cpu_inactive();
+	} else {
+		save_base_legacy(task, task->thread.fsindex, FS);
+		save_base_legacy(task, task->thread.gsindex, GS);
+	}
 }
 
 #if IS_ENABLED(CONFIG_KVM)
@@ -279,10 +289,22 @@ static __always_inline void load_seg_legacy(unsigned short prev_index,
 static __always_inline void x86_fsgsbase_load(struct thread_struct *prev,
 					      struct thread_struct *next)
 {
-	load_seg_legacy(prev->fsindex, prev->fsbase,
-			next->fsindex, next->fsbase, FS);
-	load_seg_legacy(prev->gsindex, prev->gsbase,
-			next->gsindex, next->gsbase, GS);
+	if (static_cpu_has(X86_FEATURE_FSGSBASE)) {
+		/* Update the FS and GS selectors if they could have changed. */
+		if (unlikely(prev->fsindex || next->fsindex))
+			loadseg(FS, next->fsindex);
+		if (unlikely(prev->gsindex || next->gsindex))
+			loadseg(GS, next->gsindex);
+
+		/* Update the bases. */
+		wrfsbase(next->fsbase);
+		x86_gsbase_write_cpu_inactive(next->gsbase);
+	} else {
+		load_seg_legacy(prev->fsindex, prev->fsbase,
+				next->fsindex, next->fsbase, FS);
+		load_seg_legacy(prev->gsindex, prev->gsbase,
+				next->gsindex, next->gsbase, GS);
+	}
 }
 
 static unsigned long x86_fsgsbase_read_task(struct task_struct *task,
-- 
2.20.1


  parent reply	other threads:[~2020-05-11  4:54 UTC|newest]

Thread overview: 76+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-11  4:52 [PATCH v12 00/18] Enable FSGSBASE instructions Sasha Levin
2020-05-11  4:52 ` [PATCH v12 01/18] x86/ptrace: Prevent ptrace from clearing the FS/GS selector Sasha Levin
2020-05-11  4:52 ` [PATCH v12 02/18] selftests/x86/fsgsbase: Test GS selector on ptracer-induced GS base write Sasha Levin
2020-05-11  4:52 ` [PATCH v12 03/18] x86/cpu: Add 'unsafe_fsgsbase' to enable CR4.FSGSBASE Sasha Levin
2020-05-11  4:52 ` [PATCH v12 04/18] x86/entry/64: Clean up paranoid exit Sasha Levin
2020-05-11  4:52 ` [PATCH v12 05/18] x86/entry/64: Switch CR3 before SWAPGS in paranoid entry Sasha Levin
2020-05-11  4:52 ` [PATCH v12 06/18] x86/entry/64: Introduce the FIND_PERCPU_BASE macro Sasha Levin
2020-05-11  4:53 ` [PATCH v12 07/18] x86/entry/64: Handle FSGSBASE enabled paranoid entry/exit Sasha Levin
2020-05-11  4:53 ` [PATCH v12 08/18] x86/entry/64: Document GSBASE handling in the paranoid path Sasha Levin
2020-05-11  4:53 ` [PATCH v12 09/18] x86/fsgsbase/64: Add intrinsics for FSGSBASE instructions Sasha Levin
2020-05-11  4:53 ` [PATCH v12 10/18] x86/fsgsbase/64: Enable FSGSBASE instructions in helper functions Sasha Levin
2020-05-18 18:20   ` Thomas Gleixner
2020-05-18 20:24     ` Sasha Levin
2020-05-18 22:59       ` Thomas Gleixner
2020-05-19 12:20       ` David Laight
2020-05-19 14:48         ` Thomas Gleixner
2020-05-20  9:13           ` David Laight
2020-05-11  4:53 ` Sasha Levin [this message]
2020-05-11  4:53 ` [PATCH v12 12/18] x86/fsgsbase/64: move save_fsgs to header file Sasha Levin
2020-05-11  4:53 ` [PATCH v12 13/18] x86/fsgsbase/64: Use FSGSBASE instructions on thread copy and ptrace Sasha Levin
2020-05-11  4:53 ` [PATCH v12 14/18] x86/speculation/swapgs: Check FSGSBASE in enabling SWAPGS mitigation Sasha Levin
2020-05-11  4:53 ` [PATCH v12 15/18] selftests/x86/fsgsbase: Test ptracer-induced GS base write with FSGSBASE Sasha Levin
2020-05-11  4:53 ` [PATCH v12 16/18] x86/fsgsbase/64: Enable FSGSBASE on 64bit by default and add a chicken bit Sasha Levin
2020-05-11  4:53 ` [PATCH v12 17/18] x86/elf: Enumerate kernel FSGSBASE capability in AT_HWCAP2 Sasha Levin
2020-05-11  4:53 ` [PATCH v12 18/18] Documentation/x86/64: Add documentation for GS/FS addressing mode Sasha Levin
2020-05-15  9:24 ` [PATCH v12 00/18] Enable FSGSBASE instructions Jarkko Sakkinen
2020-05-15 16:40   ` Sasha Levin
2020-05-15 17:55     ` Andi Kleen
2020-05-15 23:07       ` Sasha Levin
2020-05-16 12:21       ` Jarkko Sakkinen
2020-05-16  9:50     ` Jarkko Sakkinen
2020-05-18 15:34       ` Andi Kleen
2020-05-18 20:01         ` Jarkko Sakkinen
2020-05-18 23:03           ` Thomas Gleixner
2020-05-19 16:48             ` Jarkko Sakkinen
2020-05-22 20:14               ` Don Porter
2020-05-22 20:55                 ` Dave Hansen
2020-05-23  0:45                 ` Thomas Gleixner
2020-05-24 19:45                   ` hpa
2020-05-24 21:19                     ` Sasha Levin
2020-05-24 23:44                       ` hpa
2020-05-25  7:54                       ` Richard Weinberger
2020-05-25 21:56                         ` Tony Luck
2020-05-26  8:12                         ` David Laight
2020-05-26  8:23                           ` Richard Weinberger
2020-05-27  8:31                     ` Jarkko Sakkinen
2020-05-26 12:42                   ` Don Porter
2020-05-26 20:27                     ` Sasha Levin
2020-05-26 22:03                       ` Don Porter
2020-05-26 22:51                         ` Sasha Levin
2020-05-28 17:37                           ` Don Porter
2020-05-28 10:29                     ` Thomas Gleixner
2020-05-28 17:40                       ` Don Porter
2020-05-28 18:38                         ` Andy Lutomirski
2020-05-29 15:27                           ` Wojtek Porczyk
2020-06-25 15:27                             ` Don Porter
2020-06-25 21:37                               ` Jarkko Sakkinen
2020-07-18 18:19                                 ` Don Porter
2020-07-23  3:23                                   ` Jarkko Sakkinen
2020-05-28 19:19                         ` Jarkko Sakkinen
2020-05-28 19:41                           ` Sasha Levin
2020-05-29  3:07                             ` Jarkko Sakkinen
2020-05-29  3:10                               ` Jarkko Sakkinen
2020-06-25 15:30                                 ` Don Porter
2020-06-25 21:40                                   ` Jarkko Sakkinen
2020-05-23  4:19                 ` Andi Kleen
2020-05-28 10:36                   ` Thomas Gleixner
2020-05-27  8:20                 ` Jarkko Sakkinen
2020-05-27 12:42                   ` Wojtek Porczyk
2020-05-18  9:51     ` Thomas Gleixner
2020-05-18 15:16       ` Sasha Levin
2020-05-18 18:28         ` Thomas Gleixner
2020-05-18 19:36       ` Jarkko Sakkinen
2020-05-18  6:18 ` Christoph Hellwig
2020-05-18 12:33   ` Sasha Levin
2020-05-18 14:53 ` 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=20200511045311.4785-12-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=ak@linux.intel.com \
    --cc=bp@alien8.de \
    --cc=chang.seok.bae@intel.com \
    --cc=dave.hansen@intel.com \
    --cc=hpa@zytor.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=ravi.v.shankar@intel.com \
    --cc=tglx@linutronix.de \
    --cc=tony.luck@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 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.