This is an eBPF JIT for sparc64. All major features are supported. All tests under tools/testing/selftests/bpf/ pass. Signed-off-by: David S. Miller <davem@davemloft.net>tirimbino
parent
6b3d4eec7f
commit
7a12b5031c
@ -0,0 +1,66 @@ |
||||
#ifndef _BPF_JIT_H |
||||
#define _BPF_JIT_H |
||||
|
||||
#ifndef __ASSEMBLER__ |
||||
#define G0 0x00 |
||||
#define G1 0x01 |
||||
#define G2 0x02 |
||||
#define G3 0x03 |
||||
#define G6 0x06 |
||||
#define G7 0x07 |
||||
#define O0 0x08 |
||||
#define O1 0x09 |
||||
#define O2 0x0a |
||||
#define O3 0x0b |
||||
#define O4 0x0c |
||||
#define O5 0x0d |
||||
#define SP 0x0e |
||||
#define O7 0x0f |
||||
#define L0 0x10 |
||||
#define L1 0x11 |
||||
#define L2 0x12 |
||||
#define L3 0x13 |
||||
#define L4 0x14 |
||||
#define L5 0x15 |
||||
#define L6 0x16 |
||||
#define L7 0x17 |
||||
#define I0 0x18 |
||||
#define I1 0x19 |
||||
#define I2 0x1a |
||||
#define I3 0x1b |
||||
#define I4 0x1c |
||||
#define I5 0x1d |
||||
#define FP 0x1e |
||||
#define I7 0x1f |
||||
|
||||
#define r_SKB L0 |
||||
#define r_HEADLEN L4 |
||||
#define r_SKB_DATA L5 |
||||
#define r_TMP G1 |
||||
#define r_TMP2 G3 |
||||
|
||||
/* assembly code in arch/sparc/net/bpf_jit_asm_64.S */ |
||||
extern u32 bpf_jit_load_word[]; |
||||
extern u32 bpf_jit_load_half[]; |
||||
extern u32 bpf_jit_load_byte[]; |
||||
extern u32 bpf_jit_load_byte_msh[]; |
||||
extern u32 bpf_jit_load_word_positive_offset[]; |
||||
extern u32 bpf_jit_load_half_positive_offset[]; |
||||
extern u32 bpf_jit_load_byte_positive_offset[]; |
||||
extern u32 bpf_jit_load_byte_msh_positive_offset[]; |
||||
extern u32 bpf_jit_load_word_negative_offset[]; |
||||
extern u32 bpf_jit_load_half_negative_offset[]; |
||||
extern u32 bpf_jit_load_byte_negative_offset[]; |
||||
extern u32 bpf_jit_load_byte_msh_negative_offset[]; |
||||
|
||||
#else |
||||
#define r_RESULT %o0 |
||||
#define r_SKB %o0 |
||||
#define r_OFF %o1 |
||||
#define r_HEADLEN %l4 |
||||
#define r_SKB_DATA %l5 |
||||
#define r_TMP %g1 |
||||
#define r_TMP2 %g3 |
||||
#endif |
||||
|
||||
#endif /* _BPF_JIT_H */ |
@ -1 +1,161 @@ |
||||
#include "bpf_jit_asm_32.S" |
||||
#include <asm/ptrace.h> |
||||
|
||||
#include "bpf_jit_64.h" |
||||
|
||||
#define SAVE_SZ 176 |
||||
#define SCRATCH_OFF STACK_BIAS + 128 |
||||
#define BE_PTR(label) be,pn %xcc, label |
||||
#define SIGN_EXTEND(reg) sra reg, 0, reg |
||||
|
||||
#define SKF_MAX_NEG_OFF (-0x200000) /* SKF_LL_OFF from filter.h */ |
||||
|
||||
.text |
||||
.globl bpf_jit_load_word
|
||||
bpf_jit_load_word: |
||||
cmp r_OFF, 0 |
||||
bl bpf_slow_path_word_neg |
||||
nop |
||||
.globl bpf_jit_load_word_positive_offset
|
||||
bpf_jit_load_word_positive_offset: |
||||
sub r_HEADLEN, r_OFF, r_TMP |
||||
cmp r_TMP, 3 |
||||
ble bpf_slow_path_word |
||||
add r_SKB_DATA, r_OFF, r_TMP |
||||
andcc r_TMP, 3, %g0 |
||||
bne load_word_unaligned |
||||
nop |
||||
retl |
||||
ld [r_TMP], r_RESULT |
||||
load_word_unaligned: |
||||
ldub [r_TMP + 0x0], r_OFF |
||||
ldub [r_TMP + 0x1], r_TMP2 |
||||
sll r_OFF, 8, r_OFF |
||||
or r_OFF, r_TMP2, r_OFF |
||||
ldub [r_TMP + 0x2], r_TMP2 |
||||
sll r_OFF, 8, r_OFF |
||||
or r_OFF, r_TMP2, r_OFF |
||||
ldub [r_TMP + 0x3], r_TMP2 |
||||
sll r_OFF, 8, r_OFF |
||||
retl |
||||
or r_OFF, r_TMP2, r_RESULT |
||||
|
||||
.globl bpf_jit_load_half
|
||||
bpf_jit_load_half: |
||||
cmp r_OFF, 0 |
||||
bl bpf_slow_path_half_neg |
||||
nop |
||||
.globl bpf_jit_load_half_positive_offset
|
||||
bpf_jit_load_half_positive_offset: |
||||
sub r_HEADLEN, r_OFF, r_TMP |
||||
cmp r_TMP, 1 |
||||
ble bpf_slow_path_half |
||||
add r_SKB_DATA, r_OFF, r_TMP |
||||
andcc r_TMP, 1, %g0 |
||||
bne load_half_unaligned |
||||
nop |
||||
retl |
||||
lduh [r_TMP], r_RESULT |
||||
load_half_unaligned: |
||||
ldub [r_TMP + 0x0], r_OFF |
||||
ldub [r_TMP + 0x1], r_TMP2 |
||||
sll r_OFF, 8, r_OFF |
||||
retl |
||||
or r_OFF, r_TMP2, r_RESULT |
||||
|
||||
.globl bpf_jit_load_byte
|
||||
bpf_jit_load_byte: |
||||
cmp r_OFF, 0 |
||||
bl bpf_slow_path_byte_neg |
||||
nop |
||||
.globl bpf_jit_load_byte_positive_offset
|
||||
bpf_jit_load_byte_positive_offset: |
||||
cmp r_OFF, r_HEADLEN |
||||
bge bpf_slow_path_byte |
||||
nop |
||||
retl |
||||
ldub [r_SKB_DATA + r_OFF], r_RESULT |
||||
|
||||
#define bpf_slow_path_common(LEN) \ |
||||
save %sp, -SAVE_SZ, %sp; \
|
||||
mov %i0, %o0; \
|
||||
mov %i1, %o1; \
|
||||
add %fp, SCRATCH_OFF, %o2; \
|
||||
call skb_copy_bits; \
|
||||
mov (LEN), %o3; \
|
||||
cmp %o0, 0; \
|
||||
restore;
|
||||
|
||||
bpf_slow_path_word: |
||||
bpf_slow_path_common(4) |
||||
bl bpf_error |
||||
ld [%sp + SCRATCH_OFF], r_RESULT |
||||
retl |
||||
nop |
||||
bpf_slow_path_half: |
||||
bpf_slow_path_common(2) |
||||
bl bpf_error |
||||
lduh [%sp + SCRATCH_OFF], r_RESULT |
||||
retl |
||||
nop |
||||
bpf_slow_path_byte: |
||||
bpf_slow_path_common(1) |
||||
bl bpf_error |
||||
ldub [%sp + SCRATCH_OFF], r_RESULT |
||||
retl |
||||
nop |
||||
|
||||
#define bpf_negative_common(LEN) \ |
||||
save %sp, -SAVE_SZ, %sp; \
|
||||
mov %i0, %o0; \
|
||||
mov %i1, %o1; \
|
||||
SIGN_EXTEND(%o1); \
|
||||
call bpf_internal_load_pointer_neg_helper; \
|
||||
mov (LEN), %o2; \
|
||||
mov %o0, r_TMP; \
|
||||
cmp %o0, 0; \
|
||||
BE_PTR(bpf_error); \
|
||||
restore;
|
||||
|
||||
bpf_slow_path_word_neg: |
||||
sethi %hi(SKF_MAX_NEG_OFF), r_TMP |
||||
cmp r_OFF, r_TMP |
||||
bl bpf_error |
||||
nop |
||||
.globl bpf_jit_load_word_negative_offset
|
||||
bpf_jit_load_word_negative_offset: |
||||
bpf_negative_common(4) |
||||
andcc r_TMP, 3, %g0 |
||||
bne load_word_unaligned |
||||
nop |
||||
retl |
||||
ld [r_TMP], r_RESULT |
||||
|
||||
bpf_slow_path_half_neg: |
||||
sethi %hi(SKF_MAX_NEG_OFF), r_TMP |
||||
cmp r_OFF, r_TMP |
||||
bl bpf_error |
||||
nop |
||||
.globl bpf_jit_load_half_negative_offset
|
||||
bpf_jit_load_half_negative_offset: |
||||
bpf_negative_common(2) |
||||
andcc r_TMP, 1, %g0 |
||||
bne load_half_unaligned |
||||
nop |
||||
retl |
||||
lduh [r_TMP], r_RESULT |
||||
|
||||
bpf_slow_path_byte_neg: |
||||
sethi %hi(SKF_MAX_NEG_OFF), r_TMP |
||||
cmp r_OFF, r_TMP |
||||
bl bpf_error |
||||
nop |
||||
.globl bpf_jit_load_byte_negative_offset
|
||||
bpf_jit_load_byte_negative_offset: |
||||
bpf_negative_common(1) |
||||
retl |
||||
ldub [r_TMP], r_RESULT |
||||
|
||||
bpf_error: |
||||
/* Make the JIT program itself return zero. */ |
||||
ret |
||||
restore %g0, %g0, %o0 |
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue