LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH v3 1/6] x86/stacktrace: do not unwind after user regs
@ 2018-05-18  6:47 Jiri Slaby
  2018-05-18  6:47 ` [PATCH v3 2/6] x86/stacktrace: remove STACKTRACE_DUMP_ONCE Jiri Slaby
                   ` (5 more replies)
  0 siblings, 6 replies; 12+ messages in thread
From: Jiri Slaby @ 2018-05-18  6:47 UTC (permalink / raw)
  To: mingo
  Cc: linux-kernel, Jiri Slaby, Thomas Gleixner, H. Peter Anvin, x86,
	Josh Poimboeuf

Josh pointed out, that there is no way a frame can be after user regs.
So remove the last unwind and the check.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: x86@kernel.org
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
---
 arch/x86/kernel/stacktrace.c | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/arch/x86/kernel/stacktrace.c b/arch/x86/kernel/stacktrace.c
index 093f2ea5dd56..8948b7d9c064 100644
--- a/arch/x86/kernel/stacktrace.c
+++ b/arch/x86/kernel/stacktrace.c
@@ -113,15 +113,6 @@ __save_stack_trace_reliable(struct stack_trace *trace,
 			if (!user_mode(regs))
 				return -EINVAL;
 
-			/*
-			 * The last frame contains the user mode syscall
-			 * pt_regs.  Skip it and finish the unwind.
-			 */
-			unwind_next_frame(&state);
-			if (!unwind_done(&state)) {
-				STACKTRACE_DUMP_ONCE(task);
-				return -EINVAL;
-			}
 			break;
 		}
 
-- 
2.16.3

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v3 2/6] x86/stacktrace: remove STACKTRACE_DUMP_ONCE
  2018-05-18  6:47 [PATCH v3 1/6] x86/stacktrace: do not unwind after user regs Jiri Slaby
@ 2018-05-18  6:47 ` Jiri Slaby
  2018-05-18  6:47 ` [PATCH v3 3/6] x86/stacktrace: clarify the reliable success paths Jiri Slaby
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: Jiri Slaby @ 2018-05-18  6:47 UTC (permalink / raw)
  To: mingo
  Cc: linux-kernel, Jiri Slaby, Thomas Gleixner, H. Peter Anvin, x86,
	Josh Poimboeuf

The stack unwinding can sometimes fail yet. Especially with the
generated debug info. So do not yell at users -- live patching (the only
user of this interface) will inform the user about the failure
gracefully.

And given this was the only user of the macro, remove the macro proper
too.

[v3] remove also the macro

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: x86@kernel.org
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
---
 arch/x86/kernel/stacktrace.c | 18 ++----------------
 1 file changed, 2 insertions(+), 16 deletions(-)

diff --git a/arch/x86/kernel/stacktrace.c b/arch/x86/kernel/stacktrace.c
index 8948b7d9c064..f9dacf6d4667 100644
--- a/arch/x86/kernel/stacktrace.c
+++ b/arch/x86/kernel/stacktrace.c
@@ -81,16 +81,6 @@ EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
 
 #ifdef CONFIG_HAVE_RELIABLE_STACKTRACE
 
-#define STACKTRACE_DUMP_ONCE(task) ({				\
-	static bool __section(.data.unlikely) __dumped;		\
-								\
-	if (!__dumped) {					\
-		__dumped = true;				\
-		WARN_ON(1);					\
-		show_stack(task, NULL);				\
-	}							\
-})
-
 static int __always_inline
 __save_stack_trace_reliable(struct stack_trace *trace,
 			    struct task_struct *task)
@@ -123,20 +113,16 @@ __save_stack_trace_reliable(struct stack_trace *trace,
 		 * generated code which __kernel_text_address() doesn't know
 		 * about.
 		 */
-		if (!addr) {
-			STACKTRACE_DUMP_ONCE(task);
+		if (!addr)
 			return -EINVAL;
-		}
 
 		if (save_stack_address(trace, addr, false))
 			return -EINVAL;
 	}
 
 	/* Check for stack corruption */
-	if (unwind_error(&state)) {
-		STACKTRACE_DUMP_ONCE(task);
+	if (unwind_error(&state))
 		return -EINVAL;
-	}
 
 	if (trace->nr_entries < trace->max_entries)
 		trace->entries[trace->nr_entries++] = ULONG_MAX;
