Linux Audio

Check our new training course

Linux kernel drivers training

Mar 31-Apr 9, 2025, special US time zones
Register
Loading...
Note: File does not exist in v3.1.
  1#include <asm/ptrace.h>
  2
  3#include "bpf_jit.h"
  4
  5#ifdef CONFIG_SPARC64
  6#define SAVE_SZ		176
  7#define SCRATCH_OFF	STACK_BIAS + 128
  8#define BE_PTR(label)	be,pn %xcc, label
  9#define SIGN_EXTEND(reg)	sra reg, 0, reg
 10#else
 11#define SAVE_SZ		96
 12#define SCRATCH_OFF	72
 13#define BE_PTR(label)	be label
 14#define SIGN_EXTEND(reg)
 15#endif
 16
 17#define SKF_MAX_NEG_OFF	(-0x200000) /* SKF_LL_OFF from filter.h */
 18
 19	.text
 20	.globl	bpf_jit_load_word
 21bpf_jit_load_word:
 22	cmp	r_OFF, 0
 23	bl	bpf_slow_path_word_neg
 24	 nop
 25	.globl	bpf_jit_load_word_positive_offset
 26bpf_jit_load_word_positive_offset:
 27	sub	r_HEADLEN, r_OFF, r_TMP
 28	cmp	r_TMP, 3
 29	ble	bpf_slow_path_word
 30	 add	r_SKB_DATA, r_OFF, r_TMP
 31	andcc	r_TMP, 3, %g0
 32	bne	load_word_unaligned
 33	 nop
 34	retl
 35	 ld	[r_TMP], r_A
 36load_word_unaligned:
 37	ldub	[r_TMP + 0x0], r_OFF
 38	ldub	[r_TMP + 0x1], r_TMP2
 39	sll	r_OFF, 8, r_OFF
 40	or	r_OFF, r_TMP2, r_OFF
 41	ldub	[r_TMP + 0x2], r_TMP2
 42	sll	r_OFF, 8, r_OFF
 43	or	r_OFF, r_TMP2, r_OFF
 44	ldub	[r_TMP + 0x3], r_TMP2
 45	sll	r_OFF, 8, r_OFF
 46	retl
 47	 or	r_OFF, r_TMP2, r_A
 48
 49	.globl	bpf_jit_load_half
 50bpf_jit_load_half:
 51	cmp	r_OFF, 0
 52	bl	bpf_slow_path_half_neg
 53	 nop
 54	.globl	bpf_jit_load_half_positive_offset
 55bpf_jit_load_half_positive_offset:
 56	sub	r_HEADLEN, r_OFF, r_TMP
 57	cmp	r_TMP, 1
 58	ble	bpf_slow_path_half
 59	 add	r_SKB_DATA, r_OFF, r_TMP
 60	andcc	r_TMP, 1, %g0
 61	bne	load_half_unaligned
 62	 nop
 63	retl
 64	 lduh	[r_TMP], r_A
 65load_half_unaligned:
 66	ldub	[r_TMP + 0x0], r_OFF
 67	ldub	[r_TMP + 0x1], r_TMP2
 68	sll	r_OFF, 8, r_OFF
 69	retl
 70	 or	r_OFF, r_TMP2, r_A
 71
 72	.globl	bpf_jit_load_byte
 73bpf_jit_load_byte:
 74	cmp	r_OFF, 0
 75	bl	bpf_slow_path_byte_neg
 76	 nop
 77	.globl	bpf_jit_load_byte_positive_offset
 78bpf_jit_load_byte_positive_offset:
 79	cmp	r_OFF, r_HEADLEN
 80	bge	bpf_slow_path_byte
 81	 nop
 82	retl
 83	 ldub	[r_SKB_DATA + r_OFF], r_A
 84
 85	.globl	bpf_jit_load_byte_msh
 86bpf_jit_load_byte_msh:
 87	cmp	r_OFF, 0
 88	bl	bpf_slow_path_byte_msh_neg
 89	 nop
 90	.globl	bpf_jit_load_byte_msh_positive_offset
 91bpf_jit_load_byte_msh_positive_offset:
 92	cmp	r_OFF, r_HEADLEN
 93	bge	bpf_slow_path_byte_msh
 94	 nop
 95	ldub	[r_SKB_DATA + r_OFF], r_OFF
 96	and	r_OFF, 0xf, r_OFF
 97	retl
 98	 sll	r_OFF, 2, r_X
 99
