diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.9.21/0063-objtool-Allow-alternatives-to-be-ignored.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.9.21/0063-objtool-Allow-alternatives-to-be-ignored.patch | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.9.21/0063-objtool-Allow-alternatives-to-be-ignored.patch b/common/recipes-kernel/linux/linux-yocto-4.9.21/0063-objtool-Allow-alternatives-to-be-ignored.patch new file mode 100644 index 00000000..81beb919 --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.9.21/0063-objtool-Allow-alternatives-to-be-ignored.patch @@ -0,0 +1,166 @@ +From 6af5187229c3acb6956484634a80b69e149aa3d6 Mon Sep 17 00:00:00 2001 +From: Josh Poimboeuf <jpoimboe@redhat.com> +Date: Thu, 11 Jan 2018 21:46:24 +0000 +Subject: [PATCH 063/102] objtool: Allow alternatives to be ignored + +commit 258c76059cece01bebae098e81bacb1af2edad17 upstream. + +Getting objtool to understand retpolines is going to be a bit of a +challenge. For now, take advantage of the fact that retpolines are +patched in with alternatives. Just read the original (sane) +non-alternative instruction, and ignore the patched-in retpoline. + +This allows objtool to understand the control flow *around* the +retpoline, even if it can't yet follow what's inside. This means the +ORC unwinder will fail to unwind from inside a retpoline, but will work +fine otherwise. + +Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com> +Signed-off-by: David Woodhouse <dwmw@amazon.co.uk> +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +Cc: gnomes@lxorguk.ukuu.org.uk +Cc: Rik van Riel <riel@redhat.com> +Cc: Andi Kleen <ak@linux.intel.com> +Cc: thomas.lendacky@amd.com +Cc: Peter Zijlstra <peterz@infradead.org> +Cc: Linus Torvalds <torvalds@linux-foundation.org> +Cc: Jiri Kosina <jikos@kernel.org> +Cc: Andy Lutomirski <luto@amacapital.net> +Cc: Dave Hansen <dave.hansen@intel.com> +Cc: Kees Cook <keescook@google.com> +Cc: Tim Chen <tim.c.chen@linux.intel.com> +Cc: Greg Kroah-Hartman <gregkh@linux-foundation.org> +Cc: Paul Turner <pjt@google.com> +Link: https://lkml.kernel.org/r/1515707194-20531-3-git-send-email-dwmw@amazon.co.uk +[dwmw2: Applies to tools/objtool/builtin-check.c not check.[ch]] +Signed-off-by: David Woodhouse <dwmw@amazon.co.uk> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + tools/objtool/builtin-check.c | 64 ++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 57 insertions(+), 7 deletions(-) + +diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c +index 36784b8..ee71d4c 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; ++ bool alt_group, visited, ignore_alts; + struct symbol *call_dest; + struct instruction *jump_dest; + struct list_head alts; +@@ -353,6 +353,40 @@ static void add_ignores(struct objtool_file *file) + } + + /* ++ * FIXME: For now, just ignore any alternatives which add retpolines. This is ++ * a temporary hack, as it doesn't allow ORC to unwind from inside a retpoline. ++ * But it at least allows objtool to understand the control flow *around* the ++ * retpoline. ++ */ ++static int add_nospec_ignores(struct objtool_file *file) ++{ ++ struct section *sec; ++ struct rela *rela; ++ struct instruction *insn; ++ ++ sec = find_section_by_name(file->elf, ".rela.discard.nospec"); ++ 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 %s", sec->name); ++ return -1; ++ } ++ ++ insn = find_insn(file, rela->sym->sec, rela->addend); ++ if (!insn) { ++ WARN("bad .discard.nospec entry"); ++ return -1; ++ } ++ ++ insn->ignore_alts = true; ++ } ++ ++ return 0; ++} ++ ++/* + * Find the destination instructions for all jumps. + */ + static int add_jump_destinations(struct objtool_file *file) +@@ -435,11 +469,18 @@ static int add_call_destinations(struct objtool_file *file) + dest_off = insn->offset + insn->len + insn->immediate; + insn->call_dest = find_symbol_by_offset(insn->sec, + dest_off); ++ /* ++ * FIXME: Thanks to retpolines, it's now considered ++ * normal for a function to call within itself. So ++ * disable this warning for now. ++ */ ++#if 0 + if (!insn->call_dest) { + WARN_FUNC("can't find call dest symbol at offset 0x%lx", + insn->sec, insn->offset, dest_off); + return -1; + } ++#endif + } else if (rela->sym->type == STT_SECTION) { + insn->call_dest = find_symbol_by_offset(rela->sym->sec, + rela->addend+4); +@@ -601,12 +642,6 @@ static int add_special_section_alts(struct objtool_file *file) + return ret; + + list_for_each_entry_safe(special_alt, tmp, &special_alts, list) { +- alt = malloc(sizeof(*alt)); +- if (!alt) { +- WARN("malloc failed"); +- ret = -1; +- goto out; +- } + + orig_insn = find_insn(file, special_alt->orig_sec, + special_alt->orig_off); +@@ -617,6 +652,10 @@ static int add_special_section_alts(struct objtool_file *file) + goto out; + } + ++ /* Ignore retpoline alternatives. */ ++ if (orig_insn->ignore_alts) ++ continue; ++ + new_insn = NULL; + if (!special_alt->group || special_alt->new_len) { + new_insn = find_insn(file, special_alt->new_sec, +@@ -642,6 +681,13 @@ static int add_special_section_alts(struct objtool_file *file) + goto out; + } + ++ alt = malloc(sizeof(*alt)); ++ if (!alt) { ++ WARN("malloc failed"); ++ ret = -1; ++ goto out; ++ } ++ + alt->insn = new_insn; + list_add_tail(&alt->list, &orig_insn->alts); + +@@ -852,6 +898,10 @@ static int decode_sections(struct objtool_file *file) + + add_ignores(file); + ++ ret = add_nospec_ignores(file); ++ if (ret) ++ return ret; ++ + ret = add_jump_destinations(file); + if (ret) + return ret; +-- +2.7.4 + |