Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 351267d9 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'core-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull misc fixes from Ingo Molnar:
 "A CPU hotplug debuggability fix and three objtool false positive
  warnings fixes for new GCC6 code generation patterns"

* 'core-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  cpu/hotplug: Use distinct name for cpu_hotplug.dep_map
  objtool: Skip all "unreachable instruction" warnings for gcov kernels
  objtool: Improve rare switch jump table pattern detection
  objtool: Support '-mtune=atom' stack frame setup instruction
parents 5aa43efe a705e07b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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
};

+9 −0
Original line number Diff line number Diff line
@@ -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;
+35 −33
Original line number Diff line number Diff line
@@ -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,8 +747,14 @@ 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,
@@ -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++;
			}