All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/24] objtool/x86: noinstr vs PARAVIRT
@ 2021-06-24  9:40 Peter Zijlstra
  2021-06-24  9:41 ` [PATCH v2 01/24] x86/xen: Mark cpu_bringup_and_idle() as dead_end_function Peter Zijlstra
                   ` (24 more replies)
  0 siblings, 25 replies; 101+ messages in thread
From: Peter Zijlstra @ 2021-06-24  9:40 UTC (permalink / raw)
  To: jpoimboe, tglx
  Cc: linux-kernel, peterz, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver

Hi,

Per long standing request from Thomas, this makes the noinstr validation work
with PARAVIRT=y.

It isn't exactly pretty, but it does work.

With all this on top of tip/master (which includes some of the previous round),
all (*) the robots seem to get is endless garbage like:

  vmlinux.o: warning: objtool: __rdgsbase_inactive()+0x24: call to ftrace_likely_update() leaves .noinstr.text section

And my secret plan is to pull the KPTI CR3 swizzling into C such that all that
will insta explode and become unfixable.

Steve, can I please delete TRACE_BRANCH_PROFILING and PROFILE_ALL_BRANCHES already?


(*) there were also a few reports from 0day running out of memory.


^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v2 01/24] x86/xen: Mark cpu_bringup_and_idle() as dead_end_function
  2021-06-24  9:40 [PATCH v2 00/24] objtool/x86: noinstr vs PARAVIRT Peter Zijlstra
@ 2021-06-24  9:41 ` Peter Zijlstra
  2021-06-24 10:49   ` Juergen Gross
                     ` (3 more replies)
  2021-06-24  9:41 ` [PATCH v2 02/24] objtool: Introduce CFI hash Peter Zijlstra
                   ` (23 subsequent siblings)
  24 siblings, 4 replies; 101+ messages in thread
From: Peter Zijlstra @ 2021-06-24  9:41 UTC (permalink / raw)
  To: jpoimboe, tglx
  Cc: linux-kernel, peterz, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver

The asm_cpu_bringup_and_idle() function is required to push the return
value on the stack in order to make ORC happy, but the only reason
objtool doesn't complain is because of a happy accident.

The thing is that asm_cpu_bringup_and_idle() doesn't return, so
validate_branch() never terminates and falls through to the next
function, which in the normal case is the hypercall_page. And that, as
it happens, is 4095 NOPs and a RET.

Make asm_cpu_bringup_and_idle() terminate on it's own, by making the
function it calls as a dead-end. This way we no longer rely on what
code happens to come after.

Fixes: c3881eb58d56 ("x86/xen: Make the secondary CPU idle tasks reliable")
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 tools/objtool/check.c |    1 +
 1 file changed, 1 insertion(+)

--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -177,6 +177,7 @@ static bool __dead_end_function(struct o
 		"rewind_stack_do_exit",
 		"kunit_try_catch_throw",
 		"xen_start_kernel",
+		"cpu_bringup_and_idle",
 	};
 
 	if (!func)



^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v2 02/24] objtool: Introduce CFI hash
  2021-06-24  9:40 [PATCH v2 00/24] objtool/x86: noinstr vs PARAVIRT Peter Zijlstra
  2021-06-24  9:41 ` [PATCH v2 01/24] x86/xen: Mark cpu_bringup_and_idle() as dead_end_function Peter Zijlstra
@ 2021-06-24  9:41 ` Peter Zijlstra
  2021-06-30 12:45   ` Miroslav Benes
                     ` (2 more replies)
  2021-06-24  9:41 ` [PATCH v2 03/24] objtool: Handle __sanitize_cov*() tail calls Peter Zijlstra
                   ` (22 subsequent siblings)
  24 siblings, 3 replies; 101+ messages in thread
From: Peter Zijlstra @ 2021-06-24  9:41 UTC (permalink / raw)
  To: jpoimboe, tglx
  Cc: linux-kernel, peterz, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver, Andi Kleen

Andi reported that objtool on vmlinux.o consumes more memory than his
system has, leading to horrific performance.

This is in part because we keep a struct instruction for every
instruction in the file in-memory. Shrink struct instruction by
removing the CFI state (which includes full register state) from it
and demand allocating it.

Given most instructions don't actually change CFI state, there's lots
of repetition there, so add a hash table to find previous CFI
instances.

Reduces memory consumption (and runtime) for processing an
x86_64-allyesconfig:

  pre:  4:40.84 real,   143.99 user,    44.18 sys,      30624988 mem
  post: 2:14.61 real,   108.58 user,    25.04 sys,      16396184 mem

Suggested-by: Andi Kleen <andi@firstfloor.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 tools/objtool/arch/x86/decode.c       |    2 
 tools/objtool/check.c                 |  155 ++++++++++++++++++++++++++++++----
 tools/objtool/include/objtool/cfi.h   |    2 
 tools/objtool/include/objtool/check.h |    4 
 tools/objtool/orc_gen.c               |   15 ++-
 5 files changed, 154 insertions(+), 24 deletions(-)

--- a/tools/objtool/arch/x86/decode.c
+++ b/tools/objtool/arch/x86/decode.c
@@ -781,7 +781,7 @@ int arch_rewrite_retpolines(struct objto
 
 int arch_decode_hint_reg(struct instruction *insn, u8 sp_reg)
 {
-	struct cfi_reg *cfa = &insn->cfi.cfa;
+	struct cfi_reg *cfa = &insn->cfip->cfa;
 
 	switch (sp_reg) {
 	case ORC_REG_UNDEFINED:
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -5,6 +5,7 @@
 
 #include <string.h>
 #include <stdlib.h>
+#include <sys/mman.h>
 
 #include <arch/elf.h>
 #include <objtool/builtin.h>
@@ -26,7 +27,10 @@ struct alternative {
 	bool skip_orig;
 };
 
-struct cfi_init_state initial_func_cfi;
+static unsigned long nr_cfi, nr_cfi_reused, nr_cfi_cache;
+
+static struct cfi_init_state initial_func_cfi;
+static struct cfi_state func_cfi;
 
 struct instruction *find_insn(struct objtool_file *file,
 			      struct section *sec, unsigned long offset)
@@ -265,6 +269,87 @@ static void init_insn_state(struct insn_
 		state->noinstr = sec->noinstr;
 }
 
+static struct cfi_state *cfi_alloc(void)
+{
+	struct cfi_state *cfi = calloc(sizeof(struct cfi_state), 1);
+	if (!cfi) {
+		WARN("calloc failed");
+		exit(1);
+	}
+	nr_cfi++;
+	init_cfi_state(cfi);
+	return cfi;
+}
+
+struct cfi_state *insn_get_cfi(struct instruction *insn)
+{
+	if (!insn->cfip)
+		insn->cfip = cfi_alloc();
+
+	return insn->cfip;
+}
+
+static int cfi_bits;
+static struct hlist_head *cfi_hash;
+
+static inline bool cficmp(struct cfi_state *cfi1, struct cfi_state *cfi2)
+{
+	return memcmp((void *)cfi1 + sizeof(cfi1->hash),
+		      (void *)cfi2 + sizeof(cfi2->hash),
+		      sizeof(struct cfi_state) - sizeof(struct hlist_node));
+}
+
+static inline u32 cfi_key(struct cfi_state *cfi)
+{
+	return jhash((void *)cfi + sizeof(cfi->hash),
+		     sizeof(*cfi) - sizeof(cfi->hash), 0);
+}
+
+static struct cfi_state *cfi_hash_find(struct cfi_state *cfi)
+{
+	struct hlist_head *head = &cfi_hash[hash_min(cfi_key(cfi), cfi_bits)];
+	struct cfi_state *obj;
+
+	hlist_for_each_entry(obj, head, hash) {
+		if (!cficmp(cfi, obj)) {
+			nr_cfi_cache++;
+			return obj;
+		}
+	}
+
+	obj = cfi_alloc();
+	*obj = *cfi;
+	hlist_add_head(&obj->hash, head);
+
+	return obj;
+}
+
+static void cfi_hash_add(struct cfi_state *cfi)
+{
+	struct hlist_head *head = &cfi_hash[hash_min(cfi_key(cfi), cfi_bits)];
+
+	hlist_add_head(&cfi->hash, head);
+}
+
+static void *cfi_hash_alloc(unsigned long size)
+{
+	cfi_bits = max(10, ilog2(size));
+	cfi_hash = mmap(NULL, sizeof(struct hlist_head) << cfi_bits,
+			PROT_READ|PROT_WRITE,
+			MAP_PRIVATE|MAP_ANON, -1, 0);
+	if (cfi_hash == (void *)-1L) {
+		WARN("mmap fail cfi_hash");
+		cfi_hash = NULL;
+	}  else if (stats) {
+		printf("cfi_bits: %d\n", cfi_bits);
+	}
+
+	return cfi_hash;
+}
+
+static unsigned long nr_insns;
+static unsigned long nr_visited;
+
 /*
  * Call the arch-specific instruction decoder for all the instructions and add
  * them to the global instruction list.
@@ -275,7 +360,6 @@ static int decode_instructions(struct ob
 	struct symbol *func;
 	unsigned long offset;
 	struct instruction *insn;
-	unsigned long nr_insns = 0;
 	int ret;
 
 	for_each_sec(file, sec) {
@@ -301,7 +385,6 @@ static int decode_instructions(struct ob
 			memset(insn, 0, sizeof(*insn));
 			INIT_LIST_HEAD(&insn->alts);
 			INIT_LIST_HEAD(&insn->stack_ops);
-			init_cfi_state(&insn->cfi);
 
 			insn->sec = sec;
 			insn->offset = offset;
@@ -1136,7 +1219,6 @@ static int handle_group_alt(struct objto
 		memset(nop, 0, sizeof(*nop));
 		INIT_LIST_HEAD(&nop->alts);
 		INIT_LIST_HEAD(&nop->stack_ops);
-		init_cfi_state(&nop->cfi);
 
 		nop->sec = special_alt->new_sec;
 		nop->offset = special_alt->new_off + special_alt->new_len;
@@ -1546,9 +1628,10 @@ static void set_func_state(struct cfi_st
 static int read_unwind_hints(struct objtool_file *file)
 {
 	struct section *sec, *relocsec;
-	struct reloc *reloc;
 	struct unwind_hint *hint;
 	struct instruction *insn;
+	struct cfi_state *cfi;
+	struct reloc *reloc;
 	int i;
 
 	sec = find_section_by_name(file->elf, ".discard.unwind_hints");
@@ -1586,19 +1669,21 @@ static int read_unwind_hints(struct objt
 		insn->hint = true;
 
 		if (hint->type == UNWIND_HINT_TYPE_FUNC) {
-			set_func_state(&insn->cfi);
+			insn->cfip = &func_cfi;
 			continue;
 		}
 
+		cfi = insn_get_cfi(insn);
+
 		if (arch_decode_hint_reg(insn, hint->sp_reg)) {
 			WARN_FUNC("unsupported unwind_hint sp base reg %d",
 				  insn->sec, insn->offset, hint->sp_reg);
 			return -1;
 		}
 
-		insn->cfi.cfa.offset = bswap_if_needed(hint->sp_offset);
-		insn->cfi.type = hint->type;
-		insn->cfi.end = hint->end;
+		cfi->cfa.offset = bswap_if_needed(hint->sp_offset);
+		cfi->type = hint->type;
+		cfi->end = hint->end;
 	}
 
 	return 0;
@@ -2452,13 +2537,18 @@ static int propagate_alt_cfi(struct objt
 	if (!insn->alt_group)
 		return 0;
 
+	if (!insn->cfip) {
+		WARN("CFI missing");
+		return -1;
+	}
+
 	alt_cfi = insn->alt_group->cfi;
 	group_off = insn->offset - insn->alt_group->first_insn->offset;
 
 	if (!alt_cfi[group_off]) {
-		alt_cfi[group_off] = &insn->cfi;
+		alt_cfi[group_off] = insn->cfip;
 	} else {
-		if (memcmp(alt_cfi[group_off], &insn->cfi, sizeof(struct cfi_state))) {
+		if (cficmp(alt_cfi[group_off], insn->cfip)) {
 			WARN_FUNC("stack layout conflict in alternatives",
 				  insn->sec, insn->offset);
 			return -1;
@@ -2509,9 +2599,14 @@ static int handle_insn_ops(struct instru
 
 static bool insn_cfi_match(struct instruction *insn, struct cfi_state *cfi2)
 {
-	struct cfi_state *cfi1 = &insn->cfi;
+	struct cfi_state *cfi1 = insn->cfip;
 	int i;
 
+	if (!cfi1) {
+		WARN("CFI missing");
+		return false;
+	}
+
 	if (memcmp(&cfi1->cfa, &cfi2->cfa, sizeof(cfi1->cfa))) {
 
 		WARN_FUNC("stack state mismatch: cfa1=%d%+d cfa2=%d%+d",
@@ -2696,7 +2791,7 @@ static int validate_branch(struct objtoo
 			   struct instruction *insn, struct insn_state state)
 {
 	struct alternative *alt;
-	struct instruction *next_insn;
+	struct instruction *next_insn, *prev_insn = NULL;
 	struct section *sec;
 	u8 visited;
 	int ret;
@@ -2725,15 +2820,24 @@ static int validate_branch(struct objtoo
 
 			if (insn->visited & visited)
 				return 0;
-		}
+		} else
+			nr_visited++;
 
 		if (state.noinstr)
 			state.instr += insn->instr;
 
-		if (insn->hint)
-			state.cfi = insn->cfi;
-		else
-			insn->cfi = state.cfi;
+		if (insn->hint) {
+			state.cfi = *insn->cfip;
+		} else {
+			/* XXX track if we actually changed state.cfi */
+
+			if (prev_insn && !cficmp(prev_insn->cfip, &state.cfi)) {
+				insn->cfip = prev_insn->cfip;
+				nr_cfi_reused++;
+			} else {
+				insn->cfip = cfi_hash_find(&state.cfi);
+			}
+		}
 
 		insn->visited |= visited;
 
@@ -2883,6 +2987,7 @@ static int validate_branch(struct objtoo
 			return 1;
 		}
 
+		prev_insn = insn;
 		insn = next_insn;
 	}
 
@@ -3138,12 +3243,19 @@ int check(struct objtool_file *file)
 	int ret, warnings = 0;
 
 	arch_initial_func_cfi_state(&initial_func_cfi);
+	init_cfi_state(&func_cfi);
+	set_func_state(&func_cfi);
 
 	ret = decode_sections(file);
 	if (ret < 0)
 		goto out;
 	warnings += ret;
 
+	if (!cfi_hash_alloc(1UL << (file->elf->symbol_bits - 3)))
+		goto out;
+
+	cfi_hash_add(&func_cfi);
+
 	if (list_empty(&file->insn_list))
 		goto out;
 
@@ -3192,6 +3304,13 @@ int check(struct objtool_file *file)
 		warnings += ret;
 	}
 
+	if (stats) {
+		printf("nr_visited: %ld\n", nr_visited);
+		printf("nr_cfi: %ld\n", nr_cfi);
+		printf("nr_cfi_reused: %ld\n", nr_cfi_reused);
+		printf("nr_cfi_cache: %ld\n", nr_cfi_cache);
+	}
+
 out:
 	/*
 	 *  For now, don't fail the kernel build on fatal warnings.  These
--- a/tools/objtool/include/objtool/cfi.h
+++ b/tools/objtool/include/objtool/cfi.h
@@ -7,6 +7,7 @@
 #define _OBJTOOL_CFI_H
 
 #include <arch/cfi_regs.h>
+#include <linux/list.h>
 
 #define CFI_UNDEFINED		-1
 #define CFI_CFA			-2
@@ -24,6 +25,7 @@ struct cfi_init_state {
 };
 
 struct cfi_state {
+	struct hlist_node hash; /* must be first, cficmp() */
 	struct cfi_reg regs[CFI_NUM_REGS];
 	struct cfi_reg vals[CFI_NUM_REGS];
 	struct cfi_reg cfa;
--- a/tools/objtool/include/objtool/check.h
+++ b/tools/objtool/include/objtool/check.h
@@ -60,9 +60,11 @@ struct instruction {
 	struct list_head alts;
 	struct symbol *func;
 	struct list_head stack_ops;
-	struct cfi_state cfi;
+	struct cfi_state *cfip;
 };
 
+extern struct cfi_state *insn_get_cfi(struct instruction *);
+
 static inline bool is_static_jump(struct instruction *insn)
 {
 	return insn->type == INSN_JUMP_CONDITIONAL ||
--- a/tools/objtool/orc_gen.c
+++ b/tools/objtool/orc_gen.c
@@ -13,13 +13,19 @@
 #include <objtool/warn.h>
 #include <objtool/endianness.h>
 
-static int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi)
+static int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi,
+			  struct instruction *insn)
 {
-	struct instruction *insn = container_of(cfi, struct instruction, cfi);
 	struct cfi_reg *bp = &cfi->regs[CFI_BP];
 
 	memset(orc, 0, sizeof(*orc));
 
+	if (!cfi) {
+		orc->end = 0;
+		orc->sp_reg = ORC_REG_UNDEFINED;
+		return 0;
+	}
+
 	orc->end = cfi->end;
 
 	if (cfi->cfa.base == CFI_UNDEFINED) {
@@ -162,7 +168,7 @@ int orc_create(struct objtool_file *file
 			int i;
 
 			if (!alt_group) {
-				if (init_orc_entry(&orc, &insn->cfi))
+				if (init_orc_entry(&orc, insn->cfip, insn))
 					return -1;
 				if (!memcmp(&prev_orc, &orc, sizeof(orc)))
 					continue;
@@ -186,7 +192,8 @@ int orc_create(struct objtool_file *file
 				struct cfi_state *cfi = alt_group->cfi[i];
 				if (!cfi)
 					continue;
-				if (init_orc_entry(&orc, cfi))
+				/* errors are reported on the original insn */
+				if (init_orc_entry(&orc, cfi, insn))
 					return -1;
 				if (!memcmp(&prev_orc, &orc, sizeof(orc)))
 					continue;



^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v2 03/24] objtool: Handle __sanitize_cov*() tail calls
  2021-06-24  9:40 [PATCH v2 00/24] objtool/x86: noinstr vs PARAVIRT Peter Zijlstra
  2021-06-24  9:41 ` [PATCH v2 01/24] x86/xen: Mark cpu_bringup_and_idle() as dead_end_function Peter Zijlstra
  2021-06-24  9:41 ` [PATCH v2 02/24] objtool: Introduce CFI hash Peter Zijlstra
@ 2021-06-24  9:41 ` Peter Zijlstra
  2021-06-25 11:05   ` Marco Elver
                     ` (3 more replies)
  2021-06-24  9:41 ` [PATCH v2 04/24] x86/kvm: Always inline sev_*guest() Peter Zijlstra
                   ` (21 subsequent siblings)
  24 siblings, 4 replies; 101+ messages in thread
From: Peter Zijlstra @ 2021-06-24  9:41 UTC (permalink / raw)
  To: jpoimboe, tglx
  Cc: linux-kernel, peterz, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver

Turns out the compilers also generate tail calls to __sanitize_cov*(),
make sure to also patch those out in noinstr code.

Fixes: 0f1441b44e82 ("objtool: Fix noinstr vs KCOV")
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 tools/objtool/arch/x86/decode.c      |   20 ++++
 tools/objtool/check.c                |  153 ++++++++++++++++++-----------------
 tools/objtool/include/objtool/arch.h |    1 
 3 files changed, 100 insertions(+), 74 deletions(-)

--- a/tools/objtool/arch/x86/decode.c
+++ b/tools/objtool/arch/x86/decode.c
@@ -659,6 +659,26 @@ const char *arch_nop_insn(int len)
 	return nops[len-1];
 }
 
+#define BYTE_RET	0xC3
+
+const char *arch_ret_insn(int len)
+{
+	static const char ret[5][5] = {
+		{ BYTE_RET },
+		{ BYTE_RET, BYTES_NOP1 },
+		{ BYTE_RET, BYTES_NOP2 },
+		{ BYTE_RET, BYTES_NOP3 },
+		{ BYTE_RET, BYTES_NOP4 },
+	};
+
+	if (len < 1 || len > 5) {
+		WARN("invalid RET size: %d\n", len);
+		return NULL;
+	}
+
+	return ret[len-1];
+}
+
 /* asm/alternative.h ? */
 
 #define ALTINSTR_FLAG_INV	(1 << 15)
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -828,6 +828,74 @@ static struct reloc *insn_reloc(struct o
 	return insn->reloc;
 }
 
+static void remove_insn_ops(struct instruction *insn)
+{
+	struct stack_op *op, *tmp;
+
+	list_for_each_entry_safe(op, tmp, &insn->stack_ops, list) {
+		list_del(&op->list);
+		free(op);
+	}
+}
+
+static void add_call_dest(struct objtool_file *file, struct instruction *insn,
+			  struct symbol *dest, bool sibling)
+{
+	struct reloc *reloc = insn_reloc(file, insn);
+
+	insn->call_dest = dest;
+	if (!dest)
+		return;
+
+	if (insn->call_dest->static_call_tramp) {
+		list_add_tail(&insn->call_node,
+			      &file->static_call_list);
+	}
+
+	if (insn->sec->noinstr &&
+	    !strncmp(insn->call_dest->name, "__sanitizer_cov_", 16)) {
+		if (reloc) {
+			reloc->type = R_NONE;
+			elf_write_reloc(file->elf, reloc);
+		}
+
+		elf_write_insn(file->elf, insn->sec,
+			       insn->offset, insn->len,
+			       sibling ? arch_ret_insn(insn->len)
+			               : arch_nop_insn(insn->len));
+
+		insn->type = sibling ? INSN_RETURN : INSN_NOP;
+	}
+
+	if (mcount && !strcmp(insn->call_dest->name, "__fentry__")) {
+		if (sibling)
+			WARN_FUNC("Tail call to __fentry__ !?!?", insn->sec, insn->offset);
+
+		if (reloc) {
+			reloc->type = R_NONE;
+			elf_write_reloc(file->elf, reloc);
+		}
+
+		elf_write_insn(file->elf, insn->sec,
+			       insn->offset, insn->len,
+			       arch_nop_insn(insn->len));
+
+		insn->type = INSN_NOP;
+
+		list_add_tail(&insn->mcount_loc_node,
+			      &file->mcount_loc_list);
+	}
+
+	/*
+	 * Whatever stack impact regular CALLs have, should be undone
+	 * by the RETURN of the called function.
+	 *
+	 * Annotated intra-function calls retain the stack_ops but
+	 * are converted to JUMP, see read_intra_function_calls().
+	 */
+	remove_insn_ops(insn);
+}
+
 /*
  * Find the destination instructions for all jumps.
  */
@@ -866,11 +934,7 @@ static int add_jump_destinations(struct
 			continue;
 		} else if (insn->func) {
 			/* internal or external sibling call (with reloc) */
-			insn->call_dest = reloc->sym;
-			if (insn->call_dest->static_call_tramp) {
-				list_add_tail(&insn->call_node,
-					      &file->static_call_list);
-			}
+			add_call_dest(file, insn, reloc->sym, true);
 			continue;
 		} else if (reloc->sym->sec->idx) {
 			dest_sec = reloc->sym->sec;
@@ -926,13 +990,8 @@ static int add_jump_destinations(struct
 
 			} else if (insn->jump_dest->func->pfunc != insn->func->pfunc &&
 				   insn->jump_dest->offset == insn->jump_dest->func->offset) {
-
 				/* internal sibling call (without reloc) */
-				insn->call_dest = insn->jump_dest->func;
-				if (insn->call_dest->static_call_tramp) {
-					list_add_tail(&insn->call_node,
-						      &file->static_call_list);
-				}
+				add_call_dest(file, insn, insn->jump_dest->func, true);
 			}
 		}
 	}
@@ -940,16 +999,6 @@ static int add_jump_destinations(struct
 	return 0;
 }
 
-static void remove_insn_ops(struct instruction *insn)
-{
-	struct stack_op *op, *tmp;
-
-	list_for_each_entry_safe(op, tmp, &insn->stack_ops, list) {
-		list_del(&op->list);
-		free(op);
-	}
-}
-
 static struct symbol *find_call_destination(struct section *sec, unsigned long offset)
 {
 	struct symbol *call_dest;
@@ -968,6 +1017,7 @@ static int add_call_destinations(struct
 {
 	struct instruction *insn;
 	unsigned long dest_off;
+	struct symbol *dest;
 	struct reloc *reloc;
 
 	for_each_insn(file, insn) {
@@ -977,7 +1027,9 @@ static int add_call_destinations(struct
 		reloc = insn_reloc(file, insn);
 		if (!reloc) {
 			dest_off = arch_jump_destination(insn);
-			insn->call_dest = find_call_destination(insn->sec, dest_off);
+			dest = find_call_destination(insn->sec, dest_off);
+
+			add_call_dest(file, insn, dest, false);
 
 			if (insn->ignore)
 				continue;
@@ -995,9 +1047,8 @@ static int add_call_destinations(struct
 
 		} else if (reloc->sym->type == STT_SECTION) {
 			dest_off = arch_dest_reloc_offset(reloc->addend);
-			insn->call_dest = find_call_destination(reloc->sym->sec,
-								dest_off);
-			if (!insn->call_dest) {
+			dest = find_call_destination(reloc->sym->sec, dest_off);
+			if (!dest) {
 				WARN_FUNC("can't find call dest symbol at %s+0x%lx",
 					  insn->sec, insn->offset,
 					  reloc->sym->sec->name,
@@ -1005,6 +1056,8 @@ static int add_call_destinations(struct
 				return -1;
 			}
 
+			add_call_dest(file, insn, dest, false);
+
 		} else if (arch_is_retpoline(reloc->sym)) {
 			/*
 			 * Retpoline calls are really dynamic calls in
@@ -1020,55 +1073,7 @@ static int add_call_destinations(struct
 			continue;
 
 		} else
-			insn->call_dest = reloc->sym;
-
-		if (insn->call_dest && insn->call_dest->static_call_tramp) {
-			list_add_tail(&insn->call_node,
-				      &file->static_call_list);
-		}
-
-		/*
-		 * Many compilers cannot disable KCOV with a function attribute
-		 * so they need a little help, NOP out any KCOV calls from noinstr
-		 * text.
-		 */
-		if (insn->sec->noinstr &&
-		    !strncmp(insn->call_dest->name, "__sanitizer_cov_", 16)) {
-			if (reloc) {
-				reloc->type = R_NONE;
-				elf_write_reloc(file->elf, reloc);
-			}
-
-			elf_write_insn(file->elf, insn->sec,
-				       insn->offset, insn->len,
-				       arch_nop_insn(insn->len));
-			insn->type = INSN_NOP;
-		}
-
-		if (mcount && !strcmp(insn->call_dest->name, "__fentry__")) {
-			if (reloc) {
-				reloc->type = R_NONE;
-				elf_write_reloc(file->elf, reloc);
-			}
-
-			elf_write_insn(file->elf, insn->sec,
-				       insn->offset, insn->len,
-				       arch_nop_insn(insn->len));
-
-			insn->type = INSN_NOP;
-
-			list_add_tail(&insn->mcount_loc_node,
-				      &file->mcount_loc_list);
-		}
-
-		/*
-		 * Whatever stack impact regular CALLs have, should be undone
-		 * by the RETURN of the called function.
-		 *
-		 * Annotated intra-function calls retain the stack_ops but
-		 * are converted to JUMP, see read_intra_function_calls().
-		 */
-		remove_insn_ops(insn);
+			add_call_dest(file, insn, reloc->sym, false);
 	}
 
 	return 0;
--- a/tools/objtool/include/objtool/arch.h
+++ b/tools/objtool/include/objtool/arch.h
@@ -82,6 +82,7 @@ unsigned long arch_jump_destination(stru
 unsigned long arch_dest_reloc_offset(int addend);
 
 const char *arch_nop_insn(int len);
+const char *arch_ret_insn(int len);
 
 int arch_decode_hint_reg(struct instruction *insn, u8 sp_reg);
 



^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v2 04/24] x86/kvm: Always inline sev_*guest()
  2021-06-24  9:40 [PATCH v2 00/24] objtool/x86: noinstr vs PARAVIRT Peter Zijlstra
                   ` (2 preceding siblings ...)
  2021-06-24  9:41 ` [PATCH v2 03/24] objtool: Handle __sanitize_cov*() tail calls Peter Zijlstra
@ 2021-06-24  9:41 ` Peter Zijlstra
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
  2021-06-24  9:41 ` [PATCH v2 05/24] x86/kvm: Always inline vmload() / vmsave() Peter Zijlstra
                   ` (20 subsequent siblings)
  24 siblings, 1 reply; 101+ messages in thread
From: Peter Zijlstra @ 2021-06-24  9:41 UTC (permalink / raw)
  To: jpoimboe, tglx
  Cc: linux-kernel, peterz, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver

vmlinux.o: warning: objtool: svm_vcpu_enter_exit()+0x4d: call to sev_es_guest() leaves .noinstr.text section
vmlinux.o: warning: objtool: svm_vcpu_enter_exit()+0x50: call to sev_guest() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/kvm/svm/svm.h |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

--- a/arch/x86/kvm/svm/svm.h
+++ b/arch/x86/kvm/svm/svm.h
@@ -204,12 +204,12 @@ DECLARE_PER_CPU(struct svm_cpu_data *, s
 
 void recalc_intercepts(struct vcpu_svm *svm);
 
-static inline struct kvm_svm *to_kvm_svm(struct kvm *kvm)
+static __always_inline struct kvm_svm *to_kvm_svm(struct kvm *kvm)
 {
 	return container_of(kvm, struct kvm_svm, kvm);
 }
 
-static inline bool sev_guest(struct kvm *kvm)
+static __always_inline bool sev_guest(struct kvm *kvm)
 {
 #ifdef CONFIG_KVM_AMD_SEV
 	struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
@@ -220,7 +220,7 @@ static inline bool sev_guest(struct kvm
 #endif
 }
 
-static inline bool sev_es_guest(struct kvm *kvm)
+static __always_inline bool sev_es_guest(struct kvm *kvm)
 {
 #ifdef CONFIG_KVM_AMD_SEV
 	struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;



^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v2 05/24] x86/kvm: Always inline vmload() / vmsave()
  2021-06-24  9:40 [PATCH v2 00/24] objtool/x86: noinstr vs PARAVIRT Peter Zijlstra
                   ` (3 preceding siblings ...)
  2021-06-24  9:41 ` [PATCH v2 04/24] x86/kvm: Always inline sev_*guest() Peter Zijlstra
@ 2021-06-24  9:41 ` Peter Zijlstra
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
  2021-06-24  9:41 ` [PATCH v2 06/24] x86: Always inline context_tracking_guest_enter() Peter Zijlstra
                   ` (19 subsequent siblings)
  24 siblings, 1 reply; 101+ messages in thread
From: Peter Zijlstra @ 2021-06-24  9:41 UTC (permalink / raw)
  To: jpoimboe, tglx
  Cc: linux-kernel, peterz, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver

vmlinux.o: warning: objtool: svm_vcpu_enter_exit()+0xea: call to vmload() leaves .noinstr.text section
vmlinux.o: warning: objtool: svm_vcpu_enter_exit()+0x133: call to vmsave() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/kvm/svm/svm_ops.h |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/arch/x86/kvm/svm/svm_ops.h
+++ b/arch/x86/kvm/svm/svm_ops.h
@@ -56,12 +56,12 @@ static inline void invlpga(unsigned long
  * VMSAVE, VMLOAD, etc... is still controlled by the effective address size,
  * hence 'unsigned long' instead of 'hpa_t'.
  */
-static inline void vmsave(unsigned long pa)
+static __always_inline void vmsave(unsigned long pa)
 {
 	svm_asm1(vmsave, "a" (pa), "memory");
 }
 
-static inline void vmload(unsigned long pa)
+static __always_inline void vmload(unsigned long pa)
 {
 	svm_asm1(vmload, "a" (pa), "memory");
 }



^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v2 06/24] x86: Always inline context_tracking_guest_enter()
  2021-06-24  9:40 [PATCH v2 00/24] objtool/x86: noinstr vs PARAVIRT Peter Zijlstra
                   ` (4 preceding siblings ...)
  2021-06-24  9:41 ` [PATCH v2 05/24] x86/kvm: Always inline vmload() / vmsave() Peter Zijlstra
@ 2021-06-24  9:41 ` Peter Zijlstra
  2021-08-20 23:22   ` Josh Poimboeuf
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
  2021-06-24  9:41 ` [PATCH v2 07/24] x86/kvm: Always inline to_svm() Peter Zijlstra
                   ` (18 subsequent siblings)
  24 siblings, 2 replies; 101+ messages in thread
From: Peter Zijlstra @ 2021-06-24  9:41 UTC (permalink / raw)
  To: jpoimboe, tglx
  Cc: linux-kernel, peterz, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver

Yes, it really did out-of-line this....

vmlinux.o: warning: objtool: vmx_vcpu_enter_exit()+0x31: call to context_tracking_guest_enter() leaves .noinstr.text section

000000000019f660 <context_tracking_guest_enter>:
  19f660:	e8 00 00 00 00       	callq  19f665 <context_tracking_guest_enter+0x5>	19f661: R_X86_64_PLT32	__sanitizer_cov_trace_pc-0x4
  19f665:	31 c0                	xor    %eax,%eax
  19f667:	c3                   	retq   

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 include/linux/context_tracking.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/include/linux/context_tracking.h
+++ b/include/linux/context_tracking.h
@@ -105,7 +105,7 @@ static inline void user_exit_irqoff(void
 static inline enum ctx_state exception_enter(void) { return 0; }
 static inline void exception_exit(enum ctx_state prev_ctx) { }
 static inline enum ctx_state ct_state(void) { return CONTEXT_DISABLED; }
-static inline bool context_tracking_guest_enter(void) { return false; }
+static __always_inline bool context_tracking_guest_enter(void) { return false; }
 static inline void context_tracking_guest_exit(void) { }
 
 #endif /* !CONFIG_CONTEXT_TRACKING */



^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v2 07/24] x86/kvm: Always inline to_svm()
  2021-06-24  9:40 [PATCH v2 00/24] objtool/x86: noinstr vs PARAVIRT Peter Zijlstra
                   ` (5 preceding siblings ...)
  2021-06-24  9:41 ` [PATCH v2 06/24] x86: Always inline context_tracking_guest_enter() Peter Zijlstra
@ 2021-06-24  9:41 ` Peter Zijlstra
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
  2021-06-24  9:41 ` [PATCH v2 08/24] x86/kvm: Always inline evmcs_write64() Peter Zijlstra
                   ` (17 subsequent siblings)
  24 siblings, 1 reply; 101+ messages in thread
From: Peter Zijlstra @ 2021-06-24  9:41 UTC (permalink / raw)
  To: jpoimboe, tglx
  Cc: linux-kernel, peterz, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver

vmlinux.o: warning: objtool: svm_vcpu_enter_exit()+0x13: call to to_svm() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/kvm/svm/svm.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/arch/x86/kvm/svm/svm.h
+++ b/arch/x86/kvm/svm/svm.h
@@ -252,7 +252,7 @@ static inline bool vmcb_is_dirty(struct
         return !test_bit(bit, (unsigned long *)&vmcb->control.clean);
 }
 
-static inline struct vcpu_svm *to_svm(struct kvm_vcpu *vcpu)
+static __always_inline struct vcpu_svm *to_svm(struct kvm_vcpu *vcpu)
 {
 	return container_of(vcpu, struct vcpu_svm, vcpu);
 }



^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v2 08/24] x86/kvm: Always inline evmcs_write64()
  2021-06-24  9:40 [PATCH v2 00/24] objtool/x86: noinstr vs PARAVIRT Peter Zijlstra
                   ` (6 preceding siblings ...)
  2021-06-24  9:41 ` [PATCH v2 07/24] x86/kvm: Always inline to_svm() Peter Zijlstra
@ 2021-06-24  9:41 ` Peter Zijlstra
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
  2021-06-24  9:41 ` [PATCH v2 09/24] x86: Always inline ip_within_syscall_gap() Peter Zijlstra
                   ` (16 subsequent siblings)
  24 siblings, 1 reply; 101+ messages in thread
From: Peter Zijlstra @ 2021-06-24  9:41 UTC (permalink / raw)
  To: jpoimboe, tglx
  Cc: linux-kernel, peterz, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver

vmlinux.o: warning: objtool: vmx_update_host_rsp()+0x64: call to evmcs_write64() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/kvm/vmx/evmcs.h |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/arch/x86/kvm/vmx/evmcs.h
+++ b/arch/x86/kvm/vmx/evmcs.h
@@ -97,7 +97,7 @@ static __always_inline int get_evmcs_off
 
 #undef ROL16
 
-static inline void evmcs_write64(unsigned long field, u64 value)
+static __always_inline void evmcs_write64(unsigned long field, u64 value)
 {
 	u16 clean_field;
 	int offset = get_evmcs_offset(field, &clean_field);
@@ -187,7 +187,7 @@ static inline void evmcs_load(u64 phys_a
 
 __init void evmcs_sanitize_exec_ctrls(struct vmcs_config *vmcs_conf);
 #else /* !IS_ENABLED(CONFIG_HYPERV) */
-static inline void evmcs_write64(unsigned long field, u64 value) {}
+static __always_inline void evmcs_write64(unsigned long field, u64 value) {}
 static inline void evmcs_write32(unsigned long field, u32 value) {}
 static inline void evmcs_write16(unsigned long field, u16 value) {}
 static inline u64 evmcs_read64(unsigned long field) { return 0; }



^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v2 09/24] x86: Always inline ip_within_syscall_gap()
  2021-06-24  9:40 [PATCH v2 00/24] objtool/x86: noinstr vs PARAVIRT Peter Zijlstra
                   ` (7 preceding siblings ...)
  2021-06-24  9:41 ` [PATCH v2 08/24] x86/kvm: Always inline evmcs_write64() Peter Zijlstra
@ 2021-06-24  9:41 ` Peter Zijlstra
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
  2021-06-24  9:41 ` [PATCH v2 10/24] x86/sev: Fix noinstr for vc_ghcb_invalidate() Peter Zijlstra
                   ` (15 subsequent siblings)
  24 siblings, 1 reply; 101+ messages in thread
From: Peter Zijlstra @ 2021-06-24  9:41 UTC (permalink / raw)
  To: jpoimboe, tglx
  Cc: linux-kernel, peterz, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver

vmlinux.o: warning: objtool: vc_switch_off_ist()+0x20: call to ip_within_syscall_gap.isra.0() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/include/asm/ptrace.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/arch/x86/include/asm/ptrace.h
+++ b/arch/x86/include/asm/ptrace.h
@@ -181,7 +181,7 @@ static inline bool any_64bit_mode(struct
 #define current_user_stack_pointer()	current_pt_regs()->sp
 #define compat_user_stack_pointer()	current_pt_regs()->sp
 
-static inline bool ip_within_syscall_gap(struct pt_regs *regs)
+static __always_inline bool ip_within_syscall_gap(struct pt_regs *regs)
 {
 	bool ret = (regs->ip >= (unsigned long)entry_SYSCALL_64 &&
 		    regs->ip <  (unsigned long)entry_SYSCALL_64_safe_stack);



^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v2 10/24] x86/sev: Fix noinstr for vc_ghcb_invalidate()
  2021-06-24  9:40 [PATCH v2 00/24] objtool/x86: noinstr vs PARAVIRT Peter Zijlstra
                   ` (8 preceding siblings ...)
  2021-06-24  9:41 ` [PATCH v2 09/24] x86: Always inline ip_within_syscall_gap() Peter Zijlstra
@ 2021-06-24  9:41 ` Peter Zijlstra
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
  2021-06-24  9:41 ` [PATCH v2 11/24] locking/lockdep: Avoid RCU-induced noinstr fail Peter Zijlstra
                   ` (14 subsequent siblings)
  24 siblings, 1 reply; 101+ messages in thread
From: Peter Zijlstra @ 2021-06-24  9:41 UTC (permalink / raw)
  To: jpoimboe, tglx
  Cc: linux-kernel, peterz, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver

vmlinux.o: warning: objtool: __sev_put_ghcb()+0x88: call to __memset() leaves .noinstr.text section
vmlinux.o: warning: objtool: __sev_es_nmi_complete()+0x39: call to __memset() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/kernel/sev-shared.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/arch/x86/kernel/sev-shared.c
+++ b/arch/x86/kernel/sev-shared.c
@@ -64,7 +64,7 @@ static bool sev_es_negotiate_protocol(vo
 static __always_inline void vc_ghcb_invalidate(struct ghcb *ghcb)
 {
 	ghcb->save.sw_exit_code = 0;
-	memset(ghcb->save.valid_bitmap, 0, sizeof(ghcb->save.valid_bitmap));
+	__builtin_memset(ghcb->save.valid_bitmap, 0, sizeof(ghcb->save.valid_bitmap));
 }
 
 static bool vc_decoding_needed(unsigned long exit_code)



^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v2 11/24] locking/lockdep: Avoid RCU-induced noinstr fail
  2021-06-24  9:40 [PATCH v2 00/24] objtool/x86: noinstr vs PARAVIRT Peter Zijlstra
                   ` (9 preceding siblings ...)
  2021-06-24  9:41 ` [PATCH v2 10/24] x86/sev: Fix noinstr for vc_ghcb_invalidate() Peter Zijlstra
@ 2021-06-24  9:41 ` Peter Zijlstra
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
  2021-06-24  9:41 ` [PATCH v2 12/24] x86/paravirt: Mark arch_local_irq_*() __always_inline Peter Zijlstra
                   ` (13 subsequent siblings)
  24 siblings, 1 reply; 101+ messages in thread
From: Peter Zijlstra @ 2021-06-24  9:41 UTC (permalink / raw)
  To: jpoimboe, tglx
  Cc: linux-kernel, peterz, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver

vmlinux.o: warning: objtool: look_up_lock_class()+0xc7: call to rcu_read_lock_any_held() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 kernel/locking/lockdep.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -888,7 +888,7 @@ look_up_lock_class(const struct lockdep_
 	if (DEBUG_LOCKS_WARN_ON(!irqs_disabled()))
 		return NULL;
 
-	hlist_for_each_entry_rcu(class, hash_head, hash_entry) {
+	hlist_for_each_entry_rcu_notrace(class, hash_head, hash_entry) {
 		if (class->key == key) {
 			/*
 			 * Huh! same key, different name? Did someone trample



^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v2 12/24] x86/paravirt: Mark arch_local_irq_*() __always_inline
  2021-06-24  9:40 [PATCH v2 00/24] objtool/x86: noinstr vs PARAVIRT Peter Zijlstra
                   ` (10 preceding siblings ...)
  2021-06-24  9:41 ` [PATCH v2 11/24] locking/lockdep: Avoid RCU-induced noinstr fail Peter Zijlstra
@ 2021-06-24  9:41 ` Peter Zijlstra
  2021-06-24 10:51   ` Juergen Gross
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
  2021-06-24  9:41 ` [PATCH v2 13/24] x86/paravirt: Use PVOP_* for paravirt calls Peter Zijlstra
                   ` (12 subsequent siblings)
  24 siblings, 2 replies; 101+ messages in thread
From: Peter Zijlstra @ 2021-06-24  9:41 UTC (permalink / raw)
  To: jpoimboe, tglx
  Cc: linux-kernel, peterz, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver

vmlinux.o: warning: objtool: lockdep_hardirqs_on()+0x72: call to arch_local_save_flags() leaves .noinstr.text section
vmlinux.o: warning: objtool: lockdep_hardirqs_off()+0x73: call to arch_local_save_flags() leaves .noinstr.text section
vmlinux.o: warning: objtool: match_held_lock()+0x11f: call to arch_local_save_flags() leaves .noinstr.text section

vmlinux.o: warning: objtool: lock_is_held_type()+0x4e: call to arch_local_irq_save() leaves .noinstr.text section

vmlinux.o: warning: objtool: lock_is_held_type()+0x65: call to arch_local_irq_disable() leaves .noinstr.text section

vmlinux.o: warning: objtool: lock_is_held_type()+0xfe: call to arch_local_irq_enable() leaves .noinstr.text section

It makes no sense to not inline these things.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/include/asm/paravirt.h |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -681,23 +681,23 @@ bool __raw_callee_save___native_vcpu_is_
 	((struct paravirt_callee_save) { func })
 
 #ifdef CONFIG_PARAVIRT_XXL
-static inline notrace unsigned long arch_local_save_flags(void)
+static __always_inline unsigned long arch_local_save_flags(void)
 {
 	return PVOP_ALT_CALLEE0(unsigned long, irq.save_fl, "pushf; pop %%rax;",
 				ALT_NOT(X86_FEATURE_XENPV));
 }
 
-static inline notrace void arch_local_irq_disable(void)
+static __always_inline void arch_local_irq_disable(void)
 {
 	PVOP_ALT_VCALLEE0(irq.irq_disable, "cli;", ALT_NOT(X86_FEATURE_XENPV));
 }
 
-static inline notrace void arch_local_irq_enable(void)
+static __always_inline void arch_local_irq_enable(void)
 {
 	PVOP_ALT_VCALLEE0(irq.irq_enable, "sti;", ALT_NOT(X86_FEATURE_XENPV));
 }
 
-static inline notrace unsigned long arch_local_irq_save(void)
+static __always_inline unsigned long arch_local_irq_save(void)
 {
 	unsigned long f;
 



^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v2 13/24] x86/paravirt: Use PVOP_* for paravirt calls
  2021-06-24  9:40 [PATCH v2 00/24] objtool/x86: noinstr vs PARAVIRT Peter Zijlstra
                   ` (11 preceding siblings ...)
  2021-06-24  9:41 ` [PATCH v2 12/24] x86/paravirt: Mark arch_local_irq_*() __always_inline Peter Zijlstra
@ 2021-06-24  9:41 ` Peter Zijlstra
  2021-06-24 10:52   ` Juergen Gross
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
  2021-06-24  9:41 ` [PATCH v2 14/24] x86/xen: Make read_cr2() noinstr Peter Zijlstra
                   ` (11 subsequent siblings)
  24 siblings, 2 replies; 101+ messages in thread
From: Peter Zijlstra @ 2021-06-24  9:41 UTC (permalink / raw)
  To: jpoimboe, tglx
  Cc: linux-kernel, peterz, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver

Doing unconditional indirect calls through the pv_ops vector is weird.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/include/asm/paravirt.h |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -52,11 +52,11 @@ void __init paravirt_set_cap(void);
 /* The paravirtualized I/O functions */
 static inline void slow_down_io(void)
 {
-	pv_ops.cpu.io_delay();
+	PVOP_VCALL0(cpu.io_delay);
 #ifdef REALLY_SLOW_IO
-	pv_ops.cpu.io_delay();
-	pv_ops.cpu.io_delay();
-	pv_ops.cpu.io_delay();
+	PVOP_VCALL0(cpu.io_delay);
+	PVOP_VCALL0(cpu.io_delay);
+	PVOP_VCALL0(cpu.io_delay);
 #endif
 }
 



^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v2 14/24] x86/xen: Make read_cr2() noinstr
  2021-06-24  9:40 [PATCH v2 00/24] objtool/x86: noinstr vs PARAVIRT Peter Zijlstra
                   ` (12 preceding siblings ...)
  2021-06-24  9:41 ` [PATCH v2 13/24] x86/paravirt: Use PVOP_* for paravirt calls Peter Zijlstra
@ 2021-06-24  9:41 ` Peter Zijlstra
  2021-06-24 10:55   ` Juergen Gross
                     ` (2 more replies)
  2021-06-24  9:41 ` [PATCH v2 15/24] x86/xen: Make write_cr2() noinstr Peter Zijlstra
                   ` (10 subsequent siblings)
  24 siblings, 3 replies; 101+ messages in thread
From: Peter Zijlstra @ 2021-06-24  9:41 UTC (permalink / raw)
  To: jpoimboe, tglx
  Cc: linux-kernel, peterz, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver

vmlinux.o: warning: objtool: pv_ops[41]: native_read_cr2
vmlinux.o: warning: objtool: pv_ops[41]: xen_read_cr2
vmlinux.o: warning: objtool: pv_ops[41]: xen_read_cr2_direct
vmlinux.o: warning: objtool: exc_double_fault()+0x15: call to pv_ops[41]() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/include/asm/paravirt.h |    2 +-
 arch/x86/kernel/paravirt.c      |    7 ++++++-
 arch/x86/xen/xen-asm.S          |    2 ++
 3 files changed, 9 insertions(+), 2 deletions(-)

--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -133,7 +133,7 @@ static inline void write_cr0(unsigned lo
 	PVOP_VCALL1(cpu.write_cr0, x);
 }
 
-static inline unsigned long read_cr2(void)
+static __always_inline unsigned long read_cr2(void)
 {
 	return PVOP_ALT_CALLEE0(unsigned long, mmu.read_cr2,
 				"mov %%cr2, %%rax;",
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -238,6 +238,11 @@ struct pv_info pv_info = {
 /* 64-bit pagetable entries */
 #define PTE_IDENT	__PV_IS_CALLEE_SAVE(_paravirt_ident_64)
 
+static noinstr unsigned long pv_native_read_cr2(void)
+{
+	return native_read_cr2();
+}
+
 struct paravirt_patch_template pv_ops = {
 	/* Cpu ops. */
 	.cpu.io_delay		= native_io_delay,
@@ -298,7 +303,7 @@ struct paravirt_patch_template pv_ops =
 	.mmu.exit_mmap		= paravirt_nop,
 
 #ifdef CONFIG_PARAVIRT_XXL
-	.mmu.read_cr2		= __PV_IS_CALLEE_SAVE(native_read_cr2),
+	.mmu.read_cr2		= __PV_IS_CALLEE_SAVE(pv_native_read_cr2),
 	.mmu.write_cr2		= native_write_cr2,
 	.mmu.read_cr3		= __native_read_cr3,
 	.mmu.write_cr3		= native_write_cr3,
--- a/arch/x86/xen/xen-asm.S
+++ b/arch/x86/xen/xen-asm.S
@@ -102,6 +102,7 @@ SYM_FUNC_START(check_events)
 	ret
 SYM_FUNC_END(check_events)
 
+.pushsection .noinstr.text, "ax"
 SYM_FUNC_START(xen_read_cr2)
 	FRAME_BEGIN
 	_ASM_MOV PER_CPU_VAR(xen_vcpu), %_ASM_AX
@@ -116,6 +117,7 @@ SYM_FUNC_START(xen_read_cr2_direct)
 	FRAME_END
 	ret
 SYM_FUNC_END(xen_read_cr2_direct);
+.popsection
 
 .macro xen_pv_trap name
 SYM_CODE_START(xen_\name)



^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v2 15/24] x86/xen: Make write_cr2() noinstr
  2021-06-24  9:40 [PATCH v2 00/24] objtool/x86: noinstr vs PARAVIRT Peter Zijlstra
                   ` (13 preceding siblings ...)
  2021-06-24  9:41 ` [PATCH v2 14/24] x86/xen: Make read_cr2() noinstr Peter Zijlstra
@ 2021-06-24  9:41 ` Peter Zijlstra
  2021-06-24 10:56   ` Juergen Gross
                     ` (2 more replies)
  2021-06-24  9:41 ` [PATCH v2 16/24] x86/xen: Make get_debugreg() noinstr Peter Zijlstra
                   ` (9 subsequent siblings)
  24 siblings, 3 replies; 101+ messages in thread
From: Peter Zijlstra @ 2021-06-24  9:41 UTC (permalink / raw)
  To: jpoimboe, tglx
  Cc: linux-kernel, peterz, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver

vmlinux.o: warning: objtool: pv_ops[42]: native_write_cr2
vmlinux.o: warning: objtool: pv_ops[42]: xen_write_cr2
vmlinux.o: warning: objtool: exc_nmi()+0x127: call to pv_ops[42]() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/include/asm/paravirt.h |    2 +-
 arch/x86/kernel/paravirt.c      |    7 ++++++-
 arch/x86/xen/mmu_pv.c           |    3 ++-
 3 files changed, 9 insertions(+), 3 deletions(-)

--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -140,7 +140,7 @@ static __always_inline unsigned long rea
 				ALT_NOT(X86_FEATURE_XENPV));
 }
 
-static inline void write_cr2(unsigned long x)
+static __always_inline void write_cr2(unsigned long x)
 {
 	PVOP_VCALL1(mmu.write_cr2, x);
 }
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -243,6 +243,11 @@ static noinstr unsigned long pv_native_r
 	return native_read_cr2();
 }
 
+static noinstr void pv_native_write_cr2(unsigned long val)
+{
+	native_write_cr2(val);
+}
+
 struct paravirt_patch_template pv_ops = {
 	/* Cpu ops. */
 	.cpu.io_delay		= native_io_delay,
@@ -304,7 +309,7 @@ struct paravirt_patch_template pv_ops =
 
 #ifdef CONFIG_PARAVIRT_XXL
 	.mmu.read_cr2		= __PV_IS_CALLEE_SAVE(pv_native_read_cr2),
-	.mmu.write_cr2		= native_write_cr2,
+	.mmu.write_cr2		= pv_native_write_cr2,
 	.mmu.read_cr3		= __native_read_cr3,
 	.mmu.write_cr3		= native_write_cr3,
 
--- a/arch/x86/xen/mmu_pv.c
+++ b/arch/x86/xen/mmu_pv.c
@@ -1204,7 +1204,8 @@ static void __init xen_pagetable_init(vo
 	xen_remap_memory();
 	xen_setup_mfn_list_list();
 }
-static void xen_write_cr2(unsigned long cr2)
+
+static noinstr void xen_write_cr2(unsigned long cr2)
 {
 	this_cpu_read(xen_vcpu)->arch.cr2 = cr2;
 }



^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v2 16/24] x86/xen: Make get_debugreg() noinstr
  2021-06-24  9:40 [PATCH v2 00/24] objtool/x86: noinstr vs PARAVIRT Peter Zijlstra
                   ` (14 preceding siblings ...)
  2021-06-24  9:41 ` [PATCH v2 15/24] x86/xen: Make write_cr2() noinstr Peter Zijlstra
@ 2021-06-24  9:41 ` Peter Zijlstra
  2021-06-24 10:57   ` Juergen Gross
                     ` (2 more replies)
  2021-06-24  9:41 ` [PATCH v2 17/24] x86/xen: Make set_debugreg() noinstr Peter Zijlstra
                   ` (8 subsequent siblings)
  24 siblings, 3 replies; 101+ messages in thread
From: Peter Zijlstra @ 2021-06-24  9:41 UTC (permalink / raw)
  To: jpoimboe, tglx
  Cc: linux-kernel, peterz, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver

vmlinux.o: warning: objtool: pv_ops[1]: xen_get_debugreg
vmlinux.o: warning: objtool: pv_ops[1]: native_get_debugreg
vmlinux.o: warning: objtool: exc_debug()+0x25: call to pv_ops[1]() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/include/asm/paravirt.h      |    2 +-
 arch/x86/include/asm/xen/hypercall.h |    2 +-
 arch/x86/kernel/paravirt.c           |    8 ++++++--
 arch/x86/xen/enlighten_pv.c          |    2 +-
 4 files changed, 9 insertions(+), 5 deletions(-)

--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -113,7 +113,7 @@ static inline void __cpuid(unsigned int
 /*
  * These special macros can be used to get or set a debugging register
  */
-static inline unsigned long paravirt_get_debugreg(int reg)
+static __always_inline unsigned long paravirt_get_debugreg(int reg)
 {
 	return PVOP_CALL1(unsigned long, cpu.get_debugreg, reg);
 }
--- a/arch/x86/include/asm/xen/hypercall.h
+++ b/arch/x86/include/asm/xen/hypercall.h
@@ -314,7 +314,7 @@ HYPERVISOR_set_debugreg(int reg, unsigne
 	return _hypercall2(int, set_debugreg, reg, value);
 }
 
-static inline unsigned long
+static __always_inline unsigned long
 HYPERVISOR_get_debugreg(int reg)
 {
 	return _hypercall1(unsigned long, get_debugreg, reg);
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -248,13 +248,18 @@ static noinstr void pv_native_write_cr2(
 	native_write_cr2(val);
 }
 
+static noinstr unsigned long pv_native_get_debugreg(int regno)
+{
+	return native_get_debugreg(regno);
+}
+
 struct paravirt_patch_template pv_ops = {
 	/* Cpu ops. */
 	.cpu.io_delay		= native_io_delay,
 
 #ifdef CONFIG_PARAVIRT_XXL
 	.cpu.cpuid		= native_cpuid,
-	.cpu.get_debugreg	= native_get_debugreg,
+	.cpu.get_debugreg	= pv_native_get_debugreg,
 	.cpu.set_debugreg	= native_set_debugreg,
 	.cpu.read_cr0		= native_read_cr0,
 	.cpu.write_cr0		= native_write_cr0,
@@ -382,7 +387,6 @@ struct paravirt_patch_template pv_ops =
 
 #ifdef CONFIG_PARAVIRT_XXL
 /* At this point, native_get/set_debugreg has real function entries */
-NOKPROBE_SYMBOL(native_get_debugreg);
 NOKPROBE_SYMBOL(native_set_debugreg);
 NOKPROBE_SYMBOL(native_load_idt);
 
--- a/arch/x86/xen/enlighten_pv.c
+++ b/arch/x86/xen/enlighten_pv.c
@@ -317,7 +317,7 @@ static void xen_set_debugreg(int reg, un
 	HYPERVISOR_set_debugreg(reg, val);
 }
 
-static unsigned long xen_get_debugreg(int reg)
+static noinstr unsigned long xen_get_debugreg(int reg)
 {
 	return HYPERVISOR_get_debugreg(reg);
 }



^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v2 17/24] x86/xen: Make set_debugreg() noinstr
  2021-06-24  9:40 [PATCH v2 00/24] objtool/x86: noinstr vs PARAVIRT Peter Zijlstra
                   ` (15 preceding siblings ...)
  2021-06-24  9:41 ` [PATCH v2 16/24] x86/xen: Make get_debugreg() noinstr Peter Zijlstra
@ 2021-06-24  9:41 ` Peter Zijlstra
  2021-06-24 10:59   ` Juergen Gross
                     ` (2 more replies)
  2021-06-24  9:41 ` [PATCH v2 18/24] x86/xen: Make save_fl() noinstr Peter Zijlstra
                   ` (7 subsequent siblings)
  24 siblings, 3 replies; 101+ messages in thread
From: Peter Zijlstra @ 2021-06-24  9:41 UTC (permalink / raw)
  To: jpoimboe, tglx
  Cc: linux-kernel, peterz, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver

vmlinux.o: warning: objtool: pv_ops[2]: xen_set_debugreg
vmlinux.o: warning: objtool: pv_ops[2]: native_set_debugreg
vmlinux.o: warning: objtool: exc_debug()+0x3b: call to pv_ops[2]() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/include/asm/paravirt.h      |    2 +-
 arch/x86/include/asm/xen/hypercall.h |    2 +-
 arch/x86/kernel/paravirt.c           |    9 ++++++---
 arch/x86/xen/enlighten_pv.c          |    2 +-
 4 files changed, 9 insertions(+), 6 deletions(-)

--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -118,7 +118,7 @@ static __always_inline unsigned long par
 	return PVOP_CALL1(unsigned long, cpu.get_debugreg, reg);
 }
 #define get_debugreg(var, reg) var = paravirt_get_debugreg(reg)
-static inline void set_debugreg(unsigned long val, int reg)
+static __always_inline void set_debugreg(unsigned long val, int reg)
 {
 	PVOP_VCALL2(cpu.set_debugreg, reg, val);
 }
--- a/arch/x86/include/asm/xen/hypercall.h
+++ b/arch/x86/include/asm/xen/hypercall.h
@@ -308,7 +308,7 @@ HYPERVISOR_platform_op(struct xen_platfo
 	return _hypercall1(int, platform_op, op);
 }
 
-static inline int
+static __always_inline int
 HYPERVISOR_set_debugreg(int reg, unsigned long value)
 {
 	return _hypercall2(int, set_debugreg, reg, value);
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -253,6 +253,11 @@ static noinstr unsigned long pv_native_g
 	return native_get_debugreg(regno);
 }
 
+static noinstr void pv_native_set_debugreg(int regno, unsigned long val)
+{
+	native_set_debugreg(regno, val);
+}
+
 struct paravirt_patch_template pv_ops = {
 	/* Cpu ops. */
 	.cpu.io_delay		= native_io_delay,
@@ -260,7 +265,7 @@ struct paravirt_patch_template pv_ops =
 #ifdef CONFIG_PARAVIRT_XXL
 	.cpu.cpuid		= native_cpuid,
 	.cpu.get_debugreg	= pv_native_get_debugreg,
-	.cpu.set_debugreg	= native_set_debugreg,
+	.cpu.set_debugreg	= pv_native_set_debugreg,
 	.cpu.read_cr0		= native_read_cr0,
 	.cpu.write_cr0		= native_write_cr0,
 	.cpu.write_cr4		= native_write_cr4,
@@ -386,8 +391,6 @@ struct paravirt_patch_template pv_ops =
 };
 
 #ifdef CONFIG_PARAVIRT_XXL
-/* At this point, native_get/set_debugreg has real function entries */
-NOKPROBE_SYMBOL(native_set_debugreg);
 NOKPROBE_SYMBOL(native_load_idt);
 
 void (*paravirt_iret)(void) = native_iret;
--- a/arch/x86/xen/enlighten_pv.c
+++ b/arch/x86/xen/enlighten_pv.c
@@ -312,7 +312,7 @@ static void __init xen_init_capabilities
 	}
 }
 
-static void xen_set_debugreg(int reg, unsigned long val)
+static noinstr void xen_set_debugreg(int reg, unsigned long val)
 {
 	HYPERVISOR_set_debugreg(reg, val);
 }



^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v2 18/24] x86/xen: Make save_fl() noinstr
  2021-06-24  9:40 [PATCH v2 00/24] objtool/x86: noinstr vs PARAVIRT Peter Zijlstra
                   ` (16 preceding siblings ...)
  2021-06-24  9:41 ` [PATCH v2 17/24] x86/xen: Make set_debugreg() noinstr Peter Zijlstra
@ 2021-06-24  9:41 ` Peter Zijlstra
  2021-06-24 11:07   ` Juergen Gross
                     ` (2 more replies)
  2021-06-24  9:41 ` [PATCH v2 19/24] x86/xen: Make hypercall_page noinstr Peter Zijlstra
                   ` (6 subsequent siblings)
  24 siblings, 3 replies; 101+ messages in thread
From: Peter Zijlstra @ 2021-06-24  9:41 UTC (permalink / raw)
  To: jpoimboe, tglx
  Cc: linux-kernel, peterz, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver

vmlinux.o: warning: objtool: pv_ops[30]: native_save_fl
vmlinux.o: warning: objtool: pv_ops[30]: __raw_callee_save_xen_save_fl
vmlinux.o: warning: objtool: pv_ops[30]: xen_save_fl_direct
vmlinux.o: warning: objtool: lockdep_hardirqs_off()+0x73: call to pv_ops[30]() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/include/asm/paravirt.h |    7 +++++--
 arch/x86/kernel/irqflags.S      |    2 ++
 arch/x86/xen/irq.c              |    4 ++--
 arch/x86/xen/xen-asm.S          |   32 ++++++++++++++++----------------
 4 files changed, 25 insertions(+), 20 deletions(-)

--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -653,10 +653,10 @@ bool __raw_callee_save___native_vcpu_is_
  * functions.
  */
 #define PV_THUNK_NAME(func) "__raw_callee_save_" #func
-#define PV_CALLEE_SAVE_REGS_THUNK(func)					\
+#define __PV_CALLEE_SAVE_REGS_THUNK(func, section)			\
 	extern typeof(func) __raw_callee_save_##func;			\
 									\
-	asm(".pushsection .text;"					\
+	asm(".pushsection " section ", \"ax\";"				\
 	    ".globl " PV_THUNK_NAME(func) ";"				\
 	    ".type " PV_THUNK_NAME(func) ", @function;"			\
 	    PV_THUNK_NAME(func) ":"					\
@@ -669,6 +669,9 @@ bool __raw_callee_save___native_vcpu_is_
 	    ".size " PV_THUNK_NAME(func) ", .-" PV_THUNK_NAME(func) ";"	\
 	    ".popsection")
 
+#define PV_CALLEE_SAVE_REGS_THUNK(func)			\
+	__PV_CALLEE_SAVE_REGS_THUNK(func, ".text")
+
 /* Get a reference to a callee-save function */
 #define PV_CALLEE_SAVE(func)						\
 	((struct paravirt_callee_save) { __raw_callee_save_##func })
--- a/arch/x86/kernel/irqflags.S
+++ b/arch/x86/kernel/irqflags.S
@@ -7,9 +7,11 @@
 /*
  * unsigned long native_save_fl(void)
  */
+.pushsection .noinstr.text, "ax"
 SYM_FUNC_START(native_save_fl)
 	pushf
 	pop %_ASM_AX
 	ret
 SYM_FUNC_END(native_save_fl)
+.popsection
 EXPORT_SYMBOL(native_save_fl)
--- a/arch/x86/xen/irq.c
+++ b/arch/x86/xen/irq.c
@@ -24,7 +24,7 @@ void xen_force_evtchn_callback(void)
 	(void)HYPERVISOR_xen_version(0, NULL);
 }
 
-asmlinkage __visible unsigned long xen_save_fl(void)
+asmlinkage __visible noinstr unsigned long xen_save_fl(void)
 {
 	struct vcpu_info *vcpu;
 	unsigned long flags;
@@ -40,7 +40,7 @@ asmlinkage __visible unsigned long xen_s
 	*/
 	return (-flags) & X86_EFLAGS_IF;
 }
-PV_CALLEE_SAVE_REGS_THUNK(xen_save_fl);
+__PV_CALLEE_SAVE_REGS_THUNK(xen_save_fl, ".noinstr.text");
 
 asmlinkage __visible void xen_irq_disable(void)
 {
--- a/arch/x86/xen/xen-asm.S
+++ b/arch/x86/xen/xen-asm.S
@@ -58,22 +58,6 @@ SYM_FUNC_START(xen_irq_disable_direct)
 SYM_FUNC_END(xen_irq_disable_direct)
 
 /*
- * (xen_)save_fl is used to get the current interrupt enable status.
- * Callers expect the status to be in X86_EFLAGS_IF, and other bits
- * may be set in the return value.  We take advantage of this by
- * making sure that X86_EFLAGS_IF has the right value (and other bits
- * in that byte are 0), but other bits in the return value are
- * undefined.  We need to toggle the state of the bit, because Xen and
- * x86 use opposite senses (mask vs enable).
- */
-SYM_FUNC_START(xen_save_fl_direct)
-	testb $0xff, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask
-	setz %ah
-	addb %ah, %ah
-	ret
-SYM_FUNC_END(xen_save_fl_direct)
-
-/*
  * Force an event check by making a hypercall, but preserve regs
  * before making the call.
  */
@@ -103,6 +87,22 @@ SYM_FUNC_START(check_events)
 SYM_FUNC_END(check_events)
 
 .pushsection .noinstr.text, "ax"
+/*
+ * (xen_)save_fl is used to get the current interrupt enable status.
+ * Callers expect the status to be in X86_EFLAGS_IF, and other bits
+ * may be set in the return value.  We take advantage of this by
+ * making sure that X86_EFLAGS_IF has the right value (and other bits
+ * in that byte are 0), but other bits in the return value are
+ * undefined.  We need to toggle the state of the bit, because Xen and
+ * x86 use opposite senses (mask vs enable).
+ */
+SYM_FUNC_START(xen_save_fl_direct)
+	testb $0xff, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask
+	setz %ah
+	addb %ah, %ah
+	ret
+SYM_FUNC_END(xen_save_fl_direct)
+
 SYM_FUNC_START(xen_read_cr2)
 	FRAME_BEGIN
 	_ASM_MOV PER_CPU_VAR(xen_vcpu), %_ASM_AX



^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v2 19/24] x86/xen: Make hypercall_page noinstr
  2021-06-24  9:40 [PATCH v2 00/24] objtool/x86: noinstr vs PARAVIRT Peter Zijlstra
                   ` (17 preceding siblings ...)
  2021-06-24  9:41 ` [PATCH v2 18/24] x86/xen: Make save_fl() noinstr Peter Zijlstra
@ 2021-06-24  9:41 ` Peter Zijlstra
  2021-06-24 11:08   ` Juergen Gross
                     ` (2 more replies)
  2021-06-24  9:41 ` [PATCH v2 20/24] x86/xen: Make irq_enable() noinstr Peter Zijlstra
                   ` (5 subsequent siblings)
  24 siblings, 3 replies; 101+ messages in thread
From: Peter Zijlstra @ 2021-06-24  9:41 UTC (permalink / raw)
  To: jpoimboe, tglx
  Cc: linux-kernel, peterz, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver

vmlinux.o: warning: objtool: xen_set_debugreg()+0x3: call to hypercall_page() leaves .noinstr.text section
vmlinux.o: warning: objtool: xen_get_debugreg()+0x3: call to hypercall_page() leaves .noinstr.text section
vmlinux.o: warning: objtool: xen_irq_enable()+0x24: call to hypercall_page() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/xen/xen-head.S |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/arch/x86/xen/xen-head.S
+++ b/arch/x86/xen/xen-head.S
@@ -64,7 +64,7 @@ SYM_CODE_END(asm_cpu_bringup_and_idle)
 #endif
 #endif
 
-.pushsection .text
+.pushsection .noinstr.text, "ax"
 	.balign PAGE_SIZE
 SYM_CODE_START(hypercall_page)
 	.rept (PAGE_SIZE / 32)



^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v2 20/24] x86/xen: Make irq_enable() noinstr
  2021-06-24  9:40 [PATCH v2 00/24] objtool/x86: noinstr vs PARAVIRT Peter Zijlstra
                   ` (18 preceding siblings ...)
  2021-06-24  9:41 ` [PATCH v2 19/24] x86/xen: Make hypercall_page noinstr Peter Zijlstra
@ 2021-06-24  9:41 ` Peter Zijlstra
  2021-06-24 11:09   ` Juergen Gross
                     ` (2 more replies)
  2021-06-24  9:41 ` [PATCH v2 21/24] x86/xen: Make irq_disable() noinstr Peter Zijlstra
                   ` (4 subsequent siblings)
  24 siblings, 3 replies; 101+ messages in thread
From: Peter Zijlstra @ 2021-06-24  9:41 UTC (permalink / raw)
  To: jpoimboe, tglx
  Cc: linux-kernel, peterz, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver

vmlinux.o: warning: objtool: pv_ops[32]: native_irq_enable
vmlinux.o: warning: objtool: pv_ops[32]: __raw_callee_save_xen_irq_enable
vmlinux.o: warning: objtool: pv_ops[32]: xen_irq_enable_direct
vmlinux.o: warning: objtool: lock_is_held_type()+0xfe: call to pv_ops[32]() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/kernel/paravirt.c |    7 ++++-
 arch/x86/xen/irq.c         |    4 +--
 arch/x86/xen/xen-asm.S     |   56 ++++++++++++++++++++++-----------------------
 3 files changed, 36 insertions(+), 31 deletions(-)

--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -258,6 +258,11 @@ static noinstr void pv_native_set_debugr
 	native_set_debugreg(regno, val);
 }
 
+static noinstr void pv_native_irq_enable(void)
+{
+	native_irq_enable();
+}
+
 struct paravirt_patch_template pv_ops = {
 	/* Cpu ops. */
 	.cpu.io_delay		= native_io_delay,
@@ -302,7 +307,7 @@ struct paravirt_patch_template pv_ops =
 	/* Irq ops. */
 	.irq.save_fl		= __PV_IS_CALLEE_SAVE(native_save_fl),
 	.irq.irq_disable	= __PV_IS_CALLEE_SAVE(native_irq_disable),
-	.irq.irq_enable		= __PV_IS_CALLEE_SAVE(native_irq_enable),
+	.irq.irq_enable		= __PV_IS_CALLEE_SAVE(pv_native_irq_enable),
 	.irq.safe_halt		= native_safe_halt,
 	.irq.halt		= native_halt,
 #endif /* CONFIG_PARAVIRT_XXL */
--- a/arch/x86/xen/irq.c
+++ b/arch/x86/xen/irq.c
@@ -53,7 +53,7 @@ asmlinkage __visible void xen_irq_disabl
 }
 PV_CALLEE_SAVE_REGS_THUNK(xen_irq_disable);
 
-asmlinkage __visible void xen_irq_enable(void)
+asmlinkage __visible noinstr void xen_irq_enable(void)
 {
 	struct vcpu_info *vcpu;
 
@@ -76,7 +76,7 @@ asmlinkage __visible void xen_irq_enable
 
 	preempt_enable();
 }
-PV_CALLEE_SAVE_REGS_THUNK(xen_irq_enable);
+__PV_CALLEE_SAVE_REGS_THUNK(xen_irq_enable, ".noinstr.text");
 
 static void xen_safe_halt(void)
 {
--- a/arch/x86/xen/xen-asm.S
+++ b/arch/x86/xen/xen-asm.S
@@ -22,33 +22,6 @@
 #include <linux/linkage.h>
 
 /*
- * Enable events.  This clears the event mask and tests the pending
- * event status with one and operation.  If there are pending events,
- * then enter the hypervisor to get them handled.
- */
-SYM_FUNC_START(xen_irq_enable_direct)
-	FRAME_BEGIN
-	/* Unmask events */
-	movb $0, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask
-
-	/*
-	 * Preempt here doesn't matter because that will deal with any
-	 * pending interrupts.  The pending check may end up being run
-	 * on the wrong CPU, but that doesn't hurt.
-	 */
-
-	/* Test for pending */
-	testb $0xff, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_pending
-	jz 1f
-
-	call check_events
-1:
-	FRAME_END
-	ret
-SYM_FUNC_END(xen_irq_enable_direct)
-
-
-/*
  * Disabling events is simply a matter of making the event mask
  * non-zero.
  */
@@ -57,6 +30,8 @@ SYM_FUNC_START(xen_irq_disable_direct)
 	ret
 SYM_FUNC_END(xen_irq_disable_direct)
 
+.pushsection .noinstr.text, "ax"
+
 /*
  * Force an event check by making a hypercall, but preserve regs
  * before making the call.
@@ -86,7 +61,32 @@ SYM_FUNC_START(check_events)
 	ret
 SYM_FUNC_END(check_events)
 
-.pushsection .noinstr.text, "ax"
+/*
+ * Enable events.  This clears the event mask and tests the pending
+ * event status with one and operation.  If there are pending events,
+ * then enter the hypervisor to get them handled.
+ */
+SYM_FUNC_START(xen_irq_enable_direct)
+	FRAME_BEGIN
+	/* Unmask events */
+	movb $0, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask
+
+	/*
+	 * Preempt here doesn't matter because that will deal with any
+	 * pending interrupts.  The pending check may end up being run
+	 * on the wrong CPU, but that doesn't hurt.
+	 */
+
+	/* Test for pending */
+	testb $0xff, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_pending
+	jz 1f
+
+	call check_events
+1:
+	FRAME_END
+	ret
+SYM_FUNC_END(xen_irq_enable_direct)
+
 /*
  * (xen_)save_fl is used to get the current interrupt enable status.
  * Callers expect the status to be in X86_EFLAGS_IF, and other bits



^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v2 21/24] x86/xen: Make irq_disable() noinstr
  2021-06-24  9:40 [PATCH v2 00/24] objtool/x86: noinstr vs PARAVIRT Peter Zijlstra
                   ` (19 preceding siblings ...)
  2021-06-24  9:41 ` [PATCH v2 20/24] x86/xen: Make irq_enable() noinstr Peter Zijlstra
@ 2021-06-24  9:41 ` Peter Zijlstra
  2021-06-24 11:10   ` Juergen Gross
                     ` (2 more replies)
  2021-06-24  9:41 ` [PATCH v2 22/24] x86/xen: Mark xen_force_evtchn_callback() noinstr Peter Zijlstra
                   ` (3 subsequent siblings)
  24 siblings, 3 replies; 101+ messages in thread
From: Peter Zijlstra @ 2021-06-24  9:41 UTC (permalink / raw)
  To: jpoimboe, tglx
  Cc: linux-kernel, peterz, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver

vmlinux.o: warning: objtool: pv_ops[31]: native_irq_disable
vmlinux.o: warning: objtool: pv_ops[31]: __raw_callee_save_xen_irq_disable
vmlinux.o: warning: objtool: pv_ops[31]: xen_irq_disable_direct
vmlinux.o: warning: objtool: lock_is_held_type()+0x5b: call to pv_ops[31]() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/kernel/paravirt.c |    7 ++++++-
 arch/x86/xen/irq.c         |    4 ++--
 arch/x86/xen/xen-asm.S     |    3 +--
 3 files changed, 9 insertions(+), 5 deletions(-)

--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -263,6 +263,11 @@ static noinstr void pv_native_irq_enable
 	native_irq_enable();
 }
 
+static noinstr void pv_native_irq_disable(void)
+{
+	native_irq_disable();
+}
+
 struct paravirt_patch_template pv_ops = {
 	/* Cpu ops. */
 	.cpu.io_delay		= native_io_delay,
@@ -306,7 +311,7 @@ struct paravirt_patch_template pv_ops =
 
 	/* Irq ops. */
 	.irq.save_fl		= __PV_IS_CALLEE_SAVE(native_save_fl),
-	.irq.irq_disable	= __PV_IS_CALLEE_SAVE(native_irq_disable),
+	.irq.irq_disable	= __PV_IS_CALLEE_SAVE(pv_native_irq_disable),
 	.irq.irq_enable		= __PV_IS_CALLEE_SAVE(pv_native_irq_enable),
 	.irq.safe_halt		= native_safe_halt,
 	.irq.halt		= native_halt,
--- a/arch/x86/xen/irq.c
+++ b/arch/x86/xen/irq.c
@@ -42,7 +42,7 @@ asmlinkage __visible noinstr unsigned lo
 }
 __PV_CALLEE_SAVE_REGS_THUNK(xen_save_fl, ".noinstr.text");
 
-asmlinkage __visible void xen_irq_disable(void)
+asmlinkage __visible noinstr void xen_irq_disable(void)
 {
 	/* There's a one instruction preempt window here.  We need to
 	   make sure we're don't switch CPUs between getting the vcpu
@@ -51,7 +51,7 @@ asmlinkage __visible void xen_irq_disabl
 	this_cpu_read(xen_vcpu)->evtchn_upcall_mask = 1;
 	preempt_enable_no_resched();
 }
-PV_CALLEE_SAVE_REGS_THUNK(xen_irq_disable);
+__PV_CALLEE_SAVE_REGS_THUNK(xen_irq_disable, ".noinstr.text");
 
 asmlinkage __visible noinstr void xen_irq_enable(void)
 {
--- a/arch/x86/xen/xen-asm.S
+++ b/arch/x86/xen/xen-asm.S
@@ -21,6 +21,7 @@
 #include <linux/init.h>
 #include <linux/linkage.h>
 
+.pushsection .noinstr.text, "ax"
 /*
  * Disabling events is simply a matter of making the event mask
  * non-zero.
@@ -30,8 +31,6 @@ SYM_FUNC_START(xen_irq_disable_direct)
 	ret
 SYM_FUNC_END(xen_irq_disable_direct)
 
-.pushsection .noinstr.text, "ax"
-
 /*
  * Force an event check by making a hypercall, but preserve regs
  * before making the call.



^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v2 22/24] x86/xen: Mark xen_force_evtchn_callback() noinstr
  2021-06-24  9:40 [PATCH v2 00/24] objtool/x86: noinstr vs PARAVIRT Peter Zijlstra
                   ` (20 preceding siblings ...)
  2021-06-24  9:41 ` [PATCH v2 21/24] x86/xen: Make irq_disable() noinstr Peter Zijlstra
@ 2021-06-24  9:41 ` Peter Zijlstra
  2021-06-24 11:11   ` Juergen Gross
                     ` (2 more replies)
  2021-06-24  9:41 ` [PATCH v2 23/24] x86/xen: Rework the xen_{cpu,irq,mmu}_ops[] arrays Peter Zijlstra
                   ` (2 subsequent siblings)
  24 siblings, 3 replies; 101+ messages in thread
From: Peter Zijlstra @ 2021-06-24  9:41 UTC (permalink / raw)
  To: jpoimboe, tglx
  Cc: linux-kernel, peterz, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver

vmlinux.o: warning: objtool: check_events()+0xd: call to xen_force_evtchn_callback() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/include/asm/xen/hypercall.h |    2 +-
 arch/x86/xen/irq.c                   |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

--- a/arch/x86/include/asm/xen/hypercall.h
+++ b/arch/x86/include/asm/xen/hypercall.h
@@ -358,7 +358,7 @@ HYPERVISOR_event_channel_op(int cmd, voi
 	return _hypercall2(int, event_channel_op, cmd, arg);
 }
 
-static inline int
+static __always_inline int
 HYPERVISOR_xen_version(int cmd, void *arg)
 {
 	return _hypercall2(int, xen_version, cmd, arg);
--- a/arch/x86/xen/irq.c
+++ b/arch/x86/xen/irq.c
@@ -19,7 +19,7 @@
  * callback mask. We do this in a very simple manner, by making a call
  * down into Xen. The pending flag will be checked by Xen on return.
  */
-void xen_force_evtchn_callback(void)
+noinstr void xen_force_evtchn_callback(void)
 {
 	(void)HYPERVISOR_xen_version(0, NULL);
 }



^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v2 23/24] x86/xen: Rework the xen_{cpu,irq,mmu}_ops[] arrays
  2021-06-24  9:40 [PATCH v2 00/24] objtool/x86: noinstr vs PARAVIRT Peter Zijlstra
                   ` (21 preceding siblings ...)
  2021-06-24  9:41 ` [PATCH v2 22/24] x86/xen: Mark xen_force_evtchn_callback() noinstr Peter Zijlstra
@ 2021-06-24  9:41 ` Peter Zijlstra
  2021-06-24 12:12   ` Juergen Gross
                     ` (2 more replies)
  2021-06-24  9:41 ` [PATCH v2 24/24] objtool: Support pv_opsindirect calls for noinstr Peter Zijlstra
  2021-06-24 13:05 ` [PATCH v2 00/24] objtool/x86: noinstr vs PARAVIRT Steven Rostedt
  24 siblings, 3 replies; 101+ messages in thread
From: Peter Zijlstra @ 2021-06-24  9:41 UTC (permalink / raw)
  To: jpoimboe, tglx
  Cc: linux-kernel, peterz, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver

In order to allow objtool to make sense of all the various paravirt
functions, it needs to either parse whole pv_ops[] tables, or observe
individual assignments in the form:

  bf87:       48 c7 05 00 00 00 00 00 00 00 00        movq   $0x0,0x0(%rip)
    bf92 <xen_init_spinlocks+0x5f>
    bf8a: R_X86_64_PC32     pv_ops+0x268

As is, xen_cpu_ops[] is at offset +0 in pv_ops[] and could thus be
parsed as a 'normal' pv_ops[] table, however xen_irq_ops[] and
xen_mmu_ops[] are not.

Worse, both the latter two are compiled into the individual assignment
for by current GCC, but that's not something one can rely on.

Therefore, convert all three into full pv_ops[] tables. This has the
benefit of not needing to teach objtool about the offsets and
resulting in more conservative code-gen.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/xen/enlighten_pv.c |   66 ++++++++++++++++---------------
 arch/x86/xen/irq.c          |   17 ++++----
 arch/x86/xen/mmu_pv.c       |   92 ++++++++++++++++++++++----------------------
 3 files changed, 91 insertions(+), 84 deletions(-)

--- a/arch/x86/xen/enlighten_pv.c
+++ b/arch/x86/xen/enlighten_pv.c
@@ -1051,52 +1051,54 @@ static const struct pv_info xen_info __i
 	.name = "Xen",
 };
 
-static const struct pv_cpu_ops xen_cpu_ops __initconst = {
-	.cpuid = xen_cpuid,
+static const typeof(pv_ops) xen_cpu_ops __initconst = {
+	.cpu = {
+		.cpuid = xen_cpuid,
 
-	.set_debugreg = xen_set_debugreg,
-	.get_debugreg = xen_get_debugreg,
+		.set_debugreg = xen_set_debugreg,
+		.get_debugreg = xen_get_debugreg,
 
-	.read_cr0 = xen_read_cr0,
-	.write_cr0 = xen_write_cr0,
+		.read_cr0 = xen_read_cr0,
+		.write_cr0 = xen_write_cr0,
 
-	.write_cr4 = xen_write_cr4,
+		.write_cr4 = xen_write_cr4,
 
-	.wbinvd = native_wbinvd,
+		.wbinvd = native_wbinvd,
 
-	.read_msr = xen_read_msr,
-	.write_msr = xen_write_msr,
+		.read_msr = xen_read_msr,
+		.write_msr = xen_write_msr,
 
-	.read_msr_safe = xen_read_msr_safe,
-	.write_msr_safe = xen_write_msr_safe,
+		.read_msr_safe = xen_read_msr_safe,
+		.write_msr_safe = xen_write_msr_safe,
 
-	.read_pmc = xen_read_pmc,
+		.read_pmc = xen_read_pmc,
 
-	.load_tr_desc = paravirt_nop,
-	.set_ldt = xen_set_ldt,
-	.load_gdt = xen_load_gdt,
-	.load_idt = xen_load_idt,
-	.load_tls = xen_load_tls,
-	.load_gs_index = xen_load_gs_index,
+		.load_tr_desc = paravirt_nop,
+		.set_ldt = xen_set_ldt,
+		.load_gdt = xen_load_gdt,
+		.load_idt = xen_load_idt,
+		.load_tls = xen_load_tls,
+		.load_gs_index = xen_load_gs_index,
 
-	.alloc_ldt = xen_alloc_ldt,
-	.free_ldt = xen_free_ldt,
+		.alloc_ldt = xen_alloc_ldt,
+		.free_ldt = xen_free_ldt,
 
-	.store_tr = xen_store_tr,
+		.store_tr = xen_store_tr,
 
-	.write_ldt_entry = xen_write_ldt_entry,
-	.write_gdt_entry = xen_write_gdt_entry,
-	.write_idt_entry = xen_write_idt_entry,
-	.load_sp0 = xen_load_sp0,
+		.write_ldt_entry = xen_write_ldt_entry,
+		.write_gdt_entry = xen_write_gdt_entry,
+		.write_idt_entry = xen_write_idt_entry,
+		.load_sp0 = xen_load_sp0,
 
 #ifdef CONFIG_X86_IOPL_IOPERM
-	.invalidate_io_bitmap = xen_invalidate_io_bitmap,
-	.update_io_bitmap = xen_update_io_bitmap,
+		.invalidate_io_bitmap = xen_invalidate_io_bitmap,
+		.update_io_bitmap = xen_update_io_bitmap,
 #endif
-	.io_delay = xen_io_delay,
+		.io_delay = xen_io_delay,
 
-	.start_context_switch = paravirt_start_context_switch,
-	.end_context_switch = xen_end_context_switch,
+		.start_context_switch = paravirt_start_context_switch,
+		.end_context_switch = xen_end_context_switch,
+	},
 };
 
 static void xen_restart(char *msg)
@@ -1232,7 +1234,7 @@ asmlinkage __visible void __init xen_sta
 
 	/* Install Xen paravirt ops */
 	pv_info = xen_info;
-	pv_ops.cpu = xen_cpu_ops;
+	pv_ops.cpu = xen_cpu_ops.cpu;
 	paravirt_iret = xen_iret;
 	xen_init_irq_ops();
 
--- a/arch/x86/xen/irq.c
+++ b/arch/x86/xen/irq.c
@@ -94,17 +94,20 @@ static void xen_halt(void)
 		xen_safe_halt();
 }
 
-static const struct pv_irq_ops xen_irq_ops __initconst = {
-	.save_fl = PV_CALLEE_SAVE(xen_save_fl),
-	.irq_disable = PV_CALLEE_SAVE(xen_irq_disable),
-	.irq_enable = PV_CALLEE_SAVE(xen_irq_enable),
+static const typeof(pv_ops) xen_irq_ops __initconst = {
+	.irq = {
 
-	.safe_halt = xen_safe_halt,
-	.halt = xen_halt,
+		.save_fl = PV_CALLEE_SAVE(xen_save_fl),
+		.irq_disable = PV_CALLEE_SAVE(xen_irq_disable),
+		.irq_enable = PV_CALLEE_SAVE(xen_irq_enable),
+
+		.safe_halt = xen_safe_halt,
+		.halt = xen_halt,
+	},
 };
 
 void __init xen_init_irq_ops(void)
 {
-	pv_ops.irq = xen_irq_ops;
+	pv_ops.irq = xen_irq_ops.irq;
 	x86_init.irqs.intr_init = xen_init_IRQ;
 }
--- a/arch/x86/xen/mmu_pv.c
+++ b/arch/x86/xen/mmu_pv.c
@@ -2076,67 +2076,69 @@ static void xen_leave_lazy_mmu(void)
 	preempt_enable();
 }
 
-static const struct pv_mmu_ops xen_mmu_ops __initconst = {
-	.read_cr2 = __PV_IS_CALLEE_SAVE(xen_read_cr2),
-	.write_cr2 = xen_write_cr2,
+static const typeof(pv_ops) xen_mmu_ops __initconst = {
+	.mmu = {
+		.read_cr2 = __PV_IS_CALLEE_SAVE(xen_read_cr2),
+		.write_cr2 = xen_write_cr2,
 
-	.read_cr3 = xen_read_cr3,
-	.write_cr3 = xen_write_cr3_init,
+		.read_cr3 = xen_read_cr3,
+		.write_cr3 = xen_write_cr3_init,
 
-	.flush_tlb_user = xen_flush_tlb,
-	.flush_tlb_kernel = xen_flush_tlb,
-	.flush_tlb_one_user = xen_flush_tlb_one_user,
-	.flush_tlb_multi = xen_flush_tlb_multi,
-	.tlb_remove_table = tlb_remove_table,
+		.flush_tlb_user = xen_flush_tlb,
+		.flush_tlb_kernel = xen_flush_tlb,
+		.flush_tlb_one_user = xen_flush_tlb_one_user,
+		.flush_tlb_multi = xen_flush_tlb_multi,
+		.tlb_remove_table = tlb_remove_table,
 
-	.pgd_alloc = xen_pgd_alloc,
-	.pgd_free = xen_pgd_free,
+		.pgd_alloc = xen_pgd_alloc,
+		.pgd_free = xen_pgd_free,
 
-	.alloc_pte = xen_alloc_pte_init,
-	.release_pte = xen_release_pte_init,
-	.alloc_pmd = xen_alloc_pmd_init,
-	.release_pmd = xen_release_pmd_init,
+		.alloc_pte = xen_alloc_pte_init,
+		.release_pte = xen_release_pte_init,
+		.alloc_pmd = xen_alloc_pmd_init,
+		.release_pmd = xen_release_pmd_init,
 
-	.set_pte = xen_set_pte_init,
-	.set_pmd = xen_set_pmd_hyper,
+		.set_pte = xen_set_pte_init,
+		.set_pmd = xen_set_pmd_hyper,
 
-	.ptep_modify_prot_start = __ptep_modify_prot_start,
-	.ptep_modify_prot_commit = __ptep_modify_prot_commit,
+		.ptep_modify_prot_start = __ptep_modify_prot_start,
+		.ptep_modify_prot_commit = __ptep_modify_prot_commit,
 
-	.pte_val = PV_CALLEE_SAVE(xen_pte_val),
-	.pgd_val = PV_CALLEE_SAVE(xen_pgd_val),
+		.pte_val = PV_CALLEE_SAVE(xen_pte_val),
+		.pgd_val = PV_CALLEE_SAVE(xen_pgd_val),
 
-	.make_pte = PV_CALLEE_SAVE(xen_make_pte_init),
-	.make_pgd = PV_CALLEE_SAVE(xen_make_pgd),
+		.make_pte = PV_CALLEE_SAVE(xen_make_pte_init),
+		.make_pgd = PV_CALLEE_SAVE(xen_make_pgd),
 
-	.set_pud = xen_set_pud_hyper,
+		.set_pud = xen_set_pud_hyper,
 
-	.make_pmd = PV_CALLEE_SAVE(xen_make_pmd),
-	.pmd_val = PV_CALLEE_SAVE(xen_pmd_val),
+		.make_pmd = PV_CALLEE_SAVE(xen_make_pmd),
+		.pmd_val = PV_CALLEE_SAVE(xen_pmd_val),
 
-	.pud_val = PV_CALLEE_SAVE(xen_pud_val),
-	.make_pud = PV_CALLEE_SAVE(xen_make_pud),
-	.set_p4d = xen_set_p4d_hyper,
+		.pud_val = PV_CALLEE_SAVE(xen_pud_val),
+		.make_pud = PV_CALLEE_SAVE(xen_make_pud),
+		.set_p4d = xen_set_p4d_hyper,
 
-	.alloc_pud = xen_alloc_pmd_init,
-	.release_pud = xen_release_pmd_init,
+		.alloc_pud = xen_alloc_pmd_init,
+		.release_pud = xen_release_pmd_init,
 
 #if CONFIG_PGTABLE_LEVELS >= 5
-	.p4d_val = PV_CALLEE_SAVE(xen_p4d_val),
-	.make_p4d = PV_CALLEE_SAVE(xen_make_p4d),
+		.p4d_val = PV_CALLEE_SAVE(xen_p4d_val),
+		.make_p4d = PV_CALLEE_SAVE(xen_make_p4d),
 #endif
 
-	.activate_mm = xen_activate_mm,
-	.dup_mmap = xen_dup_mmap,
-	.exit_mmap = xen_exit_mmap,
-
-	.lazy_mode = {
-		.enter = paravirt_enter_lazy_mmu,
-		.leave = xen_leave_lazy_mmu,
-		.flush = paravirt_flush_lazy_mmu,
-	},
+		.activate_mm = xen_activate_mm,
+		.dup_mmap = xen_dup_mmap,
+		.exit_mmap = xen_exit_mmap,
+
+		.lazy_mode = {
+			.enter = paravirt_enter_lazy_mmu,
+			.leave = xen_leave_lazy_mmu,
+			.flush = paravirt_flush_lazy_mmu,
+		},
 
-	.set_fixmap = xen_set_fixmap,
+		.set_fixmap = xen_set_fixmap,
+	},
 };
 
 void __init xen_init_mmu_ops(void)
@@ -2144,7 +2146,7 @@ void __init xen_init_mmu_ops(void)
 	x86_init.paging.pagetable_init = xen_pagetable_init;
 	x86_init.hyper.init_after_bootmem = xen_after_bootmem;
 
-	pv_ops.mmu = xen_mmu_ops;
+	pv_ops.mmu = xen_mmu_ops.mmu;
 
 	memset(dummy_mapping, 0xff, PAGE_SIZE);
 }



^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH v2 24/24] objtool: Support pv_opsindirect calls for noinstr
  2021-06-24  9:40 [PATCH v2 00/24] objtool/x86: noinstr vs PARAVIRT Peter Zijlstra
                   ` (22 preceding siblings ...)
  2021-06-24  9:41 ` [PATCH v2 23/24] x86/xen: Rework the xen_{cpu,irq,mmu}_ops[] arrays Peter Zijlstra
@ 2021-06-24  9:41 ` Peter Zijlstra
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
  2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
  2021-06-24 13:05 ` [PATCH v2 00/24] objtool/x86: noinstr vs PARAVIRT Steven Rostedt
  24 siblings, 2 replies; 101+ messages in thread
From: Peter Zijlstra @ 2021-06-24  9:41 UTC (permalink / raw)
  To: jpoimboe, tglx
  Cc: linux-kernel, peterz, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver

Normally objtool will now follow indirect calls; there is no need.

However, this becomes a problem with noinstr validation; if there's an
indirect call from noinstr code, we very much need to know it is to
another noinstr function. Luckily there aren't many indirect calls in
entry code with the obvious exception of paravirt. As such, noinstr
validation didn't work with paravirt kernels.

In order to track pv_ops[] call targets, objtool reads the static
pv_ops[] tables as well as direct assignments to the pv_ops[] array,
provided the compiler makes them a single instruction like:

  bf87:       48 c7 05 00 00 00 00 00 00 00 00        movq   $0x0,0x0(%rip)
    bf92 <xen_init_spinlocks+0x5f>
    bf8a: R_X86_64_PC32     pv_ops+0x268

There are, as of yet, no warnings for when this goes wrong :/

Using the functions found with the above means, all pv_ops[] calls are
now subject to noinstr validation.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 lib/Kconfig.debug                       |    2 
 tools/objtool/arch/x86/decode.c         |   34 ++++++-
 tools/objtool/check.c                   |  151 +++++++++++++++++++++++++++++---
 tools/objtool/include/objtool/arch.h    |    2 
 tools/objtool/include/objtool/elf.h     |    1 
 tools/objtool/include/objtool/objtool.h |    9 +
 tools/objtool/objtool.c                 |   22 ++++
 7 files changed, 208 insertions(+), 13 deletions(-)

--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -445,7 +445,7 @@ config STACK_VALIDATION
 
 config VMLINUX_VALIDATION
 	bool
-	depends on STACK_VALIDATION && DEBUG_ENTRY && !PARAVIRT
+	depends on STACK_VALIDATION && DEBUG_ENTRY
 	default y
 
 config VMLINUX_MAP
--- a/tools/objtool/arch/x86/decode.c
+++ b/tools/objtool/arch/x86/decode.c
@@ -20,6 +20,7 @@
 #include <objtool/arch.h>
 #include <objtool/warn.h>
 #include <objtool/endianness.h>
+#include <objtool/builtin.h>
 #include <arch/elf.h>
 
 static int is_x86_64(const struct elf *elf)
@@ -102,12 +103,13 @@ unsigned long arch_jump_destination(stru
 #define rm_is_mem(reg)	(mod_is_mem() && !is_RIP() && rm_is(reg))
 #define rm_is_reg(reg)	(mod_is_reg() && modrm_rm == (reg))
 
-int arch_decode_instruction(const struct elf *elf, const struct section *sec,
+int arch_decode_instruction(struct objtool_file *file, const struct section *sec,
 			    unsigned long offset, unsigned int maxlen,
 			    unsigned int *len, enum insn_type *type,
 			    unsigned long *immediate,
 			    struct list_head *ops_list)
 {
+	const struct elf *elf = file->elf;
 	struct insn insn;
 	int x86_64, ret;
 	unsigned char op1, op2,
@@ -544,6 +546,36 @@ int arch_decode_instruction(const struct
 		*type = INSN_RETURN;
 		break;
 
+	case 0xc7: /* mov imm, r/m */
+		if (!noinstr)
+			break;
+
+		if (insn.length == 3+4+4 && !strncmp(sec->name, ".init.text", 10)) {
+			struct reloc *immr, *disp;
+			struct symbol *func;
+			int idx;
+
+			immr = find_reloc_by_dest(elf, (void *)sec, offset+3);
+			disp = find_reloc_by_dest(elf, (void *)sec, offset+7);
+
+			if (!immr || strcmp(immr->sym->name, "pv_ops"))
+				break;
+
+			idx = (immr->addend + 8) / sizeof(void *);
+
+			func = disp->sym;
+			if (disp->sym->type == STT_SECTION)
+				func = find_symbol_by_offset(disp->sym->sec, disp->addend);
+			if (!func) {
+				WARN("no func for pv_ops[]");
+				return -1;
+			}
+
+			objtool_pv_add(file, idx, func);
+		}
+
+		break;
+
 	case 0xcf: /* iret */
 		/*
 		 * Handle sync_core(), which has an IRET to self.
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -306,7 +306,7 @@ static int decode_instructions(struct ob
 			insn->sec = sec;
 			insn->offset = offset;
 
-			ret = arch_decode_instruction(file->elf, sec, offset,
+			ret = arch_decode_instruction(file, sec, offset,
 						      sec->len - offset,
 						      &insn->len, &insn->type,
 						      &insn->immediate,
@@ -344,6 +344,82 @@ static int decode_instructions(struct ob
 	return ret;
 }
 
+/*
+ * Read the pv_ops[] .data table to find the static initialized values.
+ */
+static int add_pv_ops(struct objtool_file *file, const char *symname)
+{
+	struct symbol *sym, *func;
+	unsigned long off, end;
+	struct reloc *rel;
+	int idx;
+
+	sym = find_symbol_by_name(file->elf, symname);
+	if (!sym)
+		return 0;
+
+	off = sym->offset;
+	end = off + sym->len;
+	for (;;) {
+		rel = find_reloc_by_dest_range(file->elf, sym->sec, off, end - off);
+		if (!rel)
+			break;
+
+		func = rel->sym;
+		if (func->type == STT_SECTION)
+			func = find_symbol_by_offset(rel->sym->sec, rel->addend);
+
+		idx = (rel->offset - sym->offset) / sizeof(unsigned long);
+
+		objtool_pv_add(file, idx, func);
+
+		off = rel->offset + 1;
+		if (off > end)
+			break;
+	}
+
+	return 0;
+}
+
+/*
+ * Allocate and initialize file->pv_ops[].
+ */
+static int init_pv_ops(struct objtool_file *file)
+{
+	static const char *pv_ops_tables[] = {
+		"pv_ops",
+		"xen_cpu_ops",
+		"xen_irq_ops",
+		"xen_mmu_ops",
+		NULL,
+	};
+	const char *pv_ops;
+	struct symbol *sym;
+	int idx, nr;
+
+	if (!noinstr)
+		return 0;
+
+	file->pv_ops = NULL;
+
+	sym = find_symbol_by_name(file->elf, "pv_ops");
+	if (!sym)
+		return 0;
+
+	nr = sym->len / sizeof(unsigned long);
+	file->pv_ops = calloc(sizeof(struct pv_state), nr);
+	if (!file->pv_ops)
+		return -1;
+
+	for (idx = 0; idx < nr; idx++)
+		INIT_LIST_HEAD(&file->pv_ops[idx].targets);
+
+	for (idx = 0; (pv_ops = pv_ops_tables[idx]); idx++)
+		add_pv_ops(file, pv_ops);
+
+	return 0;
+}
+
 static struct instruction *find_last_insn(struct objtool_file *file,
 					  struct section *sec)
 {
@@ -817,6 +893,9 @@ static struct reloc *insn_reloc(struct o
 		return NULL;
 
 	if (!insn->reloc) {
+		if (!file)
+			return NULL;
+
 		insn->reloc = find_reloc_by_dest_range(file->elf, insn->sec,
 						       insn->offset, insn->len);
 		if (!insn->reloc) {
@@ -1791,6 +1870,10 @@ static int decode_sections(struct objtoo
 
 	mark_rodata(file);
 
+	ret = init_pv_ops(file);
+	if (ret)
+		return ret;
+
 	ret = decode_instructions(file);
 	if (ret)
 		return ret;
@@ -2562,20 +2645,64 @@ static inline bool func_uaccess_safe(str
 
 static inline const char *call_dest_name(struct instruction *insn)
 {
+	static char pvname[16];
+	struct reloc *rel;
+	int idx;
+
 	if (insn->call_dest)
 		return insn->call_dest->name;
 
+	rel = insn_reloc(NULL, insn);
+	if (rel && !strcmp(rel->sym->name, "pv_ops")) {
+		idx = (rel->addend / sizeof(void *));
+		snprintf(pvname, sizeof(pvname), "pv_ops[%d]", idx);
+		return pvname;
+	}
+
 	return "{dynamic}";
 }
 
-static inline bool noinstr_call_dest(struct symbol *func)
+static bool pv_call_dest(struct objtool_file *file, struct instruction *insn)
+{
+	struct symbol *target;
+	struct reloc *rel;
+	int idx;
+
+	rel = insn_reloc(file, insn);
+	if (!rel || strcmp(rel->sym->name, "pv_ops"))
+		return false;
+
+	idx = (arch_dest_reloc_offset(rel->addend) / sizeof(void *));
+
+	if (file->pv_ops[idx].clean)
+		return true;
+
+	file->pv_ops[idx].clean = true;
+
+	list_for_each_entry(target, &file->pv_ops[idx].targets, pv_target) {
+		if (!target->sec->noinstr) {
+			WARN("pv_ops[%d]: %s", idx, target->name);
+			file->pv_ops[idx].clean = false;
+		}
+	}
+
+	return file->pv_ops[idx].clean;
+}
+
+static inline bool noinstr_call_dest(struct objtool_file *file,
+				     struct instruction *insn,
+				     struct symbol *func)
 {
 	/*
 	 * We can't deal with indirect function calls at present;
 	 * assume they're instrumented.
 	 */
-	if (!func)
+	if (!func) {
+		if (file->pv_ops)
+			return pv_call_dest(file, insn);
+
 		return false;
+	}
 
 	/*
 	 * If the symbol is from a noinstr section; we good.
@@ -2594,10 +2721,12 @@ static inline bool noinstr_call_dest(str
 	return false;
 }
 
-static int validate_call(struct instruction *insn, struct insn_state *state)
+static int validate_call(struct objtool_file *file,
+			 struct instruction *insn,
+			 struct insn_state *state)
 {
 	if (state->noinstr && state->instr <= 0 &&
-	    !noinstr_call_dest(insn->call_dest)) {
+	    !noinstr_call_dest(file, insn, insn->call_dest)) {
 		WARN_FUNC("call to %s() leaves .noinstr.text section",
 				insn->sec, insn->offset, call_dest_name(insn));
 		return 1;
@@ -2618,7 +2747,9 @@ static int validate_call(struct instruct
 	return 0;
 }
 
-static int validate_sibling_call(struct instruction *insn, struct insn_state *state)
+static int validate_sibling_call(struct objtool_file *file,
+				 struct instruction *insn,
+				 struct insn_state *state)
 {
 	if (has_modified_stack_frame(insn, state)) {
 		WARN_FUNC("sibling call from callable instruction with modified stack frame",
@@ -2626,7 +2757,7 @@ static int validate_sibling_call(struct
 		return 1;
 	}
 
-	return validate_call(insn, state);
+	return validate_call(file, insn, state);
 }
 
 static int validate_return(struct symbol *func, struct instruction *insn, struct insn_state *state)
@@ -2769,7 +2900,7 @@ static int validate_branch(struct objtoo
 
 		case INSN_CALL:
 		case INSN_CALL_DYNAMIC:
-			ret = validate_call(insn, &state);
+			ret = validate_call(file, insn, &state);
 			if (ret)
 				return ret;
 
@@ -2788,7 +2919,7 @@ static int validate_branch(struct objtoo
 		case INSN_JUMP_CONDITIONAL:
 		case INSN_JUMP_UNCONDITIONAL:
 			if (is_sibling_call(insn)) {
-				ret = validate_sibling_call(insn, &state);
+				ret = validate_sibling_call(file, insn, &state);
 				if (ret)
 					return ret;
 
@@ -2810,7 +2941,7 @@ static int validate_branch(struct objtoo
 		case INSN_JUMP_DYNAMIC:
 		case INSN_JUMP_DYNAMIC_CONDITIONAL:
 			if (is_sibling_call(insn)) {
-				ret = validate_sibling_call(insn, &state);
+				ret = validate_sibling_call(file, insn, &state);
 				if (ret)
 					return ret;
 			}
--- a/tools/objtool/include/objtool/arch.h
+++ b/tools/objtool/include/objtool/arch.h
@@ -69,7 +69,7 @@ struct instruction;
 
 void arch_initial_func_cfi_state(struct cfi_init_state *state);
 
-int arch_decode_instruction(const struct elf *elf, const struct section *sec,
+int arch_decode_instruction(struct objtool_file *file, const struct section *sec,
 			    unsigned long offset, unsigned int maxlen,
 			    unsigned int *len, enum insn_type *type,
 			    unsigned long *immediate,
--- a/tools/objtool/include/objtool/elf.h
+++ b/tools/objtool/include/objtool/elf.h
@@ -57,6 +57,7 @@ struct symbol {
 	struct symbol *pfunc, *cfunc, *alias;
 	bool uaccess_safe;
 	bool static_call_tramp;
+	struct list_head pv_target;
 };
 
 struct reloc {
--- a/tools/objtool/include/objtool/objtool.h
+++ b/tools/objtool/include/objtool/objtool.h
@@ -14,6 +14,11 @@
 
 #define __weak __attribute__((weak))
 
+struct pv_state {
+	bool clean;
+	struct list_head targets;
+};
+
 struct objtool_file {
 	struct elf *elf;
 	struct list_head insn_list;
@@ -25,10 +30,14 @@ struct objtool_file {
 
 	unsigned long jl_short, jl_long;
 	unsigned long jl_nop_short, jl_nop_long;
+
+	struct pv_state *pv_ops;
 };
 
 struct objtool_file *objtool_open_read(const char *_objname);
 
+void objtool_pv_add(struct objtool_file *file, int idx, struct symbol *func);
+
 int check(struct objtool_file *file);
 int orc_dump(const char *objname);
 int orc_create(struct objtool_file *file);
--- a/tools/objtool/objtool.c
+++ b/tools/objtool/objtool.c
@@ -135,6 +135,28 @@ struct objtool_file *objtool_open_read(c
 	return &file;
 }
 
+void objtool_pv_add(struct objtool_file *f, int idx, struct symbol *func)
+{
+	if (!noinstr)
+		return;
+
+	if (!f->pv_ops) {
+		WARN("paravirt confusion");
+		return;
+	}
+
+	/*
+	 * These functions will be patched into native code,
+	 * see paravirt_patch().
+	 */
+	if (!strcmp(func->name, "_paravirt_nop") ||
+	    !strcmp(func->name, "_paravirt_ident_64"))
+		return;
+
+	list_add(&func->pv_target, &f->pv_ops[idx].targets);
+	f->pv_ops[idx].clean = false;
+}
+
 static void cmd_usage(void)
 {
 	unsigned int i, longest = 0;



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 01/24] x86/xen: Mark cpu_bringup_and_idle() as dead_end_function
  2021-06-24  9:41 ` [PATCH v2 01/24] x86/xen: Mark cpu_bringup_and_idle() as dead_end_function Peter Zijlstra
@ 2021-06-24 10:49   ` Juergen Gross
  2021-06-30 11:47   ` Miroslav Benes
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 101+ messages in thread
From: Juergen Gross @ 2021-06-24 10:49 UTC (permalink / raw)
  To: Peter Zijlstra, jpoimboe, tglx
  Cc: linux-kernel, joro, boris.ostrovsky, x86, mbenes, rostedt,
	dvyukov, elver


[-- Attachment #1.1.1: Type: text/plain, Size: 886 bytes --]

On 24.06.21 11:41, Peter Zijlstra wrote:
> The asm_cpu_bringup_and_idle() function is required to push the return
> value on the stack in order to make ORC happy, but the only reason
> objtool doesn't complain is because of a happy accident.
> 
> The thing is that asm_cpu_bringup_and_idle() doesn't return, so
> validate_branch() never terminates and falls through to the next
> function, which in the normal case is the hypercall_page. And that, as
> it happens, is 4095 NOPs and a RET.
> 
> Make asm_cpu_bringup_and_idle() terminate on it's own, by making the
> function it calls as a dead-end. This way we no longer rely on what
> code happens to come after.
> 
> Fixes: c3881eb58d56 ("x86/xen: Make the secondary CPU idle tasks reliable")
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>

Reviewed-by: Juergen Gross <jgross@suse.com>


Juergen


[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3135 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 12/24] x86/paravirt: Mark arch_local_irq_*() __always_inline
  2021-06-24  9:41 ` [PATCH v2 12/24] x86/paravirt: Mark arch_local_irq_*() __always_inline Peter Zijlstra
@ 2021-06-24 10:51   ` Juergen Gross
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
  1 sibling, 0 replies; 101+ messages in thread
From: Juergen Gross @ 2021-06-24 10:51 UTC (permalink / raw)
  To: Peter Zijlstra, jpoimboe, tglx
  Cc: linux-kernel, joro, boris.ostrovsky, x86, mbenes, rostedt,
	dvyukov, elver


[-- Attachment #1.1.1: Type: text/plain, Size: 953 bytes --]

On 24.06.21 11:41, Peter Zijlstra wrote:
> vmlinux.o: warning: objtool: lockdep_hardirqs_on()+0x72: call to arch_local_save_flags() leaves .noinstr.text section
> vmlinux.o: warning: objtool: lockdep_hardirqs_off()+0x73: call to arch_local_save_flags() leaves .noinstr.text section
> vmlinux.o: warning: objtool: match_held_lock()+0x11f: call to arch_local_save_flags() leaves .noinstr.text section
> 
> vmlinux.o: warning: objtool: lock_is_held_type()+0x4e: call to arch_local_irq_save() leaves .noinstr.text section
> 
> vmlinux.o: warning: objtool: lock_is_held_type()+0x65: call to arch_local_irq_disable() leaves .noinstr.text section
> 
> vmlinux.o: warning: objtool: lock_is_held_type()+0xfe: call to arch_local_irq_enable() leaves .noinstr.text section
> 
> It makes no sense to not inline these things.
> 
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>

Reviewed-by: Juergen Gross <jgross@suse.com>


Juergen

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3135 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 13/24] x86/paravirt: Use PVOP_* for paravirt calls
  2021-06-24  9:41 ` [PATCH v2 13/24] x86/paravirt: Use PVOP_* for paravirt calls Peter Zijlstra
@ 2021-06-24 10:52   ` Juergen Gross
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
  1 sibling, 0 replies; 101+ messages in thread
From: Juergen Gross @ 2021-06-24 10:52 UTC (permalink / raw)
  To: Peter Zijlstra, jpoimboe, tglx
  Cc: linux-kernel, joro, boris.ostrovsky, x86, mbenes, rostedt,
	dvyukov, elver


[-- Attachment #1.1.1: Type: text/plain, Size: 245 bytes --]

On 24.06.21 11:41, Peter Zijlstra wrote:
> Doing unconditional indirect calls through the pv_ops vector is weird.
> 
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>

Reviewed-by: Juergen Gross <jgross@suse.com>


Juergen

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3135 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 14/24] x86/xen: Make read_cr2() noinstr
  2021-06-24  9:41 ` [PATCH v2 14/24] x86/xen: Make read_cr2() noinstr Peter Zijlstra
@ 2021-06-24 10:55   ` Juergen Gross
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
  2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
  2 siblings, 0 replies; 101+ messages in thread
From: Juergen Gross @ 2021-06-24 10:55 UTC (permalink / raw)
  To: Peter Zijlstra, jpoimboe, tglx
  Cc: linux-kernel, joro, boris.ostrovsky, x86, mbenes, rostedt,
	dvyukov, elver


[-- Attachment #1.1.1: Type: text/plain, Size: 459 bytes --]

On 24.06.21 11:41, Peter Zijlstra wrote:
> vmlinux.o: warning: objtool: pv_ops[41]: native_read_cr2
> vmlinux.o: warning: objtool: pv_ops[41]: xen_read_cr2
> vmlinux.o: warning: objtool: pv_ops[41]: xen_read_cr2_direct
> vmlinux.o: warning: objtool: exc_double_fault()+0x15: call to pv_ops[41]() leaves .noinstr.text section
> 
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>

Reviewed-by: Juergen Gross <jgross@suse.com>


Juergen

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3135 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 15/24] x86/xen: Make write_cr2() noinstr
  2021-06-24  9:41 ` [PATCH v2 15/24] x86/xen: Make write_cr2() noinstr Peter Zijlstra
@ 2021-06-24 10:56   ` Juergen Gross
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
  2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
  2 siblings, 0 replies; 101+ messages in thread
From: Juergen Gross @ 2021-06-24 10:56 UTC (permalink / raw)
  To: Peter Zijlstra, jpoimboe, tglx
  Cc: linux-kernel, joro, boris.ostrovsky, x86, mbenes, rostedt,
	dvyukov, elver


[-- Attachment #1.1.1: Type: text/plain, Size: 389 bytes --]

On 24.06.21 11:41, Peter Zijlstra wrote:
> vmlinux.o: warning: objtool: pv_ops[42]: native_write_cr2
> vmlinux.o: warning: objtool: pv_ops[42]: xen_write_cr2
> vmlinux.o: warning: objtool: exc_nmi()+0x127: call to pv_ops[42]() leaves .noinstr.text section
> 
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>

Reviewed-by: Juergen Gross <jgross@suse.com>


Juergen

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3135 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 16/24] x86/xen: Make get_debugreg() noinstr
  2021-06-24  9:41 ` [PATCH v2 16/24] x86/xen: Make get_debugreg() noinstr Peter Zijlstra
@ 2021-06-24 10:57   ` Juergen Gross
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
  2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
  2 siblings, 0 replies; 101+ messages in thread
From: Juergen Gross @ 2021-06-24 10:57 UTC (permalink / raw)
  To: Peter Zijlstra, jpoimboe, tglx
  Cc: linux-kernel, joro, boris.ostrovsky, x86, mbenes, rostedt,
	dvyukov, elver


[-- Attachment #1.1.1: Type: text/plain, Size: 393 bytes --]

On 24.06.21 11:41, Peter Zijlstra wrote:
> vmlinux.o: warning: objtool: pv_ops[1]: xen_get_debugreg
> vmlinux.o: warning: objtool: pv_ops[1]: native_get_debugreg
> vmlinux.o: warning: objtool: exc_debug()+0x25: call to pv_ops[1]() leaves .noinstr.text section
> 
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>

Reviewed-by: Juergen Gross <jgross@suse.com>


Juergen

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3135 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 17/24] x86/xen: Make set_debugreg() noinstr
  2021-06-24  9:41 ` [PATCH v2 17/24] x86/xen: Make set_debugreg() noinstr Peter Zijlstra
@ 2021-06-24 10:59   ` Juergen Gross
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
  2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
  2 siblings, 0 replies; 101+ messages in thread
From: Juergen Gross @ 2021-06-24 10:59 UTC (permalink / raw)
  To: Peter Zijlstra, jpoimboe, tglx
  Cc: linux-kernel, joro, boris.ostrovsky, x86, mbenes, rostedt,
	dvyukov, elver


[-- Attachment #1.1.1: Type: text/plain, Size: 395 bytes --]

On 24.06.21 11:41, Peter Zijlstra wrote:
> vmlinux.o: warning: objtool: pv_ops[2]: xen_set_debugreg
> vmlinux.o: warning: objtool: pv_ops[2]: native_set_debugreg
> vmlinux.o: warning: objtool: exc_debug()+0x3b: call to pv_ops[2]() leaves .noinstr.text section
> 
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>

Reviewed-by: Juergen Gross <jgross@suse.com>


Juergen


[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3135 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 18/24] x86/xen: Make save_fl() noinstr
  2021-06-24  9:41 ` [PATCH v2 18/24] x86/xen: Make save_fl() noinstr Peter Zijlstra
@ 2021-06-24 11:07   ` Juergen Gross
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
  2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
  2 siblings, 0 replies; 101+ messages in thread
From: Juergen Gross @ 2021-06-24 11:07 UTC (permalink / raw)
  To: Peter Zijlstra, jpoimboe, tglx
  Cc: linux-kernel, joro, boris.ostrovsky, x86, mbenes, rostedt,
	dvyukov, elver


[-- Attachment #1.1.1: Type: text/plain, Size: 478 bytes --]

On 24.06.21 11:41, Peter Zijlstra wrote:
> vmlinux.o: warning: objtool: pv_ops[30]: native_save_fl
> vmlinux.o: warning: objtool: pv_ops[30]: __raw_callee_save_xen_save_fl
> vmlinux.o: warning: objtool: pv_ops[30]: xen_save_fl_direct
> vmlinux.o: warning: objtool: lockdep_hardirqs_off()+0x73: call to pv_ops[30]() leaves .noinstr.text section
> 
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>

Reviewed-by: Juergen Gross <jgross@suse.com>


Juergen

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3135 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 19/24] x86/xen: Make hypercall_page noinstr
  2021-06-24  9:41 ` [PATCH v2 19/24] x86/xen: Make hypercall_page noinstr Peter Zijlstra
@ 2021-06-24 11:08   ` Juergen Gross
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
  2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
  2 siblings, 0 replies; 101+ messages in thread
From: Juergen Gross @ 2021-06-24 11:08 UTC (permalink / raw)
  To: Peter Zijlstra, jpoimboe, tglx
  Cc: linux-kernel, joro, boris.ostrovsky, x86, mbenes, rostedt,
	dvyukov, elver


[-- Attachment #1.1.1: Type: text/plain, Size: 500 bytes --]

On 24.06.21 11:41, Peter Zijlstra wrote:
> vmlinux.o: warning: objtool: xen_set_debugreg()+0x3: call to hypercall_page() leaves .noinstr.text section
> vmlinux.o: warning: objtool: xen_get_debugreg()+0x3: call to hypercall_page() leaves .noinstr.text section
> vmlinux.o: warning: objtool: xen_irq_enable()+0x24: call to hypercall_page() leaves .noinstr.text section
> 
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>

Reviewed-by: Juergen Gross <jgross@suse.com>


Juergen

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3135 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 20/24] x86/xen: Make irq_enable() noinstr
  2021-06-24  9:41 ` [PATCH v2 20/24] x86/xen: Make irq_enable() noinstr Peter Zijlstra
@ 2021-06-24 11:09   ` Juergen Gross
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
  2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
  2 siblings, 0 replies; 101+ messages in thread
From: Juergen Gross @ 2021-06-24 11:09 UTC (permalink / raw)
  To: Peter Zijlstra, jpoimboe, tglx
  Cc: linux-kernel, joro, boris.ostrovsky, x86, mbenes, rostedt,
	dvyukov, elver


[-- Attachment #1.1.1: Type: text/plain, Size: 486 bytes --]

On 24.06.21 11:41, Peter Zijlstra wrote:
> vmlinux.o: warning: objtool: pv_ops[32]: native_irq_enable
> vmlinux.o: warning: objtool: pv_ops[32]: __raw_callee_save_xen_irq_enable
> vmlinux.o: warning: objtool: pv_ops[32]: xen_irq_enable_direct
> vmlinux.o: warning: objtool: lock_is_held_type()+0xfe: call to pv_ops[32]() leaves .noinstr.text section
> 
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>

Reviewed-by: Juergen Gross <jgross@suse.com>


Juergen


[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3135 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 21/24] x86/xen: Make irq_disable() noinstr
  2021-06-24  9:41 ` [PATCH v2 21/24] x86/xen: Make irq_disable() noinstr Peter Zijlstra
@ 2021-06-24 11:10   ` Juergen Gross
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
  2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
  2 siblings, 0 replies; 101+ messages in thread
From: Juergen Gross @ 2021-06-24 11:10 UTC (permalink / raw)
  To: Peter Zijlstra, jpoimboe, tglx
  Cc: linux-kernel, joro, boris.ostrovsky, x86, mbenes, rostedt,
	dvyukov, elver


[-- Attachment #1.1.1: Type: text/plain, Size: 487 bytes --]

On 24.06.21 11:41, Peter Zijlstra wrote:
> vmlinux.o: warning: objtool: pv_ops[31]: native_irq_disable
> vmlinux.o: warning: objtool: pv_ops[31]: __raw_callee_save_xen_irq_disable
> vmlinux.o: warning: objtool: pv_ops[31]: xen_irq_disable_direct
> vmlinux.o: warning: objtool: lock_is_held_type()+0x5b: call to pv_ops[31]() leaves .noinstr.text section
> 
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>

Reviewed-by: Juergen Gross <jgross@suse.com>


Juergen

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3135 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 22/24] x86/xen: Mark xen_force_evtchn_callback() noinstr
  2021-06-24  9:41 ` [PATCH v2 22/24] x86/xen: Mark xen_force_evtchn_callback() noinstr Peter Zijlstra
@ 2021-06-24 11:11   ` Juergen Gross
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
  2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
  2 siblings, 0 replies; 101+ messages in thread
From: Juergen Gross @ 2021-06-24 11:11 UTC (permalink / raw)
  To: Peter Zijlstra, jpoimboe, tglx
  Cc: linux-kernel, joro, boris.ostrovsky, x86, mbenes, rostedt,
	dvyukov, elver


[-- Attachment #1.1.1: Type: text/plain, Size: 288 bytes --]

On 24.06.21 11:41, Peter Zijlstra wrote:
> vmlinux.o: warning: objtool: check_events()+0xd: call to xen_force_evtchn_callback() leaves .noinstr.text section
> 
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>

Reviewed-by: Juergen Gross <jgross@suse.com>


Juergen

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3135 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 23/24] x86/xen: Rework the xen_{cpu,irq,mmu}_ops[] arrays
  2021-06-24  9:41 ` [PATCH v2 23/24] x86/xen: Rework the xen_{cpu,irq,mmu}_ops[] arrays Peter Zijlstra
@ 2021-06-24 12:12   ` Juergen Gross
  2021-09-15 15:49   ` [tip: objtool/core] x86/xen: Rework the xen_{cpu,irq,mmu}_opsarrays tip-bot2 for Peter Zijlstra
  2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
  2 siblings, 0 replies; 101+ messages in thread
From: Juergen Gross @ 2021-06-24 12:12 UTC (permalink / raw)
  To: Peter Zijlstra, jpoimboe, tglx
  Cc: linux-kernel, joro, boris.ostrovsky, x86, mbenes, rostedt,
	dvyukov, elver


[-- Attachment #1.1.1: Type: text/plain, Size: 1168 bytes --]

On 24.06.21 11:41, Peter Zijlstra wrote:
> In order to allow objtool to make sense of all the various paravirt
> functions, it needs to either parse whole pv_ops[] tables, or observe
> individual assignments in the form:
> 
>    bf87:       48 c7 05 00 00 00 00 00 00 00 00        movq   $0x0,0x0(%rip)
>      bf92 <xen_init_spinlocks+0x5f>
>      bf8a: R_X86_64_PC32     pv_ops+0x268
> 
> As is, xen_cpu_ops[] is at offset +0 in pv_ops[] and could thus be
> parsed as a 'normal' pv_ops[] table, however xen_irq_ops[] and
> xen_mmu_ops[] are not.
> 
> Worse, both the latter two are compiled into the individual assignment
> for by current GCC, but that's not something one can rely on.
> 
> Therefore, convert all three into full pv_ops[] tables. This has the
> benefit of not needing to teach objtool about the offsets and
> resulting in more conservative code-gen.
> 
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>

First I was worried by the additional memory consumption, but as the
modified tables are all tagged to be __init I don't think this matters.

So:

Reviewed-by: Juergen Gross <jgross@suse.com>


Juergen

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3135 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 00/24] objtool/x86: noinstr vs PARAVIRT
  2021-06-24  9:40 [PATCH v2 00/24] objtool/x86: noinstr vs PARAVIRT Peter Zijlstra
                   ` (23 preceding siblings ...)
  2021-06-24  9:41 ` [PATCH v2 24/24] objtool: Support pv_opsindirect calls for noinstr Peter Zijlstra
@ 2021-06-24 13:05 ` Steven Rostedt
  24 siblings, 0 replies; 101+ messages in thread
From: Steven Rostedt @ 2021-06-24 13:05 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: jpoimboe, tglx, linux-kernel, joro, boris.ostrovsky, jgross, x86,
	mbenes, dvyukov, elver

On Thu, 24 Jun 2021 11:40:59 +0200
Peter Zijlstra <peterz@infradead.org> wrote:

> Steve, can I please delete TRACE_BRANCH_PROFILING and PROFILE_ALL_BRANCHES already?

The TRACE_BRANCH_PROFILING, I never used, so I'm happy to delete it,
but I still use the PROFILE_ALL_BRANCHES.

But I'm curious, what's the issue with the PROFILE_ALL_BRANCHES?

You can make it ignore files, by simply adding a:

#define DISABLE_BRANCH_PROFILING

at the top of the file (before any of the includes).

So if your issue is that it makes it hard for some code, simply add
that to the top of the file, and it should just work.

-- Steve

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 03/24] objtool: Handle __sanitize_cov*() tail calls
  2021-06-24  9:41 ` [PATCH v2 03/24] objtool: Handle __sanitize_cov*() tail calls Peter Zijlstra
@ 2021-06-25 11:05   ` Marco Elver
  2021-06-28  9:07     ` Peter Zijlstra
  2021-06-25 13:38   ` Steven Rostedt
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 101+ messages in thread
From: Marco Elver @ 2021-06-25 11:05 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: jpoimboe, tglx, linux-kernel, joro, boris.ostrovsky, jgross, x86,
	mbenes, rostedt, dvyukov

On Thu, Jun 24, 2021 at 11:41AM +0200, Peter Zijlstra wrote:
> Turns out the compilers also generate tail calls to __sanitize_cov*(),
> make sure to also patch those out in noinstr code.
> 
> Fixes: 0f1441b44e82 ("objtool: Fix noinstr vs KCOV")
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>

Acked-by: Marco Elver <elver@google.com>

Thanks! More reason to not even try to do the same for other
architectures, and the compiler needing the attribute...

> ---
>  tools/objtool/arch/x86/decode.c      |   20 ++++
>  tools/objtool/check.c                |  153 ++++++++++++++++++-----------------
>  tools/objtool/include/objtool/arch.h |    1 
>  3 files changed, 100 insertions(+), 74 deletions(-)
> 
> --- a/tools/objtool/arch/x86/decode.c
> +++ b/tools/objtool/arch/x86/decode.c
> @@ -659,6 +659,26 @@ const char *arch_nop_insn(int len)
>  	return nops[len-1];
>  }
>  
> +#define BYTE_RET	0xC3
> +
> +const char *arch_ret_insn(int len)
> +{
> +	static const char ret[5][5] = {
> +		{ BYTE_RET },
> +		{ BYTE_RET, BYTES_NOP1 },
> +		{ BYTE_RET, BYTES_NOP2 },
> +		{ BYTE_RET, BYTES_NOP3 },
> +		{ BYTE_RET, BYTES_NOP4 },
> +	};
> +
> +	if (len < 1 || len > 5) {
> +		WARN("invalid RET size: %d\n", len);
> +		return NULL;
> +	}
> +
> +	return ret[len-1];
> +}
> +
>  /* asm/alternative.h ? */
>  
>  #define ALTINSTR_FLAG_INV	(1 << 15)
> --- a/tools/objtool/check.c
> +++ b/tools/objtool/check.c
> @@ -828,6 +828,74 @@ static struct reloc *insn_reloc(struct o
>  	return insn->reloc;
>  }
>  
> +static void remove_insn_ops(struct instruction *insn)
> +{
> +	struct stack_op *op, *tmp;
> +
> +	list_for_each_entry_safe(op, tmp, &insn->stack_ops, list) {
> +		list_del(&op->list);
> +		free(op);
> +	}
> +}
> +
> +static void add_call_dest(struct objtool_file *file, struct instruction *insn,
> +			  struct symbol *dest, bool sibling)
> +{
> +	struct reloc *reloc = insn_reloc(file, insn);
> +
> +	insn->call_dest = dest;
> +	if (!dest)
> +		return;
> +
> +	if (insn->call_dest->static_call_tramp) {
> +		list_add_tail(&insn->call_node,
> +			      &file->static_call_list);
> +	}
> +
> +	if (insn->sec->noinstr &&
> +	    !strncmp(insn->call_dest->name, "__sanitizer_cov_", 16)) {
> +		if (reloc) {
> +			reloc->type = R_NONE;
> +			elf_write_reloc(file->elf, reloc);
> +		}
> +
> +		elf_write_insn(file->elf, insn->sec,
> +			       insn->offset, insn->len,
> +			       sibling ? arch_ret_insn(insn->len)
> +			               : arch_nop_insn(insn->len));
> +
> +		insn->type = sibling ? INSN_RETURN : INSN_NOP;
> +	}
> +
> +	if (mcount && !strcmp(insn->call_dest->name, "__fentry__")) {
> +		if (sibling)
> +			WARN_FUNC("Tail call to __fentry__ !?!?", insn->sec, insn->offset);
> +
> +		if (reloc) {
> +			reloc->type = R_NONE;
> +			elf_write_reloc(file->elf, reloc);
> +		}
> +
> +		elf_write_insn(file->elf, insn->sec,
> +			       insn->offset, insn->len,
> +			       arch_nop_insn(insn->len));
> +
> +		insn->type = INSN_NOP;
> +
> +		list_add_tail(&insn->mcount_loc_node,
> +			      &file->mcount_loc_list);
> +	}
> +
> +	/*
> +	 * Whatever stack impact regular CALLs have, should be undone
> +	 * by the RETURN of the called function.
> +	 *
> +	 * Annotated intra-function calls retain the stack_ops but
> +	 * are converted to JUMP, see read_intra_function_calls().
> +	 */
> +	remove_insn_ops(insn);
> +}
> +
>  /*
>   * Find the destination instructions for all jumps.
>   */
> @@ -866,11 +934,7 @@ static int add_jump_destinations(struct
>  			continue;
>  		} else if (insn->func) {
>  			/* internal or external sibling call (with reloc) */
> -			insn->call_dest = reloc->sym;
> -			if (insn->call_dest->static_call_tramp) {
> -				list_add_tail(&insn->call_node,
> -					      &file->static_call_list);
> -			}
> +			add_call_dest(file, insn, reloc->sym, true);
>  			continue;
>  		} else if (reloc->sym->sec->idx) {
>  			dest_sec = reloc->sym->sec;
> @@ -926,13 +990,8 @@ static int add_jump_destinations(struct
>  
>  			} else if (insn->jump_dest->func->pfunc != insn->func->pfunc &&
>  				   insn->jump_dest->offset == insn->jump_dest->func->offset) {
> -
>  				/* internal sibling call (without reloc) */
> -				insn->call_dest = insn->jump_dest->func;
> -				if (insn->call_dest->static_call_tramp) {
> -					list_add_tail(&insn->call_node,
> -						      &file->static_call_list);
> -				}
> +				add_call_dest(file, insn, insn->jump_dest->func, true);
>  			}
>  		}
>  	}
> @@ -940,16 +999,6 @@ static int add_jump_destinations(struct
>  	return 0;
>  }
>  
> -static void remove_insn_ops(struct instruction *insn)
> -{
> -	struct stack_op *op, *tmp;
> -
> -	list_for_each_entry_safe(op, tmp, &insn->stack_ops, list) {
> -		list_del(&op->list);
> -		free(op);
> -	}
> -}
> -
>  static struct symbol *find_call_destination(struct section *sec, unsigned long offset)
>  {
>  	struct symbol *call_dest;
> @@ -968,6 +1017,7 @@ static int add_call_destinations(struct
>  {
>  	struct instruction *insn;
>  	unsigned long dest_off;
> +	struct symbol *dest;
>  	struct reloc *reloc;
>  
>  	for_each_insn(file, insn) {
> @@ -977,7 +1027,9 @@ static int add_call_destinations(struct
>  		reloc = insn_reloc(file, insn);
>  		if (!reloc) {
>  			dest_off = arch_jump_destination(insn);
> -			insn->call_dest = find_call_destination(insn->sec, dest_off);
> +			dest = find_call_destination(insn->sec, dest_off);
> +
> +			add_call_dest(file, insn, dest, false);
>  
>  			if (insn->ignore)
>  				continue;
> @@ -995,9 +1047,8 @@ static int add_call_destinations(struct
>  
>  		} else if (reloc->sym->type == STT_SECTION) {
>  			dest_off = arch_dest_reloc_offset(reloc->addend);
> -			insn->call_dest = find_call_destination(reloc->sym->sec,
> -								dest_off);
> -			if (!insn->call_dest) {
> +			dest = find_call_destination(reloc->sym->sec, dest_off);
> +			if (!dest) {
>  				WARN_FUNC("can't find call dest symbol at %s+0x%lx",
>  					  insn->sec, insn->offset,
>  					  reloc->sym->sec->name,
> @@ -1005,6 +1056,8 @@ static int add_call_destinations(struct
>  				return -1;
>  			}
>  
> +			add_call_dest(file, insn, dest, false);
> +
>  		} else if (arch_is_retpoline(reloc->sym)) {
>  			/*
>  			 * Retpoline calls are really dynamic calls in
> @@ -1020,55 +1073,7 @@ static int add_call_destinations(struct
>  			continue;
>  
>  		} else
> -			insn->call_dest = reloc->sym;
> -
> -		if (insn->call_dest && insn->call_dest->static_call_tramp) {
> -			list_add_tail(&insn->call_node,
> -				      &file->static_call_list);
> -		}
> -
> -		/*
> -		 * Many compilers cannot disable KCOV with a function attribute
> -		 * so they need a little help, NOP out any KCOV calls from noinstr
> -		 * text.
> -		 */
> -		if (insn->sec->noinstr &&
> -		    !strncmp(insn->call_dest->name, "__sanitizer_cov_", 16)) {
> -			if (reloc) {
> -				reloc->type = R_NONE;
> -				elf_write_reloc(file->elf, reloc);
> -			}
> -
> -			elf_write_insn(file->elf, insn->sec,
> -				       insn->offset, insn->len,
> -				       arch_nop_insn(insn->len));
> -			insn->type = INSN_NOP;
> -		}
> -
> -		if (mcount && !strcmp(insn->call_dest->name, "__fentry__")) {
> -			if (reloc) {
> -				reloc->type = R_NONE;
> -				elf_write_reloc(file->elf, reloc);
> -			}
> -
> -			elf_write_insn(file->elf, insn->sec,
> -				       insn->offset, insn->len,
> -				       arch_nop_insn(insn->len));
> -
> -			insn->type = INSN_NOP;
> -
> -			list_add_tail(&insn->mcount_loc_node,
> -				      &file->mcount_loc_list);
> -		}
> -
> -		/*
> -		 * Whatever stack impact regular CALLs have, should be undone
> -		 * by the RETURN of the called function.
> -		 *
> -		 * Annotated intra-function calls retain the stack_ops but
> -		 * are converted to JUMP, see read_intra_function_calls().
> -		 */
> -		remove_insn_ops(insn);
> +			add_call_dest(file, insn, reloc->sym, false);
>  	}
>  
>  	return 0;
> --- a/tools/objtool/include/objtool/arch.h
> +++ b/tools/objtool/include/objtool/arch.h
> @@ -82,6 +82,7 @@ unsigned long arch_jump_destination(stru
>  unsigned long arch_dest_reloc_offset(int addend);
>  
>  const char *arch_nop_insn(int len);
> +const char *arch_ret_insn(int len);
>  
>  int arch_decode_hint_reg(struct instruction *insn, u8 sp_reg);
>  
> 
> 

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 03/24] objtool: Handle __sanitize_cov*() tail calls
  2021-06-24  9:41 ` [PATCH v2 03/24] objtool: Handle __sanitize_cov*() tail calls Peter Zijlstra
  2021-06-25 11:05   ` Marco Elver
@ 2021-06-25 13:38   ` Steven Rostedt
  2021-06-26  8:18     ` Peter Zijlstra
  2021-08-20 23:17   ` Josh Poimboeuf
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
  3 siblings, 1 reply; 101+ messages in thread
From: Steven Rostedt @ 2021-06-25 13:38 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: jpoimboe, tglx, linux-kernel, joro, boris.ostrovsky, jgross, x86,
	mbenes, dvyukov, elver

On Thu, 24 Jun 2021 11:41:02 +0200
Peter Zijlstra <peterz@infradead.org> wrote:

> +static void add_call_dest(struct objtool_file *file, struct instruction *insn,
> +			  struct symbol *dest, bool sibling)
> +{
> +	struct reloc *reloc = insn_reloc(file, insn);
> +
> +	insn->call_dest = dest;
> +	if (!dest)
> +		return;
> +
> +	if (insn->call_dest->static_call_tramp) {
> +		list_add_tail(&insn->call_node,
> +			      &file->static_call_list);
> +	}
> +
> +	if (insn->sec->noinstr &&
> +	    !strncmp(insn->call_dest->name, "__sanitizer_cov_", 16)) {
> +		if (reloc) {
> +			reloc->type = R_NONE;
> +			elf_write_reloc(file->elf, reloc);
> +		}
> +
> +		elf_write_insn(file->elf, insn->sec,
> +			       insn->offset, insn->len,
> +			       sibling ? arch_ret_insn(insn->len)
> +			               : arch_nop_insn(insn->len));
> +
> +		insn->type = sibling ? INSN_RETURN : INSN_NOP;
> +	}
> +
> +	if (mcount && !strcmp(insn->call_dest->name, "__fentry__")) {
> +		if (sibling)
> +			WARN_FUNC("Tail call to __fentry__ !?!?", insn->sec, insn->offset);

Have you ever triggered the above?

-- Steve

> +
> +		if (reloc) {
> +			reloc->type = R_NONE;
> +			elf_write_reloc(file->elf, reloc);
> +		}
> +

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 03/24] objtool: Handle __sanitize_cov*() tail calls
  2021-06-25 13:38   ` Steven Rostedt
@ 2021-06-26  8:18     ` Peter Zijlstra
  2021-06-29  1:07       ` Steven Rostedt
  0 siblings, 1 reply; 101+ messages in thread
From: Peter Zijlstra @ 2021-06-26  8:18 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: jpoimboe, tglx, linux-kernel, joro, boris.ostrovsky, jgross, x86,
	mbenes, dvyukov, elver

On Fri, Jun 25, 2021 at 09:38:24AM -0400, Steven Rostedt wrote:
> On Thu, 24 Jun 2021 11:41:02 +0200
> Peter Zijlstra <peterz@infradead.org> wrote:
> 
> > +static void add_call_dest(struct objtool_file *file, struct instruction *insn,
> > +			  struct symbol *dest, bool sibling)
> > +{
> > +	struct reloc *reloc = insn_reloc(file, insn);
> > +
> > +	insn->call_dest = dest;
> > +	if (!dest)
> > +		return;
> > +
> > +	if (insn->call_dest->static_call_tramp) {
> > +		list_add_tail(&insn->call_node,
> > +			      &file->static_call_list);
> > +	}
> > +
> > +	if (insn->sec->noinstr &&
> > +	    !strncmp(insn->call_dest->name, "__sanitizer_cov_", 16)) {
> > +		if (reloc) {
> > +			reloc->type = R_NONE;
> > +			elf_write_reloc(file->elf, reloc);
> > +		}
> > +
> > +		elf_write_insn(file->elf, insn->sec,
> > +			       insn->offset, insn->len,
> > +			       sibling ? arch_ret_insn(insn->len)
> > +			               : arch_nop_insn(insn->len));
> > +
> > +		insn->type = sibling ? INSN_RETURN : INSN_NOP;
> > +	}
> > +
> > +	if (mcount && !strcmp(insn->call_dest->name, "__fentry__")) {
> > +		if (sibling)
> > +			WARN_FUNC("Tail call to __fentry__ !?!?", insn->sec, insn->offset);
> 
> Have you ever triggered the above?

No, that would be really daft. But since this function is to be called
for both regular and tail calls, I figured I'd at least pretend to
handle the case.

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 03/24] objtool: Handle __sanitize_cov*() tail calls
  2021-06-25 11:05   ` Marco Elver
@ 2021-06-28  9:07     ` Peter Zijlstra
  0 siblings, 0 replies; 101+ messages in thread
From: Peter Zijlstra @ 2021-06-28  9:07 UTC (permalink / raw)
  To: Marco Elver
  Cc: jpoimboe, tglx, linux-kernel, joro, boris.ostrovsky, jgross, x86,
	mbenes, rostedt, dvyukov

On Fri, Jun 25, 2021 at 01:05:39PM +0200, Marco Elver wrote:
> On Thu, Jun 24, 2021 at 11:41AM +0200, Peter Zijlstra wrote:
> > Turns out the compilers also generate tail calls to __sanitize_cov*(),
> > make sure to also patch those out in noinstr code.
> > 
> > Fixes: 0f1441b44e82 ("objtool: Fix noinstr vs KCOV")
> > Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
> 
> Acked-by: Marco Elver <elver@google.com>
> 
> Thanks! More reason to not even try to do the same for other
> architectures, and the compiler needing the attribute...

Agreed!

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 03/24] objtool: Handle __sanitize_cov*() tail calls
  2021-06-26  8:18     ` Peter Zijlstra
@ 2021-06-29  1:07       ` Steven Rostedt
  0 siblings, 0 replies; 101+ messages in thread
From: Steven Rostedt @ 2021-06-29  1:07 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: jpoimboe, tglx, linux-kernel, joro, boris.ostrovsky, jgross, x86,
	mbenes, dvyukov, elver

On Sat, 26 Jun 2021 10:18:12 +0200
Peter Zijlstra <peterz@infradead.org> wrote:

> > > +	if (mcount && !strcmp(insn->call_dest->name, "__fentry__")) {
> > > +		if (sibling)
> > > +			WARN_FUNC("Tail call to __fentry__ !?!?", insn->sec, insn->offset);  
> > 
> > Have you ever triggered the above?  
> 
> No, that would be really daft. But since this function is to be called
> for both regular and tail calls, I figured I'd at least pretend to
> handle the case.

OK. I thought this was like one of those weird laws that were made
because you know that someone did something really stupid once.

-- Steve

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 01/24] x86/xen: Mark cpu_bringup_and_idle() as dead_end_function
  2021-06-24  9:41 ` [PATCH v2 01/24] x86/xen: Mark cpu_bringup_and_idle() as dead_end_function Peter Zijlstra
  2021-06-24 10:49   ` Juergen Gross
@ 2021-06-30 11:47   ` Miroslav Benes
  2021-08-20 19:22   ` Josh Poimboeuf
  2021-09-15 15:49   ` [tip: objtool/core] x86/xen: Mark cpu_bringup_and_idle() as dead_end_function tip-bot2 for Peter Zijlstra
  3 siblings, 0 replies; 101+ messages in thread
From: Miroslav Benes @ 2021-06-30 11:47 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: jpoimboe, tglx, linux-kernel, joro, boris.ostrovsky, jgross, x86,
	mbenes, rostedt, dvyukov, elver

On Thu, 24 Jun 2021, Peter Zijlstra wrote:

> The asm_cpu_bringup_and_idle() function is required to push the return
> value on the stack in order to make ORC happy, but the only reason
> objtool doesn't complain is because of a happy accident.
> 
> The thing is that asm_cpu_bringup_and_idle() doesn't return, so
> validate_branch() never terminates and falls through to the next
> function, which in the normal case is the hypercall_page. And that, as
> it happens, is 4095 NOPs and a RET.
> 
> Make asm_cpu_bringup_and_idle() terminate on it's own, by making the
> function it calls as a dead-end. This way we no longer rely on what
> code happens to come after.
> 
> Fixes: c3881eb58d56 ("x86/xen: Make the secondary CPU idle tasks reliable")
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>

Reviewed-by: Miroslav Benes <mbenes@suse.cz>

M

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 02/24] objtool: Introduce CFI hash
  2021-06-24  9:41 ` [PATCH v2 02/24] objtool: Introduce CFI hash Peter Zijlstra
@ 2021-06-30 12:45   ` Miroslav Benes
  2021-07-01  8:35     ` Peter Zijlstra
  2021-08-20 22:27   ` Josh Poimboeuf
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
  2 siblings, 1 reply; 101+ messages in thread
From: Miroslav Benes @ 2021-06-30 12:45 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: jpoimboe, tglx, linux-kernel, joro, boris.ostrovsky, jgross, x86,
	mbenes, rostedt, dvyukov, elver, Andi Kleen

> @@ -2725,15 +2820,24 @@ static int validate_branch(struct objtoo
>  
>  			if (insn->visited & visited)
>  				return 0;
> -		}
> +		} else
> +			nr_visited++;

just a coding style

	} else {
		nr_visited++;
	}

> @@ -3192,6 +3304,13 @@ int check(struct objtool_file *file)
>  		warnings += ret;
>  	}
>  
> +	if (stats) {
> +		printf("nr_visited: %ld\n", nr_visited);

Could we make this nr_insns_visited?

> +		printf("nr_cfi: %ld\n", nr_cfi);
> +		printf("nr_cfi_reused: %ld\n", nr_cfi_reused);
> +		printf("nr_cfi_cache: %ld\n", nr_cfi_cache);
> +	}
> +
> +++ b/tools/objtool/orc_gen.c
> @@ -13,13 +13,19 @@
>  #include <objtool/warn.h>
>  #include <objtool/endianness.h>
>  
> -static int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi)
> +static int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi,
> +			  struct instruction *insn)
>  {
> -	struct instruction *insn = container_of(cfi, struct instruction, cfi);
>  	struct cfi_reg *bp = &cfi->regs[CFI_BP];
>  
>  	memset(orc, 0, sizeof(*orc));
>  
> +	if (!cfi) {
> +		orc->end = 0;
> +		orc->sp_reg = ORC_REG_UNDEFINED;
> +		return 0;
> +	}
> +

This looks strange. You access cfi a couple of lines earlier (bp cfi_reg 
initialization).

Is it even possible to have cfi == NULL here? The second call site below 
has a check and the first one should not happen (insn->cfip should be 
always set if I am not missing something).

>  	orc->end = cfi->end;
>  
>  	if (cfi->cfa.base == CFI_UNDEFINED) {
> @@ -162,7 +168,7 @@ int orc_create(struct objtool_file *file
>  			int i;
>  
>  			if (!alt_group) {
> -				if (init_orc_entry(&orc, &insn->cfi))
> +				if (init_orc_entry(&orc, insn->cfip, insn))
>  					return -1;
>  				if (!memcmp(&prev_orc, &orc, sizeof(orc)))
>  					continue;
> @@ -186,7 +192,8 @@ int orc_create(struct objtool_file *file
>  				struct cfi_state *cfi = alt_group->cfi[i];
>  				if (!cfi)
>  					continue;
> -				if (init_orc_entry(&orc, cfi))
> +				/* errors are reported on the original insn */
> +				if (init_orc_entry(&orc, cfi, insn))
>  					return -1;
>  				if (!memcmp(&prev_orc, &orc, sizeof(orc)))
>  					continue;

Anyway, this is a nice improvement.

Miroslav

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 02/24] objtool: Introduce CFI hash
  2021-06-30 12:45   ` Miroslav Benes
@ 2021-07-01  8:35     ` Peter Zijlstra
  2021-07-01  8:53       ` Miroslav Benes
  0 siblings, 1 reply; 101+ messages in thread
From: Peter Zijlstra @ 2021-07-01  8:35 UTC (permalink / raw)
  To: Miroslav Benes
  Cc: jpoimboe, tglx, linux-kernel, joro, boris.ostrovsky, jgross, x86,
	mbenes, rostedt, dvyukov, elver, Andi Kleen

On Wed, Jun 30, 2021 at 02:45:57PM +0200, Miroslav Benes wrote:
> > @@ -2725,15 +2820,24 @@ static int validate_branch(struct objtoo
> >  
> >  			if (insn->visited & visited)
> >  				return 0;
> > -		}
> > +		} else
> > +			nr_visited++;
> 
> just a coding style
> 
> 	} else {
> 		nr_visited++;
> 	}
> 
> > @@ -3192,6 +3304,13 @@ int check(struct objtool_file *file)
> >  		warnings += ret;
> >  	}
> >  
> > +	if (stats) {
> > +		printf("nr_visited: %ld\n", nr_visited);
> 
> Could we make this nr_insns_visited?

Both done.

> > +		printf("nr_cfi: %ld\n", nr_cfi);
> > +		printf("nr_cfi_reused: %ld\n", nr_cfi_reused);
> > +		printf("nr_cfi_cache: %ld\n", nr_cfi_cache);
> > +	}
> > +
> > +++ b/tools/objtool/orc_gen.c
> > @@ -13,13 +13,19 @@
> >  #include <objtool/warn.h>
> >  #include <objtool/endianness.h>
> >  
> > -static int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi)
> > +static int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi,
> > +			  struct instruction *insn)
> >  {
> > -	struct instruction *insn = container_of(cfi, struct instruction, cfi);
> >  	struct cfi_reg *bp = &cfi->regs[CFI_BP];
> >  
> >  	memset(orc, 0, sizeof(*orc));
> >  
> > +	if (!cfi) {
> > +		orc->end = 0;
> > +		orc->sp_reg = ORC_REG_UNDEFINED;
> > +		return 0;
> > +	}
> > +
> 
> This looks strange. You access cfi a couple of lines earlier (bp cfi_reg 
> initialization).

That's a relative address compute, it doesn't actually dereference the
pointer.

> Is it even possible to have cfi == NULL here? The second call site below 
> has a check and the first one should not happen (insn->cfip should be 
> always set if I am not missing something).

I can happen for instructions that are not visited, like NOP fillers
between functions. Remove the check and try to build a file :-)

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 02/24] objtool: Introduce CFI hash
  2021-07-01  8:35     ` Peter Zijlstra
@ 2021-07-01  8:53       ` Miroslav Benes
  0 siblings, 0 replies; 101+ messages in thread
From: Miroslav Benes @ 2021-07-01  8:53 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: jpoimboe, tglx, linux-kernel, joro, boris.ostrovsky, jgross, x86,
	mbenes, rostedt, dvyukov, elver, Andi Kleen

> > > +++ b/tools/objtool/orc_gen.c
> > > @@ -13,13 +13,19 @@
> > >  #include <objtool/warn.h>
> > >  #include <objtool/endianness.h>
> > >  
> > > -static int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi)
> > > +static int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi,
> > > +			  struct instruction *insn)
> > >  {
> > > -	struct instruction *insn = container_of(cfi, struct instruction, cfi);
> > >  	struct cfi_reg *bp = &cfi->regs[CFI_BP];
> > >  
> > >  	memset(orc, 0, sizeof(*orc));
> > >  
> > > +	if (!cfi) {
> > > +		orc->end = 0;
> > > +		orc->sp_reg = ORC_REG_UNDEFINED;
> > > +		return 0;
> > > +	}
> > > +
> > 
> > This looks strange. You access cfi a couple of lines earlier (bp cfi_reg 
> > initialization).
> 
> That's a relative address compute, it doesn't actually dereference the
> pointer.

Right, I misread the line.
 
> > Is it even possible to have cfi == NULL here? The second call site below 
> > has a check and the first one should not happen (insn->cfip should be 
> > always set if I am not missing something).
> 
> I can happen for instructions that are not visited, like NOP fillers
> between functions. Remove the check and try to build a file :-)

Doh, I should have done that. Of course there must be unvisited 
instructions. Sorry for the noise.

Miroslav

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 01/24] x86/xen: Mark cpu_bringup_and_idle() as dead_end_function
  2021-06-24  9:41 ` [PATCH v2 01/24] x86/xen: Mark cpu_bringup_and_idle() as dead_end_function Peter Zijlstra
  2021-06-24 10:49   ` Juergen Gross
  2021-06-30 11:47   ` Miroslav Benes
@ 2021-08-20 19:22   ` Josh Poimboeuf
  2021-08-20 19:31     ` Josh Poimboeuf
  2021-09-15 15:49   ` [tip: objtool/core] x86/xen: Mark cpu_bringup_and_idle() as dead_end_function tip-bot2 for Peter Zijlstra
  3 siblings, 1 reply; 101+ messages in thread
From: Josh Poimboeuf @ 2021-08-20 19:22 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: tglx, linux-kernel, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver

On Thu, Jun 24, 2021 at 11:41:00AM +0200, Peter Zijlstra wrote:
> The asm_cpu_bringup_and_idle() function is required to push the return
> value on the stack in order to make ORC happy, but the only reason
> objtool doesn't complain is because of a happy accident.
> 
> The thing is that asm_cpu_bringup_and_idle() doesn't return, so
> validate_branch() never terminates and falls through to the next
> function, which in the normal case is the hypercall_page. And that, as
> it happens, is 4095 NOPs and a RET.
> 
> Make asm_cpu_bringup_and_idle() terminate on it's own, by making the
> function it calls as a dead-end. This way we no longer rely on what
> code happens to come after.
> 
> Fixes: c3881eb58d56 ("x86/xen: Make the secondary CPU idle tasks reliable")
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>

Looks right.  Only problem is, with my assembler I get this:

  arch/x86/kernel/head_64.o: warning: objtool: .text+0x5: unreachable instruction

Because gas insists on jumping over the page of nops...

0000000000000000 <asm_cpu_bringup_and_idle>:
       0:	e8 00 00 00 00       	callq  5 <asm_cpu_bringup_and_idle+0x5>
			1: R_X86_64_PLT32	cpu_bringup_and_idle-0x4
       5:	e9 f6 0f 00 00       	jmpq   1000 <xen_hypercall_set_trap_table>
       a:	66 66 2e 0f 1f 84 00 	data16 nopw %cs:0x0(%rax,%rax,1)
      11:	00 00 00 00 
      15:	66 66 2e 0f 1f 84 00 	data16 nopw %cs:0x0(%rax,%rax,1)
      1c:	00 00 00 00 
      20:	66 66 2e 0f 1f 84 00 	data16 nopw %cs:0x0(%rax,%rax,1)
      27:	00 00 00 00 
      2b:	66 66 2e 0f 1f 84 00 	data16 nopw %cs:0x0(%rax,%rax,1)
      32:	00 00 00 00 
      36:	66 66 2e 0f 1f 84 00 	data16 nopw %cs:0x0(%rax,%rax,1)
      3d:	00 00 00 00 

-- 
Josh


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 01/24] x86/xen: Mark cpu_bringup_and_idle() as dead_end_function
  2021-08-20 19:22   ` Josh Poimboeuf
@ 2021-08-20 19:31     ` Josh Poimboeuf
  2021-08-23  8:40       ` Juergen Gross
  2021-09-15 15:49       ` [tip: objtool/core] x86/xen: Move hypercall_page to top of the file tip-bot2 for Josh Poimboeuf
  0 siblings, 2 replies; 101+ messages in thread
From: Josh Poimboeuf @ 2021-08-20 19:31 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: tglx, linux-kernel, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver

On Fri, Aug 20, 2021 at 12:22:28PM -0700, Josh Poimboeuf wrote:
> On Thu, Jun 24, 2021 at 11:41:00AM +0200, Peter Zijlstra wrote:
> > The asm_cpu_bringup_and_idle() function is required to push the return
> > value on the stack in order to make ORC happy, but the only reason
> > objtool doesn't complain is because of a happy accident.
> > 
> > The thing is that asm_cpu_bringup_and_idle() doesn't return, so
> > validate_branch() never terminates and falls through to the next
> > function, which in the normal case is the hypercall_page. And that, as
> > it happens, is 4095 NOPs and a RET.
> > 
> > Make asm_cpu_bringup_and_idle() terminate on it's own, by making the
> > function it calls as a dead-end. This way we no longer rely on what
> > code happens to come after.
> > 
> > Fixes: c3881eb58d56 ("x86/xen: Make the secondary CPU idle tasks reliable")
> > Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
> 
> Looks right.  Only problem is, with my assembler I get this:
> 
>   arch/x86/kernel/head_64.o: warning: objtool: .text+0x5: unreachable instruction
> 
> Because gas insists on jumping over the page of nops...
> 
> 0000000000000000 <asm_cpu_bringup_and_idle>:
>        0:	e8 00 00 00 00       	callq  5 <asm_cpu_bringup_and_idle+0x5>
> 			1: R_X86_64_PLT32	cpu_bringup_and_idle-0x4
>        5:	e9 f6 0f 00 00       	jmpq   1000 <xen_hypercall_set_trap_table>
>        a:	66 66 2e 0f 1f 84 00 	data16 nopw %cs:0x0(%rax,%rax,1)
>       11:	00 00 00 00 
>       15:	66 66 2e 0f 1f 84 00 	data16 nopw %cs:0x0(%rax,%rax,1)
>       1c:	00 00 00 00 
>       20:	66 66 2e 0f 1f 84 00 	data16 nopw %cs:0x0(%rax,%rax,1)
>       27:	00 00 00 00 
>       2b:	66 66 2e 0f 1f 84 00 	data16 nopw %cs:0x0(%rax,%rax,1)
>       32:	00 00 00 00 
>       36:	66 66 2e 0f 1f 84 00 	data16 nopw %cs:0x0(%rax,%rax,1)
>       3d:	00 00 00 00 

Here's a fix:

From: Josh Poimboeuf <jpoimboe@redhat.com>
Subject: [PATCH] x86/xen: Move hypercall_page to top of the file

Because hypercall_page is page-aligned, the assembler inexplicably adds
an unreachable jump from after the end of the previous code to the
beginning of hypercall_page.

That confuses objtool, understandably.  It also creates significant text
fragmentation.  As a result, much of the object file is wasted text
(nops).

Move hypercall_page to the beginning of the file to both prevent the
text fragmentation and avoid the dead jump instruction.

$ size /tmp/head_64.before.o /tmp/head_64.after.o
   text	   data	    bss	    dec	    hex	filename
  10924	 307252	   4096	 322272	  4eae0	/tmp/head_64.before.o
   6823	 307252	   4096	 318171	  4dadb	/tmp/head_64.after.o

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
---
 arch/x86/xen/xen-head.S | 34 +++++++++++++++++-----------------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/arch/x86/xen/xen-head.S b/arch/x86/xen/xen-head.S
index cb6538ae2fe0..488944d6d430 100644
--- a/arch/x86/xen/xen-head.S
+++ b/arch/x86/xen/xen-head.S
@@ -20,6 +20,23 @@
 #include <xen/interface/xen-mca.h>
 #include <asm/xen/interface.h>
 
+.pushsection .text
+	.balign PAGE_SIZE
+SYM_CODE_START(hypercall_page)
+	.rept (PAGE_SIZE / 32)
+		UNWIND_HINT_FUNC
+		.skip 31, 0x90
+		ret
+	.endr
+
+#define HYPERCALL(n) \
+	.equ xen_hypercall_##n, hypercall_page + __HYPERVISOR_##n * 32; \
+	.type xen_hypercall_##n, @function; .size xen_hypercall_##n, 32
+#include <asm/xen-hypercalls.h>
+#undef HYPERCALL
+SYM_CODE_END(hypercall_page)
+.popsection
+
 #ifdef CONFIG_XEN_PV
 	__INIT
 SYM_CODE_START(startup_xen)
@@ -64,23 +81,6 @@ SYM_CODE_END(asm_cpu_bringup_and_idle)
 #endif
 #endif
 
-.pushsection .text
-	.balign PAGE_SIZE
-SYM_CODE_START(hypercall_page)
-	.rept (PAGE_SIZE / 32)
-		UNWIND_HINT_FUNC
-		.skip 31, 0x90
-		ret
-	.endr
-
-#define HYPERCALL(n) \
-	.equ xen_hypercall_##n, hypercall_page + __HYPERVISOR_##n * 32; \
-	.type xen_hypercall_##n, @function; .size xen_hypercall_##n, 32
-#include <asm/xen-hypercalls.h>
-#undef HYPERCALL
-SYM_CODE_END(hypercall_page)
-.popsection
-
 	ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS,       .asciz "linux")
 	ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION,  .asciz "2.6")
 	ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION,    .asciz "xen-3.0")
-- 
2.31.1


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 02/24] objtool: Introduce CFI hash
  2021-06-24  9:41 ` [PATCH v2 02/24] objtool: Introduce CFI hash Peter Zijlstra
  2021-06-30 12:45   ` Miroslav Benes
@ 2021-08-20 22:27   ` Josh Poimboeuf
  2021-08-25 10:13     ` Peter Zijlstra
  2021-08-25 10:15     ` Peter Zijlstra
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
  2 siblings, 2 replies; 101+ messages in thread
From: Josh Poimboeuf @ 2021-08-20 22:27 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: tglx, linux-kernel, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver, Andi Kleen

On Thu, Jun 24, 2021 at 11:41:01AM +0200, Peter Zijlstra wrote:
> Andi reported that objtool on vmlinux.o consumes more memory than his
> system has, leading to horrific performance.
> 
> This is in part because we keep a struct instruction for every
> instruction in the file in-memory. Shrink struct instruction by
> removing the CFI state (which includes full register state) from it
> and demand allocating it.
> 
> Given most instructions don't actually change CFI state, there's lots
> of repetition there, so add a hash table to find previous CFI
> instances.
> 
> Reduces memory consumption (and runtime) for processing an
> x86_64-allyesconfig:
> 
>   pre:  4:40.84 real,   143.99 user,    44.18 sys,      30624988 mem
>   post: 2:14.61 real,   108.58 user,    25.04 sys,      16396184 mem

Excellent.

> +static struct cfi_state *cfi_alloc(void)
> +{
> +	struct cfi_state *cfi = calloc(sizeof(struct cfi_state), 1);
> +	if (!cfi) {
> +		WARN("calloc failed");
> +		exit(1);
> +	}
> +	nr_cfi++;
> +	init_cfi_state(cfi);
> +	return cfi;
> +}

I'm thinking this should also add it to the hash.  i.e. I don't think
there's a scenario where you'd alloc a cfi and not want to add it to the
hash.  The more sharing the better.

> +
> +struct cfi_state *insn_get_cfi(struct instruction *insn)
> +{
> +	if (!insn->cfip)
> +		insn->cfip = cfi_alloc();
> +
> +	return insn->cfip;
> +}

Call it something like insn_get_or_alloc_cfi()?

Also, the function can be static.

> +static struct cfi_state *cfi_hash_find(struct cfi_state *cfi)
> +{
> +	struct hlist_head *head = &cfi_hash[hash_min(cfi_key(cfi), cfi_bits)];
> +	struct cfi_state *obj;
> +
> +	hlist_for_each_entry(obj, head, hash) {
> +		if (!cficmp(cfi, obj)) {
> +			nr_cfi_cache++;
> +			return obj;
> +		}
> +	}
> +
> +	obj = cfi_alloc();
> +	*obj = *cfi;
> +	hlist_add_head(&obj->hash, head);
> +
> +	return obj;

cfi_hash_find_or_alloc_cfi()?

> @@ -2725,15 +2820,24 @@ static int validate_branch(struct objtoo
>  
>  			if (insn->visited & visited)
>  				return 0;
> -		}
> +		} else
> +			nr_visited++;
>  
>  		if (state.noinstr)
>  			state.instr += insn->instr;
>  
> -		if (insn->hint)
> -			state.cfi = insn->cfi;
> -		else
> -			insn->cfi = state.cfi;
> +		if (insn->hint) {
> +			state.cfi = *insn->cfip;
> +		} else {
> +			/* XXX track if we actually changed state.cfi */

Why would we do that?

> +++ b/tools/objtool/include/objtool/check.h
> @@ -60,9 +60,11 @@ struct instruction {
>  	struct list_head alts;
>  	struct symbol *func;
>  	struct list_head stack_ops;
> -	struct cfi_state cfi;
> +	struct cfi_state *cfip;

Not sure about this rename.  Pointers generally don't need a 'p' postfix.

-- 
Josh


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 03/24] objtool: Handle __sanitize_cov*() tail calls
  2021-06-24  9:41 ` [PATCH v2 03/24] objtool: Handle __sanitize_cov*() tail calls Peter Zijlstra
  2021-06-25 11:05   ` Marco Elver
  2021-06-25 13:38   ` Steven Rostedt
@ 2021-08-20 23:17   ` Josh Poimboeuf
  2021-08-25 10:19     ` Peter Zijlstra
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
  3 siblings, 1 reply; 101+ messages in thread
From: Josh Poimboeuf @ 2021-08-20 23:17 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: tglx, linux-kernel, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver

On Thu, Jun 24, 2021 at 11:41:02AM +0200, Peter Zijlstra wrote:
> +	if (insn->sec->noinstr &&
> +	    !strncmp(insn->call_dest->name, "__sanitizer_cov_", 16)) {
> +		if (reloc) {
> +			reloc->type = R_NONE;
> +			elf_write_reloc(file->elf, reloc);
> +		}
> +
> +		elf_write_insn(file->elf, insn->sec,
> +			       insn->offset, insn->len,
> +			       sibling ? arch_ret_insn(insn->len)
> +			               : arch_nop_insn(insn->len));
> +
> +		insn->type = sibling ? INSN_RETURN : INSN_NOP;
> +	}

It'd be nice to keep the comment for this case that was in
add_call_destinations().

-- 
Josh


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 06/24] x86: Always inline context_tracking_guest_enter()
  2021-06-24  9:41 ` [PATCH v2 06/24] x86: Always inline context_tracking_guest_enter() Peter Zijlstra
@ 2021-08-20 23:22   ` Josh Poimboeuf
  2021-08-20 23:34     ` Josh Poimboeuf
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
  1 sibling, 1 reply; 101+ messages in thread
From: Josh Poimboeuf @ 2021-08-20 23:22 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: tglx, linux-kernel, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver

On Thu, Jun 24, 2021 at 11:41:05AM +0200, Peter Zijlstra wrote:
> Yes, it really did out-of-line this....
> 
> vmlinux.o: warning: objtool: vmx_vcpu_enter_exit()+0x31: call to context_tracking_guest_enter() leaves .noinstr.text section
> 
> 000000000019f660 <context_tracking_guest_enter>:
>   19f660:	e8 00 00 00 00       	callq  19f665 <context_tracking_guest_enter+0x5>	19f661: R_X86_64_PLT32	__sanitizer_cov_trace_pc-0x4
>   19f665:	31 c0                	xor    %eax,%eax
>   19f667:	c3                   	retq   
> 
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>

Ha.  I'm guessing this was from CONFIG_DEBUG_SECTION_MISMATCH, which is
only good for triggering a lot of these useless __always_inline patches.

I have a patch somewhere to get rid of it.

-- 
Josh


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 06/24] x86: Always inline context_tracking_guest_enter()
  2021-08-20 23:22   ` Josh Poimboeuf
@ 2021-08-20 23:34     ` Josh Poimboeuf
  2021-08-25 12:16       ` Peter Zijlstra
  2021-08-25 13:38       ` Peter Zijlstra
  0 siblings, 2 replies; 101+ messages in thread
From: Josh Poimboeuf @ 2021-08-20 23:34 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: tglx, linux-kernel, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver

On Fri, Aug 20, 2021 at 04:22:07PM -0700, Josh Poimboeuf wrote:
> On Thu, Jun 24, 2021 at 11:41:05AM +0200, Peter Zijlstra wrote:
> > Yes, it really did out-of-line this....
> > 
> > vmlinux.o: warning: objtool: vmx_vcpu_enter_exit()+0x31: call to context_tracking_guest_enter() leaves .noinstr.text section
> > 
> > 000000000019f660 <context_tracking_guest_enter>:
> >   19f660:	e8 00 00 00 00       	callq  19f665 <context_tracking_guest_enter+0x5>	19f661: R_X86_64_PLT32	__sanitizer_cov_trace_pc-0x4
> >   19f665:	31 c0                	xor    %eax,%eax
> >   19f667:	c3                   	retq   
> > 
> > Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
> 
> Ha.  I'm guessing this was from CONFIG_DEBUG_SECTION_MISMATCH, which is
> only good for triggering a lot of these useless __always_inline patches.
> 
> I have a patch somewhere to get rid of it.

Found it.

WARNING: This patch may shrink your patch set and improve your sanity.

From: Josh Poimboeuf <jpoimboe@redhat.com>
Subject: [PATCH] kbuild: Remove CONFIG_DEBUG_SECTION_MISMATCH

Modpost's section mismatch detection warns when a non-init function
references an __init function.  The warning is needed because __init
memory is freed during boot, so the non-init function might end up
calling into some random memory.

CONFIG_DEBUG_SECTION_MISMATCH is intended to root out more of these
issues by adding the -fno-inline-functions-called-once compiler flag,
which forces once-called static functions to not be inlined.  As
described in the option's help description:

  - Add the option -fno-inline-functions-called-once to gcc commands.
    When inlining a function annotated with __init in a non-init
    function, we would lose the section information and thus
    the analysis would not catch the illegal reference.
    This option tells gcc to inline less (but it does result in
    a larger kernel).

It's true that if an __init function is inlined in a non-init function,
it's no longer __init.  But that's not actually a problem.

If an inlined __init function doesn't access any other __init functions
or data, the inlining is harmless.

If the inlined __init function does access other __init functions/data,
__init relocations will be generated for a non-init section, and
modpost's section mismatch detection will discover it.

So the option isn't actually useful.  It's not even useful for finding
issues on other configs, which might have different inlining decisions,
because with -O2, once-called static functions are always inlined.  And
anyway, nowadays we have build bots everywhere, which are great at
finding such edge cases.

I get the feeling this option has been responsible for dozens of
"convert inline to __always_inline" patches over the years.  Such
patches usually complain about the compiler's inlining decisions being
unpredictable.  Turns out the culprit is this
CONFIG_DEBUG_SECTION_MISMATCH option, at least for once-called
functions.

This option really has no benefits, and only drawbacks, causing needless
churn.  Remove it.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
---
 Makefile                                      |  5 -----
 arch/arc/configs/tb10x_defconfig              |  1 -
 arch/nds32/configs/defconfig                  |  1 -
 arch/s390/configs/debug_defconfig             |  1 -
 arch/s390/configs/defconfig                   |  1 -
 lib/Kconfig.debug                             | 21 -------------------
 .../selftests/wireguard/qemu/debug.config     |  1 -
 7 files changed, 31 deletions(-)

diff --git a/Makefile b/Makefile
index c19d1638da25..195d4f4914e3 100644
--- a/Makefile
+++ b/Makefile
@@ -913,11 +913,6 @@ KBUILD_CFLAGS	+= $(CC_FLAGS_FTRACE) $(CC_FLAGS_USING)
 KBUILD_AFLAGS	+= $(CC_FLAGS_USING)
 endif
 
-# We trigger additional mismatches with less inlining
-ifdef CONFIG_DEBUG_SECTION_MISMATCH
-KBUILD_CFLAGS += $(call cc-option, -fno-inline-functions-called-once)
-endif
-
 ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION
 KBUILD_CFLAGS_KERNEL += -ffunction-sections -fdata-sections
 LDFLAGS_vmlinux += --gc-sections
diff --git a/arch/arc/configs/tb10x_defconfig b/arch/arc/configs/tb10x_defconfig
index a12656ec0072..5acf8cc3e7b0 100644
--- a/arch/arc/configs/tb10x_defconfig
+++ b/arch/arc/configs/tb10x_defconfig
@@ -96,7 +96,6 @@ CONFIG_STRIP_ASM_SYMS=y
 CONFIG_DEBUG_FS=y
 CONFIG_HEADERS_INSTALL=y
 CONFIG_HEADERS_CHECK=y
-CONFIG_DEBUG_SECTION_MISMATCH=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_MEMORY_INIT=y
 CONFIG_DEBUG_STACKOVERFLOW=y
diff --git a/arch/nds32/configs/defconfig b/arch/nds32/configs/defconfig
index f9a89cf00aa6..61b5b83bd20e 100644
--- a/arch/nds32/configs/defconfig
+++ b/arch/nds32/configs/defconfig
@@ -93,7 +93,6 @@ CONFIG_GDB_SCRIPTS=y
 CONFIG_READABLE_ASM=y
 CONFIG_HEADERS_INSTALL=y
 CONFIG_HEADERS_CHECK=y
-CONFIG_DEBUG_SECTION_MISMATCH=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_PANIC_ON_OOPS=y
diff --git a/arch/s390/configs/debug_defconfig b/arch/s390/configs/debug_defconfig
index b88184019af9..68104f82cc9d 100644
--- a/arch/s390/configs/debug_defconfig
+++ b/arch/s390/configs/debug_defconfig
@@ -782,7 +782,6 @@ CONFIG_DEBUG_INFO=y
 CONFIG_DEBUG_INFO_DWARF4=y
 CONFIG_GDB_SCRIPTS=y
 CONFIG_HEADERS_INSTALL=y
-CONFIG_DEBUG_SECTION_MISMATCH=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_PAGEALLOC=y
 CONFIG_PAGE_OWNER=y
diff --git a/arch/s390/configs/defconfig b/arch/s390/configs/defconfig
index 1667a3cdcf0a..a5e7eb0276c6 100644
--- a/arch/s390/configs/defconfig
+++ b/arch/s390/configs/defconfig
@@ -767,7 +767,6 @@ CONFIG_DYNAMIC_DEBUG=y
 CONFIG_DEBUG_INFO=y
 CONFIG_DEBUG_INFO_DWARF4=y
 CONFIG_GDB_SCRIPTS=y
-CONFIG_DEBUG_SECTION_MISMATCH=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_WX=y
 CONFIG_PTDUMP_DEBUGFS=y
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index e5cdf98f50c2..93f9c00783b2 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -381,27 +381,6 @@ config HEADERS_INSTALL
 	  user-space program samples. It is also needed by some features such
 	  as uapi header sanity checks.
 
-config DEBUG_SECTION_MISMATCH
-	bool "Enable full Section mismatch analysis"
-	help
-	  The section mismatch analysis checks if there are illegal
-	  references from one section to another section.
-	  During linktime or runtime, some sections are dropped;
-	  any use of code/data previously in these sections would
-	  most likely result in an oops.
-	  In the code, functions and variables are annotated with
-	  __init,, etc. (see the full list in include/linux/init.h),
-	  which results in the code/data being placed in specific sections.
-	  The section mismatch analysis is always performed after a full
-	  kernel build, and enabling this option causes the following
-	  additional step to occur:
-	  - Add the option -fno-inline-functions-called-once to gcc commands.
-	    When inlining a function annotated with __init in a non-init
-	    function, we would lose the section information and thus
-	    the analysis would not catch the illegal reference.
-	    This option tells gcc to inline less (but it does result in
-	    a larger kernel).
-
 config SECTION_MISMATCH_WARN_ONLY
 	bool "Make section mismatch errors non-fatal"
 	default y
diff --git a/tools/testing/selftests/wireguard/qemu/debug.config b/tools/testing/selftests/wireguard/qemu/debug.config
index fe07d97df9fa..83588bb08fde 100644
--- a/tools/testing/selftests/wireguard/qemu/debug.config
+++ b/tools/testing/selftests/wireguard/qemu/debug.config
@@ -57,7 +57,6 @@ CONFIG_USER_STACKTRACE_SUPPORT=y
 CONFIG_DEBUG_SG=y
 CONFIG_DEBUG_NOTIFIERS=y
 CONFIG_X86_DEBUG_FPU=y
-CONFIG_DEBUG_SECTION_MISMATCH=y
 CONFIG_DEBUG_PAGEALLOC=y
 CONFIG_DEBUG_PAGEALLOC_ENABLE_DEFAULT=y
 CONFIG_DEBUG_WW_MUTEX_SLOWPATH=y
-- 
2.31.1


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 01/24] x86/xen: Mark cpu_bringup_and_idle() as dead_end_function
  2021-08-20 19:31     ` Josh Poimboeuf
@ 2021-08-23  8:40       ` Juergen Gross
  2021-08-30  5:55         ` Juergen Gross
  2021-09-15 15:49       ` [tip: objtool/core] x86/xen: Move hypercall_page to top of the file tip-bot2 for Josh Poimboeuf
  1 sibling, 1 reply; 101+ messages in thread
From: Juergen Gross @ 2021-08-23  8:40 UTC (permalink / raw)
  To: Josh Poimboeuf, Peter Zijlstra
  Cc: tglx, linux-kernel, joro, boris.ostrovsky, x86, mbenes, rostedt,
	dvyukov, elver


[-- Attachment #1.1.1: Type: text/plain, Size: 4619 bytes --]

On 20.08.21 21:31, Josh Poimboeuf wrote:
> On Fri, Aug 20, 2021 at 12:22:28PM -0700, Josh Poimboeuf wrote:
>> On Thu, Jun 24, 2021 at 11:41:00AM +0200, Peter Zijlstra wrote:
>>> The asm_cpu_bringup_and_idle() function is required to push the return
>>> value on the stack in order to make ORC happy, but the only reason
>>> objtool doesn't complain is because of a happy accident.
>>>
>>> The thing is that asm_cpu_bringup_and_idle() doesn't return, so
>>> validate_branch() never terminates and falls through to the next
>>> function, which in the normal case is the hypercall_page. And that, as
>>> it happens, is 4095 NOPs and a RET.
>>>
>>> Make asm_cpu_bringup_and_idle() terminate on it's own, by making the
>>> function it calls as a dead-end. This way we no longer rely on what
>>> code happens to come after.
>>>
>>> Fixes: c3881eb58d56 ("x86/xen: Make the secondary CPU idle tasks reliable")
>>> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
>>
>> Looks right.  Only problem is, with my assembler I get this:
>>
>>    arch/x86/kernel/head_64.o: warning: objtool: .text+0x5: unreachable instruction
>>
>> Because gas insists on jumping over the page of nops...
>>
>> 0000000000000000 <asm_cpu_bringup_and_idle>:
>>         0:	e8 00 00 00 00       	callq  5 <asm_cpu_bringup_and_idle+0x5>
>> 			1: R_X86_64_PLT32	cpu_bringup_and_idle-0x4
>>         5:	e9 f6 0f 00 00       	jmpq   1000 <xen_hypercall_set_trap_table>
>>         a:	66 66 2e 0f 1f 84 00 	data16 nopw %cs:0x0(%rax,%rax,1)
>>        11:	00 00 00 00
>>        15:	66 66 2e 0f 1f 84 00 	data16 nopw %cs:0x0(%rax,%rax,1)
>>        1c:	00 00 00 00
>>        20:	66 66 2e 0f 1f 84 00 	data16 nopw %cs:0x0(%rax,%rax,1)
>>        27:	00 00 00 00
>>        2b:	66 66 2e 0f 1f 84 00 	data16 nopw %cs:0x0(%rax,%rax,1)
>>        32:	00 00 00 00
>>        36:	66 66 2e 0f 1f 84 00 	data16 nopw %cs:0x0(%rax,%rax,1)
>>        3d:	00 00 00 00
> 
> Here's a fix:
> 
> From: Josh Poimboeuf <jpoimboe@redhat.com>
> Subject: [PATCH] x86/xen: Move hypercall_page to top of the file
> 
> Because hypercall_page is page-aligned, the assembler inexplicably adds
> an unreachable jump from after the end of the previous code to the
> beginning of hypercall_page.
> 
> That confuses objtool, understandably.  It also creates significant text
> fragmentation.  As a result, much of the object file is wasted text
> (nops).
> 
> Move hypercall_page to the beginning of the file to both prevent the
> text fragmentation and avoid the dead jump instruction.
> 
> $ size /tmp/head_64.before.o /tmp/head_64.after.o
>     text	   data	    bss	    dec	    hex	filename
>    10924	 307252	   4096	 322272	  4eae0	/tmp/head_64.before.o
>     6823	 307252	   4096	 318171	  4dadb	/tmp/head_64.after.o
> 
> Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com

Reviewed-by: Juergen Gross <jgross@suse.com>


Juergen

> ---
>   arch/x86/xen/xen-head.S | 34 +++++++++++++++++-----------------
>   1 file changed, 17 insertions(+), 17 deletions(-)
> 
> diff --git a/arch/x86/xen/xen-head.S b/arch/x86/xen/xen-head.S
> index cb6538ae2fe0..488944d6d430 100644
> --- a/arch/x86/xen/xen-head.S
> +++ b/arch/x86/xen/xen-head.S
> @@ -20,6 +20,23 @@
>   #include <xen/interface/xen-mca.h>
>   #include <asm/xen/interface.h>
>   
> +.pushsection .text
> +	.balign PAGE_SIZE
> +SYM_CODE_START(hypercall_page)
> +	.rept (PAGE_SIZE / 32)
> +		UNWIND_HINT_FUNC
> +		.skip 31, 0x90
> +		ret
> +	.endr
> +
> +#define HYPERCALL(n) \
> +	.equ xen_hypercall_##n, hypercall_page + __HYPERVISOR_##n * 32; \
> +	.type xen_hypercall_##n, @function; .size xen_hypercall_##n, 32
> +#include <asm/xen-hypercalls.h>
> +#undef HYPERCALL
> +SYM_CODE_END(hypercall_page)
> +.popsection
> +
>   #ifdef CONFIG_XEN_PV
>   	__INIT
>   SYM_CODE_START(startup_xen)
> @@ -64,23 +81,6 @@ SYM_CODE_END(asm_cpu_bringup_and_idle)
>   #endif
>   #endif
>   
> -.pushsection .text
> -	.balign PAGE_SIZE
> -SYM_CODE_START(hypercall_page)
> -	.rept (PAGE_SIZE / 32)
> -		UNWIND_HINT_FUNC
> -		.skip 31, 0x90
> -		ret
> -	.endr
> -
> -#define HYPERCALL(n) \
> -	.equ xen_hypercall_##n, hypercall_page + __HYPERVISOR_##n * 32; \
> -	.type xen_hypercall_##n, @function; .size xen_hypercall_##n, 32
> -#include <asm/xen-hypercalls.h>
> -#undef HYPERCALL
> -SYM_CODE_END(hypercall_page)
> -.popsection
> -
>   	ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS,       .asciz "linux")
>   	ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION,  .asciz "2.6")
>   	ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION,    .asciz "xen-3.0")
> 


[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3135 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 02/24] objtool: Introduce CFI hash
  2021-08-20 22:27   ` Josh Poimboeuf
@ 2021-08-25 10:13     ` Peter Zijlstra
  2021-08-25 12:49       ` Peter Zijlstra
  2021-08-25 10:15     ` Peter Zijlstra
  1 sibling, 1 reply; 101+ messages in thread
From: Peter Zijlstra @ 2021-08-25 10:13 UTC (permalink / raw)
  To: Josh Poimboeuf
  Cc: tglx, linux-kernel, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver, Andi Kleen

On Fri, Aug 20, 2021 at 03:27:55PM -0700, Josh Poimboeuf wrote:
> > +static struct cfi_state *cfi_alloc(void)
> > +{
> > +	struct cfi_state *cfi = calloc(sizeof(struct cfi_state), 1);
> > +	if (!cfi) {
> > +		WARN("calloc failed");
> > +		exit(1);
> > +	}
> > +	nr_cfi++;
> > +	init_cfi_state(cfi);
> > +	return cfi;
> > +}
> 
> I'm thinking this should also add it to the hash.  i.e. I don't think
> there's a scenario where you'd alloc a cfi and not want to add it to the
> hash.  The more sharing the better.

Right, changed it like below.

> > +
> > +struct cfi_state *insn_get_cfi(struct instruction *insn)
> > +{
> > +	if (!insn->cfip)
> > +		insn->cfip = cfi_alloc();
> > +
> > +	return insn->cfip;
> > +}
> 
> Call it something like insn_get_or_alloc_cfi()?
> 
> Also, the function can be static.

It's gone now.

> > +static struct cfi_state *cfi_hash_find(struct cfi_state *cfi)
> > +{
> > +	struct hlist_head *head = &cfi_hash[hash_min(cfi_key(cfi), cfi_bits)];
> > +	struct cfi_state *obj;
> > +
> > +	hlist_for_each_entry(obj, head, hash) {
> > +		if (!cficmp(cfi, obj)) {
> > +			nr_cfi_cache++;
> > +			return obj;
> > +		}
> > +	}
> > +
> > +	obj = cfi_alloc();
> > +	*obj = *cfi;
> > +	hlist_add_head(&obj->hash, head);
> > +
> > +	return obj;
> 
> cfi_hash_find_or_alloc_cfi()?


Made that cfi_hash_find_or_add()

--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -30,6 +30,7 @@ struct alternative {
 static unsigned long nr_cfi, nr_cfi_reused, nr_cfi_cache;
 
 static struct cfi_init_state initial_func_cfi;
+static struct cfi_state init_cfi;
 static struct cfi_state func_cfi;
 
 struct instruction *find_insn(struct objtool_file *file,
@@ -278,7 +279,6 @@ static struct cfi_state *cfi_alloc(void)
 		exit(1);
 	}
 	nr_cfi++;
-	init_cfi_state(cfi);
 	return cfi;
 }
 
@@ -298,7 +298,7 @@ static inline u32 cfi_key(struct cfi_sta
 		     sizeof(*cfi) - sizeof(cfi->hash), 0);
 }
 
-static struct cfi_state *cfi_hash_find(struct cfi_state *cfi)
+static struct cfi_state *cfi_hash_find_or_add(struct cfi_state *cfi)
 {
 	struct hlist_head *head = &cfi_hash[hash_min(cfi_key(cfi), cfi_bits)];
 	struct cfi_state *obj;
@@ -1620,10 +1620,10 @@ static void set_func_state(struct cfi_st
 
 static int read_unwind_hints(struct objtool_file *file)
 {
+	struct cfi_state cfi = init_cfi;
 	struct section *sec, *relocsec;
 	struct unwind_hint *hint;
 	struct instruction *insn;
-	struct cfi_state *cfi;
 	struct reloc *reloc;
 	int i;
 
@@ -1666,9 +1666,8 @@ static int read_unwind_hints(struct objt
 			continue;
 		}
 
-		cfi = insn->cfip;
-		if (!cfi)
-			cfi = insn->cfip = cfi_alloc();
+		if (insn->cfip)
+			cfi = *(insn->cfip);
 
 		if (arch_decode_hint_reg(insn, hint->sp_reg)) {
 			WARN_FUNC("unsupported unwind_hint sp base reg %d",
@@ -1679,6 +1678,8 @@ static int read_unwind_hints(struct objt
 		cfi->cfa.offset = bswap_if_needed(hint->sp_offset);
 		cfi->type = hint->type;
 		cfi->end = hint->end;
+
+		insn->cfip = cfi_hash_find_or_add(&cfi);
 	}
 
 	return 0;
@@ -2831,7 +2832,7 @@ static int validate_branch(struct objtoo
 				insn->cfip = prev_insn->cfip;
 				nr_cfi_reused++;
 			} else {
-				insn->cfip = cfi_hash_find(&state.cfi);
+				insn->cfip = cfi_hash_find_or_add(&state.cfi);
 			}
 		}
 
@@ -3239,6 +3240,7 @@ int check(struct objtool_file *file)
 	int ret, warnings = 0;
 
 	arch_initial_func_cfi_state(&initial_func_cfi);
+	init_cfi_state(&init_cfi);
 	init_cfi_state(&func_cfi);
 	set_func_state(&func_cfi);
 
@@ -3250,6 +3252,7 @@ int check(struct objtool_file *file)
 	if (!cfi_hash_alloc(1UL << (file->elf->symbol_bits - 3)))
 		goto out;
 
+	cfi_hash_add(&init_cfi);
 	cfi_hash_add(&func_cfi);
 
 	if (list_empty(&file->insn_list))

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 02/24] objtool: Introduce CFI hash
  2021-08-20 22:27   ` Josh Poimboeuf
  2021-08-25 10:13     ` Peter Zijlstra
@ 2021-08-25 10:15     ` Peter Zijlstra
  1 sibling, 0 replies; 101+ messages in thread
From: Peter Zijlstra @ 2021-08-25 10:15 UTC (permalink / raw)
  To: Josh Poimboeuf
  Cc: tglx, linux-kernel, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver, Andi Kleen

On Fri, Aug 20, 2021 at 03:27:55PM -0700, Josh Poimboeuf wrote:

> > @@ -2725,15 +2820,24 @@ static int validate_branch(struct objtoo
> >  
> >  			if (insn->visited & visited)
> >  				return 0;
> > -		}
> > +		} else
> > +			nr_visited++;
> >  
> >  		if (state.noinstr)
> >  			state.instr += insn->instr;
> >  
> > -		if (insn->hint)
> > -			state.cfi = insn->cfi;
> > -		else
> > -			insn->cfi = state.cfi;
> > +		if (insn->hint) {
> > +			state.cfi = *insn->cfip;
> > +		} else {
> > +			/* XXX track if we actually changed state.cfi */
> 
> Why would we do that?

Saves on the memcmp()..

> > +++ b/tools/objtool/include/objtool/check.h
> > @@ -60,9 +60,11 @@ struct instruction {
> >  	struct list_head alts;
> >  	struct symbol *func;
> >  	struct list_head stack_ops;
> > -	struct cfi_state cfi;
> > +	struct cfi_state *cfip;
> 
> Not sure about this rename.  Pointers generally don't need a 'p' postfix.

It was a dev thing, meant I typically rename a member when I change
type; easy for compiler and grep.

I can s/cfip/cfi/ on the patch, no biggie.

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 03/24] objtool: Handle __sanitize_cov*() tail calls
  2021-08-20 23:17   ` Josh Poimboeuf
@ 2021-08-25 10:19     ` Peter Zijlstra
  0 siblings, 0 replies; 101+ messages in thread
From: Peter Zijlstra @ 2021-08-25 10:19 UTC (permalink / raw)
  To: Josh Poimboeuf
  Cc: tglx, linux-kernel, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver

On Fri, Aug 20, 2021 at 04:17:44PM -0700, Josh Poimboeuf wrote:
> On Thu, Jun 24, 2021 at 11:41:02AM +0200, Peter Zijlstra wrote:
> > +	if (insn->sec->noinstr &&
> > +	    !strncmp(insn->call_dest->name, "__sanitizer_cov_", 16)) {
> > +		if (reloc) {
> > +			reloc->type = R_NONE;
> > +			elf_write_reloc(file->elf, reloc);
> > +		}
> > +
> > +		elf_write_insn(file->elf, insn->sec,
> > +			       insn->offset, insn->len,
> > +			       sibling ? arch_ret_insn(insn->len)
> > +			               : arch_nop_insn(insn->len));
> > +
> > +		insn->type = sibling ? INSN_RETURN : INSN_NOP;
> > +	}
> 
> It'd be nice to keep the comment for this case that was in
> add_call_destinations().

Done!

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 06/24] x86: Always inline context_tracking_guest_enter()
  2021-08-20 23:34     ` Josh Poimboeuf
@ 2021-08-25 12:16       ` Peter Zijlstra
       [not found]         ` <YSZxtBHNJzoUbqdE@ravnborg.org>
  2021-08-25 13:38       ` Peter Zijlstra
  1 sibling, 1 reply; 101+ messages in thread
From: Peter Zijlstra @ 2021-08-25 12:16 UTC (permalink / raw)
  To: Josh Poimboeuf
  Cc: tglx, linux-kernel, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver, sam, masahiroy, hca, nickhu, vgupta

On Fri, Aug 20, 2021 at 04:34:40PM -0700, Josh Poimboeuf wrote:

> WARNING: This patch may shrink your patch set and improve your sanity.

I'll go rebuild me some kernels to see how many __always_inline things I
can drop.

Lets add a few Cc's though.

> From: Josh Poimboeuf <jpoimboe@redhat.com>
> Subject: [PATCH] kbuild: Remove CONFIG_DEBUG_SECTION_MISMATCH
> 
> Modpost's section mismatch detection warns when a non-init function
> references an __init function.  The warning is needed because __init
> memory is freed during boot, so the non-init function might end up
> calling into some random memory.
> 
> CONFIG_DEBUG_SECTION_MISMATCH is intended to root out more of these
> issues by adding the -fno-inline-functions-called-once compiler flag,
> which forces once-called static functions to not be inlined.  As
> described in the option's help description:
> 
>   - Add the option -fno-inline-functions-called-once to gcc commands.
>     When inlining a function annotated with __init in a non-init
>     function, we would lose the section information and thus
>     the analysis would not catch the illegal reference.
>     This option tells gcc to inline less (but it does result in
>     a larger kernel).
> 
> It's true that if an __init function is inlined in a non-init function,
> it's no longer __init.  But that's not actually a problem.
> 
> If an inlined __init function doesn't access any other __init functions
> or data, the inlining is harmless.
> 
> If the inlined __init function does access other __init functions/data,
> __init relocations will be generated for a non-init section, and
> modpost's section mismatch detection will discover it.
> 
> So the option isn't actually useful.  It's not even useful for finding
> issues on other configs, which might have different inlining decisions,
> because with -O2, once-called static functions are always inlined.  And
> anyway, nowadays we have build bots everywhere, which are great at
> finding such edge cases.
> 
> I get the feeling this option has been responsible for dozens of
> "convert inline to __always_inline" patches over the years.  Such
> patches usually complain about the compiler's inlining decisions being
> unpredictable.  Turns out the culprit is this
> CONFIG_DEBUG_SECTION_MISMATCH option, at least for once-called
> functions.
> 
> This option really has no benefits, and only drawbacks, causing needless
> churn.  Remove it.
> 
> Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
> ---
>  Makefile                                      |  5 -----
>  arch/arc/configs/tb10x_defconfig              |  1 -
>  arch/nds32/configs/defconfig                  |  1 -
>  arch/s390/configs/debug_defconfig             |  1 -
>  arch/s390/configs/defconfig                   |  1 -
>  lib/Kconfig.debug                             | 21 -------------------
>  .../selftests/wireguard/qemu/debug.config     |  1 -
>  7 files changed, 31 deletions(-)
> 
> diff --git a/Makefile b/Makefile
> index c19d1638da25..195d4f4914e3 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -913,11 +913,6 @@ KBUILD_CFLAGS	+= $(CC_FLAGS_FTRACE) $(CC_FLAGS_USING)
>  KBUILD_AFLAGS	+= $(CC_FLAGS_USING)
>  endif
>  
> -# We trigger additional mismatches with less inlining
> -ifdef CONFIG_DEBUG_SECTION_MISMATCH
> -KBUILD_CFLAGS += $(call cc-option, -fno-inline-functions-called-once)
> -endif
> -
>  ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION
>  KBUILD_CFLAGS_KERNEL += -ffunction-sections -fdata-sections
>  LDFLAGS_vmlinux += --gc-sections
> diff --git a/arch/arc/configs/tb10x_defconfig b/arch/arc/configs/tb10x_defconfig
> index a12656ec0072..5acf8cc3e7b0 100644
> --- a/arch/arc/configs/tb10x_defconfig
> +++ b/arch/arc/configs/tb10x_defconfig
> @@ -96,7 +96,6 @@ CONFIG_STRIP_ASM_SYMS=y
>  CONFIG_DEBUG_FS=y
>  CONFIG_HEADERS_INSTALL=y
>  CONFIG_HEADERS_CHECK=y
> -CONFIG_DEBUG_SECTION_MISMATCH=y
>  CONFIG_MAGIC_SYSRQ=y
>  CONFIG_DEBUG_MEMORY_INIT=y
>  CONFIG_DEBUG_STACKOVERFLOW=y
> diff --git a/arch/nds32/configs/defconfig b/arch/nds32/configs/defconfig
> index f9a89cf00aa6..61b5b83bd20e 100644
> --- a/arch/nds32/configs/defconfig
> +++ b/arch/nds32/configs/defconfig
> @@ -93,7 +93,6 @@ CONFIG_GDB_SCRIPTS=y
>  CONFIG_READABLE_ASM=y
>  CONFIG_HEADERS_INSTALL=y
>  CONFIG_HEADERS_CHECK=y
> -CONFIG_DEBUG_SECTION_MISMATCH=y
>  CONFIG_MAGIC_SYSRQ=y
>  CONFIG_DEBUG_KERNEL=y
>  CONFIG_PANIC_ON_OOPS=y
> diff --git a/arch/s390/configs/debug_defconfig b/arch/s390/configs/debug_defconfig
> index b88184019af9..68104f82cc9d 100644
> --- a/arch/s390/configs/debug_defconfig
> +++ b/arch/s390/configs/debug_defconfig
> @@ -782,7 +782,6 @@ CONFIG_DEBUG_INFO=y
>  CONFIG_DEBUG_INFO_DWARF4=y
>  CONFIG_GDB_SCRIPTS=y
>  CONFIG_HEADERS_INSTALL=y
> -CONFIG_DEBUG_SECTION_MISMATCH=y
>  CONFIG_MAGIC_SYSRQ=y
>  CONFIG_DEBUG_PAGEALLOC=y
>  CONFIG_PAGE_OWNER=y
> diff --git a/arch/s390/configs/defconfig b/arch/s390/configs/defconfig
> index 1667a3cdcf0a..a5e7eb0276c6 100644
> --- a/arch/s390/configs/defconfig
> +++ b/arch/s390/configs/defconfig
> @@ -767,7 +767,6 @@ CONFIG_DYNAMIC_DEBUG=y
>  CONFIG_DEBUG_INFO=y
>  CONFIG_DEBUG_INFO_DWARF4=y
>  CONFIG_GDB_SCRIPTS=y
> -CONFIG_DEBUG_SECTION_MISMATCH=y
>  CONFIG_MAGIC_SYSRQ=y
>  CONFIG_DEBUG_WX=y
>  CONFIG_PTDUMP_DEBUGFS=y
> diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
> index e5cdf98f50c2..93f9c00783b2 100644
> --- a/lib/Kconfig.debug
> +++ b/lib/Kconfig.debug
> @@ -381,27 +381,6 @@ config HEADERS_INSTALL
>  	  user-space program samples. It is also needed by some features such
>  	  as uapi header sanity checks.
>  
> -config DEBUG_SECTION_MISMATCH
> -	bool "Enable full Section mismatch analysis"
> -	help
> -	  The section mismatch analysis checks if there are illegal
> -	  references from one section to another section.
> -	  During linktime or runtime, some sections are dropped;
> -	  any use of code/data previously in these sections would
> -	  most likely result in an oops.
> -	  In the code, functions and variables are annotated with
> -	  __init,, etc. (see the full list in include/linux/init.h),
> -	  which results in the code/data being placed in specific sections.
> -	  The section mismatch analysis is always performed after a full
> -	  kernel build, and enabling this option causes the following
> -	  additional step to occur:
> -	  - Add the option -fno-inline-functions-called-once to gcc commands.
> -	    When inlining a function annotated with __init in a non-init
> -	    function, we would lose the section information and thus
> -	    the analysis would not catch the illegal reference.
> -	    This option tells gcc to inline less (but it does result in
> -	    a larger kernel).
> -
>  config SECTION_MISMATCH_WARN_ONLY
>  	bool "Make section mismatch errors non-fatal"
>  	default y
> diff --git a/tools/testing/selftests/wireguard/qemu/debug.config b/tools/testing/selftests/wireguard/qemu/debug.config
> index fe07d97df9fa..83588bb08fde 100644
> --- a/tools/testing/selftests/wireguard/qemu/debug.config
> +++ b/tools/testing/selftests/wireguard/qemu/debug.config
> @@ -57,7 +57,6 @@ CONFIG_USER_STACKTRACE_SUPPORT=y
>  CONFIG_DEBUG_SG=y
>  CONFIG_DEBUG_NOTIFIERS=y
>  CONFIG_X86_DEBUG_FPU=y
> -CONFIG_DEBUG_SECTION_MISMATCH=y
>  CONFIG_DEBUG_PAGEALLOC=y
>  CONFIG_DEBUG_PAGEALLOC_ENABLE_DEFAULT=y
>  CONFIG_DEBUG_WW_MUTEX_SLOWPATH=y
> -- 
> 2.31.1
> 

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 02/24] objtool: Introduce CFI hash
  2021-08-25 10:13     ` Peter Zijlstra
@ 2021-08-25 12:49       ` Peter Zijlstra
  0 siblings, 0 replies; 101+ messages in thread
From: Peter Zijlstra @ 2021-08-25 12:49 UTC (permalink / raw)
  To: Josh Poimboeuf
  Cc: tglx, linux-kernel, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver, Andi Kleen

On Wed, Aug 25, 2021 at 12:13:43PM +0200, Peter Zijlstra wrote:
> On Fri, Aug 20, 2021 at 03:27:55PM -0700, Josh Poimboeuf wrote:
> > > +static struct cfi_state *cfi_alloc(void)
> > > +{
> > > +	struct cfi_state *cfi = calloc(sizeof(struct cfi_state), 1);
> > > +	if (!cfi) {
> > > +		WARN("calloc failed");
> > > +		exit(1);
> > > +	}
> > > +	nr_cfi++;
> > > +	init_cfi_state(cfi);
> > > +	return cfi;
> > > +}
> > 
> > I'm thinking this should also add it to the hash.  i.e. I don't think
> > there's a scenario where you'd alloc a cfi and not want to add it to the
> > hash.  The more sharing the better.
> 

> @@ -1666,9 +1666,8 @@ static int read_unwind_hints(struct objt
>  			continue;
>  		}
>  
> -		cfi = insn->cfip;
> -		if (!cfi)
> -			cfi = insn->cfip = cfi_alloc();

Urgh, the problem is that this runs before we allocate the hash-table!
Lemme try and re-order thing.

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 06/24] x86: Always inline context_tracking_guest_enter()
  2021-08-20 23:34     ` Josh Poimboeuf
  2021-08-25 12:16       ` Peter Zijlstra
@ 2021-08-25 13:38       ` Peter Zijlstra
  1 sibling, 0 replies; 101+ messages in thread
From: Peter Zijlstra @ 2021-08-25 13:38 UTC (permalink / raw)
  To: Josh Poimboeuf
  Cc: tglx, linux-kernel, joro, boris.ostrovsky, jgross, x86, mbenes,
	rostedt, dvyukov, elver

On Fri, Aug 20, 2021 at 04:34:40PM -0700, Josh Poimboeuf wrote:
> On Fri, Aug 20, 2021 at 04:22:07PM -0700, Josh Poimboeuf wrote:
> > On Thu, Jun 24, 2021 at 11:41:05AM +0200, Peter Zijlstra wrote:
> > > Yes, it really did out-of-line this....
> > > 
> > > vmlinux.o: warning: objtool: vmx_vcpu_enter_exit()+0x31: call to context_tracking_guest_enter() leaves .noinstr.text section
> > > 
> > > 000000000019f660 <context_tracking_guest_enter>:
> > >   19f660:	e8 00 00 00 00       	callq  19f665 <context_tracking_guest_enter+0x5>	19f661: R_X86_64_PLT32	__sanitizer_cov_trace_pc-0x4
> > >   19f665:	31 c0                	xor    %eax,%eax
> > >   19f667:	c3                   	retq   
> > > 
> > > Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
> > 
> > Ha.  I'm guessing this was from CONFIG_DEBUG_SECTION_MISMATCH, which is
> > only good for triggering a lot of these useless __always_inline patches.
> > 
> > I have a patch somewhere to get rid of it.
> 
> Found it.

Even with your patch applied, x86_64-allyesconfig still gives me the
above. In fact, I had to re-instate 4 of the 6 __always_inline patches,
so I've kept them all for now.

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 06/24] x86: Always inline context_tracking_guest_enter()
       [not found]         ` <YSZxtBHNJzoUbqdE@ravnborg.org>
@ 2021-08-26  4:10           ` Josh Poimboeuf
  0 siblings, 0 replies; 101+ messages in thread
From: Josh Poimboeuf @ 2021-08-26  4:10 UTC (permalink / raw)
  To: Sam Ravnborg
  Cc: Peter Zijlstra, tglx, linux-kernel, joro, boris.ostrovsky,
	jgross, x86, mbenes, rostedt, dvyukov, elver, masahiroy, hca,
	nickhu, vgupta

On Wed, Aug 25, 2021 at 06:37:08PM +0200, Sam Ravnborg wrote:
> Hi Josh,
> 
> On Wed, Aug 25, 2021 at 02:16:01PM +0200, Peter Zijlstra wrote:
> > On Fri, Aug 20, 2021 at 04:34:40PM -0700, Josh Poimboeuf wrote:
> > 
> > > WARNING: This patch may shrink your patch set and improve your sanity.
> > 
> > I'll go rebuild me some kernels to see how many __always_inline things I
> > can drop.
> > 
> > Lets add a few Cc's though.
> > 
> > > From: Josh Poimboeuf <jpoimboe@redhat.com>
> > > Subject: [PATCH] kbuild: Remove CONFIG_DEBUG_SECTION_MISMATCH
> > > 
> > > So the option isn't actually useful.  It's not even useful for finding
> > > issues on other configs, which might have different inlining decisions,
> > > because with -O2, once-called static functions are always inlined.
> We have following -O possibilities:
> 
>     ifdef CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE
>     KBUILD_CFLAGS += -O2
>     else ifdef CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE_O3
>     KBUILD_CFLAGS += -O3
>     else ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
>     KBUILD_CFLAGS += -Os
>     endif
> 
> We always built with -Os or -O2 (and ARC supports -O3).
> Do we know that gcc and clang will always inline once-called functions
> with -O2 and -Os for the relevant architectures?

Hm, I should have read the GCC manual a little closer:

  -finline-functions-called-once
      Consider all "static" functions called once for inlining into their
      caller even if they are not marked "inline".

So it's not necessarily a guarantee that once-called functions will
always be inlined.  Looking at GCC code, there at least some theoretical
edge cases involving optimization mismatches between caller and callee,
though as a rule the kernel avoids function-specific optimizations.

Still, I think the patch is a net benefit.  I'll update the patch
description and post it again separately since Peter doesn't seem to
need it here.

> If you can answer yes to this with some confidence then you can add my:
> Acked-by: Sam Ravnborg <sam@ravnborg.org>
> 
> Note: I added this option long time ago and is unhappy if this only
> have resulted in useless code changes.

It might have been useful in the days before we had all the automated
build bots doing randconfigs.  Nowadays any __init mismatch issues which
would only be seen in obscure config/compiler combinations will be
rooted out by the bots reporting modpost section mismatch warnings.
 
-- 
Josh


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 01/24] x86/xen: Mark cpu_bringup_and_idle() as dead_end_function
  2021-08-23  8:40       ` Juergen Gross
@ 2021-08-30  5:55         ` Juergen Gross
  2021-08-30  7:48           ` Peter Zijlstra
  0 siblings, 1 reply; 101+ messages in thread
From: Juergen Gross @ 2021-08-30  5:55 UTC (permalink / raw)
  To: Josh Poimboeuf, Peter Zijlstra
  Cc: tglx, linux-kernel, joro, boris.ostrovsky, x86, mbenes, rostedt,
	dvyukov, elver


[-- Attachment #1.1.1: Type: text/plain, Size: 5462 bytes --]

On 23.08.21 10:40, Juergen Gross wrote:
> On 20.08.21 21:31, Josh Poimboeuf wrote:
>> On Fri, Aug 20, 2021 at 12:22:28PM -0700, Josh Poimboeuf wrote:
>>> On Thu, Jun 24, 2021 at 11:41:00AM +0200, Peter Zijlstra wrote:
>>>> The asm_cpu_bringup_and_idle() function is required to push the return
>>>> value on the stack in order to make ORC happy, but the only reason
>>>> objtool doesn't complain is because of a happy accident.
>>>>
>>>> The thing is that asm_cpu_bringup_and_idle() doesn't return, so
>>>> validate_branch() never terminates and falls through to the next
>>>> function, which in the normal case is the hypercall_page. And that, as
>>>> it happens, is 4095 NOPs and a RET.
>>>>
>>>> Make asm_cpu_bringup_and_idle() terminate on it's own, by making the
>>>> function it calls as a dead-end. This way we no longer rely on what
>>>> code happens to come after.
>>>>
>>>> Fixes: c3881eb58d56 ("x86/xen: Make the secondary CPU idle tasks 
>>>> reliable")
>>>> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
>>>
>>> Looks right.  Only problem is, with my assembler I get this:
>>>
>>>    arch/x86/kernel/head_64.o: warning: objtool: .text+0x5: 
>>> unreachable instruction
>>>
>>> Because gas insists on jumping over the page of nops...
>>>
>>> 0000000000000000 <asm_cpu_bringup_and_idle>:
>>>         0:    e8 00 00 00 00           callq  5 
>>> <asm_cpu_bringup_and_idle+0x5>
>>>             1: R_X86_64_PLT32    cpu_bringup_and_idle-0x4
>>>         5:    e9 f6 0f 00 00           jmpq   1000 
>>> <xen_hypercall_set_trap_table>
>>>         a:    66 66 2e 0f 1f 84 00     data16 nopw %cs:0x0(%rax,%rax,1)
>>>        11:    00 00 00 00
>>>        15:    66 66 2e 0f 1f 84 00     data16 nopw %cs:0x0(%rax,%rax,1)
>>>        1c:    00 00 00 00
>>>        20:    66 66 2e 0f 1f 84 00     data16 nopw %cs:0x0(%rax,%rax,1)
>>>        27:    00 00 00 00
>>>        2b:    66 66 2e 0f 1f 84 00     data16 nopw %cs:0x0(%rax,%rax,1)
>>>        32:    00 00 00 00
>>>        36:    66 66 2e 0f 1f 84 00     data16 nopw %cs:0x0(%rax,%rax,1)
>>>        3d:    00 00 00 00
>>
>> Here's a fix:
>>
>> From: Josh Poimboeuf <jpoimboe@redhat.com>
>> Subject: [PATCH] x86/xen: Move hypercall_page to top of the file
>>
>> Because hypercall_page is page-aligned, the assembler inexplicably adds
>> an unreachable jump from after the end of the previous code to the
>> beginning of hypercall_page.
>>
>> That confuses objtool, understandably.  It also creates significant text
>> fragmentation.  As a result, much of the object file is wasted text
>> (nops).
>>
>> Move hypercall_page to the beginning of the file to both prevent the
>> text fragmentation and avoid the dead jump instruction.
>>
>> $ size /tmp/head_64.before.o /tmp/head_64.after.o
>>     text       data        bss        dec        hex    filename
>>    10924     307252       4096     322272      4eae0    
>> /tmp/head_64.before.o
>>     6823     307252       4096     318171      4dadb    
>> /tmp/head_64.after.o
>>
>> Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com
> 
> Reviewed-by: Juergen Gross <jgross@suse.com>

Umm, will this be carried through the tip tree, or shall I take it in
the xen tree?


Juergen

> 
> 
> Juergen
> 
>> ---
>>   arch/x86/xen/xen-head.S | 34 +++++++++++++++++-----------------
>>   1 file changed, 17 insertions(+), 17 deletions(-)
>>
>> diff --git a/arch/x86/xen/xen-head.S b/arch/x86/xen/xen-head.S
>> index cb6538ae2fe0..488944d6d430 100644
>> --- a/arch/x86/xen/xen-head.S
>> +++ b/arch/x86/xen/xen-head.S
>> @@ -20,6 +20,23 @@
>>   #include <xen/interface/xen-mca.h>
>>   #include <asm/xen/interface.h>
>> +.pushsection .text
>> +    .balign PAGE_SIZE
>> +SYM_CODE_START(hypercall_page)
>> +    .rept (PAGE_SIZE / 32)
>> +        UNWIND_HINT_FUNC
>> +        .skip 31, 0x90
>> +        ret
>> +    .endr
>> +
>> +#define HYPERCALL(n) \
>> +    .equ xen_hypercall_##n, hypercall_page + __HYPERVISOR_##n * 32; \
>> +    .type xen_hypercall_##n, @function; .size xen_hypercall_##n, 32
>> +#include <asm/xen-hypercalls.h>
>> +#undef HYPERCALL
>> +SYM_CODE_END(hypercall_page)
>> +.popsection
>> +
>>   #ifdef CONFIG_XEN_PV
>>       __INIT
>>   SYM_CODE_START(startup_xen)
>> @@ -64,23 +81,6 @@ SYM_CODE_END(asm_cpu_bringup_and_idle)
>>   #endif
>>   #endif
>> -.pushsection .text
>> -    .balign PAGE_SIZE
>> -SYM_CODE_START(hypercall_page)
>> -    .rept (PAGE_SIZE / 32)
>> -        UNWIND_HINT_FUNC
>> -        .skip 31, 0x90
>> -        ret
>> -    .endr
>> -
>> -#define HYPERCALL(n) \
>> -    .equ xen_hypercall_##n, hypercall_page + __HYPERVISOR_##n * 32; \
>> -    .type xen_hypercall_##n, @function; .size xen_hypercall_##n, 32
>> -#include <asm/xen-hypercalls.h>
>> -#undef HYPERCALL
>> -SYM_CODE_END(hypercall_page)
>> -.popsection
>> -
>>       ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS,       .asciz "linux")
>>       ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION,  .asciz "2.6")
>>       ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION,    .asciz "xen-3.0")
>>
> 


[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3135 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 01/24] x86/xen: Mark cpu_bringup_and_idle() as dead_end_function
  2021-08-30  5:55         ` Juergen Gross
@ 2021-08-30  7:48           ` Peter Zijlstra
  2021-08-30  7:56             ` Juergen Gross
  0 siblings, 1 reply; 101+ messages in thread
From: Peter Zijlstra @ 2021-08-30  7:48 UTC (permalink / raw)
  To: Juergen Gross
  Cc: Josh Poimboeuf, tglx, linux-kernel, joro, boris.ostrovsky, x86,
	mbenes, rostedt, dvyukov, elver

On Mon, Aug 30, 2021 at 07:55:02AM +0200, Juergen Gross wrote:
> > > From: Josh Poimboeuf <jpoimboe@redhat.com>
> > > Subject: [PATCH] x86/xen: Move hypercall_page to top of the file
> > > 
> > > Because hypercall_page is page-aligned, the assembler inexplicably adds
> > > an unreachable jump from after the end of the previous code to the
> > > beginning of hypercall_page.
> > > 
> > > That confuses objtool, understandably.  It also creates significant text
> > > fragmentation.  As a result, much of the object file is wasted text
> > > (nops).
> > > 
> > > Move hypercall_page to the beginning of the file to both prevent the
> > > text fragmentation and avoid the dead jump instruction.
> > > 
> > > $ size /tmp/head_64.before.o /tmp/head_64.after.o
> > >     text       data        bss        dec        hex    filename
> > >    10924     307252       4096     322272      4eae0
> > > /tmp/head_64.before.o
> > >     6823     307252       4096     318171      4dadb
> > > /tmp/head_64.after.o
> > > 
> > > Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com
> > 
> > Reviewed-by: Juergen Gross <jgross@suse.com>
> 
> Umm, will this be carried through the tip tree, or shall I take it in
> the xen tree?

I have it in the whole x86/objtool/paravirt series. I you want it in the
Xen tree, I'll be happy to drop it from there, although I hope to get
all that merged this cycles somewhere.

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH v2 01/24] x86/xen: Mark cpu_bringup_and_idle() as dead_end_function
  2021-08-30  7:48           ` Peter Zijlstra
@ 2021-08-30  7:56             ` Juergen Gross
  0 siblings, 0 replies; 101+ messages in thread
From: Juergen Gross @ 2021-08-30  7:56 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Josh Poimboeuf, tglx, linux-kernel, joro, boris.ostrovsky, x86,
	mbenes, rostedt, dvyukov, elver


[-- Attachment #1.1.1: Type: text/plain, Size: 1605 bytes --]

On 30.08.21 09:48, Peter Zijlstra wrote:
> On Mon, Aug 30, 2021 at 07:55:02AM +0200, Juergen Gross wrote:
>>>> From: Josh Poimboeuf <jpoimboe@redhat.com>
>>>> Subject: [PATCH] x86/xen: Move hypercall_page to top of the file
>>>>
>>>> Because hypercall_page is page-aligned, the assembler inexplicably adds
>>>> an unreachable jump from after the end of the previous code to the
>>>> beginning of hypercall_page.
>>>>
>>>> That confuses objtool, understandably.  It also creates significant text
>>>> fragmentation.  As a result, much of the object file is wasted text
>>>> (nops).
>>>>
>>>> Move hypercall_page to the beginning of the file to both prevent the
>>>> text fragmentation and avoid the dead jump instruction.
>>>>
>>>> $ size /tmp/head_64.before.o /tmp/head_64.after.o
>>>>      text       data        bss        dec        hex    filename
>>>>     10924     307252       4096     322272      4eae0
>>>> /tmp/head_64.before.o
>>>>      6823     307252       4096     318171      4dadb
>>>> /tmp/head_64.after.o
>>>>
>>>> Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com
>>>
>>> Reviewed-by: Juergen Gross <jgross@suse.com>
>>
>> Umm, will this be carried through the tip tree, or shall I take it in
>> the xen tree?
> 
> I have it in the whole x86/objtool/paravirt series. I you want it in the
> Xen tree, I'll be happy to drop it from there, although I hope to get
> all that merged this cycles somewhere.
> 

Okay, I think it is better kept in your series then.


Juergen

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3135 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] objtool: Support pv_opsindirect calls for noinstr
  2021-06-24  9:41 ` [PATCH v2 24/24] objtool: Support pv_opsindirect calls for noinstr Peter Zijlstra
@ 2021-09-15 15:49   ` tip-bot2 for Peter Zijlstra
  2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
  1 sibling, 0 replies; 101+ messages in thread
From: tip-bot2 for Peter Zijlstra @ 2021-09-15 15:49 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: Peter Zijlstra (Intel), x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     55a918e61cf45f28157a2f0bb2535fa79e4a137d
Gitweb:        https://git.kernel.org/tip/55a918e61cf45f28157a2f0bb2535fa79e4a137d
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Thu, 24 Jun 2021 11:41:23 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Wed, 15 Sep 2021 15:51:51 +02:00

objtool: Support pv_opsindirect calls for noinstr

Normally objtool will now follow indirect calls; there is no need.

However, this becomes a problem with noinstr validation; if there's an
indirect call from noinstr code, we very much need to know it is to
another noinstr function. Luckily there aren't many indirect calls in
entry code with the obvious exception of paravirt. As such, noinstr
validation didn't work with paravirt kernels.

In order to track pv_ops[] call targets, objtool reads the static
pv_ops[] tables as well as direct assignments to the pv_ops[] array,
provided the compiler makes them a single instruction like:

  bf87:       48 c7 05 00 00 00 00 00 00 00 00        movq   $0x0,0x0(%rip)
    bf92 <xen_init_spinlocks+0x5f>
    bf8a: R_X86_64_PC32     pv_ops+0x268

There are, as of yet, no warnings for when this goes wrong :/

Using the functions found with the above means, all pv_ops[] calls are
now subject to noinstr validation.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/r/20210624095149.118815755@infradead.org
---
 lib/Kconfig.debug                       |   2 +-
 tools/objtool/arch/x86/decode.c         |  34 ++++-
 tools/objtool/check.c                   | 151 +++++++++++++++++++++--
 tools/objtool/include/objtool/arch.h    |   2 +-
 tools/objtool/include/objtool/elf.h     |   1 +-
 tools/objtool/include/objtool/objtool.h |   9 +-
 tools/objtool/objtool.c                 |  22 +++-
 7 files changed, 208 insertions(+), 13 deletions(-)

diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index ed4a31e..63a4735 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -458,7 +458,7 @@ config STACK_VALIDATION
 
 config VMLINUX_VALIDATION
 	bool
-	depends on STACK_VALIDATION && DEBUG_ENTRY && !PARAVIRT
+	depends on STACK_VALIDATION && DEBUG_ENTRY
 	default y
 
 config VMLINUX_MAP
diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c
index 340a3dc..3172983 100644
--- a/tools/objtool/arch/x86/decode.c
+++ b/tools/objtool/arch/x86/decode.c
@@ -20,6 +20,7 @@
 #include <objtool/arch.h>
 #include <objtool/warn.h>
 #include <objtool/endianness.h>
+#include <objtool/builtin.h>
 #include <arch/elf.h>
 
 static int is_x86_64(const struct elf *elf)
@@ -102,12 +103,13 @@ unsigned long arch_jump_destination(struct instruction *insn)
 #define rm_is_mem(reg)	(mod_is_mem() && !is_RIP() && rm_is(reg))
 #define rm_is_reg(reg)	(mod_is_reg() && modrm_rm == (reg))
 
-int arch_decode_instruction(const struct elf *elf, const struct section *sec,
+int arch_decode_instruction(struct objtool_file *file, const struct section *sec,
 			    unsigned long offset, unsigned int maxlen,
 			    unsigned int *len, enum insn_type *type,
 			    unsigned long *immediate,
 			    struct list_head *ops_list)
 {
+	const struct elf *elf = file->elf;
 	struct insn insn;
 	int x86_64, ret;
 	unsigned char op1, op2,
@@ -544,6 +546,36 @@ int arch_decode_instruction(const struct elf *elf, const struct section *sec,
 		*type = INSN_RETURN;
 		break;
 
+	case 0xc7: /* mov imm, r/m */
+		if (!noinstr)
+			break;
+
+		if (insn.length == 3+4+4 && !strncmp(sec->name, ".init.text", 10)) {
+			struct reloc *immr, *disp;
+			struct symbol *func;
+			int idx;
+
+			immr = find_reloc_by_dest(elf, (void *)sec, offset+3);
+			disp = find_reloc_by_dest(elf, (void *)sec, offset+7);
+
+			if (!immr || strcmp(immr->sym->name, "pv_ops"))
+				break;
+
+			idx = (immr->addend + 8) / sizeof(void *);
+
+			func = disp->sym;
+			if (disp->sym->type == STT_SECTION)
+				func = find_symbol_by_offset(disp->sym->sec, disp->addend);
+			if (!func) {
+				WARN("no func for pv_ops[]");
+				return -1;
+			}
+
+			objtool_pv_add(file, idx, func);
+		}
+
+		break;
+
 	case 0xcf: /* iret */
 		/*
 		 * Handle sync_core(), which has an IRET to self.
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index c6f206f..84e59a9 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -382,7 +382,7 @@ static int decode_instructions(struct objtool_file *file)
 			insn->sec = sec;
 			insn->offset = offset;
 
-			ret = arch_decode_instruction(file->elf, sec, offset,
+			ret = arch_decode_instruction(file, sec, offset,
 						      sec->len - offset,
 						      &insn->len, &insn->type,
 						      &insn->immediate,
@@ -420,6 +420,82 @@ err:
 	return ret;
 }
 
+/*
+ * Read the pv_ops[] .data table to find the static initialized values.
+ */
+static int add_pv_ops(struct objtool_file *file, const char *symname)
+{
+	struct symbol *sym, *func;
+	unsigned long off, end;
+	struct reloc *rel;
+	int idx;
+
+	sym = find_symbol_by_name(file->elf, symname);
+	if (!sym)
+		return 0;
+
+	off = sym->offset;
+	end = off + sym->len;
+	for (;;) {
+		rel = find_reloc_by_dest_range(file->elf, sym->sec, off, end - off);
+		if (!rel)
+			break;
+
+		func = rel->sym;
+		if (func->type == STT_SECTION)
+			func = find_symbol_by_offset(rel->sym->sec, rel->addend);
+
+		idx = (rel->offset - sym->offset) / sizeof(unsigned long);
+
+		objtool_pv_add(file, idx, func);
+
+		off = rel->offset + 1;
+		if (off > end)
+			break;
+	}
+
+	return 0;
+}
+
+/*
+ * Allocate and initialize file->pv_ops[].
+ */
+static int init_pv_ops(struct objtool_file *file)
+{
+	static const char *pv_ops_tables[] = {
+		"pv_ops",
+		"xen_cpu_ops",
+		"xen_irq_ops",
+		"xen_mmu_ops",
+		NULL,
+	};
+	const char *pv_ops;
+	struct symbol *sym;
+	int idx, nr;
+
+	if (!noinstr)
+		return 0;
+
+	file->pv_ops = NULL;
+
+	sym = find_symbol_by_name(file->elf, "pv_ops");
+	if (!sym)
+		return 0;
+
+	nr = sym->len / sizeof(unsigned long);
+	file->pv_ops = calloc(sizeof(struct pv_state), nr);
+	if (!file->pv_ops)
+		return -1;
+
+	for (idx = 0; idx < nr; idx++)
+		INIT_LIST_HEAD(&file->pv_ops[idx].targets);
+
+	for (idx = 0; (pv_ops = pv_ops_tables[idx]); idx++)
+		add_pv_ops(file, pv_ops);
+
+	return 0;
+}
+
 static struct instruction *find_last_insn(struct objtool_file *file,
 					  struct section *sec)
 {
@@ -893,6 +969,9 @@ static struct reloc *insn_reloc(struct objtool_file *file, struct instruction *i
 		return NULL;
 
 	if (!insn->reloc) {
+		if (!file)
+			return NULL;
+
 		insn->reloc = find_reloc_by_dest_range(file->elf, insn->sec,
 						       insn->offset, insn->len);
 		if (!insn->reloc) {
@@ -1882,6 +1961,10 @@ static int decode_sections(struct objtool_file *file)
 
 	mark_rodata(file);
 
+	ret = init_pv_ops(file);
+	if (ret)
+		return ret;
+
 	ret = decode_instructions(file);
 	if (ret)
 		return ret;
@@ -2663,20 +2746,64 @@ static inline bool func_uaccess_safe(struct symbol *func)
 
 static inline const char *call_dest_name(struct instruction *insn)
 {
+	static char pvname[16];
+	struct reloc *rel;
+	int idx;
+
 	if (insn->call_dest)
 		return insn->call_dest->name;
 
+	rel = insn_reloc(NULL, insn);
+	if (rel && !strcmp(rel->sym->name, "pv_ops")) {
+		idx = (rel->addend / sizeof(void *));
+		snprintf(pvname, sizeof(pvname), "pv_ops[%d]", idx);
+		return pvname;
+	}
+
 	return "{dynamic}";
 }
 
-static inline bool noinstr_call_dest(struct symbol *func)
+static bool pv_call_dest(struct objtool_file *file, struct instruction *insn)
+{
+	struct symbol *target;
+	struct reloc *rel;
+	int idx;
+
+	rel = insn_reloc(file, insn);
+	if (!rel || strcmp(rel->sym->name, "pv_ops"))
+		return false;
+
+	idx = (arch_dest_reloc_offset(rel->addend) / sizeof(void *));
+
+	if (file->pv_ops[idx].clean)
+		return true;
+
+	file->pv_ops[idx].clean = true;
+
+	list_for_each_entry(target, &file->pv_ops[idx].targets, pv_target) {
+		if (!target->sec->noinstr) {
+			WARN("pv_ops[%d]: %s", idx, target->name);
+			file->pv_ops[idx].clean = false;
+		}
+	}
+
+	return file->pv_ops[idx].clean;
+}
+
+static inline bool noinstr_call_dest(struct objtool_file *file,
+				     struct instruction *insn,
+				     struct symbol *func)
 {
 	/*
 	 * We can't deal with indirect function calls at present;
 	 * assume they're instrumented.
 	 */
-	if (!func)
+	if (!func) {
+		if (file->pv_ops)
+			return pv_call_dest(file, insn);
+
 		return false;
+	}
 
 	/*
 	 * If the symbol is from a noinstr section; we good.
@@ -2695,10 +2822,12 @@ static inline bool noinstr_call_dest(struct symbol *func)
 	return false;
 }
 
-static int validate_call(struct instruction *insn, struct insn_state *state)
+static int validate_call(struct objtool_file *file,
+			 struct instruction *insn,
+			 struct insn_state *state)
 {
 	if (state->noinstr && state->instr <= 0 &&
-	    !noinstr_call_dest(insn->call_dest)) {
+	    !noinstr_call_dest(file, insn, insn->call_dest)) {
 		WARN_FUNC("call to %s() leaves .noinstr.text section",
 				insn->sec, insn->offset, call_dest_name(insn));
 		return 1;
@@ -2719,7 +2848,9 @@ static int validate_call(struct instruction *insn, struct insn_state *state)
 	return 0;
 }
 
-static int validate_sibling_call(struct instruction *insn, struct insn_state *state)
+static int validate_sibling_call(struct objtool_file *file,
+				 struct instruction *insn,
+				 struct insn_state *state)
 {
 	if (has_modified_stack_frame(insn, state)) {
 		WARN_FUNC("sibling call from callable instruction with modified stack frame",
@@ -2727,7 +2858,7 @@ static int validate_sibling_call(struct instruction *insn, struct insn_state *st
 		return 1;
 	}
 
-	return validate_call(insn, state);
+	return validate_call(file, insn, state);
 }
 
 static int validate_return(struct symbol *func, struct instruction *insn, struct insn_state *state)
@@ -2880,7 +3011,7 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
 
 		case INSN_CALL:
 		case INSN_CALL_DYNAMIC:
-			ret = validate_call(insn, &state);
+			ret = validate_call(file, insn, &state);
 			if (ret)
 				return ret;
 
@@ -2899,7 +3030,7 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
 		case INSN_JUMP_CONDITIONAL:
 		case INSN_JUMP_UNCONDITIONAL:
 			if (is_sibling_call(insn)) {
-				ret = validate_sibling_call(insn, &state);
+				ret = validate_sibling_call(file, insn, &state);
 				if (ret)
 					return ret;
 
@@ -2921,7 +3052,7 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
 		case INSN_JUMP_DYNAMIC:
 		case INSN_JUMP_DYNAMIC_CONDITIONAL:
 			if (is_sibling_call(insn)) {
-				ret = validate_sibling_call(insn, &state);
+				ret = validate_sibling_call(file, insn, &state);
 				if (ret)
 					return ret;
 			}
diff --git a/tools/objtool/include/objtool/arch.h b/tools/objtool/include/objtool/arch.h
index 6f482ae..589ff58 100644
--- a/tools/objtool/include/objtool/arch.h
+++ b/tools/objtool/include/objtool/arch.h
@@ -69,7 +69,7 @@ struct instruction;
 
 void arch_initial_func_cfi_state(struct cfi_init_state *state);
 
-int arch_decode_instruction(const struct elf *elf, const struct section *sec,
+int arch_decode_instruction(struct objtool_file *file, const struct section *sec,
 			    unsigned long offset, unsigned int maxlen,
 			    unsigned int *len, enum insn_type *type,
 			    unsigned long *immediate,
diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/objtool/elf.h
index e343950..c3857fa 100644
--- a/tools/objtool/include/objtool/elf.h
+++ b/tools/objtool/include/objtool/elf.h
@@ -57,6 +57,7 @@ struct symbol {
 	struct symbol *pfunc, *cfunc, *alias;
 	bool uaccess_safe;
 	bool static_call_tramp;
+	struct list_head pv_target;
 };
 
 struct reloc {
diff --git a/tools/objtool/include/objtool/objtool.h b/tools/objtool/include/objtool/objtool.h
index 24fa836..f99fbc6 100644
--- a/tools/objtool/include/objtool/objtool.h
+++ b/tools/objtool/include/objtool/objtool.h
@@ -14,6 +14,11 @@
 
 #define __weak __attribute__((weak))
 
+struct pv_state {
+	bool clean;
+	struct list_head targets;
+};
+
 struct objtool_file {
 	struct elf *elf;
 	struct list_head insn_list;
@@ -25,10 +30,14 @@ struct objtool_file {
 
 	unsigned long jl_short, jl_long;
 	unsigned long jl_nop_short, jl_nop_long;
+
+	struct pv_state *pv_ops;
 };
 
 struct objtool_file *objtool_open_read(const char *_objname);
 
+void objtool_pv_add(struct objtool_file *file, int idx, struct symbol *func);
+
 int check(struct objtool_file *file);
 int orc_dump(const char *objname);
 int orc_create(struct objtool_file *file);
diff --git a/tools/objtool/objtool.c b/tools/objtool/objtool.c
index e21db8b..c90c708 100644
--- a/tools/objtool/objtool.c
+++ b/tools/objtool/objtool.c
@@ -135,6 +135,28 @@ struct objtool_file *objtool_open_read(const char *_objname)
 	return &file;
 }
 
+void objtool_pv_add(struct objtool_file *f, int idx, struct symbol *func)
+{
+	if (!noinstr)
+		return;
+
+	if (!f->pv_ops) {
+		WARN("paravirt confusion");
+		return;
+	}
+
+	/*
+	 * These functions will be patched into native code,
+	 * see paravirt_patch().
+	 */
+	if (!strcmp(func->name, "_paravirt_nop") ||
+	    !strcmp(func->name, "_paravirt_ident_64"))
+		return;
+
+	list_add(&func->pv_target, &f->pv_ops[idx].targets);
+	f->pv_ops[idx].clean = false;
+}
+
 static void cmd_usage(void)
 {
 	unsigned int i, longest = 0;

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] x86/xen: Rework the xen_{cpu,irq,mmu}_opsarrays
  2021-06-24  9:41 ` [PATCH v2 23/24] x86/xen: Rework the xen_{cpu,irq,mmu}_ops[] arrays Peter Zijlstra
  2021-06-24 12:12   ` Juergen Gross
@ 2021-09-15 15:49   ` tip-bot2 for Peter Zijlstra
  2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
  2 siblings, 0 replies; 101+ messages in thread
From: tip-bot2 for Peter Zijlstra @ 2021-09-15 15:49 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Peter Zijlstra (Intel), Juergen Gross, x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     723a80b05f0b118c53a69ff20384d28b84219afa
Gitweb:        https://git.kernel.org/tip/723a80b05f0b118c53a69ff20384d28b84219afa
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Thu, 24 Jun 2021 11:41:22 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Wed, 15 Sep 2021 15:51:51 +02:00

x86/xen: Rework the xen_{cpu,irq,mmu}_opsarrays

In order to allow objtool to make sense of all the various paravirt
functions, it needs to either parse whole pv_ops[] tables, or observe
individual assignments in the form:

  bf87:       48 c7 05 00 00 00 00 00 00 00 00        movq   $0x0,0x0(%rip)
    bf92 <xen_init_spinlocks+0x5f>
    bf8a: R_X86_64_PC32     pv_ops+0x268

As is, xen_cpu_ops[] is at offset +0 in pv_ops[] and could thus be
parsed as a 'normal' pv_ops[] table, however xen_irq_ops[] and
xen_mmu_ops[] are not.

Worse, both the latter two are compiled into the individual assignment
for by current GCC, but that's not something one can rely on.

Therefore, convert all three into full pv_ops[] tables. This has the
benefit of not needing to teach objtool about the offsets and
resulting in more conservative code-gen.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Juergen Gross <jgross@suse.com>
Link: https://lore.kernel.org/r/20210624095149.057262522@infradead.org
---
 arch/x86/xen/enlighten_pv.c | 66 +++++++++++++-------------
 arch/x86/xen/irq.c          | 17 ++++---
 arch/x86/xen/mmu_pv.c       | 90 ++++++++++++++++++------------------
 3 files changed, 90 insertions(+), 83 deletions(-)

diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c
index 2b1a8ba..6ed0af7 100644
--- a/arch/x86/xen/enlighten_pv.c
+++ b/arch/x86/xen/enlighten_pv.c
@@ -1050,52 +1050,54 @@ static const struct pv_info xen_info __initconst = {
 	.name = "Xen",
 };
 
-static const struct pv_cpu_ops xen_cpu_ops __initconst = {
-	.cpuid = xen_cpuid,
+static const typeof(pv_ops) xen_cpu_ops __initconst = {
+	.cpu = {
+		.cpuid = xen_cpuid,
 
-	.set_debugreg = xen_set_debugreg,
-	.get_debugreg = xen_get_debugreg,
+		.set_debugreg = xen_set_debugreg,
+		.get_debugreg = xen_get_debugreg,
 
-	.read_cr0 = xen_read_cr0,
-	.write_cr0 = xen_write_cr0,
+		.read_cr0 = xen_read_cr0,
+		.write_cr0 = xen_write_cr0,
 
-	.write_cr4 = xen_write_cr4,
+		.write_cr4 = xen_write_cr4,
 
-	.wbinvd = native_wbinvd,
+		.wbinvd = native_wbinvd,
 
-	.read_msr = xen_read_msr,
-	.write_msr = xen_write_msr,
+		.read_msr = xen_read_msr,
+		.write_msr = xen_write_msr,
 
-	.read_msr_safe = xen_read_msr_safe,
-	.write_msr_safe = xen_write_msr_safe,
+		.read_msr_safe = xen_read_msr_safe,
+		.write_msr_safe = xen_write_msr_safe,
 
-	.read_pmc = xen_read_pmc,
+		.read_pmc = xen_read_pmc,
 
-	.load_tr_desc = paravirt_nop,
-	.set_ldt = xen_set_ldt,
-	.load_gdt = xen_load_gdt,
-	.load_idt = xen_load_idt,
-	.load_tls = xen_load_tls,
-	.load_gs_index = xen_load_gs_index,
+		.load_tr_desc = paravirt_nop,
+		.set_ldt = xen_set_ldt,
+		.load_gdt = xen_load_gdt,
+		.load_idt = xen_load_idt,
+		.load_tls = xen_load_tls,
+		.load_gs_index = xen_load_gs_index,
 
-	.alloc_ldt = xen_alloc_ldt,
-	.free_ldt = xen_free_ldt,
+		.alloc_ldt = xen_alloc_ldt,
+		.free_ldt = xen_free_ldt,
 
-	.store_tr = xen_store_tr,
+		.store_tr = xen_store_tr,
 
-	.write_ldt_entry = xen_write_ldt_entry,
-	.write_gdt_entry = xen_write_gdt_entry,
-	.write_idt_entry = xen_write_idt_entry,
-	.load_sp0 = xen_load_sp0,
+		.write_ldt_entry = xen_write_ldt_entry,
+		.write_gdt_entry = xen_write_gdt_entry,
+		.write_idt_entry = xen_write_idt_entry,
+		.load_sp0 = xen_load_sp0,
 
 #ifdef CONFIG_X86_IOPL_IOPERM
-	.invalidate_io_bitmap = xen_invalidate_io_bitmap,
-	.update_io_bitmap = xen_update_io_bitmap,
+		.invalidate_io_bitmap = xen_invalidate_io_bitmap,
+		.update_io_bitmap = xen_update_io_bitmap,
 #endif
-	.io_delay = xen_io_delay,
+		.io_delay = xen_io_delay,
 
-	.start_context_switch = paravirt_start_context_switch,
-	.end_context_switch = xen_end_context_switch,
+		.start_context_switch = paravirt_start_context_switch,
+		.end_context_switch = xen_end_context_switch,
+	},
 };
 
 static void xen_restart(char *msg)
@@ -1231,7 +1233,7 @@ asmlinkage __visible void __init xen_start_kernel(void)
 
 	/* Install Xen paravirt ops */
 	pv_info = xen_info;
-	pv_ops.cpu = xen_cpu_ops;
+	pv_ops.cpu = xen_cpu_ops.cpu;
 	paravirt_iret = xen_iret;
 	xen_init_irq_ops();
 
diff --git a/arch/x86/xen/irq.c b/arch/x86/xen/irq.c
index 2f695b5..4fe387e 100644
--- a/arch/x86/xen/irq.c
+++ b/arch/x86/xen/irq.c
@@ -94,17 +94,20 @@ static void xen_halt(void)
 		xen_safe_halt();
 }
 
-static const struct pv_irq_ops xen_irq_ops __initconst = {
-	.save_fl = PV_CALLEE_SAVE(xen_save_fl),
-	.irq_disable = PV_CALLEE_SAVE(xen_irq_disable),
-	.irq_enable = PV_CALLEE_SAVE(xen_irq_enable),
+static const typeof(pv_ops) xen_irq_ops __initconst = {
+	.irq = {
 
-	.safe_halt = xen_safe_halt,
-	.halt = xen_halt,
+		.save_fl = PV_CALLEE_SAVE(xen_save_fl),
+		.irq_disable = PV_CALLEE_SAVE(xen_irq_disable),
+		.irq_enable = PV_CALLEE_SAVE(xen_irq_enable),
+
+		.safe_halt = xen_safe_halt,
+		.halt = xen_halt,
+	},
 };
 
 void __init xen_init_irq_ops(void)
 {
-	pv_ops.irq = xen_irq_ops;
+	pv_ops.irq = xen_irq_ops.irq;
 	x86_init.irqs.intr_init = xen_init_IRQ;
 }
diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c
index f3cafe5..b9a4f79 100644
--- a/arch/x86/xen/mmu_pv.c
+++ b/arch/x86/xen/mmu_pv.c
@@ -2076,67 +2076,69 @@ static void xen_leave_lazy_mmu(void)
 	preempt_enable();
 }
 
-static const struct pv_mmu_ops xen_mmu_ops __initconst = {
-	.read_cr2 = __PV_IS_CALLEE_SAVE(xen_read_cr2),
-	.write_cr2 = xen_write_cr2,
+static const typeof(pv_ops) xen_mmu_ops __initconst = {
+	.mmu = {
+		.read_cr2 = __PV_IS_CALLEE_SAVE(xen_read_cr2),
+		.write_cr2 = xen_write_cr2,
 
-	.read_cr3 = xen_read_cr3,
-	.write_cr3 = xen_write_cr3_init,
+		.read_cr3 = xen_read_cr3,
+		.write_cr3 = xen_write_cr3_init,
 
-	.flush_tlb_user = xen_flush_tlb,
-	.flush_tlb_kernel = xen_flush_tlb,
-	.flush_tlb_one_user = xen_flush_tlb_one_user,
-	.flush_tlb_multi = xen_flush_tlb_multi,
-	.tlb_remove_table = tlb_remove_table,
+		.flush_tlb_user = xen_flush_tlb,
+		.flush_tlb_kernel = xen_flush_tlb,
+		.flush_tlb_one_user = xen_flush_tlb_one_user,
+		.flush_tlb_multi = xen_flush_tlb_multi,
+		.tlb_remove_table = tlb_remove_table,
 
-	.pgd_alloc = xen_pgd_alloc,
-	.pgd_free = xen_pgd_free,
+		.pgd_alloc = xen_pgd_alloc,
+		.pgd_free = xen_pgd_free,
 
-	.alloc_pte = xen_alloc_pte_init,
-	.release_pte = xen_release_pte_init,
-	.alloc_pmd = xen_alloc_pmd_init,
-	.release_pmd = xen_release_pmd_init,
+		.alloc_pte = xen_alloc_pte_init,
+		.release_pte = xen_release_pte_init,
+		.alloc_pmd = xen_alloc_pmd_init,
+		.release_pmd = xen_release_pmd_init,
 
-	.set_pte = xen_set_pte_init,
-	.set_pmd = xen_set_pmd_hyper,
+		.set_pte = xen_set_pte_init,
+		.set_pmd = xen_set_pmd_hyper,
 
-	.ptep_modify_prot_start = xen_ptep_modify_prot_start,
-	.ptep_modify_prot_commit = xen_ptep_modify_prot_commit,
+		.ptep_modify_prot_start = xen_ptep_modify_prot_start,
+		.ptep_modify_prot_commit = xen_ptep_modify_prot_commit,
 
-	.pte_val = PV_CALLEE_SAVE(xen_pte_val),
-	.pgd_val = PV_CALLEE_SAVE(xen_pgd_val),
+		.pte_val = PV_CALLEE_SAVE(xen_pte_val),
+		.pgd_val = PV_CALLEE_SAVE(xen_pgd_val),
 
-	.make_pte = PV_CALLEE_SAVE(xen_make_pte_init),
-	.make_pgd = PV_CALLEE_SAVE(xen_make_pgd),
+		.make_pte = PV_CALLEE_SAVE(xen_make_pte_init),
+		.make_pgd = PV_CALLEE_SAVE(xen_make_pgd),
 
-	.set_pud = xen_set_pud_hyper,
+		.set_pud = xen_set_pud_hyper,
 
-	.make_pmd = PV_CALLEE_SAVE(xen_make_pmd),
-	.pmd_val = PV_CALLEE_SAVE(xen_pmd_val),
+		.make_pmd = PV_CALLEE_SAVE(xen_make_pmd),
+		.pmd_val = PV_CALLEE_SAVE(xen_pmd_val),
 
-	.pud_val = PV_CALLEE_SAVE(xen_pud_val),
-	.make_pud = PV_CALLEE_SAVE(xen_make_pud),
-	.set_p4d = xen_set_p4d_hyper,
+		.pud_val = PV_CALLEE_SAVE(xen_pud_val),
+		.make_pud = PV_CALLEE_SAVE(xen_make_pud),
+		.set_p4d = xen_set_p4d_hyper,
 
-	.alloc_pud = xen_alloc_pmd_init,
-	.release_pud = xen_release_pmd_init,
+		.alloc_pud = xen_alloc_pmd_init,
+		.release_pud = xen_release_pmd_init,
 
 #if CONFIG_PGTABLE_LEVELS >= 5
-	.p4d_val = PV_CALLEE_SAVE(xen_p4d_val),
-	.make_p4d = PV_CALLEE_SAVE(xen_make_p4d),
+		.p4d_val = PV_CALLEE_SAVE(xen_p4d_val),
+		.make_p4d = PV_CALLEE_SAVE(xen_make_p4d),
 #endif
 
-	.activate_mm = xen_activate_mm,
-	.dup_mmap = xen_dup_mmap,
-	.exit_mmap = xen_exit_mmap,
+		.activate_mm = xen_activate_mm,
+		.dup_mmap = xen_dup_mmap,
+		.exit_mmap = xen_exit_mmap,
 
-	.lazy_mode = {
-		.enter = paravirt_enter_lazy_mmu,
-		.leave = xen_leave_lazy_mmu,
-		.flush = paravirt_flush_lazy_mmu,
-	},
+		.lazy_mode = {
+			.enter = paravirt_enter_lazy_mmu,
+			.leave = xen_leave_lazy_mmu,
+			.flush = paravirt_flush_lazy_mmu,
+		},
 
-	.set_fixmap = xen_set_fixmap,
+		.set_fixmap = xen_set_fixmap,
+	},
 };
 
 void __init xen_init_mmu_ops(void)
@@ -2144,7 +2146,7 @@ void __init xen_init_mmu_ops(void)
 	x86_init.paging.pagetable_init = xen_pagetable_init;
 	x86_init.hyper.init_after_bootmem = xen_after_bootmem;
 
-	pv_ops.mmu = xen_mmu_ops;
+	pv_ops.mmu = xen_mmu_ops.mmu;
 
 	memset(dummy_mapping, 0xff, PAGE_SIZE);
 }

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] x86/xen: Mark xen_force_evtchn_callback() noinstr
  2021-06-24  9:41 ` [PATCH v2 22/24] x86/xen: Mark xen_force_evtchn_callback() noinstr Peter Zijlstra
  2021-06-24 11:11   ` Juergen Gross
@ 2021-09-15 15:49   ` tip-bot2 for Peter Zijlstra
  2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
  2 siblings, 0 replies; 101+ messages in thread
From: tip-bot2 for Peter Zijlstra @ 2021-09-15 15:49 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Peter Zijlstra (Intel), Juergen Gross, x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     41b8edc60d7232d1f3e49165fb6de20f424c4385
Gitweb:        https://git.kernel.org/tip/41b8edc60d7232d1f3e49165fb6de20f424c4385
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Thu, 24 Jun 2021 11:41:21 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Wed, 15 Sep 2021 15:51:51 +02:00

x86/xen: Mark xen_force_evtchn_callback() noinstr

vmlinux.o: warning: objtool: check_events()+0xd: call to xen_force_evtchn_callback() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Juergen Gross <jgross@suse.com>
Link: https://lore.kernel.org/r/20210624095148.996055323@infradead.org
---
 arch/x86/include/asm/xen/hypercall.h | 2 +-
 arch/x86/xen/irq.c                   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h
index 990b8aa..4a7ff8b 100644
--- a/arch/x86/include/asm/xen/hypercall.h
+++ b/arch/x86/include/asm/xen/hypercall.h
@@ -358,7 +358,7 @@ HYPERVISOR_event_channel_op(int cmd, void *arg)
 	return _hypercall2(int, event_channel_op, cmd, arg);
 }
 
-static inline int
+static __always_inline int
 HYPERVISOR_xen_version(int cmd, void *arg)
 {
 	return _hypercall2(int, xen_version, cmd, arg);
diff --git a/arch/x86/xen/irq.c b/arch/x86/xen/irq.c
index f52b60d..2f695b5 100644
--- a/arch/x86/xen/irq.c
+++ b/arch/x86/xen/irq.c
@@ -19,7 +19,7 @@
  * callback mask. We do this in a very simple manner, by making a call
  * down into Xen. The pending flag will be checked by Xen on return.
  */
-void xen_force_evtchn_callback(void)
+noinstr void xen_force_evtchn_callback(void)
 {
 	(void)HYPERVISOR_xen_version(0, NULL);
 }

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] x86/xen: Make irq_disable() noinstr
  2021-06-24  9:41 ` [PATCH v2 21/24] x86/xen: Make irq_disable() noinstr Peter Zijlstra
  2021-06-24 11:10   ` Juergen Gross
@ 2021-09-15 15:49   ` tip-bot2 for Peter Zijlstra
  2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
  2 siblings, 0 replies; 101+ messages in thread
From: tip-bot2 for Peter Zijlstra @ 2021-09-15 15:49 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Peter Zijlstra (Intel), Juergen Gross, x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     bf10b01f581231dc9d25a12dcfec272b981745dc
Gitweb:        https://git.kernel.org/tip/bf10b01f581231dc9d25a12dcfec272b981745dc
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Thu, 24 Jun 2021 11:41:20 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Wed, 15 Sep 2021 15:51:50 +02:00

x86/xen: Make irq_disable() noinstr

vmlinux.o: warning: objtool: pv_ops[31]: native_irq_disable
vmlinux.o: warning: objtool: pv_ops[31]: __raw_callee_save_xen_irq_disable
vmlinux.o: warning: objtool: pv_ops[31]: xen_irq_disable_direct
vmlinux.o: warning: objtool: lock_is_held_type()+0x5b: call to pv_ops[31]() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Juergen Gross <jgross@suse.com>
Link: https://lore.kernel.org/r/20210624095148.933869441@infradead.org
---
 arch/x86/kernel/paravirt.c | 7 ++++++-
 arch/x86/xen/irq.c         | 4 ++--
 arch/x86/xen/xen-asm.S     | 3 +--
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index a9b97a9..5a804de 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -263,6 +263,11 @@ static noinstr void pv_native_irq_enable(void)
 	native_irq_enable();
 }
 
+static noinstr void pv_native_irq_disable(void)
+{
+	native_irq_disable();
+}
+
 struct paravirt_patch_template pv_ops = {
 	/* Cpu ops. */
 	.cpu.io_delay		= native_io_delay,
@@ -306,7 +311,7 @@ struct paravirt_patch_template pv_ops = {
 
 	/* Irq ops. */
 	.irq.save_fl		= __PV_IS_CALLEE_SAVE(native_save_fl),
-	.irq.irq_disable	= __PV_IS_CALLEE_SAVE(native_irq_disable),
+	.irq.irq_disable	= __PV_IS_CALLEE_SAVE(pv_native_irq_disable),
 	.irq.irq_enable		= __PV_IS_CALLEE_SAVE(pv_native_irq_enable),
 	.irq.safe_halt		= native_safe_halt,
 	.irq.halt		= native_halt,
diff --git a/arch/x86/xen/irq.c b/arch/x86/xen/irq.c
index 7fb4cf2..f52b60d 100644
--- a/arch/x86/xen/irq.c
+++ b/arch/x86/xen/irq.c
@@ -42,7 +42,7 @@ asmlinkage __visible noinstr unsigned long xen_save_fl(void)
 }
 __PV_CALLEE_SAVE_REGS_THUNK(xen_save_fl, ".noinstr.text");
 
-asmlinkage __visible void xen_irq_disable(void)
+asmlinkage __visible noinstr void xen_irq_disable(void)
 {
 	/* There's a one instruction preempt window here.  We need to
 	   make sure we're don't switch CPUs between getting the vcpu
@@ -51,7 +51,7 @@ asmlinkage __visible void xen_irq_disable(void)
 	this_cpu_read(xen_vcpu)->evtchn_upcall_mask = 1;
 	preempt_enable_no_resched();
 }
-PV_CALLEE_SAVE_REGS_THUNK(xen_irq_disable);
+__PV_CALLEE_SAVE_REGS_THUNK(xen_irq_disable, ".noinstr.text");
 
 asmlinkage __visible noinstr void xen_irq_enable(void)
 {
diff --git a/arch/x86/xen/xen-asm.S b/arch/x86/xen/xen-asm.S
index 2225195..220dd96 100644
--- a/arch/x86/xen/xen-asm.S
+++ b/arch/x86/xen/xen-asm.S
@@ -21,6 +21,7 @@
 #include <linux/init.h>
 #include <linux/linkage.h>
 
+.pushsection .noinstr.text, "ax"
 /*
  * Disabling events is simply a matter of making the event mask
  * non-zero.
@@ -30,8 +31,6 @@ SYM_FUNC_START(xen_irq_disable_direct)
 	ret
 SYM_FUNC_END(xen_irq_disable_direct)
 
-.pushsection .noinstr.text, "ax"
-
 /*
  * Force an event check by making a hypercall, but preserve regs
  * before making the call.

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] x86/xen: Make irq_enable() noinstr
  2021-06-24  9:41 ` [PATCH v2 20/24] x86/xen: Make irq_enable() noinstr Peter Zijlstra
  2021-06-24 11:09   ` Juergen Gross
@ 2021-09-15 15:49   ` tip-bot2 for Peter Zijlstra
  2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
  2 siblings, 0 replies; 101+ messages in thread
From: tip-bot2 for Peter Zijlstra @ 2021-09-15 15:49 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Peter Zijlstra (Intel), Juergen Gross, x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     92e34bb9bdc242045b29269fc93942ee9befc521
Gitweb:        https://git.kernel.org/tip/92e34bb9bdc242045b29269fc93942ee9befc521
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Thu, 24 Jun 2021 11:41:19 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Wed, 15 Sep 2021 15:51:50 +02:00

x86/xen: Make irq_enable() noinstr

vmlinux.o: warning: objtool: pv_ops[32]: native_irq_enable
vmlinux.o: warning: objtool: pv_ops[32]: __raw_callee_save_xen_irq_enable
vmlinux.o: warning: objtool: pv_ops[32]: xen_irq_enable_direct
vmlinux.o: warning: objtool: lock_is_held_type()+0xfe: call to pv_ops[32]() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Juergen Gross <jgross@suse.com>
Link: https://lore.kernel.org/r/20210624095148.872254932@infradead.org
---
 arch/x86/kernel/paravirt.c |  7 ++++-
 arch/x86/xen/irq.c         |  4 +--
 arch/x86/xen/xen-asm.S     | 56 ++++++++++++++++++-------------------
 3 files changed, 36 insertions(+), 31 deletions(-)

diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index 4d98791..a9b97a9 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -258,6 +258,11 @@ static noinstr void pv_native_set_debugreg(int regno, unsigned long val)
 	native_set_debugreg(regno, val);
 }
 
+static noinstr void pv_native_irq_enable(void)
+{
+	native_irq_enable();
+}
+
 struct paravirt_patch_template pv_ops = {
 	/* Cpu ops. */
 	.cpu.io_delay		= native_io_delay,
@@ -302,7 +307,7 @@ struct paravirt_patch_template pv_ops = {
 	/* Irq ops. */
 	.irq.save_fl		= __PV_IS_CALLEE_SAVE(native_save_fl),
 	.irq.irq_disable	= __PV_IS_CALLEE_SAVE(native_irq_disable),
-	.irq.irq_enable		= __PV_IS_CALLEE_SAVE(native_irq_enable),
+	.irq.irq_enable		= __PV_IS_CALLEE_SAVE(pv_native_irq_enable),
 	.irq.safe_halt		= native_safe_halt,
 	.irq.halt		= native_halt,
 #endif /* CONFIG_PARAVIRT_XXL */
diff --git a/arch/x86/xen/irq.c b/arch/x86/xen/irq.c
index 9c71f43..7fb4cf2 100644
--- a/arch/x86/xen/irq.c
+++ b/arch/x86/xen/irq.c
@@ -53,7 +53,7 @@ asmlinkage __visible void xen_irq_disable(void)
 }
 PV_CALLEE_SAVE_REGS_THUNK(xen_irq_disable);
 
-asmlinkage __visible void xen_irq_enable(void)
+asmlinkage __visible noinstr void xen_irq_enable(void)
 {
 	struct vcpu_info *vcpu;
 
@@ -76,7 +76,7 @@ asmlinkage __visible void xen_irq_enable(void)
 
 	preempt_enable();
 }
-PV_CALLEE_SAVE_REGS_THUNK(xen_irq_enable);
+__PV_CALLEE_SAVE_REGS_THUNK(xen_irq_enable, ".noinstr.text");
 
 static void xen_safe_halt(void)
 {
diff --git a/arch/x86/xen/xen-asm.S b/arch/x86/xen/xen-asm.S
index 0883e39..2225195 100644
--- a/arch/x86/xen/xen-asm.S
+++ b/arch/x86/xen/xen-asm.S
@@ -22,33 +22,6 @@
 #include <linux/linkage.h>
 
 /*
- * Enable events.  This clears the event mask and tests the pending
- * event status with one and operation.  If there are pending events,
- * then enter the hypervisor to get them handled.
- */
-SYM_FUNC_START(xen_irq_enable_direct)
-	FRAME_BEGIN
-	/* Unmask events */
-	movb $0, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask
-
-	/*
-	 * Preempt here doesn't matter because that will deal with any
-	 * pending interrupts.  The pending check may end up being run
-	 * on the wrong CPU, but that doesn't hurt.
-	 */
-
-	/* Test for pending */
-	testb $0xff, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_pending
-	jz 1f
-
-	call check_events
-1:
-	FRAME_END
-	ret
-SYM_FUNC_END(xen_irq_enable_direct)
-
-
-/*
  * Disabling events is simply a matter of making the event mask
  * non-zero.
  */
@@ -57,6 +30,8 @@ SYM_FUNC_START(xen_irq_disable_direct)
 	ret
 SYM_FUNC_END(xen_irq_disable_direct)
 
+.pushsection .noinstr.text, "ax"
+
 /*
  * Force an event check by making a hypercall, but preserve regs
  * before making the call.
@@ -86,7 +61,32 @@ SYM_FUNC_START(check_events)
 	ret
 SYM_FUNC_END(check_events)
 
-.pushsection .noinstr.text, "ax"
+/*
+ * Enable events.  This clears the event mask and tests the pending
+ * event status with one and operation.  If there are pending events,
+ * then enter the hypervisor to get them handled.
+ */
+SYM_FUNC_START(xen_irq_enable_direct)
+	FRAME_BEGIN
+	/* Unmask events */
+	movb $0, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask
+
+	/*
+	 * Preempt here doesn't matter because that will deal with any
+	 * pending interrupts.  The pending check may end up being run
+	 * on the wrong CPU, but that doesn't hurt.
+	 */
+
+	/* Test for pending */
+	testb $0xff, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_pending
+	jz 1f
+
+	call check_events
+1:
+	FRAME_END
+	ret
+SYM_FUNC_END(xen_irq_enable_direct)
+
 /*
  * (xen_)save_fl is used to get the current interrupt enable status.
  * Callers expect the status to be in X86_EFLAGS_IF, and other bits

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] x86/xen: Make hypercall_page noinstr
  2021-06-24  9:41 ` [PATCH v2 19/24] x86/xen: Make hypercall_page noinstr Peter Zijlstra
  2021-06-24 11:08   ` Juergen Gross
@ 2021-09-15 15:49   ` tip-bot2 for Peter Zijlstra
  2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
  2 siblings, 0 replies; 101+ messages in thread
From: tip-bot2 for Peter Zijlstra @ 2021-09-15 15:49 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Peter Zijlstra (Intel), Juergen Gross, x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     9f38b2a0baf1e5c7a1d1231cd8fe706c6f769a73
Gitweb:        https://git.kernel.org/tip/9f38b2a0baf1e5c7a1d1231cd8fe706c6f769a73
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Thu, 24 Jun 2021 11:41:18 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Wed, 15 Sep 2021 15:51:50 +02:00

x86/xen: Make hypercall_page noinstr

vmlinux.o: warning: objtool: xen_set_debugreg()+0x3: call to hypercall_page() leaves .noinstr.text section
vmlinux.o: warning: objtool: xen_get_debugreg()+0x3: call to hypercall_page() leaves .noinstr.text section
vmlinux.o: warning: objtool: xen_irq_enable()+0x24: call to hypercall_page() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Juergen Gross <jgross@suse.com>
Link: https://lore.kernel.org/r/20210624095148.810950584@infradead.org
---
 arch/x86/xen/xen-head.S | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/xen/xen-head.S b/arch/x86/xen/xen-head.S
index 488944d..9e27b86 100644
--- a/arch/x86/xen/xen-head.S
+++ b/arch/x86/xen/xen-head.S
@@ -20,7 +20,7 @@
 #include <xen/interface/xen-mca.h>
 #include <asm/xen/interface.h>
 
-.pushsection .text
+.pushsection .noinstr.text, "ax"
 	.balign PAGE_SIZE
 SYM_CODE_START(hypercall_page)
 	.rept (PAGE_SIZE / 32)

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] x86/xen: Make save_fl() noinstr
  2021-06-24  9:41 ` [PATCH v2 18/24] x86/xen: Make save_fl() noinstr Peter Zijlstra
  2021-06-24 11:07   ` Juergen Gross
@ 2021-09-15 15:49   ` tip-bot2 for Peter Zijlstra
  2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
  2 siblings, 0 replies; 101+ messages in thread
From: tip-bot2 for Peter Zijlstra @ 2021-09-15 15:49 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Peter Zijlstra (Intel), Juergen Gross, x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     1126696d60d04b844be88db50099f8fdb43d8166
Gitweb:        https://git.kernel.org/tip/1126696d60d04b844be88db50099f8fdb43d8166
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Thu, 24 Jun 2021 11:41:17 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Wed, 15 Sep 2021 15:51:49 +02:00

x86/xen: Make save_fl() noinstr

vmlinux.o: warning: objtool: pv_ops[30]: native_save_fl
vmlinux.o: warning: objtool: pv_ops[30]: __raw_callee_save_xen_save_fl
vmlinux.o: warning: objtool: pv_ops[30]: xen_save_fl_direct
vmlinux.o: warning: objtool: lockdep_hardirqs_off()+0x73: call to pv_ops[30]() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Juergen Gross <jgross@suse.com>
Link: https://lore.kernel.org/r/20210624095148.749712274@infradead.org
---
 arch/x86/include/asm/paravirt.h |  7 +++++--
 arch/x86/kernel/irqflags.S      |  2 ++-
 arch/x86/xen/irq.c              |  4 ++--
 arch/x86/xen/xen-asm.S          | 32 ++++++++++++++++----------------
 4 files changed, 25 insertions(+), 20 deletions(-)

diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index 34da790..cebec95 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -653,10 +653,10 @@ bool __raw_callee_save___native_vcpu_is_preempted(long cpu);
  * functions.
  */
 #define PV_THUNK_NAME(func) "__raw_callee_save_" #func
-#define PV_CALLEE_SAVE_REGS_THUNK(func)					\
+#define __PV_CALLEE_SAVE_REGS_THUNK(func, section)			\
 	extern typeof(func) __raw_callee_save_##func;			\
 									\
-	asm(".pushsection .text;"					\
+	asm(".pushsection " section ", \"ax\";"				\
 	    ".globl " PV_THUNK_NAME(func) ";"				\
 	    ".type " PV_THUNK_NAME(func) ", @function;"			\
 	    PV_THUNK_NAME(func) ":"					\
@@ -669,6 +669,9 @@ bool __raw_callee_save___native_vcpu_is_preempted(long cpu);
 	    ".size " PV_THUNK_NAME(func) ", .-" PV_THUNK_NAME(func) ";"	\
 	    ".popsection")
 
+#define PV_CALLEE_SAVE_REGS_THUNK(func)			\
+	__PV_CALLEE_SAVE_REGS_THUNK(func, ".text")
+
 /* Get a reference to a callee-save function */
 #define PV_CALLEE_SAVE(func)						\
 	((struct paravirt_callee_save) { __raw_callee_save_##func })
diff --git a/arch/x86/kernel/irqflags.S b/arch/x86/kernel/irqflags.S
index 8ef3506..760e1f2 100644
--- a/arch/x86/kernel/irqflags.S
+++ b/arch/x86/kernel/irqflags.S
@@ -7,9 +7,11 @@
 /*
  * unsigned long native_save_fl(void)
  */
+.pushsection .noinstr.text, "ax"
 SYM_FUNC_START(native_save_fl)
 	pushf
 	pop %_ASM_AX
 	ret
 SYM_FUNC_END(native_save_fl)
+.popsection
 EXPORT_SYMBOL(native_save_fl)
diff --git a/arch/x86/xen/irq.c b/arch/x86/xen/irq.c
index dfa091d..9c71f43 100644
--- a/arch/x86/xen/irq.c
+++ b/arch/x86/xen/irq.c
@@ -24,7 +24,7 @@ void xen_force_evtchn_callback(void)
 	(void)HYPERVISOR_xen_version(0, NULL);
 }
 
-asmlinkage __visible unsigned long xen_save_fl(void)
+asmlinkage __visible noinstr unsigned long xen_save_fl(void)
 {
 	struct vcpu_info *vcpu;
 	unsigned long flags;
@@ -40,7 +40,7 @@ asmlinkage __visible unsigned long xen_save_fl(void)
 	*/
 	return (-flags) & X86_EFLAGS_IF;
 }
-PV_CALLEE_SAVE_REGS_THUNK(xen_save_fl);
+__PV_CALLEE_SAVE_REGS_THUNK(xen_save_fl, ".noinstr.text");
 
 asmlinkage __visible void xen_irq_disable(void)
 {
diff --git a/arch/x86/xen/xen-asm.S b/arch/x86/xen/xen-asm.S
index aef4a1e..0883e39 100644
--- a/arch/x86/xen/xen-asm.S
+++ b/arch/x86/xen/xen-asm.S
@@ -58,22 +58,6 @@ SYM_FUNC_START(xen_irq_disable_direct)
 SYM_FUNC_END(xen_irq_disable_direct)
 
 /*
- * (xen_)save_fl is used to get the current interrupt enable status.
- * Callers expect the status to be in X86_EFLAGS_IF, and other bits
- * may be set in the return value.  We take advantage of this by
- * making sure that X86_EFLAGS_IF has the right value (and other bits
- * in that byte are 0), but other bits in the return value are
- * undefined.  We need to toggle the state of the bit, because Xen and
- * x86 use opposite senses (mask vs enable).
- */
-SYM_FUNC_START(xen_save_fl_direct)
-	testb $0xff, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask
-	setz %ah
-	addb %ah, %ah
-	ret
-SYM_FUNC_END(xen_save_fl_direct)
-
-/*
  * Force an event check by making a hypercall, but preserve regs
  * before making the call.
  */
@@ -103,6 +87,22 @@ SYM_FUNC_START(check_events)
 SYM_FUNC_END(check_events)
 
 .pushsection .noinstr.text, "ax"
+/*
+ * (xen_)save_fl is used to get the current interrupt enable status.
+ * Callers expect the status to be in X86_EFLAGS_IF, and other bits
+ * may be set in the return value.  We take advantage of this by
+ * making sure that X86_EFLAGS_IF has the right value (and other bits
+ * in that byte are 0), but other bits in the return value are
+ * undefined.  We need to toggle the state of the bit, because Xen and
+ * x86 use opposite senses (mask vs enable).
+ */
+SYM_FUNC_START(xen_save_fl_direct)
+	testb $0xff, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask
+	setz %ah
+	addb %ah, %ah
+	ret
+SYM_FUNC_END(xen_save_fl_direct)
+
 SYM_FUNC_START(xen_read_cr2)
 	FRAME_BEGIN
 	_ASM_MOV PER_CPU_VAR(xen_vcpu), %_ASM_AX

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] x86/xen: Make set_debugreg() noinstr
  2021-06-24  9:41 ` [PATCH v2 17/24] x86/xen: Make set_debugreg() noinstr Peter Zijlstra
  2021-06-24 10:59   ` Juergen Gross
@ 2021-09-15 15:49   ` tip-bot2 for Peter Zijlstra
  2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
  2 siblings, 0 replies; 101+ messages in thread
From: tip-bot2 for Peter Zijlstra @ 2021-09-15 15:49 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Peter Zijlstra (Intel), Juergen Gross, x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     9da62cacc7ed17e2186f82273762fe850078c8c3
Gitweb:        https://git.kernel.org/tip/9da62cacc7ed17e2186f82273762fe850078c8c3
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Thu, 24 Jun 2021 11:41:16 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Wed, 15 Sep 2021 15:51:49 +02:00

x86/xen: Make set_debugreg() noinstr

vmlinux.o: warning: objtool: pv_ops[2]: xen_set_debugreg
vmlinux.o: warning: objtool: pv_ops[2]: native_set_debugreg
vmlinux.o: warning: objtool: exc_debug()+0x3b: call to pv_ops[2]() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Juergen Gross <jgross@suse.com>
Link: https://lore.kernel.org/r/20210624095148.687755639@infradead.org
---
 arch/x86/include/asm/paravirt.h      |  2 +-
 arch/x86/include/asm/xen/hypercall.h |  2 +-
 arch/x86/kernel/paravirt.c           |  9 ++++++---
 arch/x86/xen/enlighten_pv.c          |  2 +-
 4 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index f48465c..34da790 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -118,7 +118,7 @@ static __always_inline unsigned long paravirt_get_debugreg(int reg)
 	return PVOP_CALL1(unsigned long, cpu.get_debugreg, reg);
 }
 #define get_debugreg(var, reg) var = paravirt_get_debugreg(reg)
-static inline void set_debugreg(unsigned long val, int reg)
+static __always_inline void set_debugreg(unsigned long val, int reg)
 {
 	PVOP_VCALL2(cpu.set_debugreg, reg, val);
 }
diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h
index af92202..990b8aa 100644
--- a/arch/x86/include/asm/xen/hypercall.h
+++ b/arch/x86/include/asm/xen/hypercall.h
@@ -308,7 +308,7 @@ HYPERVISOR_platform_op(struct xen_platform_op *op)
 	return _hypercall1(int, platform_op, op);
 }
 
-static inline int
+static __always_inline int
 HYPERVISOR_set_debugreg(int reg, unsigned long value)
 {
 	return _hypercall2(int, set_debugreg, reg, value);
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index 9188ae1..4d98791 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -253,6 +253,11 @@ static noinstr unsigned long pv_native_get_debugreg(int regno)
 	return native_get_debugreg(regno);
 }
 
+static noinstr void pv_native_set_debugreg(int regno, unsigned long val)
+{
+	native_set_debugreg(regno, val);
+}
+
 struct paravirt_patch_template pv_ops = {
 	/* Cpu ops. */
 	.cpu.io_delay		= native_io_delay,
@@ -260,7 +265,7 @@ struct paravirt_patch_template pv_ops = {
 #ifdef CONFIG_PARAVIRT_XXL
 	.cpu.cpuid		= native_cpuid,
 	.cpu.get_debugreg	= pv_native_get_debugreg,
-	.cpu.set_debugreg	= native_set_debugreg,
+	.cpu.set_debugreg	= pv_native_set_debugreg,
 	.cpu.read_cr0		= native_read_cr0,
 	.cpu.write_cr0		= native_write_cr0,
 	.cpu.write_cr4		= native_write_cr4,
@@ -386,8 +391,6 @@ struct paravirt_patch_template pv_ops = {
 };
 
 #ifdef CONFIG_PARAVIRT_XXL
-/* At this point, native_get/set_debugreg has real function entries */
-NOKPROBE_SYMBOL(native_set_debugreg);
 NOKPROBE_SYMBOL(native_load_idt);
 
 void (*paravirt_iret)(void) = native_iret;
diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c
index 273e1fa..2b1a8ba 100644
--- a/arch/x86/xen/enlighten_pv.c
+++ b/arch/x86/xen/enlighten_pv.c
@@ -311,7 +311,7 @@ static void __init xen_init_capabilities(void)
 	}
 }
 
-static void xen_set_debugreg(int reg, unsigned long val)
+static noinstr void xen_set_debugreg(int reg, unsigned long val)
 {
 	HYPERVISOR_set_debugreg(reg, val);
 }

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] x86/xen: Make get_debugreg() noinstr
  2021-06-24  9:41 ` [PATCH v2 16/24] x86/xen: Make get_debugreg() noinstr Peter Zijlstra
  2021-06-24 10:57   ` Juergen Gross
@ 2021-09-15 15:49   ` tip-bot2 for Peter Zijlstra
  2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
  2 siblings, 0 replies; 101+ messages in thread
From: tip-bot2 for Peter Zijlstra @ 2021-09-15 15:49 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Peter Zijlstra (Intel), Juergen Gross, x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     737196b197f21326b96ba969a5b1205c90f25cdc
Gitweb:        https://git.kernel.org/tip/737196b197f21326b96ba969a5b1205c90f25cdc
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Thu, 24 Jun 2021 11:41:15 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Wed, 15 Sep 2021 15:51:49 +02:00

x86/xen: Make get_debugreg() noinstr

vmlinux.o: warning: objtool: pv_ops[1]: xen_get_debugreg
vmlinux.o: warning: objtool: pv_ops[1]: native_get_debugreg
vmlinux.o: warning: objtool: exc_debug()+0x25: call to pv_ops[1]() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Juergen Gross <jgross@suse.com>
Link: https://lore.kernel.org/r/20210624095148.625523645@infradead.org
---
 arch/x86/include/asm/paravirt.h      | 2 +-
 arch/x86/include/asm/xen/hypercall.h | 2 +-
 arch/x86/kernel/paravirt.c           | 8 ++++++--
 arch/x86/xen/enlighten_pv.c          | 2 +-
 4 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index be82b52..f48465c 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -113,7 +113,7 @@ static inline void __cpuid(unsigned int *eax, unsigned int *ebx,
 /*
  * These special macros can be used to get or set a debugging register
  */
-static inline unsigned long paravirt_get_debugreg(int reg)
+static __always_inline unsigned long paravirt_get_debugreg(int reg)
 {
 	return PVOP_CALL1(unsigned long, cpu.get_debugreg, reg);
 }
diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h
index 454b208..af92202 100644
--- a/arch/x86/include/asm/xen/hypercall.h
+++ b/arch/x86/include/asm/xen/hypercall.h
@@ -314,7 +314,7 @@ HYPERVISOR_set_debugreg(int reg, unsigned long value)
 	return _hypercall2(int, set_debugreg, reg, value);
 }
 
-static inline unsigned long
+static __always_inline unsigned long
 HYPERVISOR_get_debugreg(int reg)
 {
 	return _hypercall1(unsigned long, get_debugreg, reg);
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index 78f08e1..9188ae1 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -248,13 +248,18 @@ static noinstr void pv_native_write_cr2(unsigned long val)
 	native_write_cr2(val);
 }
 
+static noinstr unsigned long pv_native_get_debugreg(int regno)
+{
+	return native_get_debugreg(regno);
+}
+
 struct paravirt_patch_template pv_ops = {
 	/* Cpu ops. */
 	.cpu.io_delay		= native_io_delay,
 
 #ifdef CONFIG_PARAVIRT_XXL
 	.cpu.cpuid		= native_cpuid,
-	.cpu.get_debugreg	= native_get_debugreg,
+	.cpu.get_debugreg	= pv_native_get_debugreg,
 	.cpu.set_debugreg	= native_set_debugreg,
 	.cpu.read_cr0		= native_read_cr0,
 	.cpu.write_cr0		= native_write_cr0,
@@ -382,7 +387,6 @@ struct paravirt_patch_template pv_ops = {
 
 #ifdef CONFIG_PARAVIRT_XXL
 /* At this point, native_get/set_debugreg has real function entries */
-NOKPROBE_SYMBOL(native_get_debugreg);
 NOKPROBE_SYMBOL(native_set_debugreg);
 NOKPROBE_SYMBOL(native_load_idt);
 
diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c
index 753f637..273e1fa 100644
--- a/arch/x86/xen/enlighten_pv.c
+++ b/arch/x86/xen/enlighten_pv.c
@@ -316,7 +316,7 @@ static void xen_set_debugreg(int reg, unsigned long val)
 	HYPERVISOR_set_debugreg(reg, val);
 }
 
-static unsigned long xen_get_debugreg(int reg)
+static noinstr unsigned long xen_get_debugreg(int reg)
 {
 	return HYPERVISOR_get_debugreg(reg);
 }

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] x86/xen: Make write_cr2() noinstr
  2021-06-24  9:41 ` [PATCH v2 15/24] x86/xen: Make write_cr2() noinstr Peter Zijlstra
  2021-06-24 10:56   ` Juergen Gross
@ 2021-09-15 15:49   ` tip-bot2 for Peter Zijlstra
  2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
  2 siblings, 0 replies; 101+ messages in thread
From: tip-bot2 for Peter Zijlstra @ 2021-09-15 15:49 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Peter Zijlstra (Intel), Juergen Gross, x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     80de642654653a8f86b34e9072a4d2fb95c32683
Gitweb:        https://git.kernel.org/tip/80de642654653a8f86b34e9072a4d2fb95c32683
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Thu, 24 Jun 2021 11:41:14 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Wed, 15 Sep 2021 15:51:48 +02:00

x86/xen: Make write_cr2() noinstr

vmlinux.o: warning: objtool: pv_ops[42]: native_write_cr2
vmlinux.o: warning: objtool: pv_ops[42]: xen_write_cr2
vmlinux.o: warning: objtool: exc_nmi()+0x127: call to pv_ops[42]() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Juergen Gross <jgross@suse.com>
Link: https://lore.kernel.org/r/20210624095148.563524913@infradead.org
---
 arch/x86/include/asm/paravirt.h | 2 +-
 arch/x86/kernel/paravirt.c      | 7 ++++++-
 arch/x86/xen/mmu_pv.c           | 3 ++-
 3 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index 8878065..be82b52 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -140,7 +140,7 @@ static __always_inline unsigned long read_cr2(void)
 				ALT_NOT(X86_FEATURE_XENPV));
 }
 
-static inline void write_cr2(unsigned long x)
+static __always_inline void write_cr2(unsigned long x)
 {
 	PVOP_VCALL1(mmu.write_cr2, x);
 }
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index ff4ade8..78f08e1 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -243,6 +243,11 @@ static noinstr unsigned long pv_native_read_cr2(void)
 	return native_read_cr2();
 }
 
+static noinstr void pv_native_write_cr2(unsigned long val)
+{
+	native_write_cr2(val);
+}
+
 struct paravirt_patch_template pv_ops = {
 	/* Cpu ops. */
 	.cpu.io_delay		= native_io_delay,
@@ -304,7 +309,7 @@ struct paravirt_patch_template pv_ops = {
 
 #ifdef CONFIG_PARAVIRT_XXL
 	.mmu.read_cr2		= __PV_IS_CALLEE_SAVE(pv_native_read_cr2),
-	.mmu.write_cr2		= native_write_cr2,
+	.mmu.write_cr2		= pv_native_write_cr2,
 	.mmu.read_cr3		= __native_read_cr3,
 	.mmu.write_cr3		= native_write_cr3,
 
diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c
index 1df5f01..f3cafe5 100644
--- a/arch/x86/xen/mmu_pv.c
+++ b/arch/x86/xen/mmu_pv.c
@@ -1204,7 +1204,8 @@ static void __init xen_pagetable_init(void)
 	xen_remap_memory();
 	xen_setup_mfn_list_list();
 }
-static void xen_write_cr2(unsigned long cr2)
+
+static noinstr void xen_write_cr2(unsigned long cr2)
 {
 	this_cpu_read(xen_vcpu)->arch.cr2 = cr2;
 }

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] x86/xen: Make read_cr2() noinstr
  2021-06-24  9:41 ` [PATCH v2 14/24] x86/xen: Make read_cr2() noinstr Peter Zijlstra
  2021-06-24 10:55   ` Juergen Gross
@ 2021-09-15 15:49   ` tip-bot2 for Peter Zijlstra
  2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
  2 siblings, 0 replies; 101+ messages in thread
From: tip-bot2 for Peter Zijlstra @ 2021-09-15 15:49 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Peter Zijlstra (Intel), Juergen Gross, x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     ee6781aba03fc3040e3dfaa57fe8c2cea751ee35
Gitweb:        https://git.kernel.org/tip/ee6781aba03fc3040e3dfaa57fe8c2cea751ee35
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Thu, 24 Jun 2021 11:41:13 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Wed, 15 Sep 2021 15:51:48 +02:00

x86/xen: Make read_cr2() noinstr

vmlinux.o: warning: objtool: pv_ops[41]: native_read_cr2
vmlinux.o: warning: objtool: pv_ops[41]: xen_read_cr2
vmlinux.o: warning: objtool: pv_ops[41]: xen_read_cr2_direct
vmlinux.o: warning: objtool: exc_double_fault()+0x15: call to pv_ops[41]() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Juergen Gross <jgross@suse.com>
Link: https://lore.kernel.org/r/20210624095148.500331616@infradead.org
---
 arch/x86/include/asm/paravirt.h | 2 +-
 arch/x86/kernel/paravirt.c      | 7 ++++++-
 arch/x86/xen/xen-asm.S          | 2 ++
 3 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index a13a9a3..8878065 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -133,7 +133,7 @@ static inline void write_cr0(unsigned long x)
 	PVOP_VCALL1(cpu.write_cr0, x);
 }
 
-static inline unsigned long read_cr2(void)
+static __always_inline unsigned long read_cr2(void)
 {
 	return PVOP_ALT_CALLEE0(unsigned long, mmu.read_cr2,
 				"mov %%cr2, %%rax;",
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index 04cafc0..ff4ade8 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -238,6 +238,11 @@ struct pv_info pv_info = {
 /* 64-bit pagetable entries */
 #define PTE_IDENT	__PV_IS_CALLEE_SAVE(_paravirt_ident_64)
 
+static noinstr unsigned long pv_native_read_cr2(void)
+{
+	return native_read_cr2();
+}
+
 struct paravirt_patch_template pv_ops = {
 	/* Cpu ops. */
 	.cpu.io_delay		= native_io_delay,
@@ -298,7 +303,7 @@ struct paravirt_patch_template pv_ops = {
 	.mmu.exit_mmap		= paravirt_nop,
 
 #ifdef CONFIG_PARAVIRT_XXL
-	.mmu.read_cr2		= __PV_IS_CALLEE_SAVE(native_read_cr2),
+	.mmu.read_cr2		= __PV_IS_CALLEE_SAVE(pv_native_read_cr2),
 	.mmu.write_cr2		= native_write_cr2,
 	.mmu.read_cr3		= __native_read_cr3,
 	.mmu.write_cr3		= native_write_cr3,
diff --git a/arch/x86/xen/xen-asm.S b/arch/x86/xen/xen-asm.S
index 1e62644..aef4a1e 100644
--- a/arch/x86/xen/xen-asm.S
+++ b/arch/x86/xen/xen-asm.S
@@ -102,6 +102,7 @@ SYM_FUNC_START(check_events)
 	ret
 SYM_FUNC_END(check_events)
 
+.pushsection .noinstr.text, "ax"
 SYM_FUNC_START(xen_read_cr2)
 	FRAME_BEGIN
 	_ASM_MOV PER_CPU_VAR(xen_vcpu), %_ASM_AX
@@ -116,6 +117,7 @@ SYM_FUNC_START(xen_read_cr2_direct)
 	FRAME_END
 	ret
 SYM_FUNC_END(xen_read_cr2_direct);
+.popsection
 
 .macro xen_pv_trap name
 SYM_CODE_START(xen_\name)

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] x86/paravirt: Use PVOP_* for paravirt calls
  2021-06-24  9:41 ` [PATCH v2 13/24] x86/paravirt: Use PVOP_* for paravirt calls Peter Zijlstra
  2021-06-24 10:52   ` Juergen Gross
@ 2021-09-15 15:49   ` tip-bot2 for Peter Zijlstra
  1 sibling, 0 replies; 101+ messages in thread
From: tip-bot2 for Peter Zijlstra @ 2021-09-15 15:49 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Peter Zijlstra (Intel), Juergen Gross, x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     eac46b323b28215ad19d53390737df4aa336ac14
Gitweb:        https://git.kernel.org/tip/eac46b323b28215ad19d53390737df4aa336ac14
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Thu, 24 Jun 2021 11:41:12 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Wed, 15 Sep 2021 15:51:48 +02:00

x86/paravirt: Use PVOP_* for paravirt calls

Doing unconditional indirect calls through the pv_ops vector is weird.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Juergen Gross <jgross@suse.com>
Link: https://lore.kernel.org/r/20210624095148.437720419@infradead.org
---
 arch/x86/include/asm/paravirt.h | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index 89a5322..a13a9a3 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -52,11 +52,11 @@ void __init paravirt_set_cap(void);
 /* The paravirtualized I/O functions */
 static inline void slow_down_io(void)
 {
-	pv_ops.cpu.io_delay();
+	PVOP_VCALL0(cpu.io_delay);
 #ifdef REALLY_SLOW_IO
-	pv_ops.cpu.io_delay();
-	pv_ops.cpu.io_delay();
-	pv_ops.cpu.io_delay();
+	PVOP_VCALL0(cpu.io_delay);
+	PVOP_VCALL0(cpu.io_delay);
+	PVOP_VCALL0(cpu.io_delay);
 #endif
 }
 

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] x86/paravirt: Mark arch_local_irq_*() __always_inline
  2021-06-24  9:41 ` [PATCH v2 12/24] x86/paravirt: Mark arch_local_irq_*() __always_inline Peter Zijlstra
  2021-06-24 10:51   ` Juergen Gross
@ 2021-09-15 15:49   ` tip-bot2 for Peter Zijlstra
  1 sibling, 0 replies; 101+ messages in thread
From: tip-bot2 for Peter Zijlstra @ 2021-09-15 15:49 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Peter Zijlstra (Intel), Juergen Gross, x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     e9382440de18718fb6f878986c0844c30abc6f99
Gitweb:        https://git.kernel.org/tip/e9382440de18718fb6f878986c0844c30abc6f99
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Thu, 24 Jun 2021 11:41:11 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Wed, 15 Sep 2021 15:51:47 +02:00

x86/paravirt: Mark arch_local_irq_*() __always_inline

vmlinux.o: warning: objtool: lockdep_hardirqs_on()+0x72: call to arch_local_save_flags() leaves .noinstr.text section
vmlinux.o: warning: objtool: lockdep_hardirqs_off()+0x73: call to arch_local_save_flags() leaves .noinstr.text section
vmlinux.o: warning: objtool: match_held_lock()+0x11f: call to arch_local_save_flags() leaves .noinstr.text section

vmlinux.o: warning: objtool: lock_is_held_type()+0x4e: call to arch_local_irq_save() leaves .noinstr.text section

vmlinux.o: warning: objtool: lock_is_held_type()+0x65: call to arch_local_irq_disable() leaves .noinstr.text section

vmlinux.o: warning: objtool: lock_is_held_type()+0xfe: call to arch_local_irq_enable() leaves .noinstr.text section

It makes no sense to not inline these things.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Juergen Gross <jgross@suse.com>
Link: https://lore.kernel.org/r/20210624095148.373073648@infradead.org
---
 arch/x86/include/asm/paravirt.h | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index da3a1ac..89a5322 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -678,23 +678,23 @@ bool __raw_callee_save___native_vcpu_is_preempted(long cpu);
 	((struct paravirt_callee_save) { func })
 
 #ifdef CONFIG_PARAVIRT_XXL
-static inline notrace unsigned long arch_local_save_flags(void)
+static __always_inline unsigned long arch_local_save_flags(void)
 {
 	return PVOP_ALT_CALLEE0(unsigned long, irq.save_fl, "pushf; pop %%rax;",
 				ALT_NOT(X86_FEATURE_XENPV));
 }
 
-static inline notrace void arch_local_irq_disable(void)
+static __always_inline void arch_local_irq_disable(void)
 {
 	PVOP_ALT_VCALLEE0(irq.irq_disable, "cli;", ALT_NOT(X86_FEATURE_XENPV));
 }
 
-static inline notrace void arch_local_irq_enable(void)
+static __always_inline void arch_local_irq_enable(void)
 {
 	PVOP_ALT_VCALLEE0(irq.irq_enable, "sti;", ALT_NOT(X86_FEATURE_XENPV));
 }
 
-static inline notrace unsigned long arch_local_irq_save(void)
+static __always_inline unsigned long arch_local_irq_save(void)
 {
 	unsigned long f;
 

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] locking/lockdep: Avoid RCU-induced noinstr fail
  2021-06-24  9:41 ` [PATCH v2 11/24] locking/lockdep: Avoid RCU-induced noinstr fail Peter Zijlstra
@ 2021-09-15 15:49   ` tip-bot2 for Peter Zijlstra
  0 siblings, 0 replies; 101+ messages in thread
From: tip-bot2 for Peter Zijlstra @ 2021-09-15 15:49 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: Peter Zijlstra (Intel), x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     ce0b9c805dd66d5e49fd53ec5415ae398f4c56e6
Gitweb:        https://git.kernel.org/tip/ce0b9c805dd66d5e49fd53ec5415ae398f4c56e6
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Thu, 24 Jun 2021 11:41:10 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Wed, 15 Sep 2021 15:51:47 +02:00

locking/lockdep: Avoid RCU-induced noinstr fail

vmlinux.o: warning: objtool: look_up_lock_class()+0xc7: call to rcu_read_lock_any_held() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/r/20210624095148.311980536@infradead.org
---
 kernel/locking/lockdep.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index bf1c00c..8a50967 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -888,7 +888,7 @@ look_up_lock_class(const struct lockdep_map *lock, unsigned int subclass)
 	if (DEBUG_LOCKS_WARN_ON(!irqs_disabled()))
 		return NULL;
 
-	hlist_for_each_entry_rcu(class, hash_head, hash_entry) {
+	hlist_for_each_entry_rcu_notrace(class, hash_head, hash_entry) {
 		if (class->key == key) {
 			/*
 			 * Huh! same key, different name? Did someone trample

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] x86/sev: Fix noinstr for vc_ghcb_invalidate()
  2021-06-24  9:41 ` [PATCH v2 10/24] x86/sev: Fix noinstr for vc_ghcb_invalidate() Peter Zijlstra
@ 2021-09-15 15:49   ` tip-bot2 for Peter Zijlstra
  0 siblings, 0 replies; 101+ messages in thread
From: tip-bot2 for Peter Zijlstra @ 2021-09-15 15:49 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: Peter Zijlstra (Intel), x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     2c36d87be49355931da5b29ef7621505e0e46ce9
Gitweb:        https://git.kernel.org/tip/2c36d87be49355931da5b29ef7621505e0e46ce9
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Thu, 24 Jun 2021 11:41:09 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Wed, 15 Sep 2021 15:51:47 +02:00

x86/sev: Fix noinstr for vc_ghcb_invalidate()

vmlinux.o: warning: objtool: __sev_put_ghcb()+0x88: call to __memset() leaves .noinstr.text section
vmlinux.o: warning: objtool: __sev_es_nmi_complete()+0x39: call to __memset() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/r/20210624095148.250770465@infradead.org
---
 arch/x86/kernel/sev-shared.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kernel/sev-shared.c b/arch/x86/kernel/sev-shared.c
index 9f90f46..34f20e0 100644
--- a/arch/x86/kernel/sev-shared.c
+++ b/arch/x86/kernel/sev-shared.c
@@ -64,7 +64,7 @@ static bool sev_es_negotiate_protocol(void)
 static __always_inline void vc_ghcb_invalidate(struct ghcb *ghcb)
 {
 	ghcb->save.sw_exit_code = 0;
-	memset(ghcb->save.valid_bitmap, 0, sizeof(ghcb->save.valid_bitmap));
+	__builtin_memset(ghcb->save.valid_bitmap, 0, sizeof(ghcb->save.valid_bitmap));
 }
 
 static bool vc_decoding_needed(unsigned long exit_code)

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] x86: Always inline ip_within_syscall_gap()
  2021-06-24  9:41 ` [PATCH v2 09/24] x86: Always inline ip_within_syscall_gap() Peter Zijlstra
@ 2021-09-15 15:49   ` tip-bot2 for Peter Zijlstra
  0 siblings, 0 replies; 101+ messages in thread
From: tip-bot2 for Peter Zijlstra @ 2021-09-15 15:49 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: Peter Zijlstra (Intel), x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     c6b01dace2cd7f6b3e9174d4d1411755608486f1
Gitweb:        https://git.kernel.org/tip/c6b01dace2cd7f6b3e9174d4d1411755608486f1
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Thu, 24 Jun 2021 11:41:08 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Wed, 15 Sep 2021 15:51:47 +02:00

x86: Always inline ip_within_syscall_gap()

vmlinux.o: warning: objtool: vc_switch_off_ist()+0x20: call to ip_within_syscall_gap.isra.0() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/r/20210624095148.188166492@infradead.org
---
 arch/x86/include/asm/ptrace.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h
index b94f615..7036631 100644
--- a/arch/x86/include/asm/ptrace.h
+++ b/arch/x86/include/asm/ptrace.h
@@ -181,7 +181,7 @@ static inline bool any_64bit_mode(struct pt_regs *regs)
 #define current_user_stack_pointer()	current_pt_regs()->sp
 #define compat_user_stack_pointer()	current_pt_regs()->sp
 
-static inline bool ip_within_syscall_gap(struct pt_regs *regs)
+static __always_inline bool ip_within_syscall_gap(struct pt_regs *regs)
 {
 	bool ret = (regs->ip >= (unsigned long)entry_SYSCALL_64 &&
 		    regs->ip <  (unsigned long)entry_SYSCALL_64_safe_stack);

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] x86/kvm: Always inline evmcs_write64()
  2021-06-24  9:41 ` [PATCH v2 08/24] x86/kvm: Always inline evmcs_write64() Peter Zijlstra
@ 2021-09-15 15:49   ` tip-bot2 for Peter Zijlstra
  0 siblings, 0 replies; 101+ messages in thread
From: tip-bot2 for Peter Zijlstra @ 2021-09-15 15:49 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: Peter Zijlstra (Intel), x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     010050a86393703f43859a4704d2193be49126d6
Gitweb:        https://git.kernel.org/tip/010050a86393703f43859a4704d2193be49126d6
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Thu, 24 Jun 2021 11:41:07 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Wed, 15 Sep 2021 15:51:46 +02:00

x86/kvm: Always inline evmcs_write64()

vmlinux.o: warning: objtool: vmx_update_host_rsp()+0x64: call to evmcs_write64() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/r/20210624095148.126956644@infradead.org
---
 arch/x86/kvm/vmx/evmcs.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kvm/vmx/evmcs.h b/arch/x86/kvm/vmx/evmcs.h
index 152ab0a..16731d2 100644
--- a/arch/x86/kvm/vmx/evmcs.h
+++ b/arch/x86/kvm/vmx/evmcs.h
@@ -93,7 +93,7 @@ static __always_inline int get_evmcs_offset(unsigned long field,
 	return evmcs_field->offset;
 }
 
-static inline void evmcs_write64(unsigned long field, u64 value)
+static __always_inline void evmcs_write64(unsigned long field, u64 value)
 {
 	u16 clean_field;
 	int offset = get_evmcs_offset(field, &clean_field);
@@ -183,7 +183,7 @@ static inline void evmcs_load(u64 phys_addr)
 
 __init void evmcs_sanitize_exec_ctrls(struct vmcs_config *vmcs_conf);
 #else /* !IS_ENABLED(CONFIG_HYPERV) */
-static inline void evmcs_write64(unsigned long field, u64 value) {}
+static __always_inline void evmcs_write64(unsigned long field, u64 value) {}
 static inline void evmcs_write32(unsigned long field, u32 value) {}
 static inline void evmcs_write16(unsigned long field, u16 value) {}
 static inline u64 evmcs_read64(unsigned long field) { return 0; }

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] x86/kvm: Always inline to_svm()
  2021-06-24  9:41 ` [PATCH v2 07/24] x86/kvm: Always inline to_svm() Peter Zijlstra
@ 2021-09-15 15:49   ` tip-bot2 for Peter Zijlstra
  0 siblings, 0 replies; 101+ messages in thread
From: tip-bot2 for Peter Zijlstra @ 2021-09-15 15:49 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: Peter Zijlstra (Intel), x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     aee045ed0a6b22100f4d5945ee2deb75db6a0dd5
Gitweb:        https://git.kernel.org/tip/aee045ed0a6b22100f4d5945ee2deb75db6a0dd5
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Thu, 24 Jun 2021 11:41:06 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Wed, 15 Sep 2021 15:51:46 +02:00

x86/kvm: Always inline to_svm()

vmlinux.o: warning: objtool: svm_vcpu_enter_exit()+0x13: call to to_svm() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/r/20210624095148.066347165@infradead.org
---
 arch/x86/kvm/svm/svm.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
index 408031a..38f12a6 100644
--- a/arch/x86/kvm/svm/svm.h
+++ b/arch/x86/kvm/svm/svm.h
@@ -271,7 +271,7 @@ static inline bool vmcb_is_dirty(struct vmcb *vmcb, int bit)
         return !test_bit(bit, (unsigned long *)&vmcb->control.clean);
 }
 
-static inline struct vcpu_svm *to_svm(struct kvm_vcpu *vcpu)
+static __always_inline struct vcpu_svm *to_svm(struct kvm_vcpu *vcpu)
 {
 	return container_of(vcpu, struct vcpu_svm, vcpu);
 }

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] x86: Always inline context_tracking_guest_enter()
  2021-06-24  9:41 ` [PATCH v2 06/24] x86: Always inline context_tracking_guest_enter() Peter Zijlstra
  2021-08-20 23:22   ` Josh Poimboeuf
@ 2021-09-15 15:49   ` tip-bot2 for Peter Zijlstra
  1 sibling, 0 replies; 101+ messages in thread
From: tip-bot2 for Peter Zijlstra @ 2021-09-15 15:49 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: Peter Zijlstra (Intel), x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     e25b694bf1d9ef4a3f36c0b85348f8e780f22139
Gitweb:        https://git.kernel.org/tip/e25b694bf1d9ef4a3f36c0b85348f8e780f22139
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Thu, 24 Jun 2021 11:41:05 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Wed, 15 Sep 2021 15:51:46 +02:00

x86: Always inline context_tracking_guest_enter()

Yes, it really did out-of-line this....

vmlinux.o: warning: objtool: vmx_vcpu_enter_exit()+0x31: call to context_tracking_guest_enter() leaves .noinstr.text section

000000000019f660 <context_tracking_guest_enter>:
  19f660:	e8 00 00 00 00       	callq  19f665 <context_tracking_guest_enter+0x5>	19f661: R_X86_64_PLT32	__sanitizer_cov_trace_pc-0x4
  19f665:	31 c0                	xor    %eax,%eax
  19f667:	c3                   	retq

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/r/20210624095148.003928226@infradead.org
---
 include/linux/context_tracking.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/context_tracking.h b/include/linux/context_tracking.h
index 4d7fced..7a14807 100644
--- a/include/linux/context_tracking.h
+++ b/include/linux/context_tracking.h
@@ -105,7 +105,7 @@ static inline void user_exit_irqoff(void) { }
 static inline enum ctx_state exception_enter(void) { return 0; }
 static inline void exception_exit(enum ctx_state prev_ctx) { }
 static inline enum ctx_state ct_state(void) { return CONTEXT_DISABLED; }
-static inline bool context_tracking_guest_enter(void) { return false; }
+static __always_inline bool context_tracking_guest_enter(void) { return false; }
 static inline void context_tracking_guest_exit(void) { }
 
 #endif /* !CONFIG_CONTEXT_TRACKING */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] x86/kvm: Always inline vmload() / vmsave()
  2021-06-24  9:41 ` [PATCH v2 05/24] x86/kvm: Always inline vmload() / vmsave() Peter Zijlstra
@ 2021-09-15 15:49   ` tip-bot2 for Peter Zijlstra
  0 siblings, 0 replies; 101+ messages in thread
From: tip-bot2 for Peter Zijlstra @ 2021-09-15 15:49 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: Peter Zijlstra (Intel), x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     a168233a440d01d60ca65ea41e876661466f108b
Gitweb:        https://git.kernel.org/tip/a168233a440d01d60ca65ea41e876661466f108b
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Thu, 24 Jun 2021 11:41:04 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Wed, 15 Sep 2021 15:51:45 +02:00

x86/kvm: Always inline vmload() / vmsave()

vmlinux.o: warning: objtool: svm_vcpu_enter_exit()+0xea: call to vmload() leaves .noinstr.text section
vmlinux.o: warning: objtool: svm_vcpu_enter_exit()+0x133: call to vmsave() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/r/20210624095147.942250748@infradead.org
---
 arch/x86/kvm/svm/svm_ops.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kvm/svm/svm_ops.h b/arch/x86/kvm/svm/svm_ops.h
index 22e2b01..9430d64 100644
--- a/arch/x86/kvm/svm/svm_ops.h
+++ b/arch/x86/kvm/svm/svm_ops.h
@@ -56,12 +56,12 @@ static inline void invlpga(unsigned long addr, u32 asid)
  * VMSAVE, VMLOAD, etc... is still controlled by the effective address size,
  * hence 'unsigned long' instead of 'hpa_t'.
  */
-static inline void vmsave(unsigned long pa)
+static __always_inline void vmsave(unsigned long pa)
 {
 	svm_asm1(vmsave, "a" (pa), "memory");
 }
 
-static inline void vmload(unsigned long pa)
+static __always_inline void vmload(unsigned long pa)
 {
 	svm_asm1(vmload, "a" (pa), "memory");
 }

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] x86/kvm: Always inline sev_*guest()
  2021-06-24  9:41 ` [PATCH v2 04/24] x86/kvm: Always inline sev_*guest() Peter Zijlstra
@ 2021-09-15 15:49   ` tip-bot2 for Peter Zijlstra
  0 siblings, 0 replies; 101+ messages in thread
From: tip-bot2 for Peter Zijlstra @ 2021-09-15 15:49 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: Peter Zijlstra (Intel), x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     2b2f72d4d81936bc08c18c426f40b7df70e2f8e7
Gitweb:        https://git.kernel.org/tip/2b2f72d4d81936bc08c18c426f40b7df70e2f8e7
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Thu, 24 Jun 2021 11:41:03 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Wed, 15 Sep 2021 15:51:45 +02:00

x86/kvm: Always inline sev_*guest()

vmlinux.o: warning: objtool: svm_vcpu_enter_exit()+0x4d: call to sev_es_guest() leaves .noinstr.text section
vmlinux.o: warning: objtool: svm_vcpu_enter_exit()+0x50: call to sev_guest() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/r/20210624095147.880513802@infradead.org
---
 arch/x86/kvm/svm/svm.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
index 524d943..408031a 100644
--- a/arch/x86/kvm/svm/svm.h
+++ b/arch/x86/kvm/svm/svm.h
@@ -218,12 +218,12 @@ DECLARE_PER_CPU(struct svm_cpu_data *, svm_data);
 
 void recalc_intercepts(struct vcpu_svm *svm);
 
-static inline struct kvm_svm *to_kvm_svm(struct kvm *kvm)
+static __always_inline struct kvm_svm *to_kvm_svm(struct kvm *kvm)
 {
 	return container_of(kvm, struct kvm_svm, kvm);
 }
 
-static inline bool sev_guest(struct kvm *kvm)
+static __always_inline bool sev_guest(struct kvm *kvm)
 {
 #ifdef CONFIG_KVM_AMD_SEV
 	struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
@@ -234,7 +234,7 @@ static inline bool sev_guest(struct kvm *kvm)
 #endif
 }
 
-static inline bool sev_es_guest(struct kvm *kvm)
+static __always_inline bool sev_es_guest(struct kvm *kvm)
 {
 #ifdef CONFIG_KVM_AMD_SEV
 	struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] objtool: Handle __sanitize_cov*() tail calls
  2021-06-24  9:41 ` [PATCH v2 03/24] objtool: Handle __sanitize_cov*() tail calls Peter Zijlstra
                     ` (2 preceding siblings ...)
  2021-08-20 23:17   ` Josh Poimboeuf
@ 2021-09-15 15:49   ` tip-bot2 for Peter Zijlstra
  3 siblings, 0 replies; 101+ messages in thread
From: tip-bot2 for Peter Zijlstra @ 2021-09-15 15:49 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: Peter Zijlstra (Intel), Marco Elver, x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     f56dae88a81fded66adf2bea9922d1d98d1da14f
Gitweb:        https://git.kernel.org/tip/f56dae88a81fded66adf2bea9922d1d98d1da14f
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Thu, 24 Jun 2021 11:41:02 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Wed, 15 Sep 2021 15:51:45 +02:00

objtool: Handle __sanitize_cov*() tail calls

Turns out the compilers also generate tail calls to __sanitize_cov*(),
make sure to also patch those out in noinstr code.

Fixes: 0f1441b44e82 ("objtool: Fix noinstr vs KCOV")
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Marco Elver <elver@google.com>
Link: https://lore.kernel.org/r/20210624095147.818783799@infradead.org
---
 tools/objtool/arch/x86/decode.c      |  20 +++-
 tools/objtool/check.c                | 158 +++++++++++++-------------
 tools/objtool/include/objtool/arch.h |   1 +-
 3 files changed, 105 insertions(+), 74 deletions(-)

diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c
index 3435a32..340a3dc 100644
--- a/tools/objtool/arch/x86/decode.c
+++ b/tools/objtool/arch/x86/decode.c
@@ -659,6 +659,26 @@ const char *arch_nop_insn(int len)
 	return nops[len-1];
 }
 
+#define BYTE_RET	0xC3
+
+const char *arch_ret_insn(int len)
+{
+	static const char ret[5][5] = {
+		{ BYTE_RET },
+		{ BYTE_RET, BYTES_NOP1 },
+		{ BYTE_RET, BYTES_NOP2 },
+		{ BYTE_RET, BYTES_NOP3 },
+		{ BYTE_RET, BYTES_NOP4 },
+	};
+
+	if (len < 1 || len > 5) {
+		WARN("invalid RET size: %d\n", len);
+		return NULL;
+	}
+
+	return ret[len-1];
+}
+
 /* asm/alternative.h ? */
 
 #define ALTINSTR_FLAG_INV	(1 << 15)
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index d9f3273..c6f206f 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -904,6 +904,79 @@ static struct reloc *insn_reloc(struct objtool_file *file, struct instruction *i
 	return insn->reloc;
 }
 
+static void remove_insn_ops(struct instruction *insn)
+{
+	struct stack_op *op, *tmp;
+
+	list_for_each_entry_safe(op, tmp, &insn->stack_ops, list) {
+		list_del(&op->list);
+		free(op);
+	}
+}
+
+static void add_call_dest(struct objtool_file *file, struct instruction *insn,
+			  struct symbol *dest, bool sibling)
+{
+	struct reloc *reloc = insn_reloc(file, insn);
+
+	insn->call_dest = dest;
+	if (!dest)
+		return;
+
+	if (insn->call_dest->static_call_tramp) {
+		list_add_tail(&insn->call_node,
+			      &file->static_call_list);
+	}
+
+	/*
+	 * Many compilers cannot disable KCOV with a function attribute
+	 * so they need a little help, NOP out any KCOV calls from noinstr
+	 * text.
+	 */
+	if (insn->sec->noinstr &&
+	    !strncmp(insn->call_dest->name, "__sanitizer_cov_", 16)) {
+		if (reloc) {
+			reloc->type = R_NONE;
+			elf_write_reloc(file->elf, reloc);
+		}
+
+		elf_write_insn(file->elf, insn->sec,
+			       insn->offset, insn->len,
+			       sibling ? arch_ret_insn(insn->len)
+			               : arch_nop_insn(insn->len));
+
+		insn->type = sibling ? INSN_RETURN : INSN_NOP;
+	}
+
+	if (mcount && !strcmp(insn->call_dest->name, "__fentry__")) {
+		if (sibling)
+			WARN_FUNC("Tail call to __fentry__ !?!?", insn->sec, insn->offset);
+
+		if (reloc) {
+			reloc->type = R_NONE;
+			elf_write_reloc(file->elf, reloc);
+		}
+
+		elf_write_insn(file->elf, insn->sec,
+			       insn->offset, insn->len,
+			       arch_nop_insn(insn->len));
+
+		insn->type = INSN_NOP;
+
+		list_add_tail(&insn->mcount_loc_node,
+			      &file->mcount_loc_list);
+	}
+
+	/*
+	 * Whatever stack impact regular CALLs have, should be undone
+	 * by the RETURN of the called function.
+	 *
+	 * Annotated intra-function calls retain the stack_ops but
+	 * are converted to JUMP, see read_intra_function_calls().
+	 */
+	remove_insn_ops(insn);
+}
+
 /*
  * Find the destination instructions for all jumps.
  */
@@ -942,11 +1015,7 @@ static int add_jump_destinations(struct objtool_file *file)
 			continue;
 		} else if (insn->func) {
 			/* internal or external sibling call (with reloc) */
-			insn->call_dest = reloc->sym;
-			if (insn->call_dest->static_call_tramp) {
-				list_add_tail(&insn->call_node,
-					      &file->static_call_list);
-			}
+			add_call_dest(file, insn, reloc->sym, true);
 			continue;
 		} else if (reloc->sym->sec->idx) {
 			dest_sec = reloc->sym->sec;
@@ -1002,13 +1071,8 @@ static int add_jump_destinations(struct objtool_file *file)
 
 			} else if (insn->jump_dest->func->pfunc != insn->func->pfunc &&
 				   insn->jump_dest->offset == insn->jump_dest->func->offset) {
-
 				/* internal sibling call (without reloc) */
-				insn->call_dest = insn->jump_dest->func;
-				if (insn->call_dest->static_call_tramp) {
-					list_add_tail(&insn->call_node,
-						      &file->static_call_list);
-				}
+				add_call_dest(file, insn, insn->jump_dest->func, true);
 			}
 		}
 	}
@@ -1016,16 +1080,6 @@ static int add_jump_destinations(struct objtool_file *file)
 	return 0;
 }
 
-static void remove_insn_ops(struct instruction *insn)
-{
-	struct stack_op *op, *tmp;
-
-	list_for_each_entry_safe(op, tmp, &insn->stack_ops, list) {
-		list_del(&op->list);
-		free(op);
-	}
-}
-
 static struct symbol *find_call_destination(struct section *sec, unsigned long offset)
 {
 	struct symbol *call_dest;
@@ -1044,6 +1098,7 @@ static int add_call_destinations(struct objtool_file *file)
 {
 	struct instruction *insn;
 	unsigned long dest_off;
+	struct symbol *dest;
 	struct reloc *reloc;
 
 	for_each_insn(file, insn) {
@@ -1053,7 +1108,9 @@ static int add_call_destinations(struct objtool_file *file)
 		reloc = insn_reloc(file, insn);
 		if (!reloc) {
 			dest_off = arch_jump_destination(insn);
-			insn->call_dest = find_call_destination(insn->sec, dest_off);
+			dest = find_call_destination(insn->sec, dest_off);
+
+			add_call_dest(file, insn, dest, false);
 
 			if (insn->ignore)
 				continue;
@@ -1071,9 +1128,8 @@ static int add_call_destinations(struct objtool_file *file)
 
 		} else if (reloc->sym->type == STT_SECTION) {
 			dest_off = arch_dest_reloc_offset(reloc->addend);
-			insn->call_dest = find_call_destination(reloc->sym->sec,
-								dest_off);
-			if (!insn->call_dest) {
+			dest = find_call_destination(reloc->sym->sec, dest_off);
+			if (!dest) {
 				WARN_FUNC("can't find call dest symbol at %s+0x%lx",
 					  insn->sec, insn->offset,
 					  reloc->sym->sec->name,
@@ -1081,6 +1137,8 @@ static int add_call_destinations(struct objtool_file *file)
 				return -1;
 			}
 
+			add_call_dest(file, insn, dest, false);
+
 		} else if (arch_is_retpoline(reloc->sym)) {
 			/*
 			 * Retpoline calls are really dynamic calls in
@@ -1096,55 +1154,7 @@ static int add_call_destinations(struct objtool_file *file)
 			continue;
 
 		} else
-			insn->call_dest = reloc->sym;
-
-		if (insn->call_dest && insn->call_dest->static_call_tramp) {
-			list_add_tail(&insn->call_node,
-				      &file->static_call_list);
-		}
-
-		/*
-		 * Many compilers cannot disable KCOV with a function attribute
-		 * so they need a little help, NOP out any KCOV calls from noinstr
-		 * text.
-		 */
-		if (insn->sec->noinstr &&
-		    !strncmp(insn->call_dest->name, "__sanitizer_cov_", 16)) {
-			if (reloc) {
-				reloc->type = R_NONE;
-				elf_write_reloc(file->elf, reloc);
-			}
-
-			elf_write_insn(file->elf, insn->sec,
-				       insn->offset, insn->len,
-				       arch_nop_insn(insn->len));
-			insn->type = INSN_NOP;
-		}
-
-		if (mcount && !strcmp(insn->call_dest->name, "__fentry__")) {
-			if (reloc) {
-				reloc->type = R_NONE;
-				elf_write_reloc(file->elf, reloc);
-			}
-
-			elf_write_insn(file->elf, insn->sec,
-				       insn->offset, insn->len,
-				       arch_nop_insn(insn->len));
-
-			insn->type = INSN_NOP;
-
-			list_add_tail(&insn->mcount_loc_node,
-				      &file->mcount_loc_list);
-		}
-
-		/*
-		 * Whatever stack impact regular CALLs have, should be undone
-		 * by the RETURN of the called function.
-		 *
-		 * Annotated intra-function calls retain the stack_ops but
-		 * are converted to JUMP, see read_intra_function_calls().
-		 */
-		remove_insn_ops(insn);
+			add_call_dest(file, insn, reloc->sym, false);
 	}
 
 	return 0;
diff --git a/tools/objtool/include/objtool/arch.h b/tools/objtool/include/objtool/arch.h
index a5ab682..6f482ae 100644
--- a/tools/objtool/include/objtool/arch.h
+++ b/tools/objtool/include/objtool/arch.h
@@ -82,6 +82,7 @@ unsigned long arch_jump_destination(struct instruction *insn);
 unsigned long arch_dest_reloc_offset(int addend);
 
 const char *arch_nop_insn(int len);
+const char *arch_ret_insn(int len);
 
 int arch_decode_hint_reg(u8 sp_reg, int *base);
 

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] objtool: Introduce CFI hash
  2021-06-24  9:41 ` [PATCH v2 02/24] objtool: Introduce CFI hash Peter Zijlstra
  2021-06-30 12:45   ` Miroslav Benes
  2021-08-20 22:27   ` Josh Poimboeuf
@ 2021-09-15 15:49   ` tip-bot2 for Peter Zijlstra
  2 siblings, 0 replies; 101+ messages in thread
From: tip-bot2 for Peter Zijlstra @ 2021-09-15 15:49 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: Andi Kleen, Peter Zijlstra (Intel), x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     8b946cc38e063f0f7bb67789478c38f6d7d457c9
Gitweb:        https://git.kernel.org/tip/8b946cc38e063f0f7bb67789478c38f6d7d457c9
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Thu, 24 Jun 2021 11:41:01 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Wed, 15 Sep 2021 15:51:45 +02:00

objtool: Introduce CFI hash

Andi reported that objtool on vmlinux.o consumes more memory than his
system has, leading to horrific performance.

This is in part because we keep a struct instruction for every
instruction in the file in-memory. Shrink struct instruction by
removing the CFI state (which includes full register state) from it
and demand allocating it.

Given most instructions don't actually change CFI state, there's lots
of repetition there, so add a hash table to find previous CFI
instances.

Reduces memory consumption (and runtime) for processing an
x86_64-allyesconfig:

  pre:  4:40.84 real,   143.99 user,    44.18 sys,      30624988 mem
  post: 2:14.61 real,   108.58 user,    25.04 sys,      16396184 mem

Suggested-by: Andi Kleen <andi@firstfloor.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/r/20210624095147.756759107@infradead.org
---
 tools/objtool/arch/x86/decode.c       |  20 +--
 tools/objtool/check.c                 | 154 ++++++++++++++++++++++---
 tools/objtool/include/objtool/arch.h  |   2 +-
 tools/objtool/include/objtool/cfi.h   |   2 +-
 tools/objtool/include/objtool/check.h |   2 +-
 tools/objtool/orc_gen.c               |  15 +-
 6 files changed, 160 insertions(+), 35 deletions(-)

diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c
index bc82105..3435a32 100644
--- a/tools/objtool/arch/x86/decode.c
+++ b/tools/objtool/arch/x86/decode.c
@@ -779,34 +779,32 @@ int arch_rewrite_retpolines(struct objtool_file *file)
 	return 0;
 }
 
-int arch_decode_hint_reg(struct instruction *insn, u8 sp_reg)
+int arch_decode_hint_reg(u8 sp_reg, int *base)
 {
-	struct cfi_reg *cfa = &insn->cfi.cfa;
-
 	switch (sp_reg) {
 	case ORC_REG_UNDEFINED:
-		cfa->base = CFI_UNDEFINED;
+		*base = CFI_UNDEFINED;
 		break;
 	case ORC_REG_SP:
-		cfa->base = CFI_SP;
+		*base = CFI_SP;
 		break;
 	case ORC_REG_BP:
-		cfa->base = CFI_BP;
+		*base = CFI_BP;
 		break;
 	case ORC_REG_SP_INDIRECT:
-		cfa->base = CFI_SP_INDIRECT;
+		*base = CFI_SP_INDIRECT;
 		break;
 	case ORC_REG_R10:
-		cfa->base = CFI_R10;
+		*base = CFI_R10;
 		break;
 	case ORC_REG_R13:
-		cfa->base = CFI_R13;
+		*base = CFI_R13;
 		break;
 	case ORC_REG_DI:
-		cfa->base = CFI_DI;
+		*base = CFI_DI;
 		break;
 	case ORC_REG_DX:
-		cfa->base = CFI_DX;
+		*base = CFI_DX;
 		break;
 	default:
 		return -1;
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 0e3981d..d9f3273 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -5,6 +5,7 @@
 
 #include <string.h>
 #include <stdlib.h>
+#include <sys/mman.h>
 
 #include <arch/elf.h>
 #include <objtool/builtin.h>
@@ -26,7 +27,11 @@ struct alternative {
 	bool skip_orig;
 };
 
-struct cfi_init_state initial_func_cfi;
+static unsigned long nr_cfi, nr_cfi_reused, nr_cfi_cache;
+
+static struct cfi_init_state initial_func_cfi;
+static struct cfi_state init_cfi;
+static struct cfi_state func_cfi;
 
 struct instruction *find_insn(struct objtool_file *file,
 			      struct section *sec, unsigned long offset)
@@ -266,6 +271,78 @@ static void init_insn_state(struct insn_state *state, struct section *sec)
 		state->noinstr = sec->noinstr;
 }
 
+static struct cfi_state *cfi_alloc(void)
+{
+	struct cfi_state *cfi = calloc(sizeof(struct cfi_state), 1);
+	if (!cfi) {
+		WARN("calloc failed");
+		exit(1);
+	}
+	nr_cfi++;
+	return cfi;
+}
+
+static int cfi_bits;
+static struct hlist_head *cfi_hash;
+
+static inline bool cficmp(struct cfi_state *cfi1, struct cfi_state *cfi2)
+{
+	return memcmp((void *)cfi1 + sizeof(cfi1->hash),
+		      (void *)cfi2 + sizeof(cfi2->hash),
+		      sizeof(struct cfi_state) - sizeof(struct hlist_node));
+}
+
+static inline u32 cfi_key(struct cfi_state *cfi)
+{
+	return jhash((void *)cfi + sizeof(cfi->hash),
+		     sizeof(*cfi) - sizeof(cfi->hash), 0);
+}
+
+static struct cfi_state *cfi_hash_find_or_add(struct cfi_state *cfi)
+{
+	struct hlist_head *head = &cfi_hash[hash_min(cfi_key(cfi), cfi_bits)];
+	struct cfi_state *obj;
+
+	hlist_for_each_entry(obj, head, hash) {
+		if (!cficmp(cfi, obj)) {
+			nr_cfi_cache++;
+			return obj;
+		}
+	}
+
+	obj = cfi_alloc();
+	*obj = *cfi;
+	hlist_add_head(&obj->hash, head);
+
+	return obj;
+}
+
+static void cfi_hash_add(struct cfi_state *cfi)
+{
+	struct hlist_head *head = &cfi_hash[hash_min(cfi_key(cfi), cfi_bits)];
+
+	hlist_add_head(&cfi->hash, head);
+}
+
+static void *cfi_hash_alloc(unsigned long size)
+{
+	cfi_bits = max(10, ilog2(size));
+	cfi_hash = mmap(NULL, sizeof(struct hlist_head) << cfi_bits,
+			PROT_READ|PROT_WRITE,
+			MAP_PRIVATE|MAP_ANON, -1, 0);
+	if (cfi_hash == (void *)-1L) {
+		WARN("mmap fail cfi_hash");
+		cfi_hash = NULL;
+	}  else if (stats) {
+		printf("cfi_bits: %d\n", cfi_bits);
+	}
+
+	return cfi_hash;
+}
+
+static unsigned long nr_insns;
+static unsigned long nr_insns_visited;
+
 /*
  * Call the arch-specific instruction decoder for all the instructions and add
  * them to the global instruction list.
@@ -276,7 +353,6 @@ static int decode_instructions(struct objtool_file *file)
 	struct symbol *func;
 	unsigned long offset;
 	struct instruction *insn;
-	unsigned long nr_insns = 0;
 	int ret;
 
 	for_each_sec(file, sec) {
@@ -302,7 +378,6 @@ static int decode_instructions(struct objtool_file *file)
 			memset(insn, 0, sizeof(*insn));
 			INIT_LIST_HEAD(&insn->alts);
 			INIT_LIST_HEAD(&insn->stack_ops);
-			init_cfi_state(&insn->cfi);
 
 			insn->sec = sec;
 			insn->offset = offset;
@@ -1137,7 +1212,6 @@ static int handle_group_alt(struct objtool_file *file,
 		memset(nop, 0, sizeof(*nop));
 		INIT_LIST_HEAD(&nop->alts);
 		INIT_LIST_HEAD(&nop->stack_ops);
-		init_cfi_state(&nop->cfi);
 
 		nop->sec = special_alt->new_sec;
 		nop->offset = special_alt->new_off + special_alt->new_len;
@@ -1546,10 +1620,11 @@ static void set_func_state(struct cfi_state *state)
 
 static int read_unwind_hints(struct objtool_file *file)
 {
+	struct cfi_state cfi = init_cfi;
 	struct section *sec, *relocsec;
-	struct reloc *reloc;
 	struct unwind_hint *hint;
 	struct instruction *insn;
+	struct reloc *reloc;
 	int i;
 
 	sec = find_section_by_name(file->elf, ".discard.unwind_hints");
@@ -1587,19 +1662,24 @@ static int read_unwind_hints(struct objtool_file *file)
 		insn->hint = true;
 
 		if (hint->type == UNWIND_HINT_TYPE_FUNC) {
-			set_func_state(&insn->cfi);
+			insn->cfi = &func_cfi;
 			continue;
 		}
 
-		if (arch_decode_hint_reg(insn, hint->sp_reg)) {
+		if (insn->cfi)
+			cfi = *(insn->cfi);
+
+		if (arch_decode_hint_reg(hint->sp_reg, &cfi.cfa.base)) {
 			WARN_FUNC("unsupported unwind_hint sp base reg %d",
 				  insn->sec, insn->offset, hint->sp_reg);
 			return -1;
 		}
 
-		insn->cfi.cfa.offset = bswap_if_needed(hint->sp_offset);
-		insn->cfi.type = hint->type;
-		insn->cfi.end = hint->end;
+		cfi.cfa.offset = bswap_if_needed(hint->sp_offset);
+		cfi.type = hint->type;
+		cfi.end = hint->end;
+
+		insn->cfi = cfi_hash_find_or_add(&cfi);
 	}
 
 	return 0;
@@ -2453,13 +2533,18 @@ static int propagate_alt_cfi(struct objtool_file *file, struct instruction *insn
 	if (!insn->alt_group)
 		return 0;
 
+	if (!insn->cfi) {
+		WARN("CFI missing");
+		return -1;
+	}
+
 	alt_cfi = insn->alt_group->cfi;
 	group_off = insn->offset - insn->alt_group->first_insn->offset;
 
 	if (!alt_cfi[group_off]) {
-		alt_cfi[group_off] = &insn->cfi;
+		alt_cfi[group_off] = insn->cfi;
 	} else {
-		if (memcmp(alt_cfi[group_off], &insn->cfi, sizeof(struct cfi_state))) {
+		if (cficmp(alt_cfi[group_off], insn->cfi)) {
 			WARN_FUNC("stack layout conflict in alternatives",
 				  insn->sec, insn->offset);
 			return -1;
@@ -2510,9 +2595,14 @@ static int handle_insn_ops(struct instruction *insn,
 
 static bool insn_cfi_match(struct instruction *insn, struct cfi_state *cfi2)
 {
-	struct cfi_state *cfi1 = &insn->cfi;
+	struct cfi_state *cfi1 = insn->cfi;
 	int i;
 
+	if (!cfi1) {
+		WARN("CFI missing");
+		return false;
+	}
+
 	if (memcmp(&cfi1->cfa, &cfi2->cfa, sizeof(cfi1->cfa))) {
 
 		WARN_FUNC("stack state mismatch: cfa1=%d%+d cfa2=%d%+d",
@@ -2697,7 +2787,7 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
 			   struct instruction *insn, struct insn_state state)
 {
 	struct alternative *alt;
-	struct instruction *next_insn;
+	struct instruction *next_insn, *prev_insn = NULL;
 	struct section *sec;
 	u8 visited;
 	int ret;
@@ -2726,15 +2816,25 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
 
 			if (insn->visited & visited)
 				return 0;
+		} else {
+			nr_insns_visited++;
 		}
 
 		if (state.noinstr)
 			state.instr += insn->instr;
 
-		if (insn->hint)
-			state.cfi = insn->cfi;
-		else
-			insn->cfi = state.cfi;
+		if (insn->hint) {
+			state.cfi = *insn->cfi;
+		} else {
+			/* XXX track if we actually changed state.cfi */
+
+			if (prev_insn && !cficmp(prev_insn->cfi, &state.cfi)) {
+				insn->cfi = prev_insn->cfi;
+				nr_cfi_reused++;
+			} else {
+				insn->cfi = cfi_hash_find_or_add(&state.cfi);
+			}
+		}
 
 		insn->visited |= visited;
 
@@ -2884,6 +2984,7 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
 			return 1;
 		}
 
+		prev_insn = insn;
 		insn = next_insn;
 	}
 
@@ -3139,10 +3240,20 @@ int check(struct objtool_file *file)
 	int ret, warnings = 0;
 
 	arch_initial_func_cfi_state(&initial_func_cfi);
+	init_cfi_state(&init_cfi);
+	init_cfi_state(&func_cfi);
+	set_func_state(&func_cfi);
+
+	if (!cfi_hash_alloc(1UL << (file->elf->symbol_bits - 3)))
+		goto out;
+
+	cfi_hash_add(&init_cfi);
+	cfi_hash_add(&func_cfi);
 
 	ret = decode_sections(file);
 	if (ret < 0)
 		goto out;
+
 	warnings += ret;
 
 	if (list_empty(&file->insn_list))
@@ -3193,6 +3304,13 @@ int check(struct objtool_file *file)
 		warnings += ret;
 	}
 
+	if (stats) {
+		printf("nr_insns_visited: %ld\n", nr_insns_visited);
+		printf("nr_cfi: %ld\n", nr_cfi);
+		printf("nr_cfi_reused: %ld\n", nr_cfi_reused);
+		printf("nr_cfi_cache: %ld\n", nr_cfi_cache);
+	}
+
 out:
 	/*
 	 *  For now, don't fail the kernel build on fatal warnings.  These
diff --git a/tools/objtool/include/objtool/arch.h b/tools/objtool/include/objtool/arch.h
index 062bb6e..a5ab682 100644
--- a/tools/objtool/include/objtool/arch.h
+++ b/tools/objtool/include/objtool/arch.h
@@ -83,7 +83,7 @@ unsigned long arch_dest_reloc_offset(int addend);
 
 const char *arch_nop_insn(int len);
 
-int arch_decode_hint_reg(struct instruction *insn, u8 sp_reg);
+int arch_decode_hint_reg(u8 sp_reg, int *base);
 
 bool arch_is_retpoline(struct symbol *sym);
 
diff --git a/tools/objtool/include/objtool/cfi.h b/tools/objtool/include/objtool/cfi.h
index fd5cb0b..f11d1ac 100644
--- a/tools/objtool/include/objtool/cfi.h
+++ b/tools/objtool/include/objtool/cfi.h
@@ -7,6 +7,7 @@
 #define _OBJTOOL_CFI_H
 
 #include <arch/cfi_regs.h>
+#include <linux/list.h>
 
 #define CFI_UNDEFINED		-1
 #define CFI_CFA			-2
@@ -24,6 +25,7 @@ struct cfi_init_state {
 };
 
 struct cfi_state {
+	struct hlist_node hash; /* must be first, cficmp() */
 	struct cfi_reg regs[CFI_NUM_REGS];
 	struct cfi_reg vals[CFI_NUM_REGS];
 	struct cfi_reg cfa;
diff --git a/tools/objtool/include/objtool/check.h b/tools/objtool/include/objtool/check.h
index 56d50bc..07e99c2 100644
--- a/tools/objtool/include/objtool/check.h
+++ b/tools/objtool/include/objtool/check.h
@@ -60,7 +60,7 @@ struct instruction {
 	struct list_head alts;
 	struct symbol *func;
 	struct list_head stack_ops;
-	struct cfi_state cfi;
+	struct cfi_state *cfi;
 };
 
 static inline bool is_static_jump(struct instruction *insn)
diff --git a/tools/objtool/orc_gen.c b/tools/objtool/orc_gen.c
index dc9b7dd..ddacb42 100644
--- a/tools/objtool/orc_gen.c
+++ b/tools/objtool/orc_gen.c
@@ -13,13 +13,19 @@
 #include <objtool/warn.h>
 #include <objtool/endianness.h>
 
-static int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi)
+static int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi,
+			  struct instruction *insn)
 {
-	struct instruction *insn = container_of(cfi, struct instruction, cfi);
 	struct cfi_reg *bp = &cfi->regs[CFI_BP];
 
 	memset(orc, 0, sizeof(*orc));
 
+	if (!cfi) {
+		orc->end = 0;
+		orc->sp_reg = ORC_REG_UNDEFINED;
+		return 0;
+	}
+
 	orc->end = cfi->end;
 
 	if (cfi->cfa.base == CFI_UNDEFINED) {
@@ -162,7 +168,7 @@ int orc_create(struct objtool_file *file)
 			int i;
 
 			if (!alt_group) {
-				if (init_orc_entry(&orc, &insn->cfi))
+				if (init_orc_entry(&orc, insn->cfi, insn))
 					return -1;
 				if (!memcmp(&prev_orc, &orc, sizeof(orc)))
 					continue;
@@ -186,7 +192,8 @@ int orc_create(struct objtool_file *file)
 				struct cfi_state *cfi = alt_group->cfi[i];
 				if (!cfi)
 					continue;
-				if (init_orc_entry(&orc, cfi))
+				/* errors are reported on the original insn */
+				if (init_orc_entry(&orc, cfi, insn))
 					return -1;
 				if (!memcmp(&prev_orc, &orc, sizeof(orc)))
 					continue;

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] x86/xen: Move hypercall_page to top of the file
  2021-08-20 19:31     ` Josh Poimboeuf
  2021-08-23  8:40       ` Juergen Gross
@ 2021-09-15 15:49       ` tip-bot2 for Josh Poimboeuf
  1 sibling, 0 replies; 101+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2021-09-15 15:49 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Josh Poimboeuf, Peter Zijlstra (Intel), Juergen Gross, x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     b7b205c3a0bc2b51f83cb793178ccbc12addf275
Gitweb:        https://git.kernel.org/tip/b7b205c3a0bc2b51f83cb793178ccbc12addf275
Author:        Josh Poimboeuf <jpoimboe@redhat.com>
AuthorDate:    Fri, 20 Aug 2021 12:31:07 -07:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Wed, 15 Sep 2021 15:51:44 +02:00

x86/xen: Move hypercall_page to top of the file

Because hypercall_page is page-aligned, the assembler inexplicably adds
an unreachable jump from after the end of the previous code to the
beginning of hypercall_page.

That confuses objtool, understandably.  It also creates significant text
fragmentation.  As a result, much of the object file is wasted text
(nops).

Move hypercall_page to the beginning of the file to both prevent the
text fragmentation and avoid the dead jump instruction.

$ size /tmp/head_64.before.o /tmp/head_64.after.o
   text	   data	    bss	    dec	    hex	filename
  10924	 307252	   4096	 322272	  4eae0	/tmp/head_64.before.o
   6823	 307252	   4096	 318171	  4dadb	/tmp/head_64.after.o

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Juergen Gross <jgross@suse.com>
Link: https://lkml.kernel.org/r/20210820193107.omvshmsqbpxufzkc@treble
---
 arch/x86/xen/xen-head.S | 34 +++++++++++++++++-----------------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/arch/x86/xen/xen-head.S b/arch/x86/xen/xen-head.S
index cb6538a..488944d 100644
--- a/arch/x86/xen/xen-head.S
+++ b/arch/x86/xen/xen-head.S
@@ -20,6 +20,23 @@
 #include <xen/interface/xen-mca.h>
 #include <asm/xen/interface.h>
 
+.pushsection .text
+	.balign PAGE_SIZE
+SYM_CODE_START(hypercall_page)
+	.rept (PAGE_SIZE / 32)
+		UNWIND_HINT_FUNC
+		.skip 31, 0x90
+		ret
+	.endr
+
+#define HYPERCALL(n) \
+	.equ xen_hypercall_##n, hypercall_page + __HYPERVISOR_##n * 32; \
+	.type xen_hypercall_##n, @function; .size xen_hypercall_##n, 32
+#include <asm/xen-hypercalls.h>
+#undef HYPERCALL
+SYM_CODE_END(hypercall_page)
+.popsection
+
 #ifdef CONFIG_XEN_PV
 	__INIT
 SYM_CODE_START(startup_xen)
@@ -64,23 +81,6 @@ SYM_CODE_END(asm_cpu_bringup_and_idle)
 #endif
 #endif
 
-.pushsection .text
-	.balign PAGE_SIZE
-SYM_CODE_START(hypercall_page)
-	.rept (PAGE_SIZE / 32)
-		UNWIND_HINT_FUNC
-		.skip 31, 0x90
-		ret
-	.endr
-
-#define HYPERCALL(n) \
-	.equ xen_hypercall_##n, hypercall_page + __HYPERVISOR_##n * 32; \
-	.type xen_hypercall_##n, @function; .size xen_hypercall_##n, 32
-#include <asm/xen-hypercalls.h>
-#undef HYPERCALL
-SYM_CODE_END(hypercall_page)
-.popsection
-
 	ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS,       .asciz "linux")
 	ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION,  .asciz "2.6")
 	ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION,    .asciz "xen-3.0")

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] x86/xen: Mark cpu_bringup_and_idle() as dead_end_function
  2021-06-24  9:41 ` [PATCH v2 01/24] x86/xen: Mark cpu_bringup_and_idle() as dead_end_function Peter Zijlstra
                     ` (2 preceding siblings ...)
  2021-08-20 19:22   ` Josh Poimboeuf
@ 2021-09-15 15:49   ` tip-bot2 for Peter Zijlstra
  3 siblings, 0 replies; 101+ messages in thread
From: tip-bot2 for Peter Zijlstra @ 2021-09-15 15:49 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Peter Zijlstra (Intel), Juergen Gross, Miroslav Benes, x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     9af9dcf11bda3e2c0e24c1acaacb8685ad974e93
Gitweb:        https://git.kernel.org/tip/9af9dcf11bda3e2c0e24c1acaacb8685ad974e93
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Thu, 24 Jun 2021 11:41:00 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Wed, 15 Sep 2021 15:51:44 +02:00

x86/xen: Mark cpu_bringup_and_idle() as dead_end_function

The asm_cpu_bringup_and_idle() function is required to push the return
value on the stack in order to make ORC happy, but the only reason
objtool doesn't complain is because of a happy accident.

The thing is that asm_cpu_bringup_and_idle() doesn't return, so
validate_branch() never terminates and falls through to the next
function, which in the normal case is the hypercall_page. And that, as
it happens, is 4095 NOPs and a RET.

Make asm_cpu_bringup_and_idle() terminate on it's own, by making the
function it calls as a dead-end. This way we no longer rely on what
code happens to come after.

Fixes: c3881eb58d56 ("x86/xen: Make the secondary CPU idle tasks reliable")
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Miroslav Benes <mbenes@suse.cz>
Link: https://lore.kernel.org/r/20210624095147.693801717@infradead.org
---
 tools/objtool/check.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index e5947fb..0e3981d 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -173,6 +173,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
 		"rewind_stack_do_exit",
 		"kunit_try_catch_throw",
 		"xen_start_kernel",
+		"cpu_bringup_and_idle",
 	};
 
 	if (!func)

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] objtool: Support pv_opsindirect calls for noinstr
  2021-06-24  9:41 ` [PATCH v2 24/24] objtool: Support pv_opsindirect calls for noinstr Peter Zijlstra
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
@ 2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
  1 sibling, 0 replies; 101+ messages in thread
From: tip-bot2 for Peter Zijlstra @ 2021-09-17 12:58 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: Peter Zijlstra (Intel), x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     db2b0c5d7b6f19b3c2cab08c531b65342eb5252b
Gitweb:        https://git.kernel.org/tip/db2b0c5d7b6f19b3c2cab08c531b65342eb5252b
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Thu, 24 Jun 2021 11:41:23 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Fri, 17 Sep 2021 13:20:26 +02:00

objtool: Support pv_opsindirect calls for noinstr

Normally objtool will now follow indirect calls; there is no need.

However, this becomes a problem with noinstr validation; if there's an
indirect call from noinstr code, we very much need to know it is to
another noinstr function. Luckily there aren't many indirect calls in
entry code with the obvious exception of paravirt. As such, noinstr
validation didn't work with paravirt kernels.

In order to track pv_ops[] call targets, objtool reads the static
pv_ops[] tables as well as direct assignments to the pv_ops[] array,
provided the compiler makes them a single instruction like:

  bf87:       48 c7 05 00 00 00 00 00 00 00 00        movq   $0x0,0x0(%rip)
    bf92 <xen_init_spinlocks+0x5f>
    bf8a: R_X86_64_PC32     pv_ops+0x268

There are, as of yet, no warnings for when this goes wrong :/

Using the functions found with the above means, all pv_ops[] calls are
now subject to noinstr validation.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/r/20210624095149.118815755@infradead.org
---
 lib/Kconfig.debug                       |   2 +-
 tools/objtool/arch/x86/decode.c         |  34 ++++-
 tools/objtool/check.c                   | 151 +++++++++++++++++++++--
 tools/objtool/include/objtool/arch.h    |   2 +-
 tools/objtool/include/objtool/elf.h     |   1 +-
 tools/objtool/include/objtool/objtool.h |   9 +-
 tools/objtool/objtool.c                 |  22 +++-
 7 files changed, 208 insertions(+), 13 deletions(-)

diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index ed4a31e..63a4735 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -458,7 +458,7 @@ config STACK_VALIDATION
 
 config VMLINUX_VALIDATION
 	bool
-	depends on STACK_VALIDATION && DEBUG_ENTRY && !PARAVIRT
+	depends on STACK_VALIDATION && DEBUG_ENTRY
 	default y
 
 config VMLINUX_MAP
diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c
index 340a3dc..3172983 100644
--- a/tools/objtool/arch/x86/decode.c
+++ b/tools/objtool/arch/x86/decode.c
@@ -20,6 +20,7 @@
 #include <objtool/arch.h>
 #include <objtool/warn.h>
 #include <objtool/endianness.h>
+#include <objtool/builtin.h>
 #include <arch/elf.h>
 
 static int is_x86_64(const struct elf *elf)
@@ -102,12 +103,13 @@ unsigned long arch_jump_destination(struct instruction *insn)
 #define rm_is_mem(reg)	(mod_is_mem() && !is_RIP() && rm_is(reg))
 #define rm_is_reg(reg)	(mod_is_reg() && modrm_rm == (reg))
 
-int arch_decode_instruction(const struct elf *elf, const struct section *sec,
+int arch_decode_instruction(struct objtool_file *file, const struct section *sec,
 			    unsigned long offset, unsigned int maxlen,
 			    unsigned int *len, enum insn_type *type,
 			    unsigned long *immediate,
 			    struct list_head *ops_list)
 {
+	const struct elf *elf = file->elf;
 	struct insn insn;
 	int x86_64, ret;
 	unsigned char op1, op2,
@@ -544,6 +546,36 @@ int arch_decode_instruction(const struct elf *elf, const struct section *sec,
 		*type = INSN_RETURN;
 		break;
 
+	case 0xc7: /* mov imm, r/m */
+		if (!noinstr)
+			break;
+
+		if (insn.length == 3+4+4 && !strncmp(sec->name, ".init.text", 10)) {
+			struct reloc *immr, *disp;
+			struct symbol *func;
+			int idx;
+
+			immr = find_reloc_by_dest(elf, (void *)sec, offset+3);
+			disp = find_reloc_by_dest(elf, (void *)sec, offset+7);
+
+			if (!immr || strcmp(immr->sym->name, "pv_ops"))
+				break;
+
+			idx = (immr->addend + 8) / sizeof(void *);
+
+			func = disp->sym;
+			if (disp->sym->type == STT_SECTION)
+				func = find_symbol_by_offset(disp->sym->sec, disp->addend);
+			if (!func) {
+				WARN("no func for pv_ops[]");
+				return -1;
+			}
+
+			objtool_pv_add(file, idx, func);
+		}
+
+		break;
+
 	case 0xcf: /* iret */
 		/*
 		 * Handle sync_core(), which has an IRET to self.
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index c6f206f..84e59a9 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -382,7 +382,7 @@ static int decode_instructions(struct objtool_file *file)
 			insn->sec = sec;
 			insn->offset = offset;
 
-			ret = arch_decode_instruction(file->elf, sec, offset,
+			ret = arch_decode_instruction(file, sec, offset,
 						      sec->len - offset,
 						      &insn->len, &insn->type,
 						      &insn->immediate,
@@ -420,6 +420,82 @@ err:
 	return ret;
 }
 
+/*
+ * Read the pv_ops[] .data table to find the static initialized values.
+ */
+static int add_pv_ops(struct objtool_file *file, const char *symname)
+{
+	struct symbol *sym, *func;
+	unsigned long off, end;
+	struct reloc *rel;
+	int idx;
+
+	sym = find_symbol_by_name(file->elf, symname);
+	if (!sym)
+		return 0;
+
+	off = sym->offset;
+	end = off + sym->len;
+	for (;;) {
+		rel = find_reloc_by_dest_range(file->elf, sym->sec, off, end - off);
+		if (!rel)
+			break;
+
+		func = rel->sym;
+		if (func->type == STT_SECTION)
+			func = find_symbol_by_offset(rel->sym->sec, rel->addend);
+
+		idx = (rel->offset - sym->offset) / sizeof(unsigned long);
+
+		objtool_pv_add(file, idx, func);
+
+		off = rel->offset + 1;
+		if (off > end)
+			break;
+	}
+
+	return 0;
+}
+
+/*
+ * Allocate and initialize file->pv_ops[].
+ */
+static int init_pv_ops(struct objtool_file *file)
+{
+	static const char *pv_ops_tables[] = {
+		"pv_ops",
+		"xen_cpu_ops",
+		"xen_irq_ops",
+		"xen_mmu_ops",
+		NULL,
+	};
+	const char *pv_ops;
+	struct symbol *sym;
+	int idx, nr;
+
+	if (!noinstr)
+		return 0;
+
+	file->pv_ops = NULL;
+
+	sym = find_symbol_by_name(file->elf, "pv_ops");
+	if (!sym)
+		return 0;
+
+	nr = sym->len / sizeof(unsigned long);
+	file->pv_ops = calloc(sizeof(struct pv_state), nr);
+	if (!file->pv_ops)
+		return -1;
+
+	for (idx = 0; idx < nr; idx++)
+		INIT_LIST_HEAD(&file->pv_ops[idx].targets);
+
+	for (idx = 0; (pv_ops = pv_ops_tables[idx]); idx++)
+		add_pv_ops(file, pv_ops);
+
+	return 0;
+}
+
 static struct instruction *find_last_insn(struct objtool_file *file,
 					  struct section *sec)
 {
@@ -893,6 +969,9 @@ static struct reloc *insn_reloc(struct objtool_file *file, struct instruction *i
 		return NULL;
 
 	if (!insn->reloc) {
+		if (!file)
+			return NULL;
+
 		insn->reloc = find_reloc_by_dest_range(file->elf, insn->sec,
 						       insn->offset, insn->len);
 		if (!insn->reloc) {
@@ -1882,6 +1961,10 @@ static int decode_sections(struct objtool_file *file)
 
 	mark_rodata(file);
 
+	ret = init_pv_ops(file);
+	if (ret)
+		return ret;
+
 	ret = decode_instructions(file);
 	if (ret)
 		return ret;
@@ -2663,20 +2746,64 @@ static inline bool func_uaccess_safe(struct symbol *func)
 
 static inline const char *call_dest_name(struct instruction *insn)
 {
+	static char pvname[16];
+	struct reloc *rel;
+	int idx;
+
 	if (insn->call_dest)
 		return insn->call_dest->name;
 
+	rel = insn_reloc(NULL, insn);
+	if (rel && !strcmp(rel->sym->name, "pv_ops")) {
+		idx = (rel->addend / sizeof(void *));
+		snprintf(pvname, sizeof(pvname), "pv_ops[%d]", idx);
+		return pvname;
+	}
+
 	return "{dynamic}";
 }
 
-static inline bool noinstr_call_dest(struct symbol *func)
+static bool pv_call_dest(struct objtool_file *file, struct instruction *insn)
+{
+	struct symbol *target;
+	struct reloc *rel;
+	int idx;
+
+	rel = insn_reloc(file, insn);
+	if (!rel || strcmp(rel->sym->name, "pv_ops"))
+		return false;
+
+	idx = (arch_dest_reloc_offset(rel->addend) / sizeof(void *));
+
+	if (file->pv_ops[idx].clean)
+		return true;
+
+	file->pv_ops[idx].clean = true;
+
+	list_for_each_entry(target, &file->pv_ops[idx].targets, pv_target) {
+		if (!target->sec->noinstr) {
+			WARN("pv_ops[%d]: %s", idx, target->name);
+			file->pv_ops[idx].clean = false;
+		}
+	}
+
+	return file->pv_ops[idx].clean;
+}
+
+static inline bool noinstr_call_dest(struct objtool_file *file,
+				     struct instruction *insn,
+				     struct symbol *func)
 {
 	/*
 	 * We can't deal with indirect function calls at present;
 	 * assume they're instrumented.
 	 */
-	if (!func)
+	if (!func) {
+		if (file->pv_ops)
+			return pv_call_dest(file, insn);
+
 		return false;
+	}
 
 	/*
 	 * If the symbol is from a noinstr section; we good.
@@ -2695,10 +2822,12 @@ static inline bool noinstr_call_dest(struct symbol *func)
 	return false;
 }
 
-static int validate_call(struct instruction *insn, struct insn_state *state)
+static int validate_call(struct objtool_file *file,
+			 struct instruction *insn,
+			 struct insn_state *state)
 {
 	if (state->noinstr && state->instr <= 0 &&
-	    !noinstr_call_dest(insn->call_dest)) {
+	    !noinstr_call_dest(file, insn, insn->call_dest)) {
 		WARN_FUNC("call to %s() leaves .noinstr.text section",
 				insn->sec, insn->offset, call_dest_name(insn));
 		return 1;
@@ -2719,7 +2848,9 @@ static int validate_call(struct instruction *insn, struct insn_state *state)
 	return 0;
 }
 
-static int validate_sibling_call(struct instruction *insn, struct insn_state *state)
+static int validate_sibling_call(struct objtool_file *file,
+				 struct instruction *insn,
+				 struct insn_state *state)
 {
 	if (has_modified_stack_frame(insn, state)) {
 		WARN_FUNC("sibling call from callable instruction with modified stack frame",
@@ -2727,7 +2858,7 @@ static int validate_sibling_call(struct instruction *insn, struct insn_state *st
 		return 1;
 	}
 
-	return validate_call(insn, state);
+	return validate_call(file, insn, state);
 }
 
 static int validate_return(struct symbol *func, struct instruction *insn, struct insn_state *state)
@@ -2880,7 +3011,7 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
 
 		case INSN_CALL:
 		case INSN_CALL_DYNAMIC:
-			ret = validate_call(insn, &state);
+			ret = validate_call(file, insn, &state);
 			if (ret)
 				return ret;
 
@@ -2899,7 +3030,7 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
 		case INSN_JUMP_CONDITIONAL:
 		case INSN_JUMP_UNCONDITIONAL:
 			if (is_sibling_call(insn)) {
-				ret = validate_sibling_call(insn, &state);
+				ret = validate_sibling_call(file, insn, &state);
 				if (ret)
 					return ret;
 
@@ -2921,7 +3052,7 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
 		case INSN_JUMP_DYNAMIC:
 		case INSN_JUMP_DYNAMIC_CONDITIONAL:
 			if (is_sibling_call(insn)) {
-				ret = validate_sibling_call(insn, &state);
+				ret = validate_sibling_call(file, insn, &state);
 				if (ret)
 					return ret;
 			}
diff --git a/tools/objtool/include/objtool/arch.h b/tools/objtool/include/objtool/arch.h
index 6f482ae..589ff58 100644
--- a/tools/objtool/include/objtool/arch.h
+++ b/tools/objtool/include/objtool/arch.h
@@ -69,7 +69,7 @@ struct instruction;
 
 void arch_initial_func_cfi_state(struct cfi_init_state *state);
 
-int arch_decode_instruction(const struct elf *elf, const struct section *sec,
+int arch_decode_instruction(struct objtool_file *file, const struct section *sec,
 			    unsigned long offset, unsigned int maxlen,
 			    unsigned int *len, enum insn_type *type,
 			    unsigned long *immediate,
diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/objtool/elf.h
index e343950..c3857fa 100644
--- a/tools/objtool/include/objtool/elf.h
+++ b/tools/objtool/include/objtool/elf.h
@@ -57,6 +57,7 @@ struct symbol {
 	struct symbol *pfunc, *cfunc, *alias;
 	bool uaccess_safe;
 	bool static_call_tramp;
+	struct list_head pv_target;
 };
 
 struct reloc {
diff --git a/tools/objtool/include/objtool/objtool.h b/tools/objtool/include/objtool/objtool.h
index 24fa836..f99fbc6 100644
--- a/tools/objtool/include/objtool/objtool.h
+++ b/tools/objtool/include/objtool/objtool.h
@@ -14,6 +14,11 @@
 
 #define __weak __attribute__((weak))
 
+struct pv_state {
+	bool clean;
+	struct list_head targets;
+};
+
 struct objtool_file {
 	struct elf *elf;
 	struct list_head insn_list;
@@ -25,10 +30,14 @@ struct objtool_file {
 
 	unsigned long jl_short, jl_long;
 	unsigned long jl_nop_short, jl_nop_long;
+
+	struct pv_state *pv_ops;
 };
 
 struct objtool_file *objtool_open_read(const char *_objname);
 
+void objtool_pv_add(struct objtool_file *file, int idx, struct symbol *func);
+
 int check(struct objtool_file *file);
 int orc_dump(const char *objname);
 int orc_create(struct objtool_file *file);
diff --git a/tools/objtool/objtool.c b/tools/objtool/objtool.c
index e21db8b..c90c708 100644
--- a/tools/objtool/objtool.c
+++ b/tools/objtool/objtool.c
@@ -135,6 +135,28 @@ struct objtool_file *objtool_open_read(const char *_objname)
 	return &file;
 }
 
+void objtool_pv_add(struct objtool_file *f, int idx, struct symbol *func)
+{
+	if (!noinstr)
+		return;
+
+	if (!f->pv_ops) {
+		WARN("paravirt confusion");
+		return;
+	}
+
+	/*
+	 * These functions will be patched into native code,
+	 * see paravirt_patch().
+	 */
+	if (!strcmp(func->name, "_paravirt_nop") ||
+	    !strcmp(func->name, "_paravirt_ident_64"))
+		return;
+
+	list_add(&func->pv_target, &f->pv_ops[idx].targets);
+	f->pv_ops[idx].clean = false;
+}
+
 static void cmd_usage(void)
 {
 	unsigned int i, longest = 0;

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] x86/xen: Rework the xen_{cpu,irq,mmu}_opsarrays
  2021-06-24  9:41 ` [PATCH v2 23/24] x86/xen: Rework the xen_{cpu,irq,mmu}_ops[] arrays Peter Zijlstra
  2021-06-24 12:12   ` Juergen Gross
  2021-09-15 15:49   ` [tip: objtool/core] x86/xen: Rework the xen_{cpu,irq,mmu}_opsarrays tip-bot2 for Peter Zijlstra
@ 2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
  2 siblings, 0 replies; 101+ messages in thread
From: tip-bot2 for Peter Zijlstra @ 2021-09-17 12:58 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Peter Zijlstra (Intel), Juergen Gross, x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     1462eb381b4c27576a3e818bc9f918765d327fdf
Gitweb:        https://git.kernel.org/tip/1462eb381b4c27576a3e818bc9f918765d327fdf
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Thu, 24 Jun 2021 11:41:22 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Fri, 17 Sep 2021 13:20:26 +02:00

x86/xen: Rework the xen_{cpu,irq,mmu}_opsarrays

In order to allow objtool to make sense of all the various paravirt
functions, it needs to either parse whole pv_ops[] tables, or observe
individual assignments in the form:

  bf87:       48 c7 05 00 00 00 00 00 00 00 00        movq   $0x0,0x0(%rip)
    bf92 <xen_init_spinlocks+0x5f>
    bf8a: R_X86_64_PC32     pv_ops+0x268

As is, xen_cpu_ops[] is at offset +0 in pv_ops[] and could thus be
parsed as a 'normal' pv_ops[] table, however xen_irq_ops[] and
xen_mmu_ops[] are not.

Worse, both the latter two are compiled into the individual assignment
for by current GCC, but that's not something one can rely on.

Therefore, convert all three into full pv_ops[] tables. This has the
benefit of not needing to teach objtool about the offsets and
resulting in more conservative code-gen.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Juergen Gross <jgross@suse.com>
Link: https://lore.kernel.org/r/20210624095149.057262522@infradead.org
---
 arch/x86/xen/enlighten_pv.c | 66 +++++++++++++-------------
 arch/x86/xen/irq.c          | 17 ++++---
 arch/x86/xen/mmu_pv.c       | 90 ++++++++++++++++++------------------
 3 files changed, 90 insertions(+), 83 deletions(-)

diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c
index 2b1a8ba..6ed0af7 100644
--- a/arch/x86/xen/enlighten_pv.c
+++ b/arch/x86/xen/enlighten_pv.c
@@ -1050,52 +1050,54 @@ static const struct pv_info xen_info __initconst = {
 	.name = "Xen",
 };
 
-static const struct pv_cpu_ops xen_cpu_ops __initconst = {
-	.cpuid = xen_cpuid,
+static const typeof(pv_ops) xen_cpu_ops __initconst = {
+	.cpu = {
+		.cpuid = xen_cpuid,
 
-	.set_debugreg = xen_set_debugreg,
-	.get_debugreg = xen_get_debugreg,
+		.set_debugreg = xen_set_debugreg,
+		.get_debugreg = xen_get_debugreg,
 
-	.read_cr0 = xen_read_cr0,
-	.write_cr0 = xen_write_cr0,
+		.read_cr0 = xen_read_cr0,
+		.write_cr0 = xen_write_cr0,
 
-	.write_cr4 = xen_write_cr4,
+		.write_cr4 = xen_write_cr4,
 
-	.wbinvd = native_wbinvd,
+		.wbinvd = native_wbinvd,
 
-	.read_msr = xen_read_msr,
-	.write_msr = xen_write_msr,
+		.read_msr = xen_read_msr,
+		.write_msr = xen_write_msr,
 
-	.read_msr_safe = xen_read_msr_safe,
-	.write_msr_safe = xen_write_msr_safe,
+		.read_msr_safe = xen_read_msr_safe,
+		.write_msr_safe = xen_write_msr_safe,
 
-	.read_pmc = xen_read_pmc,
+		.read_pmc = xen_read_pmc,
 
-	.load_tr_desc = paravirt_nop,
-	.set_ldt = xen_set_ldt,
-	.load_gdt = xen_load_gdt,
-	.load_idt = xen_load_idt,
-	.load_tls = xen_load_tls,
-	.load_gs_index = xen_load_gs_index,
+		.load_tr_desc = paravirt_nop,
+		.set_ldt = xen_set_ldt,
+		.load_gdt = xen_load_gdt,
+		.load_idt = xen_load_idt,
+		.load_tls = xen_load_tls,
+		.load_gs_index = xen_load_gs_index,
 
-	.alloc_ldt = xen_alloc_ldt,
-	.free_ldt = xen_free_ldt,
+		.alloc_ldt = xen_alloc_ldt,
+		.free_ldt = xen_free_ldt,
 
-	.store_tr = xen_store_tr,
+		.store_tr = xen_store_tr,
 
-	.write_ldt_entry = xen_write_ldt_entry,
-	.write_gdt_entry = xen_write_gdt_entry,
-	.write_idt_entry = xen_write_idt_entry,
-	.load_sp0 = xen_load_sp0,
+		.write_ldt_entry = xen_write_ldt_entry,
+		.write_gdt_entry = xen_write_gdt_entry,
+		.write_idt_entry = xen_write_idt_entry,
+		.load_sp0 = xen_load_sp0,
 
 #ifdef CONFIG_X86_IOPL_IOPERM
-	.invalidate_io_bitmap = xen_invalidate_io_bitmap,
-	.update_io_bitmap = xen_update_io_bitmap,
+		.invalidate_io_bitmap = xen_invalidate_io_bitmap,
+		.update_io_bitmap = xen_update_io_bitmap,
 #endif
-	.io_delay = xen_io_delay,
+		.io_delay = xen_io_delay,
 
-	.start_context_switch = paravirt_start_context_switch,
-	.end_context_switch = xen_end_context_switch,
+		.start_context_switch = paravirt_start_context_switch,
+		.end_context_switch = xen_end_context_switch,
+	},
 };
 
 static void xen_restart(char *msg)
@@ -1231,7 +1233,7 @@ asmlinkage __visible void __init xen_start_kernel(void)
 
 	/* Install Xen paravirt ops */
 	pv_info = xen_info;
-	pv_ops.cpu = xen_cpu_ops;
+	pv_ops.cpu = xen_cpu_ops.cpu;
 	paravirt_iret = xen_iret;
 	xen_init_irq_ops();
 
diff --git a/arch/x86/xen/irq.c b/arch/x86/xen/irq.c
index 2f695b5..4fe387e 100644
--- a/arch/x86/xen/irq.c
+++ b/arch/x86/xen/irq.c
@@ -94,17 +94,20 @@ static void xen_halt(void)
 		xen_safe_halt();
 }
 
-static const struct pv_irq_ops xen_irq_ops __initconst = {
-	.save_fl = PV_CALLEE_SAVE(xen_save_fl),
-	.irq_disable = PV_CALLEE_SAVE(xen_irq_disable),
-	.irq_enable = PV_CALLEE_SAVE(xen_irq_enable),
+static const typeof(pv_ops) xen_irq_ops __initconst = {
+	.irq = {
 
-	.safe_halt = xen_safe_halt,
-	.halt = xen_halt,
+		.save_fl = PV_CALLEE_SAVE(xen_save_fl),
+		.irq_disable = PV_CALLEE_SAVE(xen_irq_disable),
+		.irq_enable = PV_CALLEE_SAVE(xen_irq_enable),
+
+		.safe_halt = xen_safe_halt,
+		.halt = xen_halt,
+	},
 };
 
 void __init xen_init_irq_ops(void)
 {
-	pv_ops.irq = xen_irq_ops;
+	pv_ops.irq = xen_irq_ops.irq;
 	x86_init.irqs.intr_init = xen_init_IRQ;
 }
diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c
index f3cafe5..b9a4f79 100644
--- a/arch/x86/xen/mmu_pv.c
+++ b/arch/x86/xen/mmu_pv.c
@@ -2076,67 +2076,69 @@ static void xen_leave_lazy_mmu(void)
 	preempt_enable();
 }
 
-static const struct pv_mmu_ops xen_mmu_ops __initconst = {
-	.read_cr2 = __PV_IS_CALLEE_SAVE(xen_read_cr2),
-	.write_cr2 = xen_write_cr2,
+static const typeof(pv_ops) xen_mmu_ops __initconst = {
+	.mmu = {
+		.read_cr2 = __PV_IS_CALLEE_SAVE(xen_read_cr2),
+		.write_cr2 = xen_write_cr2,
 
-	.read_cr3 = xen_read_cr3,
-	.write_cr3 = xen_write_cr3_init,
+		.read_cr3 = xen_read_cr3,
+		.write_cr3 = xen_write_cr3_init,
 
-	.flush_tlb_user = xen_flush_tlb,
-	.flush_tlb_kernel = xen_flush_tlb,
-	.flush_tlb_one_user = xen_flush_tlb_one_user,
-	.flush_tlb_multi = xen_flush_tlb_multi,
-	.tlb_remove_table = tlb_remove_table,
+		.flush_tlb_user = xen_flush_tlb,
+		.flush_tlb_kernel = xen_flush_tlb,
+		.flush_tlb_one_user = xen_flush_tlb_one_user,
+		.flush_tlb_multi = xen_flush_tlb_multi,
+		.tlb_remove_table = tlb_remove_table,
 
-	.pgd_alloc = xen_pgd_alloc,
-	.pgd_free = xen_pgd_free,
+		.pgd_alloc = xen_pgd_alloc,
+		.pgd_free = xen_pgd_free,
 
-	.alloc_pte = xen_alloc_pte_init,
-	.release_pte = xen_release_pte_init,
-	.alloc_pmd = xen_alloc_pmd_init,
-	.release_pmd = xen_release_pmd_init,
+		.alloc_pte = xen_alloc_pte_init,
+		.release_pte = xen_release_pte_init,
+		.alloc_pmd = xen_alloc_pmd_init,
+		.release_pmd = xen_release_pmd_init,
 
-	.set_pte = xen_set_pte_init,
-	.set_pmd = xen_set_pmd_hyper,
+		.set_pte = xen_set_pte_init,
+		.set_pmd = xen_set_pmd_hyper,
 
-	.ptep_modify_prot_start = xen_ptep_modify_prot_start,
-	.ptep_modify_prot_commit = xen_ptep_modify_prot_commit,
+		.ptep_modify_prot_start = xen_ptep_modify_prot_start,
+		.ptep_modify_prot_commit = xen_ptep_modify_prot_commit,
 
-	.pte_val = PV_CALLEE_SAVE(xen_pte_val),
-	.pgd_val = PV_CALLEE_SAVE(xen_pgd_val),
+		.pte_val = PV_CALLEE_SAVE(xen_pte_val),
+		.pgd_val = PV_CALLEE_SAVE(xen_pgd_val),
 
-	.make_pte = PV_CALLEE_SAVE(xen_make_pte_init),
-	.make_pgd = PV_CALLEE_SAVE(xen_make_pgd),
+		.make_pte = PV_CALLEE_SAVE(xen_make_pte_init),
+		.make_pgd = PV_CALLEE_SAVE(xen_make_pgd),
 
-	.set_pud = xen_set_pud_hyper,
+		.set_pud = xen_set_pud_hyper,
 
-	.make_pmd = PV_CALLEE_SAVE(xen_make_pmd),
-	.pmd_val = PV_CALLEE_SAVE(xen_pmd_val),
+		.make_pmd = PV_CALLEE_SAVE(xen_make_pmd),
+		.pmd_val = PV_CALLEE_SAVE(xen_pmd_val),
 
-	.pud_val = PV_CALLEE_SAVE(xen_pud_val),
-	.make_pud = PV_CALLEE_SAVE(xen_make_pud),
-	.set_p4d = xen_set_p4d_hyper,
+		.pud_val = PV_CALLEE_SAVE(xen_pud_val),
+		.make_pud = PV_CALLEE_SAVE(xen_make_pud),
+		.set_p4d = xen_set_p4d_hyper,
 
-	.alloc_pud = xen_alloc_pmd_init,
-	.release_pud = xen_release_pmd_init,
+		.alloc_pud = xen_alloc_pmd_init,
+		.release_pud = xen_release_pmd_init,
 
 #if CONFIG_PGTABLE_LEVELS >= 5
-	.p4d_val = PV_CALLEE_SAVE(xen_p4d_val),
-	.make_p4d = PV_CALLEE_SAVE(xen_make_p4d),
+		.p4d_val = PV_CALLEE_SAVE(xen_p4d_val),
+		.make_p4d = PV_CALLEE_SAVE(xen_make_p4d),
 #endif
 
-	.activate_mm = xen_activate_mm,
-	.dup_mmap = xen_dup_mmap,
-	.exit_mmap = xen_exit_mmap,
+		.activate_mm = xen_activate_mm,
+		.dup_mmap = xen_dup_mmap,
+		.exit_mmap = xen_exit_mmap,
 
-	.lazy_mode = {
-		.enter = paravirt_enter_lazy_mmu,
-		.leave = xen_leave_lazy_mmu,
-		.flush = paravirt_flush_lazy_mmu,
-	},
+		.lazy_mode = {
+			.enter = paravirt_enter_lazy_mmu,
+			.leave = xen_leave_lazy_mmu,
+			.flush = paravirt_flush_lazy_mmu,
+		},
 
-	.set_fixmap = xen_set_fixmap,
+		.set_fixmap = xen_set_fixmap,
+	},
 };
 
 void __init xen_init_mmu_ops(void)
@@ -2144,7 +2146,7 @@ void __init xen_init_mmu_ops(void)
 	x86_init.paging.pagetable_init = xen_pagetable_init;
 	x86_init.hyper.init_after_bootmem = xen_after_bootmem;
 
-	pv_ops.mmu = xen_mmu_ops;
+	pv_ops.mmu = xen_mmu_ops.mmu;
 
 	memset(dummy_mapping, 0xff, PAGE_SIZE);
 }

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] x86/xen: Mark xen_force_evtchn_callback() noinstr
  2021-06-24  9:41 ` [PATCH v2 22/24] x86/xen: Mark xen_force_evtchn_callback() noinstr Peter Zijlstra
  2021-06-24 11:11   ` Juergen Gross
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
@ 2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
  2 siblings, 0 replies; 101+ messages in thread
From: tip-bot2 for Peter Zijlstra @ 2021-09-17 12:58 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Peter Zijlstra (Intel), Juergen Gross, x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     847d9317b2b9c7ecc14b953e6ecf9c12bcdb42e9
Gitweb:        https://git.kernel.org/tip/847d9317b2b9c7ecc14b953e6ecf9c12bcdb42e9
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Thu, 24 Jun 2021 11:41:21 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Fri, 17 Sep 2021 13:20:25 +02:00

x86/xen: Mark xen_force_evtchn_callback() noinstr

vmlinux.o: warning: objtool: check_events()+0xd: call to xen_force_evtchn_callback() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Juergen Gross <jgross@suse.com>
Link: https://lore.kernel.org/r/20210624095148.996055323@infradead.org
---
 arch/x86/include/asm/xen/hypercall.h | 2 +-
 arch/x86/xen/irq.c                   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h
index 990b8aa..4a7ff8b 100644
--- a/arch/x86/include/asm/xen/hypercall.h
+++ b/arch/x86/include/asm/xen/hypercall.h
@@ -358,7 +358,7 @@ HYPERVISOR_event_channel_op(int cmd, void *arg)
 	return _hypercall2(int, event_channel_op, cmd, arg);
 }
 
-static inline int
+static __always_inline int
 HYPERVISOR_xen_version(int cmd, void *arg)
 {
 	return _hypercall2(int, xen_version, cmd, arg);
diff --git a/arch/x86/xen/irq.c b/arch/x86/xen/irq.c
index f52b60d..2f695b5 100644
--- a/arch/x86/xen/irq.c
+++ b/arch/x86/xen/irq.c
@@ -19,7 +19,7 @@
  * callback mask. We do this in a very simple manner, by making a call
  * down into Xen. The pending flag will be checked by Xen on return.
  */
-void xen_force_evtchn_callback(void)
+noinstr void xen_force_evtchn_callback(void)
 {
 	(void)HYPERVISOR_xen_version(0, NULL);
 }

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] x86/xen: Make irq_disable() noinstr
  2021-06-24  9:41 ` [PATCH v2 21/24] x86/xen: Make irq_disable() noinstr Peter Zijlstra
  2021-06-24 11:10   ` Juergen Gross
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
@ 2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
  2 siblings, 0 replies; 101+ messages in thread
From: tip-bot2 for Peter Zijlstra @ 2021-09-17 12:58 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Peter Zijlstra (Intel), Juergen Gross, x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     09c413071e2de71d1f28813c560ae0c06b344520
Gitweb:        https://git.kernel.org/tip/09c413071e2de71d1f28813c560ae0c06b344520
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Thu, 24 Jun 2021 11:41:20 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Fri, 17 Sep 2021 13:20:23 +02:00

x86/xen: Make irq_disable() noinstr

vmlinux.o: warning: objtool: pv_ops[31]: native_irq_disable
vmlinux.o: warning: objtool: pv_ops[31]: __raw_callee_save_xen_irq_disable
vmlinux.o: warning: objtool: pv_ops[31]: xen_irq_disable_direct
vmlinux.o: warning: objtool: lock_is_held_type()+0x5b: call to pv_ops[31]() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Juergen Gross <jgross@suse.com>
Link: https://lore.kernel.org/r/20210624095148.933869441@infradead.org
---
 arch/x86/kernel/paravirt.c | 7 ++++++-
 arch/x86/xen/irq.c         | 4 ++--
 arch/x86/xen/xen-asm.S     | 3 +--
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index 75f0d24..ebc4536 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -243,6 +243,11 @@ static noinstr void pv_native_irq_enable(void)
 {
 	native_irq_enable();
 }
+
+static noinstr void pv_native_irq_disable(void)
+{
+	native_irq_disable();
+}
 #endif
 
 enum paravirt_lazy_mode paravirt_get_lazy_mode(void)
@@ -306,7 +311,7 @@ struct paravirt_patch_template pv_ops = {
 
 	/* Irq ops. */
 	.irq.save_fl		= __PV_IS_CALLEE_SAVE(native_save_fl),
-	.irq.irq_disable	= __PV_IS_CALLEE_SAVE(native_irq_disable),
+	.irq.irq_disable	= __PV_IS_CALLEE_SAVE(pv_native_irq_disable),
 	.irq.irq_enable		= __PV_IS_CALLEE_SAVE(pv_native_irq_enable),
 	.irq.safe_halt		= native_safe_halt,
 	.irq.halt		= native_halt,
diff --git a/arch/x86/xen/irq.c b/arch/x86/xen/irq.c
index 7fb4cf2..f52b60d 100644
--- a/arch/x86/xen/irq.c
+++ b/arch/x86/xen/irq.c
@@ -42,7 +42,7 @@ asmlinkage __visible noinstr unsigned long xen_save_fl(void)
 }
 __PV_CALLEE_SAVE_REGS_THUNK(xen_save_fl, ".noinstr.text");
 
-asmlinkage __visible void xen_irq_disable(void)
+asmlinkage __visible noinstr void xen_irq_disable(void)
 {
 	/* There's a one instruction preempt window here.  We need to
 	   make sure we're don't switch CPUs between getting the vcpu
@@ -51,7 +51,7 @@ asmlinkage __visible void xen_irq_disable(void)
 	this_cpu_read(xen_vcpu)->evtchn_upcall_mask = 1;
 	preempt_enable_no_resched();
 }
-PV_CALLEE_SAVE_REGS_THUNK(xen_irq_disable);
+__PV_CALLEE_SAVE_REGS_THUNK(xen_irq_disable, ".noinstr.text");
 
 asmlinkage __visible noinstr void xen_irq_enable(void)
 {
diff --git a/arch/x86/xen/xen-asm.S b/arch/x86/xen/xen-asm.S
index 2225195..220dd96 100644
--- a/arch/x86/xen/xen-asm.S
+++ b/arch/x86/xen/xen-asm.S
@@ -21,6 +21,7 @@
 #include <linux/init.h>
 #include <linux/linkage.h>
 
+.pushsection .noinstr.text, "ax"
 /*
  * Disabling events is simply a matter of making the event mask
  * non-zero.
@@ -30,8 +31,6 @@ SYM_FUNC_START(xen_irq_disable_direct)
 	ret
 SYM_FUNC_END(xen_irq_disable_direct)
 
-.pushsection .noinstr.text, "ax"
-
 /*
  * Force an event check by making a hypercall, but preserve regs
  * before making the call.

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] x86/xen: Make irq_enable() noinstr
  2021-06-24  9:41 ` [PATCH v2 20/24] x86/xen: Make irq_enable() noinstr Peter Zijlstra
  2021-06-24 11:09   ` Juergen Gross
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
@ 2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
  2 siblings, 0 replies; 101+ messages in thread
From: tip-bot2 for Peter Zijlstra @ 2021-09-17 12:58 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Peter Zijlstra (Intel), Juergen Gross, x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     d7bfc7d57cbe13382fd3eb739667fd0e2f74122b
Gitweb:        https://git.kernel.org/tip/d7bfc7d57cbe13382fd3eb739667fd0e2f74122b
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Thu, 24 Jun 2021 11:41:19 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Fri, 17 Sep 2021 13:17:12 +02:00

x86/xen: Make irq_enable() noinstr

vmlinux.o: warning: objtool: pv_ops[32]: native_irq_enable
vmlinux.o: warning: objtool: pv_ops[32]: __raw_callee_save_xen_irq_enable
vmlinux.o: warning: objtool: pv_ops[32]: xen_irq_enable_direct
vmlinux.o: warning: objtool: lock_is_held_type()+0xfe: call to pv_ops[32]() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Juergen Gross <jgross@suse.com>
Link: https://lore.kernel.org/r/20210624095148.872254932@infradead.org
---
 arch/x86/kernel/paravirt.c |  7 ++++-
 arch/x86/xen/irq.c         |  4 +--
 arch/x86/xen/xen-asm.S     | 56 ++++++++++++++++++-------------------
 3 files changed, 36 insertions(+), 31 deletions(-)

diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index cdaf862..75f0d24 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -238,6 +238,11 @@ static noinstr void pv_native_set_debugreg(int regno, unsigned long val)
 {
 	native_set_debugreg(regno, val);
 }
+
+static noinstr void pv_native_irq_enable(void)
+{
+	native_irq_enable();
+}
 #endif
 
 enum paravirt_lazy_mode paravirt_get_lazy_mode(void)
@@ -302,7 +307,7 @@ struct paravirt_patch_template pv_ops = {
 	/* Irq ops. */
 	.irq.save_fl		= __PV_IS_CALLEE_SAVE(native_save_fl),
 	.irq.irq_disable	= __PV_IS_CALLEE_SAVE(native_irq_disable),
-	.irq.irq_enable		= __PV_IS_CALLEE_SAVE(native_irq_enable),
+	.irq.irq_enable		= __PV_IS_CALLEE_SAVE(pv_native_irq_enable),
 	.irq.safe_halt		= native_safe_halt,
 	.irq.halt		= native_halt,
 #endif /* CONFIG_PARAVIRT_XXL */
diff --git a/arch/x86/xen/irq.c b/arch/x86/xen/irq.c
index 9c71f43..7fb4cf2 100644
--- a/arch/x86/xen/irq.c
+++ b/arch/x86/xen/irq.c
@@ -53,7 +53,7 @@ asmlinkage __visible void xen_irq_disable(void)
 }
 PV_CALLEE_SAVE_REGS_THUNK(xen_irq_disable);
 
-asmlinkage __visible void xen_irq_enable(void)
+asmlinkage __visible noinstr void xen_irq_enable(void)
 {
 	struct vcpu_info *vcpu;
 
@@ -76,7 +76,7 @@ asmlinkage __visible void xen_irq_enable(void)
 
 	preempt_enable();
 }
-PV_CALLEE_SAVE_REGS_THUNK(xen_irq_enable);
+__PV_CALLEE_SAVE_REGS_THUNK(xen_irq_enable, ".noinstr.text");
 
 static void xen_safe_halt(void)
 {
diff --git a/arch/x86/xen/xen-asm.S b/arch/x86/xen/xen-asm.S
index 0883e39..2225195 100644
--- a/arch/x86/xen/xen-asm.S
+++ b/arch/x86/xen/xen-asm.S
@@ -22,33 +22,6 @@
 #include <linux/linkage.h>
 
 /*
- * Enable events.  This clears the event mask and tests the pending
- * event status with one and operation.  If there are pending events,
- * then enter the hypervisor to get them handled.
- */
-SYM_FUNC_START(xen_irq_enable_direct)
-	FRAME_BEGIN
-	/* Unmask events */
-	movb $0, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask
-
-	/*
-	 * Preempt here doesn't matter because that will deal with any
-	 * pending interrupts.  The pending check may end up being run
-	 * on the wrong CPU, but that doesn't hurt.
-	 */
-
-	/* Test for pending */
-	testb $0xff, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_pending
-	jz 1f
-
-	call check_events
-1:
-	FRAME_END
-	ret
-SYM_FUNC_END(xen_irq_enable_direct)
-
-
-/*
  * Disabling events is simply a matter of making the event mask
  * non-zero.
  */
@@ -57,6 +30,8 @@ SYM_FUNC_START(xen_irq_disable_direct)
 	ret
 SYM_FUNC_END(xen_irq_disable_direct)
 
+.pushsection .noinstr.text, "ax"
+
 /*
  * Force an event check by making a hypercall, but preserve regs
  * before making the call.
@@ -86,7 +61,32 @@ SYM_FUNC_START(check_events)
 	ret
 SYM_FUNC_END(check_events)
 
-.pushsection .noinstr.text, "ax"
+/*
+ * Enable events.  This clears the event mask and tests the pending
+ * event status with one and operation.  If there are pending events,
+ * then enter the hypervisor to get them handled.
+ */
+SYM_FUNC_START(xen_irq_enable_direct)
+	FRAME_BEGIN
+	/* Unmask events */
+	movb $0, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask
+
+	/*
+	 * Preempt here doesn't matter because that will deal with any
+	 * pending interrupts.  The pending check may end up being run
+	 * on the wrong CPU, but that doesn't hurt.
+	 */
+
+	/* Test for pending */
+	testb $0xff, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_pending
+	jz 1f
+
+	call check_events
+1:
+	FRAME_END
+	ret
+SYM_FUNC_END(xen_irq_enable_direct)
+
 /*
  * (xen_)save_fl is used to get the current interrupt enable status.
  * Callers expect the status to be in X86_EFLAGS_IF, and other bits

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] x86/xen: Make hypercall_page noinstr
  2021-06-24  9:41 ` [PATCH v2 19/24] x86/xen: Make hypercall_page noinstr Peter Zijlstra
  2021-06-24 11:08   ` Juergen Gross
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
@ 2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
  2 siblings, 0 replies; 101+ messages in thread
From: tip-bot2 for Peter Zijlstra @ 2021-09-17 12:58 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Peter Zijlstra (Intel), Juergen Gross, x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     74ea805b79d2b6eb472daa2540ed35ccb4ed23e7
Gitweb:        https://git.kernel.org/tip/74ea805b79d2b6eb472daa2540ed35ccb4ed23e7
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Thu, 24 Jun 2021 11:41:18 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Fri, 17 Sep 2021 13:14:44 +02:00

x86/xen: Make hypercall_page noinstr

vmlinux.o: warning: objtool: xen_set_debugreg()+0x3: call to hypercall_page() leaves .noinstr.text section
vmlinux.o: warning: objtool: xen_get_debugreg()+0x3: call to hypercall_page() leaves .noinstr.text section
vmlinux.o: warning: objtool: xen_irq_enable()+0x24: call to hypercall_page() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Juergen Gross <jgross@suse.com>
Link: https://lore.kernel.org/r/20210624095148.810950584@infradead.org
---
 arch/x86/xen/xen-head.S | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/xen/xen-head.S b/arch/x86/xen/xen-head.S
index 488944d..9e27b86 100644
--- a/arch/x86/xen/xen-head.S
+++ b/arch/x86/xen/xen-head.S
@@ -20,7 +20,7 @@
 #include <xen/interface/xen-mca.h>
 #include <asm/xen/interface.h>
 
-.pushsection .text
+.pushsection .noinstr.text, "ax"
 	.balign PAGE_SIZE
 SYM_CODE_START(hypercall_page)
 	.rept (PAGE_SIZE / 32)

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] x86/xen: Make set_debugreg() noinstr
  2021-06-24  9:41 ` [PATCH v2 17/24] x86/xen: Make set_debugreg() noinstr Peter Zijlstra
  2021-06-24 10:59   ` Juergen Gross
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
@ 2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
  2 siblings, 0 replies; 101+ messages in thread
From: tip-bot2 for Peter Zijlstra @ 2021-09-17 12:58 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Peter Zijlstra (Intel), Juergen Gross, x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     7361fac0465ba96ec8f7559459e3c70818ba6c78
Gitweb:        https://git.kernel.org/tip/7361fac0465ba96ec8f7559459e3c70818ba6c78
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Thu, 24 Jun 2021 11:41:16 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Fri, 17 Sep 2021 13:14:39 +02:00

x86/xen: Make set_debugreg() noinstr

vmlinux.o: warning: objtool: pv_ops[2]: xen_set_debugreg
vmlinux.o: warning: objtool: pv_ops[2]: native_set_debugreg
vmlinux.o: warning: objtool: exc_debug()+0x3b: call to pv_ops[2]() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Juergen Gross <jgross@suse.com>
Link: https://lore.kernel.org/r/20210624095148.687755639@infradead.org
---
 arch/x86/include/asm/paravirt.h      |  2 +-
 arch/x86/include/asm/xen/hypercall.h |  2 +-
 arch/x86/kernel/paravirt.c           |  9 ++++++---
 arch/x86/xen/enlighten_pv.c          |  2 +-
 4 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index f48465c..34da790 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -118,7 +118,7 @@ static __always_inline unsigned long paravirt_get_debugreg(int reg)
 	return PVOP_CALL1(unsigned long, cpu.get_debugreg, reg);
 }
 #define get_debugreg(var, reg) var = paravirt_get_debugreg(reg)
-static inline void set_debugreg(unsigned long val, int reg)
+static __always_inline void set_debugreg(unsigned long val, int reg)
 {
 	PVOP_VCALL2(cpu.set_debugreg, reg, val);
 }
diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h
index af92202..990b8aa 100644
--- a/arch/x86/include/asm/xen/hypercall.h
+++ b/arch/x86/include/asm/xen/hypercall.h
@@ -308,7 +308,7 @@ HYPERVISOR_platform_op(struct xen_platform_op *op)
 	return _hypercall1(int, platform_op, op);
 }
 
-static inline int
+static __always_inline int
 HYPERVISOR_set_debugreg(int reg, unsigned long value)
 {
 	return _hypercall2(int, set_debugreg, reg, value);
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index 8af526c..cdaf862 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -233,6 +233,11 @@ static noinstr unsigned long pv_native_get_debugreg(int regno)
 {
 	return native_get_debugreg(regno);
 }
+
+static noinstr void pv_native_set_debugreg(int regno, unsigned long val)
+{
+	native_set_debugreg(regno, val);
+}
 #endif
 
 enum paravirt_lazy_mode paravirt_get_lazy_mode(void)
@@ -260,7 +265,7 @@ struct paravirt_patch_template pv_ops = {
 #ifdef CONFIG_PARAVIRT_XXL
 	.cpu.cpuid		= native_cpuid,
 	.cpu.get_debugreg	= pv_native_get_debugreg,
-	.cpu.set_debugreg	= native_set_debugreg,
+	.cpu.set_debugreg	= pv_native_set_debugreg,
 	.cpu.read_cr0		= native_read_cr0,
 	.cpu.write_cr0		= native_write_cr0,
 	.cpu.write_cr4		= native_write_cr4,
@@ -386,8 +391,6 @@ struct paravirt_patch_template pv_ops = {
 };
 
 #ifdef CONFIG_PARAVIRT_XXL
-/* At this point, native_get/set_debugreg has real function entries */
-NOKPROBE_SYMBOL(native_set_debugreg);
 NOKPROBE_SYMBOL(native_load_idt);
 
 void (*paravirt_iret)(void) = native_iret;
diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c
index 273e1fa..2b1a8ba 100644
--- a/arch/x86/xen/enlighten_pv.c
+++ b/arch/x86/xen/enlighten_pv.c
@@ -311,7 +311,7 @@ static void __init xen_init_capabilities(void)
 	}
 }
 
-static void xen_set_debugreg(int reg, unsigned long val)
+static noinstr void xen_set_debugreg(int reg, unsigned long val)
 {
 	HYPERVISOR_set_debugreg(reg, val);
 }

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] x86/xen: Make save_fl() noinstr
  2021-06-24  9:41 ` [PATCH v2 18/24] x86/xen: Make save_fl() noinstr Peter Zijlstra
  2021-06-24 11:07   ` Juergen Gross
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
@ 2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
  2 siblings, 0 replies; 101+ messages in thread
From: tip-bot2 for Peter Zijlstra @ 2021-09-17 12:58 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Peter Zijlstra (Intel), Juergen Gross, x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     20125c872a3f129cef7fdec2b7681da98502a55d
Gitweb:        https://git.kernel.org/tip/20125c872a3f129cef7fdec2b7681da98502a55d
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Thu, 24 Jun 2021 11:41:17 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Fri, 17 Sep 2021 13:14:44 +02:00

x86/xen: Make save_fl() noinstr

vmlinux.o: warning: objtool: pv_ops[30]: native_save_fl
vmlinux.o: warning: objtool: pv_ops[30]: __raw_callee_save_xen_save_fl
vmlinux.o: warning: objtool: pv_ops[30]: xen_save_fl_direct
vmlinux.o: warning: objtool: lockdep_hardirqs_off()+0x73: call to pv_ops[30]() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Juergen Gross <jgross@suse.com>
Link: https://lore.kernel.org/r/20210624095148.749712274@infradead.org
---
 arch/x86/include/asm/paravirt.h |  7 +++++--
 arch/x86/kernel/irqflags.S      |  2 ++-
 arch/x86/xen/irq.c              |  4 ++--
 arch/x86/xen/xen-asm.S          | 32 ++++++++++++++++----------------
 4 files changed, 25 insertions(+), 20 deletions(-)

diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index 34da790..cebec95 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -653,10 +653,10 @@ bool __raw_callee_save___native_vcpu_is_preempted(long cpu);
  * functions.
  */
 #define PV_THUNK_NAME(func) "__raw_callee_save_" #func
-#define PV_CALLEE_SAVE_REGS_THUNK(func)					\
+#define __PV_CALLEE_SAVE_REGS_THUNK(func, section)			\
 	extern typeof(func) __raw_callee_save_##func;			\
 									\
-	asm(".pushsection .text;"					\
+	asm(".pushsection " section ", \"ax\";"				\
 	    ".globl " PV_THUNK_NAME(func) ";"				\
 	    ".type " PV_THUNK_NAME(func) ", @function;"			\
 	    PV_THUNK_NAME(func) ":"					\
@@ -669,6 +669,9 @@ bool __raw_callee_save___native_vcpu_is_preempted(long cpu);
 	    ".size " PV_THUNK_NAME(func) ", .-" PV_THUNK_NAME(func) ";"	\
 	    ".popsection")
 
+#define PV_CALLEE_SAVE_REGS_THUNK(func)			\
+	__PV_CALLEE_SAVE_REGS_THUNK(func, ".text")
+
 /* Get a reference to a callee-save function */
 #define PV_CALLEE_SAVE(func)						\
 	((struct paravirt_callee_save) { __raw_callee_save_##func })
diff --git a/arch/x86/kernel/irqflags.S b/arch/x86/kernel/irqflags.S
index 8ef3506..760e1f2 100644
--- a/arch/x86/kernel/irqflags.S
+++ b/arch/x86/kernel/irqflags.S
@@ -7,9 +7,11 @@
 /*
  * unsigned long native_save_fl(void)
  */
+.pushsection .noinstr.text, "ax"
 SYM_FUNC_START(native_save_fl)
 	pushf
 	pop %_ASM_AX
 	ret
 SYM_FUNC_END(native_save_fl)
+.popsection
 EXPORT_SYMBOL(native_save_fl)
diff --git a/arch/x86/xen/irq.c b/arch/x86/xen/irq.c
index dfa091d..9c71f43 100644
--- a/arch/x86/xen/irq.c
+++ b/arch/x86/xen/irq.c
@@ -24,7 +24,7 @@ void xen_force_evtchn_callback(void)
 	(void)HYPERVISOR_xen_version(0, NULL);
 }
 
-asmlinkage __visible unsigned long xen_save_fl(void)
+asmlinkage __visible noinstr unsigned long xen_save_fl(void)
 {
 	struct vcpu_info *vcpu;
 	unsigned long flags;
@@ -40,7 +40,7 @@ asmlinkage __visible unsigned long xen_save_fl(void)
 	*/
 	return (-flags) & X86_EFLAGS_IF;
 }
-PV_CALLEE_SAVE_REGS_THUNK(xen_save_fl);
+__PV_CALLEE_SAVE_REGS_THUNK(xen_save_fl, ".noinstr.text");
 
 asmlinkage __visible void xen_irq_disable(void)
 {
diff --git a/arch/x86/xen/xen-asm.S b/arch/x86/xen/xen-asm.S
index aef4a1e..0883e39 100644
--- a/arch/x86/xen/xen-asm.S
+++ b/arch/x86/xen/xen-asm.S
@@ -58,22 +58,6 @@ SYM_FUNC_START(xen_irq_disable_direct)
 SYM_FUNC_END(xen_irq_disable_direct)
 
 /*
- * (xen_)save_fl is used to get the current interrupt enable status.
- * Callers expect the status to be in X86_EFLAGS_IF, and other bits
- * may be set in the return value.  We take advantage of this by
- * making sure that X86_EFLAGS_IF has the right value (and other bits
- * in that byte are 0), but other bits in the return value are
- * undefined.  We need to toggle the state of the bit, because Xen and
- * x86 use opposite senses (mask vs enable).
- */
-SYM_FUNC_START(xen_save_fl_direct)
-	testb $0xff, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask
-	setz %ah
-	addb %ah, %ah
-	ret
-SYM_FUNC_END(xen_save_fl_direct)
-
-/*
  * Force an event check by making a hypercall, but preserve regs
  * before making the call.
  */
@@ -103,6 +87,22 @@ SYM_FUNC_START(check_events)
 SYM_FUNC_END(check_events)
 
 .pushsection .noinstr.text, "ax"
+/*
+ * (xen_)save_fl is used to get the current interrupt enable status.
+ * Callers expect the status to be in X86_EFLAGS_IF, and other bits
+ * may be set in the return value.  We take advantage of this by
+ * making sure that X86_EFLAGS_IF has the right value (and other bits
+ * in that byte are 0), but other bits in the return value are
+ * undefined.  We need to toggle the state of the bit, because Xen and
+ * x86 use opposite senses (mask vs enable).
+ */
+SYM_FUNC_START(xen_save_fl_direct)
+	testb $0xff, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask
+	setz %ah
+	addb %ah, %ah
+	ret
+SYM_FUNC_END(xen_save_fl_direct)
+
 SYM_FUNC_START(xen_read_cr2)
 	FRAME_BEGIN
 	_ASM_MOV PER_CPU_VAR(xen_vcpu), %_ASM_AX

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] x86/xen: Make get_debugreg() noinstr
  2021-06-24  9:41 ` [PATCH v2 16/24] x86/xen: Make get_debugreg() noinstr Peter Zijlstra
  2021-06-24 10:57   ` Juergen Gross
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
@ 2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
  2 siblings, 0 replies; 101+ messages in thread
From: tip-bot2 for Peter Zijlstra @ 2021-09-17 12:58 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Peter Zijlstra (Intel), Juergen Gross, x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     f4afb713e5c3a4419ba7aaecc31a8c8bd91d13fb
Gitweb:        https://git.kernel.org/tip/f4afb713e5c3a4419ba7aaecc31a8c8bd91d13fb
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Thu, 24 Jun 2021 11:41:15 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Fri, 17 Sep 2021 13:12:34 +02:00

x86/xen: Make get_debugreg() noinstr

vmlinux.o: warning: objtool: pv_ops[1]: xen_get_debugreg
vmlinux.o: warning: objtool: pv_ops[1]: native_get_debugreg
vmlinux.o: warning: objtool: exc_debug()+0x25: call to pv_ops[1]() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Juergen Gross <jgross@suse.com>
Link: https://lore.kernel.org/r/20210624095148.625523645@infradead.org
---
 arch/x86/include/asm/paravirt.h      | 2 +-
 arch/x86/include/asm/xen/hypercall.h | 2 +-
 arch/x86/kernel/paravirt.c           | 8 ++++++--
 arch/x86/xen/enlighten_pv.c          | 2 +-
 4 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index be82b52..f48465c 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -113,7 +113,7 @@ static inline void __cpuid(unsigned int *eax, unsigned int *ebx,
 /*
  * These special macros can be used to get or set a debugging register
  */
-static inline unsigned long paravirt_get_debugreg(int reg)
+static __always_inline unsigned long paravirt_get_debugreg(int reg)
 {
 	return PVOP_CALL1(unsigned long, cpu.get_debugreg, reg);
 }
diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h
index 454b208..af92202 100644
--- a/arch/x86/include/asm/xen/hypercall.h
+++ b/arch/x86/include/asm/xen/hypercall.h
@@ -314,7 +314,7 @@ HYPERVISOR_set_debugreg(int reg, unsigned long value)
 	return _hypercall2(int, set_debugreg, reg, value);
 }
 
-static inline unsigned long
+static __always_inline unsigned long
 HYPERVISOR_get_debugreg(int reg)
 {
 	return _hypercall1(unsigned long, get_debugreg, reg);
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index fc2cf2b..8af526c 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -228,6 +228,11 @@ static noinstr void pv_native_write_cr2(unsigned long val)
 {
 	native_write_cr2(val);
 }
+
+static noinstr unsigned long pv_native_get_debugreg(int regno)
+{
+	return native_get_debugreg(regno);
+}
 #endif
 
 enum paravirt_lazy_mode paravirt_get_lazy_mode(void)
@@ -254,7 +259,7 @@ struct paravirt_patch_template pv_ops = {
 
 #ifdef CONFIG_PARAVIRT_XXL
 	.cpu.cpuid		= native_cpuid,
-	.cpu.get_debugreg	= native_get_debugreg,
+	.cpu.get_debugreg	= pv_native_get_debugreg,
 	.cpu.set_debugreg	= native_set_debugreg,
 	.cpu.read_cr0		= native_read_cr0,
 	.cpu.write_cr0		= native_write_cr0,
@@ -382,7 +387,6 @@ struct paravirt_patch_template pv_ops = {
 
 #ifdef CONFIG_PARAVIRT_XXL
 /* At this point, native_get/set_debugreg has real function entries */
-NOKPROBE_SYMBOL(native_get_debugreg);
 NOKPROBE_SYMBOL(native_set_debugreg);
 NOKPROBE_SYMBOL(native_load_idt);
 
diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c
index 753f637..273e1fa 100644
--- a/arch/x86/xen/enlighten_pv.c
+++ b/arch/x86/xen/enlighten_pv.c
@@ -316,7 +316,7 @@ static void xen_set_debugreg(int reg, unsigned long val)
 	HYPERVISOR_set_debugreg(reg, val);
 }
 
-static unsigned long xen_get_debugreg(int reg)
+static noinstr unsigned long xen_get_debugreg(int reg)
 {
 	return HYPERVISOR_get_debugreg(reg);
 }

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] x86/xen: Make write_cr2() noinstr
  2021-06-24  9:41 ` [PATCH v2 15/24] x86/xen: Make write_cr2() noinstr Peter Zijlstra
  2021-06-24 10:56   ` Juergen Gross
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
@ 2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
  2 siblings, 0 replies; 101+ messages in thread
From: tip-bot2 for Peter Zijlstra @ 2021-09-17 12:58 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Peter Zijlstra (Intel), Juergen Gross, x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     209cfd0cbb6722d3461e4f928dc150e4c3811948
Gitweb:        https://git.kernel.org/tip/209cfd0cbb6722d3461e4f928dc150e4c3811948
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Thu, 24 Jun 2021 11:41:14 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Fri, 17 Sep 2021 13:12:16 +02:00

x86/xen: Make write_cr2() noinstr

vmlinux.o: warning: objtool: pv_ops[42]: native_write_cr2
vmlinux.o: warning: objtool: pv_ops[42]: xen_write_cr2
vmlinux.o: warning: objtool: exc_nmi()+0x127: call to pv_ops[42]() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Juergen Gross <jgross@suse.com>
Link: https://lore.kernel.org/r/20210624095148.563524913@infradead.org
---
 arch/x86/include/asm/paravirt.h | 2 +-
 arch/x86/kernel/paravirt.c      | 7 ++++++-
 arch/x86/xen/mmu_pv.c           | 3 ++-
 3 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index 8878065..be82b52 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -140,7 +140,7 @@ static __always_inline unsigned long read_cr2(void)
 				ALT_NOT(X86_FEATURE_XENPV));
 }
 
-static inline void write_cr2(unsigned long x)
+static __always_inline void write_cr2(unsigned long x)
 {
 	PVOP_VCALL1(mmu.write_cr2, x);
 }
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index e351014..fc2cf2b 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -223,6 +223,11 @@ static noinstr unsigned long pv_native_read_cr2(void)
 {
 	return native_read_cr2();
 }
+
+static noinstr void pv_native_write_cr2(unsigned long val)
+{
+	native_write_cr2(val);
+}
 #endif
 
 enum paravirt_lazy_mode paravirt_get_lazy_mode(void)
@@ -304,7 +309,7 @@ struct paravirt_patch_template pv_ops = {
 
 #ifdef CONFIG_PARAVIRT_XXL
 	.mmu.read_cr2		= __PV_IS_CALLEE_SAVE(pv_native_read_cr2),
-	.mmu.write_cr2		= native_write_cr2,
+	.mmu.write_cr2		= pv_native_write_cr2,
 	.mmu.read_cr3		= __native_read_cr3,
 	.mmu.write_cr3		= native_write_cr3,
 
diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c
index 1df5f01..f3cafe5 100644
--- a/arch/x86/xen/mmu_pv.c
+++ b/arch/x86/xen/mmu_pv.c
@@ -1204,7 +1204,8 @@ static void __init xen_pagetable_init(void)
 	xen_remap_memory();
 	xen_setup_mfn_list_list();
 }
-static void xen_write_cr2(unsigned long cr2)
+
+static noinstr void xen_write_cr2(unsigned long cr2)
 {
 	this_cpu_read(xen_vcpu)->arch.cr2 = cr2;
 }

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [tip: objtool/core] x86/xen: Make read_cr2() noinstr
  2021-06-24  9:41 ` [PATCH v2 14/24] x86/xen: Make read_cr2() noinstr Peter Zijlstra
  2021-06-24 10:55   ` Juergen Gross
  2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
@ 2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
  2 siblings, 0 replies; 101+ messages in thread
From: tip-bot2 for Peter Zijlstra @ 2021-09-17 12:58 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Peter Zijlstra (Intel), Juergen Gross, x86, linux-kernel

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     0a53c9acf4da51a75392b0b543ce5eaae78a567f
Gitweb:        https://git.kernel.org/tip/0a53c9acf4da51a75392b0b543ce5eaae78a567f
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Thu, 24 Jun 2021 11:41:13 +02:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Fri, 17 Sep 2021 13:11:50 +02:00

x86/xen: Make read_cr2() noinstr

vmlinux.o: warning: objtool: pv_ops[41]: native_read_cr2
vmlinux.o: warning: objtool: pv_ops[41]: xen_read_cr2
vmlinux.o: warning: objtool: pv_ops[41]: xen_read_cr2_direct
vmlinux.o: warning: objtool: exc_double_fault()+0x15: call to pv_ops[41]() leaves .noinstr.text section

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Juergen Gross <jgross@suse.com>
Link: https://lore.kernel.org/r/20210624095148.500331616@infradead.org
---
 arch/x86/include/asm/paravirt.h | 2 +-
 arch/x86/kernel/paravirt.c      | 7 ++++++-
 arch/x86/xen/xen-asm.S          | 2 ++
 3 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index a13a9a3..8878065 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -133,7 +133,7 @@ static inline void write_cr0(unsigned long x)
 	PVOP_VCALL1(cpu.write_cr0, x);
 }
 
-static inline unsigned long read_cr2(void)
+static __always_inline unsigned long read_cr2(void)
 {
 	return PVOP_ALT_CALLEE0(unsigned long, mmu.read_cr2,
 				"mov %%cr2, %%rax;",
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index 04cafc0..e351014 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -218,6 +218,11 @@ void paravirt_end_context_switch(struct task_struct *next)
 	if (test_and_clear_ti_thread_flag(task_thread_info(next), TIF_LAZY_MMU_UPDATES))
 		arch_enter_lazy_mmu_mode();
 }
+
+static noinstr unsigned long pv_native_read_cr2(void)
+{
+	return native_read_cr2();
+}
 #endif
 
 enum paravirt_lazy_mode paravirt_get_lazy_mode(void)
@@ -298,7 +303,7 @@ struct paravirt_patch_template pv_ops = {
 	.mmu.exit_mmap		= paravirt_nop,
 
 #ifdef CONFIG_PARAVIRT_XXL
-	.mmu.read_cr2		= __PV_IS_CALLEE_SAVE(native_read_cr2),
+	.mmu.read_cr2		= __PV_IS_CALLEE_SAVE(pv_native_read_cr2),
 	.mmu.write_cr2		= native_write_cr2,
 	.mmu.read_cr3		= __native_read_cr3,
 	.mmu.write_cr3		= native_write_cr3,
diff --git a/arch/x86/xen/xen-asm.S b/arch/x86/xen/xen-asm.S
index 1e62644..aef4a1e 100644
--- a/arch/x86/xen/xen-asm.S
+++ b/arch/x86/xen/xen-asm.S
@@ -102,6 +102,7 @@ SYM_FUNC_START(check_events)
 	ret
 SYM_FUNC_END(check_events)
 
+.pushsection .noinstr.text, "ax"
 SYM_FUNC_START(xen_read_cr2)
 	FRAME_BEGIN
 	_ASM_MOV PER_CPU_VAR(xen_vcpu), %_ASM_AX
@@ -116,6 +117,7 @@ SYM_FUNC_START(xen_read_cr2_direct)
 	FRAME_END
 	ret
 SYM_FUNC_END(xen_read_cr2_direct);
+.popsection
 
 .macro xen_pv_trap name
 SYM_CODE_START(xen_\name)

^ permalink raw reply	[flat|nested] 101+ messages in thread

end of thread, other threads:[~2021-09-17 12:58 UTC | newest]

Thread overview: 101+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-24  9:40 [PATCH v2 00/24] objtool/x86: noinstr vs PARAVIRT Peter Zijlstra
2021-06-24  9:41 ` [PATCH v2 01/24] x86/xen: Mark cpu_bringup_and_idle() as dead_end_function Peter Zijlstra
2021-06-24 10:49   ` Juergen Gross
2021-06-30 11:47   ` Miroslav Benes
2021-08-20 19:22   ` Josh Poimboeuf
2021-08-20 19:31     ` Josh Poimboeuf
2021-08-23  8:40       ` Juergen Gross
2021-08-30  5:55         ` Juergen Gross
2021-08-30  7:48           ` Peter Zijlstra
2021-08-30  7:56             ` Juergen Gross
2021-09-15 15:49       ` [tip: objtool/core] x86/xen: Move hypercall_page to top of the file tip-bot2 for Josh Poimboeuf
2021-09-15 15:49   ` [tip: objtool/core] x86/xen: Mark cpu_bringup_and_idle() as dead_end_function tip-bot2 for Peter Zijlstra
2021-06-24  9:41 ` [PATCH v2 02/24] objtool: Introduce CFI hash Peter Zijlstra
2021-06-30 12:45   ` Miroslav Benes
2021-07-01  8:35     ` Peter Zijlstra
2021-07-01  8:53       ` Miroslav Benes
2021-08-20 22:27   ` Josh Poimboeuf
2021-08-25 10:13     ` Peter Zijlstra
2021-08-25 12:49       ` Peter Zijlstra
2021-08-25 10:15     ` Peter Zijlstra
2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
2021-06-24  9:41 ` [PATCH v2 03/24] objtool: Handle __sanitize_cov*() tail calls Peter Zijlstra
2021-06-25 11:05   ` Marco Elver
2021-06-28  9:07     ` Peter Zijlstra
2021-06-25 13:38   ` Steven Rostedt
2021-06-26  8:18     ` Peter Zijlstra
2021-06-29  1:07       ` Steven Rostedt
2021-08-20 23:17   ` Josh Poimboeuf
2021-08-25 10:19     ` Peter Zijlstra
2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
2021-06-24  9:41 ` [PATCH v2 04/24] x86/kvm: Always inline sev_*guest() Peter Zijlstra
2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
2021-06-24  9:41 ` [PATCH v2 05/24] x86/kvm: Always inline vmload() / vmsave() Peter Zijlstra
2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
2021-06-24  9:41 ` [PATCH v2 06/24] x86: Always inline context_tracking_guest_enter() Peter Zijlstra
2021-08-20 23:22   ` Josh Poimboeuf
2021-08-20 23:34     ` Josh Poimboeuf
2021-08-25 12:16       ` Peter Zijlstra
     [not found]         ` <YSZxtBHNJzoUbqdE@ravnborg.org>
2021-08-26  4:10           ` Josh Poimboeuf
2021-08-25 13:38       ` Peter Zijlstra
2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
2021-06-24  9:41 ` [PATCH v2 07/24] x86/kvm: Always inline to_svm() Peter Zijlstra
2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
2021-06-24  9:41 ` [PATCH v2 08/24] x86/kvm: Always inline evmcs_write64() Peter Zijlstra
2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
2021-06-24  9:41 ` [PATCH v2 09/24] x86: Always inline ip_within_syscall_gap() Peter Zijlstra
2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
2021-06-24  9:41 ` [PATCH v2 10/24] x86/sev: Fix noinstr for vc_ghcb_invalidate() Peter Zijlstra
2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
2021-06-24  9:41 ` [PATCH v2 11/24] locking/lockdep: Avoid RCU-induced noinstr fail Peter Zijlstra
2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
2021-06-24  9:41 ` [PATCH v2 12/24] x86/paravirt: Mark arch_local_irq_*() __always_inline Peter Zijlstra
2021-06-24 10:51   ` Juergen Gross
2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
2021-06-24  9:41 ` [PATCH v2 13/24] x86/paravirt: Use PVOP_* for paravirt calls Peter Zijlstra
2021-06-24 10:52   ` Juergen Gross
2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
2021-06-24  9:41 ` [PATCH v2 14/24] x86/xen: Make read_cr2() noinstr Peter Zijlstra
2021-06-24 10:55   ` Juergen Gross
2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
2021-06-24  9:41 ` [PATCH v2 15/24] x86/xen: Make write_cr2() noinstr Peter Zijlstra
2021-06-24 10:56   ` Juergen Gross
2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
2021-06-24  9:41 ` [PATCH v2 16/24] x86/xen: Make get_debugreg() noinstr Peter Zijlstra
2021-06-24 10:57   ` Juergen Gross
2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
2021-06-24  9:41 ` [PATCH v2 17/24] x86/xen: Make set_debugreg() noinstr Peter Zijlstra
2021-06-24 10:59   ` Juergen Gross
2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
2021-06-24  9:41 ` [PATCH v2 18/24] x86/xen: Make save_fl() noinstr Peter Zijlstra
2021-06-24 11:07   ` Juergen Gross
2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
2021-06-24  9:41 ` [PATCH v2 19/24] x86/xen: Make hypercall_page noinstr Peter Zijlstra
2021-06-24 11:08   ` Juergen Gross
2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
2021-06-24  9:41 ` [PATCH v2 20/24] x86/xen: Make irq_enable() noinstr Peter Zijlstra
2021-06-24 11:09   ` Juergen Gross
2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
2021-06-24  9:41 ` [PATCH v2 21/24] x86/xen: Make irq_disable() noinstr Peter Zijlstra
2021-06-24 11:10   ` Juergen Gross
2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
2021-06-24  9:41 ` [PATCH v2 22/24] x86/xen: Mark xen_force_evtchn_callback() noinstr Peter Zijlstra
2021-06-24 11:11   ` Juergen Gross
2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
2021-06-24  9:41 ` [PATCH v2 23/24] x86/xen: Rework the xen_{cpu,irq,mmu}_ops[] arrays Peter Zijlstra
2021-06-24 12:12   ` Juergen Gross
2021-09-15 15:49   ` [tip: objtool/core] x86/xen: Rework the xen_{cpu,irq,mmu}_opsarrays tip-bot2 for Peter Zijlstra
2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
2021-06-24  9:41 ` [PATCH v2 24/24] objtool: Support pv_opsindirect calls for noinstr Peter Zijlstra
2021-09-15 15:49   ` [tip: objtool/core] " tip-bot2 for Peter Zijlstra
2021-09-17 12:58   ` tip-bot2 for Peter Zijlstra
2021-06-24 13:05 ` [PATCH v2 00/24] objtool/x86: noinstr vs PARAVIRT Steven Rostedt

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.