Skip to content

Commit d375cf1

Browse files
amlutoIngo Molnar
authored andcommitted
x86/entry/64: Remove thread_struct::sp0
On x86_64, we can easily calculate sp0 when needed instead of storing it in thread_struct. On x86_32, a similar cleanup would be possible, but it would require cleaning up the vm86 code first, and that can wait for a later cleanup series. Signed-off-by: Andy Lutomirski <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Brian Gerst <[email protected]> Cc: Dave Hansen <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Thomas Gleixner <[email protected]> Link: http://lkml.kernel.org/r/719cd9c66c548c4350d98a90f050aee8b17f8919.1509609304.git.luto@kernel.org Signed-off-by: Ingo Molnar <[email protected]>
1 parent cd493a6 commit d375cf1

File tree

4 files changed

+16
-20
lines changed

4 files changed

+16
-20
lines changed

arch/x86/include/asm/compat.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77
#include <linux/types.h>
88
#include <linux/sched.h>
9+
#include <linux/sched/task_stack.h>
910
#include <asm/processor.h>
1011
#include <asm/user32.h>
1112
#include <asm/unistd.h>

arch/x86/include/asm/processor.h

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,9 @@ typedef struct {
430430
struct thread_struct {
431431
/* Cached TLS descriptors: */
432432
struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
433+
#ifdef CONFIG_X86_32
433434
unsigned long sp0;
435+
#endif
434436
unsigned long sp;
435437
#ifdef CONFIG_X86_32
436438
unsigned long sysenter_cs;
@@ -797,6 +799,13 @@ static inline void spin_lock_prefetch(const void *x)
797799

798800
#define task_top_of_stack(task) ((unsigned long)(task_pt_regs(task) + 1))
799801

802+
#define task_pt_regs(task) \
803+
({ \
804+
unsigned long __ptr = (unsigned long)task_stack_page(task); \
805+
__ptr += THREAD_SIZE - TOP_OF_KERNEL_STACK_PADDING; \
806+
((struct pt_regs *)__ptr) - 1; \
807+
})
808+
800809
#ifdef CONFIG_X86_32
801810
/*
802811
* User space process size: 3GB (default).
@@ -816,23 +825,6 @@ static inline void spin_lock_prefetch(const void *x)
816825
.addr_limit = KERNEL_DS, \
817826
}
818827

819-
/*
820-
* TOP_OF_KERNEL_STACK_PADDING reserves 8 bytes on top of the ring0 stack.
821-
* This is necessary to guarantee that the entire "struct pt_regs"
822-
* is accessible even if the CPU haven't stored the SS/ESP registers
823-
* on the stack (interrupt gate does not save these registers
824-
* when switching to the same priv ring).
825-
* Therefore beware: accessing the ss/esp fields of the
826-
* "struct pt_regs" is possible, but they may contain the
827-
* completely wrong values.
828-
*/
829-
#define task_pt_regs(task) \
830-
({ \
831-
unsigned long __ptr = (unsigned long)task_stack_page(task); \
832-
__ptr += THREAD_SIZE - TOP_OF_KERNEL_STACK_PADDING; \
833-
((struct pt_regs *)__ptr) - 1; \
834-
})
835-
836828
#define KSTK_ESP(task) (task_pt_regs(task)->sp)
837829

838830
#else
@@ -866,11 +858,9 @@ static inline void spin_lock_prefetch(const void *x)
866858
#define STACK_TOP_MAX TASK_SIZE_MAX
867859

868860
#define INIT_THREAD { \
869-
.sp0 = TOP_OF_INIT_STACK, \
870861
.addr_limit = KERNEL_DS, \
871862
}
872863

873-
#define task_pt_regs(tsk) ((struct pt_regs *)(tsk)->thread.sp0 - 1)
874864
extern unsigned long KSTK_ESP(struct task_struct *task);
875865

876866
#endif /* CONFIG_X86_64 */

arch/x86/include/asm/switch_to.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#ifndef _ASM_X86_SWITCH_TO_H
22
#define _ASM_X86_SWITCH_TO_H
33

4+
#include <linux/sched/task_stack.h>
5+
46
struct task_struct; /* one of the stranger aspects of C forward declarations */
57

68
struct task_struct *__switch_to_asm(struct task_struct *prev,
@@ -87,7 +89,11 @@ static inline void refresh_sysenter_cs(struct thread_struct *thread)
8789
/* This is used when switching tasks or entering/exiting vm86 mode. */
8890
static inline void update_sp0(struct task_struct *task)
8991
{
92+
#ifdef CONFIG_X86_32
9093
load_sp0(task->thread.sp0);
94+
#else
95+
load_sp0(task_top_of_stack(task));
96+
#endif
9197
}
9298

9399
#endif /* _ASM_X86_SWITCH_TO_H */

arch/x86/kernel/process_64.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,6 @@ int copy_thread_tls(unsigned long clone_flags, unsigned long sp,
274274
struct inactive_task_frame *frame;
275275
struct task_struct *me = current;
276276

277-
p->thread.sp0 = (unsigned long)task_stack_page(p) + THREAD_SIZE;
278277
childregs = task_pt_regs(p);
279278
fork_frame = container_of(childregs, struct fork_frame, regs);
280279
frame = &fork_frame->frame;

0 commit comments

Comments
 (0)