-- 
2.16.3

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v3 3/6] x86/stacktrace: clarify the reliable success paths
  2018-05-18  6:47 [PATCH v3 1/6] x86/stacktrace: do not unwind after user regs Jiri Slaby
  2018-05-18  6:47 ` [PATCH v3 2/6] x86/stacktrace: remove STACKTRACE_DUMP_ONCE Jiri Slaby
@ 2018-05-18  6:47 ` Jiri Slaby
  2018-05-18  6:47 ` [PATCH v3 4/6] x86/stacktrace: do not fail for ORC with regs on stack Jiri Slaby
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: Jiri Slaby @ 2018-05-18  6:47 UTC (permalink / raw)
  To: mingo
  Cc: linux-kernel, Jiri Slaby, Thomas Gleixner, H. Peter Anvin, x86,
	Josh Poimboeuf

Make clear which path is for user tasks and for kthreads and idle
tasks. This will allow easier plug-in of the ORC unwinder in the next
patches.

Note that we added a check for unwind error to the top of the loop, so
that an error is returned also for user tasks (the 'goto success' would
skip the check after the loop otherwise).

[v3] check for unwind_error in the loop

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: x86@kernel.org
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
---
 arch/x86/kernel/stacktrace.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/stacktrace.c b/arch/x86/kernel/stacktrace.c
index f9dacf6d4667..6acf1d5ca832 100644
--- a/arch/x86/kernel/stacktrace.c
+++ b/arch/x86/kernel/stacktrace.c
@@ -89,21 +89,24 @@ __save_stack_trace_reliable(struct stack_trace *trace,
 	struct pt_regs *regs;
 	unsigned long addr;
 
-	for (unwind_start(&state, task, NULL, NULL); !unwind_done(&state);
+	for (unwind_start(&state, task, NULL, NULL);
+	     !unwind_done(&state) && !unwind_error(&state);
 	     unwind_next_frame(&state)) {
 
 		regs = unwind_get_entry_regs(&state, NULL);
 		if (regs) {
+			/* Success path for user tasks */
+			if (user_mode(regs))
+				goto success;
+
 			/*
 			 * Kernel mode registers on the stack indicate an
 			 * in-kernel interrupt or exception (e.g., preemption
 			 * or a page fault), which can make frame pointers
 			 * unreliable.
 			 */
-			if (!user_mode(regs))
-				return -EINVAL;
 
-			break;
+			return -EINVAL;
 		}
 
 		addr = unwind_get_return_address(&state);
@@ -124,6 +127,11 @@ __save_stack_trace_reliable(struct stack_trace *trace,
 	if (unwind_error(&state))
 		return -EINVAL;
 
+	/* Success path for non-user tasks, i.e. kthreads and idle tasks */
+	if (!(task->flags & (PF_KTHREAD | PF_IDLE)))
+		return -EINVAL;
+
+success:
 	if (trace->nr_entries < trace->max_entries)
 		trace->entries[trace->nr_entries++] = ULONG_MAX;
 
-- 
2.16.3

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v3 4/6] x86/stacktrace: do not fail for ORC with regs on stack
  2018-05-18  6:47 [PATCH v3 1/6] x86/stacktrace: do not unwind after user regs Jiri Slaby
  2018-05-18  6:47 ` [PATCH v3 2/6] x86/stacktrace: remove STACKTRACE_DUMP_ONCE Jiri Slaby
  2018-05-18  6:47 ` [PATCH v3 3/6] x86/stacktrace: clarify the reliable success paths Jiri Slaby
@ 2018-05-18  6:47 ` Jiri Slaby
  2018-05-18  6:47 ` [PATCH v3 5/6] x86/unwind/orc: Detect the end of the stack Jiri Slaby
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: Jiri Slaby @ 2018-05-18  6:47 UTC (permalink / raw)
  To: mingo
  Cc: linux-kernel, Jiri Slaby, Thomas Gleixner, H. Peter Anvin, x86,
	Josh Poimboeuf

save_stack_trace_reliable now returns "non reliable" when there are
kernel pt_regs on stack. This means an interrupt or exception happened
somewhere down the route. It is a problem for the frame pointer
unwinder, because the frame might not have been set up yet when the irq
happened, so the unwinder might fail to unwind from the interrupted
function.

With ORC, this is not a problem, as ORC has out-of-band data. We can
find ORC data even for the IP in the interrupted function and always
unwind one level up reliably.

So lift the check to apply only when CONFIG_FRAME_POINTER is enabled.

[v2]
- rewrite the code in favor of Josh's suggestions

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: x86@kernel.org
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
---
 arch/x86/kernel/stacktrace.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/stacktrace.c b/arch/x86/kernel/stacktrace.c
index 6acf1d5ca832..7627455047c2 100644
--- a/arch/x86/kernel/stacktrace.c
+++ b/arch/x86/kernel/stacktrace.c
@@ -106,7 +106,8 @@ __save_stack_trace_reliable(struct stack_trace *trace,
 			 * unreliable.
 			 */
 
-			return -EINVAL;
+			if (IS_ENABLED(CONFIG_FRAME_POINTER))
+				return -EINVAL;
 		}
 
 		addr = unwind_get_return_address(&state);
-- 
2.16.3

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v3 5/6] x86/unwind/orc: Detect the end of the stack
  2018-05-18  6:47 [PATCH v3 1/6] x86/stacktrace: do not unwind after user regs Jiri Slaby
                   ` (2 preceding siblings ...)
  2018-05-18  6:47 ` [PATCH v3 4/6] x86/stacktrace: do not fail for ORC with regs on stack Jiri Slaby
@ 2018-05-18  6:47 ` Jiri Slaby
  2018-05-18  6:47 ` [PATCH v3 6/6] x86/stacktrace: enable HAVE_RELIABLE_STACKTRACE for the ORC unwinder Jiri Slaby
  2018-05-18  6:55 ` [PATCH v3 1/6] x86/stacktrace: do not unwind after user regs Ingo Molnar
  5 siblings, 0 replies; 12+ messages in thread
