aboutsummaryrefslogtreecommitdiff
path: root/arch/x86/include/asm/switch_to.h
diff options
context:
space:
mode:
authorGravatar Lai Jiangshan <laijs@linux.alibaba.com> 2021-01-26 01:34:29 +0800
committerGravatar Thomas Gleixner <tglx@linutronix.de> 2021-03-28 22:40:10 +0200
commit1591584e2e762edecefde403c44d9c26c9ff72c9 (patch)
tree01f5935e0be3b2ce212bfaf51b7ef725a523c97e /arch/x86/include/asm/switch_to.h
parenttools/turbostat: Unmark non-kernel-doc comment (diff)
downloadlinux-1591584e2e762edecefde403c44d9c26c9ff72c9.tar.gz
linux-1591584e2e762edecefde403c44d9c26c9ff72c9.tar.bz2
linux-1591584e2e762edecefde403c44d9c26c9ff72c9.zip
x86/process/64: Move cpu_current_top_of_stack out of TSS
cpu_current_top_of_stack is currently stored in TSS.sp1. TSS is exposed through the cpu_entry_area which is visible with user CR3 when PTI is enabled and active. This makes it a coveted fruit for attackers. An attacker can fetch the kernel stack top from it and continue next steps of actions based on the kernel stack. But it is actualy not necessary to be stored in the TSS. It is only accessed after the entry code switched to kernel CR3 and kernel GS_BASE which means it can be in any regular percpu variable. The reason why it is in TSS is historical (pre PTI) because TSS is also used as scratch space in SYSCALL_64 and therefore cache hot. A syscall also needs the per CPU variable current_task and eventually __preempt_count, so placing cpu_current_top_of_stack next to them makes it likely that they end up in the same cache line which should avoid performance regressions. This is not enforced as the compiler is free to place these variables, so these entry relevant variables should move into a data structure to make this enforceable. The seccomp_benchmark doesn't show any performance loss in the "getpid native" test result. Actually, the result changes from 93ns before to 92ns with this change when KPTI is disabled. The test is very stable and although the test doesn't show a higher degree of precision it gives enough confidence that moving cpu_current_top_of_stack does not cause a regression. [ tglx: Removed unneeded export. Massaged changelog ] Signed-off-by: Lai Jiangshan <laijs@linux.alibaba.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://lore.kernel.org/r/20210125173444.22696-2-jiangshanlai@gmail.com
Diffstat (limited to 'arch/x86/include/asm/switch_to.h')
-rw-r--r--arch/x86/include/asm/switch_to.h7
1 files changed, 1 insertions, 6 deletions
diff --git a/arch/x86/include/asm/switch_to.h b/arch/x86/include/asm/switch_to.h
index 9f69cc497f4b..b5f0d2ff47e4 100644
--- a/arch/x86/include/asm/switch_to.h
+++ b/arch/x86/include/asm/switch_to.h
@@ -71,12 +71,7 @@ static inline void update_task_stack(struct task_struct *task)
else
this_cpu_write(cpu_tss_rw.x86_tss.sp1, task->thread.sp0);
#else
- /*
- * x86-64 updates x86_tss.sp1 via cpu_current_top_of_stack. That
- * doesn't work on x86-32 because sp1 and
- * cpu_current_top_of_stack have different values (because of
- * the non-zero stack-padding on 32bit).
- */
+ /* Xen PV enters the kernel on the thread stack. */
if (static_cpu_has(X86_FEATURE_XENPV))
load_sp0(task_top_of_stack(task));
#endif