Skip to content

Commit

Permalink
x86/stackframe: Move ENCODE_FRAME_POINTER to asm/frame.h
Browse files Browse the repository at this point in the history
In preparation for wider use, move the ENCODE_FRAME_POINTER macros to
a common header and provide inline asm versions.

These macros are used to encode a pt_regs frame for the unwinder; see
unwind_frame.c:decode_frame_pointer().

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
  • Loading branch information
Peter Zijlstra authored and Ingo Molnar committed Jun 25, 2019
1 parent 5e1246f commit a9b3c69
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 31 deletions.
15 changes: 0 additions & 15 deletions arch/x86/entry/calling.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,21 +172,6 @@ For 32-bit we have the following conventions - kernel is built with
.endif
.endm

/*
* This is a sneaky trick to help the unwinder find pt_regs on the stack. The
* frame pointer is replaced with an encoded pointer to pt_regs. The encoding
* is just setting the LSB, which makes it an invalid stack address and is also
* a signal to the unwinder that it's a pt_regs pointer in disguise.
*
* NOTE: This macro must be used *after* PUSH_AND_CLEAR_REGS because it corrupts
* the original rbp.
*/
.macro ENCODE_FRAME_POINTER ptregs_offset=0
#ifdef CONFIG_FRAME_POINTER
leaq 1+\ptregs_offset(%rsp), %rbp
#endif
.endm

#ifdef CONFIG_PAGE_TABLE_ISOLATION

/*
Expand Down
16 changes: 0 additions & 16 deletions arch/x86/entry/entry_32.S
Original file line number Diff line number Diff line change
Expand Up @@ -246,22 +246,6 @@
.Lend_\@:
.endm

/*
* This is a sneaky trick to help the unwinder find pt_regs on the stack. The
* frame pointer is replaced with an encoded pointer to pt_regs. The encoding
* is just clearing the MSB, which makes it an invalid stack address and is also
* a signal to the unwinder that it's a pt_regs pointer in disguise.
*
* NOTE: This macro must be used *after* SAVE_ALL because it corrupts the
* original rbp.
*/
.macro ENCODE_FRAME_POINTER
#ifdef CONFIG_FRAME_POINTER
mov %esp, %ebp
andl $0x7fffffff, %ebp
#endif
.endm

.macro RESTORE_INT_REGS
popl %ebx
popl %ecx
Expand Down
49 changes: 49 additions & 0 deletions arch/x86/include/asm/frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,35 @@
pop %_ASM_BP
.endm

#ifdef CONFIG_X86_64
/*
* This is a sneaky trick to help the unwinder find pt_regs on the stack. The
* frame pointer is replaced with an encoded pointer to pt_regs. The encoding
* is just setting the LSB, which makes it an invalid stack address and is also
* a signal to the unwinder that it's a pt_regs pointer in disguise.
*
* NOTE: This macro must be used *after* PUSH_AND_CLEAR_REGS because it corrupts
* the original rbp.
*/
.macro ENCODE_FRAME_POINTER ptregs_offset=0
leaq 1+\ptregs_offset(%rsp), %rbp
.endm
#else /* !CONFIG_X86_64 */
/*
* This is a sneaky trick to help the unwinder find pt_regs on the stack. The
* frame pointer is replaced with an encoded pointer to pt_regs. The encoding
* is just clearing the MSB, which makes it an invalid stack address and is also
* a signal to the unwinder that it's a pt_regs pointer in disguise.
*
* NOTE: This macro must be used *after* SAVE_ALL because it corrupts the
* original ebp.
*/
.macro ENCODE_FRAME_POINTER
mov %esp, %ebp
andl $0x7fffffff, %ebp
.endm
#endif /* CONFIG_X86_64 */

#else /* !__ASSEMBLY__ */

#define FRAME_BEGIN \
Expand All @@ -30,12 +59,32 @@

#define FRAME_END "pop %" _ASM_BP "\n"

#ifdef CONFIG_X86_64
#define ENCODE_FRAME_POINTER \
"lea 1(%rsp), %rbp\n\t"
#else /* !CONFIG_X86_64 */
#define ENCODE_FRAME_POINTER \
"movl %esp, %ebp\n\t" \
"andl $0x7fffffff, %ebp\n\t"
#endif /* CONFIG_X86_64 */

#endif /* __ASSEMBLY__ */

#define FRAME_OFFSET __ASM_SEL(4, 8)

#else /* !CONFIG_FRAME_POINTER */

#ifdef __ASSEMBLY__

.macro ENCODE_FRAME_POINTER ptregs_offset=0
.endm

#else /* !__ASSEMBLY */

#define ENCODE_FRAME_POINTER

#endif

#define FRAME_BEGIN
#define FRAME_END
#define FRAME_OFFSET 0
Expand Down

0 comments on commit a9b3c69

Please sign in to comment.