From: Jiri Slaby @ 2018-05-18  6:47 UTC (permalink / raw)
  To: mingo; +Cc: linux-kernel, Josh Poimboeuf, Jiri Slaby

From: Josh Poimboeuf <jpoimboe@redhat.com>

The existing UNWIND_HINT_EMPTY annotations happen to be good indicators
of where entry code calls into C code for the first time.  So also use
them to mark the end of the stack for the ORC unwinder.

Use that information to set unwind->error if the ORC unwinder doesn't
unwind all the way to the end.  This will be needed for enabling
HAVE_RELIABLE_STACKTRACE for the ORC unwinder so we can use it with the
livepatch consistency model.

Thanks to Jiri Slaby for teaching the ORCs about the unwind hints.

[v2] this patch is new in v2

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 arch/x86/entry/entry_64.S                      |  1 +
 arch/x86/include/asm/orc_types.h               |  2 +
 arch/x86/include/asm/unwind_hints.h            | 16 +++++---
 arch/x86/kernel/unwind_orc.c                   | 52 +++++++++++++++-----------
 tools/objtool/arch/x86/include/asm/orc_types.h |  2 +
 tools/objtool/check.c                          |  1 +
 tools/objtool/check.h                          |  2 +-
 tools/objtool/orc_dump.c                       |  3 +-
 tools/objtool/orc_gen.c                        |  2 +
 9 files changed, 52 insertions(+), 29 deletions(-)

diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 702ff719443b..e40ec8549fdc 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -410,6 +410,7 @@ SYM_CODE_START(ret_from_fork)
 
 1:
 	/* kernel thread */
+	UNWIND_HINT_EMPTY
 	movq	%r12, %rdi
 	CALL_NOSPEC %rbx
 	/*
diff --git a/arch/x86/include/asm/orc_types.h b/arch/x86/include/asm/orc_types.h
index 9c9dc579bd7d..46f516dd80ce 100644
--- a/arch/x86/include/asm/orc_types.h
+++ b/arch/x86/include/asm/orc_types.h
@@ -88,6 +88,7 @@ struct orc_entry {
 	unsigned	sp_reg:4;
 	unsigned	bp_reg:4;
 	unsigned	type:2;
+	unsigned	end:1;
 } __packed;
 
 /*
@@ -101,6 +102,7 @@ struct unwind_hint {
 	s16		sp_offset;
 	u8		sp_reg;
 	u8		type;
+	u8		end;
 };
 #endif /* __ASSEMBLY__ */
 
diff --git a/arch/x86/include/asm/unwind_hints.h b/arch/x86/include/asm/unwind_hints.h
index bae46fc6b9de..0bcdb1279361 100644
--- a/arch/x86/include/asm/unwind_hints.h
+++ b/arch/x86/include/asm/unwind_hints.h
@@ -26,7 +26,7 @@
  * the debuginfo as necessary.  It will also warn if it sees any
  * inconsistencies.
  */
-.macro UNWIND_HINT sp_reg=ORC_REG_SP sp_offset=0 type=ORC_TYPE_CALL
+.macro UNWIND_HINT sp_reg=ORC_REG_SP sp_offset=0 type=ORC_TYPE_CALL end=0
 #ifdef CONFIG_STACK_VALIDATION
 .Lunwind_hint_ip_\@:
 	.pushsection .discard.unwind_hints
@@ -35,12 +35,14 @@
 		.short \sp_offset
 		.byte \sp_reg
 		.byte \type
+		.byte \end
+		.balign 4
 	.popsection
 #endif
 .endm
 
 .macro UNWIND_HINT_EMPTY
-	UNWIND_HINT sp_reg=ORC_REG_UNDEFINED
+	UNWIND_HINT sp_reg=ORC_REG_UNDEFINED end=1
 .endm
 
 .macro UNWIND_HINT_REGS base=%rsp offset=0 indirect=0 extra=1 iret=0
@@ -86,19 +88,21 @@
 
 #else /* !__ASSEMBLY__ */
 
-#define UNWIND_HINT(sp_reg, sp_offset, type)			\
+#define UNWIND_HINT(sp_reg, sp_offset, type, end)		\
 	"987: \n\t"						\
 	".pushsection .discard.unwind_hints\n\t"		\
 	/* struct unwind_hint */				\
 	".long 987b - .\n\t"					\
