Skip to content

Commit

Permalink
x86-64: Fix CFI data for interrupt frames
Browse files Browse the repository at this point in the history
The patch titled "x86: Don't use frame pointer to save old stack
on irq entry" did not properly adjust CFI directives, so this
patch is a follow-up to that one.

With the old stack pointer no longer stored in a callee-saved
register (plus some offset), we now have to use a CFA expression
to describe the memory location where it is being found. This
requires the use of .cfi_escape (allowing arbitrary byte streams
to be emitted into .eh_frame), as there is no
.cfi_def_cfa_expression (which also cannot reasonably be
expected, as it would require a full expression parser).

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Link: http://lkml.kernel.org/r/4E8360200200007800058467@nat28.tlf.novell.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
  • Loading branch information
Jan Beulich authored and Ingo Molnar committed Sep 28, 2011
1 parent e05139f commit eab9e61
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 5 deletions.
2 changes: 2 additions & 0 deletions arch/x86/include/asm/dwarf2.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#define CFI_REMEMBER_STATE .cfi_remember_state
#define CFI_RESTORE_STATE .cfi_restore_state
#define CFI_UNDEFINED .cfi_undefined
#define CFI_ESCAPE .cfi_escape

#ifdef CONFIG_AS_CFI_SIGNAL_FRAME
#define CFI_SIGNAL_FRAME .cfi_signal_frame
Expand Down Expand Up @@ -68,6 +69,7 @@
#define CFI_REMEMBER_STATE cfi_ignore
#define CFI_RESTORE_STATE cfi_ignore
#define CFI_UNDEFINED cfi_ignore
#define CFI_ESCAPE cfi_ignore
#define CFI_SIGNAL_FRAME cfi_ignore

#endif
Expand Down
14 changes: 9 additions & 5 deletions arch/x86/kernel/entry_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -331,10 +331,15 @@ ENDPROC(native_usergs_sysret64)
1: incl PER_CPU_VAR(irq_count)
jne 2f
mov PER_CPU_VAR(irq_stack_ptr),%rsp
EMPTY_FRAME 0
CFI_DEF_CFA_REGISTER rsi

2: /* Store previous stack value */
pushq %rsi
CFI_ESCAPE 0x0f /* DW_CFA_def_cfa_expression */, 6, \
0x77 /* DW_OP_breg7 */, 0, \
0x06 /* DW_OP_deref */, \
0x08 /* DW_OP_const1u */, SS+8-RBP, \
0x22 /* DW_OP_plus */
/* We entered an interrupt context - irqs are off: */
TRACE_IRQS_OFF
.endm
Expand Down Expand Up @@ -788,7 +793,6 @@ END(interrupt)
subq $ORIG_RAX-RBP, %rsp
CFI_ADJUST_CFA_OFFSET ORIG_RAX-RBP
SAVE_ARGS_IRQ
PARTIAL_FRAME 0
call \func
.endm

Expand All @@ -813,10 +817,10 @@ ret_from_intr:

/* Restore saved previous stack */
popq %rsi
leaq 16(%rsi), %rsp

CFI_DEF_CFA_REGISTER rsi
leaq ARGOFFSET-RBP(%rsi), %rsp
CFI_DEF_CFA_REGISTER rsp
CFI_ADJUST_CFA_OFFSET -16
CFI_ADJUST_CFA_OFFSET RBP-ARGOFFSET

exit_intr:
GET_THREAD_INFO(%rcx)
Expand Down

0 comments on commit eab9e61

Please sign in to comment.