aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.9.21/0086-objtool-Improve-detection-of-BUG-and-other-dead-ends.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.9.21/0086-objtool-Improve-detection-of-BUG-and-other-dead-ends.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.9.21/0086-objtool-Improve-detection-of-BUG-and-other-dead-ends.patch217
1 files changed, 0 insertions, 217 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.9.21/0086-objtool-Improve-detection-of-BUG-and-other-dead-ends.patch b/common/recipes-kernel/linux/linux-yocto-4.9.21/0086-objtool-Improve-detection-of-BUG-and-other-dead-ends.patch
deleted file mode 100644
index f659e885..00000000
--- a/common/recipes-kernel/linux/linux-yocto-4.9.21/0086-objtool-Improve-detection-of-BUG-and-other-dead-ends.patch
+++ /dev/null
@@ -1,217 +0,0 @@
-From 655125acee5c084743a8bae4ffe2b723856594ce Mon Sep 17 00:00:00 2001
-From: Josh Poimboeuf <jpoimboe@redhat.com>
-Date: Tue, 21 Feb 2017 15:35:32 -0600
-Subject: [PATCH 86/93] objtool: Improve detection of BUG() and other dead ends
-
-commit d1091c7fa3d52ebce4dd3f15d04155b3469b2f90 upstream.
-
-The BUG() macro's use of __builtin_unreachable() via the unreachable()
-macro tells gcc that the instruction is a dead end, and that it's safe
-to assume the current code path will not execute past the previous
-instruction.
-
-On x86, the BUG() macro is implemented with the 'ud2' instruction. When
-objtool's branch analysis sees that instruction, it knows the current
-code path has come to a dead end.
-
-Peter Zijlstra has been working on a patch to change the WARN macros to
-use 'ud2'. That patch will break objtool's assumption that 'ud2' is
-always a dead end.
-
-Generally it's best for objtool to avoid making those kinds of
-assumptions anyway. The more ignorant it is of kernel code internals,
-the better.
-
-So create a more generic way for objtool to detect dead ends by adding
-an annotation to the unreachable() macro. The annotation stores a
-pointer to the end of the unreachable code path in an '__unreachable'
-section. Objtool can read that section to find the dead ends.
-
-Tested-by: Peter Zijlstra (Intel) <peterz@infradead.org>
-Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Thomas Gleixner <tglx@linutronix.de>
-Link: http://lkml.kernel.org/r/41a6d33971462ebd944a1c60ad4bf5be86c17b77.1487712920.git.jpoimboe@redhat.com
-Signed-off-by: Ingo Molnar <mingo@kernel.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- arch/x86/kernel/vmlinux.lds.S | 1 +
- include/linux/compiler-gcc.h | 13 ++++++++-
- tools/objtool/arch.h | 5 ++--
- tools/objtool/arch/x86/decode.c | 3 ---
- tools/objtool/builtin-check.c | 60 ++++++++++++++++++++++++++++++++++++++---
- 5 files changed, 71 insertions(+), 11 deletions(-)
-
-diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
-index c7194e9..4ef267f 100644
---- a/arch/x86/kernel/vmlinux.lds.S
-+++ b/arch/x86/kernel/vmlinux.lds.S
-@@ -353,6 +353,7 @@ SECTIONS
- /DISCARD/ : {
- *(.eh_frame)
- *(__func_stack_frame_non_standard)
-+ *(__unreachable)
- }
- }
-
-diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
-index 362a1e17..b69d102 100644
---- a/include/linux/compiler-gcc.h
-+++ b/include/linux/compiler-gcc.h
-@@ -199,6 +199,17 @@
- #endif
- #endif
-
-+#ifdef CONFIG_STACK_VALIDATION
-+#define annotate_unreachable() ({ \
-+ asm("1:\t\n" \
-+ ".pushsection __unreachable, \"a\"\t\n" \
-+ ".long 1b\t\n" \
-+ ".popsection\t\n"); \
-+})
-+#else
-+#define annotate_unreachable()
-+#endif
-+
- /*
- * Mark a position in code as unreachable. This can be used to
- * suppress control flow warnings after asm blocks that transfer
-@@ -208,7 +219,7 @@
- * this in the preprocessor, but we can live with this because they're
- * unreleased. Really, we need to have autoconf for the kernel.
- */
--#define unreachable() __builtin_unreachable()
-+#define unreachable() annotate_unreachable(); __builtin_unreachable()
-
- /* Mark a function definition as prohibited from being cloned. */
- #define __noclone __attribute__((__noclone__, __optimize__("no-tracer")))
-diff --git a/tools/objtool/arch.h b/tools/objtool/arch.h
-index f7350fc..a59e061 100644
---- a/tools/objtool/arch.h
-+++ b/tools/objtool/arch.h
-@@ -31,9 +31,8 @@
- #define INSN_CALL_DYNAMIC 8
- #define INSN_RETURN 9
- #define INSN_CONTEXT_SWITCH 10
--#define INSN_BUG 11
--#define INSN_NOP 12
--#define INSN_OTHER 13
-+#define INSN_NOP 11
-+#define INSN_OTHER 12
- #define INSN_LAST INSN_OTHER
-
- int arch_decode_instruction(struct elf *elf, struct section *sec,
-diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c
-index 5e0dea2..9fb487f 100644
---- a/tools/objtool/arch/x86/decode.c
-+++ b/tools/objtool/arch/x86/decode.c
-@@ -118,9 +118,6 @@ int arch_decode_instruction(struct elf *elf, struct section *sec,
- op2 == 0x35)
- /* sysenter, sysret */
- *type = INSN_CONTEXT_SWITCH;
-- else if (op2 == 0x0b || op2 == 0xb9)
-- /* ud2 */
-- *type = INSN_BUG;
- else if (op2 == 0x0d || op2 == 0x1f)
- /* nopl/nopw */
- *type = INSN_NOP;
-diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c
-index 377bff0..ad9eda9 100644
---- a/tools/objtool/builtin-check.c
-+++ b/tools/objtool/builtin-check.c
-@@ -51,7 +51,7 @@ struct instruction {
- unsigned int len, state;
- unsigned char type;
- unsigned long immediate;
-- bool alt_group, visited, ignore_alts;
-+ bool alt_group, visited, dead_end, ignore_alts;
- struct symbol *call_dest;
- struct instruction *jump_dest;
- struct list_head alts;
-@@ -330,6 +330,54 @@ static int decode_instructions(struct objtool_file *file)
- }
-
- /*
-+ * Find all uses of the unreachable() macro, which are code path dead ends.
-+ */
-+static int add_dead_ends(struct objtool_file *file)
-+{
-+ struct section *sec;
-+ struct rela *rela;
-+ struct instruction *insn;
-+ bool found;
-+
-+ sec = find_section_by_name(file->elf, ".rela__unreachable");
-+ if (!sec)
-+ return 0;
-+
-+ list_for_each_entry(rela, &sec->rela_list, list) {
-+ if (rela->sym->type != STT_SECTION) {
-+ WARN("unexpected relocation symbol type in .rela__unreachable");
-+ return -1;
-+ }
-+ insn = find_insn(file, rela->sym->sec, rela->addend);
-+ if (insn)
-+ insn = list_prev_entry(insn, list);
-+ else if (rela->addend == rela->sym->sec->len) {
-+ found = false;
-+ list_for_each_entry_reverse(insn, &file->insn_list, list) {
-+ if (insn->sec == rela->sym->sec) {
-+ found = true;
-+ break;
-+ }
-+ }
-+
-+ if (!found) {
-+ WARN("can't find unreachable insn at %s+0x%x",
-+ rela->sym->sec->name, rela->addend);
-+ return -1;
-+ }
-+ } else {
-+ WARN("can't find unreachable insn at %s+0x%x",
-+ rela->sym->sec->name, rela->addend);
-+ return -1;
-+ }
-+
-+ insn->dead_end = true;
-+ }
-+
-+ return 0;
-+}
-+
-+/*
- * Warnings shouldn't be reported for ignored functions.
- */
- static void add_ignores(struct objtool_file *file)
-@@ -896,6 +944,10 @@ static int decode_sections(struct objtool_file *file)
- if (ret)
- return ret;
-
-+ ret = add_dead_ends(file);
-+ if (ret)
-+ return ret;
-+
- add_ignores(file);
-
- ret = add_nospec_ignores(file);
-@@ -1094,13 +1146,13 @@ static int validate_branch(struct objtool_file *file,
-
- return 0;
-
-- case INSN_BUG:
-- return 0;
--
- default:
- break;
- }
-
-+ if (insn->dead_end)
-+ return 0;
-+
- insn = next_insn_same_sec(file, insn);
- if (!insn) {
- WARN("%s: unexpected end of section", sec->name);
---
-2.7.4
-