-	".short " __stringify(sp_offset) "\n\t"		\
+	".short " __stringify(sp_offset) "\n\t"			\
 	".byte " __stringify(sp_reg) "\n\t"			\
 	".byte " __stringify(type) "\n\t"			\
+	".byte " __stringify(end) "\n\t"			\
+	".balign 4 \n\t"					\
 	".popsection\n\t"
 
-#define UNWIND_HINT_SAVE UNWIND_HINT(0, 0, UNWIND_HINT_TYPE_SAVE)
+#define UNWIND_HINT_SAVE UNWIND_HINT(0, 0, UNWIND_HINT_TYPE_SAVE, 0)
 
-#define UNWIND_HINT_RESTORE UNWIND_HINT(0, 0, UNWIND_HINT_TYPE_RESTORE)
+#define UNWIND_HINT_RESTORE UNWIND_HINT(0, 0, UNWIND_HINT_TYPE_RESTORE, 0)
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/arch/x86/kernel/unwind_orc.c b/arch/x86/kernel/unwind_orc.c
index feb28fee6cea..26038eacf74a 100644
--- a/arch/x86/kernel/unwind_orc.c
+++ b/arch/x86/kernel/unwind_orc.c
@@ -198,7 +198,7 @@ static int orc_sort_cmp(const void *_a, const void *_b)
 	 * whitelisted .o files which didn't get objtool generation.
 	 */
 	orc_a = cur_orc_table + (a - cur_orc_ip_table);
-	return orc_a->sp_reg == ORC_REG_UNDEFINED ? -1 : 1;
+	return orc_a->sp_reg == ORC_REG_UNDEFINED && !orc_a->end ? -1 : 1;
 }
 
 #ifdef CONFIG_MODULES
@@ -352,7 +352,7 @@ static bool deref_stack_iret_regs(struct unwind_state *state, unsigned long addr
 
 bool unwind_next_frame(struct unwind_state *state)
 {
-	unsigned long ip_p, sp, orig_ip, prev_sp = state->sp;
+	unsigned long ip_p, sp, orig_ip = state->ip, prev_sp = state->sp;
 	enum stack_type prev_type = state->stack_info.type;
 	struct orc_entry *orc;
 	bool indirect = false;
@@ -363,9 +363,9 @@ bool unwind_next_frame(struct unwind_state *state)
 	/* Don't let modules unload while we're reading their ORC data. */
 	preempt_disable();
 
-	/* Have we reached the end? */
+	/* End-of-stack check for user tasks: */
 	if (state->regs && user_mode(state->regs))
-		goto done;
+		goto the_end;
 
 	/*
 	 * Find the orc_entry associated with the text address.
@@ -374,9 +374,16 @@ bool unwind_next_frame(struct unwind_state *state)
 	 * calls and calls to noreturn functions.
 	 */
 	orc = orc_find(state->signal ? state->ip : state->ip - 1);
-	if (!orc || orc->sp_reg == ORC_REG_UNDEFINED)
-		goto done;
-	orig_ip = state->ip;
+	if (!orc)
+		goto err;
+
+	/* End-of-stack check for kernel threads: */
+	if (orc->sp_reg == ORC_REG_UNDEFINED) {
+		if (!orc->end)
+			goto err;
+
+		goto the_end;
+	}
 
 	/* Find the previous frame's stack: */
 	switch (orc->sp_reg) {
@@ -402,7 +409,7 @@ bool unwind_next_frame(struct unwind_state *state)
 		if (!state->regs || !state->full_regs) {
 			orc_warn("missing regs for base reg R10 at ip %pB\n",
 				 (void *)state->ip);
-			goto done;
+			goto err;
 		}
 		sp = state->regs->r10;
 		break;
@@ -411,7 +418,7 @@ bool unwind_next_frame(struct unwind_state *state)
 		if (!state->regs || !state->full_regs) {
 			orc_warn("missing regs for base reg R13 at ip %pB\n",
 				 (void *)state->ip);
-			goto done;
+			goto err;
 		}
 		sp = state->regs->r13;
 		break;
@@ -420,7 +427,7 @@ bool unwind_next_frame(struct unwind_state *state)
 		if (!state->regs || !state->full_regs) {
 			orc_warn("missing regs for base reg DI at ip %pB\n",
 				 (void *)state->ip);
-			goto done;
+			goto err;
 		}
 		sp = state->regs->di;
 		break;
@@ -429,7 +436,7 @@ bool unwind_next_frame(struct unwind_state *state)
 		if (!state->regs || !state->full_regs) {
 			orc_warn("missing regs for base reg DX at ip %pB\n",
 				 (void *)state->ip);
-			goto done;
+			goto err;
 		}
 		sp = state->regs->dx;
 		break;
@@ -437,12 +444,12 @@ bool unwind_next_frame(struct unwind_state *state)
 	default:
 		orc_warn("unknown SP base reg %d for ip %pB\n",
 			 orc->sp_reg, (void *)state->ip);
-		goto done;
+		goto err;
 	}
 
 	if (indirect) {
 		if (!deref_stack_reg(state, sp, &sp))
-			goto done;
+			goto err;
 	}
 
 	/* Find IP, SP and possibly regs: */
@@ -451,7 +458,7 @@ bool unwind_next_frame(struct unwind_state *state)
 		ip_p = sp - sizeof(long);
 
 		if (!deref_stack_reg(state, ip_p, &state->ip))
-			goto done;
+			goto err;
 
 		state->ip = ftrace_graph_ret_addr(state->task, &state->graph_idx,
 						  state->ip, (void *)ip_p);
@@ -465,7 +472,7 @@ bool unwind_next_frame(struct unwind_state *state)
 		if (!deref_stack_regs(state, sp, &state->ip, &state->sp)) {
 			orc_warn("can't dereference registers at %p for ip %pB\n",
 				 (void *)sp, (void *)orig_ip);
-			goto done;
+			goto err;
 		}
 
 		state->regs = (struct pt_regs *)sp;
@@ -477,7 +484,7 @@ bool unwind_next_frame(struct unwind_state *state)
 		if (!deref_stack_iret_regs(state, sp, &state->ip, &state->sp)) {
 			orc_warn("can't dereference iret registers at %p for ip %pB\n",
 				 (void *)sp, (void *)orig_ip);
-			goto done;
+			goto err;
 		}
 
 		state->regs = (void *)sp - IRET_FRAME_OFFSET;
@@ -500,18 +507,18 @@ bool unwind_next_frame(struct unwind_state *state)
 
 	case ORC_REG_PREV_SP:
 		if (!deref_stack_reg(state, sp + orc->bp_offset, &state->bp))
-			goto done;
+			goto err;
 		break;
 
 	case ORC_REG_BP:
 		if (!deref_stack_reg(state, state->bp + orc->bp_offset, &state->bp))
-			goto done;
+			goto err;
 		break;
 
 	default:
 		orc_warn("unknown BP base reg %d for ip %pB\n",
 			 orc->bp_reg, (void *)orig_ip);
-		goto done;
+		goto err;
 	}
 
 	/* Prevent a recursive loop due to bad ORC data: */
@@ -520,13 +527,16 @@ bool unwind_next_frame(struct unwind_state *state)
 	    state->sp <= prev_sp) {
 		orc_warn("stack going in the wrong direction? ip=%pB\n",
 			 (void *)orig_ip);
-		goto done;
+		goto err;
 	}
 
 	preempt_enable();
 	return true;
 
