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 v10 12/18] x86/fsgsbase/64: move save_fsgs to header file
Date: Thu, 23 Apr 2020 19:22:01 -0400 [thread overview]
Message-ID: <20200423232207.5797-13-sashal@kernel.org> (raw)
In-Reply-To: <20200423232207.5797-1-sashal@kernel.org>
Given copy_thread_tls() is now shared between 32 and 64 bit and we need
to use save_fsgs() there, move it to a header file.
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/kernel/process.h | 69 ++++++++++++++++++++++++++++++++++++
arch/x86/kernel/process_64.c | 68 -----------------------------------
2 files changed, 69 insertions(+), 68 deletions(-)
diff --git a/arch/x86/kernel/process.h b/arch/x86/kernel/process.h
index 1d0797b2338a2..dbdab420fe001 100644
--- a/arch/x86/kernel/process.h
+++ b/arch/x86/kernel/process.h
@@ -37,3 +37,72 @@ static inline void switch_to_extra(struct task_struct *prev,
prev_tif & _TIF_WORK_CTXSW_PREV))
__switch_to_xtra(prev, next);
}
+
+enum which_selector {
+ FS,
+ GS
+};
+
+/*
+ * Saves the FS or GS base for an outgoing thread if FSGSBASE extensions are
+ * not available. The goal is to be reasonably fast on non-FSGSBASE systems.
+ * It's forcibly inlined because it'll generate better code and this function
+ * is hot.
+ */
+static __always_inline void save_base_legacy(struct task_struct *prev_p,
+ unsigned short selector,
+ enum which_selector which)
+{
+ if (likely(selector == 0)) {
+ /*
+ * On Intel (without X86_BUG_NULL_SEG), the segment base could
+ * be the pre-existing saved base or it could be zero. On AMD
+ * (with X86_BUG_NULL_SEG), the segment base could be almost
+ * anything.
+ *
+ * This branch is very hot (it's hit twice on almost every
+ * context switch between 64-bit programs), and avoiding
+ * the RDMSR helps a lot, so we just assume that whatever
+ * value is already saved is correct. This matches historical
+ * Linux behavior, so it won't break existing applications.
+ *
+ * To avoid leaking state, on non-X86_BUG_NULL_SEG CPUs, if we
+ * report that the base is zero, it needs to actually be zero:
+ * see the corresponding logic in load_seg_legacy.
+ */
+ } else {
+ /*
+ * If the selector is 1, 2, or 3, then the base is zero on
+ * !X86_BUG_NULL_SEG CPUs and could be anything on
+ * X86_BUG_NULL_SEG CPUs. In the latter case, Linux
+ * has never attempted to preserve the base across context
+ * switches.
+ *
+ * If selector > 3, then it refers to a real segment, and
+ * saving the base isn't necessary.
+ */
+ if (which == FS)
+ prev_p->thread.fsbase = 0;
+ else
+ prev_p->thread.gsbase = 0;
+ }
+}
+
+static __always_inline void save_fsgs(struct task_struct *task)
+{
+ savesegment(fs, task->thread.fsindex);
+ savesegment(gs, task->thread.gsindex);
+ 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);
+ }
+}
+
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index e066750be89a0..4be88124d81ea 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -145,74 +145,6 @@ void release_thread(struct task_struct *dead_task)
WARN_ON(dead_task->mm);
}
-enum which_selector {
- FS,
- GS
-};
-
-/*
- * Saves the FS or GS base for an outgoing thread if FSGSBASE extensions are
- * not available. The goal is to be reasonably fast on non-FSGSBASE systems.
- * It's forcibly inlined because it'll generate better code and this function
- * is hot.
- */
-static __always_inline void save_base_legacy(struct task_struct *prev_p,
- unsigned short selector,
- enum which_selector which)
-{
- if (likely(selector == 0)) {
- /*
- * On Intel (without X86_BUG_NULL_SEG), the segment base could
- * be the pre-existing saved base or it could be zero. On AMD
- * (with X86_BUG_NULL_SEG), the segment base could be almost
- * anything.
- *
- * This branch is very hot (it's hit twice on almost every
- * context switch between 64-bit programs), and avoiding
- * the RDMSR helps a lot, so we just assume that whatever
- * value is already saved is correct. This matches historical
- * Linux behavior, so it won't break existing applications.
- *
- * To avoid leaking state, on non-X86_BUG_NULL_SEG CPUs, if we
- * report that the base is zero, it needs to actually be zero:
- * see the corresponding logic in load_seg_legacy.
- */
- } else {
- /*
- * If the selector is 1, 2, or 3, then the base is zero on
- * !X86_BUG_NULL_SEG CPUs and could be anything on
- * X86_BUG_NULL_SEG CPUs. In the latter case, Linux
- * has never attempted to preserve the base across context
- * switches.
- *
- * If selector > 3, then it refers to a real segment, and
- * saving the base isn't necessary.
- */
- if (which == FS)
- prev_p->thread.fsbase = 0;
- else
- prev_p->thread.gsbase = 0;
- }
-}
-
-static __always_inline void save_fsgs(struct task_struct *task)
-{
- savesegment(fs, task->thread.fsindex);
- savesegment(gs, task->thread.gsindex);
- 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)
/*
* While a process is running,current->thread.fsbase and current->thread.gsbase
--
2.20.1
next prev parent reply other threads:[~2020-04-23 23:22 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-04-23 23:21 [PATCH v10 00/18] Enable FSGSBASE instructions Sasha Levin
2020-04-23 23:21 ` [PATCH v10 01/18] x86/ptrace: Prevent ptrace from clearing the FS/GS selector Sasha Levin
2020-04-25 22:46 ` Andy Lutomirski
2020-04-23 23:21 ` [PATCH v10 02/18] selftests/x86/fsgsbase: Test GS selector on ptracer-induced GS base write Sasha Levin
2020-04-23 23:21 ` [PATCH v10 03/18] x86/cpu: Add 'unsafe_fsgsbase' to enable CR4.FSGSBASE Sasha Levin
2020-04-23 23:21 ` [PATCH v10 04/18] x86/entry/64: Clean up paranoid exit Sasha Levin
2020-04-23 23:21 ` [PATCH v10 05/18] x86/entry/64: Switch CR3 before SWAPGS in paranoid entry Sasha Levin
2020-04-23 23:21 ` [PATCH v10 06/18] x86/entry/64: Introduce the FIND_PERCPU_BASE macro Sasha Levin
2020-04-23 23:21 ` [PATCH v10 07/18] x86/entry/64: Handle FSGSBASE enabled paranoid entry/exit Sasha Levin
2020-04-23 23:21 ` [PATCH v10 08/18] x86/entry/64: Document GSBASE handling in the paranoid path Sasha Levin
2020-04-23 23:21 ` [PATCH v10 09/18] x86/fsgsbase/64: Add intrinsics for FSGSBASE instructions Sasha Levin
2020-04-23 23:21 ` [PATCH v10 10/18] x86/fsgsbase/64: Enable FSGSBASE instructions in helper functions Sasha Levin
2020-04-23 23:22 ` [PATCH v10 11/18] x86/fsgsbase/64: Use FSGSBASE in switch_to() if available Sasha Levin
2020-04-23 23:22 ` Sasha Levin [this message]
2020-04-23 23:22 ` [PATCH v10 13/18] x86/fsgsbase/64: Use FSGSBASE instructions on thread copy and ptrace Sasha Levin
2020-04-23 23:22 ` [PATCH v10 14/18] x86/speculation/swapgs: Check FSGSBASE in enabling SWAPGS mitigation Sasha Levin
2020-04-23 23:22 ` [PATCH v10 15/18] selftests/x86/fsgsbase: Test ptracer-induced GS base write with FSGSBASE Sasha Levin
2020-04-23 23:22 ` [PATCH v10 16/18] x86/fsgsbase/64: Enable FSGSBASE on 64bit by default and add a chicken bit Sasha Levin
2020-04-23 23:22 ` [PATCH v10 17/18] x86/elf: Enumerate kernel FSGSBASE capability in AT_HWCAP2 Sasha Levin
2020-04-23 23:22 ` [PATCH v10 18/18] Documentation/x86/64: Add documentation for GS/FS addressing mode Sasha Levin
2020-05-10 8:09 ` [PATCH v10 00/18] Enable FSGSBASE instructions Vegard Nossum
2020-05-10 8:29 ` Vegard Nossum
2020-05-10 10:15 ` Thomas Gleixner
2020-05-10 14:17 ` Sasha Levin
2020-05-11 0:48 ` Andi Kleen
2020-05-11 0:50 ` Andi Kleen
2020-05-11 5:03 ` Sasha Levin
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=20200423232207.5797-13-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 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).