All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] objtool: Fix infinite loop in find_jump_table()
@ 2020-04-28 21:45 Josh Poimboeuf
  2020-04-28 22:40 ` Peter Zijlstra
  2020-05-07 15:28 ` [tip: objtool/urgent] " tip-bot2 for Josh Poimboeuf
  0 siblings, 2 replies; 3+ messages in thread
From: Josh Poimboeuf @ 2020-04-28 21:45 UTC (permalink / raw)
  To: x86
  Cc: linux-kernel, Peter Zijlstra, Miroslav Benes, Julien Thierry,
	Kristen Carlson Accardi

Kristen found a hang in objtool when building with -ffunction-sections.

It was caused by evergreen_pcie_gen2_enable.cold() being laid out
immediately before evergreen_pcie_gen2_enable().  Since their "pfunc" is
always the same, find_jump_table() got into an infinite loop because it
didn't recognize the boundary between the two functions.

Fix that with a new prev_insn_same_sym() helper, which doesn't cross
subfunction boundaries.

Reported-by: Kristen Carlson Accardi <kristen@linux.intel.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
---
 tools/objtool/check.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 0c732d586924..4b51a06c7683 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -73,6 +73,17 @@ static struct instruction *next_insn_same_func(struct objtool_file *file,
 	return find_insn(file, func->cfunc->sec, func->cfunc->offset);
 }
 
+static struct instruction *prev_insn_same_sym(struct objtool_file *file,
+					       struct instruction *insn)
+{
+	struct instruction *prev = list_prev_entry(insn, list);
+
+	if (&prev->list != &file->insn_list && prev->func == insn->func)
+		return prev;
+
+	return NULL;
+}
+
 #define func_for_each_insn(file, func, insn)				\
 	for (insn = find_insn(file, func->sec, func->offset);		\
 	     insn;							\
@@ -1096,8 +1107,8 @@ static struct rela *find_jump_table(struct objtool_file *file,
 	 * it.
 	 */
 	for (;
-	     &insn->list != &file->insn_list && insn->func && insn->func->pfunc == func;
-	     insn = insn->first_jump_src ?: list_prev_entry(insn, list)) {
+	     insn && insn->func && insn->func->pfunc == func;
+	     insn = insn->first_jump_src ?: prev_insn_same_sym(file, insn)) {
 
 		if (insn != orig_insn && insn->type == INSN_JUMP_DYNAMIC)
 			break;
-- 
2.21.1


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

* Re: [PATCH] objtool: Fix infinite loop in find_jump_table()
  2020-04-28 21:45 [PATCH] objtool: Fix infinite loop in find_jump_table() Josh Poimboeuf
@ 2020-04-28 22:40 ` Peter Zijlstra
  2020-05-07 15:28 ` [tip: objtool/urgent] " tip-bot2 for Josh Poimboeuf
  1 sibling, 0 replies; 3+ messages in thread
From: Peter Zijlstra @ 2020-04-28 22:40 UTC (permalink / raw)
  To: Josh Poimboeuf
  Cc: x86, linux-kernel, Miroslav Benes, Julien Thierry,
	Kristen Carlson Accardi

On Tue, Apr 28, 2020 at 04:45:16PM -0500, Josh Poimboeuf wrote:
> Kristen found a hang in objtool when building with -ffunction-sections.
> 
> It was caused by evergreen_pcie_gen2_enable.cold() being laid out
> immediately before evergreen_pcie_gen2_enable().  Since their "pfunc" is
> always the same, find_jump_table() got into an infinite loop because it
> didn't recognize the boundary between the two functions.
> 
> Fix that with a new prev_insn_same_sym() helper, which doesn't cross
> subfunction boundaries.
> 
> Reported-by: Kristen Carlson Accardi <kristen@linux.intel.com>
> Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>

Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>

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

* [tip: objtool/urgent] objtool: Fix infinite loop in find_jump_table()
  2020-04-28 21:45 [PATCH] objtool: Fix infinite loop in find_jump_table() Josh Poimboeuf
  2020-04-28 22:40 ` Peter Zijlstra
@ 2020-05-07 15:28 ` tip-bot2 for Josh Poimboeuf
  1 sibling, 0 replies; 3+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2020-05-07 15:28 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Kristen Carlson Accardi, Josh Poimboeuf, Peter Zijlstra (Intel),
	x86, LKML

The following commit has been merged into the objtool/urgent branch of tip:

Commit-ID:     1119d265bc20226c241e5540fc8a246d9e30b272
Gitweb:        https://git.kernel.org/tip/1119d265bc20226c241e5540fc8a246d9e30b272
Author:        Josh Poimboeuf <jpoimboe@redhat.com>
AuthorDate:    Tue, 28 Apr 2020 16:45:16 -05:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Thu, 07 May 2020 17:22:31 +02:00

objtool: Fix infinite loop in find_jump_table()

Kristen found a hang in objtool when building with -ffunction-sections.

It was caused by evergreen_pcie_gen2_enable.cold() being laid out
immediately before evergreen_pcie_gen2_enable().  Since their "pfunc" is
always the same, find_jump_table() got into an infinite loop because it
didn't recognize the boundary between the two functions.

Fix that with a new prev_insn_same_sym() helper, which doesn't cross
subfunction boundaries.

Reported-by: Kristen Carlson Accardi <kristen@linux.intel.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/378b51c9d9c894dc3294bc460b4b0869e950b7c5.1588110291.git.jpoimboe@redhat.com
---
 tools/objtool/check.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 4b170fd..0e8f9a3 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -72,6 +72,17 @@ static struct instruction *next_insn_same_func(struct objtool_file *file,
 	return find_insn(file, func->cfunc->sec, func->cfunc->offset);
 }
 
+static struct instruction *prev_insn_same_sym(struct objtool_file *file,
+					       struct instruction *insn)
+{
+	struct instruction *prev = list_prev_entry(insn, list);
+
+	if (&prev->list != &file->insn_list && prev->func == insn->func)
+		return prev;
+
+	return NULL;
+}
+
 #define func_for_each_insn(file, func, insn)				\
 	for (insn = find_insn(file, func->sec, func->offset);		\
 	     insn;							\
@@ -1050,8 +1061,8 @@ static struct rela *find_jump_table(struct objtool_file *file,
 	 * it.
 	 */
 	for (;
-	     &insn->list != &file->insn_list && insn->func && insn->func->pfunc == func;
-	     insn = insn->first_jump_src ?: list_prev_entry(insn, list)) {
+	     insn && insn->func && insn->func->pfunc == func;
+	     insn = insn->first_jump_src ?: prev_insn_same_sym(file, insn)) {
 
 		if (insn != orig_insn && insn->type == INSN_JUMP_DYNAMIC)
 			break;

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

end of thread, other threads:[~2020-05-07 15:28 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-28 21:45 [PATCH] objtool: Fix infinite loop in find_jump_table() Josh Poimboeuf
2020-04-28 22:40 ` Peter Zijlstra
2020-05-07 15:28 ` [tip: objtool/urgent] " tip-bot2 for Josh Poimboeuf

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.