-done:
+err:
+	state->error = true;
+
+the_end:
 	preempt_enable();
 	state->stack_info.type = STACK_TYPE_UNKNOWN;
 	return false;
diff --git a/tools/objtool/arch/x86/include/asm/orc_types.h b/tools/objtool/arch/x86/include/asm/orc_types.h
index 9c9dc579bd7d..46f516dd80ce 100644
--- a/tools/objtool/arch/x86/include/asm/orc_types.h
+++ b/tools/objtool/arch/x86/include/asm/orc_types.h
@@ -88,6 +88,7 @@ struct orc_entry {
 	unsigned	sp_reg:4;
 	unsigned	bp_reg:4;
 	unsigned	type:2;
+	unsigned	end:1;
 } __packed;
 
 /*
@@ -101,6 +102,7 @@ struct unwind_hint {
 	s16		sp_offset;
 	u8		sp_reg;
 	u8		type;
+	u8		end;
 };
 #endif /* __ASSEMBLY__ */
 
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 5409f6f6c48d..fef15cea9f1e 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -1109,6 +1109,7 @@ static int read_unwind_hints(struct objtool_file *file)
 
 		cfa->offset = hint->sp_offset;
 		insn->state.type = hint->type;
+		insn->state.end = hint->end;
 	}
 
 	return 0;
diff --git a/tools/objtool/check.h b/tools/objtool/check.h
index c6b68fcb926f..95700a2bcb7c 100644
--- a/tools/objtool/check.h
+++ b/tools/objtool/check.h
@@ -31,7 +31,7 @@ struct insn_state {
 	int stack_size;
 	unsigned char type;
 	bool bp_scratch;
-	bool drap;
+	bool drap, end;
 	int drap_reg, drap_offset;
 	struct cfi_reg vals[CFI_NUM_REGS];
 };
diff --git a/tools/objtool/orc_dump.c b/tools/objtool/orc_dump.c
index c3343820916a..faa444270ee3 100644
--- a/tools/objtool/orc_dump.c
+++ b/tools/objtool/orc_dump.c
@@ -203,7 +203,8 @@ int orc_dump(const char *_objname)
 
 		print_reg(orc[i].bp_reg, orc[i].bp_offset);
 
-		printf(" type:%s\n", orc_type_name(orc[i].type));
+		printf(" type:%s end:%d\n",
+		       orc_type_name(orc[i].type), orc[i].end);
 	}
 
 	elf_end(elf);
