Commit 857f1268 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'objtool-core-2023-03-02' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull objtool updates from Ingo Molnar:

 - Shrink 'struct instruction', to improve objtool performance & memory
   footprint

 - Other maximum memory usage reductions - this makes the build both
   faster, and fixes kernel build OOM failures on allyesconfig and
   similar configs when they try to build the final (large) vmlinux.o

 - Fix ORC unwinding when a kprobe (INT3) is set on a stack-modifying
   single-byte instruction (PUSH/POP or LEAVE). This requires the
   extension of the ORC metadata structure with a 'signal' field

 - Misc fixes & cleanups

* tag 'objtool-core-2023-03-02' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (22 commits)
  objtool: Fix ORC 'signal' propagation
  objtool: Remove instruction::list
  x86: Fix FILL_RETURN_BUFFER
  objtool: Fix overlapping alternatives
  objtool: Union instruction::{call_dest,jump_table}
  objtool: Remove instruction::reloc
  objtool: Shrink instruction::{type,visited}
  objtool: Make instruction::alts a single-linked list
  objtool: Make instruction::stack_ops a single-linked list
  objtool: Change arch_decode_instruction() signature
  x86/entry: Fix unwinding from kprobe on PUSH/POP instruction
  x86/unwind/orc: Add 'signal' field to ORC metadata
  objtool: Optimize layout of struct special_alt
  objtool: Optimize layout of struct symbol
  objtool: Allocate multiple structures with calloc()
  objtool: Make struct check_options static
  objtool: Make struct entries[] static and const
  objtool: Fix HOSTCC flag usage
  objtool: Properly support make V=1
  objtool: Install libsubcmd in build
  ...
parents 6972633c 00c8f01c
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -385,7 +385,14 @@ SYM_CODE_END(xen_error_entry)
 */
.macro idtentry vector asmsym cfunc has_error_code:req
SYM_CODE_START(\asmsym)

	.if \vector == X86_TRAP_BP
		/* #BP advances %rip to the next instruction */
		UNWIND_HINT_IRET_REGS offset=\has_error_code*8 signal=0
	.else
		UNWIND_HINT_IRET_REGS offset=\has_error_code*8
	.endif

	ENDBR
	ASM_CLAC
	cld
+1 −1
Original line number Diff line number Diff line
@@ -261,7 +261,7 @@
.macro FILL_RETURN_BUFFER reg:req nr:req ftr:req ftr2=ALT_NOT(X86_FEATURE_ALWAYS)
	ALTERNATIVE_2 "jmp .Lskip_rsb_\@", \
		__stringify(__FILL_RETURN_BUFFER(\reg,\nr)), \ftr, \
		__stringify(__FILL_ONE_RETURN), \ftr2
		__stringify(nop;nop;__FILL_ONE_RETURN), \ftr2

.Lskip_rsb_\@:
.endm
+3 −1
Original line number Diff line number Diff line
@@ -57,12 +57,14 @@ struct orc_entry {
	unsigned	sp_reg:4;
	unsigned	bp_reg:4;
	unsigned	type:2;
	unsigned	signal:1;
	unsigned	end:1;
#elif defined(__BIG_ENDIAN_BITFIELD)
	unsigned	bp_reg:4;
	unsigned	sp_reg:4;
	unsigned	unused:5;
	unsigned	unused:4;
	unsigned	end:1;
	unsigned	signal:1;
	unsigned	type:2;
#endif
} __packed;
+5 −5
Original line number Diff line number Diff line
@@ -15,7 +15,7 @@
	UNWIND_HINT type=UNWIND_HINT_TYPE_ENTRY end=1
.endm

.macro UNWIND_HINT_REGS base=%rsp offset=0 indirect=0 extra=1 partial=0
.macro UNWIND_HINT_REGS base=%rsp offset=0 indirect=0 extra=1 partial=0 signal=1
	.if \base == %rsp
		.if \indirect
			.set sp_reg, ORC_REG_SP_INDIRECT
@@ -45,11 +45,11 @@
		.set type, UNWIND_HINT_TYPE_REGS
	.endif

	UNWIND_HINT sp_reg=sp_reg sp_offset=sp_offset type=type
	UNWIND_HINT sp_reg=sp_reg sp_offset=sp_offset type=type signal=\signal
.endm

.macro UNWIND_HINT_IRET_REGS base=%rsp offset=0
	UNWIND_HINT_REGS base=\base offset=\offset partial=1
.macro UNWIND_HINT_IRET_REGS base=%rsp offset=0 signal=1
	UNWIND_HINT_REGS base=\base offset=\offset partial=1 signal=\signal
.endm

.macro UNWIND_HINT_FUNC
@@ -67,7 +67,7 @@
#else

#define UNWIND_HINT_FUNC \
	UNWIND_HINT(ORC_REG_SP, 8, UNWIND_HINT_TYPE_FUNC, 0)
	UNWIND_HINT(ORC_REG_SP, 8, UNWIND_HINT_TYPE_FUNC, 0, 0)

#endif /* __ASSEMBLY__ */

+2 −3
Original line number Diff line number Diff line
@@ -484,6 +484,8 @@ bool unwind_next_frame(struct unwind_state *state)
		goto the_end;
	}

	state->signal = orc->signal;

	/* Find the previous frame's stack: */
	switch (orc->sp_reg) {
	case ORC_REG_SP:
@@ -563,7 +565,6 @@ bool unwind_next_frame(struct unwind_state *state)
		state->sp = sp;
		state->regs = NULL;
		state->prev_regs = NULL;
		state->signal = false;
		break;

	case UNWIND_HINT_TYPE_REGS:
@@ -587,7 +588,6 @@ bool unwind_next_frame(struct unwind_state *state)
		state->regs = (struct pt_regs *)sp;
		state->prev_regs = NULL;
		state->full_regs = true;
		state->signal = true;
		break;

	case UNWIND_HINT_TYPE_REGS_PARTIAL:
@@ -604,7 +604,6 @@ bool unwind_next_frame(struct unwind_state *state)
			state->prev_regs = state->regs;
		state->regs = (void *)sp - IRET_FRAME_OFFSET;
		state->full_regs = false;
		state->signal = true;
		break;

	default:
Loading