All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Chang S. Bae" <chang.seok.bae@intel.com>
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
Subject: [PATCH v9 11/17] x86/fsgsbase/64: Use FSGSBASE in switch_to() if available
Date: Fri,  4 Oct 2019 11:16:03 -0700	[thread overview]
Message-ID: <1570212969-21888-12-git-send-email-chang.seok.bae@intel.com> (raw)
In-Reply-To: <1570212969-21888-1-git-send-email-chang.seok.bae@intel.com>

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>
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>
---

Changes from v8:
* Rebased on the precedent helper changes; removed the interrupt
  condition check and IRQ disablement from save_fsgs() and
  x86_fsgsbase_load().

Changes from v7:
* Used appropriate GS base read/write functions depending on interrupt
  conditions. This fixes the bug in v7.
* Massaged changelog by Thomas
* Used '[FS|GS] base' consistently, instead of '[FS|GS]BASE'
---
 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 295aa0c..56c0e5b 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -200,8 +200,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)
@@ -280,10 +290,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.7.4


  parent reply	other threads:[~2019-10-04 18:17 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-04 18:15 [PATCH v9 00/17] Enable FSGSBASE instructions Chang S. Bae
2019-10-04 18:15 ` [PATCH v9 01/17] x86/ptrace: Prevent ptrace from clearing the FS/GS selector Chang S. Bae
2019-10-04 18:15 ` [PATCH v9 02/17] selftests/x86/fsgsbase: Test GS selector on ptracer-induced GS base write Chang S. Bae
2019-10-04 18:15 ` [PATCH v9 03/17] x86/cpu: Add 'unsafe_fsgsbase' to enable CR4.FSGSBASE Chang S. Bae
2019-10-04 18:15 ` [PATCH v9 04/17] x86/entry/64: Clean up paranoid exit Chang S. Bae
2019-10-04 18:15 ` [PATCH v9 05/17] x86/entry/64: Switch CR3 before SWAPGS in paranoid entry Chang S. Bae
2019-10-04 18:15 ` [PATCH v9 06/17] x86/entry/64: Introduce the FIND_PERCPU_BASE macro Chang S. Bae
2019-10-04 18:15 ` [PATCH v9 07/17] x86/entry/64: Handle FSGSBASE enabled paranoid entry/exit Chang S. Bae
2019-10-04 18:16 ` [PATCH v9 08/17] x86/entry/64: Document GSBASE handling in the paranoid path Chang S. Bae
2019-10-04 18:16 ` [PATCH v9 09/17] x86/fsgsbase/64: Add intrinsics for FSGSBASE instructions Chang S. Bae
2019-10-04 18:16 ` [PATCH v9 10/17] x86/fsgsbase/64: Enable FSGSBASE instructions in helper functions Chang S. Bae
2019-10-04 18:16 ` Chang S. Bae [this message]
2019-10-04 18:16 ` [PATCH v9 12/17] x86/fsgsbase/64: Use FSGSBASE instructions on thread copy and ptrace Chang S. Bae
2019-10-04 18:16 ` [PATCH v9 13/17] x86/speculation/swapgs: Check FSGSBASE in enabling SWAPGS mitigation Chang S. Bae
2019-10-04 18:16 ` [PATCH v9 14/17] selftests/x86/fsgsbase: Test ptracer-induced GS base write with FSGSBASE Chang S. Bae
2019-10-04 18:16 ` [PATCH v9 15/17] x86/fsgsbase/64: Enable FSGSBASE on 64bit by default and add a chicken bit Chang S. Bae
2019-10-04 18:16 ` [PATCH v9 16/17] x86/elf: Enumerate kernel FSGSBASE capability in AT_HWCAP2 Chang S. Bae
2019-10-04 18:16 ` [PATCH v9 17/17] Documentation/x86/64: Add documentation for GS/FS addressing mode Chang S. Bae
2019-10-04 22:54   ` Randy Dunlap
2019-11-15 18:29 ` [PATCH v9 00/17] Enable FSGSBASE instructions Thomas Gleixner
2019-11-15 19:12   ` Andi Kleen
2019-11-29 14:56     ` Metzger, Markus T
2019-11-29 16:51       ` Andy Lutomirski
2019-12-02  8:23         ` Metzger, Markus T
2019-12-04 20:20           ` Andy Lutomirski
2019-12-10  8:27             ` Metzger, Markus T
2020-02-24 18:02             ` Bae, Chang Seok
2020-04-13 20:03               ` Sasha Levin
2020-04-14  0:32                 ` Andi Kleen
2020-04-17 13:30                   ` Sasha Levin
2020-04-17 15:52                     ` Andy Lutomirski
2020-04-20 14:13                       ` Andi Kleen
2020-04-20 17:14                         ` Thomas Gleixner
2020-04-21 16:06                           ` Sasha Levin
2020-04-21 16:49                             ` Andy Lutomirski
2020-04-21 20:02                               ` Andi Kleen
2020-04-21 17:15                             ` Bae, Chang Seok
2020-04-21 19:56                             ` Andi Kleen
2020-04-21 20:21                               ` Andy Lutomirski
2020-04-21 20:51                                 ` Sasha Levin
2020-04-22 23:00                                   ` Andy Lutomirski
2020-04-23  4:08                                     ` Sasha Levin
2020-04-25 22:39                                       ` Thomas Gleixner
2020-04-26  2:52                                         ` Sasha Levin
2020-04-26 10:04                                           ` Thomas Gleixner
2020-04-14 15:47                 ` Bae, Chang Seok

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=1570212969-21888-12-git-send-email-chang.seok.bae@intel.com \
    --to=chang.seok.bae@intel.com \
    --cc=ak@linux.intel.com \
    --cc=bp@alien8.de \
    --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.