diff --git a/tools/objtool/orc_gen.c b/tools/objtool/orc_gen.c
index 18384d9be4e1..3f98dcfbc177 100644
--- a/tools/objtool/orc_gen.c
+++ b/tools/objtool/orc_gen.c
@@ -31,6 +31,8 @@ int create_orc(struct objtool_file *file)
 		struct cfi_reg *cfa = &insn->state.cfa;
 		struct cfi_reg *bp = &insn->state.regs[CFI_BP];
 
+		orc->end = insn->state.end;
+
 		if (cfa->base == CFI_UNDEFINED) {
 			orc->sp_reg = ORC_REG_UNDEFINED;
 			continue;
-- 
2.16.3

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v3 6/6] x86/stacktrace: enable HAVE_RELIABLE_STACKTRACE for the ORC unwinder
  2018-05-18  6:47 [PATCH v3 1/6] x86/stacktrace: do not unwind after user regs Jiri Slaby
                   ` (3 preceding siblings ...)
  2018-05-18  6:47 ` [PATCH v3 5/6] x86/unwind/orc: Detect the end of the stack Jiri Slaby
@ 2018-05-18  6:47 ` Jiri Slaby
  2018-05-18  6:55 ` [PATCH v3 1/6] x86/stacktrace: do not unwind after user regs Ingo Molnar
  5 siblings, 0 replies; 12+ messages in thread
From: Jiri Slaby @ 2018-05-18  6:47 UTC (permalink / raw)
  To: mingo
  Cc: linux-kernel, Jiri Slaby, Josh Poimboeuf, Thomas Gleixner,
	H. Peter Anvin, x86

In SUSE, we need a reliable stack unwinder for kernel live patching, but
we do not want to enable frame pointers for performance reasons. So
after the previous patches to make the ORC reliable, mark ORC as a
reliable stack unwinder on x86.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: x86@kernel.org
---
 arch/x86/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 47e7f582f86a..e4199fbcc7f2 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -181,7 +181,7 @@ config X86
 	select HAVE_PERF_USER_STACK_DUMP
 	select HAVE_RCU_TABLE_FREE
 	select HAVE_REGS_AND_STACK_ACCESS_API
-	select HAVE_RELIABLE_STACKTRACE		if X86_64 && UNWINDER_FRAME_POINTER && STACK_VALIDATION
+	select HAVE_RELIABLE_STACKTRACE		if X86_64 && (UNWINDER_FRAME_POINTER || UNWINDER_ORC) && STACK_VALIDATION
 	select HAVE_STACK_VALIDATION		if X86_64
 	select HAVE_SYSCALL_TRACEPOINTS
 	select HAVE_UNSTABLE_SCHED_CLOCK
-- 
2.16.3

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 1/6] x86/stacktrace: do not unwind after user regs
  2018-05-18  6:47 [PATCH v3 1/6] x86/stacktrace: do not unwind after user regs Jiri Slaby
                   ` (4 preceding siblings ...)
  2018-05-18  6:47 ` [PATCH v3 6/6] x86/stacktrace: enable HAVE_RELIABLE_STACKTRACE for the ORC unwinder Jiri Slaby
@ 2018-05-18  6:55 ` Ingo Molnar
  2018-05-18 22:41   ` Josh Poimboeuf
  5 siblings, 1 reply; 12+ messages in thread
From: Ingo Molnar @ 2018-05-18  6:55 UTC (permalink / raw)
  To: Jiri Slaby, Josh Poimboeuf, Peter Zijlstra, Andy Lutomirski,
	Borislav Petkov
  Cc: mingo, linux-kernel, Thomas Gleixner, H. Peter Anvin, x86,
	Josh Poimboeuf


* Jiri Slaby <jslaby@suse.cz> wrote:

> Josh pointed out, that there is no way a frame can be after user regs.
> So remove the last unwind and the check.
> 
> Signed-off-by: Jiri Slaby <jslaby@suse.cz>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: "H. Peter Anvin" <hpa@zytor.com>
> Cc: x86@kernel.org
> Cc: Josh Poimboeuf <jpoimboe@redhat.com>

