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

Commit 606c88a8 authored by Daniel Borkmann's avatar Daniel Borkmann Committed by David S. Miller
Browse files

bpf, x86: detect/optimize loading 0 immediates



When sometimes structs or variables need to be initialized/'memset' to 0 in
an eBPF C program, the x86 BPF JIT converts this to use immediates. We can
however save a couple of bytes (f.e. even up to 7 bytes on a single emmission
of BPF_LD | BPF_IMM | BPF_DW) in the image by detecting such case and use xor
on the dst register instead.

Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Acked-by: default avatarAlexei Starovoitov <ast@kernel.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 23bf8807
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -459,6 +459,18 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
			}

		case BPF_ALU | BPF_MOV | BPF_K:
			/* optimization: if imm32 is zero, use 'xor <dst>,<dst>'
			 * to save 3 bytes.
			 */
			if (imm32 == 0) {
				if (is_ereg(dst_reg))
					EMIT1(add_2mod(0x40, dst_reg, dst_reg));
				b2 = 0x31; /* xor */
				b3 = 0xC0;
				EMIT2(b2, add_2reg(b3, dst_reg, dst_reg));
				break;
			}

			/* mov %eax, imm32 */
			if (is_ereg(dst_reg))
				EMIT1(add_1mod(0x40, dst_reg));
@@ -473,6 +485,20 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
				return -EINVAL;
			}

			/* optimization: if imm64 is zero, use 'xor <dst>,<dst>'
			 * to save 7 bytes.
			 */
			if (insn[0].imm == 0 && insn[1].imm == 0) {
				b1 = add_2mod(0x48, dst_reg, dst_reg);
				b2 = 0x31; /* xor */
				b3 = 0xC0;
				EMIT3(b1, b2, add_2reg(b3, dst_reg, dst_reg));

				insn++;
				i++;
				break;
			}

			/* movabsq %rax, imm64 */
			EMIT2(add_1mod(0x48, dst_reg), add_1reg(0xB8, dst_reg));
			EMIT(insn[0].imm, 4);