100#define bpf_slow_path_common(LEN)	\
101	save	%sp, -SAVE_SZ, %sp;	\
102	mov	%i0, %o0;		\
103	mov	r_OFF, %o1;		\
104	add	%fp, SCRATCH_OFF, %o2;	\
105	call	skb_copy_bits;		\
106	 mov	(LEN), %o3;		\
107	cmp	%o0, 0;			\
108	restore;
109
110bpf_slow_path_word:
111	bpf_slow_path_common(4)
112	bl	bpf_error
113	 ld	[%sp + SCRATCH_OFF], r_A
114	retl
115	 nop
116bpf_slow_path_half:
117	bpf_slow_path_common(2)
118	bl	bpf_error
119	 lduh	[%sp + SCRATCH_OFF], r_A
120	retl
121	 nop
122bpf_slow_path_byte:
123	bpf_slow_path_common(1)
124	bl	bpf_error
125	 ldub	[%sp + SCRATCH_OFF], r_A
126	retl
127	 nop
128bpf_slow_path_byte_msh:
129	bpf_slow_path_common(1)
130	bl	bpf_error
131	 ldub	[%sp + SCRATCH_OFF], r_A
132	and	r_OFF, 0xf, r_OFF
133	retl
134	 sll	r_OFF, 2, r_X
135
136#define bpf_negative_common(LEN)			\
137	save	%sp, -SAVE_SZ, %sp;			\
138	mov	%i0, %o0;				\
139	mov	r_OFF, %o1;				\
140	SIGN_EXTEND(%o1);				\
141	call	bpf_internal_load_pointer_neg_helper;	\
142	 mov	(LEN), %o2;				\
143	mov	%o0, r_TMP;				\
144	cmp	%o0, 0;					\
145	BE_PTR(bpf_error);				\
146	 restore;
147
148bpf_slow_path_word_neg:
149	sethi	%hi(SKF_MAX_NEG_OFF), r_TMP
150	cmp	r_OFF, r_TMP
151	bl	bpf_error
152	 nop
153	.globl	bpf_jit_load_word_negative_offset
154bpf_jit_load_word_negative_offset:
155	bpf_negative_common(4)
156	andcc	r_TMP, 3, %g0
157	bne	load_word_unaligned
158	 nop
159	retl
160	 ld	[r_TMP], r_A
161
162bpf_slow_path_half_neg:
163	sethi	%hi(SKF_MAX_NEG_OFF), r_TMP
164	cmp	r_OFF, r_TMP
165	bl	bpf_error
166	 nop
167	.globl	bpf_jit_load_half_negative_offset
168bpf_jit_load_half_negative_offset:
169	bpf_negative_common(2)
170	andcc	r_TMP, 1, %g0
171	bne	load_half_unaligned
172	 nop
173	retl
174	 lduh	[r_TMP], r_A
175
176bpf_slow_path_byte_neg:
177	sethi	%hi(SKF_MAX_NEG_OFF), r_TMP
178	cmp	r_OFF, r_TMP
179	bl	bpf_error
180	 nop
181	.globl	bpf_jit_load_byte_negative_offset
182bpf_jit_load_byte_negative_offset:
183	bpf_negative_common(1)
184	retl
185	 ldub	[r_TMP], r_A
186
187bpf_slow_path_byte_msh_neg:
188	sethi	%hi(SKF_MAX_NEG_OFF), r_TMP
189	cmp	r_OFF, r_TMP
190	bl	bpf_error
191	 nop
192	.globl	bpf_jit_load_byte_msh_negative_offset
193bpf_jit_load_byte_msh_negative_offset:
194	bpf_negative_common(1)
195	ldub	[r_TMP], r_OFF
196	and	r_OFF, 0xf, r_OFF
197	retl
198	 sll	r_OFF, 2, r_X
199
200bpf_error:
201	/* Make the JIT program return zero.  The JIT epilogue
202	 * stores away the original %o7 into r_saved_O7.  The
203	 * normal leaf function return is to use "retl" which
204	 * would evalute to "jmpl %o7 + 8, %g0" but we want to
205	 * use the saved value thus the sequence you see here.
206	 */
207	jmpl	r_saved_O7 + 8, %g0
208	 clr	%o0