History

x86/asm: Use register variable to get stack pointer value

Currently we use current_stack_pointer() function to get the value of the stack pointer register. Since commit: f5caf621ee35 ("x86/asm: Fix inline asm call constraints for Clang") ... we have a stack register variable declared. It can be used instead of current_stack_pointer() function which allows to optimize away some excessive "mov %rsp, %<dst>" instructions: -mov %rsp,%rdx -sub %rdx,%rax -cmp $0x3fff,%rax -ja ffffffff810722fd <ist_begin_non_atomic+0x2d> +sub %rsp,%rax +cmp $0x3fff,%rax +ja ffffffff810722fa <ist_begin_non_atomic+0x2a> Remove current_stack_pointer(), rename __asm_call_sp to current_stack_pointer and use it instead of the removed function.

Andrey Ryabinin committed 9 years ago

Commit 196bd481 parent bc829ee5 files · +7 −18Browse files

Unified · Split

5 files
  1. arch/x86/include/asm/asm.h +2 −2
  2. arch/x86/include/asm/thread_info.h +0 −11
  3. arch/x86/kernel/irq_32.c +3 −3
  4. arch/x86/kernel/traps.c +1 −1
  5. arch/x86/mm/tlb.c +1 −1
arch/x86/include/asm/asm.h+2−2
@@ -141,8 +141,8 @@ · 140 unmodified lines
141141 * gets set up by the containing function. If you forget to do this, objtool
142142 * may print a "call without frame pointer save/setup" warning.
143143 */
144−register unsigned long __asm_call_sp asm(_ASM_SP);
145−#define ASM_CALL_CONSTRAINT "+r" (__asm_call_sp)
144+register unsigned long current_stack_pointer asm(_ASM_SP);
145+#define ASM_CALL_CONSTRAINT "+r" (current_stack_pointer)
146146 #endif
147147
148148 #endif /* _ASM_X86_ASM_H */
arch/x86/include/asm/thread_info.h+0−11
@@ -158,17 +158,6 @@ struct thread_info { · 157 unmodified lines
158158 */
159159 #ifndef __ASSEMBLY__
160160
161−static inline unsigned long current_stack_pointer(void)
162−{
163− unsigned long sp;
164−#ifdef CONFIG_X86_64
165− asm("mov %%rsp,%0" : "=g" (sp));
166−#else
167− asm("mov %%esp,%0" : "=g" (sp));
168−#endif
169− return sp;
170−}
171−
172161 /*
173162 * Walks up the stack frames to make sure that the specified object is
174163 * entirely contained by a single stack frame.
arch/x86/kernel/irq_32.c+3−3
@@ -64,7 +64,7 @@ static void call_on_stack(void *func, void *stack) · 63 unmodified lines
6464
6565 static inline void *current_stack(void)
6666 {
67− return (void *)(current_stack_pointer() & ~(THREAD_SIZE - 1));
67+ return (void *)(current_stack_pointer & ~(THREAD_SIZE - 1));
6868 }
6969
7070 static inline int execute_on_irq_stack(int overflow, struct irq_desc *desc)
@@ -88,7 +88,7 @@ static inline int execute_on_irq_stack(int overflow, struct irq_desc *desc) · 17 unmodified lines
8888
8989 /* Save the next esp at the bottom of the stack */
9090 prev_esp = (u32 *)irqstk;
91− *prev_esp = current_stack_pointer();
91+ *prev_esp = current_stack_pointer;
9292
9393 if (unlikely(overflow))
9494 call_on_stack(print_stack_overflow, isp);
@@ -139,7 +139,7 @@ void do_softirq_own_stack(void) · 44 unmodified lines
139139
140140 /* Push the previous esp onto the stack */
141141 prev_esp = (u32 *)irqstk;
142− *prev_esp = current_stack_pointer();
142+ *prev_esp = current_stack_pointer;
143143
144144 call_on_stack(__do_softirq, isp);
145145 }
arch/x86/kernel/traps.c+1−1
@@ -142,7 +142,7 @@ void ist_begin_non_atomic(struct pt_regs *regs) · 141 unmodified lines
142142 * from double_fault.
143143 */
144144 BUG_ON((unsigned long)(current_top_of_stack() -
145− current_stack_pointer()) >= THREAD_SIZE);
145+ current_stack_pointer) >= THREAD_SIZE);
146146
147147 preempt_enable_no_resched();
148148 }
arch/x86/mm/tlb.c+1−1
@@ -191,7 +191,7 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next, · 190 unmodified lines
191191 * mapped in the new pgd, we'll double-fault. Forcibly
192192 * map it.
193193 */
194− unsigned int index = pgd_index(current_stack_pointer());
194+ unsigned int index = pgd_index(current_stack_pointer);
195195 pgd_t *pgd = next->pgd + index;
196196
197197 if (unlikely(pgd_none(*pgd)))