Commit 00bc8988 authored by Leon Hwang's avatar Leon Hwang Committed by Alexei Starovoitov
Browse files

bpf, x86: Use emit_nops to replace memcpy x86_nops



Move emit_nops() before emit_prologue() and replace
memcpy(prog, x86_nops[5], X86_PATCH_SIZE) with emit_nops(&prog, X86_PATCH_SIZE).

Signed-off-by: default avatarLeon Hwang <hffilwlqm@gmail.com>
Link: https://lore.kernel.org/r/20240104142226.87869-2-hffilwlqm@gmail.com


Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent 61a40c12
Loading
Loading
Loading
Loading
+22 −25
Original line number Diff line number Diff line
@@ -307,6 +307,25 @@ static void pop_callee_regs(u8 **pprog, bool *callee_regs_used)
	*pprog = prog;
}

static void emit_nops(u8 **pprog, int len)
{
	u8 *prog = *pprog;
	int i, noplen;

	while (len > 0) {
		noplen = len;

		if (noplen > ASM_NOP_MAX)
			noplen = ASM_NOP_MAX;

		for (i = 0; i < noplen; i++)
			EMIT1(x86_nops[noplen][i]);
		len -= noplen;
	}

	*pprog = prog;
}

/*
 * Emit the various CFI preambles, see asm/cfi.h and the comments about FineIBT
 * in arch/x86/kernel/alternative.c
@@ -385,8 +404,7 @@ static void emit_prologue(u8 **pprog, u32 stack_depth, bool ebpf_from_cbpf,
	/* BPF trampoline can be made to work without these nops,
	 * but let's waste 5 bytes for now and optimize later
	 */
	memcpy(prog, x86_nops[5], X86_PATCH_SIZE);
	prog += X86_PATCH_SIZE;
	emit_nops(&prog, X86_PATCH_SIZE);
	if (!ebpf_from_cbpf) {
		if (tail_call_reachable && !is_subprog)
			/* When it's the entry of the whole tailcall context,
@@ -692,8 +710,7 @@ static void emit_bpf_tail_call_direct(struct bpf_prog *bpf_prog,
	if (stack_depth)
		EMIT3_off32(0x48, 0x81, 0xC4, round_up(stack_depth, 8));

	memcpy(prog, x86_nops[5], X86_PATCH_SIZE);
	prog += X86_PATCH_SIZE;
	emit_nops(&prog, X86_PATCH_SIZE);

	/* out: */
	ctx->tail_call_direct_label = prog - start;
@@ -1055,25 +1072,6 @@ static void detect_reg_usage(struct bpf_insn *insn, int insn_cnt,
	}
}

static void emit_nops(u8 **pprog, int len)
{
	u8 *prog = *pprog;
	int i, noplen;

	while (len > 0) {
		noplen = len;

		if (noplen > ASM_NOP_MAX)
			noplen = ASM_NOP_MAX;

		for (i = 0; i < noplen; i++)
			EMIT1(x86_nops[noplen][i]);
		len -= noplen;
	}

	*pprog = prog;
}

/* emit the 3-byte VEX prefix
 *
 * r: same as rex.r, extra bit for ModRM reg field
@@ -2700,8 +2698,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
		/* remember return value in a stack for bpf prog to access */
		emit_stx(&prog, BPF_DW, BPF_REG_FP, BPF_REG_0, -8);
		im->ip_after_call = image + (prog - (u8 *)rw_image);
		memcpy(prog, x86_nops[5], X86_PATCH_SIZE);
		prog += X86_PATCH_SIZE;
		emit_nops(&prog, X86_PATCH_SIZE);
	}

	if (fmod_ret->nr_links) {