lkml.org 
[lkml]   [2016]   [Oct]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[GIT PULL] core kernel fixes
Linus,

Please pull the latest core-urgent-for-linus git tree from:

git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git core-urgent-for-linus

# HEAD: a705e07b9c80df27b6bb12f7a4cd4cf4ed2f728b cpu/hotplug: Use distinct name for cpu_hotplug.dep_map

A CPU hotplug debuggability fix and three objtool false positive warnings fixes
for new GCC6 code generation patterns.

Thanks,

Ingo

------------------>
Joonas Lahtinen (1):
cpu/hotplug: Use distinct name for cpu_hotplug.dep_map

Josh Poimboeuf (3):
objtool: Support '-mtune=atom' stack frame setup instruction
objtool: Improve rare switch jump table pattern detection
objtool: Skip all "unreachable instruction" warnings for gcov kernels


kernel/cpu.c | 2 +-
tools/objtool/arch/x86/decode.c | 9 ++++++
tools/objtool/builtin-check.c | 68 +++++++++++++++++++++--------------------
3 files changed, 45 insertions(+), 34 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index 5df20d6d1520..29de1a9352c0 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -228,7 +228,7 @@ static struct {
.wq = __WAIT_QUEUE_HEAD_INITIALIZER(cpu_hotplug.wq),
.lock = __MUTEX_INITIALIZER(cpu_hotplug.lock),
#ifdef CONFIG_DEBUG_LOCK_ALLOC
- .dep_map = {.name = "cpu_hotplug.lock" },
+ .dep_map = STATIC_LOCKDEP_MAP_INIT("cpu_hotplug.dep_map", &cpu_hotplug.dep_map),
#endif
};

diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c
index c0c0b265e88e..b63a31be1218 100644
--- a/tools/objtool/arch/x86/decode.c
+++ b/tools/objtool/arch/x86/decode.c
@@ -98,6 +98,15 @@ int arch_decode_instruction(struct elf *elf, struct section *sec,
*type = INSN_FP_SETUP;
break;

+ case 0x8d:
+ if (insn.rex_prefix.bytes &&
+ insn.rex_prefix.bytes[0] == 0x48 &&
+ insn.modrm.nbytes && insn.modrm.bytes[0] == 0x2c &&
+ insn.sib.nbytes && insn.sib.bytes[0] == 0x24)
+ /* lea %(rsp), %rbp */
+ *type = INSN_FP_SETUP;
+ break;
+
case 0x90:
*type = INSN_NOP;
break;
diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c
index 143b6cdd7f06..4490601a9235 100644
--- a/tools/objtool/builtin-check.c
+++ b/tools/objtool/builtin-check.c
@@ -97,6 +97,19 @@ static struct instruction *next_insn_same_sec(struct objtool_file *file,
return next;
}

+static bool gcov_enabled(struct objtool_file *file)
+{
+ struct section *sec;
+ struct symbol *sym;
+
+ list_for_each_entry(sec, &file->elf->sections, list)
+ list_for_each_entry(sym, &sec->symbol_list, list)
+ if (!strncmp(sym->name, "__gcov_.", 8))
+ return true;
+
+ return false;
+}
+
#define for_each_insn(file, insn) \
list_for_each_entry(insn, &file->insn_list, list)

@@ -713,6 +726,7 @@ static struct rela *find_switch_table(struct objtool_file *file,
struct instruction *insn)
{
struct rela *text_rela, *rodata_rela;
+ struct instruction *orig_insn = insn;

text_rela = find_rela_by_dest_range(insn->sec, insn->offset, insn->len);
if (text_rela && text_rela->sym == file->rodata->sym) {
@@ -733,10 +747,16 @@ static struct rela *find_switch_table(struct objtool_file *file,

/* case 3 */
func_for_each_insn_continue_reverse(file, func, insn) {
- if (insn->type == INSN_JUMP_UNCONDITIONAL ||
- insn->type == INSN_JUMP_DYNAMIC)
+ if (insn->type == INSN_JUMP_DYNAMIC)
break;

+ /* allow small jumps within the range */
+ if (insn->type == INSN_JUMP_UNCONDITIONAL &&
+ insn->jump_dest &&
+ (insn->jump_dest->offset <= insn->offset ||
+ insn->jump_dest->offset >= orig_insn->offset))
+ break;
+
text_rela = find_rela_by_dest_range(insn->sec, insn->offset,
insn->len);
if (text_rela && text_rela->sym == file->rodata->sym)
@@ -1034,34 +1054,6 @@ static int validate_branch(struct objtool_file *file,
return 0;
}

-static bool is_gcov_insn(struct instruction *insn)
-{
- struct rela *rela;
- struct section *sec;
- struct symbol *sym;
- unsigned long offset;
-
- rela = find_rela_by_dest_range(insn->sec, insn->offset, insn->len);
- if (!rela)
- return false;
-
- if (rela->sym->type != STT_SECTION)
- return false;
-
- sec = rela->sym->sec;
- offset = rela->addend + insn->offset + insn->len - rela->offset;
-
- list_for_each_entry(sym, &sec->symbol_list, list) {
- if (sym->type != STT_OBJECT)
- continue;
-
- if (offset >= sym->offset && offset < sym->offset + sym->len)
- return (!memcmp(sym->name, "__gcov0.", 8));
- }
-
- return false;
-}
-
static bool is_kasan_insn(struct instruction *insn)
{
return (insn->type == INSN_CALL &&
@@ -1083,9 +1075,6 @@ static bool ignore_unreachable_insn(struct symbol *func,
if (insn->type == INSN_NOP)
return true;

- if (is_gcov_insn(insn))
- return true;
-
/*
* Check if this (or a subsequent) instruction is related to
* CONFIG_UBSAN or CONFIG_KASAN.
@@ -1146,6 +1135,19 @@ static int validate_functions(struct objtool_file *file)
ignore_unreachable_insn(func, insn))
continue;

+ /*
+ * gcov produces a lot of unreachable
+ * instructions. If we get an unreachable
+ * warning and the file has gcov enabled, just
+ * ignore it, and all other such warnings for
+ * the file.
+ */
+ if (!file->ignore_unreachables &&
+ gcov_enabled(file)) {
+ file->ignore_unreachables = true;
+ continue;
+ }
+
WARN_FUNC("function has unreachable instruction", insn->sec, insn->offset);
warnings++;
}
\
 
 \ /
  Last update: 2016-10-18 12:15    [W:0.036 / U:0.272 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site