linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/22] objtool: CONFIG_OBJTOOL_WERROR fixes and cleanups
@ 2025-03-24 21:55 Josh Poimboeuf
  2025-03-24 21:55 ` [PATCH 01/22] objtool: Fix detection of consecutive jump tables Josh Poimboeuf
                   ` (21 more replies)
  0 siblings, 22 replies; 75+ messages in thread
From: Josh Poimboeuf @ 2025-03-24 21:55 UTC (permalink / raw)
  To: x86
  Cc: linux-kernel, Peter Zijlstra, Ingo Molnar, Miroslav Benes,
	Brendan Jackman, Nathan Chancellor, Raju Rangoju, Mark Brown,
	Christoph Hellwig, Sagi Grimberg, Chaitanya Kulkarni,
	Mauro Carvalho Chehab, Dmitry Torokhov, Srinivas Kandagatla,
	Liam Girdwood, Kees Cook

Since CONFIG_OBJTOOL_WERROR got merged into -tip, a lot of warnings have
been reported.  Fix those along with several other improvements.

Cc: Raju Rangoju <Raju.Rangoju@amd.com>
CC: Mark Brown <broonie@kernel.org>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Sagi Grimberg <sagi@grimberg.me>
Cc: Chaitanya Kulkarni <kch@nvidia.com>
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Cc: Liam Girdwood <lgirdwood@gmail.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Kees Cook <kees@kernel.org>

Josh Poimboeuf (22):
  objtool: Fix detection of consecutive jump tables
  objtool: Warn when disabling unreachable warnings
  objtool: Ignore entire functions rather than instructions
  objtool: Fix X86_FEATURE_SMAP alternative handling
  objtool: Fix CONFIG_OBJTOOL_WERROR for vmlinux.o
  objtool: Fix init_module() handling
  objtool: Silence more KCOV warnings
  objtool: Properly disable uaccess validation
  objtool: Improve error handling
  objtool: Reduce CONFIG_OBJTOOL_WERROR verbosity
  objtool: Fix up some outdated references to ENTRY/ENDPROC
  objtool: Remove --no-unreachable for noinstr-only vmlinux.o runs
  objtool: Remove redundant opts.noinstr dependency
  spi: amd: Fix out-of-bounds stack access in amd_set_spi_freq()
  nvmet: Fix out-of-bounds stack access in nvmet_ctrl_state_show()
  media: dib8000: Prevent divide-by-zero in dib8000_set_dds()
  panic: Disable SMAP in __stack_chk_fail()
  Input: cyapa - remove undefined behavior in cyapa_update_fw_store()
  ASoC: codecs: wcd934x: Remove undefined behavior in
    wcd934x_slim_irq_handler()
  regulator: rk808: Remove undefined behavior in rk806_set_mode_dcdc()
  pwm: mediatek: Prevent divide-by-zero in pwm_mediatek_config()
  lkdtm: Obfuscate do_nothing() pointer

 arch/x86/include/asm/arch_hweight.h     |   8 +-
 arch/x86/include/asm/smap.h             |  23 +-
 arch/x86/include/asm/xen/hypercall.h    |   6 +-
 drivers/input/mouse/cyapa.c             |   4 +-
 drivers/media/dvb-frontends/dib8000.c   |   5 +-
 drivers/misc/lkdtm/perms.c              |  14 +-
 drivers/nvme/target/debugfs.c           |   2 +-
 drivers/pwm/pwm-mediatek.c              |   8 +-
 drivers/regulator/rk808-regulator.c     |   4 +-
 drivers/spi/spi-amd.c                   |   2 +-
 include/linux/linkage.h                 |   4 -
 include/linux/objtool.h                 |   2 +-
 kernel/panic.c                          |   6 +
 scripts/Makefile.lib                    |   2 +-
 scripts/Makefile.vmlinux_o              |  15 +-
 sound/soc/codecs/wcd934x.c              |   2 +-
 tools/objtool/Documentation/objtool.txt |  10 +-
 tools/objtool/arch/x86/special.c        |  38 +-
 tools/objtool/builtin-check.c           | 146 ++++---
 tools/objtool/check.c                   | 525 ++++++++++++------------
 tools/objtool/elf.c                     |  28 +-
 tools/objtool/include/objtool/builtin.h |   6 +-
 tools/objtool/include/objtool/check.h   |   3 +-
 tools/objtool/include/objtool/elf.h     |  28 +-
 tools/objtool/include/objtool/objtool.h |   2 +-
 tools/objtool/include/objtool/special.h |   4 +-
 tools/objtool/include/objtool/warn.h    |  13 +-
 tools/objtool/objtool.c                 |  11 +-
 tools/objtool/special.c                 |  12 +-
 29 files changed, 477 insertions(+), 456 deletions(-)

-- 
2.48.1


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

* [PATCH 01/22] objtool: Fix detection of consecutive jump tables
  2025-03-24 21:55 [PATCH 00/22] objtool: CONFIG_OBJTOOL_WERROR fixes and cleanups Josh Poimboeuf
@ 2025-03-24 21:55 ` Josh Poimboeuf
  2025-03-25  8:35   ` [tip: objtool/urgent] objtool: Fix detection of consecutive jump tables on Clang 20 tip-bot2 for Josh Poimboeuf
  2025-03-24 21:55 ` [PATCH 02/22] objtool: Warn when disabling unreachable warnings Josh Poimboeuf
                   ` (20 subsequent siblings)
  21 siblings, 1 reply; 75+ messages in thread
From: Josh Poimboeuf @ 2025-03-24 21:55 UTC (permalink / raw)
  To: x86
  Cc: linux-kernel, Peter Zijlstra, Ingo Molnar, Miroslav Benes,
	Brendan Jackman, Nathan Chancellor, kernel test robot

The jump table detection code assumes jump tables are in the same order
as their corresponding indirect branches.  That's apparently not always
true with Clang 20.

Fix that by changing how multiple jump tables are detected.  In the
first detection pass, mark the beginning of each jump table so the
second pass can tell where one ends and the next one begins.

Fixes the following warnings:

  vmlinux.o: warning: objtool: SiS_GetCRT2Ptr+0x1ad: stack state mismatch: cfa1=4+8 cfa2=5+16
  sound/core/seq/snd-seq.o: warning: objtool: cc_ev_to_ump_midi2+0x589: return with modified stack frame

Fixes: be2f0b1e1264 ("objtool: Get rid of reloc->jump_table_start")
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202503171547.LlCTJLQL-lkp@intel.com/
Closes: https://lore.kernel.org/oe-kbuild-all/202503200535.J3hAvcjw-lkp@intel.com/
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
 tools/objtool/check.c               | 26 ++++++++------------------
 tools/objtool/elf.c                 |  6 +++---
 tools/objtool/include/objtool/elf.h | 27 ++++++++++++++++++++++++++-
 3 files changed, 37 insertions(+), 22 deletions(-)

diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 48d7bc5b4736..33beefd459a6 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -1949,8 +1949,7 @@ __weak unsigned long arch_jump_table_sym_offset(struct reloc *reloc, struct relo
 	return reloc->sym->offset + reloc_addend(reloc);
 }
 
-static int add_jump_table(struct objtool_file *file, struct instruction *insn,
-			  struct reloc *next_table)
+static int add_jump_table(struct objtool_file *file, struct instruction *insn)
 {
 	unsigned long table_size = insn_jump_table_size(insn);
 	struct symbol *pfunc = insn_func(insn)->pfunc;
@@ -1970,7 +1969,7 @@ static int add_jump_table(struct objtool_file *file, struct instruction *insn,
 		/* Check for the end of the table: */
 		if (table_size && reloc_offset(reloc) - reloc_offset(table) >= table_size)
 			break;
-		if (reloc != table && reloc == next_table)
+		if (reloc != table && is_jump_table(reloc))
 			break;
 
 		/* Make sure the table entries are consecutive: */
@@ -2061,8 +2060,10 @@ static void find_jump_table(struct objtool_file *file, struct symbol *func,
 		if (!dest_insn || !insn_func(dest_insn) || insn_func(dest_insn)->pfunc != func)
 			continue;
 
+		set_jump_table(table_reloc);
 		orig_insn->_jump_table = table_reloc;
 		orig_insn->_jump_table_size = table_size;
+
 		break;
 	}
 }
@@ -2104,31 +2105,20 @@ static void mark_func_jump_tables(struct objtool_file *file,
 static int add_func_jump_tables(struct objtool_file *file,
 				  struct symbol *func)
 {
-	struct instruction *insn, *insn_t1 = NULL, *insn_t2;
-	int ret = 0;
+	struct instruction *insn;
+	int ret;
 
 	func_for_each_insn(file, func, insn) {
 		if (!insn_jump_table(insn))
 			continue;
 
-		if (!insn_t1) {
-			insn_t1 = insn;
-			continue;
-		}
 
-		insn_t2 = insn;
-
-		ret = add_jump_table(file, insn_t1, insn_jump_table(insn_t2));
+		ret = add_jump_table(file, insn);
 		if (ret)
 			return ret;
-
-		insn_t1 = insn_t2;
 	}
 
-	if (insn_t1)
-		ret = add_jump_table(file, insn_t1, NULL);
-
-	return ret;
+	return 0;
 }
 
 /*
diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index be4f4b62730c..0f38167bd840 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -583,7 +583,7 @@ static int elf_update_sym_relocs(struct elf *elf, struct symbol *sym)
 {
 	struct reloc *reloc;
 
-	for (reloc = sym->relocs; reloc; reloc = reloc->sym_next_reloc)
+	for (reloc = sym->relocs; reloc; reloc = sym_next_reloc(reloc))
 		set_reloc_sym(elf, reloc, reloc->sym->idx);
 
 	return 0;
@@ -880,7 +880,7 @@ static struct reloc *elf_init_reloc(struct elf *elf, struct section *rsec,
 	set_reloc_addend(elf, reloc, addend);
 
 	elf_hash_add(reloc, &reloc->hash, reloc_hash(reloc));
-	reloc->sym_next_reloc = sym->relocs;
+	set_sym_next_reloc(reloc, sym->relocs);
 	sym->relocs = reloc;
 
 	return reloc;
@@ -979,7 +979,7 @@ static int read_relocs(struct elf *elf)
 			}
 
 			elf_hash_add(reloc, &reloc->hash, reloc_hash(reloc));
-			reloc->sym_next_reloc = sym->relocs;
+			set_sym_next_reloc(reloc, sym->relocs);
 			sym->relocs = reloc;
 
 			nr_reloc++;
diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/objtool/elf.h
index 223ac1c24b90..4edc957a6f6b 100644
--- a/tools/objtool/include/objtool/elf.h
+++ b/tools/objtool/include/objtool/elf.h
@@ -77,7 +77,7 @@ struct reloc {
 	struct elf_hash_node hash;
 	struct section *sec;
 	struct symbol *sym;
-	struct reloc *sym_next_reloc;
+	unsigned long _sym_next_reloc;
 };
 
 struct elf {
@@ -297,6 +297,31 @@ static inline void set_reloc_type(struct elf *elf, struct reloc *reloc, unsigned
 	mark_sec_changed(elf, reloc->sec, true);
 }
 
+#define RELOC_JUMP_TABLE_BIT 1UL
+
+/* Does reloc mark the beginning of a jump table? */
+static inline bool is_jump_table(struct reloc *reloc)
+{
+	return reloc->_sym_next_reloc & RELOC_JUMP_TABLE_BIT;
+}
+
+static inline void set_jump_table(struct reloc *reloc)
+{
+	reloc->_sym_next_reloc |= RELOC_JUMP_TABLE_BIT;
+}
+
+static inline struct reloc *sym_next_reloc(struct reloc *reloc)
+{
+	return (struct reloc *)(reloc->_sym_next_reloc & ~RELOC_JUMP_TABLE_BIT);
+}
+
+static inline void set_sym_next_reloc(struct reloc *reloc, struct reloc *next)
+{
+	unsigned long bit = reloc->_sym_next_reloc & RELOC_JUMP_TABLE_BIT;
+
+	reloc->_sym_next_reloc = (unsigned long)next | bit;
+}
+
 #define for_each_sec(file, sec)						\
 	list_for_each_entry(sec, &file->elf->sections, list)
 
-- 
2.48.1


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

* [PATCH 02/22] objtool: Warn when disabling unreachable warnings
  2025-03-24 21:55 [PATCH 00/22] objtool: CONFIG_OBJTOOL_WERROR fixes and cleanups Josh Poimboeuf
  2025-03-24 21:55 ` [PATCH 01/22] objtool: Fix detection of consecutive jump tables Josh Poimboeuf
@ 2025-03-24 21:55 ` Josh Poimboeuf
  2025-03-25  8:35   ` [tip: objtool/urgent] " tip-bot2 for Josh Poimboeuf
  2025-03-24 21:55 ` [PATCH 03/22] objtool: Ignore entire functions rather than instructions Josh Poimboeuf
                   ` (19 subsequent siblings)
  21 siblings, 1 reply; 75+ messages in thread
From: Josh Poimboeuf @ 2025-03-24 21:55 UTC (permalink / raw)
  To: x86
  Cc: linux-kernel, Peter Zijlstra, Ingo Molnar, Miroslav Benes,
	Brendan Jackman, Nathan Chancellor

Print a warning when disabling the unreachable warnings (due to a GCC
bug).  This will help determine if recent GCCs still have the issue and
alert us if any other issues might be silently lurking behind the
unreachable disablement.

Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
 tools/objtool/arch/x86/special.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/tools/objtool/arch/x86/special.c b/tools/objtool/arch/x86/special.c
index 9c1c9df09aaa..5f46d4e7f7f8 100644
--- a/tools/objtool/arch/x86/special.c
+++ b/tools/objtool/arch/x86/special.c
@@ -3,6 +3,7 @@
 
 #include <objtool/special.h>
 #include <objtool/builtin.h>
+#include <objtool/warn.h>
 
 #define X86_FEATURE_POPCNT (4 * 32 + 23)
 #define X86_FEATURE_SMAP   (9 * 32 + 20)
@@ -156,8 +157,10 @@ struct reloc *arch_find_switch_table(struct objtool_file *file,
 	 * indicates a rare GCC quirk/bug which can leave dead
 	 * code behind.
 	 */
-	if (reloc_type(text_reloc) == R_X86_64_PC32)
+	if (reloc_type(text_reloc) == R_X86_64_PC32) {
+		WARN_INSN(insn, "ignoring unreachables due to jump table quirk");
 		file->ignore_unreachables = true;
+	}
 
 	*table_size = 0;
 	return rodata_reloc;
-- 
2.48.1


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

* [PATCH 03/22] objtool: Ignore entire functions rather than instructions
  2025-03-24 21:55 [PATCH 00/22] objtool: CONFIG_OBJTOOL_WERROR fixes and cleanups Josh Poimboeuf
  2025-03-24 21:55 ` [PATCH 01/22] objtool: Fix detection of consecutive jump tables Josh Poimboeuf
  2025-03-24 21:55 ` [PATCH 02/22] objtool: Warn when disabling unreachable warnings Josh Poimboeuf
@ 2025-03-24 21:55 ` Josh Poimboeuf
  2025-03-25  8:35   ` [tip: objtool/urgent] " tip-bot2 for Josh Poimboeuf
  2025-03-24 21:55 ` [PATCH 04/22] objtool: Fix X86_FEATURE_SMAP alternative handling Josh Poimboeuf
                   ` (18 subsequent siblings)
  21 siblings, 1 reply; 75+ messages in thread
From: Josh Poimboeuf @ 2025-03-24 21:55 UTC (permalink / raw)
  To: x86
  Cc: linux-kernel, Peter Zijlstra, Ingo Molnar, Miroslav Benes,
	Brendan Jackman, Nathan Chancellor

STACK_FRAME_NON_STANDARD applies to functions.  Use a function-specific
ignore attribute in preparation for getting rid of insn->ignore.

Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
 tools/objtool/check.c               | 35 +++++++++++++++--------------
 tools/objtool/include/objtool/elf.h |  1 +
 2 files changed, 19 insertions(+), 17 deletions(-)

diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 33beefd459a6..8e2f3405d78c 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -981,7 +981,6 @@ static int create_direct_call_sections(struct objtool_file *file)
  */
 static void add_ignores(struct objtool_file *file)
 {
-	struct instruction *insn;
 	struct section *rsec;
 	struct symbol *func;
 	struct reloc *reloc;
@@ -1008,8 +1007,7 @@ static void add_ignores(struct objtool_file *file)
 			continue;
 		}
 
-		func_for_each_insn(file, func, insn)
-			insn->ignore = true;
+		func->ignore = true;
 	}
 }
 
@@ -1620,6 +1618,7 @@ static int add_call_destinations(struct objtool_file *file)
 	struct reloc *reloc;
 
 	for_each_insn(file, insn) {
+		struct symbol *func = insn_func(insn);
 		if (insn->type != INSN_CALL)
 			continue;
 
@@ -1630,7 +1629,7 @@ static int add_call_destinations(struct objtool_file *file)
 
 			add_call_dest(file, insn, dest, false);
 
-			if (insn->ignore)
+			if (func && func->ignore)
 				continue;
 
 			if (!insn_call_dest(insn)) {
@@ -1638,7 +1637,7 @@ static int add_call_destinations(struct objtool_file *file)
 				return -1;
 			}
 
-			if (insn_func(insn) && insn_call_dest(insn)->type != STT_FUNC) {
+			if (func && insn_call_dest(insn)->type != STT_FUNC) {
 				WARN_INSN(insn, "unsupported call to non-function");
 				return -1;
 			}
@@ -3478,6 +3477,9 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
 	u8 visited;
 	int ret;
 
+	if (func && func->ignore)
+		return 0;
+
 	sec = insn->sec;
 
 	while (1) {
@@ -3723,7 +3725,7 @@ static int validate_unwind_hint(struct objtool_file *file,
 				  struct instruction *insn,
 				  struct insn_state *state)
 {
-	if (insn->hint && !insn->visited && !insn->ignore) {
+	if (insn->hint && !insn->visited) {
 		int ret = validate_branch(file, insn_func(insn), insn, *state);
 		if (ret)
 			BT_INSN(insn, "<=== (hint)");
@@ -3937,10 +3939,11 @@ static bool is_ubsan_insn(struct instruction *insn)
 
 static bool ignore_unreachable_insn(struct objtool_file *file, struct instruction *insn)
 {
-	int i;
+	struct symbol *func = insn_func(insn);
 	struct instruction *prev_insn;
+	int i;
 
-	if (insn->ignore || insn->type == INSN_NOP || insn->type == INSN_TRAP)
+	if (insn->ignore || insn->type == INSN_NOP || insn->type == INSN_TRAP || (func && func->ignore))
 		return true;
 
 	/*
@@ -3959,7 +3962,7 @@ static bool ignore_unreachable_insn(struct objtool_file *file, struct instructio
 	 * In this case we'll find a piece of code (whole function) that is not
 	 * covered by a !section symbol. Ignore them.
 	 */
-	if (opts.link && !insn_func(insn)) {
+	if (opts.link && !func) {
 		int size = find_symbol_hole_containing(insn->sec, insn->offset);
 		unsigned long end = insn->offset + size;
 
@@ -3985,19 +3988,17 @@ static bool ignore_unreachable_insn(struct objtool_file *file, struct instructio
 			 */
 			if (insn->jump_dest && insn_func(insn->jump_dest) &&
 			    strstr(insn_func(insn->jump_dest)->name, ".cold")) {
-				struct instruction *dest = insn->jump_dest;
-				func_for_each_insn(file, insn_func(dest), dest)
-					dest->ignore = true;
+				insn_func(insn->jump_dest)->ignore = true;
 			}
 		}
 
 		return false;
 	}
 
-	if (!insn_func(insn))
+	if (!func)
 		return false;
 
-	if (insn_func(insn)->static_call_tramp)
+	if (func->static_call_tramp)
 		return true;
 
 	/*
@@ -4028,7 +4029,7 @@ static bool ignore_unreachable_insn(struct objtool_file *file, struct instructio
 
 		if (insn->type == INSN_JUMP_UNCONDITIONAL) {
 			if (insn->jump_dest &&
-			    insn_func(insn->jump_dest) == insn_func(insn)) {
+			    insn_func(insn->jump_dest) == func) {
 				insn = insn->jump_dest;
 				continue;
 			}
@@ -4036,7 +4037,7 @@ static bool ignore_unreachable_insn(struct objtool_file *file, struct instructio
 			break;
 		}
 
-		if (insn->offset + insn->len >= insn_func(insn)->offset + insn_func(insn)->len)
+		if (insn->offset + insn->len >= func->offset + func->len)
 			break;
 
 		insn = next_insn_same_sec(file, insn);
@@ -4128,7 +4129,7 @@ static int validate_symbol(struct objtool_file *file, struct section *sec,
 		return 0;
 
 	insn = find_insn(file, sec, sym->offset);
-	if (!insn || insn->ignore || insn->visited)
+	if (!insn || insn->visited)
 		return 0;
 
 	state->uaccess = sym->uaccess_safe;
diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/objtool/elf.h
index 4edc957a6f6b..eba04392c6fd 100644
--- a/tools/objtool/include/objtool/elf.h
+++ b/tools/objtool/include/objtool/elf.h
@@ -68,6 +68,7 @@ struct symbol {
 	u8 embedded_insn     : 1;
 	u8 local_label       : 1;
 	u8 frame_pointer     : 1;
+	u8 ignore	     : 1;
 	u8 warnings	     : 2;
 	struct list_head pv_target;
 	struct reloc *relocs;
-- 
2.48.1


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

* [PATCH 04/22] objtool: Fix X86_FEATURE_SMAP alternative handling
  2025-03-24 21:55 [PATCH 00/22] objtool: CONFIG_OBJTOOL_WERROR fixes and cleanups Josh Poimboeuf
                   ` (2 preceding siblings ...)
  2025-03-24 21:55 ` [PATCH 03/22] objtool: Ignore entire functions rather than instructions Josh Poimboeuf
@ 2025-03-24 21:55 ` Josh Poimboeuf
  2025-03-25  8:35   ` [tip: objtool/urgent] " tip-bot2 for Josh Poimboeuf
  2025-03-24 21:55 ` [PATCH 05/22] objtool: Fix CONFIG_OBJTOOL_WERROR for vmlinux.o Josh Poimboeuf
                   ` (17 subsequent siblings)
  21 siblings, 1 reply; 75+ messages in thread
From: Josh Poimboeuf @ 2025-03-24 21:55 UTC (permalink / raw)
  To: x86
  Cc: linux-kernel, Peter Zijlstra, Ingo Molnar, Miroslav Benes,
	Brendan Jackman, Nathan Chancellor, kernel test robot

For X86_FEATURE_SMAP alternatives which replace NOP with STAC or CLAC,
uaccess validation skips the NOP branch to avoid following impossible
code paths, e.g. where a STAC would be patched but a CLAC wouldn't.

However, it's not safe to assume an X86_FEATURE_SMAP alternative is
patching STAC/CLAC.  There can be other alternatives, like
static_cpu_has(), where both branches need to be validated.

Fix that by repurposing ANNOTATE_IGNORE_ALTERNATIVE for skipping either
original instructions or new ones.  This is a more generic approach
which enables the removal of the feature checking hacks and the
insn->ignore bit.

Fixes the following warnings:

  arch/x86/mm/fault.o: warning: objtool: do_user_addr_fault+0x8ec: __stack_chk_fail() missing __noreturn in .c/.h or NORETURN() in noreturns.h
  arch/x86/mm/fault.o: warning: objtool: do_user_addr_fault+0x8f1: unreachable instruction

Fixes: ea24213d8088 ("objtool: Add UACCESS validation")
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202503181736.zkZUBv4N-lkp@intel.com/
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
 arch/x86/include/asm/arch_hweight.h     |  8 +++--
 arch/x86/include/asm/smap.h             | 23 ++++++++++-----
 arch/x86/include/asm/xen/hypercall.h    |  6 ++--
 tools/objtool/arch/x86/special.c        | 33 +--------------------
 tools/objtool/check.c                   | 39 +++++++------------------
 tools/objtool/include/objtool/check.h   |  3 +-
 tools/objtool/include/objtool/special.h |  4 +--
 tools/objtool/special.c                 | 12 ++------
 8 files changed, 39 insertions(+), 89 deletions(-)

diff --git a/arch/x86/include/asm/arch_hweight.h b/arch/x86/include/asm/arch_hweight.h
index ba88edd0d58b..a0eaa8fda55f 100644
--- a/arch/x86/include/asm/arch_hweight.h
+++ b/arch/x86/include/asm/arch_hweight.h
@@ -16,7 +16,9 @@ static __always_inline unsigned int __arch_hweight32(unsigned int w)
 {
 	unsigned int res;
 
-	asm (ALTERNATIVE("call __sw_hweight32", "popcntl %1, %0", X86_FEATURE_POPCNT)
+	asm (ALTERNATIVE(ANNOTATE_IGNORE_ALTERNATIVE
+			 "call __sw_hweight32",
+			 "popcntl %1, %0", X86_FEATURE_POPCNT)
 			 : "="REG_OUT (res)
 			 : REG_IN (w));
 
@@ -44,7 +46,9 @@ static __always_inline unsigned long __arch_hweight64(__u64 w)
 {
 	unsigned long res;
 
-	asm (ALTERNATIVE("call __sw_hweight64", "popcntq %1, %0", X86_FEATURE_POPCNT)
+	asm (ALTERNATIVE(ANNOTATE_IGNORE_ALTERNATIVE
+			 "call __sw_hweight64",
+			 "popcntq %1, %0", X86_FEATURE_POPCNT)
 			 : "="REG_OUT (res)
 			 : REG_IN (w));
 
diff --git a/arch/x86/include/asm/smap.h b/arch/x86/include/asm/smap.h
index 2de1e5a75c57..a984cdd6de30 100644
--- a/arch/x86/include/asm/smap.h
+++ b/arch/x86/include/asm/smap.h
@@ -16,23 +16,23 @@
 #ifdef __ASSEMBLY__
 
 #define ASM_CLAC \
-	ALTERNATIVE "", "clac", X86_FEATURE_SMAP
+	ALTERNATIVE __stringify(ANNOTATE_IGNORE_ALTERNATIVE), "clac", X86_FEATURE_SMAP
 
 #define ASM_STAC \
-	ALTERNATIVE "", "stac", X86_FEATURE_SMAP
+	ALTERNATIVE __stringify(ANNOTATE_IGNORE_ALTERNATIVE), "stac", X86_FEATURE_SMAP
 
 #else /* __ASSEMBLY__ */
 
 static __always_inline void clac(void)
 {
 	/* Note: a barrier is implicit in alternative() */
-	alternative("", "clac", X86_FEATURE_SMAP);
+	alternative(ANNOTATE_IGNORE_ALTERNATIVE "", "clac", X86_FEATURE_SMAP);
 }
 
 static __always_inline void stac(void)
 {
 	/* Note: a barrier is implicit in alternative() */
-	alternative("", "stac", X86_FEATURE_SMAP);
+	alternative(ANNOTATE_IGNORE_ALTERNATIVE "", "stac", X86_FEATURE_SMAP);
 }
 
 static __always_inline unsigned long smap_save(void)
@@ -40,7 +40,8 @@ static __always_inline unsigned long smap_save(void)
 	unsigned long flags;
 
 	asm volatile ("# smap_save\n\t"
-		      ALTERNATIVE("", "pushf; pop %0; " "clac" "\n\t",
+		      ALTERNATIVE(ANNOTATE_IGNORE_ALTERNATIVE
+				  "", "pushf; pop %0; clac",
 				  X86_FEATURE_SMAP)
 		      : "=rm" (flags) : : "memory", "cc");
 
@@ -50,16 +51,22 @@ static __always_inline unsigned long smap_save(void)
 static __always_inline void smap_restore(unsigned long flags)
 {
 	asm volatile ("# smap_restore\n\t"
-		      ALTERNATIVE("", "push %0; popf\n\t",
+		      ALTERNATIVE(ANNOTATE_IGNORE_ALTERNATIVE
+				  "", "push %0; popf",
 				  X86_FEATURE_SMAP)
 		      : : "g" (flags) : "memory", "cc");
 }
 
 /* These macros can be used in asm() statements */
 #define ASM_CLAC \
-	ALTERNATIVE("", "clac", X86_FEATURE_SMAP)
+	ALTERNATIVE(ANNOTATE_IGNORE_ALTERNATIVE "", "clac", X86_FEATURE_SMAP)
 #define ASM_STAC \
-	ALTERNATIVE("", "stac", X86_FEATURE_SMAP)
+	ALTERNATIVE(ANNOTATE_IGNORE_ALTERNATIVE "", "stac", X86_FEATURE_SMAP)
+
+#define ASM_CLAC_UNSAFE \
+	ALTERNATIVE("", ANNOTATE_IGNORE_ALTERNATIVE "clac", X86_FEATURE_SMAP)
+#define ASM_STAC_UNSAFE \
+	ALTERNATIVE("", ANNOTATE_IGNORE_ALTERNATIVE "stac", X86_FEATURE_SMAP)
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h
index 97771b9d33af..59a62c3780a2 100644
--- a/arch/x86/include/asm/xen/hypercall.h
+++ b/arch/x86/include/asm/xen/hypercall.h
@@ -231,14 +231,12 @@ static __always_inline void __xen_stac(void)
 	 * Suppress objtool seeing the STAC/CLAC and getting confused about it
 	 * calling random code with AC=1.
 	 */
-	asm volatile(ANNOTATE_IGNORE_ALTERNATIVE
-		     ASM_STAC ::: "memory", "flags");
+	asm volatile(ASM_STAC_UNSAFE ::: "memory", "flags");
 }
 
 static __always_inline void __xen_clac(void)
 {
-	asm volatile(ANNOTATE_IGNORE_ALTERNATIVE
-		     ASM_CLAC ::: "memory", "flags");
+	asm volatile(ASM_CLAC_UNSAFE ::: "memory", "flags");
 }
 
 static inline long
diff --git a/tools/objtool/arch/x86/special.c b/tools/objtool/arch/x86/special.c
index 5f46d4e7f7f8..403e587676f1 100644
--- a/tools/objtool/arch/x86/special.c
+++ b/tools/objtool/arch/x86/special.c
@@ -5,10 +5,7 @@
 #include <objtool/builtin.h>
 #include <objtool/warn.h>
 
-#define X86_FEATURE_POPCNT (4 * 32 + 23)
-#define X86_FEATURE_SMAP   (9 * 32 + 20)
-
-void arch_handle_alternative(unsigned short feature, struct special_alt *alt)
+void arch_handle_alternative(struct special_alt *alt)
 {
 	static struct special_alt *group, *prev;
 
@@ -32,34 +29,6 @@ void arch_handle_alternative(unsigned short feature, struct special_alt *alt)
 	} else group = alt;
 
 	prev = alt;
-
-	switch (feature) {
-	case X86_FEATURE_SMAP:
-		/*
-		 * If UACCESS validation is enabled; force that alternative;
-		 * otherwise force it the other way.
-		 *
-		 * What we want to avoid is having both the original and the
-		 * alternative code flow at the same time, in that case we can
-		 * find paths that see the STAC but take the NOP instead of
-		 * CLAC and the other way around.
-		 */
-		if (opts.uaccess)
-			alt->skip_orig = true;
-		else
-			alt->skip_alt = true;
-		break;
-	case X86_FEATURE_POPCNT:
-		/*
-		 * It has been requested that we don't validate the !POPCNT
-		 * feature path which is a "very very small percentage of
-		 * machines".
-		 */
-		alt->skip_orig = true;
-		break;
-	default:
-		break;
-	}
 }
 
 bool arch_support_alt_relocation(struct special_alt *special_alt,
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 8e2f3405d78c..bac88ca82dec 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -25,7 +25,6 @@
 struct alternative {
 	struct alternative *next;
 	struct instruction *insn;
-	bool skip_orig;
 };
 
 static unsigned long nr_cfi, nr_cfi_reused, nr_cfi_cache;
@@ -1704,6 +1703,7 @@ static int handle_group_alt(struct objtool_file *file,
 		orig_alt_group->first_insn = orig_insn;
 		orig_alt_group->last_insn = last_orig_insn;
 		orig_alt_group->nop = NULL;
+		orig_alt_group->ignore = orig_insn->ignore_alts;
 	} else {
 		if (orig_alt_group->last_insn->offset + orig_alt_group->last_insn->len -
 		    orig_alt_group->first_insn->offset != special_alt->orig_len) {
@@ -1743,7 +1743,6 @@ static int handle_group_alt(struct objtool_file *file,
 		nop->type = INSN_NOP;
 		nop->sym = orig_insn->sym;
 		nop->alt_group = new_alt_group;
-		nop->ignore = orig_insn->ignore_alts;
 	}
 
 	if (!special_alt->new_len) {
@@ -1760,7 +1759,6 @@ static int handle_group_alt(struct objtool_file *file,
 
 		last_new_insn = insn;
 
-		insn->ignore = orig_insn->ignore_alts;
 		insn->sym = orig_insn->sym;
 		insn->alt_group = new_alt_group;
 
@@ -1807,6 +1805,7 @@ static int handle_group_alt(struct objtool_file *file,
 	new_alt_group->first_insn = *new_insn;
 	new_alt_group->last_insn = last_new_insn;
 	new_alt_group->nop = nop;
+	new_alt_group->ignore = (*new_insn)->ignore_alts;
 	new_alt_group->cfi = orig_alt_group->cfi;
 	return 0;
 }
@@ -1924,8 +1923,6 @@ static int add_special_section_alts(struct objtool_file *file)
 		}
 
 		alt->insn = new_insn;
-		alt->skip_orig = special_alt->skip_orig;
-		orig_insn->ignore_alts |= special_alt->skip_alt;
 		alt->next = orig_insn->alts;
 		orig_insn->alts = alt;
 
@@ -2303,6 +2300,8 @@ static int read_annotate(struct objtool_file *file,
 static int __annotate_early(struct objtool_file *file, int type, struct instruction *insn)
 {
 	switch (type) {
+
+	/* Must be before add_special_section_alts() */
 	case ANNOTYPE_IGNORE_ALTS:
 		insn->ignore_alts = true;
 		break;
@@ -3496,11 +3495,6 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
 			return 1;
 		}
 
-		if (func && insn->ignore) {
-			WARN_INSN(insn, "BUG: why am I validating an ignored function?");
-			return 1;
-		}
-
 		visited = VISITED_BRANCH << state.uaccess;
 		if (insn->visited & VISITED_BRANCH_MASK) {
 			if (!insn->hint && !insn_cfi_match(insn, &state.cfi))
@@ -3572,24 +3566,19 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
 		if (propagate_alt_cfi(file, insn))
 			return 1;
 
-		if (!insn->ignore_alts && insn->alts) {
-			bool skip_orig = false;
-
+		if (insn->alts) {
 			for (alt = insn->alts; alt; alt = alt->next) {
-				if (alt->skip_orig)
-					skip_orig = true;
-
 				ret = validate_branch(file, func, alt->insn, state);
 				if (ret) {
 					BT_INSN(insn, "(alt)");
 					return ret;
 				}
 			}
-
-			if (skip_orig)
-				return 0;
 		}
 
+		if (insn->alt_group && insn->alt_group->ignore)
+			return 0;
+
 		if (handle_insn_ops(insn, next_insn, &state))
 			return 1;
 
@@ -3776,23 +3765,15 @@ static int validate_unret(struct objtool_file *file, struct instruction *insn)
 
 		insn->visited |= VISITED_UNRET;
 
-		if (!insn->ignore_alts && insn->alts) {
+		if (insn->alts) {
 			struct alternative *alt;
-			bool skip_orig = false;
-
 			for (alt = insn->alts; alt; alt = alt->next) {
-				if (alt->skip_orig)
-					skip_orig = true;
-
 				ret = validate_unret(file, alt->insn);
 				if (ret) {
 					BT_INSN(insn, "(alt)");
 					return ret;
 				}
 			}
-
-			if (skip_orig)
-				return 0;
 		}
 
 		switch (insn->type) {
@@ -3943,7 +3924,7 @@ static bool ignore_unreachable_insn(struct objtool_file *file, struct instructio
 	struct instruction *prev_insn;
 	int i;
 
-	if (insn->ignore || insn->type == INSN_NOP || insn->type == INSN_TRAP || (func && func->ignore))
+	if (insn->type == INSN_NOP || insn->type == INSN_TRAP || (func && func->ignore))
 		return true;
 
 	/*
diff --git a/tools/objtool/include/objtool/check.h b/tools/objtool/include/objtool/check.h
index e1cd13cd28a3..00fb745e7233 100644
--- a/tools/objtool/include/objtool/check.h
+++ b/tools/objtool/include/objtool/check.h
@@ -34,6 +34,8 @@ struct alt_group {
 	 * This is shared with the other alt_groups in the same alternative.
 	 */
 	struct cfi_state **cfi;
+
+	bool ignore;
 };
 
 #define INSN_CHUNK_BITS		8
@@ -54,7 +56,6 @@ struct instruction {
 
 	u32 idx			: INSN_CHUNK_BITS,
 	    dead_end		: 1,
-	    ignore		: 1,
 	    ignore_alts		: 1,
 	    hint		: 1,
 	    save		: 1,
diff --git a/tools/objtool/include/objtool/special.h b/tools/objtool/include/objtool/special.h
index e049679bb17b..72d09c0adf1a 100644
--- a/tools/objtool/include/objtool/special.h
+++ b/tools/objtool/include/objtool/special.h
@@ -16,8 +16,6 @@ struct special_alt {
 	struct list_head list;
 
 	bool group;
-	bool skip_orig;
-	bool skip_alt;
 	bool jump_or_nop;
 	u8 key_addend;
 
@@ -32,7 +30,7 @@ struct special_alt {
 
 int special_get_alts(struct elf *elf, struct list_head *alts);
 
-void arch_handle_alternative(unsigned short feature, struct special_alt *alt);
+void arch_handle_alternative(struct special_alt *alt);
 
 bool arch_support_alt_relocation(struct special_alt *special_alt,
 				 struct instruction *insn,
diff --git a/tools/objtool/special.c b/tools/objtool/special.c
index 097a69db82a0..6cd7b1be5331 100644
--- a/tools/objtool/special.c
+++ b/tools/objtool/special.c
@@ -54,7 +54,7 @@ static const struct special_entry entries[] = {
 	{},
 };
 
-void __weak arch_handle_alternative(unsigned short feature, struct special_alt *alt)
+void __weak arch_handle_alternative(struct special_alt *alt)
 {
 }
 
@@ -92,15 +92,7 @@ static int get_alt_entry(struct elf *elf, const struct special_entry *entry,
 
 	reloc_to_sec_off(orig_reloc, &alt->orig_sec, &alt->orig_off);
 
-	if (entry->feature) {
-		unsigned short feature;
-
-		feature = bswap_if_needed(elf,
-					  *(unsigned short *)(sec->data->d_buf +
-							      offset +
-							      entry->feature));
-		arch_handle_alternative(feature, alt);
-	}
+	arch_handle_alternative(alt);
 
 	if (!entry->group || alt->new_len) {
 		new_reloc = find_reloc_by_dest(elf, sec, offset + entry->new);
-- 
2.48.1


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

* [PATCH 05/22] objtool: Fix CONFIG_OBJTOOL_WERROR for vmlinux.o
  2025-03-24 21:55 [PATCH 00/22] objtool: CONFIG_OBJTOOL_WERROR fixes and cleanups Josh Poimboeuf
                   ` (3 preceding siblings ...)
  2025-03-24 21:55 ` [PATCH 04/22] objtool: Fix X86_FEATURE_SMAP alternative handling Josh Poimboeuf
@ 2025-03-24 21:55 ` Josh Poimboeuf
  2025-03-25  8:35   ` [tip: objtool/urgent] " tip-bot2 for Josh Poimboeuf
  2025-03-24 21:55 ` [PATCH 06/22] objtool: Fix init_module() handling Josh Poimboeuf
                   ` (16 subsequent siblings)
  21 siblings, 1 reply; 75+ messages in thread
From: Josh Poimboeuf @ 2025-03-24 21:55 UTC (permalink / raw)
  To: x86
  Cc: linux-kernel, Peter Zijlstra, Ingo Molnar, Miroslav Benes,
	Brendan Jackman, Nathan Chancellor

With (!X86_KERNEL_IBT && !LTO_CLANG && NOINSTR_VALIDATION), objtool runs
on both translation units and vmlinux.o.  With CONFIG_OBJTOOL_WERROR,
the TUs get --Werror but vmlinux.o doesn't.  Fix that.

Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
 scripts/Makefile.vmlinux_o | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/scripts/Makefile.vmlinux_o b/scripts/Makefile.vmlinux_o
index 0b6e2ebf60dc..f476f5605029 100644
--- a/scripts/Makefile.vmlinux_o
+++ b/scripts/Makefile.vmlinux_o
@@ -30,12 +30,20 @@ endif
 # objtool for vmlinux.o
 # ---------------------------------------------------------------------------
 #
-# For LTO and IBT, objtool doesn't run on individual translation units.
-# Run everything on vmlinux instead.
+# For delay-objtool (IBT or LTO), objtool doesn't run on individual translation
+# units.  Instead it runs on vmlinux.o.
+#
+# For !delay-objtool + CONFIG_NOINSTR_VALIDATION, it runs on both translation
+# units and vmlinux.o, with the latter only used for noinstr/unret validation.
 
 objtool-enabled := $(or $(delay-objtool),$(CONFIG_NOINSTR_VALIDATION))
 
-vmlinux-objtool-args-$(delay-objtool)			+= $(objtool-args-y)
+ifeq ($(delay-objtool),y)
+vmlinux-objtool-args-y					+= $(objtool-args-y)
+else
+vmlinux-objtool-args-$(CONFIG_OBJTOOL_WERROR)		+= --Werror
+endif
+
 vmlinux-objtool-args-$(CONFIG_GCOV_KERNEL)		+= --no-unreachable
 vmlinux-objtool-args-$(CONFIG_NOINSTR_VALIDATION)	+= --noinstr \
 							   $(if $(or $(CONFIG_MITIGATION_UNRET_ENTRY),$(CONFIG_MITIGATION_SRSO)), --unret)
-- 
2.48.1


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

* [PATCH 06/22] objtool: Fix init_module() handling
  2025-03-24 21:55 [PATCH 00/22] objtool: CONFIG_OBJTOOL_WERROR fixes and cleanups Josh Poimboeuf
                   ` (4 preceding siblings ...)
  2025-03-24 21:55 ` [PATCH 05/22] objtool: Fix CONFIG_OBJTOOL_WERROR for vmlinux.o Josh Poimboeuf
@ 2025-03-24 21:55 ` Josh Poimboeuf
  2025-03-25  8:35   ` [tip: objtool/urgent] " tip-bot2 for Josh Poimboeuf
  2025-03-24 21:55 ` [PATCH 07/22] objtool: Silence more KCOV warnings Josh Poimboeuf
                   ` (15 subsequent siblings)
  21 siblings, 1 reply; 75+ messages in thread
From: Josh Poimboeuf @ 2025-03-24 21:55 UTC (permalink / raw)
  To: x86
  Cc: linux-kernel, Peter Zijlstra, Ingo Molnar, Miroslav Benes,
	Brendan Jackman, Nathan Chancellor

If IBT is enabled and a module uses the deprecated init_module() magic
function name rather than module_init(fn), its ENDBR will get removed,
causing an IBT failure during module load.

Objtool does print an obscure warning, but then does nothing to either
correct it or return an error.

Improve the usefulness of the warning and return an error so it will at
least fail the build with CONFIG_OBJTOOL_WERROR.

Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
 tools/objtool/check.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index bac88ca82dec..8edb7044f7fc 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -828,8 +828,11 @@ static int create_ibt_endbr_seal_sections(struct objtool_file *file)
 		if (opts.module && sym && sym->type == STT_FUNC &&
 		    insn->offset == sym->offset &&
 		    (!strcmp(sym->name, "init_module") ||
-		     !strcmp(sym->name, "cleanup_module")))
-			WARN("%s(): not an indirect call target", sym->name);
+		     !strcmp(sym->name, "cleanup_module"))) {
+			WARN("%s(): Magic init_module() function name is deprecated, use module_init(fn) instead",
+			     sym->name);
+			return -1;
+		}
 
 		if (!elf_init_reloc_text_sym(file->elf, sec,
 					     idx * sizeof(int), idx,
-- 
2.48.1


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

* [PATCH 07/22] objtool: Silence more KCOV warnings
  2025-03-24 21:55 [PATCH 00/22] objtool: CONFIG_OBJTOOL_WERROR fixes and cleanups Josh Poimboeuf
                   ` (5 preceding siblings ...)
  2025-03-24 21:55 ` [PATCH 06/22] objtool: Fix init_module() handling Josh Poimboeuf
@ 2025-03-24 21:55 ` Josh Poimboeuf
  2025-03-25  8:35   ` [tip: objtool/urgent] " tip-bot2 for Josh Poimboeuf
  2025-03-24 21:55 ` [PATCH 08/22] objtool: Properly disable uaccess validation Josh Poimboeuf
                   ` (14 subsequent siblings)
  21 siblings, 1 reply; 75+ messages in thread
From: Josh Poimboeuf @ 2025-03-24 21:55 UTC (permalink / raw)
  To: x86
  Cc: linux-kernel, Peter Zijlstra, Ingo Molnar, Miroslav Benes,
	Brendan Jackman, Nathan Chancellor, kernel test robot

In the past there were issues with KCOV triggering unreachable
instruction warnings, which is why unreachable warnings are now disabled
with CONFIG_KCOV.

Now some new KCOV warnings are showing up with GCC 14:

  vmlinux.o: warning: objtool: cpuset_write_resmask() falls through to next function cpuset_update_active_cpus.cold()
  drivers/usb/core/driver.o: error: objtool: usb_deregister() falls through to next function usb_match_device()
  sound/soc/codecs/snd-soc-wcd934x.o: warning: objtool: .text.wcd934x_slim_irq_handler: unexpected end of section

All are caused by GCC KCOV not finishing an optimization, leaving behind
a never-taken conditional branch to a basic block which falls through to
the next function (or end of section).

At a high level this is similar to the unreachable warnings mentioned
above, in that KCOV isn't fully removing dead code.  Treat it the same
way by adding these to the list of warnings to ignore with CONFIG_KCOV.

Reported-by: Ingo Molnar <mingo@kernel.org>
Closes: https://lore.kernel.org/Z9iTsI09AEBlxlHC@gmail.com
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202503180044.oH9gyPeg-lkp@intel.com/
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
 tools/objtool/check.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 8edb7044f7fc..032b3be409f2 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -3493,6 +3493,9 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
 			    !strncmp(func->name, "__pfx_", 6))
 				return 0;
 
+			if (file->ignore_unreachables)
+				return 0;
+
 			WARN("%s() falls through to next function %s()",
 			     func->name, insn_func(insn)->name);
 			return 1;
@@ -3702,6 +3705,9 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
 		if (!next_insn) {
 			if (state.cfi.cfa.base == CFI_UNDEFINED)
 				return 0;
+			if (file->ignore_unreachables)
+				return 0;
+
 			WARN("%s: unexpected end of section", sec->name);
 			return 1;
 		}
-- 
2.48.1


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

* [PATCH 08/22] objtool: Properly disable uaccess validation
  2025-03-24 21:55 [PATCH 00/22] objtool: CONFIG_OBJTOOL_WERROR fixes and cleanups Josh Poimboeuf
                   ` (6 preceding siblings ...)
  2025-03-24 21:55 ` [PATCH 07/22] objtool: Silence more KCOV warnings Josh Poimboeuf
@ 2025-03-24 21:55 ` Josh Poimboeuf
  2025-03-25  8:35   ` [tip: objtool/urgent] " tip-bot2 for Josh Poimboeuf
  2025-03-24 21:55 ` [PATCH 09/22] objtool: Improve error handling Josh Poimboeuf
                   ` (13 subsequent siblings)
  21 siblings, 1 reply; 75+ messages in thread
From: Josh Poimboeuf @ 2025-03-24 21:55 UTC (permalink / raw)
  To: x86
  Cc: linux-kernel, Peter Zijlstra, Ingo Molnar, Miroslav Benes,
	Brendan Jackman, Nathan Chancellor

If opts.uaccess isn't set, the uaccess validation is disabled, but only
partially: it doesn't read the uaccess_safe_builtin list but still tries
to do the validation.  Disable it completely to prevent false warnings.

Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
 tools/objtool/check.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 032b3be409f2..3966fc81a77e 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -3195,7 +3195,7 @@ static int handle_insn_ops(struct instruction *insn,
 		if (update_cfi_state(insn, next_insn, &state->cfi, op))
 			return 1;
 
-		if (!insn->alt_group)
+		if (!opts.uaccess || !insn->alt_group)
 			continue;
 
 		if (op->dest.type == OP_DEST_PUSHF) {
@@ -3655,6 +3655,9 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
 			return 0;
 
 		case INSN_STAC:
+			if (!opts.uaccess)
+				break;
+
 			if (state.uaccess) {
 				WARN_INSN(insn, "recursive UACCESS enable");
 				return 1;
@@ -3664,6 +3667,9 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
 			break;
 
 		case INSN_CLAC:
+			if (!opts.uaccess)
+				break;
+
 			if (!state.uaccess && func) {
 				WARN_INSN(insn, "redundant UACCESS disable");
 				return 1;
@@ -4122,7 +4128,8 @@ static int validate_symbol(struct objtool_file *file, struct section *sec,
 	if (!insn || insn->visited)
 		return 0;
 
-	state->uaccess = sym->uaccess_safe;
+	if (opts.uaccess)
+		state->uaccess = sym->uaccess_safe;
 
 	ret = validate_branch(file, insn_func(insn), insn, *state);
 	if (ret)
-- 
2.48.1


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

* [PATCH 09/22] objtool: Improve error handling
  2025-03-24 21:55 [PATCH 00/22] objtool: CONFIG_OBJTOOL_WERROR fixes and cleanups Josh Poimboeuf
                   ` (7 preceding siblings ...)
  2025-03-24 21:55 ` [PATCH 08/22] objtool: Properly disable uaccess validation Josh Poimboeuf
@ 2025-03-24 21:55 ` Josh Poimboeuf
  2025-03-25  8:35   ` [tip: objtool/urgent] " tip-bot2 for Josh Poimboeuf
  2025-03-24 21:56 ` [PATCH 10/22] objtool: Reduce CONFIG_OBJTOOL_WERROR verbosity Josh Poimboeuf
                   ` (12 subsequent siblings)
  21 siblings, 1 reply; 75+ messages in thread
From: Josh Poimboeuf @ 2025-03-24 21:55 UTC (permalink / raw)
  To: x86
  Cc: linux-kernel, Peter Zijlstra, Ingo Molnar, Miroslav Benes,
	Brendan Jackman, Nathan Chancellor

Fix some error handling issues, improve error messages, properly
distinguish betwee errors and warnings, and generally try to make all
the error handling more consistent.

Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
 tools/objtool/builtin-check.c           |  37 ++-
 tools/objtool/check.c                   | 370 ++++++++++++------------
 tools/objtool/elf.c                     |  22 +-
 tools/objtool/include/objtool/objtool.h |   2 +-
 tools/objtool/include/objtool/warn.h    |  13 +-
 tools/objtool/objtool.c                 |  11 +-
 6 files changed, 233 insertions(+), 222 deletions(-)

diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c
index 5f761f420b8c..c973a751fb7d 100644
--- a/tools/objtool/builtin-check.c
+++ b/tools/objtool/builtin-check.c
@@ -8,15 +8,12 @@
 #include <stdlib.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <errno.h>
 #include <sys/stat.h>
 #include <sys/sendfile.h>
 #include <objtool/builtin.h>
 #include <objtool/objtool.h>
-
-#define ERROR(format, ...)				\
-	fprintf(stderr,					\
-		"error: objtool: " format "\n",		\
-		##__VA_ARGS__)
+#include <objtool/warn.h>
 
 const char *objname;
 
@@ -139,22 +136,22 @@ int cmd_parse_options(int argc, const char **argv, const char * const usage[])
 static bool opts_valid(void)
 {
 	if (opts.mnop && !opts.mcount) {
-		ERROR("--mnop requires --mcount");
+		WARN("--mnop requires --mcount");
 		return false;
 	}
 
 	if (opts.noinstr && !opts.link) {
-		ERROR("--noinstr requires --link");
+		WARN("--noinstr requires --link");
 		return false;
 	}
 
 	if (opts.ibt && !opts.link) {
-		ERROR("--ibt requires --link");
+		WARN("--ibt requires --link");
 		return false;
 	}
 
 	if (opts.unret && !opts.link) {
-		ERROR("--unret requires --link");
+		WARN("--unret requires --link");
 		return false;
 	}
 
@@ -171,7 +168,7 @@ static bool opts_valid(void)
 	    opts.static_call		||
 	    opts.uaccess) {
 		if (opts.dump_orc) {
-			ERROR("--dump can't be combined with other actions");
+			WARN("--dump can't be combined with other actions");
 			return false;
 		}
 
@@ -181,7 +178,7 @@ static bool opts_valid(void)
 	if (opts.dump_orc)
 		return true;
 
-	ERROR("At least one action required");
+	WARN("At least one action required");
 	return false;
 }
 
@@ -194,30 +191,30 @@ static int copy_file(const char *src, const char *dst)
 
 	src_fd = open(src, O_RDONLY);
 	if (src_fd == -1) {
-		ERROR("can't open '%s' for reading", src);
+		WARN("can't open %s for reading: %s", src, strerror(errno));
 		return 1;
 	}
 
 	dst_fd = open(dst, O_WRONLY | O_CREAT | O_TRUNC, 0400);
 	if (dst_fd == -1) {
-		ERROR("can't open '%s' for writing", dst);
+		WARN("can't open %s for writing: %s", dst, strerror(errno));
 		return 1;
 	}
 
 	if (fstat(src_fd, &stat) == -1) {
-		perror("fstat");
+		WARN_GLIBC("fstat");
 		return 1;
 	}
 
 	if (fchmod(dst_fd, stat.st_mode) == -1) {
-		perror("fchmod");
+		WARN_GLIBC("fchmod");
 		return 1;
 	}
 
 	for (to_copy = stat.st_size; to_copy > 0; to_copy -= copied) {
 		copied = sendfile(dst_fd, src_fd, &offset, to_copy);
 		if (copied == -1) {
-			perror("sendfile");
+			WARN_GLIBC("sendfile");
 			return 1;
 		}
 	}
@@ -233,14 +230,14 @@ static char **save_argv(int argc, const char **argv)
 
 	orig_argv = calloc(argc, sizeof(char *));
 	if (!orig_argv) {
-		perror("calloc");
+		WARN_GLIBC("calloc");
 		return NULL;
 	}
 
 	for (int i = 0; i < argc; i++) {
 		orig_argv[i] = strdup(argv[i]);
 		if (!orig_argv[i]) {
-			perror("strdup");
+			WARN_GLIBC("strdup(%s)", orig_argv[i]);
 			return NULL;
 		}
 	};
@@ -285,7 +282,7 @@ int objtool_run(int argc, const char **argv)
 		goto err;
 
 	if (!opts.link && has_multiple_files(file->elf)) {
-		ERROR("Linked object requires --link");
+		WARN("Linked object requires --link");
 		goto err;
 	}
 
@@ -313,7 +310,7 @@ int objtool_run(int argc, const char **argv)
 	 */
 	backup = malloc(strlen(objname) + strlen(ORIG_SUFFIX) + 1);
 	if (!backup) {
-		perror("malloc");
+		WARN_GLIBC("malloc");
 		return 1;
 	}
 
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 3966fc81a77e..fbe2a5ef2c40 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -353,7 +353,7 @@ static struct cfi_state *cfi_alloc(void)
 {
 	struct cfi_state *cfi = calloc(1, sizeof(struct cfi_state));
 	if (!cfi) {
-		WARN("calloc failed");
+		WARN_GLIBC("calloc");
 		exit(1);
 	}
 	nr_cfi++;
@@ -409,7 +409,7 @@ static void *cfi_hash_alloc(unsigned long size)
 			PROT_READ|PROT_WRITE,
 			MAP_PRIVATE|MAP_ANON, -1, 0);
 	if (cfi_hash == (void *)-1L) {
-		WARN("mmap fail cfi_hash");
+		WARN_GLIBC("mmap fail cfi_hash");
 		cfi_hash = NULL;
 	}  else if (opts.stats) {
 		printf("cfi_bits: %d\n", cfi_bits);
@@ -465,7 +465,7 @@ static int decode_instructions(struct objtool_file *file)
 			if (!insns || idx == INSN_CHUNK_MAX) {
 				insns = calloc(sizeof(*insn), INSN_CHUNK_SIZE);
 				if (!insns) {
-					WARN("malloc failed");
+					WARN_GLIBC("calloc");
 					return -1;
 				}
 				idx = 0;
@@ -567,14 +567,21 @@ static int add_pv_ops(struct objtool_file *file, const char *symname)
 		if (!reloc)
 			break;
 
+		idx = (reloc_offset(reloc) - sym->offset) / sizeof(unsigned long);
+
 		func = reloc->sym;
 		if (func->type == STT_SECTION)
 			func = find_symbol_by_offset(reloc->sym->sec,
 						     reloc_addend(reloc));
+		if (!func) {
+			WARN_FUNC("can't find func at %s[%d]",
+				  reloc->sym->sec, reloc_addend(reloc),
+				  symname, idx);
+			return -1;
+		}
 
-		idx = (reloc_offset(reloc) - sym->offset) / sizeof(unsigned long);
-
-		objtool_pv_add(file, idx, func);
+		if (objtool_pv_add(file, idx, func))
+			return -1;
 
 		off = reloc_offset(reloc) + 1;
 		if (off > end)
@@ -598,7 +605,7 @@ static int init_pv_ops(struct objtool_file *file)
 	};
 	const char *pv_ops;
 	struct symbol *sym;
-	int idx, nr;
+	int idx, nr, ret;
 
 	if (!opts.noinstr)
 		return 0;
@@ -611,14 +618,19 @@ static int init_pv_ops(struct objtool_file *file)
 
 	nr = sym->len / sizeof(unsigned long);
 	file->pv_ops = calloc(sizeof(struct pv_state), nr);
-	if (!file->pv_ops)
+	if (!file->pv_ops) {
+		WARN_GLIBC("calloc");
 		return -1;
+	}
 
 	for (idx = 0; idx < nr; idx++)
 		INIT_LIST_HEAD(&file->pv_ops[idx].targets);
 
-	for (idx = 0; (pv_ops = pv_ops_tables[idx]); idx++)
-		add_pv_ops(file, pv_ops);
+	for (idx = 0; (pv_ops = pv_ops_tables[idx]); idx++) {
+		ret = add_pv_ops(file, pv_ops);
+		if (ret)
+			return ret;
+	}
 
 	return 0;
 }
@@ -666,13 +678,12 @@ static int create_static_call_sections(struct objtool_file *file)
 		/* find key symbol */
 		key_name = strdup(insn_call_dest(insn)->name);
 		if (!key_name) {
-			perror("strdup");
+			WARN_GLIBC("strdup");
 			return -1;
 		}
 		if (strncmp(key_name, STATIC_CALL_TRAMP_PREFIX_STR,
 			    STATIC_CALL_TRAMP_PREFIX_LEN)) {
 			WARN("static_call: trampoline name malformed: %s", key_name);
-			free(key_name);
 			return -1;
 		}
 		tmp = key_name + STATIC_CALL_TRAMP_PREFIX_LEN - STATIC_CALL_KEY_PREFIX_LEN;
@@ -682,7 +693,6 @@ static int create_static_call_sections(struct objtool_file *file)
 		if (!key_sym) {
 			if (!opts.module) {
 				WARN("static_call: can't find static_call_key symbol: %s", tmp);
-				free(key_name);
 				return -1;
 			}
 
@@ -697,7 +707,6 @@ static int create_static_call_sections(struct objtool_file *file)
 			 */
 			key_sym = insn_call_dest(insn);
 		}
-		free(key_name);
 
 		/* populate reloc for 'key' */
 		if (!elf_init_reloc_data_sym(file->elf, sec,
@@ -981,7 +990,7 @@ static int create_direct_call_sections(struct objtool_file *file)
 /*
  * Warnings shouldn't be reported for ignored functions.
  */
-static void add_ignores(struct objtool_file *file)
+static int add_ignores(struct objtool_file *file)
 {
 	struct section *rsec;
 	struct symbol *func;
@@ -989,7 +998,7 @@ static void add_ignores(struct objtool_file *file)
 
 	rsec = find_section_by_name(file->elf, ".rela.discard.func_stack_frame_non_standard");
 	if (!rsec)
-		return;
+		return 0;
 
 	for_each_reloc(rsec, reloc) {
 		switch (reloc->sym->type) {
@@ -1006,11 +1015,13 @@ static void add_ignores(struct objtool_file *file)
 		default:
 			WARN("unexpected relocation symbol type in %s: %d",
 			     rsec->name, reloc->sym->type);
-			continue;
+			return -1;
 		}
 
 		func->ignore = true;
 	}
+
+	return 0;
 }
 
 /*
@@ -1275,7 +1286,7 @@ static void remove_insn_ops(struct instruction *insn)
 	insn->stack_ops = NULL;
 }
 
-static void annotate_call_site(struct objtool_file *file,
+static int annotate_call_site(struct objtool_file *file,
 			       struct instruction *insn, bool sibling)
 {
 	struct reloc *reloc = insn_reloc(file, insn);
@@ -1291,16 +1302,16 @@ static void annotate_call_site(struct objtool_file *file,
 	 * original instruction if/when it ever makes sense to do so.)
 	 */
 	if (!strcmp(insn->sec->name, ".altinstr_replacement"))
-		return;
+		return 0;
 
 	if (sym->static_call_tramp) {
 		list_add_tail(&insn->call_node, &file->static_call_list);
-		return;
+		return 0;
 	}
 
 	if (sym->retpoline_thunk) {
 		list_add_tail(&insn->call_node, &file->retpoline_call_list);
-		return;
+		return 0;
 	}
 
 	/*
@@ -1312,10 +1323,12 @@ static void annotate_call_site(struct objtool_file *file,
 		if (reloc)
 			set_reloc_type(file->elf, reloc, R_NONE);
 
-		elf_write_insn(file->elf, insn->sec,
-			       insn->offset, insn->len,
-			       sibling ? arch_ret_insn(insn->len)
-			               : arch_nop_insn(insn->len));
+		if (elf_write_insn(file->elf, insn->sec,
+				   insn->offset, insn->len,
+				   sibling ? arch_ret_insn(insn->len)
+					   : arch_nop_insn(insn->len))) {
+			return -1;
+		}
 
 		insn->type = sibling ? INSN_RETURN : INSN_NOP;
 
@@ -1329,7 +1342,7 @@ static void annotate_call_site(struct objtool_file *file,
 			insn->retpoline_safe = true;
 		}
 
-		return;
+		return 0;
 	}
 
 	if (opts.mcount && sym->fentry) {
@@ -1339,15 +1352,17 @@ static void annotate_call_site(struct objtool_file *file,
 			if (reloc)
 				set_reloc_type(file->elf, reloc, R_NONE);
 
-			elf_write_insn(file->elf, insn->sec,
-				       insn->offset, insn->len,
-				       arch_nop_insn(insn->len));
+			if (elf_write_insn(file->elf, insn->sec,
+					   insn->offset, insn->len,
+					   arch_nop_insn(insn->len))) {
+				return -1;
+			}
 
 			insn->type = INSN_NOP;
 		}
 
 		list_add_tail(&insn->call_node, &file->mcount_loc_list);
-		return;
+		return 0;
 	}
 
 	if (insn->type == INSN_CALL && !insn->sec->init)
@@ -1355,14 +1370,16 @@ static void annotate_call_site(struct objtool_file *file,
 
 	if (!sibling && dead_end_function(file, sym))
 		insn->dead_end = true;
+
+	return 0;
 }
 
-static void add_call_dest(struct objtool_file *file, struct instruction *insn,
+static int add_call_dest(struct objtool_file *file, struct instruction *insn,
 			  struct symbol *dest, bool sibling)
 {
 	insn->_call_dest = dest;
 	if (!dest)
-		return;
+		return 0;
 
 	/*
 	 * Whatever stack impact regular CALLs have, should be undone
@@ -1373,10 +1390,10 @@ static void add_call_dest(struct objtool_file *file, struct instruction *insn,
 	 */
 	remove_insn_ops(insn);
 
-	annotate_call_site(file, insn, sibling);
+	return annotate_call_site(file, insn, sibling);
 }
 
-static void add_retpoline_call(struct objtool_file *file, struct instruction *insn)
+static int add_retpoline_call(struct objtool_file *file, struct instruction *insn)
 {
 	/*
 	 * Retpoline calls/jumps are really dynamic calls/jumps in disguise,
@@ -1393,7 +1410,7 @@ static void add_retpoline_call(struct objtool_file *file, struct instruction *in
 		insn->type = INSN_JUMP_DYNAMIC_CONDITIONAL;
 		break;
 	default:
-		return;
+		return 0;
 	}
 
 	insn->retpoline_safe = true;
@@ -1407,7 +1424,7 @@ static void add_retpoline_call(struct objtool_file *file, struct instruction *in
 	 */
 	remove_insn_ops(insn);
 
-	annotate_call_site(file, insn, false);
+	return annotate_call_site(file, insn, false);
 }
 
 static void add_return_call(struct objtool_file *file, struct instruction *insn, bool add)
@@ -1476,6 +1493,7 @@ static int add_jump_destinations(struct objtool_file *file)
 	struct reloc *reloc;
 	struct section *dest_sec;
 	unsigned long dest_off;
+	int ret;
 
 	for_each_insn(file, insn) {
 		if (insn->jump_dest) {
@@ -1496,7 +1514,9 @@ static int add_jump_destinations(struct objtool_file *file)
 			dest_sec = reloc->sym->sec;
 			dest_off = arch_dest_reloc_offset(reloc_addend(reloc));
 		} else if (reloc->sym->retpoline_thunk) {
-			add_retpoline_call(file, insn);
+			ret = add_retpoline_call(file, insn);
+			if (ret)
+				return ret;
 			continue;
 		} else if (reloc->sym->return_thunk) {
 			add_return_call(file, insn, true);
@@ -1506,7 +1526,9 @@ static int add_jump_destinations(struct objtool_file *file)
 			 * External sibling call or internal sibling call with
 			 * STT_FUNC reloc.
 			 */
-			add_call_dest(file, insn, reloc->sym, true);
+			ret = add_call_dest(file, insn, reloc->sym, true);
+			if (ret)
+				return ret;
 			continue;
 		} else if (reloc->sym->sec->idx) {
 			dest_sec = reloc->sym->sec;
@@ -1546,7 +1568,9 @@ static int add_jump_destinations(struct objtool_file *file)
 		 */
 		if (jump_dest->sym && jump_dest->offset == jump_dest->sym->offset) {
 			if (jump_dest->sym->retpoline_thunk) {
-				add_retpoline_call(file, insn);
+				ret = add_retpoline_call(file, insn);
+				if (ret)
+					return ret;
 				continue;
 			}
 			if (jump_dest->sym->return_thunk) {
@@ -1588,7 +1612,9 @@ static int add_jump_destinations(struct objtool_file *file)
 			 * Internal sibling call without reloc or with
 			 * STT_SECTION reloc.
 			 */
-			add_call_dest(file, insn, insn_func(jump_dest), true);
+			ret = add_call_dest(file, insn, insn_func(jump_dest), true);
+			if (ret)
+				return ret;
 			continue;
 		}
 
@@ -1618,6 +1644,7 @@ static int add_call_destinations(struct objtool_file *file)
 	unsigned long dest_off;
 	struct symbol *dest;
 	struct reloc *reloc;
+	int ret;
 
 	for_each_insn(file, insn) {
 		struct symbol *func = insn_func(insn);
@@ -1629,7 +1656,9 @@ static int add_call_destinations(struct objtool_file *file)
 			dest_off = arch_jump_destination(insn);
 			dest = find_call_destination(insn->sec, dest_off);
 
-			add_call_dest(file, insn, dest, false);
+			ret = add_call_dest(file, insn, dest, false);
+			if (ret)
+				return ret;
 
 			if (func && func->ignore)
 				continue;
@@ -1653,13 +1682,20 @@ static int add_call_destinations(struct objtool_file *file)
 				return -1;
 			}
 
-			add_call_dest(file, insn, dest, false);
+			ret = add_call_dest(file, insn, dest, false);
+			if (ret)
+				return ret;
 
 		} else if (reloc->sym->retpoline_thunk) {
-			add_retpoline_call(file, insn);
+			ret = add_retpoline_call(file, insn);
+			if (ret)
+				return ret;
 
-		} else
-			add_call_dest(file, insn, reloc->sym, false);
+		} else {
+			ret = add_call_dest(file, insn, reloc->sym, false);
+			if (ret)
+				return ret;
+		}
 	}
 
 	return 0;
@@ -1682,15 +1718,15 @@ static int handle_group_alt(struct objtool_file *file,
 	if (!orig_alt_group) {
 		struct instruction *last_orig_insn = NULL;
 
-		orig_alt_group = malloc(sizeof(*orig_alt_group));
+		orig_alt_group = calloc(1, sizeof(*orig_alt_group));
 		if (!orig_alt_group) {
-			WARN("malloc failed");
+			WARN_GLIBC("calloc");
 			return -1;
 		}
 		orig_alt_group->cfi = calloc(special_alt->orig_len,
 					     sizeof(struct cfi_state *));
 		if (!orig_alt_group->cfi) {
-			WARN("calloc failed");
+			WARN_GLIBC("calloc");
 			return -1;
 		}
 
@@ -1719,9 +1755,9 @@ static int handle_group_alt(struct objtool_file *file,
 		}
 	}
 
-	new_alt_group = malloc(sizeof(*new_alt_group));
+	new_alt_group = calloc(1, sizeof(*new_alt_group));
 	if (!new_alt_group) {
-		WARN("malloc failed");
+		WARN_GLIBC("calloc");
 		return -1;
 	}
 
@@ -1733,9 +1769,9 @@ static int handle_group_alt(struct objtool_file *file,
 		 * instruction affects the stack, the instruction after it (the
 		 * nop) will propagate the new state to the shared CFI array.
 		 */
-		nop = malloc(sizeof(*nop));
+		nop = calloc(1, sizeof(*nop));
 		if (!nop) {
-			WARN("malloc failed");
+			WARN_GLIBC("calloc");
 			return -1;
 		}
 		memset(nop, 0, sizeof(*nop));
@@ -1835,9 +1871,13 @@ static int handle_jump_alt(struct objtool_file *file,
 
 		if (reloc)
 			set_reloc_type(file->elf, reloc, R_NONE);
-		elf_write_insn(file->elf, orig_insn->sec,
-			       orig_insn->offset, orig_insn->len,
-			       arch_nop_insn(orig_insn->len));
+
+		if (elf_write_insn(file->elf, orig_insn->sec,
+				   orig_insn->offset, orig_insn->len,
+				   arch_nop_insn(orig_insn->len))) {
+			return -1;
+		}
+
 		orig_insn->type = INSN_NOP;
 	}
 
@@ -1873,9 +1913,8 @@ static int add_special_section_alts(struct objtool_file *file)
 	struct alternative *alt;
 	int ret;
 
-	ret = special_get_alts(file->elf, &special_alts);
-	if (ret)
-		return ret;
+	if (special_get_alts(file->elf, &special_alts))
+		return -1;
 
 	list_for_each_entry_safe(special_alt, tmp, &special_alts, list) {
 
@@ -1884,8 +1923,7 @@ static int add_special_section_alts(struct objtool_file *file)
 		if (!orig_insn) {
 			WARN_FUNC("special: can't find orig instruction",
 				  special_alt->orig_sec, special_alt->orig_off);
-			ret = -1;
-			goto out;
+			return -1;
 		}
 
 		new_insn = NULL;
@@ -1896,8 +1934,7 @@ static int add_special_section_alts(struct objtool_file *file)
 				WARN_FUNC("special: can't find new instruction",
 					  special_alt->new_sec,
 					  special_alt->new_off);
-				ret = -1;
-				goto out;
+				return -1;
 			}
 		}
 
@@ -1910,19 +1947,19 @@ static int add_special_section_alts(struct objtool_file *file)
 			ret = handle_group_alt(file, special_alt, orig_insn,
 					       &new_insn);
 			if (ret)
-				goto out;
+				return ret;
+
 		} else if (special_alt->jump_or_nop) {
 			ret = handle_jump_alt(file, special_alt, orig_insn,
 					      &new_insn);
 			if (ret)
-				goto out;
+				return ret;
 		}
 
-		alt = malloc(sizeof(*alt));
+		alt = calloc(1, sizeof(*alt));
 		if (!alt) {
-			WARN("malloc failed");
-			ret = -1;
-			goto out;
+			WARN_GLIBC("calloc");
+			return -1;
 		}
 
 		alt->insn = new_insn;
@@ -1939,8 +1976,7 @@ static int add_special_section_alts(struct objtool_file *file)
 		printf("long:\t%ld\t%ld\n", file->jl_nop_long, file->jl_long);
 	}
 
-out:
-	return ret;
+	return 0;
 }
 
 __weak unsigned long arch_jump_table_sym_offset(struct reloc *reloc, struct reloc *table)
@@ -1997,9 +2033,9 @@ static int add_jump_table(struct objtool_file *file, struct instruction *insn)
 		if (!insn_func(dest_insn) || insn_func(dest_insn)->pfunc != pfunc)
 			break;
 
-		alt = malloc(sizeof(*alt));
+		alt = calloc(1, sizeof(*alt));
 		if (!alt) {
-			WARN("malloc failed");
+			WARN_GLIBC("calloc");
 			return -1;
 		}
 
@@ -2047,7 +2083,7 @@ static void find_jump_table(struct objtool_file *file, struct symbol *func,
 		    insn->jump_dest &&
 		    (insn->jump_dest->offset <= insn->offset ||
 		     insn->jump_dest->offset > orig_insn->offset))
-		    break;
+			break;
 
 		table_reloc = arch_find_switch_table(file, insn, &table_size);
 		if (!table_reloc)
@@ -2111,7 +2147,6 @@ static int add_func_jump_tables(struct objtool_file *file,
 		if (!insn_jump_table(insn))
 			continue;
 
-
 		ret = add_jump_table(file, insn);
 		if (ret)
 			return ret;
@@ -2229,6 +2264,7 @@ static int read_unwind_hints(struct objtool_file *file)
 			if (sym && sym->bind == STB_GLOBAL) {
 				if (opts.ibt && insn->type != INSN_ENDBR && !insn->noendbr) {
 					WARN_INSN(insn, "UNWIND_HINT_IRET_REGS without ENDBR");
+					return -1;
 				}
 			}
 		}
@@ -2398,7 +2434,7 @@ static int __annotate_late(struct objtool_file *file, int type, struct instructi
 
 	default:
 		WARN_INSN(insn, "Unknown annotation type: %d", type);
-		break;
+		return -1;
 	}
 
 	return 0;
@@ -2511,7 +2547,10 @@ static int decode_sections(struct objtool_file *file)
 	if (ret)
 		return ret;
 
-	add_ignores(file);
+	ret = add_ignores(file);
+	if (ret)
+		return ret;
+
 	add_uaccess_safe(file);
 
 	ret = read_annotate(file, __annotate_early);
@@ -2731,7 +2770,7 @@ static int update_cfi_state(struct instruction *insn,
 	if (cfa->base == CFI_UNDEFINED) {
 		if (insn_func(insn)) {
 			WARN_INSN(insn, "undefined stack state");
-			return -1;
+			return 1;
 		}
 		return 0;
 	}
@@ -3174,9 +3213,8 @@ static int propagate_alt_cfi(struct objtool_file *file, struct instruction *insn
 		if (cficmp(alt_cfi[group_off], insn->cfi)) {
 			struct alt_group *orig_group = insn->alt_group->orig_group ?: insn->alt_group;
 			struct instruction *orig = orig_group->first_insn;
-			char *where = offstr(insn->sec, insn->offset);
-			WARN_INSN(orig, "stack layout conflict in alternatives: %s", where);
-			free(where);
+			WARN_INSN(orig, "stack layout conflict in alternatives: %s",
+				  offstr(insn->sec, insn->offset));
 			return -1;
 		}
 	}
@@ -3189,11 +3227,13 @@ static int handle_insn_ops(struct instruction *insn,
 			   struct insn_state *state)
 {
 	struct stack_op *op;
+	int ret;
 
 	for (op = insn->stack_ops; op; op = op->next) {
 
-		if (update_cfi_state(insn, next_insn, &state->cfi, op))
-			return 1;
+		ret = update_cfi_state(insn, next_insn, &state->cfi, op);
+		if (ret)
+			return ret;
 
 		if (!opts.uaccess || !insn->alt_group)
 			continue;
@@ -3237,36 +3277,41 @@ static bool insn_cfi_match(struct instruction *insn, struct cfi_state *cfi2)
 		WARN_INSN(insn, "stack state mismatch: cfa1=%d%+d cfa2=%d%+d",
 			  cfi1->cfa.base, cfi1->cfa.offset,
 			  cfi2->cfa.base, cfi2->cfa.offset);
+		return false;
 
-	} else if (memcmp(&cfi1->regs, &cfi2->regs, sizeof(cfi1->regs))) {
+	}
+
+	if (memcmp(&cfi1->regs, &cfi2->regs, sizeof(cfi1->regs))) {
 		for (i = 0; i < CFI_NUM_REGS; i++) {
-			if (!memcmp(&cfi1->regs[i], &cfi2->regs[i],
-				    sizeof(struct cfi_reg)))
+
+			if (!memcmp(&cfi1->regs[i], &cfi2->regs[i], sizeof(struct cfi_reg)))
 				continue;
 
 			WARN_INSN(insn, "stack state mismatch: reg1[%d]=%d%+d reg2[%d]=%d%+d",
 				  i, cfi1->regs[i].base, cfi1->regs[i].offset,
 				  i, cfi2->regs[i].base, cfi2->regs[i].offset);
-			break;
 		}
+		return false;
+	}
 
-	} else if (cfi1->type != cfi2->type) {
+	if (cfi1->type != cfi2->type) {
 
 		WARN_INSN(insn, "stack state mismatch: type1=%d type2=%d",
 			  cfi1->type, cfi2->type);
+		return false;
+	}
 
-	} else if (cfi1->drap != cfi2->drap ||
+	if (cfi1->drap != cfi2->drap ||
 		   (cfi1->drap && cfi1->drap_reg != cfi2->drap_reg) ||
 		   (cfi1->drap && cfi1->drap_offset != cfi2->drap_offset)) {
 
 		WARN_INSN(insn, "stack state mismatch: drap1=%d(%d,%d) drap2=%d(%d,%d)",
 			  cfi1->drap, cfi1->drap_reg, cfi1->drap_offset,
 			  cfi2->drap, cfi2->drap_reg, cfi2->drap_offset);
+		return false;
+	}
 
-	} else
-		return true;
-
-	return false;
+	return true;
 }
 
 static inline bool func_uaccess_safe(struct symbol *func)
@@ -3498,6 +3543,8 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
 
 			WARN("%s() falls through to next function %s()",
 			     func->name, insn_func(insn)->name);
+			func->warnings++;
+
 			return 1;
 		}
 
@@ -3605,9 +3652,6 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
 				return 1;
 			}
 
-			if (insn->dead_end)
-				return 0;
-
 			break;
 
 		case INSN_JUMP_CONDITIONAL:
@@ -3714,7 +3758,9 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
 			if (file->ignore_unreachables)
 				return 0;
 
-			WARN("%s: unexpected end of section", sec->name);
+			WARN("%s%sunexpected end of section %s",
+			     func ? func->name : "", func ? ": " : "",
+			     sec->name);
 			return 1;
 		}
 
@@ -3804,7 +3850,7 @@ static int validate_unret(struct objtool_file *file, struct instruction *insn)
 			if (!is_sibling_call(insn)) {
 				if (!insn->jump_dest) {
 					WARN_INSN(insn, "unresolved jump target after linking?!?");
-					return -1;
+					return 1;
 				}
 				ret = validate_unret(file, insn->jump_dest);
 				if (ret) {
@@ -3826,7 +3872,7 @@ static int validate_unret(struct objtool_file *file, struct instruction *insn)
 			if (!dest) {
 				WARN("Unresolved function after linking!?: %s",
 				     insn_call_dest(insn)->name);
-				return -1;
+				return 1;
 			}
 
 			ret = validate_unret(file, dest);
@@ -3855,7 +3901,7 @@ static int validate_unret(struct objtool_file *file, struct instruction *insn)
 
 		if (!next) {
 			WARN_INSN(insn, "teh end!");
-			return -1;
+			return 1;
 		}
 		insn = next;
 	}
@@ -3870,18 +3916,13 @@ static int validate_unret(struct objtool_file *file, struct instruction *insn)
 static int validate_unrets(struct objtool_file *file)
 {
 	struct instruction *insn;
-	int ret, warnings = 0;
+	int warnings = 0;
 
 	for_each_insn(file, insn) {
 		if (!insn->unret)
 			continue;
 
-		ret = validate_unret(file, insn);
-		if (ret < 0) {
-			WARN_INSN(insn, "Failed UNRET validation");
-			return ret;
-		}
-		warnings += ret;
+		warnings += validate_unret(file, insn);
 	}
 
 	return warnings;
@@ -3907,13 +3948,13 @@ static int validate_retpoline(struct objtool_file *file)
 		if (insn->type == INSN_RETURN) {
 			if (opts.rethunk) {
 				WARN_INSN(insn, "'naked' return found in MITIGATION_RETHUNK build");
-			} else
-				continue;
-		} else {
-			WARN_INSN(insn, "indirect %s found in MITIGATION_RETPOLINE build",
-				  insn->type == INSN_JUMP_DYNAMIC ? "jump" : "call");
+				warnings++;
+			}
+			continue;
 		}
 
+		WARN_INSN(insn, "indirect %s found in MITIGATION_RETPOLINE build",
+			  insn->type == INSN_JUMP_DYNAMIC ? "jump" : "call");
 		warnings++;
 	}
 
@@ -4480,7 +4521,7 @@ static int validate_reachable_instructions(struct objtool_file *file)
 }
 
 /* 'funcs' is a space-separated list of function names */
-static int disas_funcs(const char *funcs)
+static void disas_funcs(const char *funcs)
 {
 	const char *objdump_str, *cross_compile;
 	int size, ret;
@@ -4513,7 +4554,7 @@ static int disas_funcs(const char *funcs)
 	size = snprintf(NULL, 0, objdump_str, cross_compile, objname, funcs) + 1;
 	if (size <= 0) {
 		WARN("objdump string size calculation failed");
-		return -1;
+		return;
 	}
 
 	cmd = malloc(size);
@@ -4523,13 +4564,11 @@ static int disas_funcs(const char *funcs)
 	ret = system(cmd);
 	if (ret) {
 		WARN("disassembly failed: %d", ret);
-		return -1;
+		return;
 	}
-
-	return 0;
 }
 
-static int disas_warned_funcs(struct objtool_file *file)
+static void disas_warned_funcs(struct objtool_file *file)
 {
 	struct symbol *sym;
 	char *funcs = NULL, *tmp;
@@ -4538,9 +4577,17 @@ static int disas_warned_funcs(struct objtool_file *file)
 		if (sym->warnings) {
 			if (!funcs) {
 				funcs = malloc(strlen(sym->name) + 1);
+				if (!funcs) {
+					WARN_GLIBC("malloc");
+					return;
+				}
 				strcpy(funcs, sym->name);
 			} else {
 				tmp = malloc(strlen(funcs) + strlen(sym->name) + 2);
+				if (!tmp) {
+					WARN_GLIBC("malloc");
+					return;
+				}
 				sprintf(tmp, "%s %s", funcs, sym->name);
 				free(funcs);
 				funcs = tmp;
@@ -4550,8 +4597,6 @@ static int disas_warned_funcs(struct objtool_file *file)
 
 	if (funcs)
 		disas_funcs(funcs);
-
-	return 0;
 }
 
 struct insn_chunk {
@@ -4584,7 +4629,7 @@ static void free_insns(struct objtool_file *file)
 
 int check(struct objtool_file *file)
 {
-	int ret, warnings = 0;
+	int ret = 0, warnings = 0;
 
 	arch_initial_func_cfi_state(&initial_func_cfi);
 	init_cfi_state(&init_cfi);
@@ -4602,44 +4647,27 @@ int check(struct objtool_file *file)
 	cfi_hash_add(&func_cfi);
 
 	ret = decode_sections(file);
-	if (ret < 0)
+	if (ret)
 		goto out;
 
-	warnings += ret;
-
 	if (!nr_insns)
 		goto out;
 
-	if (opts.retpoline) {
-		ret = validate_retpoline(file);
-		if (ret < 0)
-			goto out;
-		warnings += ret;
-	}
+	if (opts.retpoline)
+		warnings += validate_retpoline(file);
 
 	if (opts.stackval || opts.orc || opts.uaccess) {
-		ret = validate_functions(file);
-		if (ret < 0)
-			goto out;
-		warnings += ret;
+		int w = 0;
 
-		ret = validate_unwind_hints(file, NULL);
-		if (ret < 0)
-			goto out;
-		warnings += ret;
+		w += validate_functions(file);
+		w += validate_unwind_hints(file, NULL);
+		if (!w)
+			w += validate_reachable_instructions(file);
 
-		if (!warnings) {
-			ret = validate_reachable_instructions(file);
-			if (ret < 0)
-				goto out;
-			warnings += ret;
-		}
+		warnings += w;
 
 	} else if (opts.noinstr) {
-		ret = validate_noinstr_sections(file);
-		if (ret < 0)
-			goto out;
-		warnings += ret;
+		warnings += validate_noinstr_sections(file);
 	}
 
 	if (opts.unret) {
@@ -4647,87 +4675,67 @@ int check(struct objtool_file *file)
 		 * Must be after validate_branch() and friends, it plays
 		 * further games with insn->visited.
 		 */
-		ret = validate_unrets(file);
-		if (ret < 0)
-			goto out;
-		warnings += ret;
+		warnings += validate_unrets(file);
 	}
 
-	if (opts.ibt) {
-		ret = validate_ibt(file);
-		if (ret < 0)
-			goto out;
-		warnings += ret;
-	}
+	if (opts.ibt)
+		warnings += validate_ibt(file);
 
-	if (opts.sls) {
-		ret = validate_sls(file);
-		if (ret < 0)
-			goto out;
-		warnings += ret;
-	}
+	if (opts.sls)
+		warnings += validate_sls(file);
 
 	if (opts.static_call) {
 		ret = create_static_call_sections(file);
-		if (ret < 0)
+		if (ret)
 			goto out;
-		warnings += ret;
 	}
 
 	if (opts.retpoline) {
 		ret = create_retpoline_sites_sections(file);
-		if (ret < 0)
+		if (ret)
 			goto out;
-		warnings += ret;
 	}
 
 	if (opts.cfi) {
 		ret = create_cfi_sections(file);
-		if (ret < 0)
+		if (ret)
 			goto out;
-		warnings += ret;
 	}
 
 	if (opts.rethunk) {
 		ret = create_return_sites_sections(file);
-		if (ret < 0)
+		if (ret)
 			goto out;
-		warnings += ret;
 
 		if (opts.hack_skylake) {
 			ret = create_direct_call_sections(file);
-			if (ret < 0)
+			if (ret)
 				goto out;
-			warnings += ret;
 		}
 	}
 
 	if (opts.mcount) {
 		ret = create_mcount_loc_sections(file);
-		if (ret < 0)
+		if (ret)
 			goto out;
-		warnings += ret;
 	}
 
 	if (opts.prefix) {
 		ret = add_prefix_symbols(file);
-		if (ret < 0)
+		if (ret)
 			goto out;
-		warnings += ret;
 	}
 
 	if (opts.ibt) {
 		ret = create_ibt_endbr_seal_sections(file);
-		if (ret < 0)
+		if (ret)
 			goto out;
-		warnings += ret;
 	}
 
 	if (opts.orc && nr_insns) {
 		ret = orc_create(file);
-		if (ret < 0)
+		if (ret)
 			goto out;
-		warnings += ret;
 	}
 
 	free_insns(file);
diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index 0f38167bd840..b352a78b596c 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -331,7 +331,7 @@ static int read_sections(struct elf *elf)
 
 	elf->section_data = calloc(sections_nr, sizeof(*sec));
 	if (!elf->section_data) {
-		perror("calloc");
+		WARN_GLIBC("calloc");
 		return -1;
 	}
 	for (i = 0; i < sections_nr; i++) {
@@ -467,7 +467,7 @@ static int read_symbols(struct elf *elf)
 
 	elf->symbol_data = calloc(symbols_nr, sizeof(*sym));
 	if (!elf->symbol_data) {
-		perror("calloc");
+		WARN_GLIBC("calloc");
 		return -1;
 	}
 	for (i = 0; i < symbols_nr; i++) {
@@ -799,7 +799,7 @@ elf_create_section_symbol(struct elf *elf, struct section *sec)
 	struct symbol *sym = calloc(1, sizeof(*sym));
 
 	if (!sym) {
-		perror("malloc");
+		WARN_GLIBC("malloc");
 		return NULL;
 	}
 
@@ -829,7 +829,7 @@ elf_create_prefix_symbol(struct elf *elf, struct symbol *orig, long size)
 	char *name = malloc(namelen);
 
 	if (!sym || !name) {
-		perror("malloc");
+		WARN_GLIBC("malloc");
 		return NULL;
 	}
 
@@ -963,7 +963,7 @@ static int read_relocs(struct elf *elf)
 		nr_reloc = 0;
 		rsec->relocs = calloc(sec_num_entries(rsec), sizeof(*reloc));
 		if (!rsec->relocs) {
-			perror("calloc");
+			WARN_GLIBC("calloc");
 			return -1;
 		}
 		for (i = 0; i < sec_num_entries(rsec); i++) {
@@ -1005,7 +1005,7 @@ struct elf *elf_open_read(const char *name, int flags)
 
 	elf = malloc(sizeof(*elf));
 	if (!elf) {
-		perror("malloc");
+		WARN_GLIBC("malloc");
 		return NULL;
 	}
 	memset(elf, 0, sizeof(*elf));
@@ -1099,7 +1099,7 @@ struct section *elf_create_section(struct elf *elf, const char *name,
 
 	sec = malloc(sizeof(*sec));
 	if (!sec) {
-		perror("malloc");
+		WARN_GLIBC("malloc");
 		return NULL;
 	}
 	memset(sec, 0, sizeof(*sec));
@@ -1114,7 +1114,7 @@ struct section *elf_create_section(struct elf *elf, const char *name,
 
 	sec->name = strdup(name);
 	if (!sec->name) {
-		perror("strdup");
+		WARN_GLIBC("strdup");
 		return NULL;
 	}
 
@@ -1132,7 +1132,7 @@ struct section *elf_create_section(struct elf *elf, const char *name,
 	if (size) {
 		sec->data->d_buf = malloc(size);
 		if (!sec->data->d_buf) {
-			perror("malloc");
+			WARN_GLIBC("malloc");
 			return NULL;
 		}
 		memset(sec->data->d_buf, 0, size);
@@ -1179,7 +1179,7 @@ static struct section *elf_create_rela_section(struct elf *elf,
 
 	rsec_name = malloc(strlen(sec->name) + strlen(".rela") + 1);
 	if (!rsec_name) {
-		perror("malloc");
+		WARN_GLIBC("malloc");
 		return NULL;
 	}
 	strcpy(rsec_name, ".rela");
@@ -1199,7 +1199,7 @@ static struct section *elf_create_rela_section(struct elf *elf,
 
 	rsec->relocs = calloc(sec_num_entries(rsec), sizeof(struct reloc));
 	if (!rsec->relocs) {
-		perror("calloc");
+		WARN_GLIBC("calloc");
 		return NULL;
 	}
 
diff --git a/tools/objtool/include/objtool/objtool.h b/tools/objtool/include/objtool/objtool.h
index 94a33ee7b363..c0dc86a78ff6 100644
--- a/tools/objtool/include/objtool/objtool.h
+++ b/tools/objtool/include/objtool/objtool.h
@@ -41,7 +41,7 @@ struct objtool_file {
 
 struct objtool_file *objtool_open_read(const char *_objname);
 
-void objtool_pv_add(struct objtool_file *file, int idx, struct symbol *func);
+int objtool_pv_add(struct objtool_file *file, int idx, struct symbol *func);
 
 int check(struct objtool_file *file);
 int orc_dump(const char *objname);
diff --git a/tools/objtool/include/objtool/warn.h b/tools/objtool/include/objtool/warn.h
index e72b9d630551..b29ac144e4f5 100644
--- a/tools/objtool/include/objtool/warn.h
+++ b/tools/objtool/include/objtool/warn.h
@@ -11,6 +11,7 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#include <errno.h>
 #include <objtool/builtin.h>
 #include <objtool/elf.h>
 
@@ -43,8 +44,9 @@ static inline char *offstr(struct section *sec, unsigned long offset)
 
 #define WARN(format, ...)				\
 	fprintf(stderr,					\
-		"%s: %s: objtool: " format "\n",	\
-		objname,				\
+		"%s%s%s: objtool: " format "\n",	\
+		objname ?: "",				\
+		objname ? ": " : "",			\
 		opts.werror ? "error" : "warning",	\
 		##__VA_ARGS__)
 
@@ -83,7 +85,10 @@ static inline char *offstr(struct section *sec, unsigned long offset)
 	}							\
 })
 
-#define WARN_ELF(format, ...)				\
-	WARN(format ": %s", ##__VA_ARGS__, elf_errmsg(-1))
+#define WARN_ELF(format, ...)					\
+	WARN("%s: " format " failed: %s", __func__, ##__VA_ARGS__, elf_errmsg(-1))
+
+#define WARN_GLIBC(format, ...)					\
+	WARN("%s: " format " failed: %s", __func__, ##__VA_ARGS__, strerror(errno))
 
 #endif /* _WARN_H */
diff --git a/tools/objtool/objtool.c b/tools/objtool/objtool.c
index 1c73fb62fd57..e4b49c534e4d 100644
--- a/tools/objtool/objtool.c
+++ b/tools/objtool/objtool.c
@@ -44,14 +44,14 @@ struct objtool_file *objtool_open_read(const char *filename)
 	return &file;
 }
 
-void objtool_pv_add(struct objtool_file *f, int idx, struct symbol *func)
+int objtool_pv_add(struct objtool_file *f, int idx, struct symbol *func)
 {
 	if (!opts.noinstr)
-		return;
+		return 0;
 
 	if (!f->pv_ops) {
 		WARN("paravirt confusion");
-		return;
+		return -1;
 	}
 
 	/*
@@ -60,14 +60,15 @@ void objtool_pv_add(struct objtool_file *f, int idx, struct symbol *func)
 	 */
 	if (!strcmp(func->name, "_paravirt_nop") ||
 	    !strcmp(func->name, "_paravirt_ident_64"))
-		return;
+		return 0;
 
 	/* already added this function */
 	if (!list_empty(&func->pv_target))
-		return;
+		return 0;
 
 	list_add(&func->pv_target, &f->pv_ops[idx].targets);
 	f->pv_ops[idx].clean = false;
+	return 0;
 }
 
 int main(int argc, const char **argv)
-- 
2.48.1


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

* [PATCH 10/22] objtool: Reduce CONFIG_OBJTOOL_WERROR verbosity
  2025-03-24 21:55 [PATCH 00/22] objtool: CONFIG_OBJTOOL_WERROR fixes and cleanups Josh Poimboeuf
                   ` (8 preceding siblings ...)
  2025-03-24 21:55 ` [PATCH 09/22] objtool: Improve error handling Josh Poimboeuf
@ 2025-03-24 21:56 ` Josh Poimboeuf
  2025-03-25  8:35   ` [tip: objtool/urgent] " tip-bot2 for Josh Poimboeuf
  2025-03-24 21:56 ` [PATCH 11/22] objtool: Fix up some outdated references to ENTRY/ENDPROC Josh Poimboeuf
                   ` (11 subsequent siblings)
  21 siblings, 1 reply; 75+ messages in thread
From: Josh Poimboeuf @ 2025-03-24 21:56 UTC (permalink / raw)
  To: x86
  Cc: linux-kernel, Peter Zijlstra, Ingo Molnar, Miroslav Benes,
	Brendan Jackman, Nathan Chancellor

Remove the following from CONFIG_OBJTOOL_WERROR:

  * backtrace

  * "upgraded warnings to errors" message

  * cmdline args

This makes the default output less cluttered and makes it easier to spot
the actual warnings.  Note the above options are still are available
with --verbose or OBJTOOL_VERBOSE=1.

Also, do the cmdline arg printing on all warnings, regardless of werror.

Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
 scripts/Makefile.lib                    |   2 +-
 tools/objtool/builtin-check.c           | 113 ++++++++++++------------
 tools/objtool/check.c                   |  23 ++---
 tools/objtool/include/objtool/builtin.h |   6 +-
 4 files changed, 73 insertions(+), 71 deletions(-)

diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 99e281966ba3..cdf45722626c 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -277,7 +277,7 @@ objtool-args-$(CONFIG_HAVE_STATIC_CALL_INLINE)		+= --static-call
 objtool-args-$(CONFIG_HAVE_UACCESS_VALIDATION)		+= --uaccess
 objtool-args-$(CONFIG_GCOV_KERNEL)			+= --no-unreachable
 objtool-args-$(CONFIG_PREFIX_SYMBOLS)			+= --prefix=$(CONFIG_FUNCTION_PADDING_BYTES)
-objtool-args-$(CONFIG_OBJTOOL_WERROR)			+= --Werror --backtrace
+objtool-args-$(CONFIG_OBJTOOL_WERROR)			+= --Werror
 
 objtool-args = $(objtool-args-y)					\
 	$(if $(delay-objtool), --link)					\
diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c
index c973a751fb7d..2bdff910430e 100644
--- a/tools/objtool/builtin-check.c
+++ b/tools/objtool/builtin-check.c
@@ -15,8 +15,11 @@
 #include <objtool/objtool.h>
 #include <objtool/warn.h>
 
-const char *objname;
+#define ORIG_SUFFIX ".orig"
 
+int orig_argc;
+static char **orig_argv;
+const char *objname;
 struct opts opts;
 
 static const char * const check_usage[] = {
@@ -224,39 +227,73 @@ static int copy_file(const char *src, const char *dst)
 	return 0;
 }
 
-static char **save_argv(int argc, const char **argv)
+static void save_argv(int argc, const char **argv)
 {
-	char **orig_argv;
-
 	orig_argv = calloc(argc, sizeof(char *));
 	if (!orig_argv) {
 		WARN_GLIBC("calloc");
-		return NULL;
+		exit(1);
 	}
 
 	for (int i = 0; i < argc; i++) {
 		orig_argv[i] = strdup(argv[i]);
 		if (!orig_argv[i]) {
 			WARN_GLIBC("strdup(%s)", orig_argv[i]);
-			return NULL;
+			exit(1);
 		}
 	};
-
-	return orig_argv;
 }
 
-#define ORIG_SUFFIX ".orig"
+void print_args(void)
+{
+	char *backup = NULL;
+
+	if (opts.output || opts.dryrun)
+		goto print;
+
+	/*
+	 * Make a backup before kbuild deletes the file so the error
+	 * can be recreated without recompiling or relinking.
+	 */
+	backup = malloc(strlen(objname) + strlen(ORIG_SUFFIX) + 1);
+	if (!backup) {
+		WARN_GLIBC("malloc");
+		goto print;
+	}
+
+	strcpy(backup, objname);
+	strcat(backup, ORIG_SUFFIX);
+	if (copy_file(objname, backup)) {
+		backup = NULL;
+		goto print;
+	}
+
+print:
+	/*
+	 * Print the cmdline args to make it easier to recreate.  If '--output'
+	 * wasn't used, add it to the printed args with the backup as input.
+	 */
+	fprintf(stderr, "%s", orig_argv[0]);
+
+	for (int i = 1; i < orig_argc; i++) {
+		char *arg = orig_argv[i];
+
+		if (backup && !strcmp(arg, objname))
+			fprintf(stderr, " %s -o %s", backup, objname);
+		else
+			fprintf(stderr, " %s", arg);
+	}
+
+	fprintf(stderr, "\n");
+}
 
 int objtool_run(int argc, const char **argv)
 {
 	struct objtool_file *file;
-	char *backup = NULL;
-	char **orig_argv;
 	int ret = 0;
 
-	orig_argv = save_argv(argc, argv);
-	if (!orig_argv)
-		return 1;
+	orig_argc = argc;
+	save_argv(argc, argv);
 
 	cmd_parse_options(argc, argv, check_usage);
 
@@ -279,59 +316,19 @@ int objtool_run(int argc, const char **argv)
 
 	file = objtool_open_read(objname);
 	if (!file)
-		goto err;
+		return 1;
 
 	if (!opts.link && has_multiple_files(file->elf)) {
 		WARN("Linked object requires --link");
-		goto err;
+		return 1;
 	}
 
 	ret = check(file);
 	if (ret)
-		goto err;
+		return ret;
 
 	if (!opts.dryrun && file->elf->changed && elf_write(file->elf))
-		goto err;
+		return 1;
 
 	return 0;
-
-err:
-	if (opts.dryrun)
-		goto err_msg;
-
-	if (opts.output) {
-		unlink(opts.output);
-		goto err_msg;
-	}
-
-	/*
-	 * Make a backup before kbuild deletes the file so the error
-	 * can be recreated without recompiling or relinking.
-	 */
-	backup = malloc(strlen(objname) + strlen(ORIG_SUFFIX) + 1);
-	if (!backup) {
-		WARN_GLIBC("malloc");
-		return 1;
-	}
-
-	strcpy(backup, objname);
-	strcat(backup, ORIG_SUFFIX);
-	if (copy_file(objname, backup))
-		return 1;
-
-err_msg:
-	fprintf(stderr, "%s", orig_argv[0]);
-
-	for (int i = 1; i < argc; i++) {
-		char *arg = orig_argv[i];
-
-		if (backup && !strcmp(arg, objname))
-			fprintf(stderr, " %s -o %s", backup, objname);
-		else
-			fprintf(stderr, " %s", arg);
-	}
-
-	fprintf(stderr, "\n");
-
-	return 1;
 }
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index fbe2a5ef2c40..03ec485a376a 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -4740,9 +4740,6 @@ int check(struct objtool_file *file)
 
 	free_insns(file);
 
-	if (opts.verbose)
-		disas_warned_funcs(file);
-
 	if (opts.stats) {
 		printf("nr_insns_visited: %ld\n", nr_insns_visited);
 		printf("nr_cfi: %ld\n", nr_cfi);
@@ -4751,19 +4748,25 @@ int check(struct objtool_file *file)
 	}
 
 out:
+	if (!ret && !warnings)
+		return 0;
+
+	if (opts.verbose) {
+		if (opts.werror && warnings)
+			WARN("%d warning(s) upgraded to errors", warnings);
+		print_args();
+		disas_warned_funcs(file);
+	}
+
 	/*
 	 * CONFIG_OBJTOOL_WERROR upgrades all warnings (and errors) to actual
 	 * errors.
 	 *
-	 * Note that even "fatal" type errors don't actually return an error
-	 * without CONFIG_OBJTOOL_WERROR.  That probably needs improved at some
-	 * point.
+	 * Note that even fatal errors don't yet actually return an error
+	 * without CONFIG_OBJTOOL_WERROR.  That will be fixed soon-ish.
 	 */
-	if (opts.werror && (ret || warnings)) {
-		if (warnings)
-			WARN("%d warning(s) upgraded to errors", warnings);
+	if (opts.werror)
 		return 1;
-	}
 
 	return 0;
 }
diff --git a/tools/objtool/include/objtool/builtin.h b/tools/objtool/include/objtool/builtin.h
index 0fafd0f7a209..6b08666fa69d 100644
--- a/tools/objtool/include/objtool/builtin.h
+++ b/tools/objtool/include/objtool/builtin.h
@@ -43,8 +43,10 @@ struct opts {
 
 extern struct opts opts;
 
-extern int cmd_parse_options(int argc, const char **argv, const char * const usage[]);
+int cmd_parse_options(int argc, const char **argv, const char * const usage[]);
 
-extern int objtool_run(int argc, const char **argv);
+int objtool_run(int argc, const char **argv);
+
+void print_args(void);
 
 #endif /* _BUILTIN_H */
-- 
2.48.1


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

* [PATCH 11/22] objtool: Fix up some outdated references to ENTRY/ENDPROC
  2025-03-24 21:55 [PATCH 00/22] objtool: CONFIG_OBJTOOL_WERROR fixes and cleanups Josh Poimboeuf
                   ` (9 preceding siblings ...)
  2025-03-24 21:56 ` [PATCH 10/22] objtool: Reduce CONFIG_OBJTOOL_WERROR verbosity Josh Poimboeuf
@ 2025-03-24 21:56 ` Josh Poimboeuf
  2025-03-25  8:35   ` [tip: objtool/urgent] " tip-bot2 for Josh Poimboeuf
  2025-03-24 21:56 ` [PATCH 12/22] objtool: Remove --no-unreachable for noinstr-only vmlinux.o runs Josh Poimboeuf
                   ` (10 subsequent siblings)
  21 siblings, 1 reply; 75+ messages in thread
From: Josh Poimboeuf @ 2025-03-24 21:56 UTC (permalink / raw)
  To: x86
  Cc: linux-kernel, Peter Zijlstra, Ingo Molnar, Miroslav Benes,
	Brendan Jackman, Nathan Chancellor

ENTRY and ENDPROC were deprecated years ago and replaced with
SYM_FUNC_{START,END}.  Fix up a few outdated references in the objtool
documentation and comments.  Also fix a few typos.

Suggested-by: Brendan Jackman <jackmanb@google.com>
Suggested-by: Miroslav Benes <mbenes@suse.cz>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
 include/linux/linkage.h                 |  4 ----
 include/linux/objtool.h                 |  2 +-
 tools/objtool/Documentation/objtool.txt | 10 +++++-----
 3 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/include/linux/linkage.h b/include/linux/linkage.h
index 5c8865bb59d9..b11660b706c5 100644
--- a/include/linux/linkage.h
+++ b/include/linux/linkage.h
@@ -134,10 +134,6 @@
 	.size name, .-name
 #endif
 
-/* If symbol 'name' is treated as a subroutine (gets called, and returns)
- * then please use ENDPROC to mark 'name' as STT_FUNC for the benefit of
- * static analysis tools such as stack depth analyzer.
- */
 #ifndef ENDPROC
 /* deprecated, use SYM_FUNC_END */
 #define ENDPROC(name) \
diff --git a/include/linux/objtool.h b/include/linux/objtool.h
index c722a921165b..248d9363ca85 100644
--- a/include/linux/objtool.h
+++ b/include/linux/objtool.h
@@ -69,7 +69,7 @@
  * In asm, there are two kinds of code: normal C-type callable functions and
  * the rest.  The normal callable functions can be called by other code, and
  * don't do anything unusual with the stack.  Such normal callable functions
- * are annotated with the ENTRY/ENDPROC macros.  Most asm code falls in this
+ * are annotated with SYM_FUNC_{START,END}.  Most asm code falls in this
  * category.  In this case, no special debugging annotations are needed because
  * objtool can automatically generate the ORC data for the ORC unwinder to read
  * at runtime.
diff --git a/tools/objtool/Documentation/objtool.txt b/tools/objtool/Documentation/objtool.txt
index 28ac57b9e102..9e97fc25b2d8 100644
--- a/tools/objtool/Documentation/objtool.txt
+++ b/tools/objtool/Documentation/objtool.txt
@@ -34,7 +34,7 @@ Objtool has the following features:
 - Return thunk annotation -- annotates all return thunk sites so kernel
   can patch them inline, depending on enabled mitigations
 
-- Return thunk training valiation -- validate that all entry paths
+- Return thunk untraining validation -- validate that all entry paths
   untrain a "safe return" before the first return (or call)
 
 - Non-instrumentation validation -- validates non-instrumentable
@@ -281,8 +281,8 @@ the objtool maintainers.
    If the error is for an asm file, and func() is indeed a callable
    function, add proper frame pointer logic using the FRAME_BEGIN and
    FRAME_END macros.  Otherwise, if it's not a callable function, remove
-   its ELF function annotation by changing ENDPROC to END, and instead
-   use the manual unwind hint macros in asm/unwind_hints.h.
+   its ELF function annotation by using SYM_CODE_{START,END} and use the
+   manual unwind hint macros in asm/unwind_hints.h.
 
    If it's a GCC-compiled .c file, the error may be because the function
    uses an inline asm() statement which has a "call" instruction.  An
@@ -352,7 +352,7 @@ the objtool maintainers.
    This is a kernel entry/exit instruction like sysenter or iret.  Such
    instructions aren't allowed in a callable function, and are most
    likely part of the kernel entry code.  Such code should probably be
-   placed in a SYM_FUNC_CODE block with unwind hints.
+   placed in a SYM_CODE_{START,END} block with unwind hints.
 
 
 6. file.o: warning: objtool: func()+0x26: sibling call from callable instruction with modified stack frame
@@ -381,7 +381,7 @@ the objtool maintainers.
 
    Another possibility is that the code has some asm or inline asm which
    does some unusual things to the stack or the frame pointer.  In such
-   cases it's probably appropriate to use SYM_FUNC_CODE with unwind
+   cases it's probably appropriate to use SYM_CODE_{START,END} with unwind
    hints.
 
 
-- 
2.48.1


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

* [PATCH 12/22] objtool: Remove --no-unreachable for noinstr-only vmlinux.o runs
  2025-03-24 21:55 [PATCH 00/22] objtool: CONFIG_OBJTOOL_WERROR fixes and cleanups Josh Poimboeuf
                   ` (10 preceding siblings ...)
  2025-03-24 21:56 ` [PATCH 11/22] objtool: Fix up some outdated references to ENTRY/ENDPROC Josh Poimboeuf
@ 2025-03-24 21:56 ` Josh Poimboeuf
  2025-03-25  8:35   ` [tip: objtool/urgent] " tip-bot2 for Josh Poimboeuf
  2025-03-24 21:56 ` [PATCH 13/22] objtool: Remove redundant opts.noinstr dependency Josh Poimboeuf
                   ` (9 subsequent siblings)
  21 siblings, 1 reply; 75+ messages in thread
From: Josh Poimboeuf @ 2025-03-24 21:56 UTC (permalink / raw)
  To: x86
  Cc: linux-kernel, Peter Zijlstra, Ingo Molnar, Miroslav Benes,
	Brendan Jackman, Nathan Chancellor

For (!X86_KERNEL_IBT && !LTO_CLANG && NOINSTR_VALIDATION), objtool runs
on both translation units and vmlinux.o.  The vmlinux.o run only does
noinstr/noret validation.  In that case --no-unreachable has no effect.
Remove it.

Note that for ((X86_KERNEL_IBT || LTO_CLANG) && KCOV), --no-unreachable
still gets set in objtool-args-y by scripts/Makefile.lib.

Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
 scripts/Makefile.vmlinux_o | 1 -
 1 file changed, 1 deletion(-)

diff --git a/scripts/Makefile.vmlinux_o b/scripts/Makefile.vmlinux_o
index f476f5605029..938c7457717e 100644
--- a/scripts/Makefile.vmlinux_o
+++ b/scripts/Makefile.vmlinux_o
@@ -44,7 +44,6 @@ else
 vmlinux-objtool-args-$(CONFIG_OBJTOOL_WERROR)		+= --Werror
 endif
 
-vmlinux-objtool-args-$(CONFIG_GCOV_KERNEL)		+= --no-unreachable
 vmlinux-objtool-args-$(CONFIG_NOINSTR_VALIDATION)	+= --noinstr \
 							   $(if $(or $(CONFIG_MITIGATION_UNRET_ENTRY),$(CONFIG_MITIGATION_SRSO)), --unret)
 
-- 
2.48.1


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

* [PATCH 13/22] objtool: Remove redundant opts.noinstr dependency
  2025-03-24 21:55 [PATCH 00/22] objtool: CONFIG_OBJTOOL_WERROR fixes and cleanups Josh Poimboeuf
                   ` (11 preceding siblings ...)
  2025-03-24 21:56 ` [PATCH 12/22] objtool: Remove --no-unreachable for noinstr-only vmlinux.o runs Josh Poimboeuf
@ 2025-03-24 21:56 ` Josh Poimboeuf
  2025-03-25  8:34   ` [tip: objtool/urgent] " tip-bot2 for Josh Poimboeuf
  2025-03-24 21:56 ` [PATCH 14/22] spi: amd: Fix out-of-bounds stack access in amd_set_spi_freq() Josh Poimboeuf
                   ` (8 subsequent siblings)
  21 siblings, 1 reply; 75+ messages in thread
From: Josh Poimboeuf @ 2025-03-24 21:56 UTC (permalink / raw)
  To: x86
  Cc: linux-kernel, Peter Zijlstra, Ingo Molnar, Miroslav Benes,
	Brendan Jackman, Nathan Chancellor

The --noinstr dependecy on --link is already enforced in the cmdline arg
parsing code.  Remove the redundant check.

Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
 tools/objtool/check.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 03ec485a376a..f4b9fcc395eb 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -340,12 +340,7 @@ static void init_insn_state(struct objtool_file *file, struct insn_state *state,
 	memset(state, 0, sizeof(*state));
 	init_cfi_state(&state->cfi);
 
-	/*
-	 * We need the full vmlinux for noinstr validation, otherwise we can
-	 * not correctly determine insn_call_dest(insn)->sec (external symbols
-	 * do not have a section).
-	 */
-	if (opts.link && opts.noinstr && sec)
+	if (opts.noinstr && sec)
 		state->noinstr = sec->noinstr;
 }
 
-- 
2.48.1


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

* [PATCH 14/22] spi: amd: Fix out-of-bounds stack access in amd_set_spi_freq()
  2025-03-24 21:55 [PATCH 00/22] objtool: CONFIG_OBJTOOL_WERROR fixes and cleanups Josh Poimboeuf
                   ` (12 preceding siblings ...)
  2025-03-24 21:56 ` [PATCH 13/22] objtool: Remove redundant opts.noinstr dependency Josh Poimboeuf
@ 2025-03-24 21:56 ` Josh Poimboeuf
  2025-03-25  8:34   ` [tip: objtool/urgent] objtool, " tip-bot2 for Josh Poimboeuf
  2025-03-25 22:10   ` tip-bot2 for Josh Poimboeuf
  2025-03-24 21:56 ` [PATCH 15/22] nvmet: Fix out-of-bounds stack access in nvmet_ctrl_state_show() Josh Poimboeuf
                   ` (7 subsequent siblings)
  21 siblings, 2 replies; 75+ messages in thread
From: Josh Poimboeuf @ 2025-03-24 21:56 UTC (permalink / raw)
  To: x86
  Cc: linux-kernel, Peter Zijlstra, Ingo Molnar, Miroslav Benes,
	Brendan Jackman, Nathan Chancellor, Raju Rangoju, Mark Brown,
	kernel test robot

If speed_hz < AMD_SPI_MIN_HZ, amd_set_spi_freq() iterates over the
entire amd_spi_freq array without breaking out early, causing 'i' to go
beyond the array bounds.

Fix that by stopping the loop when it gets to the last entry, so the low
speed_hz value gets clamped up to AMD_SPI_MIN_HZ.

Fixes the following warning with an UBSAN kernel:

  drivers/spi/spi-amd.o: error: objtool: amd_set_spi_freq() falls through to next function amd_spi_set_opcode()

Cc: Raju Rangoju <Raju.Rangoju@amd.com>
CC: Mark Brown <broonie@kernel.org>
Fixes: 3fe26121dc3a ("spi: amd: Configure device speed")
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/r/202503161828.RUk9EhWx-lkp@intel.com/
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
 drivers/spi/spi-amd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/spi/spi-amd.c b/drivers/spi/spi-amd.c
index c85997478b81..17fc0b17e756 100644
--- a/drivers/spi/spi-amd.c
+++ b/drivers/spi/spi-amd.c
@@ -302,7 +302,7 @@ static void amd_set_spi_freq(struct amd_spi *amd_spi, u32 speed_hz)
 {
 	unsigned int i, spd7_val, alt_spd;
 
-	for (i = 0; i < ARRAY_SIZE(amd_spi_freq); i++)
+	for (i = 0; i < ARRAY_SIZE(amd_spi_freq)-1; i++)
 		if (speed_hz >= amd_spi_freq[i].speed_hz)
 			break;
 
-- 
2.48.1


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

* [PATCH 15/22] nvmet: Fix out-of-bounds stack access in nvmet_ctrl_state_show()
  2025-03-24 21:55 [PATCH 00/22] objtool: CONFIG_OBJTOOL_WERROR fixes and cleanups Josh Poimboeuf
                   ` (13 preceding siblings ...)
  2025-03-24 21:56 ` [PATCH 14/22] spi: amd: Fix out-of-bounds stack access in amd_set_spi_freq() Josh Poimboeuf
@ 2025-03-24 21:56 ` Josh Poimboeuf
  2025-03-25  8:34   ` [tip: objtool/urgent] objtool, " tip-bot2 for Josh Poimboeuf
  2025-03-25 22:09   ` tip-bot2 for Josh Poimboeuf
  2025-03-24 21:56 ` [PATCH 16/22] media: dib8000: Prevent divide-by-zero in dib8000_set_dds() Josh Poimboeuf
                   ` (6 subsequent siblings)
  21 siblings, 2 replies; 75+ messages in thread
From: Josh Poimboeuf @ 2025-03-24 21:56 UTC (permalink / raw)
  To: x86
  Cc: linux-kernel, Peter Zijlstra, Ingo Molnar, Miroslav Benes,
	Brendan Jackman, Nathan Chancellor, Christoph Hellwig,
	Sagi Grimberg, Chaitanya Kulkarni, kernel test robot

The csts_state_names array only has six sparse entries, but the
iteration code in nvmet_ctrl_state_show() iterates seven, resulting in a
potential out-of-bounds stack read.  Fix that.

Fixes the following warning with an UBSAN kernel:

  vmlinux.o: warning: objtool: .text.nvmet_ctrl_state_show: unexpected end of section

Cc: Christoph Hellwig <hch@lst.de>
Cc: Sagi Grimberg <sagi@grimberg.me>
Cc: Chaitanya Kulkarni <kch@nvidia.com>
Fixes: 649fd41420a8 ("nvmet: add debugfs support")
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202503171547.LlCTJLQL-lkp@intel.com/
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
 drivers/nvme/target/debugfs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/nvme/target/debugfs.c b/drivers/nvme/target/debugfs.c
index 220c7391fc19..c6571fbd35e3 100644
--- a/drivers/nvme/target/debugfs.c
+++ b/drivers/nvme/target/debugfs.c
@@ -78,7 +78,7 @@ static int nvmet_ctrl_state_show(struct seq_file *m, void *p)
 	bool sep = false;
 	int i;
 
-	for (i = 0; i < 7; i++) {
+	for (i = 0; i < ARRAY_SIZE(csts_state_names); i++) {
 		int state = BIT(i);
 
 		if (!(ctrl->csts & state))
-- 
2.48.1


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

* [PATCH 16/22] media: dib8000: Prevent divide-by-zero in dib8000_set_dds()
  2025-03-24 21:55 [PATCH 00/22] objtool: CONFIG_OBJTOOL_WERROR fixes and cleanups Josh Poimboeuf
                   ` (14 preceding siblings ...)
  2025-03-24 21:56 ` [PATCH 15/22] nvmet: Fix out-of-bounds stack access in nvmet_ctrl_state_show() Josh Poimboeuf
@ 2025-03-24 21:56 ` Josh Poimboeuf
  2025-03-25  8:34   ` [tip: objtool/urgent] objtool, " tip-bot2 for Josh Poimboeuf
  2025-03-25 22:09   ` tip-bot2 for Josh Poimboeuf
  2025-03-24 21:56 ` [PATCH 17/22] panic: Disable SMAP in __stack_chk_fail() Josh Poimboeuf
                   ` (5 subsequent siblings)
  21 siblings, 2 replies; 75+ messages in thread
From: Josh Poimboeuf @ 2025-03-24 21:56 UTC (permalink / raw)
  To: x86
  Cc: linux-kernel, Peter Zijlstra, Ingo Molnar, Miroslav Benes,
	Brendan Jackman, Nathan Chancellor, Mauro Carvalho Chehab,
	kernel test robot

If dib8000_set_dds()'s call to dib8000_read32() returns zero, the result
is a divide-by-zero.  Prevent that from happening.

Fixes the following warning with an UBSAN kernel:

  drivers/media/dvb-frontends/dib8000.o: warning: objtool: dib8000_tune() falls through to next function dib8096p_cfg_DibRx()

Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Fixes: 173a64cb3fcf ("[media] dib8000: enhancement")
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/r/202503210602.fvH5DO1i-lkp@intel.com/
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
 drivers/media/dvb-frontends/dib8000.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/media/dvb-frontends/dib8000.c b/drivers/media/dvb-frontends/dib8000.c
index 2f5165918163..cfe59c3255f7 100644
--- a/drivers/media/dvb-frontends/dib8000.c
+++ b/drivers/media/dvb-frontends/dib8000.c
@@ -2701,8 +2701,11 @@ static void dib8000_set_dds(struct dib8000_state *state, s32 offset_khz)
 	u8 ratio;
 
 	if (state->revision == 0x8090) {
+		u32 internal = dib8000_read32(state, 23) / 1000;
+
 		ratio = 4;
-		unit_khz_dds_val = (1<<26) / (dib8000_read32(state, 23) / 1000);
+
+		unit_khz_dds_val = (1<<26) / (internal ?: 1);
 		if (offset_khz < 0)
 			dds = (1 << 26) - (abs_offset_khz * unit_khz_dds_val);
 		else
-- 
2.48.1


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

* [PATCH 17/22] panic: Disable SMAP in __stack_chk_fail()
  2025-03-24 21:55 [PATCH 00/22] objtool: CONFIG_OBJTOOL_WERROR fixes and cleanups Josh Poimboeuf
                   ` (15 preceding siblings ...)
  2025-03-24 21:56 ` [PATCH 16/22] media: dib8000: Prevent divide-by-zero in dib8000_set_dds() Josh Poimboeuf
@ 2025-03-24 21:56 ` Josh Poimboeuf
  2025-03-25  8:34   ` [tip: objtool/urgent] objtool, " tip-bot2 for Josh Poimboeuf
  2025-03-25 22:09   ` tip-bot2 for Josh Poimboeuf
  2025-03-24 21:56 ` [PATCH 18/22] Input: cyapa - remove undefined behavior in cyapa_update_fw_store() Josh Poimboeuf
                   ` (4 subsequent siblings)
  21 siblings, 2 replies; 75+ messages in thread
From: Josh Poimboeuf @ 2025-03-24 21:56 UTC (permalink / raw)
  To: x86
  Cc: linux-kernel, Peter Zijlstra, Ingo Molnar, Miroslav Benes,
	Brendan Jackman, Nathan Chancellor

__stack_chk_fail() can be called from uaccess-enabled code.  Make sure
uaccess gets disabled before calling panic().

Fixes the following warning:

  kernel/trace/trace_branch.o: error: objtool: ftrace_likely_update+0x1ea: call to __stack_chk_fail() with UACCESS enabled

Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
 kernel/panic.c        | 6 ++++++
 tools/objtool/check.c | 5 ++++-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/kernel/panic.c b/kernel/panic.c
index d8635d5cecb2..f9f0c5148f6a 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -832,9 +832,15 @@ device_initcall(register_warn_debugfs);
  */
 __visible noinstr void __stack_chk_fail(void)
 {
+	unsigned long flags;
+
 	instrumentation_begin();
+	flags = user_access_save();
+
 	panic("stack-protector: Kernel stack is corrupted in: %pB",
 		__builtin_return_address(0));
+
+	user_access_restore(flags);
 	instrumentation_end();
 }
 EXPORT_SYMBOL(__stack_chk_fail);
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index f4b9fcc395eb..a953ce5fe395 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -1194,12 +1194,15 @@ static const char *uaccess_safe_builtin[] = {
 	"__ubsan_handle_load_invalid_value",
 	/* STACKLEAK */
 	"stackleak_track_stack",
+	/* TRACE_BRANCH_PROFILING */
+	"ftrace_likely_update",
+	/* STACKPROTECTOR */
+	"__stack_chk_fail",
 	/* misc */
 	"csum_partial_copy_generic",
 	"copy_mc_fragile",
 	"copy_mc_fragile_handle_tail",
 	"copy_mc_enhanced_fast_string",
-	"ftrace_likely_update", /* CONFIG_TRACE_BRANCH_PROFILING */
 	"rep_stos_alternative",
 	"rep_movs_alternative",
 	"__copy_user_nocache",
-- 
2.48.1


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

* [PATCH 18/22] Input: cyapa - remove undefined behavior in cyapa_update_fw_store()
  2025-03-24 21:55 [PATCH 00/22] objtool: CONFIG_OBJTOOL_WERROR fixes and cleanups Josh Poimboeuf
                   ` (16 preceding siblings ...)
  2025-03-24 21:56 ` [PATCH 17/22] panic: Disable SMAP in __stack_chk_fail() Josh Poimboeuf
@ 2025-03-24 21:56 ` Josh Poimboeuf
  2025-03-25  8:34   ` [tip: objtool/urgent] objtool, Input: cyapa - Remove " tip-bot2 for Josh Poimboeuf
  2025-03-25 22:09   ` tip-bot2 for Josh Poimboeuf
  2025-03-24 21:56 ` [PATCH 19/22] ASoC: codecs: wcd934x: Remove undefined behavior in wcd934x_slim_irq_handler() Josh Poimboeuf
                   ` (3 subsequent siblings)
  21 siblings, 2 replies; 75+ messages in thread
From: Josh Poimboeuf @ 2025-03-24 21:56 UTC (permalink / raw)
  To: x86
  Cc: linux-kernel, Peter Zijlstra, Ingo Molnar, Miroslav Benes,
	Brendan Jackman, Nathan Chancellor, Dmitry Torokhov,
	kernel test robot

In cyapa_update_fw_store(), if count is zero, the write to
fw_name[count-1] underflows the array.

Presumably that's not possible in normal operation, as its caller
sysfs_kf_write() already checks for zero.  Regardless it's a good idea
to check for the error explicitly and avoid undefined behavior.

Fixes the following warning with an UBSAN kernel:

  vmlinux.o: warning: objtool: .text.cyapa_update_fw_store: unexpected end of section

Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202503171547.LlCTJLQL-lkp@intel.com/
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
 drivers/input/mouse/cyapa.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/input/mouse/cyapa.c b/drivers/input/mouse/cyapa.c
index 2f2d925a55d7..00c87c0532a6 100644
--- a/drivers/input/mouse/cyapa.c
+++ b/drivers/input/mouse/cyapa.c
@@ -1080,8 +1080,8 @@ static ssize_t cyapa_update_fw_store(struct device *dev,
 	char fw_name[NAME_MAX];
 	int ret, error;
 
-	if (count >= NAME_MAX) {
-		dev_err(dev, "File name too long\n");
+	if (!count || count >= NAME_MAX) {
+		dev_err(dev, "Bad file name size\n");
 		return -EINVAL;
 	}
 
-- 
2.48.1


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

* [PATCH 19/22] ASoC: codecs: wcd934x: Remove undefined behavior in wcd934x_slim_irq_handler()
  2025-03-24 21:55 [PATCH 00/22] objtool: CONFIG_OBJTOOL_WERROR fixes and cleanups Josh Poimboeuf
                   ` (17 preceding siblings ...)
  2025-03-24 21:56 ` [PATCH 18/22] Input: cyapa - remove undefined behavior in cyapa_update_fw_store() Josh Poimboeuf
@ 2025-03-24 21:56 ` Josh Poimboeuf
  2025-03-25  8:34   ` [tip: objtool/urgent] objtool, ASoC: codecs: wcd934x: Remove potential " tip-bot2 for Josh Poimboeuf
  2025-03-25 22:09   ` tip-bot2 for Josh Poimboeuf
  2025-03-24 21:56 ` [PATCH 20/22] regulator: rk808: Remove undefined behavior in rk806_set_mode_dcdc() Josh Poimboeuf
                   ` (2 subsequent siblings)
  21 siblings, 2 replies; 75+ messages in thread
From: Josh Poimboeuf @ 2025-03-24 21:56 UTC (permalink / raw)
  To: x86
  Cc: linux-kernel, Peter Zijlstra, Ingo Molnar, Miroslav Benes,
	Brendan Jackman, Nathan Chancellor, Srinivas Kandagatla,
	kernel test robot

If port_id is negative, the shift counts in wcd934x_slim_irq_handler()
also become negative, resulting in undefined behavior due to shift out
of bounds.

If I'm reading the code correctly, that appears to be not possible, but
with KCOV enabled, Clang's range analysis isn't always able to determine
that and generates undefined behavior.

As a result the code generation isn't optimal, and undefined behavior
should be avoided regardless.  Improve code generation and remove the
undefined behavior by converting the signed variables to unsigned.

Fixes the following warning with UBSAN:

  sound/soc/codecs/snd-soc-wcd934x.o: warning: objtool: .text.wcd934x_slim_irq_handler: unexpected end of section

Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202503180044.oH9gyPeg-lkp@intel.com/
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
 sound/soc/codecs/wcd934x.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/soc/codecs/wcd934x.c b/sound/soc/codecs/wcd934x.c
index 910852eb9698..c7f1b28f3b23 100644
--- a/sound/soc/codecs/wcd934x.c
+++ b/sound/soc/codecs/wcd934x.c
@@ -2273,7 +2273,7 @@ static irqreturn_t wcd934x_slim_irq_handler(int irq, void *data)
 {
 	struct wcd934x_codec *wcd = data;
 	unsigned long status = 0;
-	int i, j, port_id;
+	unsigned int i, j, port_id;
 	unsigned int val, int_val = 0;
 	irqreturn_t ret = IRQ_NONE;
 	bool tx;
-- 
2.48.1


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

* [PATCH 20/22] regulator: rk808: Remove undefined behavior in rk806_set_mode_dcdc()
  2025-03-24 21:55 [PATCH 00/22] objtool: CONFIG_OBJTOOL_WERROR fixes and cleanups Josh Poimboeuf
                   ` (18 preceding siblings ...)
  2025-03-24 21:56 ` [PATCH 19/22] ASoC: codecs: wcd934x: Remove undefined behavior in wcd934x_slim_irq_handler() Josh Poimboeuf
@ 2025-03-24 21:56 ` Josh Poimboeuf
  2025-03-25  8:34   ` [tip: objtool/urgent] objtool, regulator: rk808: Remove potential " tip-bot2 for Josh Poimboeuf
  2025-03-25 22:09   ` tip-bot2 for Josh Poimboeuf
  2025-03-24 21:56 ` [PATCH 21/22] pwm: mediatek: Prevent divide-by-zero in pwm_mediatek_config() Josh Poimboeuf
  2025-03-24 21:56 ` [PATCH 22/22] lkdtm: Obfuscate do_nothing() pointer Josh Poimboeuf
  21 siblings, 2 replies; 75+ messages in thread
From: Josh Poimboeuf @ 2025-03-24 21:56 UTC (permalink / raw)
  To: x86
  Cc: linux-kernel, Peter Zijlstra, Ingo Molnar, Miroslav Benes,
	Brendan Jackman, Nathan Chancellor, Liam Girdwood, Mark Brown,
	kernel test robot

If ctr_bit is negative, the shift counts become negative, causing a
shift of bounds and undefined behavior.

Presumably that's not possible in normal operation, but the code
generation isn't optimal.  And undefined behavior should be avoided
regardless.

Improve code generation and remove the undefined behavior by converting
the signed variables to unsigned.

Fixes the following warning with an UBSAN kernel:

  vmlinux.o: warning: objtool: rk806_set_mode_dcdc() falls through to next function rk806_get_mode_dcdc()
  vmlinux.o: warning: objtool: .text.rk806_set_mode_dcdc: unexpected end of section

Cc: Liam Girdwood <lgirdwood@gmail.com>
Cc: Mark Brown <broonie@kernel.org>
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202503182350.52KeHGD4-lkp@intel.com/
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
 drivers/regulator/rk808-regulator.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c
index 7d82bd1b36df..1e8142479656 100644
--- a/drivers/regulator/rk808-regulator.c
+++ b/drivers/regulator/rk808-regulator.c
@@ -270,8 +270,8 @@ static const unsigned int rk817_buck1_4_ramp_table[] = {
 
 static int rk806_set_mode_dcdc(struct regulator_dev *rdev, unsigned int mode)
 {
-	int rid = rdev_get_id(rdev);
-	int ctr_bit, reg;
+	unsigned int rid = rdev_get_id(rdev);
+	unsigned int ctr_bit, reg;
 
 	reg = RK806_POWER_FPWM_EN0 + rid / 8;
 	ctr_bit = rid % 8;
-- 
2.48.1


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

* [PATCH 21/22] pwm: mediatek: Prevent divide-by-zero in pwm_mediatek_config()
  2025-03-24 21:55 [PATCH 00/22] objtool: CONFIG_OBJTOOL_WERROR fixes and cleanups Josh Poimboeuf
                   ` (19 preceding siblings ...)
  2025-03-24 21:56 ` [PATCH 20/22] regulator: rk808: Remove undefined behavior in rk806_set_mode_dcdc() Josh Poimboeuf
@ 2025-03-24 21:56 ` Josh Poimboeuf
  2025-03-25  8:34   ` [tip: objtool/urgent] objtool, pwm: mediatek: Prevent theoretical " tip-bot2 for Josh Poimboeuf
                     ` (2 more replies)
  2025-03-24 21:56 ` [PATCH 22/22] lkdtm: Obfuscate do_nothing() pointer Josh Poimboeuf
  21 siblings, 3 replies; 75+ messages in thread
From: Josh Poimboeuf @ 2025-03-24 21:56 UTC (permalink / raw)
  To: x86
  Cc: linux-kernel, Peter Zijlstra, Ingo Molnar, Miroslav Benes,
	Brendan Jackman, Nathan Chancellor, Uwe Kleine-König

With CONFIG_COMPILE_TEST && !CONFIG_CLK, pwm_mediatek_config() has a
divide-by-zero in the following line:

	do_div(resolution, clk_get_rate(pc->clk_pwms[pwm->hwpwm]));

due to the fact that the !CONFIG_CLK version of clk_get_rate() returns
zero.

This is presumably just a theoretical problem: COMPILE_TEST overrides
the dependency on RALINK which would select COMMON_CLK.  Regardless it's
a good idea to check for the error explicitly to avoid divide-by-zero.

Fixes the following warning:

  drivers/pwm/pwm-mediatek.o: warning: objtool: .text: unexpected end of section

Cc: Uwe Kleine-König <ukleinek@kernel.org>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
 drivers/pwm/pwm-mediatek.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
index 01dfa0fab80a..7eaab5831499 100644
--- a/drivers/pwm/pwm-mediatek.c
+++ b/drivers/pwm/pwm-mediatek.c
@@ -121,21 +121,25 @@ static int pwm_mediatek_config(struct pwm_chip *chip, struct pwm_device *pwm,
 	struct pwm_mediatek_chip *pc = to_pwm_mediatek_chip(chip);
 	u32 clkdiv = 0, cnt_period, cnt_duty, reg_width = PWMDWIDTH,
 	    reg_thres = PWMTHRES;
+	unsigned long clk_rate;
 	u64 resolution;
 	int ret;
 
 	ret = pwm_mediatek_clk_enable(chip, pwm);
-
 	if (ret < 0)
 		return ret;
 
+	clk_rate = clk_get_rate(pc->clk_pwms[pwm->hwpwm]);
+	if (!clk_rate)
+		return -EINVAL;
+
 	/* Make sure we use the bus clock and not the 26MHz clock */
 	if (pc->soc->has_ck_26m_sel)
 		writel(0, pc->regs + PWM_CK_26M_SEL);
 
 	/* Using resolution in picosecond gets accuracy higher */
 	resolution = (u64)NSEC_PER_SEC * 1000;
-	do_div(resolution, clk_get_rate(pc->clk_pwms[pwm->hwpwm]));
+	do_div(resolution, clk_rate);
 
 	cnt_period = DIV_ROUND_CLOSEST_ULL((u64)period_ns * 1000, resolution);
 	while (cnt_period > 8191) {
-- 
2.48.1


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

* [PATCH 22/22] lkdtm: Obfuscate do_nothing() pointer
  2025-03-24 21:55 [PATCH 00/22] objtool: CONFIG_OBJTOOL_WERROR fixes and cleanups Josh Poimboeuf
                   ` (20 preceding siblings ...)
  2025-03-24 21:56 ` [PATCH 21/22] pwm: mediatek: Prevent divide-by-zero in pwm_mediatek_config() Josh Poimboeuf
@ 2025-03-24 21:56 ` Josh Poimboeuf
  2025-03-25  8:34   ` [tip: objtool/urgent] objtool, lkdtm: Obfuscate the " tip-bot2 for Josh Poimboeuf
                     ` (4 more replies)
  21 siblings, 5 replies; 75+ messages in thread
From: Josh Poimboeuf @ 2025-03-24 21:56 UTC (permalink / raw)
  To: x86
  Cc: linux-kernel, Peter Zijlstra, Ingo Molnar, Miroslav Benes,
	Brendan Jackman, Nathan Chancellor, Kees Cook, kernel test robot

If execute_location()'s memcpy of do_nothing() gets inlined and unrolled
by the compiler, it copies one word at a time:

    mov    0x0(%rip),%rax    R_X86_64_PC32    .text+0x1374
    mov    %rax,0x38(%rbx)
    mov    0x0(%rip),%rax    R_X86_64_PC32    .text+0x136c
    mov    %rax,0x30(%rbx)
    ...

Those .text references point to the middle of the function, causing
objtool to complain about their lack of ENDBR.

Prevent that by resolving the function pointer at runtime rather than
build time.  This fixes the following warning:

  drivers/misc/lkdtm/lkdtm.o: warning: objtool: execute_location+0x23: relocation to !ENDBR: .text+0x1378

Cc: Kees Cook <kees@kernel.org>
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202503191453.uFfxQy5R-lkp@intel.com/
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
 drivers/misc/lkdtm/perms.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
index 5b861dbff27e..6c24426104ba 100644
--- a/drivers/misc/lkdtm/perms.c
+++ b/drivers/misc/lkdtm/perms.c
@@ -28,6 +28,13 @@ static const unsigned long rodata = 0xAA55AA55;
 /* This is marked __ro_after_init, so it should ultimately be .rodata. */
 static unsigned long ro_after_init __ro_after_init = 0x55AA5500;
 
+/*
+ * This is a pointer to do_nothing() which is initialized at runtime rather
+ * than build time to avoid objtool IBT validation warnings caused by an
+ * inlined unrolled memcpy() in execute_location().
+ */
+static void __ro_after_init *do_nothing_ptr;
+
 /*
  * This just returns to the caller. It is designed to be copied into
  * non-executable memory regions.
@@ -65,13 +72,12 @@ static noinline __nocfi void execute_location(void *dst, bool write)
 {
 	void (*func)(void);
 	func_desc_t fdesc;
-	void *do_nothing_text = dereference_function_descriptor(do_nothing);
 
-	pr_info("attempting ok execution at %px\n", do_nothing_text);
+	pr_info("attempting ok execution at %px\n", do_nothing_ptr);
 	do_nothing();
 
 	if (write == CODE_WRITE) {
-		memcpy(dst, do_nothing_text, EXEC_SIZE);
+		memcpy(dst, do_nothing_ptr, EXEC_SIZE);
 		flush_icache_range((unsigned long)dst,
 				   (unsigned long)dst + EXEC_SIZE);
 	}
@@ -267,6 +273,8 @@ static void lkdtm_ACCESS_NULL(void)
 
 void __init lkdtm_perms_init(void)
 {
+	do_nothing_ptr = dereference_function_descriptor(do_nothing);
+
 	/* Make sure we can write to __ro_after_init values during __init */
 	ro_after_init |= 0xAA;
 }
-- 
2.48.1


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

* [tip: objtool/urgent] objtool, lkdtm: Obfuscate the do_nothing() pointer
  2025-03-24 21:56 ` [PATCH 22/22] lkdtm: Obfuscate do_nothing() pointer Josh Poimboeuf
@ 2025-03-25  8:34   ` tip-bot2 for Josh Poimboeuf
  2025-03-25 19:39   ` [PATCH 22/22] lkdtm: Obfuscate " Kees Cook
                     ` (3 subsequent siblings)
  4 siblings, 0 replies; 75+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2025-03-25  8:34 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: kernel test robot, Josh Poimboeuf, Ingo Molnar, Kees Cook,
	Arnd Bergmann, Greg Kroah-Hartman, Linus Torvalds, x86,
	linux-kernel

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

Commit-ID:     33fea486a42d952a40eb110a9b7885a7ac8d2778
Gitweb:        https://git.kernel.org/tip/33fea486a42d952a40eb110a9b7885a7ac8d2778
Author:        Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate:    Mon, 24 Mar 2025 14:56:12 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Tue, 25 Mar 2025 09:20:33 +01:00

objtool, lkdtm: Obfuscate the do_nothing() pointer

If execute_location()'s memcpy of do_nothing() gets inlined and unrolled
by the compiler, it copies one word at a time:

    mov    0x0(%rip),%rax    R_X86_64_PC32    .text+0x1374
    mov    %rax,0x38(%rbx)
    mov    0x0(%rip),%rax    R_X86_64_PC32    .text+0x136c
    mov    %rax,0x30(%rbx)
    ...

Those .text references point to the middle of the function, causing
objtool to complain about their lack of ENDBR.

Prevent that by resolving the function pointer at runtime rather than
build time.  This fixes the following warning:

  drivers/misc/lkdtm/lkdtm.o: warning: objtool: execute_location+0x23: relocation to !ENDBR: .text+0x1378

Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Kees Cook <kees@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/30b9abffbddeb43c4f6320b1270fa9b4d74c54ed.1742852847.git.jpoimboe@kernel.org
Closes: https://lore.kernel.org/oe-kbuild-all/202503191453.uFfxQy5R-lkp@intel.com/
---
 drivers/misc/lkdtm/perms.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
index 5b861db..6c24426 100644
--- a/drivers/misc/lkdtm/perms.c
+++ b/drivers/misc/lkdtm/perms.c
@@ -29,6 +29,13 @@ static const unsigned long rodata = 0xAA55AA55;
 static unsigned long ro_after_init __ro_after_init = 0x55AA5500;
 
 /*
+ * This is a pointer to do_nothing() which is initialized at runtime rather
+ * than build time to avoid objtool IBT validation warnings caused by an
+ * inlined unrolled memcpy() in execute_location().
+ */
+static void __ro_after_init *do_nothing_ptr;
+
+/*
  * This just returns to the caller. It is designed to be copied into
  * non-executable memory regions.
  */
@@ -65,13 +72,12 @@ static noinline __nocfi void execute_location(void *dst, bool write)
 {
 	void (*func)(void);
 	func_desc_t fdesc;
-	void *do_nothing_text = dereference_function_descriptor(do_nothing);
 
-	pr_info("attempting ok execution at %px\n", do_nothing_text);
+	pr_info("attempting ok execution at %px\n", do_nothing_ptr);
 	do_nothing();
 
 	if (write == CODE_WRITE) {
-		memcpy(dst, do_nothing_text, EXEC_SIZE);
+		memcpy(dst, do_nothing_ptr, EXEC_SIZE);
 		flush_icache_range((unsigned long)dst,
 				   (unsigned long)dst + EXEC_SIZE);
 	}
@@ -267,6 +273,8 @@ static void lkdtm_ACCESS_NULL(void)
 
 void __init lkdtm_perms_init(void)
 {
+	do_nothing_ptr = dereference_function_descriptor(do_nothing);
+
 	/* Make sure we can write to __ro_after_init values during __init */
 	ro_after_init |= 0xAA;
 }

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

* [tip: objtool/urgent] objtool, pwm: mediatek: Prevent theoretical divide-by-zero in pwm_mediatek_config()
  2025-03-24 21:56 ` [PATCH 21/22] pwm: mediatek: Prevent divide-by-zero in pwm_mediatek_config() Josh Poimboeuf
@ 2025-03-25  8:34   ` tip-bot2 for Josh Poimboeuf
  2025-03-26 10:35     ` Uwe Kleine-König
       [not found]     ` <m7pgkp3ueo7iqgqf74upjrihr3mpmb3sqhwegnjxxwsrgx2jsw@dnec5iqiyobh>
  2025-03-25 22:09   ` tip-bot2 for Josh Poimboeuf
  2025-03-27 11:06   ` tip-bot2 for Josh Poimboeuf
  2 siblings, 2 replies; 75+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2025-03-25  8:34 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Josh Poimboeuf, Ingo Molnar, ukleinek, Linus Torvalds, x86,
	linux-kernel

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

Commit-ID:     2becbc66a151500636046503f541255af6acf4fa
Gitweb:        https://git.kernel.org/tip/2becbc66a151500636046503f541255af6acf4fa
Author:        Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate:    Mon, 24 Mar 2025 14:56:11 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Tue, 25 Mar 2025 09:20:32 +01:00

objtool, pwm: mediatek: Prevent theoretical divide-by-zero in pwm_mediatek_config()

With CONFIG_COMPILE_TEST && !CONFIG_CLK, pwm_mediatek_config() has a
divide-by-zero in the following line:

	do_div(resolution, clk_get_rate(pc->clk_pwms[pwm->hwpwm]));

due to the fact that the !CONFIG_CLK version of clk_get_rate() returns
zero.

This is presumably just a theoretical problem: COMPILE_TEST overrides
the dependency on RALINK which would select COMMON_CLK.  Regardless it's
a good idea to check for the error explicitly to avoid divide-by-zero.

Fixes the following warning:

  drivers/pwm/pwm-mediatek.o: warning: objtool: .text: unexpected end of section

Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: "Uwe Kleine-König" <ukleinek@kernel.org> (maintainer:PWM SUBSYSTEM)
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/fb56444939325cc173e752ba199abd7aeae3bf12.1742852847.git.jpoimboe@kernel.org
---
 drivers/pwm/pwm-mediatek.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
index 01dfa0f..7eaab58 100644
--- a/drivers/pwm/pwm-mediatek.c
+++ b/drivers/pwm/pwm-mediatek.c
@@ -121,21 +121,25 @@ static int pwm_mediatek_config(struct pwm_chip *chip, struct pwm_device *pwm,
 	struct pwm_mediatek_chip *pc = to_pwm_mediatek_chip(chip);
 	u32 clkdiv = 0, cnt_period, cnt_duty, reg_width = PWMDWIDTH,
 	    reg_thres = PWMTHRES;
+	unsigned long clk_rate;
 	u64 resolution;
 	int ret;
 
 	ret = pwm_mediatek_clk_enable(chip, pwm);
-
 	if (ret < 0)
 		return ret;
 
+	clk_rate = clk_get_rate(pc->clk_pwms[pwm->hwpwm]);
+	if (!clk_rate)
+		return -EINVAL;
+
 	/* Make sure we use the bus clock and not the 26MHz clock */
 	if (pc->soc->has_ck_26m_sel)
 		writel(0, pc->regs + PWM_CK_26M_SEL);
 
 	/* Using resolution in picosecond gets accuracy higher */
 	resolution = (u64)NSEC_PER_SEC * 1000;
-	do_div(resolution, clk_get_rate(pc->clk_pwms[pwm->hwpwm]));
+	do_div(resolution, clk_rate);
 
 	cnt_period = DIV_ROUND_CLOSEST_ULL((u64)period_ns * 1000, resolution);
 	while (cnt_period > 8191) {

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

* [tip: objtool/urgent] objtool, regulator: rk808: Remove potential undefined behavior in rk806_set_mode_dcdc()
  2025-03-24 21:56 ` [PATCH 20/22] regulator: rk808: Remove undefined behavior in rk806_set_mode_dcdc() Josh Poimboeuf
@ 2025-03-25  8:34   ` tip-bot2 for Josh Poimboeuf
  2025-03-25 13:17     ` Mark Brown
  2025-03-25 22:09   ` tip-bot2 for Josh Poimboeuf
  1 sibling, 1 reply; 75+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2025-03-25  8:34 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: kernel test robot, Josh Poimboeuf, Ingo Molnar, Liam Girdwood,
	Mark Brown, Linus Torvalds, x86, linux-kernel

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

Commit-ID:     4d014a6b8e4dba75eb0b99e6ed990bb7e38da294
Gitweb:        https://git.kernel.org/tip/4d014a6b8e4dba75eb0b99e6ed990bb7e38da294
Author:        Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate:    Mon, 24 Mar 2025 14:56:10 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Tue, 25 Mar 2025 09:20:29 +01:00

objtool, regulator: rk808: Remove potential undefined behavior in rk806_set_mode_dcdc()

If 'ctr_bit' is negative, the shift counts become negative, causing a
shift of bounds and undefined behavior.

Presumably that's not possible in normal operation, but the code
generation isn't optimal.  And undefined behavior should be avoided
regardless.

Improve code generation and remove the undefined behavior by converting
the signed variables to unsigned.

Fixes the following warning with an UBSAN kernel:

  vmlinux.o: warning: objtool: rk806_set_mode_dcdc() falls through to next function rk806_get_mode_dcdc()
  vmlinux.o: warning: objtool: .text.rk806_set_mode_dcdc: unexpected end of section

Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Liam Girdwood <lgirdwood@gmail.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/2023abcddf3f524ba478d64339996f25dc4097d2.1742852847.git.jpoimboe@kernel.org
Closes: https://lore.kernel.org/oe-kbuild-all/202503182350.52KeHGD4-lkp@intel.com/
---
 drivers/regulator/rk808-regulator.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c
index 7d82bd1..1e81424 100644
--- a/drivers/regulator/rk808-regulator.c
+++ b/drivers/regulator/rk808-regulator.c
@@ -270,8 +270,8 @@ static const unsigned int rk817_buck1_4_ramp_table[] = {
 
 static int rk806_set_mode_dcdc(struct regulator_dev *rdev, unsigned int mode)
 {
-	int rid = rdev_get_id(rdev);
-	int ctr_bit, reg;
+	unsigned int rid = rdev_get_id(rdev);
+	unsigned int ctr_bit, reg;
 
 	reg = RK806_POWER_FPWM_EN0 + rid / 8;
 	ctr_bit = rid % 8;

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

* [tip: objtool/urgent] objtool, ASoC: codecs: wcd934x: Remove potential undefined behavior in wcd934x_slim_irq_handler()
  2025-03-24 21:56 ` [PATCH 19/22] ASoC: codecs: wcd934x: Remove undefined behavior in wcd934x_slim_irq_handler() Josh Poimboeuf
@ 2025-03-25  8:34   ` tip-bot2 for Josh Poimboeuf
  2025-03-25 11:32     ` Mark Brown
  2025-03-25 22:09   ` tip-bot2 for Josh Poimboeuf
  1 sibling, 1 reply; 75+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2025-03-25  8:34 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: kernel test robot, Josh Poimboeuf, Ingo Molnar,
	Srinivas Kandagatla, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai, Linus Torvalds, x86, linux-kernel

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

Commit-ID:     46b70c569b774ea2c671bb3aff2a50d29760b7c3
Gitweb:        https://git.kernel.org/tip/46b70c569b774ea2c671bb3aff2a50d29760b7c3
Author:        Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate:    Mon, 24 Mar 2025 14:56:09 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Tue, 25 Mar 2025 09:20:29 +01:00

objtool, ASoC: codecs: wcd934x: Remove potential undefined behavior in wcd934x_slim_irq_handler()

If 'port_id' is negative, the shift counts in wcd934x_slim_irq_handler()
also become negative, resulting in undefined behavior due to shift out
of bounds.

If I'm reading the code correctly, that appears to be not possible, but
with KCOV enabled, Clang's range analysis isn't always able to determine
that and generates undefined behavior.

As a result the code generation isn't optimal, and undefined behavior
should be avoided regardless.  Improve code generation and remove the
undefined behavior by converting the signed variables to unsigned.

Fixes the following warning with UBSAN:

  sound/soc/codecs/snd-soc-wcd934x.o: warning: objtool: .text.wcd934x_slim_irq_handler: unexpected end of section

Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Cc: Liam Girdwood <lgirdwood@gmail.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Jaroslav Kysela <perex@perex.cz>
Cc: Takashi Iwai <tiwai@suse.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/7e863839ec7301bf9c0f429a03873d44e484c31c.1742852847.git.jpoimboe@kernel.org
Closes: https://lore.kernel.org/oe-kbuild-all/202503180044.oH9gyPeg-lkp@intel.com/
---
 sound/soc/codecs/wcd934x.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/soc/codecs/wcd934x.c b/sound/soc/codecs/wcd934x.c
index 910852e..c7f1b28 100644
--- a/sound/soc/codecs/wcd934x.c
+++ b/sound/soc/codecs/wcd934x.c
@@ -2273,7 +2273,7 @@ static irqreturn_t wcd934x_slim_irq_handler(int irq, void *data)
 {
 	struct wcd934x_codec *wcd = data;
 	unsigned long status = 0;
-	int i, j, port_id;
+	unsigned int i, j, port_id;
 	unsigned int val, int_val = 0;
 	irqreturn_t ret = IRQ_NONE;
 	bool tx;

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

* [tip: objtool/urgent] objtool, Input: cyapa - Remove undefined behavior in cyapa_update_fw_store()
  2025-03-24 21:56 ` [PATCH 18/22] Input: cyapa - remove undefined behavior in cyapa_update_fw_store() Josh Poimboeuf
@ 2025-03-25  8:34   ` tip-bot2 for Josh Poimboeuf
  2025-03-25 22:09   ` tip-bot2 for Josh Poimboeuf
  1 sibling, 0 replies; 75+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2025-03-25  8:34 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: kernel test robot, Josh Poimboeuf, Ingo Molnar, Dmitry Torokhov,
	Linus Torvalds, x86, linux-kernel

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

Commit-ID:     e3c9ccbbf5c5e1238d4ac8577559e61576b9210f
Gitweb:        https://git.kernel.org/tip/e3c9ccbbf5c5e1238d4ac8577559e61576b9210f
Author:        Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate:    Mon, 24 Mar 2025 14:56:08 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Tue, 25 Mar 2025 09:20:29 +01:00

objtool, Input: cyapa - Remove undefined behavior in cyapa_update_fw_store()

In cyapa_update_fw_store(), if 'count' is zero, the write to
fw_name[count-1] underflows the array.

Presumably that's not possible in normal operation, as its caller
sysfs_kf_write() already checks for zero.  Regardless it's a good idea
to check for the error explicitly and avoid undefined behavior.

Fixes the following warning with an UBSAN kernel:

  vmlinux.o: warning: objtool: .text.cyapa_update_fw_store: unexpected end of section

Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/73ae0bb3c656735890d914b74c9d6bb40c25d3cd.1742852847.git.jpoimboe@kernel.org
Closes: https://lore.kernel.org/oe-kbuild-all/202503171547.LlCTJLQL-lkp@intel.com/
---
 drivers/input/mouse/cyapa.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/input/mouse/cyapa.c b/drivers/input/mouse/cyapa.c
index 2f2d925..00c87c0 100644
--- a/drivers/input/mouse/cyapa.c
+++ b/drivers/input/mouse/cyapa.c
@@ -1080,8 +1080,8 @@ static ssize_t cyapa_update_fw_store(struct device *dev,
 	char fw_name[NAME_MAX];
 	int ret, error;
 
-	if (count >= NAME_MAX) {
-		dev_err(dev, "File name too long\n");
+	if (!count || count >= NAME_MAX) {
+		dev_err(dev, "Bad file name size\n");
 		return -EINVAL;
 	}
 

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

* [tip: objtool/urgent] objtool, panic: Disable SMAP in __stack_chk_fail()
  2025-03-24 21:56 ` [PATCH 17/22] panic: Disable SMAP in __stack_chk_fail() Josh Poimboeuf
@ 2025-03-25  8:34   ` tip-bot2 for Josh Poimboeuf
  2025-03-25 22:09   ` tip-bot2 for Josh Poimboeuf
  1 sibling, 0 replies; 75+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2025-03-25  8:34 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Josh Poimboeuf, Ingo Molnar, Kees Cook, Andrew Morton,
	Linus Torvalds, x86, linux-kernel

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

Commit-ID:     c2299757eb5bbc121177a23559eff8f66e944381
Gitweb:        https://git.kernel.org/tip/c2299757eb5bbc121177a23559eff8f66e944381
Author:        Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate:    Mon, 24 Mar 2025 14:56:07 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Tue, 25 Mar 2025 09:20:28 +01:00

objtool, panic: Disable SMAP in __stack_chk_fail()

__stack_chk_fail() can be called from uaccess-enabled code.  Make sure
uaccess gets disabled before calling panic().

Fixes the following warning:

  kernel/trace/trace_branch.o: error: objtool: ftrace_likely_update+0x1ea: call to __stack_chk_fail() with UACCESS enabled

Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Kees Cook <keescook@chromium.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/a3e97e0119e1b04c725a8aa05f7bc83d98e657eb.1742852847.git.jpoimboe@kernel.org
---
 kernel/panic.c        | 6 ++++++
 tools/objtool/check.c | 5 ++++-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/kernel/panic.c b/kernel/panic.c
index d8635d5..f9f0c51 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -832,9 +832,15 @@ device_initcall(register_warn_debugfs);
  */
 __visible noinstr void __stack_chk_fail(void)
 {
+	unsigned long flags;
+
 	instrumentation_begin();
+	flags = user_access_save();
+
 	panic("stack-protector: Kernel stack is corrupted in: %pB",
 		__builtin_return_address(0));
+
+	user_access_restore(flags);
 	instrumentation_end();
 }
 EXPORT_SYMBOL(__stack_chk_fail);
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 0caabf0..3bf2992 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -1194,12 +1194,15 @@ static const char *uaccess_safe_builtin[] = {
 	"__ubsan_handle_load_invalid_value",
 	/* STACKLEAK */
 	"stackleak_track_stack",
+	/* TRACE_BRANCH_PROFILING */
+	"ftrace_likely_update",
+	/* STACKPROTECTOR */
+	"__stack_chk_fail",
 	/* misc */
 	"csum_partial_copy_generic",
 	"copy_mc_fragile",
 	"copy_mc_fragile_handle_tail",
 	"copy_mc_enhanced_fast_string",
-	"ftrace_likely_update", /* CONFIG_TRACE_BRANCH_PROFILING */
 	"rep_stos_alternative",
 	"rep_movs_alternative",
 	"__copy_user_nocache",

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

* [tip: objtool/urgent] objtool, media: dib8000: Prevent divide-by-zero in dib8000_set_dds()
  2025-03-24 21:56 ` [PATCH 16/22] media: dib8000: Prevent divide-by-zero in dib8000_set_dds() Josh Poimboeuf
@ 2025-03-25  8:34   ` tip-bot2 for Josh Poimboeuf
  2025-03-25 22:09   ` tip-bot2 for Josh Poimboeuf
  1 sibling, 0 replies; 75+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2025-03-25  8:34 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: kernel test robot, Josh Poimboeuf, Ingo Molnar,
	Mauro Carvalho Chehab, Linus Torvalds, x86, linux-kernel

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

Commit-ID:     c13d957b38b43cfee77f210c2f6c64c2957afed0
Gitweb:        https://git.kernel.org/tip/c13d957b38b43cfee77f210c2f6c64c2957afed0
Author:        Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate:    Mon, 24 Mar 2025 14:56:06 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Tue, 25 Mar 2025 09:20:28 +01:00

objtool, media: dib8000: Prevent divide-by-zero in dib8000_set_dds()

If dib8000_set_dds()'s call to dib8000_read32() returns zero, the result
is a divide-by-zero.  Prevent that from happening.

Fixes the following warning with an UBSAN kernel:

  drivers/media/dvb-frontends/dib8000.o: warning: objtool: dib8000_tune() falls through to next function dib8096p_cfg_DibRx()

Fixes: 173a64cb3fcf ("[media] dib8000: enhancement")
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/bd1d504d930ae3f073b1e071bcf62cae7708773c.1742852847.git.jpoimboe@kernel.org
Closes: https://lore.kernel.org/r/202503210602.fvH5DO1i-lkp@intel.com/
---
 drivers/media/dvb-frontends/dib8000.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/media/dvb-frontends/dib8000.c b/drivers/media/dvb-frontends/dib8000.c
index 2f51659..cfe59c3 100644
--- a/drivers/media/dvb-frontends/dib8000.c
+++ b/drivers/media/dvb-frontends/dib8000.c
@@ -2701,8 +2701,11 @@ static void dib8000_set_dds(struct dib8000_state *state, s32 offset_khz)
 	u8 ratio;
 
 	if (state->revision == 0x8090) {
+		u32 internal = dib8000_read32(state, 23) / 1000;
+
 		ratio = 4;
-		unit_khz_dds_val = (1<<26) / (dib8000_read32(state, 23) / 1000);
+
+		unit_khz_dds_val = (1<<26) / (internal ?: 1);
 		if (offset_khz < 0)
 			dds = (1 << 26) - (abs_offset_khz * unit_khz_dds_val);
 		else

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

* [tip: objtool/urgent] objtool, nvmet: Fix out-of-bounds stack access in nvmet_ctrl_state_show()
  2025-03-24 21:56 ` [PATCH 15/22] nvmet: Fix out-of-bounds stack access in nvmet_ctrl_state_show() Josh Poimboeuf
@ 2025-03-25  8:34   ` tip-bot2 for Josh Poimboeuf
  2025-03-25 22:09   ` tip-bot2 for Josh Poimboeuf
  1 sibling, 0 replies; 75+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2025-03-25  8:34 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: kernel test robot, Josh Poimboeuf, Ingo Molnar, Christoph Hellwig,
	Sagi Grimberg, Chaitanya Kulkarni, Linus Torvalds, x86,
	linux-kernel

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

Commit-ID:     ea0d2a4c77d98e983b42f61790a0760a68983156
Gitweb:        https://git.kernel.org/tip/ea0d2a4c77d98e983b42f61790a0760a68983156
Author:        Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate:    Mon, 24 Mar 2025 14:56:05 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Tue, 25 Mar 2025 09:20:28 +01:00

objtool, nvmet: Fix out-of-bounds stack access in nvmet_ctrl_state_show()

The csts_state_names[] array only has six sparse entries, but the
iteration code in nvmet_ctrl_state_show() iterates seven, resulting in a
potential out-of-bounds stack read.  Fix that.

Fixes the following warning with an UBSAN kernel:

  vmlinux.o: warning: objtool: .text.nvmet_ctrl_state_show: unexpected end of section

Fixes: 649fd41420a8 ("nvmet: add debugfs support")
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Sagi Grimberg <sagi@grimberg.me>
Cc: Chaitanya Kulkarni <kch@nvidia.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/f1f60858ee7a941863dc7f5506c540cb9f97b5f6.1742852847.git.jpoimboe@kernel.org
Closes: https://lore.kernel.org/oe-kbuild-all/202503171547.LlCTJLQL-lkp@intel.com/
---
 drivers/nvme/target/debugfs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/nvme/target/debugfs.c b/drivers/nvme/target/debugfs.c
index 220c739..c6571fb 100644
--- a/drivers/nvme/target/debugfs.c
+++ b/drivers/nvme/target/debugfs.c
@@ -78,7 +78,7 @@ static int nvmet_ctrl_state_show(struct seq_file *m, void *p)
 	bool sep = false;
 	int i;
 
-	for (i = 0; i < 7; i++) {
+	for (i = 0; i < ARRAY_SIZE(csts_state_names); i++) {
 		int state = BIT(i);
 
 		if (!(ctrl->csts & state))

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

* [tip: objtool/urgent] objtool, spi: amd: Fix out-of-bounds stack access in amd_set_spi_freq()
  2025-03-24 21:56 ` [PATCH 14/22] spi: amd: Fix out-of-bounds stack access in amd_set_spi_freq() Josh Poimboeuf
@ 2025-03-25  8:34   ` tip-bot2 for Josh Poimboeuf
  2025-03-25 13:13     ` Mark Brown
  2025-03-25 22:10   ` tip-bot2 for Josh Poimboeuf
  1 sibling, 1 reply; 75+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2025-03-25  8:34 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: kernel test robot, Josh Poimboeuf, Ingo Molnar, Raju Rangoju,
	Mark Brown, Linus Torvalds, x86, linux-kernel

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

Commit-ID:     0239716b82b75dc5cb64c5ec5405dac6c3448d48
Gitweb:        https://git.kernel.org/tip/0239716b82b75dc5cb64c5ec5405dac6c3448d48
Author:        Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate:    Mon, 24 Mar 2025 14:56:04 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Tue, 25 Mar 2025 09:20:28 +01:00

objtool, spi: amd: Fix out-of-bounds stack access in amd_set_spi_freq()

If speed_hz < AMD_SPI_MIN_HZ, amd_set_spi_freq() iterates over the
entire amd_spi_freq array without breaking out early, causing 'i' to go
beyond the array bounds.

Fix that by stopping the loop when it gets to the last entry, so the low
speed_hz value gets clamped up to AMD_SPI_MIN_HZ.

Fixes the following warning with an UBSAN kernel:

  drivers/spi/spi-amd.o: error: objtool: amd_set_spi_freq() falls through to next function amd_spi_set_opcode()

Fixes: 3fe26121dc3a ("spi: amd: Configure device speed")
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Raju Rangoju <Raju.Rangoju@amd.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/78fef0f2434f35be9095bcc9ffa23dd8cab667b9.1742852847.git.jpoimboe@kernel.org
Closes: https://lore.kernel.org/r/202503161828.RUk9EhWx-lkp@intel.com/
---
 drivers/spi/spi-amd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/spi/spi-amd.c b/drivers/spi/spi-amd.c
index c859974..17fc0b1 100644
--- a/drivers/spi/spi-amd.c
+++ b/drivers/spi/spi-amd.c
@@ -302,7 +302,7 @@ static void amd_set_spi_freq(struct amd_spi *amd_spi, u32 speed_hz)
 {
 	unsigned int i, spd7_val, alt_spd;
 
-	for (i = 0; i < ARRAY_SIZE(amd_spi_freq); i++)
+	for (i = 0; i < ARRAY_SIZE(amd_spi_freq)-1; i++)
 		if (speed_hz >= amd_spi_freq[i].speed_hz)
 			break;
 

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

* [tip: objtool/urgent] objtool: Remove redundant opts.noinstr dependency
  2025-03-24 21:56 ` [PATCH 13/22] objtool: Remove redundant opts.noinstr dependency Josh Poimboeuf
@ 2025-03-25  8:34   ` tip-bot2 for Josh Poimboeuf
  0 siblings, 0 replies; 75+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2025-03-25  8:34 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Josh Poimboeuf, Ingo Molnar, Linus Torvalds, x86, linux-kernel

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

Commit-ID:     a8d39a62c6f5ad76b8a1ebfbf10dd9fe8ca2bbcc
Gitweb:        https://git.kernel.org/tip/a8d39a62c6f5ad76b8a1ebfbf10dd9fe8ca2bbcc
Author:        Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate:    Mon, 24 Mar 2025 14:56:03 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Tue, 25 Mar 2025 09:20:28 +01:00

objtool: Remove redundant opts.noinstr dependency

The --noinstr dependecy on --link is already enforced in the cmdline arg
parsing code.  Remove the redundant check.

Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/0ead7ffa0f5be2e81aebbcc585e07b2c98702b44.1742852847.git.jpoimboe@kernel.org
---
 tools/objtool/check.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index ac21f28..0caabf0 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -340,12 +340,7 @@ static void init_insn_state(struct objtool_file *file, struct insn_state *state,
 	memset(state, 0, sizeof(*state));
 	init_cfi_state(&state->cfi);
 
-	/*
-	 * We need the full vmlinux for noinstr validation, otherwise we can
-	 * not correctly determine insn_call_dest(insn)->sec (external symbols
-	 * do not have a section).
-	 */
-	if (opts.link && opts.noinstr && sec)
+	if (opts.noinstr && sec)
 		state->noinstr = sec->noinstr;
 }
 

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

* [tip: objtool/urgent] objtool: Remove --no-unreachable for noinstr-only vmlinux.o runs
  2025-03-24 21:56 ` [PATCH 12/22] objtool: Remove --no-unreachable for noinstr-only vmlinux.o runs Josh Poimboeuf
@ 2025-03-25  8:35   ` tip-bot2 for Josh Poimboeuf
  0 siblings, 0 replies; 75+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2025-03-25  8:35 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Josh Poimboeuf, Ingo Molnar, Linus Torvalds, x86, linux-kernel

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

Commit-ID:     876a4bce3849b235d752d13ec3180e15a35e52de
Gitweb:        https://git.kernel.org/tip/876a4bce3849b235d752d13ec3180e15a35e52de
Author:        Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate:    Mon, 24 Mar 2025 14:56:02 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Tue, 25 Mar 2025 09:20:27 +01:00

objtool: Remove --no-unreachable for noinstr-only vmlinux.o runs

For (!X86_KERNEL_IBT && !LTO_CLANG && NOINSTR_VALIDATION), objtool runs
on both translation units and vmlinux.o.  The vmlinux.o run only does
noinstr/noret validation.  In that case --no-unreachable has no effect.
Remove it.

Note that for ((X86_KERNEL_IBT || LTO_CLANG) && KCOV), --no-unreachable
still gets set in objtool-args-y by scripts/Makefile.lib.

Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/05414246a0124db2f21b0d071b652aa9043d039d.1742852847.git.jpoimboe@kernel.org
---
 scripts/Makefile.vmlinux_o | 1 -
 1 file changed, 1 deletion(-)

diff --git a/scripts/Makefile.vmlinux_o b/scripts/Makefile.vmlinux_o
index f476f56..938c745 100644
--- a/scripts/Makefile.vmlinux_o
+++ b/scripts/Makefile.vmlinux_o
@@ -44,7 +44,6 @@ else
 vmlinux-objtool-args-$(CONFIG_OBJTOOL_WERROR)		+= --Werror
 endif
 
-vmlinux-objtool-args-$(CONFIG_GCOV_KERNEL)		+= --no-unreachable
 vmlinux-objtool-args-$(CONFIG_NOINSTR_VALIDATION)	+= --noinstr \
 							   $(if $(or $(CONFIG_MITIGATION_UNRET_ENTRY),$(CONFIG_MITIGATION_SRSO)), --unret)
 

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

* [tip: objtool/urgent] objtool: Fix up some outdated references to ENTRY/ENDPROC
  2025-03-24 21:56 ` [PATCH 11/22] objtool: Fix up some outdated references to ENTRY/ENDPROC Josh Poimboeuf
@ 2025-03-25  8:35   ` tip-bot2 for Josh Poimboeuf
  0 siblings, 0 replies; 75+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2025-03-25  8:35 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Brendan Jackman, Miroslav Benes, Josh Poimboeuf, Ingo Molnar,
	Linus Torvalds, x86, linux-kernel

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

Commit-ID:     24fe172b50b5749c315349e740e4a09e3a0165d5
Gitweb:        https://git.kernel.org/tip/24fe172b50b5749c315349e740e4a09e3a0165d5
Author:        Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate:    Mon, 24 Mar 2025 14:56:01 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Tue, 25 Mar 2025 09:20:27 +01:00

objtool: Fix up some outdated references to ENTRY/ENDPROC

ENTRY and ENDPROC were deprecated years ago and replaced with
SYM_FUNC_{START,END}.  Fix up a few outdated references in the objtool
documentation and comments.  Also fix a few typos.

Suggested-by: Brendan Jackman <jackmanb@google.com>
Suggested-by: Miroslav Benes <mbenes@suse.cz>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/5eb7e06e1a0e87aaeda8d583ab060e7638a6ea8e.1742852846.git.jpoimboe@kernel.org
---
 include/linux/linkage.h                 |  4 ----
 include/linux/objtool.h                 |  2 +-
 tools/objtool/Documentation/objtool.txt | 10 +++++-----
 3 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/include/linux/linkage.h b/include/linux/linkage.h
index 5c8865b..b11660b 100644
--- a/include/linux/linkage.h
+++ b/include/linux/linkage.h
@@ -134,10 +134,6 @@
 	.size name, .-name
 #endif
 
-/* If symbol 'name' is treated as a subroutine (gets called, and returns)
- * then please use ENDPROC to mark 'name' as STT_FUNC for the benefit of
- * static analysis tools such as stack depth analyzer.
- */
 #ifndef ENDPROC
 /* deprecated, use SYM_FUNC_END */
 #define ENDPROC(name) \
diff --git a/include/linux/objtool.h b/include/linux/objtool.h
index 3ca965a..366ad00 100644
--- a/include/linux/objtool.h
+++ b/include/linux/objtool.h
@@ -69,7 +69,7 @@
  * In asm, there are two kinds of code: normal C-type callable functions and
  * the rest.  The normal callable functions can be called by other code, and
  * don't do anything unusual with the stack.  Such normal callable functions
- * are annotated with the ENTRY/ENDPROC macros.  Most asm code falls in this
+ * are annotated with SYM_FUNC_{START,END}.  Most asm code falls in this
  * category.  In this case, no special debugging annotations are needed because
  * objtool can automatically generate the ORC data for the ORC unwinder to read
  * at runtime.
diff --git a/tools/objtool/Documentation/objtool.txt b/tools/objtool/Documentation/objtool.txt
index 28ac57b..9e97fc2 100644
--- a/tools/objtool/Documentation/objtool.txt
+++ b/tools/objtool/Documentation/objtool.txt
@@ -34,7 +34,7 @@ Objtool has the following features:
 - Return thunk annotation -- annotates all return thunk sites so kernel
   can patch them inline, depending on enabled mitigations
 
-- Return thunk training valiation -- validate that all entry paths
+- Return thunk untraining validation -- validate that all entry paths
   untrain a "safe return" before the first return (or call)
 
 - Non-instrumentation validation -- validates non-instrumentable
@@ -281,8 +281,8 @@ the objtool maintainers.
    If the error is for an asm file, and func() is indeed a callable
    function, add proper frame pointer logic using the FRAME_BEGIN and
    FRAME_END macros.  Otherwise, if it's not a callable function, remove
-   its ELF function annotation by changing ENDPROC to END, and instead
-   use the manual unwind hint macros in asm/unwind_hints.h.
+   its ELF function annotation by using SYM_CODE_{START,END} and use the
+   manual unwind hint macros in asm/unwind_hints.h.
 
    If it's a GCC-compiled .c file, the error may be because the function
    uses an inline asm() statement which has a "call" instruction.  An
@@ -352,7 +352,7 @@ the objtool maintainers.
    This is a kernel entry/exit instruction like sysenter or iret.  Such
    instructions aren't allowed in a callable function, and are most
    likely part of the kernel entry code.  Such code should probably be
-   placed in a SYM_FUNC_CODE block with unwind hints.
+   placed in a SYM_CODE_{START,END} block with unwind hints.
 
 
 6. file.o: warning: objtool: func()+0x26: sibling call from callable instruction with modified stack frame
@@ -381,7 +381,7 @@ the objtool maintainers.
 
    Another possibility is that the code has some asm or inline asm which
    does some unusual things to the stack or the frame pointer.  In such
-   cases it's probably appropriate to use SYM_FUNC_CODE with unwind
+   cases it's probably appropriate to use SYM_CODE_{START,END} with unwind
    hints.
 
 

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

* [tip: objtool/urgent] objtool: Reduce CONFIG_OBJTOOL_WERROR verbosity
  2025-03-24 21:56 ` [PATCH 10/22] objtool: Reduce CONFIG_OBJTOOL_WERROR verbosity Josh Poimboeuf
@ 2025-03-25  8:35   ` tip-bot2 for Josh Poimboeuf
  0 siblings, 0 replies; 75+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2025-03-25  8:35 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Josh Poimboeuf, Ingo Molnar, Linus Torvalds, x86, linux-kernel

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

Commit-ID:     d39f82a058c0269392a797cb04f2a6064e5dcab6
Gitweb:        https://git.kernel.org/tip/d39f82a058c0269392a797cb04f2a6064e5dcab6
Author:        Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate:    Mon, 24 Mar 2025 14:56:00 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Tue, 25 Mar 2025 09:20:27 +01:00

objtool: Reduce CONFIG_OBJTOOL_WERROR verbosity

Remove the following from CONFIG_OBJTOOL_WERROR:

  * backtrace

  * "upgraded warnings to errors" message

  * cmdline args

This makes the default output less cluttered and makes it easier to spot
the actual warnings.  Note the above options are still are available
with --verbose or OBJTOOL_VERBOSE=1.

Also, do the cmdline arg printing on all warnings, regardless of werror.

Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/d61df69f64b396fa6b2a1335588aad7a34ea9e71.1742852846.git.jpoimboe@kernel.org
---
 scripts/Makefile.lib                    |   2 +-
 tools/objtool/builtin-check.c           | 113 +++++++++++------------
 tools/objtool/check.c                   |  23 ++---
 tools/objtool/include/objtool/builtin.h |   6 +-
 4 files changed, 73 insertions(+), 71 deletions(-)

diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 57620b4..b935974 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -277,7 +277,7 @@ objtool-args-$(CONFIG_HAVE_STATIC_CALL_INLINE)		+= --static-call
 objtool-args-$(CONFIG_HAVE_UACCESS_VALIDATION)		+= --uaccess
 objtool-args-$(CONFIG_GCOV_KERNEL)			+= --no-unreachable
 objtool-args-$(CONFIG_PREFIX_SYMBOLS)			+= --prefix=$(CONFIG_FUNCTION_PADDING_BYTES)
-objtool-args-$(CONFIG_OBJTOOL_WERROR)			+= --Werror --backtrace
+objtool-args-$(CONFIG_OBJTOOL_WERROR)			+= --Werror
 
 objtool-args = $(objtool-args-y)					\
 	$(if $(delay-objtool), --link)					\
diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c
index c973a75..2bdff91 100644
--- a/tools/objtool/builtin-check.c
+++ b/tools/objtool/builtin-check.c
@@ -15,8 +15,11 @@
 #include <objtool/objtool.h>
 #include <objtool/warn.h>
 
-const char *objname;
+#define ORIG_SUFFIX ".orig"
 
+int orig_argc;
+static char **orig_argv;
+const char *objname;
 struct opts opts;
 
 static const char * const check_usage[] = {
@@ -224,39 +227,73 @@ static int copy_file(const char *src, const char *dst)
 	return 0;
 }
 
-static char **save_argv(int argc, const char **argv)
+static void save_argv(int argc, const char **argv)
 {
-	char **orig_argv;
-
 	orig_argv = calloc(argc, sizeof(char *));
 	if (!orig_argv) {
 		WARN_GLIBC("calloc");
-		return NULL;
+		exit(1);
 	}
 
 	for (int i = 0; i < argc; i++) {
 		orig_argv[i] = strdup(argv[i]);
 		if (!orig_argv[i]) {
 			WARN_GLIBC("strdup(%s)", orig_argv[i]);
-			return NULL;
+			exit(1);
 		}
 	};
-
-	return orig_argv;
 }
 
-#define ORIG_SUFFIX ".orig"
+void print_args(void)
+{
+	char *backup = NULL;
+
+	if (opts.output || opts.dryrun)
+		goto print;
+
+	/*
+	 * Make a backup before kbuild deletes the file so the error
+	 * can be recreated without recompiling or relinking.
+	 */
+	backup = malloc(strlen(objname) + strlen(ORIG_SUFFIX) + 1);
+	if (!backup) {
+		WARN_GLIBC("malloc");
+		goto print;
+	}
+
+	strcpy(backup, objname);
+	strcat(backup, ORIG_SUFFIX);
+	if (copy_file(objname, backup)) {
+		backup = NULL;
+		goto print;
+	}
+
+print:
+	/*
+	 * Print the cmdline args to make it easier to recreate.  If '--output'
+	 * wasn't used, add it to the printed args with the backup as input.
+	 */
+	fprintf(stderr, "%s", orig_argv[0]);
+
+	for (int i = 1; i < orig_argc; i++) {
+		char *arg = orig_argv[i];
+
+		if (backup && !strcmp(arg, objname))
+			fprintf(stderr, " %s -o %s", backup, objname);
+		else
+			fprintf(stderr, " %s", arg);
+	}
+
+	fprintf(stderr, "\n");
+}
 
 int objtool_run(int argc, const char **argv)
 {
 	struct objtool_file *file;
-	char *backup = NULL;
-	char **orig_argv;
 	int ret = 0;
 
-	orig_argv = save_argv(argc, argv);
-	if (!orig_argv)
-		return 1;
+	orig_argc = argc;
+	save_argv(argc, argv);
 
 	cmd_parse_options(argc, argv, check_usage);
 
@@ -279,59 +316,19 @@ int objtool_run(int argc, const char **argv)
 
 	file = objtool_open_read(objname);
 	if (!file)
-		goto err;
+		return 1;
 
 	if (!opts.link && has_multiple_files(file->elf)) {
 		WARN("Linked object requires --link");
-		goto err;
+		return 1;
 	}
 
 	ret = check(file);
 	if (ret)
-		goto err;
+		return ret;
 
 	if (!opts.dryrun && file->elf->changed && elf_write(file->elf))
-		goto err;
-
-	return 0;
-
-err:
-	if (opts.dryrun)
-		goto err_msg;
-
-	if (opts.output) {
-		unlink(opts.output);
-		goto err_msg;
-	}
-
-	/*
-	 * Make a backup before kbuild deletes the file so the error
-	 * can be recreated without recompiling or relinking.
-	 */
-	backup = malloc(strlen(objname) + strlen(ORIG_SUFFIX) + 1);
-	if (!backup) {
-		WARN_GLIBC("malloc");
 		return 1;
-	}
-
-	strcpy(backup, objname);
-	strcat(backup, ORIG_SUFFIX);
-	if (copy_file(objname, backup))
-		return 1;
-
-err_msg:
-	fprintf(stderr, "%s", orig_argv[0]);
-
-	for (int i = 1; i < argc; i++) {
-		char *arg = orig_argv[i];
 
-		if (backup && !strcmp(arg, objname))
-			fprintf(stderr, " %s -o %s", backup, objname);
-		else
-			fprintf(stderr, " %s", arg);
-	}
-
-	fprintf(stderr, "\n");
-
-	return 1;
+	return 0;
 }
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index f4e7ee8..ac21f28 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -4732,9 +4732,6 @@ int check(struct objtool_file *file)
 
 	free_insns(file);
 
-	if (opts.verbose)
-		disas_warned_funcs(file);
-
 	if (opts.stats) {
 		printf("nr_insns_visited: %ld\n", nr_insns_visited);
 		printf("nr_cfi: %ld\n", nr_cfi);
@@ -4743,19 +4740,25 @@ int check(struct objtool_file *file)
 	}
 
 out:
+	if (!ret && !warnings)
+		return 0;
+
+	if (opts.verbose) {
+		if (opts.werror && warnings)
+			WARN("%d warning(s) upgraded to errors", warnings);
+		print_args();
+		disas_warned_funcs(file);
+	}
+
 	/*
 	 * CONFIG_OBJTOOL_WERROR upgrades all warnings (and errors) to actual
 	 * errors.
 	 *
-	 * Note that even "fatal" type errors don't actually return an error
-	 * without CONFIG_OBJTOOL_WERROR.  That probably needs improved at some
-	 * point.
+	 * Note that even fatal errors don't yet actually return an error
+	 * without CONFIG_OBJTOOL_WERROR.  That will be fixed soon-ish.
 	 */
-	if (opts.werror && (ret || warnings)) {
-		if (warnings)
-			WARN("%d warning(s) upgraded to errors", warnings);
+	if (opts.werror)
 		return 1;
-	}
 
 	return 0;
 }
diff --git a/tools/objtool/include/objtool/builtin.h b/tools/objtool/include/objtool/builtin.h
index 0fafd0f..6b08666 100644
--- a/tools/objtool/include/objtool/builtin.h
+++ b/tools/objtool/include/objtool/builtin.h
@@ -43,8 +43,10 @@ struct opts {
 
 extern struct opts opts;
 
-extern int cmd_parse_options(int argc, const char **argv, const char * const usage[]);
+int cmd_parse_options(int argc, const char **argv, const char * const usage[]);
 
-extern int objtool_run(int argc, const char **argv);
+int objtool_run(int argc, const char **argv);
+
+void print_args(void);
 
 #endif /* _BUILTIN_H */

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

* [tip: objtool/urgent] objtool: Properly disable uaccess validation
  2025-03-24 21:55 ` [PATCH 08/22] objtool: Properly disable uaccess validation Josh Poimboeuf
@ 2025-03-25  8:35   ` tip-bot2 for Josh Poimboeuf
  0 siblings, 0 replies; 75+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2025-03-25  8:35 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Josh Poimboeuf, Ingo Molnar, Linus Torvalds, x86, linux-kernel

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

Commit-ID:     e1a9dda74dbffbc3fa2069ff418a1876dc99fb14
Gitweb:        https://git.kernel.org/tip/e1a9dda74dbffbc3fa2069ff418a1876dc99fb14
Author:        Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate:    Mon, 24 Mar 2025 14:55:58 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Tue, 25 Mar 2025 09:20:26 +01:00

objtool: Properly disable uaccess validation

If opts.uaccess isn't set, the uaccess validation is disabled, but only
partially: it doesn't read the uaccess_safe_builtin list but still tries
to do the validation.  Disable it completely to prevent false warnings.

Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/0e95581c1d2107fb5f59418edf2b26bba38b0cbb.1742852846.git.jpoimboe@kernel.org
---
 tools/objtool/check.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index cb66e6b..b0ef14a 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -3187,7 +3187,7 @@ static int handle_insn_ops(struct instruction *insn,
 		if (update_cfi_state(insn, next_insn, &state->cfi, op))
 			return 1;
 
-		if (!insn->alt_group)
+		if (!opts.uaccess || !insn->alt_group)
 			continue;
 
 		if (op->dest.type == OP_DEST_PUSHF) {
@@ -3647,6 +3647,9 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
 			return 0;
 
 		case INSN_STAC:
+			if (!opts.uaccess)
+				break;
+
 			if (state.uaccess) {
 				WARN_INSN(insn, "recursive UACCESS enable");
 				return 1;
@@ -3656,6 +3659,9 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
 			break;
 
 		case INSN_CLAC:
+			if (!opts.uaccess)
+				break;
+
 			if (!state.uaccess && func) {
 				WARN_INSN(insn, "redundant UACCESS disable");
 				return 1;
@@ -4114,7 +4120,8 @@ static int validate_symbol(struct objtool_file *file, struct section *sec,
 	if (!insn || insn->visited)
 		return 0;
 
-	state->uaccess = sym->uaccess_safe;
+	if (opts.uaccess)
+		state->uaccess = sym->uaccess_safe;
 
 	ret = validate_branch(file, insn_func(insn), insn, *state);
 	if (ret)

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

* [tip: objtool/urgent] objtool: Improve error handling
  2025-03-24 21:55 ` [PATCH 09/22] objtool: Improve error handling Josh Poimboeuf
@ 2025-03-25  8:35   ` tip-bot2 for Josh Poimboeuf
  0 siblings, 0 replies; 75+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2025-03-25  8:35 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Josh Poimboeuf, Ingo Molnar, Linus Torvalds, x86, linux-kernel

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

Commit-ID:     c5995abe15476798b2e2f0163a33404c41aafc8f
Gitweb:        https://git.kernel.org/tip/c5995abe15476798b2e2f0163a33404c41aafc8f
Author:        Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate:    Mon, 24 Mar 2025 14:55:59 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Tue, 25 Mar 2025 09:20:27 +01:00

objtool: Improve error handling

Fix some error handling issues, improve error messages, properly
distinguish betwee errors and warnings, and generally try to make all
the error handling more consistent.

Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/3094bb4463dad29b6bd1bea03848d1571ace771c.1742852846.git.jpoimboe@kernel.org
---
 tools/objtool/builtin-check.c           |  37 +--
 tools/objtool/check.c                   | 368 +++++++++++------------
 tools/objtool/elf.c                     |  22 +-
 tools/objtool/include/objtool/objtool.h |   2 +-
 tools/objtool/include/objtool/warn.h    |  13 +-
 tools/objtool/objtool.c                 |  11 +-
 6 files changed, 232 insertions(+), 221 deletions(-)

diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c
index 5f761f4..c973a75 100644
--- a/tools/objtool/builtin-check.c
+++ b/tools/objtool/builtin-check.c
@@ -8,15 +8,12 @@
 #include <stdlib.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <errno.h>
 #include <sys/stat.h>
 #include <sys/sendfile.h>
 #include <objtool/builtin.h>
 #include <objtool/objtool.h>
-
-#define ERROR(format, ...)				\
-	fprintf(stderr,					\
-		"error: objtool: " format "\n",		\
-		##__VA_ARGS__)
+#include <objtool/warn.h>
 
 const char *objname;
 
@@ -139,22 +136,22 @@ int cmd_parse_options(int argc, const char **argv, const char * const usage[])
 static bool opts_valid(void)
 {
 	if (opts.mnop && !opts.mcount) {
-		ERROR("--mnop requires --mcount");
+		WARN("--mnop requires --mcount");
 		return false;
 	}
 
 	if (opts.noinstr && !opts.link) {
-		ERROR("--noinstr requires --link");
+		WARN("--noinstr requires --link");
 		return false;
 	}
 
 	if (opts.ibt && !opts.link) {
-		ERROR("--ibt requires --link");
+		WARN("--ibt requires --link");
 		return false;
 	}
 
 	if (opts.unret && !opts.link) {
-		ERROR("--unret requires --link");
+		WARN("--unret requires --link");
 		return false;
 	}
 
@@ -171,7 +168,7 @@ static bool opts_valid(void)
 	    opts.static_call		||
 	    opts.uaccess) {
 		if (opts.dump_orc) {
-			ERROR("--dump can't be combined with other actions");
+			WARN("--dump can't be combined with other actions");
 			return false;
 		}
 
@@ -181,7 +178,7 @@ static bool opts_valid(void)
 	if (opts.dump_orc)
 		return true;
 
-	ERROR("At least one action required");
+	WARN("At least one action required");
 	return false;
 }
 
@@ -194,30 +191,30 @@ static int copy_file(const char *src, const char *dst)
 
 	src_fd = open(src, O_RDONLY);
 	if (src_fd == -1) {
-		ERROR("can't open '%s' for reading", src);
+		WARN("can't open %s for reading: %s", src, strerror(errno));
 		return 1;
 	}
 
 	dst_fd = open(dst, O_WRONLY | O_CREAT | O_TRUNC, 0400);
 	if (dst_fd == -1) {
-		ERROR("can't open '%s' for writing", dst);
+		WARN("can't open %s for writing: %s", dst, strerror(errno));
 		return 1;
 	}
 
 	if (fstat(src_fd, &stat) == -1) {
-		perror("fstat");
+		WARN_GLIBC("fstat");
 		return 1;
 	}
 
 	if (fchmod(dst_fd, stat.st_mode) == -1) {
-		perror("fchmod");
+		WARN_GLIBC("fchmod");
 		return 1;
 	}
 
 	for (to_copy = stat.st_size; to_copy > 0; to_copy -= copied) {
 		copied = sendfile(dst_fd, src_fd, &offset, to_copy);
 		if (copied == -1) {
-			perror("sendfile");
+			WARN_GLIBC("sendfile");
 			return 1;
 		}
 	}
@@ -233,14 +230,14 @@ static char **save_argv(int argc, const char **argv)
 
 	orig_argv = calloc(argc, sizeof(char *));
 	if (!orig_argv) {
-		perror("calloc");
+		WARN_GLIBC("calloc");
 		return NULL;
 	}
 
 	for (int i = 0; i < argc; i++) {
 		orig_argv[i] = strdup(argv[i]);
 		if (!orig_argv[i]) {
-			perror("strdup");
+			WARN_GLIBC("strdup(%s)", orig_argv[i]);
 			return NULL;
 		}
 	};
@@ -285,7 +282,7 @@ int objtool_run(int argc, const char **argv)
 		goto err;
 
 	if (!opts.link && has_multiple_files(file->elf)) {
-		ERROR("Linked object requires --link");
+		WARN("Linked object requires --link");
 		goto err;
 	}
 
@@ -313,7 +310,7 @@ err:
 	 */
 	backup = malloc(strlen(objname) + strlen(ORIG_SUFFIX) + 1);
 	if (!backup) {
-		perror("malloc");
+		WARN_GLIBC("malloc");
 		return 1;
 	}
 
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index b0ef14a..f4e7ee8 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -353,7 +353,7 @@ static struct cfi_state *cfi_alloc(void)
 {
 	struct cfi_state *cfi = calloc(1, sizeof(struct cfi_state));
 	if (!cfi) {
-		WARN("calloc failed");
+		WARN_GLIBC("calloc");
 		exit(1);
 	}
 	nr_cfi++;
@@ -409,7 +409,7 @@ static void *cfi_hash_alloc(unsigned long size)
 			PROT_READ|PROT_WRITE,
 			MAP_PRIVATE|MAP_ANON, -1, 0);
 	if (cfi_hash == (void *)-1L) {
-		WARN("mmap fail cfi_hash");
+		WARN_GLIBC("mmap fail cfi_hash");
 		cfi_hash = NULL;
 	}  else if (opts.stats) {
 		printf("cfi_bits: %d\n", cfi_bits);
@@ -465,7 +465,7 @@ static int decode_instructions(struct objtool_file *file)
 			if (!insns || idx == INSN_CHUNK_MAX) {
 				insns = calloc(sizeof(*insn), INSN_CHUNK_SIZE);
 				if (!insns) {
-					WARN("malloc failed");
+					WARN_GLIBC("calloc");
 					return -1;
 				}
 				idx = 0;
@@ -567,14 +567,21 @@ static int add_pv_ops(struct objtool_file *file, const char *symname)
 		if (!reloc)
 			break;
 
+		idx = (reloc_offset(reloc) - sym->offset) / sizeof(unsigned long);
+
 		func = reloc->sym;
 		if (func->type == STT_SECTION)
 			func = find_symbol_by_offset(reloc->sym->sec,
 						     reloc_addend(reloc));
+		if (!func) {
+			WARN_FUNC("can't find func at %s[%d]",
+				  reloc->sym->sec, reloc_addend(reloc),
+				  symname, idx);
+			return -1;
+		}
 
-		idx = (reloc_offset(reloc) - sym->offset) / sizeof(unsigned long);
-
-		objtool_pv_add(file, idx, func);
+		if (objtool_pv_add(file, idx, func))
+			return -1;
 
 		off = reloc_offset(reloc) + 1;
 		if (off > end)
@@ -598,7 +605,7 @@ static int init_pv_ops(struct objtool_file *file)
 	};
 	const char *pv_ops;
 	struct symbol *sym;
-	int idx, nr;
+	int idx, nr, ret;
 
 	if (!opts.noinstr)
 		return 0;
@@ -611,14 +618,19 @@ static int init_pv_ops(struct objtool_file *file)
 
 	nr = sym->len / sizeof(unsigned long);
 	file->pv_ops = calloc(sizeof(struct pv_state), nr);
-	if (!file->pv_ops)
+	if (!file->pv_ops) {
+		WARN_GLIBC("calloc");
 		return -1;
+	}
 
 	for (idx = 0; idx < nr; idx++)
 		INIT_LIST_HEAD(&file->pv_ops[idx].targets);
 
-	for (idx = 0; (pv_ops = pv_ops_tables[idx]); idx++)
-		add_pv_ops(file, pv_ops);
+	for (idx = 0; (pv_ops = pv_ops_tables[idx]); idx++) {
+		ret = add_pv_ops(file, pv_ops);
+		if (ret)
+			return ret;
+	}
 
 	return 0;
 }
@@ -666,13 +678,12 @@ static int create_static_call_sections(struct objtool_file *file)
 		/* find key symbol */
 		key_name = strdup(insn_call_dest(insn)->name);
 		if (!key_name) {
-			perror("strdup");
+			WARN_GLIBC("strdup");
 			return -1;
 		}
 		if (strncmp(key_name, STATIC_CALL_TRAMP_PREFIX_STR,
 			    STATIC_CALL_TRAMP_PREFIX_LEN)) {
 			WARN("static_call: trampoline name malformed: %s", key_name);
-			free(key_name);
 			return -1;
 		}
 		tmp = key_name + STATIC_CALL_TRAMP_PREFIX_LEN - STATIC_CALL_KEY_PREFIX_LEN;
@@ -682,7 +693,6 @@ static int create_static_call_sections(struct objtool_file *file)
 		if (!key_sym) {
 			if (!opts.module) {
 				WARN("static_call: can't find static_call_key symbol: %s", tmp);
-				free(key_name);
 				return -1;
 			}
 
@@ -697,7 +707,6 @@ static int create_static_call_sections(struct objtool_file *file)
 			 */
 			key_sym = insn_call_dest(insn);
 		}
-		free(key_name);
 
 		/* populate reloc for 'key' */
 		if (!elf_init_reloc_data_sym(file->elf, sec,
@@ -981,7 +990,7 @@ static int create_direct_call_sections(struct objtool_file *file)
 /*
  * Warnings shouldn't be reported for ignored functions.
  */
-static void add_ignores(struct objtool_file *file)
+static int add_ignores(struct objtool_file *file)
 {
 	struct section *rsec;
 	struct symbol *func;
@@ -989,7 +998,7 @@ static void add_ignores(struct objtool_file *file)
 
 	rsec = find_section_by_name(file->elf, ".rela.discard.func_stack_frame_non_standard");
 	if (!rsec)
-		return;
+		return 0;
 
 	for_each_reloc(rsec, reloc) {
 		switch (reloc->sym->type) {
@@ -1006,11 +1015,13 @@ static void add_ignores(struct objtool_file *file)
 		default:
 			WARN("unexpected relocation symbol type in %s: %d",
 			     rsec->name, reloc->sym->type);
-			continue;
+			return -1;
 		}
 
 		func->ignore = true;
 	}
+
+	return 0;
 }
 
 /*
@@ -1275,7 +1286,7 @@ static void remove_insn_ops(struct instruction *insn)
 	insn->stack_ops = NULL;
 }
 
-static void annotate_call_site(struct objtool_file *file,
+static int annotate_call_site(struct objtool_file *file,
 			       struct instruction *insn, bool sibling)
 {
 	struct reloc *reloc = insn_reloc(file, insn);
@@ -1286,12 +1297,12 @@ static void annotate_call_site(struct objtool_file *file,
 
 	if (sym->static_call_tramp) {
 		list_add_tail(&insn->call_node, &file->static_call_list);
-		return;
+		return 0;
 	}
 
 	if (sym->retpoline_thunk) {
 		list_add_tail(&insn->call_node, &file->retpoline_call_list);
-		return;
+		return 0;
 	}
 
 	/*
@@ -1303,10 +1314,12 @@ static void annotate_call_site(struct objtool_file *file,
 		if (reloc)
 			set_reloc_type(file->elf, reloc, R_NONE);
 
-		elf_write_insn(file->elf, insn->sec,
-			       insn->offset, insn->len,
-			       sibling ? arch_ret_insn(insn->len)
-			               : arch_nop_insn(insn->len));
+		if (elf_write_insn(file->elf, insn->sec,
+				   insn->offset, insn->len,
+				   sibling ? arch_ret_insn(insn->len)
+					   : arch_nop_insn(insn->len))) {
+			return -1;
+		}
 
 		insn->type = sibling ? INSN_RETURN : INSN_NOP;
 
@@ -1320,7 +1333,7 @@ static void annotate_call_site(struct objtool_file *file,
 			insn->retpoline_safe = true;
 		}
 
-		return;
+		return 0;
 	}
 
 	if (opts.mcount && sym->fentry) {
@@ -1330,15 +1343,17 @@ static void annotate_call_site(struct objtool_file *file,
 			if (reloc)
 				set_reloc_type(file->elf, reloc, R_NONE);
 
-			elf_write_insn(file->elf, insn->sec,
-				       insn->offset, insn->len,
-				       arch_nop_insn(insn->len));
+			if (elf_write_insn(file->elf, insn->sec,
+					   insn->offset, insn->len,
+					   arch_nop_insn(insn->len))) {
+				return -1;
+			}
 
 			insn->type = INSN_NOP;
 		}
 
 		list_add_tail(&insn->call_node, &file->mcount_loc_list);
-		return;
+		return 0;
 	}
 
 	if (insn->type == INSN_CALL && !insn->sec->init &&
@@ -1347,14 +1362,16 @@ static void annotate_call_site(struct objtool_file *file,
 
 	if (!sibling && dead_end_function(file, sym))
 		insn->dead_end = true;
+
+	return 0;
 }
 
-static void add_call_dest(struct objtool_file *file, struct instruction *insn,
+static int add_call_dest(struct objtool_file *file, struct instruction *insn,
 			  struct symbol *dest, bool sibling)
 {
 	insn->_call_dest = dest;
 	if (!dest)
-		return;
+		return 0;
 
 	/*
 	 * Whatever stack impact regular CALLs have, should be undone
@@ -1365,10 +1382,10 @@ static void add_call_dest(struct objtool_file *file, struct instruction *insn,
 	 */
 	remove_insn_ops(insn);
 
-	annotate_call_site(file, insn, sibling);
+	return annotate_call_site(file, insn, sibling);
 }
 
-static void add_retpoline_call(struct objtool_file *file, struct instruction *insn)
+static int add_retpoline_call(struct objtool_file *file, struct instruction *insn)
 {
 	/*
 	 * Retpoline calls/jumps are really dynamic calls/jumps in disguise,
@@ -1385,7 +1402,7 @@ static void add_retpoline_call(struct objtool_file *file, struct instruction *in
 		insn->type = INSN_JUMP_DYNAMIC_CONDITIONAL;
 		break;
 	default:
-		return;
+		return 0;
 	}
 
 	insn->retpoline_safe = true;
@@ -1399,7 +1416,7 @@ static void add_retpoline_call(struct objtool_file *file, struct instruction *in
 	 */
 	remove_insn_ops(insn);
 
-	annotate_call_site(file, insn, false);
+	return annotate_call_site(file, insn, false);
 }
 
 static void add_return_call(struct objtool_file *file, struct instruction *insn, bool add)
@@ -1468,6 +1485,7 @@ static int add_jump_destinations(struct objtool_file *file)
 	struct reloc *reloc;
 	struct section *dest_sec;
 	unsigned long dest_off;
+	int ret;
 
 	for_each_insn(file, insn) {
 		if (insn->jump_dest) {
@@ -1488,7 +1506,9 @@ static int add_jump_destinations(struct objtool_file *file)
 			dest_sec = reloc->sym->sec;
 			dest_off = arch_dest_reloc_offset(reloc_addend(reloc));
 		} else if (reloc->sym->retpoline_thunk) {
-			add_retpoline_call(file, insn);
+			ret = add_retpoline_call(file, insn);
+			if (ret)
+				return ret;
 			continue;
 		} else if (reloc->sym->return_thunk) {
 			add_return_call(file, insn, true);
@@ -1498,7 +1518,9 @@ static int add_jump_destinations(struct objtool_file *file)
 			 * External sibling call or internal sibling call with
 			 * STT_FUNC reloc.
 			 */
-			add_call_dest(file, insn, reloc->sym, true);
+			ret = add_call_dest(file, insn, reloc->sym, true);
+			if (ret)
+				return ret;
 			continue;
 		} else if (reloc->sym->sec->idx) {
 			dest_sec = reloc->sym->sec;
@@ -1538,7 +1560,9 @@ static int add_jump_destinations(struct objtool_file *file)
 		 */
 		if (jump_dest->sym && jump_dest->offset == jump_dest->sym->offset) {
 			if (jump_dest->sym->retpoline_thunk) {
-				add_retpoline_call(file, insn);
+				ret = add_retpoline_call(file, insn);
+				if (ret)
+					return ret;
 				continue;
 			}
 			if (jump_dest->sym->return_thunk) {
@@ -1580,7 +1604,9 @@ static int add_jump_destinations(struct objtool_file *file)
 			 * Internal sibling call without reloc or with
 			 * STT_SECTION reloc.
 			 */
-			add_call_dest(file, insn, insn_func(jump_dest), true);
+			ret = add_call_dest(file, insn, insn_func(jump_dest), true);
+			if (ret)
+				return ret;
 			continue;
 		}
 
@@ -1610,6 +1636,7 @@ static int add_call_destinations(struct objtool_file *file)
 	unsigned long dest_off;
 	struct symbol *dest;
 	struct reloc *reloc;
+	int ret;
 
 	for_each_insn(file, insn) {
 		struct symbol *func = insn_func(insn);
@@ -1621,7 +1648,9 @@ static int add_call_destinations(struct objtool_file *file)
 			dest_off = arch_jump_destination(insn);
 			dest = find_call_destination(insn->sec, dest_off);
 
-			add_call_dest(file, insn, dest, false);
+			ret = add_call_dest(file, insn, dest, false);
+			if (ret)
+				return ret;
 
 			if (func && func->ignore)
 				continue;
@@ -1645,13 +1674,20 @@ static int add_call_destinations(struct objtool_file *file)
 				return -1;
 			}
 
-			add_call_dest(file, insn, dest, false);
+			ret = add_call_dest(file, insn, dest, false);
+			if (ret)
+				return ret;
 
 		} else if (reloc->sym->retpoline_thunk) {
-			add_retpoline_call(file, insn);
+			ret = add_retpoline_call(file, insn);
+			if (ret)
+				return ret;
 
-		} else
-			add_call_dest(file, insn, reloc->sym, false);
+		} else {
+			ret = add_call_dest(file, insn, reloc->sym, false);
+			if (ret)
+				return ret;
+		}
 	}
 
 	return 0;
@@ -1674,15 +1710,15 @@ static int handle_group_alt(struct objtool_file *file,
 	if (!orig_alt_group) {
 		struct instruction *last_orig_insn = NULL;
 
-		orig_alt_group = malloc(sizeof(*orig_alt_group));
+		orig_alt_group = calloc(1, sizeof(*orig_alt_group));
 		if (!orig_alt_group) {
-			WARN("malloc failed");
+			WARN_GLIBC("calloc");
 			return -1;
 		}
 		orig_alt_group->cfi = calloc(special_alt->orig_len,
 					     sizeof(struct cfi_state *));
 		if (!orig_alt_group->cfi) {
-			WARN("calloc failed");
+			WARN_GLIBC("calloc");
 			return -1;
 		}
 
@@ -1711,9 +1747,9 @@ static int handle_group_alt(struct objtool_file *file,
 		}
 	}
 
-	new_alt_group = malloc(sizeof(*new_alt_group));
+	new_alt_group = calloc(1, sizeof(*new_alt_group));
 	if (!new_alt_group) {
-		WARN("malloc failed");
+		WARN_GLIBC("calloc");
 		return -1;
 	}
 
@@ -1725,9 +1761,9 @@ static int handle_group_alt(struct objtool_file *file,
 		 * instruction affects the stack, the instruction after it (the
 		 * nop) will propagate the new state to the shared CFI array.
 		 */
-		nop = malloc(sizeof(*nop));
+		nop = calloc(1, sizeof(*nop));
 		if (!nop) {
-			WARN("malloc failed");
+			WARN_GLIBC("calloc");
 			return -1;
 		}
 		memset(nop, 0, sizeof(*nop));
@@ -1827,9 +1863,13 @@ static int handle_jump_alt(struct objtool_file *file,
 
 		if (reloc)
 			set_reloc_type(file->elf, reloc, R_NONE);
-		elf_write_insn(file->elf, orig_insn->sec,
-			       orig_insn->offset, orig_insn->len,
-			       arch_nop_insn(orig_insn->len));
+
+		if (elf_write_insn(file->elf, orig_insn->sec,
+				   orig_insn->offset, orig_insn->len,
+				   arch_nop_insn(orig_insn->len))) {
+			return -1;
+		}
+
 		orig_insn->type = INSN_NOP;
 	}
 
@@ -1865,9 +1905,8 @@ static int add_special_section_alts(struct objtool_file *file)
 	struct alternative *alt;
 	int ret;
 
-	ret = special_get_alts(file->elf, &special_alts);
-	if (ret)
-		return ret;
+	if (special_get_alts(file->elf, &special_alts))
+		return -1;
 
 	list_for_each_entry_safe(special_alt, tmp, &special_alts, list) {
 
@@ -1876,8 +1915,7 @@ static int add_special_section_alts(struct objtool_file *file)
 		if (!orig_insn) {
 			WARN_FUNC("special: can't find orig instruction",
 				  special_alt->orig_sec, special_alt->orig_off);
-			ret = -1;
-			goto out;
+			return -1;
 		}
 
 		new_insn = NULL;
@@ -1888,8 +1926,7 @@ static int add_special_section_alts(struct objtool_file *file)
 				WARN_FUNC("special: can't find new instruction",
 					  special_alt->new_sec,
 					  special_alt->new_off);
-				ret = -1;
-				goto out;
+				return -1;
 			}
 		}
 
@@ -1902,19 +1939,19 @@ static int add_special_section_alts(struct objtool_file *file)
 			ret = handle_group_alt(file, special_alt, orig_insn,
 					       &new_insn);
 			if (ret)
-				goto out;
+				return ret;
+
 		} else if (special_alt->jump_or_nop) {
 			ret = handle_jump_alt(file, special_alt, orig_insn,
 					      &new_insn);
 			if (ret)
-				goto out;
+				return ret;
 		}
 
-		alt = malloc(sizeof(*alt));
+		alt = calloc(1, sizeof(*alt));
 		if (!alt) {
-			WARN("malloc failed");
-			ret = -1;
-			goto out;
+			WARN_GLIBC("calloc");
+			return -1;
 		}
 
 		alt->insn = new_insn;
@@ -1931,8 +1968,7 @@ static int add_special_section_alts(struct objtool_file *file)
 		printf("long:\t%ld\t%ld\n", file->jl_nop_long, file->jl_long);
 	}
 
-out:
-	return ret;
+	return 0;
 }
 
 __weak unsigned long arch_jump_table_sym_offset(struct reloc *reloc, struct reloc *table)
@@ -1989,9 +2025,9 @@ static int add_jump_table(struct objtool_file *file, struct instruction *insn)
 		if (!insn_func(dest_insn) || insn_func(dest_insn)->pfunc != pfunc)
 			break;
 
-		alt = malloc(sizeof(*alt));
+		alt = calloc(1, sizeof(*alt));
 		if (!alt) {
-			WARN("malloc failed");
+			WARN_GLIBC("calloc");
 			return -1;
 		}
 
@@ -2039,7 +2075,7 @@ static void find_jump_table(struct objtool_file *file, struct symbol *func,
 		    insn->jump_dest &&
 		    (insn->jump_dest->offset <= insn->offset ||
 		     insn->jump_dest->offset > orig_insn->offset))
-		    break;
+			break;
 
 		table_reloc = arch_find_switch_table(file, insn, &table_size);
 		if (!table_reloc)
@@ -2103,7 +2139,6 @@ static int add_func_jump_tables(struct objtool_file *file,
 		if (!insn_jump_table(insn))
 			continue;
 
-
 		ret = add_jump_table(file, insn);
 		if (ret)
 			return ret;
@@ -2221,6 +2256,7 @@ static int read_unwind_hints(struct objtool_file *file)
 			if (sym && sym->bind == STB_GLOBAL) {
 				if (opts.ibt && insn->type != INSN_ENDBR && !insn->noendbr) {
 					WARN_INSN(insn, "UNWIND_HINT_IRET_REGS without ENDBR");
+					return -1;
 				}
 			}
 		}
@@ -2390,7 +2426,7 @@ static int __annotate_late(struct objtool_file *file, int type, struct instructi
 
 	default:
 		WARN_INSN(insn, "Unknown annotation type: %d", type);
-		break;
+		return -1;
 	}
 
 	return 0;
@@ -2503,7 +2539,10 @@ static int decode_sections(struct objtool_file *file)
 	if (ret)
 		return ret;
 
-	add_ignores(file);
+	ret = add_ignores(file);
+	if (ret)
+		return ret;
+
 	add_uaccess_safe(file);
 
 	ret = read_annotate(file, __annotate_early);
@@ -2723,7 +2762,7 @@ static int update_cfi_state(struct instruction *insn,
 	if (cfa->base == CFI_UNDEFINED) {
 		if (insn_func(insn)) {
 			WARN_INSN(insn, "undefined stack state");
-			return -1;
+			return 1;
 		}
 		return 0;
 	}
@@ -3166,9 +3205,8 @@ static int propagate_alt_cfi(struct objtool_file *file, struct instruction *insn
 		if (cficmp(alt_cfi[group_off], insn->cfi)) {
 			struct alt_group *orig_group = insn->alt_group->orig_group ?: insn->alt_group;
 			struct instruction *orig = orig_group->first_insn;
-			char *where = offstr(insn->sec, insn->offset);
-			WARN_INSN(orig, "stack layout conflict in alternatives: %s", where);
-			free(where);
+			WARN_INSN(orig, "stack layout conflict in alternatives: %s",
+				  offstr(insn->sec, insn->offset));
 			return -1;
 		}
 	}
@@ -3181,11 +3219,13 @@ static int handle_insn_ops(struct instruction *insn,
 			   struct insn_state *state)
 {
 	struct stack_op *op;
+	int ret;
 
 	for (op = insn->stack_ops; op; op = op->next) {
 
-		if (update_cfi_state(insn, next_insn, &state->cfi, op))
-			return 1;
+		ret = update_cfi_state(insn, next_insn, &state->cfi, op);
+		if (ret)
+			return ret;
 
 		if (!opts.uaccess || !insn->alt_group)
 			continue;
@@ -3229,36 +3269,41 @@ static bool insn_cfi_match(struct instruction *insn, struct cfi_state *cfi2)
 		WARN_INSN(insn, "stack state mismatch: cfa1=%d%+d cfa2=%d%+d",
 			  cfi1->cfa.base, cfi1->cfa.offset,
 			  cfi2->cfa.base, cfi2->cfa.offset);
+		return false;
 
-	} else if (memcmp(&cfi1->regs, &cfi2->regs, sizeof(cfi1->regs))) {
+	}
+
+	if (memcmp(&cfi1->regs, &cfi2->regs, sizeof(cfi1->regs))) {
 		for (i = 0; i < CFI_NUM_REGS; i++) {
-			if (!memcmp(&cfi1->regs[i], &cfi2->regs[i],
-				    sizeof(struct cfi_reg)))
+
+			if (!memcmp(&cfi1->regs[i], &cfi2->regs[i], sizeof(struct cfi_reg)))
 				continue;
 
 			WARN_INSN(insn, "stack state mismatch: reg1[%d]=%d%+d reg2[%d]=%d%+d",
 				  i, cfi1->regs[i].base, cfi1->regs[i].offset,
 				  i, cfi2->regs[i].base, cfi2->regs[i].offset);
-			break;
 		}
+		return false;
+	}
 
-	} else if (cfi1->type != cfi2->type) {
+	if (cfi1->type != cfi2->type) {
 
 		WARN_INSN(insn, "stack state mismatch: type1=%d type2=%d",
 			  cfi1->type, cfi2->type);
+		return false;
+	}
 
-	} else if (cfi1->drap != cfi2->drap ||
+	if (cfi1->drap != cfi2->drap ||
 		   (cfi1->drap && cfi1->drap_reg != cfi2->drap_reg) ||
 		   (cfi1->drap && cfi1->drap_offset != cfi2->drap_offset)) {
 
 		WARN_INSN(insn, "stack state mismatch: drap1=%d(%d,%d) drap2=%d(%d,%d)",
 			  cfi1->drap, cfi1->drap_reg, cfi1->drap_offset,
 			  cfi2->drap, cfi2->drap_reg, cfi2->drap_offset);
+		return false;
+	}
 
-	} else
-		return true;
-
-	return false;
+	return true;
 }
 
 static inline bool func_uaccess_safe(struct symbol *func)
@@ -3490,6 +3535,8 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
 
 			WARN("%s() falls through to next function %s()",
 			     func->name, insn_func(insn)->name);
+			func->warnings++;
+
 			return 1;
 		}
 
@@ -3597,9 +3644,6 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
 				return 1;
 			}
 
-			if (insn->dead_end)
-				return 0;
-
 			break;
 
 		case INSN_JUMP_CONDITIONAL:
@@ -3706,7 +3750,9 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
 			if (file->ignore_unreachables)
 				return 0;
 
-			WARN("%s: unexpected end of section", sec->name);
+			WARN("%s%sunexpected end of section %s",
+			     func ? func->name : "", func ? ": " : "",
+			     sec->name);
 			return 1;
 		}
 
@@ -3796,7 +3842,7 @@ static int validate_unret(struct objtool_file *file, struct instruction *insn)
 			if (!is_sibling_call(insn)) {
 				if (!insn->jump_dest) {
 					WARN_INSN(insn, "unresolved jump target after linking?!?");
-					return -1;
+					return 1;
 				}
 				ret = validate_unret(file, insn->jump_dest);
 				if (ret) {
@@ -3818,7 +3864,7 @@ static int validate_unret(struct objtool_file *file, struct instruction *insn)
 			if (!dest) {
 				WARN("Unresolved function after linking!?: %s",
 				     insn_call_dest(insn)->name);
-				return -1;
+				return 1;
 			}
 
 			ret = validate_unret(file, dest);
@@ -3847,7 +3893,7 @@ static int validate_unret(struct objtool_file *file, struct instruction *insn)
 
 		if (!next) {
 			WARN_INSN(insn, "teh end!");
-			return -1;
+			return 1;
 		}
 		insn = next;
 	}
@@ -3862,18 +3908,13 @@ static int validate_unret(struct objtool_file *file, struct instruction *insn)
 static int validate_unrets(struct objtool_file *file)
 {
 	struct instruction *insn;
-	int ret, warnings = 0;
+	int warnings = 0;
 
 	for_each_insn(file, insn) {
 		if (!insn->unret)
 			continue;
 
-		ret = validate_unret(file, insn);
-		if (ret < 0) {
-			WARN_INSN(insn, "Failed UNRET validation");
-			return ret;
-		}
-		warnings += ret;
+		warnings += validate_unret(file, insn);
 	}
 
 	return warnings;
@@ -3899,13 +3940,13 @@ static int validate_retpoline(struct objtool_file *file)
 		if (insn->type == INSN_RETURN) {
 			if (opts.rethunk) {
 				WARN_INSN(insn, "'naked' return found in MITIGATION_RETHUNK build");
-			} else
-				continue;
-		} else {
-			WARN_INSN(insn, "indirect %s found in MITIGATION_RETPOLINE build",
-				  insn->type == INSN_JUMP_DYNAMIC ? "jump" : "call");
+				warnings++;
+			}
+			continue;
 		}
 
+		WARN_INSN(insn, "indirect %s found in MITIGATION_RETPOLINE build",
+			  insn->type == INSN_JUMP_DYNAMIC ? "jump" : "call");
 		warnings++;
 	}
 
@@ -4472,7 +4513,7 @@ static int validate_reachable_instructions(struct objtool_file *file)
 }
 
 /* 'funcs' is a space-separated list of function names */
-static int disas_funcs(const char *funcs)
+static void disas_funcs(const char *funcs)
 {
 	const char *objdump_str, *cross_compile;
 	int size, ret;
@@ -4505,7 +4546,7 @@ static int disas_funcs(const char *funcs)
 	size = snprintf(NULL, 0, objdump_str, cross_compile, objname, funcs) + 1;
 	if (size <= 0) {
 		WARN("objdump string size calculation failed");
-		return -1;
+		return;
 	}
 
 	cmd = malloc(size);
@@ -4515,13 +4556,11 @@ static int disas_funcs(const char *funcs)
 	ret = system(cmd);
 	if (ret) {
 		WARN("disassembly failed: %d", ret);
-		return -1;
+		return;
 	}
-
-	return 0;
 }
 
-static int disas_warned_funcs(struct objtool_file *file)
+static void disas_warned_funcs(struct objtool_file *file)
 {
 	struct symbol *sym;
 	char *funcs = NULL, *tmp;
@@ -4530,9 +4569,17 @@ static int disas_warned_funcs(struct objtool_file *file)
 		if (sym->warnings) {
 			if (!funcs) {
 				funcs = malloc(strlen(sym->name) + 1);
+				if (!funcs) {
+					WARN_GLIBC("malloc");
+					return;
+				}
 				strcpy(funcs, sym->name);
 			} else {
 				tmp = malloc(strlen(funcs) + strlen(sym->name) + 2);
+				if (!tmp) {
+					WARN_GLIBC("malloc");
+					return;
+				}
 				sprintf(tmp, "%s %s", funcs, sym->name);
 				free(funcs);
 				funcs = tmp;
@@ -4542,8 +4589,6 @@ static int disas_warned_funcs(struct objtool_file *file)
 
 	if (funcs)
 		disas_funcs(funcs);
-
-	return 0;
 }
 
 struct insn_chunk {
@@ -4576,7 +4621,7 @@ static void free_insns(struct objtool_file *file)
 
 int check(struct objtool_file *file)
 {
-	int ret, warnings = 0;
+	int ret = 0, warnings = 0;
 
 	arch_initial_func_cfi_state(&initial_func_cfi);
 	init_cfi_state(&init_cfi);
@@ -4594,44 +4639,27 @@ int check(struct objtool_file *file)
 	cfi_hash_add(&func_cfi);
 
 	ret = decode_sections(file);
-	if (ret < 0)
+	if (ret)
 		goto out;
 
-	warnings += ret;
-
 	if (!nr_insns)
 		goto out;
 
-	if (opts.retpoline) {
-		ret = validate_retpoline(file);
-		if (ret < 0)
-			goto out;
-		warnings += ret;
-	}
+	if (opts.retpoline)
+		warnings += validate_retpoline(file);
 
 	if (opts.stackval || opts.orc || opts.uaccess) {
-		ret = validate_functions(file);
-		if (ret < 0)
-			goto out;
-		warnings += ret;
+		int w = 0;
 
-		ret = validate_unwind_hints(file, NULL);
-		if (ret < 0)
-			goto out;
-		warnings += ret;
+		w += validate_functions(file);
+		w += validate_unwind_hints(file, NULL);
+		if (!w)
+			w += validate_reachable_instructions(file);
 
-		if (!warnings) {
-			ret = validate_reachable_instructions(file);
-			if (ret < 0)
-				goto out;
-			warnings += ret;
-		}
+		warnings += w;
 
 	} else if (opts.noinstr) {
-		ret = validate_noinstr_sections(file);
-		if (ret < 0)
-			goto out;
-		warnings += ret;
+		warnings += validate_noinstr_sections(file);
 	}
 
 	if (opts.unret) {
@@ -4639,87 +4667,67 @@ int check(struct objtool_file *file)
 		 * Must be after validate_branch() and friends, it plays
 		 * further games with insn->visited.
 		 */
-		ret = validate_unrets(file);
-		if (ret < 0)
-			goto out;
-		warnings += ret;
+		warnings += validate_unrets(file);
 	}
 
-	if (opts.ibt) {
-		ret = validate_ibt(file);
-		if (ret < 0)
-			goto out;
-		warnings += ret;
-	}
+	if (opts.ibt)
+		warnings += validate_ibt(file);
 
-	if (opts.sls) {
-		ret = validate_sls(file);
-		if (ret < 0)
-			goto out;
-		warnings += ret;
-	}
+	if (opts.sls)
+		warnings += validate_sls(file);
 
 	if (opts.static_call) {
 		ret = create_static_call_sections(file);
-		if (ret < 0)
+		if (ret)
 			goto out;
-		warnings += ret;
 	}
 
 	if (opts.retpoline) {
 		ret = create_retpoline_sites_sections(file);
-		if (ret < 0)
+		if (ret)
 			goto out;
-		warnings += ret;
 	}
 
 	if (opts.cfi) {
 		ret = create_cfi_sections(file);
-		if (ret < 0)
+		if (ret)
 			goto out;
-		warnings += ret;
 	}
 
 	if (opts.rethunk) {
 		ret = create_return_sites_sections(file);
-		if (ret < 0)
+		if (ret)
 			goto out;
-		warnings += ret;
 
 		if (opts.hack_skylake) {
 			ret = create_direct_call_sections(file);
-			if (ret < 0)
+			if (ret)
 				goto out;
-			warnings += ret;
 		}
 	}
 
 	if (opts.mcount) {
 		ret = create_mcount_loc_sections(file);
-		if (ret < 0)
+		if (ret)
 			goto out;
-		warnings += ret;
 	}
 
 	if (opts.prefix) {
 		ret = add_prefix_symbols(file);
-		if (ret < 0)
+		if (ret)
 			goto out;
-		warnings += ret;
 	}
 
 	if (opts.ibt) {
 		ret = create_ibt_endbr_seal_sections(file);
-		if (ret < 0)
+		if (ret)
 			goto out;
-		warnings += ret;
 	}
 
 	if (opts.orc && nr_insns) {
 		ret = orc_create(file);
-		if (ret < 0)
+		if (ret)
 			goto out;
-		warnings += ret;
 	}
 
 	free_insns(file);
diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index 0f38167..b352a78 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -331,7 +331,7 @@ static int read_sections(struct elf *elf)
 
 	elf->section_data = calloc(sections_nr, sizeof(*sec));
 	if (!elf->section_data) {
-		perror("calloc");
+		WARN_GLIBC("calloc");
 		return -1;
 	}
 	for (i = 0; i < sections_nr; i++) {
@@ -467,7 +467,7 @@ static int read_symbols(struct elf *elf)
 
 	elf->symbol_data = calloc(symbols_nr, sizeof(*sym));
 	if (!elf->symbol_data) {
-		perror("calloc");
+		WARN_GLIBC("calloc");
 		return -1;
 	}
 	for (i = 0; i < symbols_nr; i++) {
@@ -799,7 +799,7 @@ elf_create_section_symbol(struct elf *elf, struct section *sec)
 	struct symbol *sym = calloc(1, sizeof(*sym));
 
 	if (!sym) {
-		perror("malloc");
+		WARN_GLIBC("malloc");
 		return NULL;
 	}
 
@@ -829,7 +829,7 @@ elf_create_prefix_symbol(struct elf *elf, struct symbol *orig, long size)
 	char *name = malloc(namelen);
 
 	if (!sym || !name) {
-		perror("malloc");
+		WARN_GLIBC("malloc");
 		return NULL;
 	}
 
@@ -963,7 +963,7 @@ static int read_relocs(struct elf *elf)
 		nr_reloc = 0;
 		rsec->relocs = calloc(sec_num_entries(rsec), sizeof(*reloc));
 		if (!rsec->relocs) {
-			perror("calloc");
+			WARN_GLIBC("calloc");
 			return -1;
 		}
 		for (i = 0; i < sec_num_entries(rsec); i++) {
@@ -1005,7 +1005,7 @@ struct elf *elf_open_read(const char *name, int flags)
 
 	elf = malloc(sizeof(*elf));
 	if (!elf) {
-		perror("malloc");
+		WARN_GLIBC("malloc");
 		return NULL;
 	}
 	memset(elf, 0, sizeof(*elf));
@@ -1099,7 +1099,7 @@ struct section *elf_create_section(struct elf *elf, const char *name,
 
 	sec = malloc(sizeof(*sec));
 	if (!sec) {
-		perror("malloc");
+		WARN_GLIBC("malloc");
 		return NULL;
 	}
 	memset(sec, 0, sizeof(*sec));
@@ -1114,7 +1114,7 @@ struct section *elf_create_section(struct elf *elf, const char *name,
 
 	sec->name = strdup(name);
 	if (!sec->name) {
-		perror("strdup");
+		WARN_GLIBC("strdup");
 		return NULL;
 	}
 
@@ -1132,7 +1132,7 @@ struct section *elf_create_section(struct elf *elf, const char *name,
 	if (size) {
 		sec->data->d_buf = malloc(size);
 		if (!sec->data->d_buf) {
-			perror("malloc");
+			WARN_GLIBC("malloc");
 			return NULL;
 		}
 		memset(sec->data->d_buf, 0, size);
@@ -1179,7 +1179,7 @@ static struct section *elf_create_rela_section(struct elf *elf,
 
 	rsec_name = malloc(strlen(sec->name) + strlen(".rela") + 1);
 	if (!rsec_name) {
-		perror("malloc");
+		WARN_GLIBC("malloc");
 		return NULL;
 	}
 	strcpy(rsec_name, ".rela");
@@ -1199,7 +1199,7 @@ static struct section *elf_create_rela_section(struct elf *elf,
 
 	rsec->relocs = calloc(sec_num_entries(rsec), sizeof(struct reloc));
 	if (!rsec->relocs) {
-		perror("calloc");
+		WARN_GLIBC("calloc");
 		return NULL;
 	}
 
diff --git a/tools/objtool/include/objtool/objtool.h b/tools/objtool/include/objtool/objtool.h
index 94a33ee..c0dc86a 100644
--- a/tools/objtool/include/objtool/objtool.h
+++ b/tools/objtool/include/objtool/objtool.h
@@ -41,7 +41,7 @@ struct objtool_file {
 
 struct objtool_file *objtool_open_read(const char *_objname);
 
-void objtool_pv_add(struct objtool_file *file, int idx, struct symbol *func);
+int objtool_pv_add(struct objtool_file *file, int idx, struct symbol *func);
 
 int check(struct objtool_file *file);
 int orc_dump(const char *objname);
diff --git a/tools/objtool/include/objtool/warn.h b/tools/objtool/include/objtool/warn.h
index e72b9d6..b29ac14 100644
--- a/tools/objtool/include/objtool/warn.h
+++ b/tools/objtool/include/objtool/warn.h
@@ -11,6 +11,7 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#include <errno.h>
 #include <objtool/builtin.h>
 #include <objtool/elf.h>
 
@@ -43,8 +44,9 @@ static inline char *offstr(struct section *sec, unsigned long offset)
 
 #define WARN(format, ...)				\
 	fprintf(stderr,					\
-		"%s: %s: objtool: " format "\n",	\
-		objname,				\
+		"%s%s%s: objtool: " format "\n",	\
+		objname ?: "",				\
+		objname ? ": " : "",			\
 		opts.werror ? "error" : "warning",	\
 		##__VA_ARGS__)
 
@@ -83,7 +85,10 @@ static inline char *offstr(struct section *sec, unsigned long offset)
 	}							\
 })
 
-#define WARN_ELF(format, ...)				\
-	WARN(format ": %s", ##__VA_ARGS__, elf_errmsg(-1))
+#define WARN_ELF(format, ...)					\
+	WARN("%s: " format " failed: %s", __func__, ##__VA_ARGS__, elf_errmsg(-1))
+
+#define WARN_GLIBC(format, ...)					\
+	WARN("%s: " format " failed: %s", __func__, ##__VA_ARGS__, strerror(errno))
 
 #endif /* _WARN_H */
diff --git a/tools/objtool/objtool.c b/tools/objtool/objtool.c
index 1c73fb6..e4b49c5 100644
--- a/tools/objtool/objtool.c
+++ b/tools/objtool/objtool.c
@@ -44,14 +44,14 @@ struct objtool_file *objtool_open_read(const char *filename)
 	return &file;
 }
 
-void objtool_pv_add(struct objtool_file *f, int idx, struct symbol *func)
+int objtool_pv_add(struct objtool_file *f, int idx, struct symbol *func)
 {
 	if (!opts.noinstr)
-		return;
+		return 0;
 
 	if (!f->pv_ops) {
 		WARN("paravirt confusion");
-		return;
+		return -1;
 	}
 
 	/*
@@ -60,14 +60,15 @@ void objtool_pv_add(struct objtool_file *f, int idx, struct symbol *func)
 	 */
 	if (!strcmp(func->name, "_paravirt_nop") ||
 	    !strcmp(func->name, "_paravirt_ident_64"))
-		return;
+		return 0;
 
 	/* already added this function */
 	if (!list_empty(&func->pv_target))
-		return;
+		return 0;
 
 	list_add(&func->pv_target, &f->pv_ops[idx].targets);
 	f->pv_ops[idx].clean = false;
+	return 0;
 }
 
 int main(int argc, const char **argv)

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

* [tip: objtool/urgent] objtool: Silence more KCOV warnings
  2025-03-24 21:55 ` [PATCH 07/22] objtool: Silence more KCOV warnings Josh Poimboeuf
@ 2025-03-25  8:35   ` tip-bot2 for Josh Poimboeuf
  0 siblings, 0 replies; 75+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2025-03-25  8:35 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Ingo Molnar, kernel test robot, Josh Poimboeuf, Linus Torvalds,
	x86, linux-kernel

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

Commit-ID:     6b023c7842048c4bbeede802f3cf36b96c7a8b25
Gitweb:        https://git.kernel.org/tip/6b023c7842048c4bbeede802f3cf36b96c7a8b25
Author:        Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate:    Mon, 24 Mar 2025 14:55:57 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Tue, 25 Mar 2025 09:20:26 +01:00

objtool: Silence more KCOV warnings

In the past there were issues with KCOV triggering unreachable
instruction warnings, which is why unreachable warnings are now disabled
with CONFIG_KCOV.

Now some new KCOV warnings are showing up with GCC 14:

  vmlinux.o: warning: objtool: cpuset_write_resmask() falls through to next function cpuset_update_active_cpus.cold()
  drivers/usb/core/driver.o: error: objtool: usb_deregister() falls through to next function usb_match_device()
  sound/soc/codecs/snd-soc-wcd934x.o: warning: objtool: .text.wcd934x_slim_irq_handler: unexpected end of section

All are caused by GCC KCOV not finishing an optimization, leaving behind
a never-taken conditional branch to a basic block which falls through to
the next function (or end of section).

At a high level this is similar to the unreachable warnings mentioned
above, in that KCOV isn't fully removing dead code.  Treat it the same
way by adding these to the list of warnings to ignore with CONFIG_KCOV.

Reported-by: Ingo Molnar <mingo@kernel.org>
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/66a61a0b65d74e072d3dc02384e395edb2adc3c5.1742852846.git.jpoimboe@kernel.org
Closes: https://lore.kernel.org/Z9iTsI09AEBlxlHC@gmail.com
Closes: https://lore.kernel.org/oe-kbuild-all/202503180044.oH9gyPeg-lkp@intel.com/
---
 tools/objtool/check.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 2f7aff1..cb66e6b 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -3485,6 +3485,9 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
 			    !strncmp(func->name, "__pfx_", 6))
 				return 0;
 
+			if (file->ignore_unreachables)
+				return 0;
+
 			WARN("%s() falls through to next function %s()",
 			     func->name, insn_func(insn)->name);
 			return 1;
@@ -3694,6 +3697,9 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
 		if (!next_insn) {
 			if (state.cfi.cfa.base == CFI_UNDEFINED)
 				return 0;
+			if (file->ignore_unreachables)
+				return 0;
+
 			WARN("%s: unexpected end of section", sec->name);
 			return 1;
 		}

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

* [tip: objtool/urgent] objtool: Fix init_module() handling
  2025-03-24 21:55 ` [PATCH 06/22] objtool: Fix init_module() handling Josh Poimboeuf
@ 2025-03-25  8:35   ` tip-bot2 for Josh Poimboeuf
  0 siblings, 0 replies; 75+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2025-03-25  8:35 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Josh Poimboeuf, Ingo Molnar, Linus Torvalds, x86, linux-kernel

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

Commit-ID:     4fab2d7628dd38f3fa8a5e615199350ecaeb17a8
Gitweb:        https://git.kernel.org/tip/4fab2d7628dd38f3fa8a5e615199350ecaeb17a8
Author:        Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate:    Mon, 24 Mar 2025 14:55:56 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Tue, 25 Mar 2025 09:20:26 +01:00

objtool: Fix init_module() handling

If IBT is enabled and a module uses the deprecated init_module() magic
function name rather than module_init(fn), its ENDBR will get removed,
causing an IBT failure during module load.

Objtool does print an obscure warning, but then does nothing to either
correct it or return an error.

Improve the usefulness of the warning and return an error so it will at
least fail the build with CONFIG_OBJTOOL_WERROR.

Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/366bfdbe92736cde9fb01d5d3eb9b98e9070a1ec.1742852846.git.jpoimboe@kernel.org
---
 tools/objtool/check.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index b2f6a7f..2f7aff1 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -828,8 +828,11 @@ static int create_ibt_endbr_seal_sections(struct objtool_file *file)
 		if (opts.module && sym && sym->type == STT_FUNC &&
 		    insn->offset == sym->offset &&
 		    (!strcmp(sym->name, "init_module") ||
-		     !strcmp(sym->name, "cleanup_module")))
-			WARN("%s(): not an indirect call target", sym->name);
+		     !strcmp(sym->name, "cleanup_module"))) {
+			WARN("%s(): Magic init_module() function name is deprecated, use module_init(fn) instead",
+			     sym->name);
+			return -1;
+		}
 
 		if (!elf_init_reloc_text_sym(file->elf, sec,
 					     idx * sizeof(int), idx,

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

* [tip: objtool/urgent] objtool: Fix CONFIG_OBJTOOL_WERROR for vmlinux.o
  2025-03-24 21:55 ` [PATCH 05/22] objtool: Fix CONFIG_OBJTOOL_WERROR for vmlinux.o Josh Poimboeuf
@ 2025-03-25  8:35   ` tip-bot2 for Josh Poimboeuf
  0 siblings, 0 replies; 75+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2025-03-25  8:35 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Josh Poimboeuf, Ingo Molnar, Linus Torvalds, x86, linux-kernel

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

Commit-ID:     4759670bc3e670069c055c2b33174813099fea4f
Gitweb:        https://git.kernel.org/tip/4759670bc3e670069c055c2b33174813099fea4f
Author:        Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate:    Mon, 24 Mar 2025 14:55:55 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Tue, 25 Mar 2025 09:20:26 +01:00

objtool: Fix CONFIG_OBJTOOL_WERROR for vmlinux.o

With (!X86_KERNEL_IBT && !LTO_CLANG && NOINSTR_VALIDATION), objtool runs
on both translation units and vmlinux.o.  With CONFIG_OBJTOOL_WERROR,
the TUs get --Werror but vmlinux.o doesn't.  Fix that.

Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/4f71ab9b947ffc47b6a87dd3b9aff4bb32b36d0a.1742852846.git.jpoimboe@kernel.org
---
 scripts/Makefile.vmlinux_o | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/scripts/Makefile.vmlinux_o b/scripts/Makefile.vmlinux_o
index 0b6e2eb..f476f56 100644
--- a/scripts/Makefile.vmlinux_o
+++ b/scripts/Makefile.vmlinux_o
@@ -30,12 +30,20 @@ endif
 # objtool for vmlinux.o
 # ---------------------------------------------------------------------------
 #
-# For LTO and IBT, objtool doesn't run on individual translation units.
-# Run everything on vmlinux instead.
+# For delay-objtool (IBT or LTO), objtool doesn't run on individual translation
+# units.  Instead it runs on vmlinux.o.
+#
+# For !delay-objtool + CONFIG_NOINSTR_VALIDATION, it runs on both translation
+# units and vmlinux.o, with the latter only used for noinstr/unret validation.
 
 objtool-enabled := $(or $(delay-objtool),$(CONFIG_NOINSTR_VALIDATION))
 
-vmlinux-objtool-args-$(delay-objtool)			+= $(objtool-args-y)
+ifeq ($(delay-objtool),y)
+vmlinux-objtool-args-y					+= $(objtool-args-y)
+else
+vmlinux-objtool-args-$(CONFIG_OBJTOOL_WERROR)		+= --Werror
+endif
+
 vmlinux-objtool-args-$(CONFIG_GCOV_KERNEL)		+= --no-unreachable
 vmlinux-objtool-args-$(CONFIG_NOINSTR_VALIDATION)	+= --noinstr \
 							   $(if $(or $(CONFIG_MITIGATION_UNRET_ENTRY),$(CONFIG_MITIGATION_SRSO)), --unret)

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

* [tip: objtool/urgent] objtool: Fix X86_FEATURE_SMAP alternative handling
  2025-03-24 21:55 ` [PATCH 04/22] objtool: Fix X86_FEATURE_SMAP alternative handling Josh Poimboeuf
@ 2025-03-25  8:35   ` tip-bot2 for Josh Poimboeuf
  0 siblings, 0 replies; 75+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2025-03-25  8:35 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: kernel test robot, Josh Poimboeuf, Ingo Molnar, Linus Torvalds,
	x86, linux-kernel

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

Commit-ID:     1154bbd326de4453858cf78cf29420888b3ffd52
Gitweb:        https://git.kernel.org/tip/1154bbd326de4453858cf78cf29420888b3ffd52
Author:        Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate:    Mon, 24 Mar 2025 14:55:54 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Tue, 25 Mar 2025 09:20:26 +01:00

objtool: Fix X86_FEATURE_SMAP alternative handling

For X86_FEATURE_SMAP alternatives which replace NOP with STAC or CLAC,
uaccess validation skips the NOP branch to avoid following impossible
code paths, e.g. where a STAC would be patched but a CLAC wouldn't.

However, it's not safe to assume an X86_FEATURE_SMAP alternative is
patching STAC/CLAC.  There can be other alternatives, like
static_cpu_has(), where both branches need to be validated.

Fix that by repurposing ANNOTATE_IGNORE_ALTERNATIVE for skipping either
original instructions or new ones.  This is a more generic approach
which enables the removal of the feature checking hacks and the
insn->ignore bit.

Fixes the following warnings:

  arch/x86/mm/fault.o: warning: objtool: do_user_addr_fault+0x8ec: __stack_chk_fail() missing __noreturn in .c/.h or NORETURN() in noreturns.h
  arch/x86/mm/fault.o: warning: objtool: do_user_addr_fault+0x8f1: unreachable instruction

[ mingo: Fix up conflicts with recent x86 changes. ]

Fixes: ea24213d8088 ("objtool: Add UACCESS validation")
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/de0621ca242130156a55d5d74fed86994dfa4c9c.1742852846.git.jpoimboe@kernel.org
Closes: https://lore.kernel.org/oe-kbuild-all/202503181736.zkZUBv4N-lkp@intel.com/
---
 arch/x86/include/asm/arch_hweight.h     |  6 ++--
 arch/x86/include/asm/smap.h             | 23 +++++++++-----
 arch/x86/include/asm/xen/hypercall.h    |  6 +---
 tools/objtool/arch/x86/special.c        | 33 +--------------------
 tools/objtool/check.c                   | 39 ++++++------------------
 tools/objtool/include/objtool/check.h   |  3 +-
 tools/objtool/include/objtool/special.h |  4 +--
 tools/objtool/special.c                 | 12 +------
 8 files changed, 37 insertions(+), 89 deletions(-)

diff --git a/arch/x86/include/asm/arch_hweight.h b/arch/x86/include/asm/arch_hweight.h
index b5982b9..cbc6157 100644
--- a/arch/x86/include/asm/arch_hweight.h
+++ b/arch/x86/include/asm/arch_hweight.h
@@ -16,7 +16,8 @@ static __always_inline unsigned int __arch_hweight32(unsigned int w)
 {
 	unsigned int res;
 
-	asm_inline (ALTERNATIVE("call __sw_hweight32",
+	asm_inline (ALTERNATIVE(ANNOTATE_IGNORE_ALTERNATIVE
+				"call __sw_hweight32",
 				"popcntl %[val], %[cnt]", X86_FEATURE_POPCNT)
 			 : [cnt] "=" REG_OUT (res), ASM_CALL_CONSTRAINT
 			 : [val] REG_IN (w));
@@ -45,7 +46,8 @@ static __always_inline unsigned long __arch_hweight64(__u64 w)
 {
 	unsigned long res;
 
-	asm_inline (ALTERNATIVE("call __sw_hweight64",
+	asm_inline (ALTERNATIVE(ANNOTATE_IGNORE_ALTERNATIVE
+				"call __sw_hweight64",
 				"popcntq %[val], %[cnt]", X86_FEATURE_POPCNT)
 			 : [cnt] "=" REG_OUT (res), ASM_CALL_CONSTRAINT
 			 : [val] REG_IN (w));
diff --git a/arch/x86/include/asm/smap.h b/arch/x86/include/asm/smap.h
index daea94c..55a5e65 100644
--- a/arch/x86/include/asm/smap.h
+++ b/arch/x86/include/asm/smap.h
@@ -16,23 +16,23 @@
 #ifdef __ASSEMBLER__
 
 #define ASM_CLAC \
-	ALTERNATIVE "", "clac", X86_FEATURE_SMAP
+	ALTERNATIVE __stringify(ANNOTATE_IGNORE_ALTERNATIVE), "clac", X86_FEATURE_SMAP
 
 #define ASM_STAC \
-	ALTERNATIVE "", "stac", X86_FEATURE_SMAP
+	ALTERNATIVE __stringify(ANNOTATE_IGNORE_ALTERNATIVE), "stac", X86_FEATURE_SMAP
 
 #else /* __ASSEMBLER__ */
 
 static __always_inline void clac(void)
 {
 	/* Note: a barrier is implicit in alternative() */
-	alternative("", "clac", X86_FEATURE_SMAP);
+	alternative(ANNOTATE_IGNORE_ALTERNATIVE "", "clac", X86_FEATURE_SMAP);
 }
 
 static __always_inline void stac(void)
 {
 	/* Note: a barrier is implicit in alternative() */
-	alternative("", "stac", X86_FEATURE_SMAP);
+	alternative(ANNOTATE_IGNORE_ALTERNATIVE "", "stac", X86_FEATURE_SMAP);
 }
 
 static __always_inline unsigned long smap_save(void)
@@ -40,7 +40,8 @@ static __always_inline unsigned long smap_save(void)
 	unsigned long flags;
 
 	asm volatile ("# smap_save\n\t"
-		      ALTERNATIVE("", "pushf; pop %0; " "clac" "\n\t",
+		      ALTERNATIVE(ANNOTATE_IGNORE_ALTERNATIVE
+				  "", "pushf; pop %0; clac",
 				  X86_FEATURE_SMAP)
 		      : "=rm" (flags) : : "memory", "cc");
 
@@ -50,16 +51,22 @@ static __always_inline unsigned long smap_save(void)
 static __always_inline void smap_restore(unsigned long flags)
 {
 	asm volatile ("# smap_restore\n\t"
-		      ALTERNATIVE("", "push %0; popf\n\t",
+		      ALTERNATIVE(ANNOTATE_IGNORE_ALTERNATIVE
+				  "", "push %0; popf",
 				  X86_FEATURE_SMAP)
 		      : : "g" (flags) : "memory", "cc");
 }
 
 /* These macros can be used in asm() statements */
 #define ASM_CLAC \
-	ALTERNATIVE("", "clac", X86_FEATURE_SMAP)
+	ALTERNATIVE(ANNOTATE_IGNORE_ALTERNATIVE "", "clac", X86_FEATURE_SMAP)
 #define ASM_STAC \
-	ALTERNATIVE("", "stac", X86_FEATURE_SMAP)
+	ALTERNATIVE(ANNOTATE_IGNORE_ALTERNATIVE "", "stac", X86_FEATURE_SMAP)
+
+#define ASM_CLAC_UNSAFE \
+	ALTERNATIVE("", ANNOTATE_IGNORE_ALTERNATIVE "clac", X86_FEATURE_SMAP)
+#define ASM_STAC_UNSAFE \
+	ALTERNATIVE("", ANNOTATE_IGNORE_ALTERNATIVE "stac", X86_FEATURE_SMAP)
 
 #endif /* __ASSEMBLER__ */
 
diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h
index 97771b9..59a62c3 100644
--- a/arch/x86/include/asm/xen/hypercall.h
+++ b/arch/x86/include/asm/xen/hypercall.h
@@ -231,14 +231,12 @@ static __always_inline void __xen_stac(void)
 	 * Suppress objtool seeing the STAC/CLAC and getting confused about it
 	 * calling random code with AC=1.
 	 */
-	asm volatile(ANNOTATE_IGNORE_ALTERNATIVE
-		     ASM_STAC ::: "memory", "flags");
+	asm volatile(ASM_STAC_UNSAFE ::: "memory", "flags");
 }
 
 static __always_inline void __xen_clac(void)
 {
-	asm volatile(ANNOTATE_IGNORE_ALTERNATIVE
-		     ASM_CLAC ::: "memory", "flags");
+	asm volatile(ASM_CLAC_UNSAFE ::: "memory", "flags");
 }
 
 static inline long
diff --git a/tools/objtool/arch/x86/special.c b/tools/objtool/arch/x86/special.c
index 5f46d4e..403e587 100644
--- a/tools/objtool/arch/x86/special.c
+++ b/tools/objtool/arch/x86/special.c
@@ -5,10 +5,7 @@
 #include <objtool/builtin.h>
 #include <objtool/warn.h>
 
-#define X86_FEATURE_POPCNT (4 * 32 + 23)
-#define X86_FEATURE_SMAP   (9 * 32 + 20)
-
-void arch_handle_alternative(unsigned short feature, struct special_alt *alt)
+void arch_handle_alternative(struct special_alt *alt)
 {
 	static struct special_alt *group, *prev;
 
@@ -32,34 +29,6 @@ void arch_handle_alternative(unsigned short feature, struct special_alt *alt)
 	} else group = alt;
 
 	prev = alt;
-
-	switch (feature) {
-	case X86_FEATURE_SMAP:
-		/*
-		 * If UACCESS validation is enabled; force that alternative;
-		 * otherwise force it the other way.
-		 *
-		 * What we want to avoid is having both the original and the
-		 * alternative code flow at the same time, in that case we can
-		 * find paths that see the STAC but take the NOP instead of
-		 * CLAC and the other way around.
-		 */
-		if (opts.uaccess)
-			alt->skip_orig = true;
-		else
-			alt->skip_alt = true;
-		break;
-	case X86_FEATURE_POPCNT:
-		/*
-		 * It has been requested that we don't validate the !POPCNT
-		 * feature path which is a "very very small percentage of
-		 * machines".
-		 */
-		alt->skip_orig = true;
-		break;
-	default:
-		break;
-	}
 }
 
 bool arch_support_alt_relocation(struct special_alt *special_alt,
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index f465020..b2f6a7f 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -25,7 +25,6 @@
 struct alternative {
 	struct alternative *next;
 	struct instruction *insn;
-	bool skip_orig;
 };
 
 static unsigned long nr_cfi, nr_cfi_reused, nr_cfi_cache;
@@ -1696,6 +1695,7 @@ static int handle_group_alt(struct objtool_file *file,
 		orig_alt_group->first_insn = orig_insn;
 		orig_alt_group->last_insn = last_orig_insn;
 		orig_alt_group->nop = NULL;
+		orig_alt_group->ignore = orig_insn->ignore_alts;
 	} else {
 		if (orig_alt_group->last_insn->offset + orig_alt_group->last_insn->len -
 		    orig_alt_group->first_insn->offset != special_alt->orig_len) {
@@ -1735,7 +1735,6 @@ static int handle_group_alt(struct objtool_file *file,
 		nop->type = INSN_NOP;
 		nop->sym = orig_insn->sym;
 		nop->alt_group = new_alt_group;
-		nop->ignore = orig_insn->ignore_alts;
 	}
 
 	if (!special_alt->new_len) {
@@ -1752,7 +1751,6 @@ static int handle_group_alt(struct objtool_file *file,
 
 		last_new_insn = insn;
 
-		insn->ignore = orig_insn->ignore_alts;
 		insn->sym = orig_insn->sym;
 		insn->alt_group = new_alt_group;
 
@@ -1799,6 +1797,7 @@ end:
 	new_alt_group->first_insn = *new_insn;
 	new_alt_group->last_insn = last_new_insn;
 	new_alt_group->nop = nop;
+	new_alt_group->ignore = (*new_insn)->ignore_alts;
 	new_alt_group->cfi = orig_alt_group->cfi;
 	return 0;
 }
@@ -1916,8 +1915,6 @@ static int add_special_section_alts(struct objtool_file *file)
 		}
 
 		alt->insn = new_insn;
-		alt->skip_orig = special_alt->skip_orig;
-		orig_insn->ignore_alts |= special_alt->skip_alt;
 		alt->next = orig_insn->alts;
 		orig_insn->alts = alt;
 
@@ -2295,6 +2292,8 @@ static int read_annotate(struct objtool_file *file,
 static int __annotate_early(struct objtool_file *file, int type, struct instruction *insn)
 {
 	switch (type) {
+
+	/* Must be before add_special_section_alts() */
 	case ANNOTYPE_IGNORE_ALTS:
 		insn->ignore_alts = true;
 		break;
@@ -3488,11 +3487,6 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
 			return 1;
 		}
 
-		if (func && insn->ignore) {
-			WARN_INSN(insn, "BUG: why am I validating an ignored function?");
-			return 1;
-		}
-
 		visited = VISITED_BRANCH << state.uaccess;
 		if (insn->visited & VISITED_BRANCH_MASK) {
 			if (!insn->hint && !insn_cfi_match(insn, &state.cfi))
@@ -3564,24 +3558,19 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
 		if (propagate_alt_cfi(file, insn))
 			return 1;
 
-		if (!insn->ignore_alts && insn->alts) {
-			bool skip_orig = false;
-
+		if (insn->alts) {
 			for (alt = insn->alts; alt; alt = alt->next) {
-				if (alt->skip_orig)
-					skip_orig = true;
-
 				ret = validate_branch(file, func, alt->insn, state);
 				if (ret) {
 					BT_INSN(insn, "(alt)");
 					return ret;
 				}
 			}
-
-			if (skip_orig)
-				return 0;
 		}
 
+		if (insn->alt_group && insn->alt_group->ignore)
+			return 0;
+
 		if (handle_insn_ops(insn, next_insn, &state))
 			return 1;
 
@@ -3768,23 +3757,15 @@ static int validate_unret(struct objtool_file *file, struct instruction *insn)
 
 		insn->visited |= VISITED_UNRET;
 
-		if (!insn->ignore_alts && insn->alts) {
+		if (insn->alts) {
 			struct alternative *alt;
-			bool skip_orig = false;
-
 			for (alt = insn->alts; alt; alt = alt->next) {
-				if (alt->skip_orig)
-					skip_orig = true;
-
 				ret = validate_unret(file, alt->insn);
 				if (ret) {
 					BT_INSN(insn, "(alt)");
 					return ret;
 				}
 			}
-
-			if (skip_orig)
-				return 0;
 		}
 
 		switch (insn->type) {
@@ -3935,7 +3916,7 @@ static bool ignore_unreachable_insn(struct objtool_file *file, struct instructio
 	struct instruction *prev_insn;
 	int i;
 
-	if (insn->ignore || insn->type == INSN_NOP || insn->type == INSN_TRAP || (func && func->ignore))
+	if (insn->type == INSN_NOP || insn->type == INSN_TRAP || (func && func->ignore))
 		return true;
 
 	/*
diff --git a/tools/objtool/include/objtool/check.h b/tools/objtool/include/objtool/check.h
index e1cd13c..00fb745 100644
--- a/tools/objtool/include/objtool/check.h
+++ b/tools/objtool/include/objtool/check.h
@@ -34,6 +34,8 @@ struct alt_group {
 	 * This is shared with the other alt_groups in the same alternative.
 	 */
 	struct cfi_state **cfi;
+
+	bool ignore;
 };
 
 #define INSN_CHUNK_BITS		8
@@ -54,7 +56,6 @@ struct instruction {
 
 	u32 idx			: INSN_CHUNK_BITS,
 	    dead_end		: 1,
-	    ignore		: 1,
 	    ignore_alts		: 1,
 	    hint		: 1,
 	    save		: 1,
diff --git a/tools/objtool/include/objtool/special.h b/tools/objtool/include/objtool/special.h
index e049679..72d09c0 100644
--- a/tools/objtool/include/objtool/special.h
+++ b/tools/objtool/include/objtool/special.h
@@ -16,8 +16,6 @@ struct special_alt {
 	struct list_head list;
 
 	bool group;
-	bool skip_orig;
-	bool skip_alt;
 	bool jump_or_nop;
 	u8 key_addend;
 
@@ -32,7 +30,7 @@ struct special_alt {
 
 int special_get_alts(struct elf *elf, struct list_head *alts);
 
-void arch_handle_alternative(unsigned short feature, struct special_alt *alt);
+void arch_handle_alternative(struct special_alt *alt);
 
 bool arch_support_alt_relocation(struct special_alt *special_alt,
 				 struct instruction *insn,
diff --git a/tools/objtool/special.c b/tools/objtool/special.c
index 097a69d..6cd7b1b 100644
--- a/tools/objtool/special.c
+++ b/tools/objtool/special.c
@@ -54,7 +54,7 @@ static const struct special_entry entries[] = {
 	{},
 };
 
-void __weak arch_handle_alternative(unsigned short feature, struct special_alt *alt)
+void __weak arch_handle_alternative(struct special_alt *alt)
 {
 }
 
@@ -92,15 +92,7 @@ static int get_alt_entry(struct elf *elf, const struct special_entry *entry,
 
 	reloc_to_sec_off(orig_reloc, &alt->orig_sec, &alt->orig_off);
 
-	if (entry->feature) {
-		unsigned short feature;
-
-		feature = bswap_if_needed(elf,
-					  *(unsigned short *)(sec->data->d_buf +
-							      offset +
-							      entry->feature));
-		arch_handle_alternative(feature, alt);
-	}
+	arch_handle_alternative(alt);
 
 	if (!entry->group || alt->new_len) {
 		new_reloc = find_reloc_by_dest(elf, sec, offset + entry->new);

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

* [tip: objtool/urgent] objtool: Warn when disabling unreachable warnings
  2025-03-24 21:55 ` [PATCH 02/22] objtool: Warn when disabling unreachable warnings Josh Poimboeuf
@ 2025-03-25  8:35   ` tip-bot2 for Josh Poimboeuf
  0 siblings, 0 replies; 75+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2025-03-25  8:35 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Josh Poimboeuf, Ingo Molnar, Linus Torvalds, x86, linux-kernel

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

Commit-ID:     eeff7ac61526a4a9c3916cf46885622078ad886b
Gitweb:        https://git.kernel.org/tip/eeff7ac61526a4a9c3916cf46885622078ad886b
Author:        Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate:    Mon, 24 Mar 2025 14:55:52 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Tue, 25 Mar 2025 09:20:25 +01:00

objtool: Warn when disabling unreachable warnings

Print a warning when disabling the unreachable warnings (due to a GCC
bug).  This will help determine if recent GCCs still have the issue and
alert us if any other issues might be silently lurking behind the
unreachable disablement.

Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/df243063787596e6031367e6659e7e43409d6c6d.1742852846.git.jpoimboe@kernel.org
---
 tools/objtool/arch/x86/special.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/tools/objtool/arch/x86/special.c b/tools/objtool/arch/x86/special.c
index 9c1c9df..5f46d4e 100644
--- a/tools/objtool/arch/x86/special.c
+++ b/tools/objtool/arch/x86/special.c
@@ -3,6 +3,7 @@
 
 #include <objtool/special.h>
 #include <objtool/builtin.h>
+#include <objtool/warn.h>
 
 #define X86_FEATURE_POPCNT (4 * 32 + 23)
 #define X86_FEATURE_SMAP   (9 * 32 + 20)
@@ -156,8 +157,10 @@ struct reloc *arch_find_switch_table(struct objtool_file *file,
 	 * indicates a rare GCC quirk/bug which can leave dead
 	 * code behind.
 	 */
-	if (reloc_type(text_reloc) == R_X86_64_PC32)
+	if (reloc_type(text_reloc) == R_X86_64_PC32) {
+		WARN_INSN(insn, "ignoring unreachables due to jump table quirk");
 		file->ignore_unreachables = true;
+	}
 
 	*table_size = 0;
 	return rodata_reloc;

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

* [tip: objtool/urgent] objtool: Ignore entire functions rather than instructions
  2025-03-24 21:55 ` [PATCH 03/22] objtool: Ignore entire functions rather than instructions Josh Poimboeuf
@ 2025-03-25  8:35   ` tip-bot2 for Josh Poimboeuf
  0 siblings, 0 replies; 75+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2025-03-25  8:35 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Josh Poimboeuf, Ingo Molnar, Linus Torvalds, x86, linux-kernel

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

Commit-ID:     c84301d706c5456b1460439b2987a0f0b6362a82
Gitweb:        https://git.kernel.org/tip/c84301d706c5456b1460439b2987a0f0b6362a82
Author:        Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate:    Mon, 24 Mar 2025 14:55:53 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Tue, 25 Mar 2025 09:20:25 +01:00

objtool: Ignore entire functions rather than instructions

STACK_FRAME_NON_STANDARD applies to functions.  Use a function-specific
ignore attribute in preparation for getting rid of insn->ignore.

Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/4af13376567f83331a9372ae2bb25e11a3d0f055.1742852846.git.jpoimboe@kernel.org
---
 tools/objtool/check.c               | 35 ++++++++++++++--------------
 tools/objtool/include/objtool/elf.h |  1 +-
 2 files changed, 19 insertions(+), 17 deletions(-)

diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index dae17ed..f465020 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -981,7 +981,6 @@ static int create_direct_call_sections(struct objtool_file *file)
  */
 static void add_ignores(struct objtool_file *file)
 {
-	struct instruction *insn;
 	struct section *rsec;
 	struct symbol *func;
 	struct reloc *reloc;
@@ -1008,8 +1007,7 @@ static void add_ignores(struct objtool_file *file)
 			continue;
 		}
 
-		func_for_each_insn(file, func, insn)
-			insn->ignore = true;
+		func->ignore = true;
 	}
 }
 
@@ -1612,6 +1610,7 @@ static int add_call_destinations(struct objtool_file *file)
 	struct reloc *reloc;
 
 	for_each_insn(file, insn) {
+		struct symbol *func = insn_func(insn);
 		if (insn->type != INSN_CALL)
 			continue;
 
@@ -1622,7 +1621,7 @@ static int add_call_destinations(struct objtool_file *file)
 
 			add_call_dest(file, insn, dest, false);
 
-			if (insn->ignore)
+			if (func && func->ignore)
 				continue;
 
 			if (!insn_call_dest(insn)) {
@@ -1630,7 +1629,7 @@ static int add_call_destinations(struct objtool_file *file)
 				return -1;
 			}
 
-			if (insn_func(insn) && insn_call_dest(insn)->type != STT_FUNC) {
+			if (func && insn_call_dest(insn)->type != STT_FUNC) {
 				WARN_INSN(insn, "unsupported call to non-function");
 				return -1;
 			}
@@ -3470,6 +3469,9 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
 	u8 visited;
 	int ret;
 
+	if (func && func->ignore)
+		return 0;
+
 	sec = insn->sec;
 
 	while (1) {
@@ -3715,7 +3717,7 @@ static int validate_unwind_hint(struct objtool_file *file,
 				  struct instruction *insn,
 				  struct insn_state *state)
 {
-	if (insn->hint && !insn->visited && !insn->ignore) {
+	if (insn->hint && !insn->visited) {
 		int ret = validate_branch(file, insn_func(insn), insn, *state);
 		if (ret)
 			BT_INSN(insn, "<=== (hint)");
@@ -3929,10 +3931,11 @@ static bool is_ubsan_insn(struct instruction *insn)
 
 static bool ignore_unreachable_insn(struct objtool_file *file, struct instruction *insn)
 {
-	int i;
+	struct symbol *func = insn_func(insn);
 	struct instruction *prev_insn;
+	int i;
 
-	if (insn->ignore || insn->type == INSN_NOP || insn->type == INSN_TRAP)
+	if (insn->ignore || insn->type == INSN_NOP || insn->type == INSN_TRAP || (func && func->ignore))
 		return true;
 
 	/*
@@ -3951,7 +3954,7 @@ static bool ignore_unreachable_insn(struct objtool_file *file, struct instructio
 	 * In this case we'll find a piece of code (whole function) that is not
 	 * covered by a !section symbol. Ignore them.
 	 */
-	if (opts.link && !insn_func(insn)) {
+	if (opts.link && !func) {
 		int size = find_symbol_hole_containing(insn->sec, insn->offset);
 		unsigned long end = insn->offset + size;
 
@@ -3977,19 +3980,17 @@ static bool ignore_unreachable_insn(struct objtool_file *file, struct instructio
 			 */
 			if (insn->jump_dest && insn_func(insn->jump_dest) &&
 			    strstr(insn_func(insn->jump_dest)->name, ".cold")) {
-				struct instruction *dest = insn->jump_dest;
-				func_for_each_insn(file, insn_func(dest), dest)
-					dest->ignore = true;
+				insn_func(insn->jump_dest)->ignore = true;
 			}
 		}
 
 		return false;
 	}
 
-	if (!insn_func(insn))
+	if (!func)
 		return false;
 
-	if (insn_func(insn)->static_call_tramp)
+	if (func->static_call_tramp)
 		return true;
 
 	/*
@@ -4020,7 +4021,7 @@ static bool ignore_unreachable_insn(struct objtool_file *file, struct instructio
 
 		if (insn->type == INSN_JUMP_UNCONDITIONAL) {
 			if (insn->jump_dest &&
-			    insn_func(insn->jump_dest) == insn_func(insn)) {
+			    insn_func(insn->jump_dest) == func) {
 				insn = insn->jump_dest;
 				continue;
 			}
@@ -4028,7 +4029,7 @@ static bool ignore_unreachable_insn(struct objtool_file *file, struct instructio
 			break;
 		}
 
-		if (insn->offset + insn->len >= insn_func(insn)->offset + insn_func(insn)->len)
+		if (insn->offset + insn->len >= func->offset + func->len)
 			break;
 
 		insn = next_insn_same_sec(file, insn);
@@ -4120,7 +4121,7 @@ static int validate_symbol(struct objtool_file *file, struct section *sec,
 		return 0;
 
 	insn = find_insn(file, sec, sym->offset);
-	if (!insn || insn->ignore || insn->visited)
+	if (!insn || insn->visited)
 		return 0;
 
 	state->uaccess = sym->uaccess_safe;
diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/objtool/elf.h
index 4edc957..eba0439 100644
--- a/tools/objtool/include/objtool/elf.h
+++ b/tools/objtool/include/objtool/elf.h
@@ -68,6 +68,7 @@ struct symbol {
 	u8 embedded_insn     : 1;
 	u8 local_label       : 1;
 	u8 frame_pointer     : 1;
+	u8 ignore	     : 1;
 	u8 warnings	     : 2;
 	struct list_head pv_target;
 	struct reloc *relocs;

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

* [tip: objtool/urgent] objtool: Fix detection of consecutive jump tables on Clang 20
  2025-03-24 21:55 ` [PATCH 01/22] objtool: Fix detection of consecutive jump tables Josh Poimboeuf
@ 2025-03-25  8:35   ` tip-bot2 for Josh Poimboeuf
  0 siblings, 0 replies; 75+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2025-03-25  8:35 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: kernel test robot, Josh Poimboeuf, Ingo Molnar, Nathan Chancellor,
	Nick Desaulniers, Linus Torvalds, x86, linux-kernel

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

Commit-ID:     ef753d66051ca03bee1982ce047f9eaf90f81ab4
Gitweb:        https://git.kernel.org/tip/ef753d66051ca03bee1982ce047f9eaf90f81ab4
Author:        Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate:    Mon, 24 Mar 2025 14:55:51 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Tue, 25 Mar 2025 09:20:25 +01:00

objtool: Fix detection of consecutive jump tables on Clang 20

The jump table detection code assumes jump tables are in the same order
as their corresponding indirect branches.  That's apparently not always
true with Clang 20.

Fix that by changing how multiple jump tables are detected.  In the
first detection pass, mark the beginning of each jump table so the
second pass can tell where one ends and the next one begins.

Fixes the following warnings:

  vmlinux.o: warning: objtool: SiS_GetCRT2Ptr+0x1ad: stack state mismatch: cfa1=4+8 cfa2=5+16
  sound/core/seq/snd-seq.o: warning: objtool: cc_ev_to_ump_midi2+0x589: return with modified stack frame

Fixes: be2f0b1e1264 ("objtool: Get rid of reloc->jump_table_start")
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nick Desaulniers <ndesaulniers@google.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/141752fff614eab962dba6bdfaa54aa67ff03bba.1742852846.git.jpoimboe@kernel.org
Closes: https://lore.kernel.org/oe-kbuild-all/202503171547.LlCTJLQL-lkp@intel.com/
Closes: https://lore.kernel.org/oe-kbuild-all/202503200535.J3hAvcjw-lkp@intel.com/
---
 tools/objtool/check.c               | 26 ++++++++------------------
 tools/objtool/elf.c                 |  6 +++---
 tools/objtool/include/objtool/elf.h | 27 ++++++++++++++++++++++++++-
 3 files changed, 37 insertions(+), 22 deletions(-)

diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index ca3435a..dae17ed 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -1941,8 +1941,7 @@ __weak unsigned long arch_jump_table_sym_offset(struct reloc *reloc, struct relo
 	return reloc->sym->offset + reloc_addend(reloc);
 }
 
-static int add_jump_table(struct objtool_file *file, struct instruction *insn,
-			  struct reloc *next_table)
+static int add_jump_table(struct objtool_file *file, struct instruction *insn)
 {
 	unsigned long table_size = insn_jump_table_size(insn);
 	struct symbol *pfunc = insn_func(insn)->pfunc;
@@ -1962,7 +1961,7 @@ static int add_jump_table(struct objtool_file *file, struct instruction *insn,
 		/* Check for the end of the table: */
 		if (table_size && reloc_offset(reloc) - reloc_offset(table) >= table_size)
 			break;
-		if (reloc != table && reloc == next_table)
+		if (reloc != table && is_jump_table(reloc))
 			break;
 
 		/* Make sure the table entries are consecutive: */
@@ -2053,8 +2052,10 @@ static void find_jump_table(struct objtool_file *file, struct symbol *func,
 		if (!dest_insn || !insn_func(dest_insn) || insn_func(dest_insn)->pfunc != func)
 			continue;
 
+		set_jump_table(table_reloc);
 		orig_insn->_jump_table = table_reloc;
 		orig_insn->_jump_table_size = table_size;
+
 		break;
 	}
 }
@@ -2096,31 +2097,20 @@ static void mark_func_jump_tables(struct objtool_file *file,
 static int add_func_jump_tables(struct objtool_file *file,
 				  struct symbol *func)
 {
-	struct instruction *insn, *insn_t1 = NULL, *insn_t2;
-	int ret = 0;
+	struct instruction *insn;
+	int ret;
 
 	func_for_each_insn(file, func, insn) {
 		if (!insn_jump_table(insn))
 			continue;
 
-		if (!insn_t1) {
-			insn_t1 = insn;
-			continue;
-		}
-
-		insn_t2 = insn;
 
-		ret = add_jump_table(file, insn_t1, insn_jump_table(insn_t2));
+		ret = add_jump_table(file, insn);
 		if (ret)
 			return ret;
-
-		insn_t1 = insn_t2;
 	}
 
-	if (insn_t1)
-		ret = add_jump_table(file, insn_t1, NULL);
-
-	return ret;
+	return 0;
 }
 
 /*
diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index be4f4b6..0f38167 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -583,7 +583,7 @@ static int elf_update_sym_relocs(struct elf *elf, struct symbol *sym)
 {
 	struct reloc *reloc;
 
-	for (reloc = sym->relocs; reloc; reloc = reloc->sym_next_reloc)
+	for (reloc = sym->relocs; reloc; reloc = sym_next_reloc(reloc))
 		set_reloc_sym(elf, reloc, reloc->sym->idx);
 
 	return 0;
@@ -880,7 +880,7 @@ static struct reloc *elf_init_reloc(struct elf *elf, struct section *rsec,
 	set_reloc_addend(elf, reloc, addend);
 
 	elf_hash_add(reloc, &reloc->hash, reloc_hash(reloc));
-	reloc->sym_next_reloc = sym->relocs;
+	set_sym_next_reloc(reloc, sym->relocs);
 	sym->relocs = reloc;
 
 	return reloc;
@@ -979,7 +979,7 @@ static int read_relocs(struct elf *elf)
 			}
 
 			elf_hash_add(reloc, &reloc->hash, reloc_hash(reloc));
-			reloc->sym_next_reloc = sym->relocs;
+			set_sym_next_reloc(reloc, sym->relocs);
 			sym->relocs = reloc;
 
 			nr_reloc++;
diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/objtool/elf.h
index 223ac1c..4edc957 100644
--- a/tools/objtool/include/objtool/elf.h
+++ b/tools/objtool/include/objtool/elf.h
@@ -77,7 +77,7 @@ struct reloc {
 	struct elf_hash_node hash;
 	struct section *sec;
 	struct symbol *sym;
-	struct reloc *sym_next_reloc;
+	unsigned long _sym_next_reloc;
 };
 
 struct elf {
@@ -297,6 +297,31 @@ static inline void set_reloc_type(struct elf *elf, struct reloc *reloc, unsigned
 	mark_sec_changed(elf, reloc->sec, true);
 }
 
+#define RELOC_JUMP_TABLE_BIT 1UL
+
+/* Does reloc mark the beginning of a jump table? */
+static inline bool is_jump_table(struct reloc *reloc)
+{
+	return reloc->_sym_next_reloc & RELOC_JUMP_TABLE_BIT;
+}
+
+static inline void set_jump_table(struct reloc *reloc)
+{
+	reloc->_sym_next_reloc |= RELOC_JUMP_TABLE_BIT;
+}
+
+static inline struct reloc *sym_next_reloc(struct reloc *reloc)
+{
+	return (struct reloc *)(reloc->_sym_next_reloc & ~RELOC_JUMP_TABLE_BIT);
+}
+
+static inline void set_sym_next_reloc(struct reloc *reloc, struct reloc *next)
+{
+	unsigned long bit = reloc->_sym_next_reloc & RELOC_JUMP_TABLE_BIT;
+
+	reloc->_sym_next_reloc = (unsigned long)next | bit;
+}
+
 #define for_each_sec(file, sec)						\
 	list_for_each_entry(sec, &file->elf->sections, list)
 

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

* Re: [tip: objtool/urgent] objtool, ASoC: codecs: wcd934x: Remove potential undefined behavior in wcd934x_slim_irq_handler()
  2025-03-25  8:34   ` [tip: objtool/urgent] objtool, ASoC: codecs: wcd934x: Remove potential " tip-bot2 for Josh Poimboeuf
@ 2025-03-25 11:32     ` Mark Brown
  2025-03-25 11:36       ` Ingo Molnar
  0 siblings, 1 reply; 75+ messages in thread
From: Mark Brown @ 2025-03-25 11:32 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-tip-commits, kernel test robot, Josh Poimboeuf, Ingo Molnar,
	Srinivas Kandagatla, Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
	Linus Torvalds, x86

[-- Attachment #1: Type: text/plain, Size: 837 bytes --]

On Tue, Mar 25, 2025 at 08:34:53AM -0000, tip-bot2 for Josh Poimboeuf wrote:
> The following commit has been merged into the objtool/urgent branch of tip:
> 
> Commit-ID:     46b70c569b774ea2c671bb3aff2a50d29760b7c3
> Gitweb:        https://git.kernel.org/tip/46b70c569b774ea2c671bb3aff2a50d29760b7c3
> Author:        Josh Poimboeuf <jpoimboe@kernel.org>
> AuthorDate:    Mon, 24 Mar 2025 14:56:09 -07:00
> Committer:     Ingo Molnar <mingo@kernel.org>
> CommitterDate: Tue, 25 Mar 2025 09:20:29 +01:00
> 
> objtool, ASoC: codecs: wcd934x: Remove potential undefined behavior in wcd934x_slim_irq_handler()

FWIW the original patch doesn't seem to have made it into my inbox (the
regmap one did), not that it makes a *huge* difference but might be some
infra/script issue which crops up on some other more urgent occasion.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [tip: objtool/urgent] objtool, ASoC: codecs: wcd934x: Remove potential undefined behavior in wcd934x_slim_irq_handler()
  2025-03-25 11:32     ` Mark Brown
@ 2025-03-25 11:36       ` Ingo Molnar
  2025-03-25 13:12         ` Mark Brown
  0 siblings, 1 reply; 75+ messages in thread
From: Ingo Molnar @ 2025-03-25 11:36 UTC (permalink / raw)
  To: Mark Brown
  Cc: linux-kernel, linux-tip-commits, kernel test robot,
	Josh Poimboeuf, Srinivas Kandagatla, Liam Girdwood,
	Jaroslav Kysela, Takashi Iwai, Linus Torvalds, x86


* Mark Brown <broonie@kernel.org> wrote:

> On Tue, Mar 25, 2025 at 08:34:53AM -0000, tip-bot2 for Josh Poimboeuf wrote:
> > The following commit has been merged into the objtool/urgent branch of tip:
> > 
> > Commit-ID:     46b70c569b774ea2c671bb3aff2a50d29760b7c3
> > Gitweb:        https://git.kernel.org/tip/46b70c569b774ea2c671bb3aff2a50d29760b7c3
> > Author:        Josh Poimboeuf <jpoimboe@kernel.org>
> > AuthorDate:    Mon, 24 Mar 2025 14:56:09 -07:00
> > Committer:     Ingo Molnar <mingo@kernel.org>
> > CommitterDate: Tue, 25 Mar 2025 09:20:29 +01:00
> > 
> > objtool, ASoC: codecs: wcd934x: Remove potential undefined behavior in wcd934x_slim_irq_handler()
> 
> FWIW the original patch doesn't seem to have made it into my inbox 
> (the regmap one did), not that it makes a *huge* difference but might 
> be some infra/script issue which crops up on some other more urgent 
> occasion.

Yeah, I noticed that the Cc: lines were incomplete for some of the 
patches, so before applying them I went over the series and regenerated 
the Cc: lines so everyone is informed and can review/object/ack if 
necessary.

If there's any serious mistake we'll rebase the branch!

Thanks,

	Ingo

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

* Re: [tip: objtool/urgent] objtool, ASoC: codecs: wcd934x: Remove potential undefined behavior in wcd934x_slim_irq_handler()
  2025-03-25 11:36       ` Ingo Molnar
@ 2025-03-25 13:12         ` Mark Brown
  0 siblings, 0 replies; 75+ messages in thread
From: Mark Brown @ 2025-03-25 13:12 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, linux-tip-commits, kernel test robot,
	Josh Poimboeuf, Srinivas Kandagatla, Liam Girdwood,
	Jaroslav Kysela, Takashi Iwai, Linus Torvalds, x86

[-- Attachment #1: Type: text/plain, Size: 766 bytes --]

On Tue, Mar 25, 2025 at 12:36:11PM +0100, Ingo Molnar wrote:

> > FWIW the original patch doesn't seem to have made it into my inbox 
> > (the regmap one did), not that it makes a *huge* difference but might 
> > be some infra/script issue which crops up on some other more urgent 
> > occasion.

> Yeah, I noticed that the Cc: lines were incomplete for some of the 
> patches, so before applying them I went over the series and regenerated 
> the Cc: lines so everyone is informed and can review/object/ack if 
> necessary.

> If there's any serious mistake we'll rebase the branch!

No problem here, just wanted to flag the potential infra thing.  I
didn't bother acking since the patches were applied:

Acked-by: Mark Brown <broonie@kernel.org>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [tip: objtool/urgent] objtool, spi: amd: Fix out-of-bounds stack access in amd_set_spi_freq()
  2025-03-25  8:34   ` [tip: objtool/urgent] objtool, " tip-bot2 for Josh Poimboeuf
@ 2025-03-25 13:13     ` Mark Brown
  0 siblings, 0 replies; 75+ messages in thread
From: Mark Brown @ 2025-03-25 13:13 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-tip-commits, kernel test robot, Josh Poimboeuf, Ingo Molnar,
	Raju Rangoju, Linus Torvalds, x86

[-- Attachment #1: Type: text/plain, Size: 557 bytes --]

On Tue, Mar 25, 2025 at 08:34:58AM -0000, tip-bot2 for Josh Poimboeuf wrote:
> The following commit has been merged into the objtool/urgent branch of tip:
> 
> Commit-ID:     0239716b82b75dc5cb64c5ec5405dac6c3448d48
> Gitweb:        https://git.kernel.org/tip/0239716b82b75dc5cb64c5ec5405dac6c3448d48
> Author:        Josh Poimboeuf <jpoimboe@kernel.org>
> AuthorDate:    Mon, 24 Mar 2025 14:56:04 -07:00
> Committer:     Ingo Molnar <mingo@kernel.org>
> CommitterDate: Tue, 25 Mar 2025 09:20:28 +01:00

Acked-by: Mark Brown <broonie@kernel.org>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [tip: objtool/urgent] objtool, regulator: rk808: Remove potential undefined behavior in rk806_set_mode_dcdc()
  2025-03-25  8:34   ` [tip: objtool/urgent] objtool, regulator: rk808: Remove potential " tip-bot2 for Josh Poimboeuf
@ 2025-03-25 13:17     ` Mark Brown
  0 siblings, 0 replies; 75+ messages in thread
From: Mark Brown @ 2025-03-25 13:17 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-tip-commits, kernel test robot, Josh Poimboeuf, Ingo Molnar,
	Liam Girdwood, Linus Torvalds, x86

[-- Attachment #1: Type: text/plain, Size: 557 bytes --]

On Tue, Mar 25, 2025 at 08:34:52AM -0000, tip-bot2 for Josh Poimboeuf wrote:
> The following commit has been merged into the objtool/urgent branch of tip:
> 
> Commit-ID:     4d014a6b8e4dba75eb0b99e6ed990bb7e38da294
> Gitweb:        https://git.kernel.org/tip/4d014a6b8e4dba75eb0b99e6ed990bb7e38da294
> Author:        Josh Poimboeuf <jpoimboe@kernel.org>
> AuthorDate:    Mon, 24 Mar 2025 14:56:10 -07:00
> Committer:     Ingo Molnar <mingo@kernel.org>
> CommitterDate: Tue, 25 Mar 2025 09:20:29 +01:00

Acked-by: Mark Brown <broonie@kernel.org>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH 22/22] lkdtm: Obfuscate do_nothing() pointer
  2025-03-24 21:56 ` [PATCH 22/22] lkdtm: Obfuscate do_nothing() pointer Josh Poimboeuf
  2025-03-25  8:34   ` [tip: objtool/urgent] objtool, lkdtm: Obfuscate the " tip-bot2 for Josh Poimboeuf
@ 2025-03-25 19:39   ` Kees Cook
  2025-03-25 22:09   ` [tip: objtool/urgent] objtool, lkdtm: Obfuscate the " tip-bot2 for Josh Poimboeuf
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 75+ messages in thread
From: Kees Cook @ 2025-03-25 19:39 UTC (permalink / raw)
  To: Josh Poimboeuf
  Cc: x86, linux-kernel, Peter Zijlstra, Ingo Molnar, Miroslav Benes,
	Brendan Jackman, Nathan Chancellor, kernel test robot

On Mon, Mar 24, 2025 at 02:56:12PM -0700, Josh Poimboeuf wrote:
> If execute_location()'s memcpy of do_nothing() gets inlined and unrolled
> by the compiler, it copies one word at a time:
> 
>     mov    0x0(%rip),%rax    R_X86_64_PC32    .text+0x1374
>     mov    %rax,0x38(%rbx)
>     mov    0x0(%rip),%rax    R_X86_64_PC32    .text+0x136c
>     mov    %rax,0x30(%rbx)
>     ...
> 
> Those .text references point to the middle of the function, causing
> objtool to complain about their lack of ENDBR.
> 
> Prevent that by resolving the function pointer at runtime rather than
> build time.  This fixes the following warning:
> 
>   drivers/misc/lkdtm/lkdtm.o: warning: objtool: execute_location+0x23: relocation to !ENDBR: .text+0x1378
> 
> Cc: Kees Cook <kees@kernel.org>
> Reported-by: kernel test robot <lkp@intel.com>
> Closes: https://lore.kernel.org/oe-kbuild-all/202503191453.uFfxQy5R-lkp@intel.com/
> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>

Thanks!

Reviewed-by: Kees Cook <kees@kernel.org>

-- 
Kees Cook

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

* [tip: objtool/urgent] objtool, lkdtm: Obfuscate the do_nothing() pointer
  2025-03-24 21:56 ` [PATCH 22/22] lkdtm: Obfuscate do_nothing() pointer Josh Poimboeuf
  2025-03-25  8:34   ` [tip: objtool/urgent] objtool, lkdtm: Obfuscate the " tip-bot2 for Josh Poimboeuf
  2025-03-25 19:39   ` [PATCH 22/22] lkdtm: Obfuscate " Kees Cook
@ 2025-03-25 22:09   ` tip-bot2 for Josh Poimboeuf
  2025-03-27 11:06   ` tip-bot2 for Josh Poimboeuf
  2025-03-28 13:48   ` tip-bot2 for Josh Poimboeuf
  4 siblings, 0 replies; 75+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2025-03-25 22:09 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: kernel test robot, Josh Poimboeuf, Ingo Molnar, Kees Cook,
	Arnd Bergmann, Greg Kroah-Hartman, Linus Torvalds, x86,
	linux-kernel

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

Commit-ID:     26d2ab43acdd1fd5fab3c3abb0b79d7ff14fedaa
Gitweb:        https://git.kernel.org/tip/26d2ab43acdd1fd5fab3c3abb0b79d7ff14fedaa
Author:        Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate:    Mon, 24 Mar 2025 14:56:12 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Tue, 25 Mar 2025 23:00:45 +01:00

objtool, lkdtm: Obfuscate the do_nothing() pointer

If execute_location()'s memcpy of do_nothing() gets inlined and unrolled
by the compiler, it copies one word at a time:

    mov    0x0(%rip),%rax    R_X86_64_PC32    .text+0x1374
    mov    %rax,0x38(%rbx)
    mov    0x0(%rip),%rax    R_X86_64_PC32    .text+0x136c
    mov    %rax,0x30(%rbx)
    ...

Those .text references point to the middle of the function, causing
objtool to complain about their lack of ENDBR.

Prevent that by resolving the function pointer at runtime rather than
build time.  This fixes the following warning:

  drivers/misc/lkdtm/lkdtm.o: warning: objtool: execute_location+0x23: relocation to !ENDBR: .text+0x1378

Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Kees Cook <kees@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/30b9abffbddeb43c4f6320b1270fa9b4d74c54ed.1742852847.git.jpoimboe@kernel.org
Closes: https://lore.kernel.org/oe-kbuild-all/202503191453.uFfxQy5R-lkp@intel.com/
---
 drivers/misc/lkdtm/perms.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
index 5b861db..6c24426 100644
--- a/drivers/misc/lkdtm/perms.c
+++ b/drivers/misc/lkdtm/perms.c
@@ -29,6 +29,13 @@ static const unsigned long rodata = 0xAA55AA55;
 static unsigned long ro_after_init __ro_after_init = 0x55AA5500;
 
 /*
+ * This is a pointer to do_nothing() which is initialized at runtime rather
+ * than build time to avoid objtool IBT validation warnings caused by an
+ * inlined unrolled memcpy() in execute_location().
+ */
+static void __ro_after_init *do_nothing_ptr;
+
+/*
  * This just returns to the caller. It is designed to be copied into
  * non-executable memory regions.
  */
@@ -65,13 +72,12 @@ static noinline __nocfi void execute_location(void *dst, bool write)
 {
 	void (*func)(void);
 	func_desc_t fdesc;
-	void *do_nothing_text = dereference_function_descriptor(do_nothing);
 
-	pr_info("attempting ok execution at %px\n", do_nothing_text);
+	pr_info("attempting ok execution at %px\n", do_nothing_ptr);
 	do_nothing();
 
 	if (write == CODE_WRITE) {
-		memcpy(dst, do_nothing_text, EXEC_SIZE);
+		memcpy(dst, do_nothing_ptr, EXEC_SIZE);
 		flush_icache_range((unsigned long)dst,
 				   (unsigned long)dst + EXEC_SIZE);
 	}
@@ -267,6 +273,8 @@ static void lkdtm_ACCESS_NULL(void)
 
 void __init lkdtm_perms_init(void)
 {
+	do_nothing_ptr = dereference_function_descriptor(do_nothing);
+
 	/* Make sure we can write to __ro_after_init values during __init */
 	ro_after_init |= 0xAA;
 }

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

* [tip: objtool/urgent] objtool, pwm: mediatek: Prevent theoretical divide-by-zero in pwm_mediatek_config()
  2025-03-24 21:56 ` [PATCH 21/22] pwm: mediatek: Prevent divide-by-zero in pwm_mediatek_config() Josh Poimboeuf
  2025-03-25  8:34   ` [tip: objtool/urgent] objtool, pwm: mediatek: Prevent theoretical " tip-bot2 for Josh Poimboeuf
@ 2025-03-25 22:09   ` tip-bot2 for Josh Poimboeuf
  2025-03-27 11:06   ` tip-bot2 for Josh Poimboeuf
  2 siblings, 0 replies; 75+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2025-03-25 22:09 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Josh Poimboeuf, Ingo Molnar, ukleinek, Linus Torvalds, x86,
	linux-kernel

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

Commit-ID:     2dad2ba8f2487de932d503a6cd1095c31b2261c9
Gitweb:        https://git.kernel.org/tip/2dad2ba8f2487de932d503a6cd1095c31b2261c9
Author:        Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate:    Mon, 24 Mar 2025 14:56:11 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Tue, 25 Mar 2025 23:00:44 +01:00

objtool, pwm: mediatek: Prevent theoretical divide-by-zero in pwm_mediatek_config()

With CONFIG_COMPILE_TEST && !CONFIG_CLK, pwm_mediatek_config() has a
divide-by-zero in the following line:

	do_div(resolution, clk_get_rate(pc->clk_pwms[pwm->hwpwm]));

due to the fact that the !CONFIG_CLK version of clk_get_rate() returns
zero.

This is presumably just a theoretical problem: COMPILE_TEST overrides
the dependency on RALINK which would select COMMON_CLK.  Regardless it's
a good idea to check for the error explicitly to avoid divide-by-zero.

Fixes the following warning:

  drivers/pwm/pwm-mediatek.o: warning: objtool: .text: unexpected end of section

Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: "Uwe Kleine-König" <ukleinek@kernel.org> (maintainer:PWM SUBSYSTEM)
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/fb56444939325cc173e752ba199abd7aeae3bf12.1742852847.git.jpoimboe@kernel.org
---
 drivers/pwm/pwm-mediatek.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
index 01dfa0f..7eaab58 100644
--- a/drivers/pwm/pwm-mediatek.c
+++ b/drivers/pwm/pwm-mediatek.c
@@ -121,21 +121,25 @@ static int pwm_mediatek_config(struct pwm_chip *chip, struct pwm_device *pwm,
 	struct pwm_mediatek_chip *pc = to_pwm_mediatek_chip(chip);
 	u32 clkdiv = 0, cnt_period, cnt_duty, reg_width = PWMDWIDTH,
 	    reg_thres = PWMTHRES;
+	unsigned long clk_rate;
 	u64 resolution;
 	int ret;
 
 	ret = pwm_mediatek_clk_enable(chip, pwm);
-
 	if (ret < 0)
 		return ret;
 
+	clk_rate = clk_get_rate(pc->clk_pwms[pwm->hwpwm]);
+	if (!clk_rate)
+		return -EINVAL;
+
 	/* Make sure we use the bus clock and not the 26MHz clock */
 	if (pc->soc->has_ck_26m_sel)
 		writel(0, pc->regs + PWM_CK_26M_SEL);
 
 	/* Using resolution in picosecond gets accuracy higher */
 	resolution = (u64)NSEC_PER_SEC * 1000;
-	do_div(resolution, clk_get_rate(pc->clk_pwms[pwm->hwpwm]));
+	do_div(resolution, clk_rate);
 
 	cnt_period = DIV_ROUND_CLOSEST_ULL((u64)period_ns * 1000, resolution);
 	while (cnt_period > 8191) {

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

* [tip: objtool/urgent] objtool, regulator: rk808: Remove potential undefined behavior in rk806_set_mode_dcdc()
  2025-03-24 21:56 ` [PATCH 20/22] regulator: rk808: Remove undefined behavior in rk806_set_mode_dcdc() Josh Poimboeuf
  2025-03-25  8:34   ` [tip: objtool/urgent] objtool, regulator: rk808: Remove potential " tip-bot2 for Josh Poimboeuf
@ 2025-03-25 22:09   ` tip-bot2 for Josh Poimboeuf
  1 sibling, 0 replies; 75+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2025-03-25 22:09 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: kernel test robot, Josh Poimboeuf, Ingo Molnar, Mark Brown,
	Liam Girdwood, Linus Torvalds, x86, linux-kernel

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

Commit-ID:     29c578c848402a34e8c8e115bf66cb6008b77062
Gitweb:        https://git.kernel.org/tip/29c578c848402a34e8c8e115bf66cb6008b77062
Author:        Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate:    Mon, 24 Mar 2025 14:56:10 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Tue, 25 Mar 2025 23:00:29 +01:00

objtool, regulator: rk808: Remove potential undefined behavior in rk806_set_mode_dcdc()

If 'ctr_bit' is negative, the shift counts become negative, causing a
shift of bounds and undefined behavior.

Presumably that's not possible in normal operation, but the code
generation isn't optimal.  And undefined behavior should be avoided
regardless.

Improve code generation and remove the undefined behavior by converting
the signed variables to unsigned.

Fixes the following warning with an UBSAN kernel:

  vmlinux.o: warning: objtool: rk806_set_mode_dcdc() falls through to next function rk806_get_mode_dcdc()
  vmlinux.o: warning: objtool: .text.rk806_set_mode_dcdc: unexpected end of section

Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Acked-by: Mark Brown <broonie@kernel.org>
Cc: Liam Girdwood <lgirdwood@gmail.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/2023abcddf3f524ba478d64339996f25dc4097d2.1742852847.git.jpoimboe@kernel.org
Closes: https://lore.kernel.org/oe-kbuild-all/202503182350.52KeHGD4-lkp@intel.com/
---
 drivers/regulator/rk808-regulator.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c
index 7d82bd1..1e81424 100644
--- a/drivers/regulator/rk808-regulator.c
+++ b/drivers/regulator/rk808-regulator.c
@@ -270,8 +270,8 @@ static const unsigned int rk817_buck1_4_ramp_table[] = {
 
 static int rk806_set_mode_dcdc(struct regulator_dev *rdev, unsigned int mode)
 {
-	int rid = rdev_get_id(rdev);
-	int ctr_bit, reg;
+	unsigned int rid = rdev_get_id(rdev);
+	unsigned int ctr_bit, reg;
 
 	reg = RK806_POWER_FPWM_EN0 + rid / 8;
 	ctr_bit = rid % 8;

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

* [tip: objtool/urgent] objtool, ASoC: codecs: wcd934x: Remove potential undefined behavior in wcd934x_slim_irq_handler()
  2025-03-24 21:56 ` [PATCH 19/22] ASoC: codecs: wcd934x: Remove undefined behavior in wcd934x_slim_irq_handler() Josh Poimboeuf
  2025-03-25  8:34   ` [tip: objtool/urgent] objtool, ASoC: codecs: wcd934x: Remove potential " tip-bot2 for Josh Poimboeuf
@ 2025-03-25 22:09   ` tip-bot2 for Josh Poimboeuf
  1 sibling, 0 replies; 75+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2025-03-25 22:09 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: kernel test robot, Josh Poimboeuf, Ingo Molnar, Mark Brown,
	Srinivas Kandagatla, Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
	Linus Torvalds, x86, linux-kernel

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

Commit-ID:     060aed9c0093b341480770457093449771cf1496
Gitweb:        https://git.kernel.org/tip/060aed9c0093b341480770457093449771cf1496
Author:        Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate:    Mon, 24 Mar 2025 14:56:09 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Tue, 25 Mar 2025 23:00:16 +01:00

objtool, ASoC: codecs: wcd934x: Remove potential undefined behavior in wcd934x_slim_irq_handler()

If 'port_id' is negative, the shift counts in wcd934x_slim_irq_handler()
also become negative, resulting in undefined behavior due to shift out
of bounds.

If I'm reading the code correctly, that appears to be not possible, but
with KCOV enabled, Clang's range analysis isn't always able to determine
that and generates undefined behavior.

As a result the code generation isn't optimal, and undefined behavior
should be avoided regardless.  Improve code generation and remove the
undefined behavior by converting the signed variables to unsigned.

Fixes the following warning with UBSAN:

  sound/soc/codecs/snd-soc-wcd934x.o: warning: objtool: .text.wcd934x_slim_irq_handler: unexpected end of section

Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Acked-by: Mark Brown <broonie@kernel.org>
Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Cc: Liam Girdwood <lgirdwood@gmail.com>
Cc: Jaroslav Kysela <perex@perex.cz>
Cc: Takashi Iwai <tiwai@suse.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/7e863839ec7301bf9c0f429a03873d44e484c31c.1742852847.git.jpoimboe@kernel.org
Closes: https://lore.kernel.org/oe-kbuild-all/202503180044.oH9gyPeg-lkp@intel.com/
---
 sound/soc/codecs/wcd934x.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/soc/codecs/wcd934x.c b/sound/soc/codecs/wcd934x.c
index 910852e..c7f1b28 100644
--- a/sound/soc/codecs/wcd934x.c
+++ b/sound/soc/codecs/wcd934x.c
@@ -2273,7 +2273,7 @@ static irqreturn_t wcd934x_slim_irq_handler(int irq, void *data)
 {
 	struct wcd934x_codec *wcd = data;
 	unsigned long status = 0;
-	int i, j, port_id;
+	unsigned int i, j, port_id;
 	unsigned int val, int_val = 0;
 	irqreturn_t ret = IRQ_NONE;
 	bool tx;

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

* [tip: objtool/urgent] objtool, Input: cyapa - Remove undefined behavior in cyapa_update_fw_store()
  2025-03-24 21:56 ` [PATCH 18/22] Input: cyapa - remove undefined behavior in cyapa_update_fw_store() Josh Poimboeuf
  2025-03-25  8:34   ` [tip: objtool/urgent] objtool, Input: cyapa - Remove " tip-bot2 for Josh Poimboeuf
@ 2025-03-25 22:09   ` tip-bot2 for Josh Poimboeuf
  1 sibling, 0 replies; 75+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2025-03-25 22:09 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: kernel test robot, Josh Poimboeuf, Ingo Molnar, Dmitry Torokhov,
	Linus Torvalds, x86, linux-kernel

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

Commit-ID:     7501153750b47416c9891038330359fad0205839
Gitweb:        https://git.kernel.org/tip/7501153750b47416c9891038330359fad0205839
Author:        Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate:    Mon, 24 Mar 2025 14:56:08 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Tue, 25 Mar 2025 23:00:15 +01:00

objtool, Input: cyapa - Remove undefined behavior in cyapa_update_fw_store()

In cyapa_update_fw_store(), if 'count' is zero, the write to
fw_name[count-1] underflows the array.

Presumably that's not possible in normal operation, as its caller
sysfs_kf_write() already checks for zero.  Regardless it's a good idea
to check for the error explicitly and avoid undefined behavior.

Fixes the following warning with an UBSAN kernel:

  vmlinux.o: warning: objtool: .text.cyapa_update_fw_store: unexpected end of section

Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/73ae0bb3c656735890d914b74c9d6bb40c25d3cd.1742852847.git.jpoimboe@kernel.org
Closes: https://lore.kernel.org/oe-kbuild-all/202503171547.LlCTJLQL-lkp@intel.com/
---
 drivers/input/mouse/cyapa.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/input/mouse/cyapa.c b/drivers/input/mouse/cyapa.c
index 2f2d925..00c87c0 100644
--- a/drivers/input/mouse/cyapa.c
+++ b/drivers/input/mouse/cyapa.c
@@ -1080,8 +1080,8 @@ static ssize_t cyapa_update_fw_store(struct device *dev,
 	char fw_name[NAME_MAX];
 	int ret, error;
 
-	if (count >= NAME_MAX) {
-		dev_err(dev, "File name too long\n");
+	if (!count || count >= NAME_MAX) {
+		dev_err(dev, "Bad file name size\n");
 		return -EINVAL;
 	}
 

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

* [tip: objtool/urgent] objtool, panic: Disable SMAP in __stack_chk_fail()
  2025-03-24 21:56 ` [PATCH 17/22] panic: Disable SMAP in __stack_chk_fail() Josh Poimboeuf
  2025-03-25  8:34   ` [tip: objtool/urgent] objtool, " tip-bot2 for Josh Poimboeuf
@ 2025-03-25 22:09   ` tip-bot2 for Josh Poimboeuf
  1 sibling, 0 replies; 75+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2025-03-25 22:09 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Josh Poimboeuf, Ingo Molnar, Kees Cook, Andrew Morton,
	Linus Torvalds, x86, linux-kernel

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

Commit-ID:     72c774aa9d1e16bfd247096935e7dae194d84929
Gitweb:        https://git.kernel.org/tip/72c774aa9d1e16bfd247096935e7dae194d84929
Author:        Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate:    Mon, 24 Mar 2025 14:56:07 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Tue, 25 Mar 2025 23:00:15 +01:00

objtool, panic: Disable SMAP in __stack_chk_fail()

__stack_chk_fail() can be called from uaccess-enabled code.  Make sure
uaccess gets disabled before calling panic().

Fixes the following warning:

  kernel/trace/trace_branch.o: error: objtool: ftrace_likely_update+0x1ea: call to __stack_chk_fail() with UACCESS enabled

Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Kees Cook <keescook@chromium.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/a3e97e0119e1b04c725a8aa05f7bc83d98e657eb.1742852847.git.jpoimboe@kernel.org
---
 kernel/panic.c        | 6 ++++++
 tools/objtool/check.c | 5 ++++-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/kernel/panic.c b/kernel/panic.c
index d8635d5..f9f0c51 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -832,9 +832,15 @@ device_initcall(register_warn_debugfs);
  */
 __visible noinstr void __stack_chk_fail(void)
 {
+	unsigned long flags;
+
 	instrumentation_begin();
+	flags = user_access_save();
+
 	panic("stack-protector: Kernel stack is corrupted in: %pB",
 		__builtin_return_address(0));
+
+	user_access_restore(flags);
 	instrumentation_end();
 }
 EXPORT_SYMBOL(__stack_chk_fail);
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 0caabf0..3bf2992 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -1194,12 +1194,15 @@ static const char *uaccess_safe_builtin[] = {
 	"__ubsan_handle_load_invalid_value",
 	/* STACKLEAK */
 	"stackleak_track_stack",
+	/* TRACE_BRANCH_PROFILING */
+	"ftrace_likely_update",
+	/* STACKPROTECTOR */
+	"__stack_chk_fail",
 	/* misc */
 	"csum_partial_copy_generic",
 	"copy_mc_fragile",
 	"copy_mc_fragile_handle_tail",
 	"copy_mc_enhanced_fast_string",
-	"ftrace_likely_update", /* CONFIG_TRACE_BRANCH_PROFILING */
 	"rep_stos_alternative",
 	"rep_movs_alternative",
 	"__copy_user_nocache",

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

* [tip: objtool/urgent] objtool, media: dib8000: Prevent divide-by-zero in dib8000_set_dds()
  2025-03-24 21:56 ` [PATCH 16/22] media: dib8000: Prevent divide-by-zero in dib8000_set_dds() Josh Poimboeuf
  2025-03-25  8:34   ` [tip: objtool/urgent] objtool, " tip-bot2 for Josh Poimboeuf
@ 2025-03-25 22:09   ` tip-bot2 for Josh Poimboeuf
  2025-03-25 22:42     ` Mauro Carvalho Chehab
  1 sibling, 1 reply; 75+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2025-03-25 22:09 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: kernel test robot, Josh Poimboeuf, Ingo Molnar,
	Mauro Carvalho Chehab, Linus Torvalds, x86, linux-kernel

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

Commit-ID:     e63d465f59011dede0a0f1d21718b59a64c3ff5c
Gitweb:        https://git.kernel.org/tip/e63d465f59011dede0a0f1d21718b59a64c3ff5c
Author:        Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate:    Mon, 24 Mar 2025 14:56:06 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Tue, 25 Mar 2025 23:00:15 +01:00

objtool, media: dib8000: Prevent divide-by-zero in dib8000_set_dds()

If dib8000_set_dds()'s call to dib8000_read32() returns zero, the result
is a divide-by-zero.  Prevent that from happening.

Fixes the following warning with an UBSAN kernel:

  drivers/media/dvb-frontends/dib8000.o: warning: objtool: dib8000_tune() falls through to next function dib8096p_cfg_DibRx()

Fixes: 173a64cb3fcf ("[media] dib8000: enhancement")
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/bd1d504d930ae3f073b1e071bcf62cae7708773c.1742852847.git.jpoimboe@kernel.org
Closes: https://lore.kernel.org/r/202503210602.fvH5DO1i-lkp@intel.com/
---
 drivers/media/dvb-frontends/dib8000.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/media/dvb-frontends/dib8000.c b/drivers/media/dvb-frontends/dib8000.c
index 2f51659..cfe59c3 100644
--- a/drivers/media/dvb-frontends/dib8000.c
+++ b/drivers/media/dvb-frontends/dib8000.c
@@ -2701,8 +2701,11 @@ static void dib8000_set_dds(struct dib8000_state *state, s32 offset_khz)
 	u8 ratio;
 
 	if (state->revision == 0x8090) {
+		u32 internal = dib8000_read32(state, 23) / 1000;
+
 		ratio = 4;
-		unit_khz_dds_val = (1<<26) / (dib8000_read32(state, 23) / 1000);
+
+		unit_khz_dds_val = (1<<26) / (internal ?: 1);
 		if (offset_khz < 0)
 			dds = (1 << 26) - (abs_offset_khz * unit_khz_dds_val);
 		else

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

* [tip: objtool/urgent] objtool, nvmet: Fix out-of-bounds stack access in nvmet_ctrl_state_show()
  2025-03-24 21:56 ` [PATCH 15/22] nvmet: Fix out-of-bounds stack access in nvmet_ctrl_state_show() Josh Poimboeuf
  2025-03-25  8:34   ` [tip: objtool/urgent] objtool, " tip-bot2 for Josh Poimboeuf
@ 2025-03-25 22:09   ` tip-bot2 for Josh Poimboeuf
  2025-03-25 22:20     ` Chaitanya Kulkarni
  1 sibling, 1 reply; 75+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2025-03-25 22:09 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: kernel test robot, Josh Poimboeuf, Ingo Molnar, Christoph Hellwig,
	Sagi Grimberg, Chaitanya Kulkarni, Linus Torvalds, x86,
	linux-kernel

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

Commit-ID:     107a23185d990e3df6638d9a84c835f963fe30a6
Gitweb:        https://git.kernel.org/tip/107a23185d990e3df6638d9a84c835f963fe30a6
Author:        Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate:    Mon, 24 Mar 2025 14:56:05 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Tue, 25 Mar 2025 23:00:15 +01:00

objtool, nvmet: Fix out-of-bounds stack access in nvmet_ctrl_state_show()

The csts_state_names[] array only has six sparse entries, but the
iteration code in nvmet_ctrl_state_show() iterates seven, resulting in a
potential out-of-bounds stack read.  Fix that.

Fixes the following warning with an UBSAN kernel:

  vmlinux.o: warning: objtool: .text.nvmet_ctrl_state_show: unexpected end of section

Fixes: 649fd41420a8 ("nvmet: add debugfs support")
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Sagi Grimberg <sagi@grimberg.me>
Cc: Chaitanya Kulkarni <kch@nvidia.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/f1f60858ee7a941863dc7f5506c540cb9f97b5f6.1742852847.git.jpoimboe@kernel.org
Closes: https://lore.kernel.org/oe-kbuild-all/202503171547.LlCTJLQL-lkp@intel.com/
---
 drivers/nvme/target/debugfs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/nvme/target/debugfs.c b/drivers/nvme/target/debugfs.c
index 220c739..c6571fb 100644
--- a/drivers/nvme/target/debugfs.c
+++ b/drivers/nvme/target/debugfs.c
@@ -78,7 +78,7 @@ static int nvmet_ctrl_state_show(struct seq_file *m, void *p)
 	bool sep = false;
 	int i;
 
-	for (i = 0; i < 7; i++) {
+	for (i = 0; i < ARRAY_SIZE(csts_state_names); i++) {
 		int state = BIT(i);
 
 		if (!(ctrl->csts & state))

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

* [tip: objtool/urgent] objtool, spi: amd: Fix out-of-bounds stack access in amd_set_spi_freq()
  2025-03-24 21:56 ` [PATCH 14/22] spi: amd: Fix out-of-bounds stack access in amd_set_spi_freq() Josh Poimboeuf
  2025-03-25  8:34   ` [tip: objtool/urgent] objtool, " tip-bot2 for Josh Poimboeuf
@ 2025-03-25 22:10   ` tip-bot2 for Josh Poimboeuf
  1 sibling, 0 replies; 75+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2025-03-25 22:10 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: kernel test robot, Josh Poimboeuf, Ingo Molnar, Mark Brown,
	Raju Rangoju, Linus Torvalds, x86, linux-kernel

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

Commit-ID:     76e51db43fe4aaaebcc5ddda67b0807f7c9bdecc
Gitweb:        https://git.kernel.org/tip/76e51db43fe4aaaebcc5ddda67b0807f7c9bdecc
Author:        Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate:    Mon, 24 Mar 2025 14:56:04 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Tue, 25 Mar 2025 23:00:03 +01:00

objtool, spi: amd: Fix out-of-bounds stack access in amd_set_spi_freq()

If speed_hz < AMD_SPI_MIN_HZ, amd_set_spi_freq() iterates over the
entire amd_spi_freq array without breaking out early, causing 'i' to go
beyond the array bounds.

Fix that by stopping the loop when it gets to the last entry, so the low
speed_hz value gets clamped up to AMD_SPI_MIN_HZ.

Fixes the following warning with an UBSAN kernel:

  drivers/spi/spi-amd.o: error: objtool: amd_set_spi_freq() falls through to next function amd_spi_set_opcode()

Fixes: 3fe26121dc3a ("spi: amd: Configure device speed")
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Acked-by: Mark Brown <broonie@kernel.org>
Cc: Raju Rangoju <Raju.Rangoju@amd.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/78fef0f2434f35be9095bcc9ffa23dd8cab667b9.1742852847.git.jpoimboe@kernel.org
Closes: https://lore.kernel.org/r/202503161828.RUk9EhWx-lkp@intel.com/
---
 drivers/spi/spi-amd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/spi/spi-amd.c b/drivers/spi/spi-amd.c
index c859974..17fc0b1 100644
--- a/drivers/spi/spi-amd.c
+++ b/drivers/spi/spi-amd.c
@@ -302,7 +302,7 @@ static void amd_set_spi_freq(struct amd_spi *amd_spi, u32 speed_hz)
 {
 	unsigned int i, spd7_val, alt_spd;
 
-	for (i = 0; i < ARRAY_SIZE(amd_spi_freq); i++)
+	for (i = 0; i < ARRAY_SIZE(amd_spi_freq)-1; i++)
 		if (speed_hz >= amd_spi_freq[i].speed_hz)
 			break;
 

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

* Re: [tip: objtool/urgent] objtool, nvmet: Fix out-of-bounds stack access in nvmet_ctrl_state_show()
  2025-03-25 22:09   ` tip-bot2 for Josh Poimboeuf
@ 2025-03-25 22:20     ` Chaitanya Kulkarni
  0 siblings, 0 replies; 75+ messages in thread
From: Chaitanya Kulkarni @ 2025-03-25 22:20 UTC (permalink / raw)
  To: linux-kernel@vger.kernel.org, linux-tip-commits@vger.kernel.org
  Cc: kernel test robot, Josh Poimboeuf, Ingo Molnar, Christoph Hellwig,
	Sagi Grimberg, Chaitanya Kulkarni, Linus Torvalds, x86@kernel.org,
	linux-nvme@lists.infradead.org

(+linux-nvme)

On 3/25/25 15:09, tip-bot2 for Josh Poimboeuf wrote:
> The following commit has been merged into the objtool/urgent branch of tip:
>
> Commit-ID:     107a23185d990e3df6638d9a84c835f963fe30a6
> Gitweb:        https://git.kernel.org/tip/107a23185d990e3df6638d9a84c835f963fe30a6
> Author:        Josh Poimboeuf <jpoimboe@kernel.org>
> AuthorDate:    Mon, 24 Mar 2025 14:56:05 -07:00
> Committer:     Ingo Molnar <mingo@kernel.org>
> CommitterDate: Tue, 25 Mar 2025 23:00:15 +01:00
>
> objtool, nvmet: Fix out-of-bounds stack access in nvmet_ctrl_state_show()
>
> The csts_state_names[] array only has six sparse entries, but the
> iteration code in nvmet_ctrl_state_show() iterates seven, resulting in a
> potential out-of-bounds stack read.  Fix that.
>
> Fixes the following warning with an UBSAN kernel:
>
>    vmlinux.o: warning: objtool: .text.nvmet_ctrl_state_show: unexpected end of section
>
> Fixes: 649fd41420a8 ("nvmet: add debugfs support")
> Reported-by: kernel test robot <lkp@intel.com>
> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
> Signed-off-by: Ingo Molnar <mingo@kernel.org>
> Cc: Christoph Hellwig <hch@lst.de>
> Cc: Sagi Grimberg <sagi@grimberg.me>
> Cc: Chaitanya Kulkarni <kch@nvidia.com>
> Cc: Linus Torvalds <torvalds@linux-foundation.org>
> Link: https://lore.kernel.org/r/f1f60858ee7a941863dc7f5506c540cb9f97b5f6.1742852847.git.jpoimboe@kernel.org
> Closes: https://lore.kernel.org/oe-kbuild-all/202503171547.LlCTJLQL-lkp@intel.com/
> ---
>   drivers/nvme/target/debugfs.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/nvme/target/debugfs.c b/drivers/nvme/target/debugfs.c
> index 220c739..c6571fb 100644
> --- a/drivers/nvme/target/debugfs.c
> +++ b/drivers/nvme/target/debugfs.c
> @@ -78,7 +78,7 @@ static int nvmet_ctrl_state_show(struct seq_file *m, void *p)
>   	bool sep = false;
>   	int i;
>   
> -	for (i = 0; i < 7; i++) {
> +	for (i = 0; i < ARRAY_SIZE(csts_state_names); i++) {
>   		int state = BIT(i);
>   
>   		if (!(ctrl->csts & state))

Looks good.

Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>

-ck



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

* Re: [tip: objtool/urgent] objtool, media: dib8000: Prevent divide-by-zero in dib8000_set_dds()
  2025-03-25 22:09   ` tip-bot2 for Josh Poimboeuf
@ 2025-03-25 22:42     ` Mauro Carvalho Chehab
  2025-03-26  1:46       ` Josh Poimboeuf
  0 siblings, 1 reply; 75+ messages in thread
From: Mauro Carvalho Chehab @ 2025-03-25 22:42 UTC (permalink / raw)
  To: tip-bot2 for Josh Poimboeuf
  Cc: linux-kernel, linux-tip-commits, kernel test robot,
	Josh Poimboeuf, Ingo Molnar, Mauro Carvalho Chehab,
	Linus Torvalds, x86

Em Tue, 25 Mar 2025 22:09:58 -0000
"tip-bot2 for Josh Poimboeuf" <tip-bot2@linutronix.de> escreveu:

> The following commit has been merged into the objtool/urgent branch of tip:
> 
> Commit-ID:     e63d465f59011dede0a0f1d21718b59a64c3ff5c
> Gitweb:        https://git.kernel.org/tip/e63d465f59011dede0a0f1d21718b59a64c3ff5c
> Author:        Josh Poimboeuf <jpoimboe@kernel.org>
> AuthorDate:    Mon, 24 Mar 2025 14:56:06 -07:00
> Committer:     Ingo Molnar <mingo@kernel.org>
> CommitterDate: Tue, 25 Mar 2025 23:00:15 +01:00
> 
> objtool, media: dib8000: Prevent divide-by-zero in dib8000_set_dds()
> 
> If dib8000_set_dds()'s call to dib8000_read32() returns zero, the result
> is a divide-by-zero.  Prevent that from happening.
> 
> Fixes the following warning with an UBSAN kernel:
> 
>   drivers/media/dvb-frontends/dib8000.o: warning: objtool: dib8000_tune() falls through to next function dib8096p_cfg_DibRx()
> 
> Fixes: 173a64cb3fcf ("[media] dib8000: enhancement")
> Reported-by: kernel test robot <lkp@intel.com>
> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
> Signed-off-by: Ingo Molnar <mingo@kernel.org>
> Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
> Cc: Linus Torvalds <torvalds@linux-foundation.org>
> Link: https://lore.kernel.org/r/bd1d504d930ae3f073b1e071bcf62cae7708773c.1742852847.git.jpoimboe@kernel.org
> Closes: https://lore.kernel.org/r/202503210602.fvH5DO1i-lkp@intel.com/
> ---
>  drivers/media/dvb-frontends/dib8000.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/media/dvb-frontends/dib8000.c b/drivers/media/dvb-frontends/dib8000.c
> index 2f51659..cfe59c3 100644
> --- a/drivers/media/dvb-frontends/dib8000.c
> +++ b/drivers/media/dvb-frontends/dib8000.c
> @@ -2701,8 +2701,11 @@ static void dib8000_set_dds(struct dib8000_state *state, s32 offset_khz)
>  	u8 ratio;
>  
>  	if (state->revision == 0x8090) {
> +		u32 internal = dib8000_read32(state, 23) / 1000;
> +
>  		ratio = 4;
> -		unit_khz_dds_val = (1<<26) / (dib8000_read32(state, 23) / 1000);
> +
> +		unit_khz_dds_val = (1<<26) / (internal ?: 1);

This is theoretical, as in practice dib8096 won't likely be tuning
if reading this register would return zero, but at least for my
eyes, it would sound better to set unit_khz_dds_val to 1 internal
is zero, instead of 1<<26. 

>  		if (offset_khz < 0)
>  			dds = (1 << 26) - (abs_offset_khz * unit_khz_dds_val);
>  		else


Regards,
Mauro

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

* Re: [tip: objtool/urgent] objtool, media: dib8000: Prevent divide-by-zero in dib8000_set_dds()
  2025-03-25 22:42     ` Mauro Carvalho Chehab
@ 2025-03-26  1:46       ` Josh Poimboeuf
  0 siblings, 0 replies; 75+ messages in thread
From: Josh Poimboeuf @ 2025-03-26  1:46 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: tip-bot2 for Josh Poimboeuf, linux-kernel, linux-tip-commits,
	kernel test robot, Ingo Molnar, Mauro Carvalho Chehab,
	Linus Torvalds, x86

On Wed, Mar 26, 2025 at 06:42:39AM +0800, Mauro Carvalho Chehab wrote:
> > +		u32 internal = dib8000_read32(state, 23) / 1000;
> > +
> >  		ratio = 4;
> > -		unit_khz_dds_val = (1<<26) / (dib8000_read32(state, 23) / 1000);
> > +
> > +		unit_khz_dds_val = (1<<26) / (internal ?: 1);
> 
> This is theoretical, as in practice dib8096 won't likely be tuning
> if reading this register would return zero, but at least for my
> eyes, it would sound better to set unit_khz_dds_val to 1 internal
> is zero, instead of 1<<26. 

I don't pretend to understand this device, I just figured one is the
closest you can get to zero :-)

So something like this instead?

diff --git a/drivers/media/dvb-frontends/dib8000.c b/drivers/media/dvb-frontends/dib8000.c
index cfe59c3255f7..c80134ff511b 100644
--- a/drivers/media/dvb-frontends/dib8000.c
+++ b/drivers/media/dvb-frontends/dib8000.c
@@ -2705,7 +2705,7 @@ static void dib8000_set_dds(struct dib8000_state *state, s32 offset_khz)
 
 		ratio = 4;
 
-		unit_khz_dds_val = (1<<26) / (internal ?: 1);
+		unit_khz_dds_val = internal ? ((1<<26) / internal) : 1;
 		if (offset_khz < 0)
 			dds = (1 << 26) - (abs_offset_khz * unit_khz_dds_val);
 		else

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

* Re: [tip: objtool/urgent] objtool, pwm: mediatek: Prevent theoretical divide-by-zero in pwm_mediatek_config()
  2025-03-25  8:34   ` [tip: objtool/urgent] objtool, pwm: mediatek: Prevent theoretical " tip-bot2 for Josh Poimboeuf
@ 2025-03-26 10:35     ` Uwe Kleine-König
  2025-03-26 11:11       ` Peter Zijlstra
  2025-03-27  5:44       ` Josh Poimboeuf
       [not found]     ` <m7pgkp3ueo7iqgqf74upjrihr3mpmb3sqhwegnjxxwsrgx2jsw@dnec5iqiyobh>
  1 sibling, 2 replies; 75+ messages in thread
From: Uwe Kleine-König @ 2025-03-26 10:35 UTC (permalink / raw)
  To: Josh Poimboeuf, Ingo Molnar
  Cc: linux-tip-commits, linux-kernel, Linus Torvalds, x86

[-- Attachment #1: Type: text/plain, Size: 2931 bytes --]

[I forgot a comma in the original post and so the list of Cc: was
broken. Here comes a resend, sorry to everyone who get the mail twice
now. If you reply, please do so on this copy to not continue using the
broken address.]

Hello,

On Tue, Mar 25, 2025 at 08:34:51AM +0000, tip-bot2 for Josh Poimboeuf wrote:
> The following commit has been merged into the objtool/urgent branch of tip:
>
> Commit-ID:     2becbc66a151500636046503f541255af6acf4fa
> Gitweb:        https://git.kernel.org/tip/2becbc66a151500636046503f541255af6acf4fa
> Author:        Josh Poimboeuf <jpoimboe@kernel.org>
> AuthorDate:    Mon, 24 Mar 2025 14:56:11 -07:00
> Committer:     Ingo Molnar <mingo@kernel.org>
> CommitterDate: Tue, 25 Mar 2025 09:20:32 +01:00

I wonder a bit about procedures here. While I like that warnings that
pop up in drivers/pwm (and elsewhere) are cared for, I think that the
sensible way to change warning related settings is to make it hard to
enable them first (harder than "depends on !COMPILE_TEST" "To avoid
breaking bots too badly") and then work on the identified problems
before warning broadly. The way chosen here instead seems to be enabling
the warning immediately and then post fixes to the warnings and merge
them without respective maintainer feedback in less than 12 hours.

> objtool, pwm: mediatek: Prevent theoretical divide-by-zero in pwm_mediatek_config()
>
> With CONFIG_COMPILE_TEST && !CONFIG_CLK, pwm_mediatek_config() has a
> divide-by-zero in the following line:
>
>       do_div(resolution, clk_get_rate(pc->clk_pwms[pwm->hwpwm]));
>
> due to the fact that the !CONFIG_CLK version of clk_get_rate() returns
> zero.
>
> This is presumably just a theoretical problem: COMPILE_TEST overrides
> the dependency on RALINK which would select COMMON_CLK.  Regardless it's

RALINK and ARCH_MEDIATEK. The latter enables COMMON_CLK as it depends on
ARM or ARM64 which both select COMMON_CLK.

> a good idea to check for the error explicitly to avoid divide-by-zero.
>
> Fixes the following warning:
>
>   drivers/pwm/pwm-mediatek.o: warning: objtool: .text: unexpected end of section
>
> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
> Signed-off-by: Ingo Molnar <mingo@kernel.org>

Fixes: caf065f8fd58 ("pwm: Add MediaTek PWM support")

would be nice.

> Cc: "Uwe Kleine-König" <ukleinek@kernel.org> (maintainer:PWM SUBSYSTEM)
> Cc: Linus Torvalds <torvalds@linux-foundation.org>
> Link: https://lore.kernel.org/r/fb56444939325cc173e752ba199abd7aeae3bf12.1742852847.git.jpoimboe@kernel.org

I fail to reproduce the warning here for an x86_64 build on
1e26c5e28ca5. I have:

        $ grep -E 'CONFIG_(CLK|PWM_MEDIATEK|OBJTOOL_WERROR)\>' .config
        CONFIG_PWM_MEDIATEK=m
        CONFIG_OBJTOOL_WERROR=y

and the build works fine for me and there is no warning about
drivers/pwm/pwm-mediatek.o. What am I missing?

Best regards
Uwe

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [tip: objtool/urgent] objtool, pwm: mediatek: Prevent theoretical divide-by-zero in pwm_mediatek_config()
  2025-03-26 10:35     ` Uwe Kleine-König
@ 2025-03-26 11:11       ` Peter Zijlstra
  2025-03-27  5:44       ` Josh Poimboeuf
  1 sibling, 0 replies; 75+ messages in thread
From: Peter Zijlstra @ 2025-03-26 11:11 UTC (permalink / raw)
  To: Uwe Kleine-König
  Cc: Josh Poimboeuf, Ingo Molnar, linux-tip-commits, linux-kernel,
	Linus Torvalds, x86

[-- Attachment #1: Type: text/plain, Size: 512 bytes --]

On Wed, Mar 26, 2025 at 11:35:28AM +0100, Uwe Kleine-König wrote:

> and the build works fine for me and there is no warning about
> drivers/pwm/pwm-mediatek.o. What am I missing?

Could be compiler related; IIRC it is mostly clang that does this. When
it finds /0 it simply stops code-gen.

I *really* dislike this behaviour, but since C declares this UB, they're
basically free to do whatever.

IMO it should just emit the code; kernel has exceptions to deal with
this and userspace gets signals.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [tip: objtool/urgent] objtool, pwm: mediatek: Prevent theoretical divide-by-zero in pwm_mediatek_config()
  2025-03-26 10:35     ` Uwe Kleine-König
  2025-03-26 11:11       ` Peter Zijlstra
@ 2025-03-27  5:44       ` Josh Poimboeuf
  2025-03-27  8:27         ` Uwe Kleine-König
  1 sibling, 1 reply; 75+ messages in thread
From: Josh Poimboeuf @ 2025-03-27  5:44 UTC (permalink / raw)
  To: Uwe Kleine-König
  Cc: Ingo Molnar, linux-tip-commits, linux-kernel, Linus Torvalds, x86

On Wed, Mar 26, 2025 at 11:35:28AM +0100, Uwe Kleine-König wrote:
> I wonder a bit about procedures here. While I like that warnings that
> pop up in drivers/pwm (and elsewhere) are cared for, I think that the
> sensible way to change warning related settings is to make it hard to
> enable them first (harder than "depends on !COMPILE_TEST" "To avoid
> breaking bots too badly") and then work on the identified problems
> before warning broadly. The way chosen here instead seems to be enabling
> the warning immediately and then post fixes to the warnings and merge
> them without respective maintainer feedback in less than 12 hours.

Actually, this type of warning has existed for years.  Nothing in the
recent objtool patches enabled it.

I only discovered this particular one a few days ago.  I suspect it only
exists with newer compilers.

> I fail to reproduce the warning here for an x86_64 build on
> 1e26c5e28ca5. I have:
> 
>         $ grep -E 'CONFIG_(CLK|PWM_MEDIATEK|OBJTOOL_WERROR)\>' .config
>         CONFIG_PWM_MEDIATEK=m
>         CONFIG_OBJTOOL_WERROR=y
> 
> and the build works fine for me and there is no warning about
> drivers/pwm/pwm-mediatek.o. What am I missing?

Sorry, I should have given more details about that.  It was likely
something with KCOV and/or UBSAN, though I can't seem to recreate it at
the moment either :-/

-- 
Josh

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

* Re: [tip: objtool/urgent] objtool, pwm: mediatek: Prevent theoretical divide-by-zero in pwm_mediatek_config()
  2025-03-27  5:44       ` Josh Poimboeuf
@ 2025-03-27  8:27         ` Uwe Kleine-König
  0 siblings, 0 replies; 75+ messages in thread
From: Uwe Kleine-König @ 2025-03-27  8:27 UTC (permalink / raw)
  To: Josh Poimboeuf
  Cc: Ingo Molnar, linux-tip-commits, linux-kernel, Linus Torvalds, x86

[-- Attachment #1: Type: text/plain, Size: 2143 bytes --]

Hello Josh,

On Wed, Mar 26, 2025 at 10:44:04PM -0700, Josh Poimboeuf wrote:
> On Wed, Mar 26, 2025 at 11:35:28AM +0100, Uwe Kleine-König wrote:
> > I wonder a bit about procedures here. While I like that warnings that
> > pop up in drivers/pwm (and elsewhere) are cared for, I think that the
> > sensible way to change warning related settings is to make it hard to
> > enable them first (harder than "depends on !COMPILE_TEST" "To avoid
> > breaking bots too badly") and then work on the identified problems
> > before warning broadly. The way chosen here instead seems to be enabling
> > the warning immediately and then post fixes to the warnings and merge
> > them without respective maintainer feedback in less than 12 hours.
> 
> Actually, this type of warning has existed for years.  Nothing in the
> recent objtool patches enabled it.

Yes, I understood that the recent patch only made the warning fatal.

> I only discovered this particular one a few days ago.  I suspect it only
> exists with newer compilers.
> 
> > I fail to reproduce the warning here for an x86_64 build on
> > 1e26c5e28ca5. I have:
> > 
> >         $ grep -E 'CONFIG_(CLK|PWM_MEDIATEK|OBJTOOL_WERROR)\>' .config
> >         CONFIG_PWM_MEDIATEK=m
> >         CONFIG_OBJTOOL_WERROR=y
> > 
> > and the build works fine for me and there is no warning about
> > drivers/pwm/pwm-mediatek.o. What am I missing?
> 
> Sorry, I should have given more details about that.  It was likely
> something with KCOV and/or UBSAN, though I can't seem to recreate it at
> the moment either :-/

The combination "existed for years" + "discovered a few days ago" +
needs particular combination of .config and toolchain makes me believe
the right way to fix is a medium priority patch via the maintainer of
the affected driver. I don't see the urgency to justify the current
procedure.

I don't know what the current merge plan is, but if you want to merge it
through the pwm tree, I'm willing to take it. I wouldn't create a pull
request just for that before 6.15, but send it along if something more
urgent pops up.

Best regards
Uwe

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* [tip: objtool/urgent] objtool, lkdtm: Obfuscate the do_nothing() pointer
  2025-03-24 21:56 ` [PATCH 22/22] lkdtm: Obfuscate do_nothing() pointer Josh Poimboeuf
                     ` (2 preceding siblings ...)
  2025-03-25 22:09   ` [tip: objtool/urgent] objtool, lkdtm: Obfuscate the " tip-bot2 for Josh Poimboeuf
@ 2025-03-27 11:06   ` tip-bot2 for Josh Poimboeuf
  2025-03-28 13:48   ` tip-bot2 for Josh Poimboeuf
  4 siblings, 0 replies; 75+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2025-03-27 11:06 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: kernel test robot, Josh Poimboeuf, Ingo Molnar, Kees Cook,
	Arnd Bergmann, Greg Kroah-Hartman, Linus Torvalds, x86,
	linux-kernel

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

Commit-ID:     42e5650944b8cd4361385cc9414f03a6d6748989
Gitweb:        https://git.kernel.org/tip/42e5650944b8cd4361385cc9414f03a6d6748989
Author:        Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate:    Mon, 24 Mar 2025 14:56:12 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Thu, 27 Mar 2025 11:59:11 +01:00

objtool, lkdtm: Obfuscate the do_nothing() pointer

If execute_location()'s memcpy of do_nothing() gets inlined and unrolled
by the compiler, it copies one word at a time:

    mov    0x0(%rip),%rax    R_X86_64_PC32    .text+0x1374
    mov    %rax,0x38(%rbx)
    mov    0x0(%rip),%rax    R_X86_64_PC32    .text+0x136c
    mov    %rax,0x30(%rbx)
    ...

Those .text references point to the middle of the function, causing
objtool to complain about their lack of ENDBR.

Prevent that by resolving the function pointer at runtime rather than
build time.  This fixes the following warning:

  drivers/misc/lkdtm/lkdtm.o: warning: objtool: execute_location+0x23: relocation to !ENDBR: .text+0x1378

Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Kees Cook <kees@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/30b9abffbddeb43c4f6320b1270fa9b4d74c54ed.1742852847.git.jpoimboe@kernel.org
Closes: https://lore.kernel.org/oe-kbuild-all/202503191453.uFfxQy5R-lkp@intel.com/
---
 drivers/misc/lkdtm/perms.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
index 5b861db..6c24426 100644
--- a/drivers/misc/lkdtm/perms.c
+++ b/drivers/misc/lkdtm/perms.c
@@ -29,6 +29,13 @@ static const unsigned long rodata = 0xAA55AA55;
 static unsigned long ro_after_init __ro_after_init = 0x55AA5500;
 
 /*
+ * This is a pointer to do_nothing() which is initialized at runtime rather
+ * than build time to avoid objtool IBT validation warnings caused by an
+ * inlined unrolled memcpy() in execute_location().
+ */
+static void __ro_after_init *do_nothing_ptr;
+
+/*
  * This just returns to the caller. It is designed to be copied into
  * non-executable memory regions.
  */
@@ -65,13 +72,12 @@ static noinline __nocfi void execute_location(void *dst, bool write)
 {
 	void (*func)(void);
 	func_desc_t fdesc;
-	void *do_nothing_text = dereference_function_descriptor(do_nothing);
 
-	pr_info("attempting ok execution at %px\n", do_nothing_text);
+	pr_info("attempting ok execution at %px\n", do_nothing_ptr);
 	do_nothing();
 
 	if (write == CODE_WRITE) {
-		memcpy(dst, do_nothing_text, EXEC_SIZE);
+		memcpy(dst, do_nothing_ptr, EXEC_SIZE);
 		flush_icache_range((unsigned long)dst,
 				   (unsigned long)dst + EXEC_SIZE);
 	}
@@ -267,6 +273,8 @@ static void lkdtm_ACCESS_NULL(void)
 
 void __init lkdtm_perms_init(void)
 {
+	do_nothing_ptr = dereference_function_descriptor(do_nothing);
+
 	/* Make sure we can write to __ro_after_init values during __init */
 	ro_after_init |= 0xAA;
 }

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

* [tip: objtool/urgent] objtool, pwm: mediatek: Prevent theoretical divide-by-zero in pwm_mediatek_config()
  2025-03-24 21:56 ` [PATCH 21/22] pwm: mediatek: Prevent divide-by-zero in pwm_mediatek_config() Josh Poimboeuf
  2025-03-25  8:34   ` [tip: objtool/urgent] objtool, pwm: mediatek: Prevent theoretical " tip-bot2 for Josh Poimboeuf
  2025-03-25 22:09   ` tip-bot2 for Josh Poimboeuf
@ 2025-03-27 11:06   ` tip-bot2 for Josh Poimboeuf
  2 siblings, 0 replies; 75+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2025-03-27 11:06 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Josh Poimboeuf, Ingo Molnar, ukleinek, Linus Torvalds, x86,
	linux-kernel

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

Commit-ID:     4e8af314386ec3e0b842f47705321e074b1dd556
Gitweb:        https://git.kernel.org/tip/4e8af314386ec3e0b842f47705321e074b1dd556
Author:        Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate:    Mon, 24 Mar 2025 14:56:11 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Thu, 27 Mar 2025 11:57:45 +01:00

objtool, pwm: mediatek: Prevent theoretical divide-by-zero in pwm_mediatek_config()

With CONFIG_COMPILE_TEST && !CONFIG_CLK, pwm_mediatek_config() has a
divide-by-zero in the following line:

	do_div(resolution, clk_get_rate(pc->clk_pwms[pwm->hwpwm]));

due to the fact that the !CONFIG_CLK version of clk_get_rate() returns
zero.

This is presumably just a theoretical problem: COMPILE_TEST overrides
the dependency on RALINK which would select COMMON_CLK.  Regardless it's
a good idea to check for the error explicitly to avoid divide-by-zero.

Fixes the following warning:

  drivers/pwm/pwm-mediatek.o: warning: objtool: .text: unexpected end of section

Fixes: caf065f8fd58 ("pwm: Add MediaTek PWM support")
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Acked-by: "Uwe Kleine-König" <ukleinek@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/fb56444939325cc173e752ba199abd7aeae3bf12.1742852847.git.jpoimboe@kernel.org
---
 drivers/pwm/pwm-mediatek.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
index 01dfa0f..7eaab58 100644
--- a/drivers/pwm/pwm-mediatek.c
+++ b/drivers/pwm/pwm-mediatek.c
@@ -121,21 +121,25 @@ static int pwm_mediatek_config(struct pwm_chip *chip, struct pwm_device *pwm,
 	struct pwm_mediatek_chip *pc = to_pwm_mediatek_chip(chip);
 	u32 clkdiv = 0, cnt_period, cnt_duty, reg_width = PWMDWIDTH,
 	    reg_thres = PWMTHRES;
+	unsigned long clk_rate;
 	u64 resolution;
 	int ret;
 
 	ret = pwm_mediatek_clk_enable(chip, pwm);
-
 	if (ret < 0)
 		return ret;
 
+	clk_rate = clk_get_rate(pc->clk_pwms[pwm->hwpwm]);
+	if (!clk_rate)
+		return -EINVAL;
+
 	/* Make sure we use the bus clock and not the 26MHz clock */
 	if (pc->soc->has_ck_26m_sel)
 		writel(0, pc->regs + PWM_CK_26M_SEL);
 
 	/* Using resolution in picosecond gets accuracy higher */
 	resolution = (u64)NSEC_PER_SEC * 1000;
-	do_div(resolution, clk_get_rate(pc->clk_pwms[pwm->hwpwm]));
+	do_div(resolution, clk_rate);
 
 	cnt_period = DIV_ROUND_CLOSEST_ULL((u64)period_ns * 1000, resolution);
 	while (cnt_period > 8191) {

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

* Re: [tip: objtool/urgent] objtool, pwm: mediatek: Prevent theoretical divide-by-zero in pwm_mediatek_config()
       [not found]       ` <Z-Uv60sD_S2xYVB1@gmail.com>
@ 2025-03-27 18:14         ` Uwe Kleine-König
  2025-03-27 21:21           ` Ingo Molnar
  0 siblings, 1 reply; 75+ messages in thread
From: Uwe Kleine-König @ 2025-03-27 18:14 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Josh Poimboeuf, linux-tip-commits, linux-kernel, Linus Torvalds,
	x86

[-- Attachment #1: Type: text/plain, Size: 1747 bytes --]

Hello Ingo,

On Thu, Mar 27, 2025 at 12:00:59PM +0100, Ingo Molnar wrote:
> * Uwe Kleine-König <ukleinek@kernel.org> wrote:
> 
> > I wonder a bit about procedures here. While I like that warnings that 
> > pop up in drivers/pwm (and elsewhere) are cared for, I think that the 
> > sensible way to change warning related settings is to make it hard to 
> > enable them first (harder than "depends on !COMPILE_TEST" "To avoid 
> > breaking bots too badly") and then work on the identified problems 
> > before warning broadly. The way chosen here instead seems to be 
> > enabling the warning immediately and then post fixes to the warnings 
> > and merge them without respective maintainer feedback in less than 12 
> > hours.
> 
> As I indicated elsewhere in this thread, it's a WIP branch, so we'll 

That sounds as if I should know that. But it's neither in the part of
the thread that I was Cc:d, nor in the cover letter.

> rebase it if/as we get feedback from maintainers: fix or skip the patch 
> on negative feedback, adding in tags on positive feedback.
> 
> Does this particular patch look good to you?

I fail to see an urgency and so think this patch should better go via
the pwm tree. Do you consider it urgent (as the branch name suggests)?
Or is this v6.16 material?

> > > Cc: "Uwe Kleine-König" <ukleinek@kernel.org> (maintainer:PWM SUBSYSTEM)
> > > Cc: Linus Torvalds <torvalds@linux-foundation.org>
> > > Link: https://lore.kernel.org/r/fb56444939325cc173e752ba199abd7aeae3bf12.1742852847.git.jpoimboe@kernel.org
> 
> I've also tentatively added your Acked-by, if that's OK with you.

The patch is OK. Iff you can convince me that it should go via tip, it's
fine for me.

Best regards
Uwe

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [tip: objtool/urgent] objtool, pwm: mediatek: Prevent theoretical divide-by-zero in pwm_mediatek_config()
  2025-03-27 18:14         ` Uwe Kleine-König
@ 2025-03-27 21:21           ` Ingo Molnar
  2025-03-28 10:24             ` Uwe Kleine-König
  0 siblings, 1 reply; 75+ messages in thread
From: Ingo Molnar @ 2025-03-27 21:21 UTC (permalink / raw)
  To: Uwe Kleine-König
  Cc: Josh Poimboeuf, linux-tip-commits, linux-kernel, Linus Torvalds,
	x86


* Uwe Kleine-König <ukleinek@kernel.org> wrote:

> > > > Cc: "Uwe Kleine-König" <ukleinek@kernel.org> (maintainer:PWM SUBSYSTEM)
> > > > Cc: Linus Torvalds <torvalds@linux-foundation.org>
> > > > Link: https://lore.kernel.org/r/fb56444939325cc173e752ba199abd7aeae3bf12.1742852847.git.jpoimboe@kernel.org
> > 
> > I've also tentatively added your Acked-by, if that's OK with you.
> 
> The patch is OK.

Thanks!

> [...] Iff you can convince me that it should go via tip, it's fine 
> for me.

I wanted to collect all the objtool fixes for CONFIG_OBJTOOL_WERROR=y 
failures in a single place to not inconvenience randconfig CI testing 
efforts, so in that sense it would be nice to send this via the 
objtool/urgent tree, but I'll remove it if you insist.

Thanks,

	Ingo

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

* Re: [tip: objtool/urgent] objtool, pwm: mediatek: Prevent theoretical divide-by-zero in pwm_mediatek_config()
  2025-03-27 21:21           ` Ingo Molnar
@ 2025-03-28 10:24             ` Uwe Kleine-König
  2025-03-28 13:45               ` Ingo Molnar
  0 siblings, 1 reply; 75+ messages in thread
From: Uwe Kleine-König @ 2025-03-28 10:24 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Josh Poimboeuf, linux-tip-commits, linux-kernel, Linus Torvalds,
	x86

[-- Attachment #1: Type: text/plain, Size: 1779 bytes --]

Hello Ingo,

On Thu, Mar 27, 2025 at 10:21:51PM +0100, Ingo Molnar wrote:
> 
> * Uwe Kleine-König <ukleinek@kernel.org> wrote:
> 
> > > > > Cc: "Uwe Kleine-König" <ukleinek@kernel.org> (maintainer:PWM SUBSYSTEM)
> > > > > Cc: Linus Torvalds <torvalds@linux-foundation.org>
> > > > > Link: https://lore.kernel.org/r/fb56444939325cc173e752ba199abd7aeae3bf12.1742852847.git.jpoimboe@kernel.org
> > > 
> > > I've also tentatively added your Acked-by, if that's OK with you.
> > 
> > The patch is OK.
> 
> Thanks!
> 
> > [...] Iff you can convince me that it should go via tip, it's fine 
> > for me.
> 
> I wanted to collect all the objtool fixes for CONFIG_OBJTOOL_WERROR=y 

Regarding "all": Taking a quick look, I wonder if
drivers/pwm/pwm-fsl-ftm.c is also affected. Given I cannot reproduce the
warning for the pwm-mediatek driver, I can only guess. This driver
does:

	static unsigned int fsl_pwm_ticks_to_ns(struct fsl_pwm_chip *fpc,
						  unsigned int ticks)
	{
		unsigned long rate;
		unsigned long long exval;

		rate = clk_get_rate(fpc->clk[fpc->period.clk_select]);
		exval = ticks;
		exval *= 1000000000UL;
		do_div(exval, rate >> fpc->period.clk_ps);
		return exval;
	}

and doesn't depend on HAVE_CLK. So similar to the pwm-mediatek driver
there are configurations where clk_get_rate() returns 0.

Assuming this is indeed a problem, I wonder how many more offenders
there are and if CONFIG_OBJTOOL_WERROR is ready for prime time already.

> failures in a single place to not inconvenience randconfig CI testing 
> efforts, so in that sense it would be nice to send this via the 
> objtool/urgent tree, but I'll remove it if you insist.

I'm still in the process to determine my opinion on that.

Best regards
Uwe

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [tip: objtool/urgent] objtool, pwm: mediatek: Prevent theoretical divide-by-zero in pwm_mediatek_config()
  2025-03-28 10:24             ` Uwe Kleine-König
@ 2025-03-28 13:45               ` Ingo Molnar
  2025-03-28 18:19                 ` Uwe Kleine-König
  0 siblings, 1 reply; 75+ messages in thread
From: Ingo Molnar @ 2025-03-28 13:45 UTC (permalink / raw)
  To: Uwe Kleine-König
  Cc: Josh Poimboeuf, linux-tip-commits, linux-kernel, Linus Torvalds,
	x86


* Uwe Kleine-König <ukleinek@kernel.org> wrote:

> > failures in a single place to not inconvenience randconfig CI 
> > testing efforts, so in that sense it would be nice to send this via 
> > the objtool/urgent tree, but I'll remove it if you insist.
> 
> I'm still in the process to determine my opinion on that.

Although Josh's fix looks obviously correct to me, I've removed the 
commit from objtool/urgent, because your indecision about it is 
blocking other fixes. Feel free to pick up the fix in your tree.

Thanks,

	Ingo

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

* [tip: objtool/urgent] objtool, lkdtm: Obfuscate the do_nothing() pointer
  2025-03-24 21:56 ` [PATCH 22/22] lkdtm: Obfuscate do_nothing() pointer Josh Poimboeuf
                     ` (3 preceding siblings ...)
  2025-03-27 11:06   ` tip-bot2 for Josh Poimboeuf
@ 2025-03-28 13:48   ` tip-bot2 for Josh Poimboeuf
  4 siblings, 0 replies; 75+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2025-03-28 13:48 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: kernel test robot, Josh Poimboeuf, Ingo Molnar, Kees Cook,
	Arnd Bergmann, Greg Kroah-Hartman, Linus Torvalds, x86,
	linux-kernel

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

Commit-ID:     05026ea01e95ffdeb0e5ac8fb7fb1b551e3a8726
Gitweb:        https://git.kernel.org/tip/05026ea01e95ffdeb0e5ac8fb7fb1b551e3a8726
Author:        Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate:    Mon, 24 Mar 2025 14:56:12 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Fri, 28 Mar 2025 14:38:09 +01:00

objtool, lkdtm: Obfuscate the do_nothing() pointer

If execute_location()'s memcpy of do_nothing() gets inlined and unrolled
by the compiler, it copies one word at a time:

    mov    0x0(%rip),%rax    R_X86_64_PC32    .text+0x1374
    mov    %rax,0x38(%rbx)
    mov    0x0(%rip),%rax    R_X86_64_PC32    .text+0x136c
    mov    %rax,0x30(%rbx)
    ...

Those .text references point to the middle of the function, causing
objtool to complain about their lack of ENDBR.

Prevent that by resolving the function pointer at runtime rather than
build time.  This fixes the following warning:

  drivers/misc/lkdtm/lkdtm.o: warning: objtool: execute_location+0x23: relocation to !ENDBR: .text+0x1378

Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Kees Cook <kees@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/30b9abffbddeb43c4f6320b1270fa9b4d74c54ed.1742852847.git.jpoimboe@kernel.org
Closes: https://lore.kernel.org/oe-kbuild-all/202503191453.uFfxQy5R-lkp@intel.com/
---
 drivers/misc/lkdtm/perms.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
index 5b861db..6c24426 100644
--- a/drivers/misc/lkdtm/perms.c
+++ b/drivers/misc/lkdtm/perms.c
@@ -29,6 +29,13 @@ static const unsigned long rodata = 0xAA55AA55;
 static unsigned long ro_after_init __ro_after_init = 0x55AA5500;
 
 /*
+ * This is a pointer to do_nothing() which is initialized at runtime rather
+ * than build time to avoid objtool IBT validation warnings caused by an
+ * inlined unrolled memcpy() in execute_location().
+ */
+static void __ro_after_init *do_nothing_ptr;
+
+/*
  * This just returns to the caller. It is designed to be copied into
  * non-executable memory regions.
  */
@@ -65,13 +72,12 @@ static noinline __nocfi void execute_location(void *dst, bool write)
 {
 	void (*func)(void);
 	func_desc_t fdesc;
-	void *do_nothing_text = dereference_function_descriptor(do_nothing);
 
-	pr_info("attempting ok execution at %px\n", do_nothing_text);
+	pr_info("attempting ok execution at %px\n", do_nothing_ptr);
 	do_nothing();
 
 	if (write == CODE_WRITE) {
-		memcpy(dst, do_nothing_text, EXEC_SIZE);
+		memcpy(dst, do_nothing_ptr, EXEC_SIZE);
 		flush_icache_range((unsigned long)dst,
 				   (unsigned long)dst + EXEC_SIZE);
 	}
@@ -267,6 +273,8 @@ static void lkdtm_ACCESS_NULL(void)
 
 void __init lkdtm_perms_init(void)
 {
+	do_nothing_ptr = dereference_function_descriptor(do_nothing);
+
 	/* Make sure we can write to __ro_after_init values during __init */
 	ro_after_init |= 0xAA;
 }

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

* Re: [tip: objtool/urgent] objtool, pwm: mediatek: Prevent theoretical divide-by-zero in pwm_mediatek_config()
  2025-03-28 13:45               ` Ingo Molnar
@ 2025-03-28 18:19                 ` Uwe Kleine-König
  0 siblings, 0 replies; 75+ messages in thread
From: Uwe Kleine-König @ 2025-03-28 18:19 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Josh Poimboeuf, linux-tip-commits, linux-kernel, Linus Torvalds,
	x86

[-- Attachment #1: Type: text/plain, Size: 957 bytes --]

Hello Ingo,

On Fri, Mar 28, 2025 at 02:45:04PM +0100, Ingo Molnar wrote:
> * Uwe Kleine-König <ukleinek@kernel.org> wrote:
> 
> > > failures in a single place to not inconvenience randconfig CI 
> > > testing efforts, so in that sense it would be nice to send this via 
> > > the objtool/urgent tree, but I'll remove it if you insist.
> > 
> > I'm still in the process to determine my opinion on that.
> 
> Although Josh's fix looks obviously correct to me, I've removed the 
> commit from objtool/urgent, because your indecision about it is 
> blocking other fixes.

This isn't exactly the reaction that I expected, but of course you're
entitled to do that.

> Feel free to pick up the fix in your tree.

I'd like to understand if there are still more fixes needed similar to
the pwm-mediatek one. I managed to reproduce that issue and will play
around with that a bit to check if some more fixes are needed.

Best regards
Uwe


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

end of thread, other threads:[~2025-03-28 18:19 UTC | newest]

Thread overview: 75+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-24 21:55 [PATCH 00/22] objtool: CONFIG_OBJTOOL_WERROR fixes and cleanups Josh Poimboeuf
2025-03-24 21:55 ` [PATCH 01/22] objtool: Fix detection of consecutive jump tables Josh Poimboeuf
2025-03-25  8:35   ` [tip: objtool/urgent] objtool: Fix detection of consecutive jump tables on Clang 20 tip-bot2 for Josh Poimboeuf
2025-03-24 21:55 ` [PATCH 02/22] objtool: Warn when disabling unreachable warnings Josh Poimboeuf
2025-03-25  8:35   ` [tip: objtool/urgent] " tip-bot2 for Josh Poimboeuf
2025-03-24 21:55 ` [PATCH 03/22] objtool: Ignore entire functions rather than instructions Josh Poimboeuf
2025-03-25  8:35   ` [tip: objtool/urgent] " tip-bot2 for Josh Poimboeuf
2025-03-24 21:55 ` [PATCH 04/22] objtool: Fix X86_FEATURE_SMAP alternative handling Josh Poimboeuf
2025-03-25  8:35   ` [tip: objtool/urgent] " tip-bot2 for Josh Poimboeuf
2025-03-24 21:55 ` [PATCH 05/22] objtool: Fix CONFIG_OBJTOOL_WERROR for vmlinux.o Josh Poimboeuf
2025-03-25  8:35   ` [tip: objtool/urgent] " tip-bot2 for Josh Poimboeuf
2025-03-24 21:55 ` [PATCH 06/22] objtool: Fix init_module() handling Josh Poimboeuf
2025-03-25  8:35   ` [tip: objtool/urgent] " tip-bot2 for Josh Poimboeuf
2025-03-24 21:55 ` [PATCH 07/22] objtool: Silence more KCOV warnings Josh Poimboeuf
2025-03-25  8:35   ` [tip: objtool/urgent] " tip-bot2 for Josh Poimboeuf
2025-03-24 21:55 ` [PATCH 08/22] objtool: Properly disable uaccess validation Josh Poimboeuf
2025-03-25  8:35   ` [tip: objtool/urgent] " tip-bot2 for Josh Poimboeuf
2025-03-24 21:55 ` [PATCH 09/22] objtool: Improve error handling Josh Poimboeuf
2025-03-25  8:35   ` [tip: objtool/urgent] " tip-bot2 for Josh Poimboeuf
2025-03-24 21:56 ` [PATCH 10/22] objtool: Reduce CONFIG_OBJTOOL_WERROR verbosity Josh Poimboeuf
2025-03-25  8:35   ` [tip: objtool/urgent] " tip-bot2 for Josh Poimboeuf
2025-03-24 21:56 ` [PATCH 11/22] objtool: Fix up some outdated references to ENTRY/ENDPROC Josh Poimboeuf
2025-03-25  8:35   ` [tip: objtool/urgent] " tip-bot2 for Josh Poimboeuf
2025-03-24 21:56 ` [PATCH 12/22] objtool: Remove --no-unreachable for noinstr-only vmlinux.o runs Josh Poimboeuf
2025-03-25  8:35   ` [tip: objtool/urgent] " tip-bot2 for Josh Poimboeuf
2025-03-24 21:56 ` [PATCH 13/22] objtool: Remove redundant opts.noinstr dependency Josh Poimboeuf
2025-03-25  8:34   ` [tip: objtool/urgent] " tip-bot2 for Josh Poimboeuf
2025-03-24 21:56 ` [PATCH 14/22] spi: amd: Fix out-of-bounds stack access in amd_set_spi_freq() Josh Poimboeuf
2025-03-25  8:34   ` [tip: objtool/urgent] objtool, " tip-bot2 for Josh Poimboeuf
2025-03-25 13:13     ` Mark Brown
2025-03-25 22:10   ` tip-bot2 for Josh Poimboeuf
2025-03-24 21:56 ` [PATCH 15/22] nvmet: Fix out-of-bounds stack access in nvmet_ctrl_state_show() Josh Poimboeuf
2025-03-25  8:34   ` [tip: objtool/urgent] objtool, " tip-bot2 for Josh Poimboeuf
2025-03-25 22:09   ` tip-bot2 for Josh Poimboeuf
2025-03-25 22:20     ` Chaitanya Kulkarni
2025-03-24 21:56 ` [PATCH 16/22] media: dib8000: Prevent divide-by-zero in dib8000_set_dds() Josh Poimboeuf
2025-03-25  8:34   ` [tip: objtool/urgent] objtool, " tip-bot2 for Josh Poimboeuf
2025-03-25 22:09   ` tip-bot2 for Josh Poimboeuf
2025-03-25 22:42     ` Mauro Carvalho Chehab
2025-03-26  1:46       ` Josh Poimboeuf
2025-03-24 21:56 ` [PATCH 17/22] panic: Disable SMAP in __stack_chk_fail() Josh Poimboeuf
2025-03-25  8:34   ` [tip: objtool/urgent] objtool, " tip-bot2 for Josh Poimboeuf
2025-03-25 22:09   ` tip-bot2 for Josh Poimboeuf
2025-03-24 21:56 ` [PATCH 18/22] Input: cyapa - remove undefined behavior in cyapa_update_fw_store() Josh Poimboeuf
2025-03-25  8:34   ` [tip: objtool/urgent] objtool, Input: cyapa - Remove " tip-bot2 for Josh Poimboeuf
2025-03-25 22:09   ` tip-bot2 for Josh Poimboeuf
2025-03-24 21:56 ` [PATCH 19/22] ASoC: codecs: wcd934x: Remove undefined behavior in wcd934x_slim_irq_handler() Josh Poimboeuf
2025-03-25  8:34   ` [tip: objtool/urgent] objtool, ASoC: codecs: wcd934x: Remove potential " tip-bot2 for Josh Poimboeuf
2025-03-25 11:32     ` Mark Brown
2025-03-25 11:36       ` Ingo Molnar
2025-03-25 13:12         ` Mark Brown
2025-03-25 22:09   ` tip-bot2 for Josh Poimboeuf
2025-03-24 21:56 ` [PATCH 20/22] regulator: rk808: Remove undefined behavior in rk806_set_mode_dcdc() Josh Poimboeuf
2025-03-25  8:34   ` [tip: objtool/urgent] objtool, regulator: rk808: Remove potential " tip-bot2 for Josh Poimboeuf
2025-03-25 13:17     ` Mark Brown
2025-03-25 22:09   ` tip-bot2 for Josh Poimboeuf
2025-03-24 21:56 ` [PATCH 21/22] pwm: mediatek: Prevent divide-by-zero in pwm_mediatek_config() Josh Poimboeuf
2025-03-25  8:34   ` [tip: objtool/urgent] objtool, pwm: mediatek: Prevent theoretical " tip-bot2 for Josh Poimboeuf
2025-03-26 10:35     ` Uwe Kleine-König
2025-03-26 11:11       ` Peter Zijlstra
2025-03-27  5:44       ` Josh Poimboeuf
2025-03-27  8:27         ` Uwe Kleine-König
     [not found]     ` <m7pgkp3ueo7iqgqf74upjrihr3mpmb3sqhwegnjxxwsrgx2jsw@dnec5iqiyobh>
     [not found]       ` <Z-Uv60sD_S2xYVB1@gmail.com>
2025-03-27 18:14         ` Uwe Kleine-König
2025-03-27 21:21           ` Ingo Molnar
2025-03-28 10:24             ` Uwe Kleine-König
2025-03-28 13:45               ` Ingo Molnar
2025-03-28 18:19                 ` Uwe Kleine-König
2025-03-25 22:09   ` tip-bot2 for Josh Poimboeuf
2025-03-27 11:06   ` tip-bot2 for Josh Poimboeuf
2025-03-24 21:56 ` [PATCH 22/22] lkdtm: Obfuscate do_nothing() pointer Josh Poimboeuf
2025-03-25  8:34   ` [tip: objtool/urgent] objtool, lkdtm: Obfuscate the " tip-bot2 for Josh Poimboeuf
2025-03-25 19:39   ` [PATCH 22/22] lkdtm: Obfuscate " Kees Cook
2025-03-25 22:09   ` [tip: objtool/urgent] objtool, lkdtm: Obfuscate the " tip-bot2 for Josh Poimboeuf
2025-03-27 11:06   ` tip-bot2 for Josh Poimboeuf
2025-03-28 13:48   ` tip-bot2 for Josh Poimboeuf

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