aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.9.21/0063-objtool-Allow-alternatives-to-be-ignored.patch
diff options
context:
space:
mode:
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.patch166
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
+