2011-04-20 09:27:32 +00:00
/ * bpf_ j i t . S : B P F J I T h e l p e r f u n c t i o n s
*
* Copyright ( C ) 2 0 1 1 E r i c D u m a z e t ( e r i c . d u m a z e t @gmail.com)
*
* This p r o g r a m i s f r e e s o f t w a r e ; you can redistribute it and/or
* modify i t u n d e r t h e t e r m s o f t h e G N U G e n e r a l P u b l i c L i c e n s e
* as p u b l i s h e d b y t h e F r e e S o f t w a r e F o u n d a t i o n ; version 2
* of t h e L i c e n s e .
* /
# include < l i n u x / l i n k a g e . h >
# include < a s m / d w a r f2 . h >
/ *
* Calling c o n v e n t i o n :
* rdi : s k b p o i n t e r
* esi : o f f s e t o f b y t e ( s ) t o f e t c h i n s k b ( c a n b e s c r a t c h e d )
* r8 : c o p y o f s k b - > d a t a
* r9 d : h l e n = s k b - > l e n - s k b - > d a t a _ l e n
* /
# define S K B D A T A % r8
2012-03-30 05:24:05 +00:00
# define S K F _ M A X _ N E G _ O F F $ ( - 0 x20 0 0 0 0 ) / * S K F _ L L _ O F F f r o m f i l t e r . h * /
2011-04-20 09:27:32 +00:00
sk_load_word :
.globl sk_load_word
2012-03-30 05:24:05 +00:00
test % e s i ,% e s i
js b p f _ s l o w _ p a t h _ w o r d _ n e g
sk_load_word_positive_offset :
.globl sk_load_word_positive_offset
2011-04-20 09:27:32 +00:00
mov % r9 d ,% e a x # h l e n
sub % e s i ,% e a x # h l e n - o f f s e t
cmp $ 3 ,% e a x
jle b p f _ s l o w _ p a t h _ w o r d
mov ( S K B D A T A ,% r s i ) ,% e a x
bswap % e a x / * n t o h l ( ) * /
ret
sk_load_half :
.globl sk_load_half
2012-03-30 05:24:05 +00:00
test % e s i ,% e s i
js b p f _ s l o w _ p a t h _ h a l f _ n e g
sk_load_half_positive_offset :
.globl sk_load_half_positive_offset
2011-04-20 09:27:32 +00:00
mov % r9 d ,% e a x
sub % e s i ,% e a x # h l e n - o f f s e t
cmp $ 1 ,% e a x
jle b p f _ s l o w _ p a t h _ h a l f
movzwl ( S K B D A T A ,% r s i ) ,% e a x
rol $ 8 ,% a x # n t o h s ( )
ret
sk_load_byte :
.globl sk_load_byte
2012-03-30 05:24:05 +00:00
test % e s i ,% e s i
js b p f _ s l o w _ p a t h _ b y t e _ n e g
sk_load_byte_positive_offset :
.globl sk_load_byte_positive_offset
2011-04-20 09:27:32 +00:00
cmp % e s i ,% r9 d / * i f ( o f f s e t > = h l e n ) g o t o b p f _ s l o w _ p a t h _ b y t e * /
jle b p f _ s l o w _ p a t h _ b y t e
movzbl ( S K B D A T A ,% r s i ) ,% e a x
ret
/ * *
* sk_ l o a d _ b y t e _ m s h - B P F _ S _ L D X _ B _ M S H h e l p e r
*
* Implements B P F _ S _ L D X _ B _ M S H : l d x b 4 * ( [ o f f s e t ] & 0 x f )
* Must p r e s e r v e A a c c u m u l a t o r ( % e a x )
2012-03-30 05:24:05 +00:00
* Inputs : % e s i i s t h e o f f s e t v a l u e
2011-04-20 09:27:32 +00:00
* /
2012-03-30 05:24:05 +00:00
sk_load_byte_msh :
.globl sk_load_byte_msh
test % e s i ,% e s i
js b p f _ s l o w _ p a t h _ b y t e _ m s h _ n e g
sk_load_byte_msh_positive_offset :
.globl sk_load_byte_msh_positive_offset
2011-04-20 09:27:32 +00:00
cmp % e s i ,% r9 d / * i f ( o f f s e t > = h l e n ) g o t o b p f _ s l o w _ p a t h _ b y t e _ m s h * /
jle b p f _ s l o w _ p a t h _ b y t e _ m s h
movzbl ( S K B D A T A ,% r s i ) ,% e b x
and $ 1 5 ,% b l
shl $ 2 ,% b l
ret
/* rsi contains offset and can be scratched */
# define b p f _ s l o w _ p a t h _ c o m m o n ( L E N ) \
push % r d i ; /* save skb */ \
push % r9 ; \
push S K B D A T A ; \
/* rsi already has offset */ \
mov $ L E N ,% e c x ; /* len */ \
lea - 1 2 ( % r b p ) ,% r d x ; \
call s k b _ c o p y _ b i t s ; \
test % e a x ,% e a x ; \
pop S K B D A T A ; \
pop % r9 ; \
pop % r d i
bpf_slow_path_word :
bpf_ s l o w _ p a t h _ c o m m o n ( 4 )
js b p f _ e r r o r
mov - 1 2 ( % r b p ) ,% e a x
bswap % e a x
ret
bpf_slow_path_half :
bpf_ s l o w _ p a t h _ c o m m o n ( 2 )
js b p f _ e r r o r
mov - 1 2 ( % r b p ) ,% a x
rol $ 8 ,% a x
movzwl % a x ,% e a x
ret
bpf_slow_path_byte :
bpf_ s l o w _ p a t h _ c o m m o n ( 1 )
js b p f _ e r r o r
movzbl - 1 2 ( % r b p ) ,% e a x
ret
bpf_slow_path_byte_msh :
xchg % e a x ,% e b x / * d o n t l o s e A , X i s a b o u t t o b e s c r a t c h e d * /
bpf_ s l o w _ p a t h _ c o m m o n ( 1 )
js b p f _ e r r o r
movzbl - 1 2 ( % r b p ) ,% e a x
and $ 1 5 ,% a l
shl $ 2 ,% a l
xchg % e a x ,% e b x
ret
2012-03-30 05:24:05 +00:00
# define s k _ n e g a t i v e _ c o m m o n ( S I Z E ) \
push % r d i ; /* save skb */ \
push % r9 ; \
push S K B D A T A ; \
/* rsi already has offset */ \
2014-03-10 15:56:51 -07:00
mov $ S I Z E ,% e d x ; /* size */ \
2012-03-30 05:24:05 +00:00
call b p f _ i n t e r n a l _ l o a d _ p o i n t e r _ n e g _ h e l p e r ; \
test % r a x ,% r a x ; \
pop S K B D A T A ; \
pop % r9 ; \
pop % r d i ; \
jz b p f _ e r r o r
bpf_slow_path_word_neg :
cmp S K F _ M A X _ N E G _ O F F , % e s i / * t e s t r a n g e * /
jl b p f _ e r r o r / * o f f s e t l o w e r - > e r r o r * /
sk_load_word_negative_offset :
.globl sk_load_word_negative_offset
sk_ n e g a t i v e _ c o m m o n ( 4 )
mov ( % r a x ) , % e a x
bswap % e a x
ret
bpf_slow_path_half_neg :
cmp S K F _ M A X _ N E G _ O F F , % e s i
jl b p f _ e r r o r
sk_load_half_negative_offset :
.globl sk_load_half_negative_offset
sk_ n e g a t i v e _ c o m m o n ( 2 )
mov ( % r a x ) ,% a x
rol $ 8 ,% a x
movzwl % a x ,% e a x
ret
bpf_slow_path_byte_neg :
cmp S K F _ M A X _ N E G _ O F F , % e s i
jl b p f _ e r r o r
sk_load_byte_negative_offset :
.globl sk_load_byte_negative_offset
sk_ n e g a t i v e _ c o m m o n ( 1 )
movzbl ( % r a x ) , % e a x
ret
bpf_slow_path_byte_msh_neg :
cmp S K F _ M A X _ N E G _ O F F , % e s i
jl b p f _ e r r o r
sk_load_byte_msh_negative_offset :
.globl sk_load_byte_msh_negative_offset
xchg % e a x ,% e b x / * d o n t l o s e A , X i s a b o u t t o b e s c r a t c h e d * /
sk_ n e g a t i v e _ c o m m o n ( 1 )
movzbl ( % r a x ) ,% e a x
and $ 1 5 ,% a l
shl $ 2 ,% a l
xchg % e a x ,% e b x
ret
bpf_error :
# force a r e t u r n 0 f r o m j i t h a n d l e r
xor % e a x ,% e a x
mov - 8 ( % r b p ) ,% r b x
leaveq
ret