aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Lutomirski <luto@kernel.org>2017-11-02 03:59:13 -0400
committerIngo Molnar <mingo@kernel.org>2017-11-02 06:04:46 -0400
commit20bb83443ea79087b5e5f8dab4e9d80bb9bf7acb (patch)
tree0f12b47f202f739b1e22ee6e6734273a8071ef9b
parentf16b3da1dc936c0f8121741d0a1731bf242f2f56 (diff)
x86/entry/64: Stop initializing TSS.sp0 at boot
In my quest to get rid of thread_struct::sp0, I want to clean up or remove all of its readers. Two of them are in cpu_init() (32-bit and 64-bit), and they aren't needed. This is because we never enter userspace at all on the threads that CPUs are initialized in. Poison the initial TSS.sp0 and stop initializing it on CPU init. The comment text mostly comes from Dave Hansen. Thanks! Signed-off-by: Andy Lutomirski <luto@kernel.org> Cc: Borislav Petkov <bpetkov@suse.de> Cc: Brian Gerst <brgerst@gmail.com> Cc: Dave Hansen <dave.hansen@intel.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/ee4a00540ad28c6cff475fbcc7769a4460acc861.1509609304.git.luto@kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--arch/x86/kernel/cpu/common.c13
-rw-r--r--arch/x86/kernel/process.c8
2 files changed, 17 insertions, 4 deletions
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 4e7fb9c3bfa5..cdf79ab628c2 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -1570,9 +1570,13 @@ void cpu_init(void)
1570 initialize_tlbstate_and_flush(); 1570 initialize_tlbstate_and_flush();
1571 enter_lazy_tlb(&init_mm, me); 1571 enter_lazy_tlb(&init_mm, me);
1572 1572
1573 load_sp0(current->thread.sp0); 1573 /*
1574 * Initialize the TSS. Don't bother initializing sp0, as the initial
1575 * task never enters user mode.
1576 */
1574 set_tss_desc(cpu, t); 1577 set_tss_desc(cpu, t);
1575 load_TR_desc(); 1578 load_TR_desc();
1579
1576 load_mm_ldt(&init_mm); 1580 load_mm_ldt(&init_mm);
1577 1581
1578 clear_all_debug_regs(); 1582 clear_all_debug_regs();
@@ -1594,7 +1598,6 @@ void cpu_init(void)
1594 int cpu = smp_processor_id(); 1598 int cpu = smp_processor_id();
1595 struct task_struct *curr = current; 1599 struct task_struct *curr = current;
1596 struct tss_struct *t = &per_cpu(cpu_tss, cpu); 1600 struct tss_struct *t = &per_cpu(cpu_tss, cpu);
1597 struct thread_struct *thread = &curr->thread;
1598 1601
1599 wait_for_master_cpu(cpu); 1602 wait_for_master_cpu(cpu);
1600 1603
@@ -1625,9 +1628,13 @@ void cpu_init(void)
1625 initialize_tlbstate_and_flush(); 1628 initialize_tlbstate_and_flush();
1626 enter_lazy_tlb(&init_mm, curr); 1629 enter_lazy_tlb(&init_mm, curr);
1627 1630
1628 load_sp0(thread->sp0); 1631 /*
1632 * Initialize the TSS. Don't bother initializing sp0, as the initial
1633 * task never enters user mode.
1634 */
1629 set_tss_desc(cpu, t); 1635 set_tss_desc(cpu, t);
1630 load_TR_desc(); 1636 load_TR_desc();
1637
1631 load_mm_ldt(&init_mm); 1638 load_mm_ldt(&init_mm);
1632 1639
1633 t->x86_tss.io_bitmap_base = offsetof(struct tss_struct, io_bitmap); 1640 t->x86_tss.io_bitmap_base = offsetof(struct tss_struct, io_bitmap);
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index bd6b85fac666..ff8a9acbcf8b 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -48,7 +48,13 @@
48 */ 48 */
49__visible DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, cpu_tss) = { 49__visible DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, cpu_tss) = {
50 .x86_tss = { 50 .x86_tss = {
51 .sp0 = TOP_OF_INIT_STACK, 51 /*
52 * .sp0 is only used when entering ring 0 from a lower
53 * privilege level. Since the init task never runs anything
54 * but ring 0 code, there is no need for a valid value here.
55 * Poison it.
56 */
57 .sp0 = (1UL << (BITS_PER_LONG-1)) + 1,
52#ifdef CONFIG_X86_32 58#ifdef CONFIG_X86_32
53 .ss0 = __KERNEL_DS, 59 .ss0 = __KERNEL_DS,
54 .ss1 = __KERNEL_CS, 60 .ss1 = __KERNEL_CS,