mirror of
https://github.com/ukui/kernel.git
synced 2026-03-09 10:07:04 -07:00
net: filter: Just In Time compiler for sparc
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -30,6 +30,7 @@ config SPARC
|
||||
select USE_GENERIC_SMP_HELPERS if SMP
|
||||
select GENERIC_PCI_IOMAP
|
||||
select HAVE_NMI_WATCHDOG if SPARC64
|
||||
select HAVE_BPF_JIT
|
||||
|
||||
config SPARC32
|
||||
def_bool !64BIT
|
||||
|
||||
@@ -66,6 +66,7 @@ head-y += arch/sparc/kernel/init_task.o
|
||||
|
||||
core-y += arch/sparc/kernel/
|
||||
core-y += arch/sparc/mm/ arch/sparc/math-emu/
|
||||
core-y += arch/sparc/net/
|
||||
|
||||
libs-y += arch/sparc/prom/
|
||||
libs-y += arch/sparc/lib/
|
||||
|
||||
4
arch/sparc/net/Makefile
Normal file
4
arch/sparc/net/Makefile
Normal file
@@ -0,0 +1,4 @@
|
||||
#
|
||||
# Arch-specific network modules
|
||||
#
|
||||
obj-$(CONFIG_BPF_JIT) += bpf_jit_asm.o bpf_jit_comp.o
|
||||
52
arch/sparc/net/bpf_jit.h
Normal file
52
arch/sparc/net/bpf_jit.h
Normal file
@@ -0,0 +1,52 @@
|
||||
#ifndef _BPF_JIT_H
|
||||
#define _BPF_JIT_H
|
||||
|
||||
/* Conventions:
|
||||
* %g1 : temporary
|
||||
* %g2 : Secondary temporary used by SKB data helper stubs.
|
||||
* %o0 : pointer to skb (first argument given to JIT function)
|
||||
* %o1 : BPF A accumulator
|
||||
* %o2 : BPF X accumulator
|
||||
* %o3 : Holds saved %o7 so we can call helper functions without needing
|
||||
* to allocate a register window.
|
||||
* %o4 : skb->data
|
||||
* %o5 : skb->len - skb->data_len
|
||||
*/
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
#define G0 0x00
|
||||
#define G1 0x01
|
||||
#define G3 0x03
|
||||
#define G6 0x06
|
||||
#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 FP 0x1e
|
||||
|
||||
#define r_SKB O0
|
||||
#define r_A O1
|
||||
#define r_X O2
|
||||
#define r_saved_O7 O3
|
||||
#define r_HEADLEN O4
|
||||
#define r_SKB_DATA O5
|
||||
#define r_TMP G1
|
||||
#define r_TMP2 G2
|
||||
#define r_OFF G3
|
||||
#else
|
||||
#define r_SKB %o0
|
||||
#define r_A %o1
|
||||
#define r_X %o2
|
||||
#define r_saved_O7 %o3
|
||||
#define r_HEADLEN %o4
|
||||
#define r_SKB_DATA %o5
|
||||
#define r_TMP %g1
|
||||
#define r_TMP2 %g2
|
||||
#define r_OFF %g3
|
||||
#endif
|
||||
|
||||
#endif /* _BPF_JIT_H */
|
||||
199
arch/sparc/net/bpf_jit_asm.S
Normal file
199
arch/sparc/net/bpf_jit_asm.S
Normal file
@@ -0,0 +1,199 @@
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
#include "bpf_jit.h"
|
||||
|
||||
#ifdef CONFIG_SPARC64
|
||||
#define SAVE_SZ 176
|
||||
#define SCRATCH_OFF STACK_BIAS + 128
|
||||
#define BE_PTR(label) be,pn %xcc, label
|
||||
#else
|
||||
#define SAVE_SZ 96
|
||||
#define SCRATCH_OFF 72
|
||||
#define BE_PTR(label) be label
|
||||
#endif
|
||||
|
||||
#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_SKB_DATA + r_OFF], r_A
|
||||
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_A
|
||||
|
||||
.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_SKB_DATA + r_OFF], r_A
|
||||
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_A
|
||||
|
||||
.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_A
|
||||
|
||||
.globl bpf_jit_load_byte_msh
|
||||
bpf_jit_load_byte_msh:
|
||||
cmp r_OFF, 0
|
||||
bl bpf_slow_path_byte_msh_neg
|
||||
nop
|
||||
.globl bpf_jit_load_byte_msh_positive_offset
|
||||
bpf_jit_load_byte_msh_positive_offset:
|
||||
cmp r_OFF, r_HEADLEN
|
||||
bge bpf_slow_path_byte_msh
|
||||
nop
|
||||
ldub [r_SKB_DATA + r_OFF], r_OFF
|
||||
and r_OFF, 0xf, r_OFF
|
||||
retl
|
||||
sll r_OFF, 2, r_X
|
||||
|
||||
#define bpf_slow_path_common(LEN) \
|
||||
save %sp, -SAVE_SZ, %sp; \
|
||||
mov %i0, %o0; \
|
||||
mov r_OFF, %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_A
|
||||
retl
|
||||
nop
|
||||
bpf_slow_path_half:
|
||||
bpf_slow_path_common(2)
|
||||
bl bpf_error
|
||||
lduh [%sp + SCRATCH_OFF], r_A
|
||||
retl
|
||||
nop
|
||||
bpf_slow_path_byte:
|
||||
bpf_slow_path_common(1)
|
||||
bl bpf_error
|
||||
ldub [%sp + SCRATCH_OFF], r_A
|
||||
retl
|
||||
nop
|
||||
bpf_slow_path_byte_msh:
|
||||
bpf_slow_path_common(1)
|
||||
bl bpf_error
|
||||
ldub [%sp + SCRATCH_OFF], r_A
|
||||
and r_OFF, 0xf, r_OFF
|
||||
retl
|
||||
sll r_OFF, 2, r_X
|
||||
|
||||
#define bpf_negative_common(LEN) \
|
||||
save %sp, -SAVE_SZ, %sp; \
|
||||
mov %i0, %o0; \
|
||||
mov r_OFF, %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_A
|
||||
|
||||
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_A
|
||||
|
||||
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_A
|
||||
|
||||
bpf_slow_path_byte_msh_neg:
|
||||
sethi %hi(SKF_MAX_NEG_OFF), r_TMP
|
||||
cmp r_OFF, r_TMP
|
||||
bl bpf_error
|
||||
nop
|
||||
.globl bpf_jit_load_byte_msh_negative_offset
|
||||
bpf_jit_load_byte_msh_negative_offset:
|
||||
bpf_negative_common(1)
|
||||
ldub [r_TMP], r_OFF
|
||||
and r_OFF, 0xf, r_OFF
|
||||
retl
|
||||
sll r_OFF, 2, r_X
|
||||
|
||||
bpf_error:
|
||||
jmpl r_saved_O7 + 8, %g0
|
||||
clr %o0
|
||||
785
arch/sparc/net/bpf_jit_comp.c
Normal file
785
arch/sparc/net/bpf_jit_comp.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user