Commit ef593260 authored by Denys Vlasenko's avatar Denys Vlasenko Committed by Ingo Molnar

x86/asm/entry: Get rid of KERNEL_STACK_OFFSET

PER_CPU_VAR(kernel_stack) was set up in a way where it points
five stack slots below the top of stack.

Presumably, it was done to avoid one "sub $5*8,%rsp"
in syscall/sysenter code paths, where iret frame needs to be
created by hand.

Ironically, none of them benefits from this optimization,
since all of them need to allocate additional data on stack
(struct pt_regs), so they still have to perform subtraction.

This patch eliminates KERNEL_STACK_OFFSET.

PER_CPU_VAR(kernel_stack) now points directly to top of stack.
pt_regs allocations are adjusted to allocate iret frame as well.
Hopefully we can merge it later with 32-bit specific
PER_CPU_VAR(cpu_current_top_of_stack) variable...

Net result in generated code is that constants in several insns
are changed.

This change is necessary for changing struct pt_regs creation
in SYSCALL64 code path from MOV to PUSH instructions.
Signed-off-by: default avatarDenys Vlasenko <dvlasenk@redhat.com>
Acked-by: default avatarBorislav Petkov <bp@suse.de>
Acked-by: default avatarAndy Lutomirski <luto@kernel.org>
Cc: Alexei Starovoitov <ast@plumgrid.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Will Drewry <wad@chromium.org>
Link: http://lkml.kernel.org/r/1426785469-15125-2-git-send-email-dvlasenk@redhat.comSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent b3fe8ba3
...@@ -311,7 +311,7 @@ ENDPROC(ia32_sysenter_target) ...@@ -311,7 +311,7 @@ ENDPROC(ia32_sysenter_target)
ENTRY(ia32_cstar_target) ENTRY(ia32_cstar_target)
CFI_STARTPROC32 simple CFI_STARTPROC32 simple
CFI_SIGNAL_FRAME CFI_SIGNAL_FRAME
CFI_DEF_CFA rsp,KERNEL_STACK_OFFSET CFI_DEF_CFA rsp,0
CFI_REGISTER rip,rcx CFI_REGISTER rip,rcx
/*CFI_REGISTER rflags,r11*/ /*CFI_REGISTER rflags,r11*/
SWAPGS_UNSAFE_STACK SWAPGS_UNSAFE_STACK
...@@ -323,7 +323,7 @@ ENTRY(ia32_cstar_target) ...@@ -323,7 +323,7 @@ ENTRY(ia32_cstar_target)
* disabled irqs and here we enable it straight after entry: * disabled irqs and here we enable it straight after entry:
*/ */
ENABLE_INTERRUPTS(CLBR_NONE) ENABLE_INTERRUPTS(CLBR_NONE)
ALLOC_PT_GPREGS_ON_STACK 8 /* +8: space for orig_ax */ ALLOC_PT_GPREGS_ON_STACK 6*8 /* 6*8: space for orig_ax and iret frame */
SAVE_C_REGS_EXCEPT_RCX_R891011 SAVE_C_REGS_EXCEPT_RCX_R891011
movl %eax,%eax /* zero extension */ movl %eax,%eax /* zero extension */
movq %rax,ORIG_RAX(%rsp) movq %rax,ORIG_RAX(%rsp)
......
...@@ -172,7 +172,6 @@ struct thread_info { ...@@ -172,7 +172,6 @@ struct thread_info {
#define _TIF_WORK_CTXSW_NEXT (_TIF_WORK_CTXSW) #define _TIF_WORK_CTXSW_NEXT (_TIF_WORK_CTXSW)
#define STACK_WARN (THREAD_SIZE/8) #define STACK_WARN (THREAD_SIZE/8)
#define KERNEL_STACK_OFFSET (5*(BITS_PER_LONG/8))
/* /*
* macros/functions for gaining access to the thread information structure * macros/functions for gaining access to the thread information structure
...@@ -201,10 +200,10 @@ static inline unsigned long current_stack_pointer(void) ...@@ -201,10 +200,10 @@ static inline unsigned long current_stack_pointer(void)
#else /* !__ASSEMBLY__ */ #else /* !__ASSEMBLY__ */
/* how to get the thread information struct from ASM */ /* Load thread_info address into "reg" */
#define GET_THREAD_INFO(reg) \ #define GET_THREAD_INFO(reg) \
_ASM_MOV PER_CPU_VAR(kernel_stack),reg ; \ _ASM_MOV PER_CPU_VAR(kernel_stack),reg ; \
_ASM_SUB $(THREAD_SIZE-KERNEL_STACK_OFFSET),reg ; _ASM_SUB $(THREAD_SIZE),reg ;
/* /*
* ASM operand which evaluates to thread_info address * ASM operand which evaluates to thread_info address
......
...@@ -1116,7 +1116,7 @@ static __init int setup_disablecpuid(char *arg) ...@@ -1116,7 +1116,7 @@ static __init int setup_disablecpuid(char *arg)
__setup("clearcpuid=", setup_disablecpuid); __setup("clearcpuid=", setup_disablecpuid);
DEFINE_PER_CPU(unsigned long, kernel_stack) = DEFINE_PER_CPU(unsigned long, kernel_stack) =
(unsigned long)&init_thread_union - KERNEL_STACK_OFFSET + THREAD_SIZE; (unsigned long)&init_thread_union + THREAD_SIZE;
EXPORT_PER_CPU_SYMBOL(kernel_stack); EXPORT_PER_CPU_SYMBOL(kernel_stack);
#ifdef CONFIG_X86_64 #ifdef CONFIG_X86_64
......
...@@ -225,7 +225,7 @@ ENDPROC(native_usergs_sysret64) ...@@ -225,7 +225,7 @@ ENDPROC(native_usergs_sysret64)
ENTRY(system_call) ENTRY(system_call)
CFI_STARTPROC simple CFI_STARTPROC simple
CFI_SIGNAL_FRAME CFI_SIGNAL_FRAME
CFI_DEF_CFA rsp,KERNEL_STACK_OFFSET CFI_DEF_CFA rsp,0
CFI_REGISTER rip,rcx CFI_REGISTER rip,rcx
/*CFI_REGISTER rflags,r11*/ /*CFI_REGISTER rflags,r11*/
SWAPGS_UNSAFE_STACK SWAPGS_UNSAFE_STACK
...@@ -242,9 +242,8 @@ GLOBAL(system_call_after_swapgs) ...@@ -242,9 +242,8 @@ GLOBAL(system_call_after_swapgs)
* so we can enable interrupts only after we're done with using rsp_scratch: * so we can enable interrupts only after we're done with using rsp_scratch:
*/ */
movq %rsp,PER_CPU_VAR(rsp_scratch) movq %rsp,PER_CPU_VAR(rsp_scratch)
/* kernel_stack is set so that 5 slots (iret frame) are preallocated */
movq PER_CPU_VAR(kernel_stack),%rsp movq PER_CPU_VAR(kernel_stack),%rsp
ALLOC_PT_GPREGS_ON_STACK 8 /* +8: space for orig_ax */ ALLOC_PT_GPREGS_ON_STACK 6*8 /* 6*8: space for orig_ax and iret frame */
movq %rcx,RIP(%rsp) movq %rcx,RIP(%rsp)
movq PER_CPU_VAR(rsp_scratch),%rcx movq PER_CPU_VAR(rsp_scratch),%rcx
movq %r11,EFLAGS(%rsp) movq %r11,EFLAGS(%rsp)
......
...@@ -308,7 +308,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) ...@@ -308,7 +308,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
load_sp0(tss, next); load_sp0(tss, next);
this_cpu_write(kernel_stack, this_cpu_write(kernel_stack,
(unsigned long)task_stack_page(next_p) + (unsigned long)task_stack_page(next_p) +
THREAD_SIZE - KERNEL_STACK_OFFSET); THREAD_SIZE);
this_cpu_write(cpu_current_top_of_stack, this_cpu_write(cpu_current_top_of_stack,
(unsigned long)task_stack_page(next_p) + (unsigned long)task_stack_page(next_p) +
THREAD_SIZE); THREAD_SIZE);
......
...@@ -410,8 +410,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) ...@@ -410,8 +410,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
load_sp0(tss, next); load_sp0(tss, next);
this_cpu_write(kernel_stack, this_cpu_write(kernel_stack,
(unsigned long)task_stack_page(next_p) + (unsigned long)task_stack_page(next_p) + THREAD_SIZE);
THREAD_SIZE - KERNEL_STACK_OFFSET);
/* /*
* Now maybe reload the debug registers and handle I/O bitmaps * Now maybe reload the debug registers and handle I/O bitmaps
......
...@@ -813,8 +813,7 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle) ...@@ -813,8 +813,7 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
initial_gs = per_cpu_offset(cpu); initial_gs = per_cpu_offset(cpu);
#endif #endif
per_cpu(kernel_stack, cpu) = per_cpu(kernel_stack, cpu) =
(unsigned long)task_stack_page(idle) - (unsigned long)task_stack_page(idle) + THREAD_SIZE;
KERNEL_STACK_OFFSET + THREAD_SIZE;
early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
initial_code = (unsigned long)start_secondary; initial_code = (unsigned long)start_secondary;
stack_start = idle->thread.sp; stack_start = idle->thread.sp;
......
...@@ -452,8 +452,7 @@ static int xen_cpu_up(unsigned int cpu, struct task_struct *idle) ...@@ -452,8 +452,7 @@ static int xen_cpu_up(unsigned int cpu, struct task_struct *idle)
clear_tsk_thread_flag(idle, TIF_FORK); clear_tsk_thread_flag(idle, TIF_FORK);
#endif #endif
per_cpu(kernel_stack, cpu) = per_cpu(kernel_stack, cpu) =
(unsigned long)task_stack_page(idle) - (unsigned long)task_stack_page(idle) + THREAD_SIZE;
KERNEL_STACK_OFFSET + THREAD_SIZE;
xen_setup_runstate_info(cpu); xen_setup_runstate_info(cpu);
xen_setup_timer(cpu); xen_setup_timer(cpu);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment