diff options
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.patch | 217 |
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 - |