diff options
author | Daniel Borkmann <daniel@iogearbox.net> | 2018-05-04 01:08:23 +0200 |
---|---|---|
committer | Alexei Starovoitov <ast@kernel.org> | 2018-05-03 16:49:20 -0700 |
commit | 24dea04767e6e5175f4750770281b0c17ac6a2fb (patch) | |
tree | 93a7d7735ef6e781917d4d108a2f06c0194102c4 /arch/x86/net | |
parent | e1cf4befa297b149149f633eff746593e400c030 (diff) | |
download | linux-24dea04767e6e5175f4750770281b0c17ac6a2fb.tar.bz2 |
bpf, x32: remove ld_abs/ld_ind
Since LD_ABS/LD_IND instructions are now removed from the core and
reimplemented through a combination of inlined BPF instructions and
a slow-path helper, we can get rid of the complexity from x32 JIT.
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Diffstat (limited to 'arch/x86/net')
-rw-r--r-- | arch/x86/net/bpf_jit_comp32.c | 136 |
1 files changed, 1 insertions, 135 deletions
diff --git a/arch/x86/net/bpf_jit_comp32.c b/arch/x86/net/bpf_jit_comp32.c index 61e61341b777..0cc04e30adc1 100644 --- a/arch/x86/net/bpf_jit_comp32.c +++ b/arch/x86/net/bpf_jit_comp32.c @@ -175,19 +175,13 @@ static const u8 bpf2ia32[][2] = { #define SCRATCH_SIZE 96 /* Total stack size used in JITed code */ -#define _STACK_SIZE \ - (stack_depth + \ - + SCRATCH_SIZE + \ - + 4 /* Extra space for skb_copy_bits buffer */) +#define _STACK_SIZE (stack_depth + SCRATCH_SIZE) #define STACK_SIZE ALIGN(_STACK_SIZE, STACK_ALIGNMENT) /* Get the offset of eBPF REGISTERs stored on scratch space. */ #define STACK_VAR(off) (off) -/* Offset of skb_copy_bits buffer */ -#define SKB_BUFFER STACK_VAR(SCRATCH_SIZE) - /* Encode 'dst_reg' register into IA32 opcode 'byte' */ static u8 add_1reg(u8 byte, u32 dst_reg) { @@ -2276,134 +2270,6 @@ emit_jmp: return -EFAULT; } break; - - case BPF_LD | BPF_ABS | BPF_W: - case BPF_LD | BPF_ABS | BPF_H: - case BPF_LD | BPF_ABS | BPF_B: - case BPF_LD | BPF_IND | BPF_W: - case BPF_LD | BPF_IND | BPF_H: - case BPF_LD | BPF_IND | BPF_B: - { - int size; - const u8 *r6 = bpf2ia32[BPF_REG_6]; - - /* Setting up first argument */ - /* mov eax,dword ptr [ebp+off] */ - EMIT3(0x8B, add_2reg(0x40, IA32_EBP, IA32_EAX), - STACK_VAR(r6[0])); - - /* Setting up second argument */ - if (BPF_MODE(code) == BPF_ABS) { - /* mov %edx, imm32 */ - EMIT1_off32(0xBA, imm32); - } else { - if (sstk) - /* mov edx,dword ptr [ebp+off] */ - EMIT3(0x8B, add_2reg(0x40, IA32_EBP, - IA32_EDX), - STACK_VAR(src_lo)); - else - /* mov edx,src_lo */ - EMIT2(0x8B, add_2reg(0xC0, src_lo, - IA32_EDX)); - if (imm32) { - if (is_imm8(imm32)) - /* add %edx,imm8 */ - EMIT3(0x83, 0xC2, imm32); - else - /* add %edx,imm32 */ - EMIT2_off32(0x81, 0xC2, imm32); - } - } - - /* Setting up third argument */ - switch (BPF_SIZE(code)) { - case BPF_W: - size = 4; - break; - case BPF_H: - size = 2; - break; - case BPF_B: - size = 1; - break; - default: - return -EINVAL; - } - /* mov ecx,val */ - EMIT2(0xB1, size); - /* movzx ecx,ecx */ - EMIT3(0x0F, 0xB6, add_2reg(0xC0, IA32_ECX, IA32_ECX)); - - /* mov ebx,ebp */ - EMIT2(0x8B, add_2reg(0xC0, IA32_EBP, IA32_EBX)); - /* add %ebx,imm8 */ - EMIT3(0x83, add_1reg(0xC0, IA32_EBX), SKB_BUFFER); - /* push ebx */ - EMIT1(0x53); - - /* Setting up function pointer to call */ - /* mov ebx,imm32*/ - EMIT2_off32(0xC7, add_1reg(0xC0, IA32_EBX), - (unsigned int)bpf_load_pointer); - - EMIT2(0xFF, add_1reg(0xD0, IA32_EBX)); - /* add %esp,4 */ - EMIT3(0x83, add_1reg(0xC0, IA32_ESP), 4); - /* xor edx,edx */ - EMIT2(0x33, add_2reg(0xC0, IA32_EDX, IA32_EDX)); - - /* mov dword ptr [ebp+off],eax */ - EMIT3(0x89, add_2reg(0x40, IA32_EBP, IA32_EDX), - STACK_VAR(r0[0])); - /* mov dword ptr [ebp+off],edx */ - EMIT3(0x89, add_2reg(0x40, IA32_EBP, IA32_EDX), - STACK_VAR(r0[1])); - - /* - * Check if return address is NULL or not. - * If NULL then jump to epilogue else continue - * to load the value from retn address - */ - EMIT3(0x83, add_1reg(0xF8, IA32_EAX), 0); - jmp_offset = ctx->cleanup_addr - addrs[i]; - - switch (BPF_SIZE(code)) { - case BPF_W: - jmp_offset += 7; - break; - case BPF_H: - jmp_offset += 10; - break; - case BPF_B: - jmp_offset += 6; - break; - } - - EMIT2_off32(0x0F, IA32_JE + 0x10, jmp_offset); - /* Load value from the address */ - switch (BPF_SIZE(code)) { - case BPF_W: - /* mov eax,[eax] */ - EMIT2(0x8B, 0x0); - /* Emit 'bswap eax' */ - EMIT2(0x0F, add_1reg(0xC8, IA32_EAX)); - break; - case BPF_H: - EMIT3(0x0F, 0xB7, 0x0); - EMIT1(0x66); - EMIT3(0xC1, add_1reg(0xC8, IA32_EAX), 8); - break; - case BPF_B: - EMIT3(0x0F, 0xB6, 0x0); - break; - } - - /* mov dword ptr [ebp+off],eax */ - EMIT3(0x89, add_2reg(0x40, IA32_EBP, IA32_EAX), - STACK_VAR(r0[0])); - break; - } /* STX XADD: lock *(u32 *)(dst + off) += src */ case BPF_STX | BPF_XADD | BPF_W: /* STX XADD: lock *(u64 *)(dst + off) += src */ |