Josh: an Acked-by or Reviewed-by for the whole series from you would be nice.

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 1/6] x86/stacktrace: do not unwind after user regs
  2018-05-18  6:55 ` [PATCH v3 1/6] x86/stacktrace: do not unwind after user regs Ingo Molnar
@ 2018-05-18 22:41   ` Josh Poimboeuf
  2018-05-19  7:42     ` Ingo Molnar
  0 siblings, 1 reply; 12+ messages in thread
From: Josh Poimboeuf @ 2018-05-18 22:41 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Jiri Slaby, Peter Zijlstra, Andy Lutomirski, Borislav Petkov,
	mingo, linux-kernel, Thomas Gleixner, H. Peter Anvin, x86

On Fri, May 18, 2018 at 08:55:47AM +0200, Ingo Molnar wrote:
> 
> * Jiri Slaby <jslaby@suse.cz> wrote:
> 
> > Josh pointed out, that there is no way a frame can be after user regs.
> > So remove the last unwind and the check.
> > 
> > Signed-off-by: Jiri Slaby <jslaby@suse.cz>
> > Cc: Thomas Gleixner <tglx@linutronix.de>
> > Cc: Ingo Molnar <mingo@redhat.com>
> > Cc: "H. Peter Anvin" <hpa@zytor.com>
> > Cc: x86@kernel.org
> > Cc: Josh Poimboeuf <jpoimboe@redhat.com>
> 
> Josh: an Acked-by or Reviewed-by for the whole series from you would be nice.

The patches look good, but I want to run it through some testing before
I give them an ACK.

-- 
Josh

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 1/6] x86/stacktrace: do not unwind after user regs
  2018-05-18 22:41   ` Josh Poimboeuf
@ 2018-05-19  7:42     ` Ingo Molnar
  2018-05-22 16:06       ` Josh Poimboeuf
  0 siblings, 1 reply; 12+ messages in thread
From: Ingo Molnar @ 2018-05-19  7:42 UTC (permalink / raw)
  To: Josh Poimboeuf
  Cc: Jiri Slaby, Peter Zijlstra, Andy Lutomirski, Borislav Petkov,
	mingo, linux-kernel, Thomas Gleixner, H. Peter Anvin, x86


* Josh Poimboeuf <jpoimboe@redhat.com> wrote:

> On Fri, May 18, 2018 at 08:55:47AM +0200, Ingo Molnar wrote:
> > 
> > * Jiri Slaby <jslaby@suse.cz> wrote:
> > 
> > > Josh pointed out, that there is no way a frame can be after user regs.
> > > So remove the last unwind and the check.
> > > 
> > > Signed-off-by: Jiri Slaby <jslaby@suse.cz>
> > > Cc: Thomas Gleixner <tglx@linutronix.de>
> > > Cc: Ingo Molnar <mingo@redhat.com>
> > > Cc: "H. Peter Anvin" <hpa@zytor.com>
> > > Cc: x86@kernel.org
> > > Cc: Josh Poimboeuf <jpoimboe@redhat.com>
> > 
> > Josh: an Acked-by or Reviewed-by for the whole series from you would be nice.
> 
> The patches look good, but I want to run it through some testing before
> I give them an ACK.

Sure thing and thanks!

	Ingo

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 1/6] x86/stacktrace: do not unwind after user regs
  2018-05-19  7:42     ` Ingo Molnar
@ 2018-05-22 16:06       ` Josh Poimboeuf
  2018-05-31 13:46         ` Josh Poimboeuf
  0 siblings, 1 reply; 12+ messages in thread
From: Josh Poimboeuf @ 2018-05-22 16:06 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Jiri Slaby, Peter Zijlstra, Andy Lutomirski, Borislav Petkov,
	mingo, linux-kernel, Thomas Gleixner, H. Peter Anvin, x86

On Sat, May 19, 2018 at 09:42:51AM +0200, Ingo Molnar wrote:
> 
> * Josh Poimboeuf <jpoimboe@redhat.com> wrote:
> 
> > On Fri, May 18, 2018 at 08:55:47AM +0200, Ingo Molnar wrote:
> > > 
> > > * Jiri Slaby <jslaby@suse.cz> wrote:
> > > 
> > > > Josh pointed out, that there is no way a frame can be after user regs.
> > > > So remove the last unwind and the check.
> > > > 
> > > > Signed-off-by: Jiri Slaby <jslaby@suse.cz>
> > > > Cc: Thomas Gleixner <tglx@linutronix.de>
> > > > Cc: Ingo Molnar <mingo@redhat.com>
> > > > Cc: "H. Peter Anvin" <hpa@zytor.com>
> > > > Cc: x86@kernel.org
> > > > Cc: Josh Poimboeuf <jpoimboe@redhat.com>
> > > 
> > > Josh: an Acked-by or Reviewed-by for the whole series from you would be nice.
> > 
> > The patches look good, but I want to run it through some testing before
> > I give them an ACK.

For the series:

Acked-by: Josh Poimboeuf <jpoimboe@redhat.com>

-- 
Josh

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 1/6] x86/stacktrace: do not unwind after user regs
  2018-05-22 16:06       ` Josh Poimboeuf
@ 2018-05-31 13:46         ` Josh Poimboeuf
  2018-06-21 14:35           ` Ingo Molnar
  0 siblings, 1 reply; 12+ messages in thread
From: Josh Poimboeuf @ 2018-05-31 13:46 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Jiri Slaby, Peter Zijlstra, Andy Lutomirski, Borislav Petkov,
	mingo, linux-kernel, Thomas Gleixner, H. Peter Anvin, x86

