Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eab9e613 authored by Jan Beulich's avatar Jan Beulich Committed by Ingo Molnar
Browse files

x86-64: Fix CFI data for interrupt frames



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: default avatarJan Beulich <jbeulich@suse.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Link: http://lkml.kernel.org/r/4E8360200200007800058467@nat28.tlf.novell.com


Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent e05139f2
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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
@@ -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
+9 −5
Original line number Diff line number Diff line
@@ -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
@@ -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

@@ -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)