On Tue, May 22, 2018 at 11:06:09AM -0500, Josh Poimboeuf wrote:
> On Sat, May 19, 2018 at 09:42:51AM +0200, Ingo Molnar wrote:
> > 
> > * Josh Poimboeuf <jpoimboe@redhat.com> wrote:
> > 
> > > On Fri, May 18, 2018 at 08:55:47AM +0200, Ingo Molnar wrote:
> > > > 
> > > > * Jiri Slaby <jslaby@suse.cz> wrote:
> > > > 
> > > > > Josh pointed out, that there is no way a frame can be after user regs.
> > > > > So remove the last unwind and the check.
> > > > > 
> > > > > Signed-off-by: Jiri Slaby <jslaby@suse.cz>
> > > > > Cc: Thomas Gleixner <tglx@linutronix.de>
> > > > > Cc: Ingo Molnar <mingo@redhat.com>
> > > > > Cc: "H. Peter Anvin" <hpa@zytor.com>
> > > > > Cc: x86@kernel.org
> > > > > Cc: Josh Poimboeuf <jpoimboe@redhat.com>
> > > > 
> > > > Josh: an Acked-by or Reviewed-by for the whole series from you would be nice.
> > > 
> > > The patches look good, but I want to run it through some testing before
> > > I give them an ACK.
> 
> For the series:
> 
> Acked-by: Josh Poimboeuf <jpoimboe@redhat.com>

Ingo,

Any chance this can make the next merge window?

-- 
Josh

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 1/6] x86/stacktrace: do not unwind after user regs
  2018-05-31 13:46         ` Josh Poimboeuf
@ 2018-06-21 14:35           ` Ingo Molnar
  0 siblings, 0 replies; 12+ messages in thread
From: Ingo Molnar @ 2018-06-21 14:35 UTC (permalink / raw)
  To: Josh Poimboeuf
  Cc: Jiri Slaby, Peter Zijlstra, Andy Lutomirski, Borislav Petkov,
	mingo, linux-kernel, Thomas Gleixner, H. Peter Anvin, x86


* Josh Poimboeuf <jpoimboe@redhat.com> wrote:

> On Tue, May 22, 2018 at 11:06:09AM -0500, Josh Poimboeuf wrote:
> > On Sat, May 19, 2018 at 09:42:51AM +0200, Ingo Molnar wrote:
> > > 
> > > * Josh Poimboeuf <jpoimboe@redhat.com> wrote:
> > > 
> > > > On Fri, May 18, 2018 at 08:55:47AM +0200, Ingo Molnar wrote:
> > > > > 
> > > > > * Jiri Slaby <jslaby@suse.cz> wrote:
> > > > > 
> > > > > > Josh pointed out, that there is no way a frame can be after user regs.
> > > > > > So remove the last unwind and the check.
> > > > > > 
> > > > > > Signed-off-by: Jiri Slaby <jslaby@suse.cz>
> > > > > > Cc: Thomas Gleixner <tglx@linutronix.de>
> > > > > > Cc: Ingo Molnar <mingo@redhat.com>
> > > > > > Cc: "H. Peter Anvin" <hpa@zytor.com>
> > > > > > Cc: x86@kernel.org
> > > > > > Cc: Josh Poimboeuf <jpoimboe@redhat.com>
> > > > > 
> > > > > Josh: an Acked-by or Reviewed-by for the whole series from you would be nice.
> > > > 
> > > > The patches look good, but I want to run it through some testing before
> > > > I give them an ACK.
> > 
> > For the series:
> > 
> > Acked-by: Josh Poimboeuf <jpoimboe@redhat.com>
> 
> Ingo,
> 
> Any chance this can make the next merge window?

Applied now - will push it out after testing.

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2018-06-21 14:35 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-18  6:47 [PATCH v3 1/6] x86/stacktrace: do not unwind after user regs Jiri Slaby
2018-05-18  6:47 ` [PATCH v3 2/6] x86/stacktrace: remove STACKTRACE_DUMP_ONCE Jiri Slaby
2018-05-18  6:47 ` [PATCH v3 3/6] x86/stacktrace: clarify the reliable success paths Jiri Slaby
2018-05-18  6:47 ` [PATCH v3 4/6] x86/stacktrace: do not fail for ORC with regs on stack Jiri Slaby
2018-05-18  6:47 ` [PATCH v3 5/6] x86/unwind/orc: Detect the end of the stack Jiri Slaby
2018-05-18  6:47 ` [PATCH v3 6/6] x86/stacktrace: enable HAVE_RELIABLE_STACKTRACE for the ORC unwinder Jiri Slaby
2018-05-18  6:55 ` [PATCH v3 1/6] x86/stacktrace: do not unwind after user regs Ingo Molnar
2018-05-18 22:41   ` Josh Poimboeuf
2018-05-19  7:42     ` Ingo Molnar
2018-05-22 16:06       ` Josh Poimboeuf
2018-05-31 13:46         ` Josh Poimboeuf
2018-06-21 14:35           ` Ingo Molnar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).