t_extmem.c revision 1.3.6.2 1 1.3.6.2 tls /* $NetBSD: t_extmem.c,v 1.3.6.2 2014/08/20 00:04:49 tls Exp $ */
2 1.3.6.2 tls
3 1.3.6.2 tls /*-
4 1.3.6.2 tls * Copyright (c) 2014 Alexander Nasonov.
5 1.3.6.2 tls * All rights reserved.
6 1.3.6.2 tls *
7 1.3.6.2 tls * Redistribution and use in source and binary forms, with or without
8 1.3.6.2 tls * modification, are permitted provided that the following conditions
9 1.3.6.2 tls * are met:
10 1.3.6.2 tls *
11 1.3.6.2 tls * 1. Redistributions of source code must retain the above copyright
12 1.3.6.2 tls * notice, this list of conditions and the following disclaimer.
13 1.3.6.2 tls * 2. Redistributions in binary form must reproduce the above copyright
14 1.3.6.2 tls * notice, this list of conditions and the following disclaimer in
15 1.3.6.2 tls * the documentation and/or other materials provided with the
16 1.3.6.2 tls * distribution.
17 1.3.6.2 tls *
18 1.3.6.2 tls * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 1.3.6.2 tls * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 1.3.6.2 tls * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 1.3.6.2 tls * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 1.3.6.2 tls * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 1.3.6.2 tls * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 1.3.6.2 tls * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 1.3.6.2 tls * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 1.3.6.2 tls * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 1.3.6.2 tls * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
28 1.3.6.2 tls * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 1.3.6.2 tls * SUCH DAMAGE.
30 1.3.6.2 tls */
31 1.3.6.2 tls
32 1.3.6.2 tls #include <sys/cdefs.h>
33 1.3.6.2 tls __RCSID("$NetBSD: t_extmem.c,v 1.3.6.2 2014/08/20 00:04:49 tls Exp $");
34 1.3.6.2 tls
35 1.3.6.2 tls #include <atf-c.h>
36 1.3.6.2 tls #include <stdint.h>
37 1.3.6.2 tls #include <string.h>
38 1.3.6.2 tls
39 1.3.6.2 tls #define __BPF_PRIVATE
40 1.3.6.2 tls #include <net/bpf.h>
41 1.3.6.2 tls #include <net/bpfjit.h>
42 1.3.6.2 tls
43 1.3.6.2 tls static uint32_t retM(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A);
44 1.3.6.2 tls
45 1.3.6.2 tls static const bpf_copfunc_t copfuncs[] = {
46 1.3.6.2 tls &retM
47 1.3.6.2 tls };
48 1.3.6.2 tls
49 1.3.6.2 tls static const bpf_ctx_t ctx = {
50 1.3.6.2 tls .copfuncs = copfuncs,
51 1.3.6.2 tls .nfuncs = sizeof(copfuncs) / sizeof(copfuncs[0]),
52 1.3.6.2 tls .extwords = 4,
53 1.3.6.2 tls .preinited = BPF_MEMWORD_INIT(0) | BPF_MEMWORD_INIT(3),
54 1.3.6.2 tls };
55 1.3.6.2 tls
56 1.3.6.2 tls static uint32_t
57 1.3.6.2 tls retM(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A)
58 1.3.6.2 tls {
59 1.3.6.2 tls
60 1.3.6.2 tls return args->mem[(uintptr_t)args->arg];
61 1.3.6.2 tls }
62 1.3.6.2 tls
63 1.3.6.2 tls
64 1.3.6.2 tls ATF_TC(libbpfjit_extmem_load_default);
65 1.3.6.2 tls ATF_TC_HEAD(libbpfjit_extmem_load_default, tc)
66 1.3.6.2 tls {
67 1.3.6.2 tls atf_tc_set_md_var(tc, "descr", "Test that external memory "
68 1.3.6.2 tls "is zero initialized by default");
69 1.3.6.2 tls }
70 1.3.6.2 tls
71 1.3.6.2 tls ATF_TC_BODY(libbpfjit_extmem_load_default, tc)
72 1.3.6.2 tls {
73 1.3.6.2 tls static struct bpf_insn insns[] = {
74 1.3.6.2 tls BPF_STMT(BPF_LD+BPF_MEM, 1),
75 1.3.6.2 tls BPF_STMT(BPF_RET+BPF_A, 0)
76 1.3.6.2 tls };
77 1.3.6.2 tls
78 1.3.6.2 tls bpfjit_func_t code;
79 1.3.6.2 tls uint8_t pkt[1] = { 0 };
80 1.3.6.2 tls uint32_t mem[ctx.extwords];
81 1.3.6.2 tls
82 1.3.6.2 tls /* Pre-inited words. */
83 1.3.6.2 tls mem[0] = 0;
84 1.3.6.2 tls mem[3] = 3;
85 1.3.6.2 tls
86 1.3.6.2 tls bpf_args_t args = {
87 1.3.6.2 tls .pkt = pkt,
88 1.3.6.2 tls .buflen = sizeof(pkt),
89 1.3.6.2 tls .wirelen = sizeof(pkt),
90 1.3.6.2 tls .mem = mem,
91 1.3.6.2 tls };
92 1.3.6.2 tls
93 1.3.6.2 tls size_t insn_count = sizeof(insns) / sizeof(insns[0]);
94 1.3.6.2 tls
95 1.3.6.2 tls code = bpfjit_generate_code(&ctx, insns, insn_count);
96 1.3.6.2 tls ATF_REQUIRE(code != NULL);
97 1.3.6.2 tls
98 1.3.6.2 tls ATF_CHECK(code(&ctx, &args) == 0);
99 1.3.6.2 tls
100 1.3.6.2 tls bpfjit_free_code(code);
101 1.3.6.2 tls }
102 1.3.6.2 tls
103 1.3.6.2 tls ATF_TC(libbpfjit_extmem_load_preinited);
104 1.3.6.2 tls ATF_TC_HEAD(libbpfjit_extmem_load_preinited, tc)
105 1.3.6.2 tls {
106 1.3.6.2 tls atf_tc_set_md_var(tc, "descr", "Test a load of external "
107 1.3.6.2 tls "pre-initialized memory");
108 1.3.6.2 tls }
109 1.3.6.2 tls
110 1.3.6.2 tls ATF_TC_BODY(libbpfjit_extmem_load_preinited, tc)
111 1.3.6.2 tls {
112 1.3.6.2 tls static struct bpf_insn insns[] = {
113 1.3.6.2 tls BPF_STMT(BPF_LD+BPF_MEM, 3),
114 1.3.6.2 tls BPF_STMT(BPF_RET+BPF_A, 0)
115 1.3.6.2 tls };
116 1.3.6.2 tls
117 1.3.6.2 tls bpfjit_func_t code;
118 1.3.6.2 tls uint8_t pkt[1] = { 0 };
119 1.3.6.2 tls uint32_t mem[ctx.extwords];
120 1.3.6.2 tls
121 1.3.6.2 tls /* Pre-inited words. */
122 1.3.6.2 tls mem[0] = 0;
123 1.3.6.2 tls mem[3] = 3;
124 1.3.6.2 tls
125 1.3.6.2 tls bpf_args_t args = {
126 1.3.6.2 tls .pkt = pkt,
127 1.3.6.2 tls .buflen = sizeof(pkt),
128 1.3.6.2 tls .wirelen = sizeof(pkt),
129 1.3.6.2 tls .mem = mem,
130 1.3.6.2 tls };
131 1.3.6.2 tls
132 1.3.6.2 tls size_t insn_count = sizeof(insns) / sizeof(insns[0]);
133 1.3.6.2 tls
134 1.3.6.2 tls code = bpfjit_generate_code(&ctx, insns, insn_count);
135 1.3.6.2 tls ATF_REQUIRE(code != NULL);
136 1.3.6.2 tls
137 1.3.6.2 tls ATF_CHECK(code(&ctx, &args) == 3);
138 1.3.6.2 tls
139 1.3.6.2 tls bpfjit_free_code(code);
140 1.3.6.2 tls }
141 1.3.6.2 tls
142 1.3.6.2 tls ATF_TC(libbpfjit_extmem_invalid_load);
143 1.3.6.2 tls ATF_TC_HEAD(libbpfjit_extmem_invalid_load, tc)
144 1.3.6.2 tls {
145 1.3.6.2 tls atf_tc_set_md_var(tc, "descr", "Test that out-of-range load "
146 1.3.6.2 tls "fails validation");
147 1.3.6.2 tls }
148 1.3.6.2 tls
149 1.3.6.2 tls ATF_TC_BODY(libbpfjit_extmem_invalid_load, tc)
150 1.3.6.2 tls {
151 1.3.6.2 tls static struct bpf_insn insns[] = {
152 1.3.6.2 tls BPF_STMT(BPF_LD+BPF_MEM, 4),
153 1.3.6.2 tls BPF_STMT(BPF_RET+BPF_A, 0)
154 1.3.6.2 tls };
155 1.3.6.2 tls
156 1.3.6.2 tls size_t insn_count = sizeof(insns) / sizeof(insns[0]);
157 1.3.6.2 tls
158 1.3.6.2 tls ATF_CHECK(bpfjit_generate_code(&ctx, insns, insn_count) == NULL);
159 1.3.6.2 tls }
160 1.3.6.2 tls
161 1.3.6.2 tls ATF_TC(libbpfjit_extmem_store);
162 1.3.6.2 tls ATF_TC_HEAD(libbpfjit_extmem_store, tc)
163 1.3.6.2 tls {
164 1.3.6.2 tls atf_tc_set_md_var(tc, "descr", "Test stores to external memory");
165 1.3.6.2 tls }
166 1.3.6.2 tls
167 1.3.6.2 tls ATF_TC_BODY(libbpfjit_extmem_store, tc)
168 1.3.6.2 tls {
169 1.3.6.2 tls static struct bpf_insn insns[] = {
170 1.3.6.2 tls BPF_STMT(BPF_LD+BPF_IMM, 1), /* A <- 1 */
171 1.3.6.2 tls BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), /* X <- 2 */
172 1.3.6.2 tls BPF_STMT(BPF_ST, 1), /* M[1] <- A */
173 1.3.6.2 tls BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */
174 1.3.6.2 tls BPF_STMT(BPF_STX, 2), /* M[2] <- X */
175 1.3.6.2 tls BPF_STMT(BPF_ST, 3), /* M[3] <- A */
176 1.3.6.2 tls BPF_STMT(BPF_RET+BPF_A, 0) /* ret A */
177 1.3.6.2 tls };
178 1.3.6.2 tls
179 1.3.6.2 tls bpfjit_func_t code;
180 1.3.6.2 tls uint8_t pkt[1] = { 0 };
181 1.3.6.2 tls uint32_t mem[ctx.extwords];
182 1.3.6.2 tls
183 1.3.6.2 tls /* Pre-inited words. */
184 1.3.6.2 tls mem[0] = 0;
185 1.3.6.2 tls mem[3] = 7;
186 1.3.6.2 tls
187 1.3.6.2 tls mem[1] = mem[2] = 0xdeadbeef;
188 1.3.6.2 tls
189 1.3.6.2 tls bpf_args_t args = {
190 1.3.6.2 tls .pkt = pkt,
191 1.3.6.2 tls .buflen = sizeof(pkt),
192 1.3.6.2 tls .wirelen = sizeof(pkt),
193 1.3.6.2 tls .mem = mem,
194 1.3.6.2 tls };
195 1.3.6.2 tls
196 1.3.6.2 tls size_t insn_count = sizeof(insns) / sizeof(insns[0]);
197 1.3.6.2 tls
198 1.3.6.2 tls code = bpfjit_generate_code(&ctx, insns, insn_count);
199 1.3.6.2 tls ATF_REQUIRE(code != NULL);
200 1.3.6.2 tls
201 1.3.6.2 tls ATF_CHECK(code(&ctx, &args) == 3);
202 1.3.6.2 tls
203 1.3.6.2 tls bpfjit_free_code(code);
204 1.3.6.2 tls
205 1.3.6.2 tls ATF_CHECK(mem[0] == 0);
206 1.3.6.2 tls ATF_CHECK(mem[1] == 1);
207 1.3.6.2 tls ATF_CHECK(mem[2] == 2);
208 1.3.6.2 tls ATF_CHECK(mem[3] == 3);
209 1.3.6.2 tls }
210 1.3.6.2 tls
211 1.3.6.2 tls ATF_TC(libbpfjit_extmem_side_effect);
212 1.3.6.2 tls ATF_TC_HEAD(libbpfjit_extmem_side_effect, tc)
213 1.3.6.2 tls {
214 1.3.6.2 tls atf_tc_set_md_var(tc, "descr", "Test that ABC optimization doesn\'t "
215 1.3.6.2 tls "skip stores to external memory");
216 1.3.6.2 tls }
217 1.3.6.2 tls
218 1.3.6.2 tls ATF_TC_BODY(libbpfjit_extmem_side_effect, tc)
219 1.3.6.2 tls {
220 1.3.6.2 tls static struct bpf_insn insns[] = {
221 1.3.6.2 tls BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 0), /* A <- P[0] */
222 1.3.6.2 tls BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), /* X <- 2 */
223 1.3.6.2 tls BPF_STMT(BPF_ST, 1), /* M[1] <- A */
224 1.3.6.2 tls BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */
225 1.3.6.2 tls BPF_STMT(BPF_STX, 2), /* M[2] <- X */
226 1.3.6.2 tls BPF_STMT(BPF_ST, 3), /* M[3] <- A */
227 1.3.6.2 tls BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 99), /* A <- P[99] */
228 1.3.6.2 tls BPF_STMT(BPF_RET+BPF_A, 0) /* ret A */
229 1.3.6.2 tls };
230 1.3.6.2 tls
231 1.3.6.2 tls bpfjit_func_t code;
232 1.3.6.2 tls uint8_t pkt[1] = { 1 };
233 1.3.6.2 tls uint32_t mem[ctx.extwords];
234 1.3.6.2 tls
235 1.3.6.2 tls /* Pre-inited words. */
236 1.3.6.2 tls mem[0] = 0;
237 1.3.6.2 tls mem[3] = 7;
238 1.3.6.2 tls
239 1.3.6.2 tls mem[1] = mem[2] = 0xdeadbeef;
240 1.3.6.2 tls
241 1.3.6.2 tls bpf_args_t args = {
242 1.3.6.2 tls .pkt = pkt,
243 1.3.6.2 tls .buflen = sizeof(pkt),
244 1.3.6.2 tls .wirelen = sizeof(pkt),
245 1.3.6.2 tls .mem = mem,
246 1.3.6.2 tls };
247 1.3.6.2 tls
248 1.3.6.2 tls size_t insn_count = sizeof(insns) / sizeof(insns[0]);
249 1.3.6.2 tls
250 1.3.6.2 tls code = bpfjit_generate_code(&ctx, insns, insn_count);
251 1.3.6.2 tls ATF_REQUIRE(code != NULL);
252 1.3.6.2 tls
253 1.3.6.2 tls ATF_CHECK(code(&ctx, &args) == 0);
254 1.3.6.2 tls
255 1.3.6.2 tls bpfjit_free_code(code);
256 1.3.6.2 tls
257 1.3.6.2 tls ATF_CHECK(mem[0] == 0);
258 1.3.6.2 tls ATF_CHECK(mem[1] == 1);
259 1.3.6.2 tls ATF_CHECK(mem[2] == 2);
260 1.3.6.2 tls ATF_CHECK(mem[3] == 3);
261 1.3.6.2 tls }
262 1.3.6.2 tls
263 1.3.6.2 tls ATF_TC(libbpfjit_extmem_invalid_store);
264 1.3.6.2 tls ATF_TC_HEAD(libbpfjit_extmem_invalid_store, tc)
265 1.3.6.2 tls {
266 1.3.6.2 tls atf_tc_set_md_var(tc, "descr", "Test that out-of-range store "
267 1.3.6.2 tls "fails validation");
268 1.3.6.2 tls }
269 1.3.6.2 tls
270 1.3.6.2 tls ATF_TC_BODY(libbpfjit_extmem_invalid_store, tc)
271 1.3.6.2 tls {
272 1.3.6.2 tls static struct bpf_insn insns[] = {
273 1.3.6.2 tls BPF_STMT(BPF_ST, 4),
274 1.3.6.2 tls BPF_STMT(BPF_RET+BPF_A, 0)
275 1.3.6.2 tls };
276 1.3.6.2 tls
277 1.3.6.2 tls size_t insn_count = sizeof(insns) / sizeof(insns[0]);
278 1.3.6.2 tls
279 1.3.6.2 tls ATF_CHECK(bpfjit_generate_code(&ctx, insns, insn_count) == NULL);
280 1.3.6.2 tls }
281 1.3.6.2 tls
282 1.3.6.2 tls ATF_TC(libbpfjit_cop_ret_mem);
283 1.3.6.2 tls ATF_TC_HEAD(libbpfjit_cop_ret_mem, tc)
284 1.3.6.2 tls {
285 1.3.6.2 tls atf_tc_set_md_var(tc, "descr", "Test coprocessor function "
286 1.3.6.2 tls "that returns a content of external memory word");
287 1.3.6.2 tls }
288 1.3.6.2 tls
289 1.3.6.2 tls ATF_TC_BODY(libbpfjit_cop_ret_mem, tc)
290 1.3.6.2 tls {
291 1.3.6.2 tls static struct bpf_insn insns[] = {
292 1.3.6.2 tls BPF_STMT(BPF_LD+BPF_IMM, 13),
293 1.3.6.2 tls BPF_STMT(BPF_ST, 2),
294 1.3.6.2 tls BPF_STMT(BPF_LD+BPF_IMM, 137),
295 1.3.6.2 tls BPF_STMT(BPF_ST, 1),
296 1.3.6.2 tls BPF_STMT(BPF_MISC+BPF_COP, 0), // retM
297 1.3.6.2 tls BPF_STMT(BPF_RET+BPF_A, 0)
298 1.3.6.2 tls };
299 1.3.6.2 tls
300 1.3.6.2 tls bpfjit_func_t code;
301 1.3.6.2 tls uint8_t pkt[1] = { 0 };
302 1.3.6.2 tls uint32_t mem[ctx.extwords];
303 1.3.6.2 tls void *arg = (void*)(uintptr_t)2;
304 1.3.6.2 tls
305 1.3.6.2 tls /* Pre-inited words. */
306 1.3.6.2 tls mem[0] = 0;
307 1.3.6.2 tls mem[3] = 3;
308 1.3.6.2 tls
309 1.3.6.2 tls bpf_args_t args = {
310 1.3.6.2 tls .pkt = pkt,
311 1.3.6.2 tls .buflen = sizeof(pkt),
312 1.3.6.2 tls .wirelen = sizeof(pkt),
313 1.3.6.2 tls .arg = arg,
314 1.3.6.2 tls .mem = mem,
315 1.3.6.2 tls };
316 1.3.6.2 tls
317 1.3.6.2 tls size_t insn_count = sizeof(insns) / sizeof(insns[0]);
318 1.3.6.2 tls
319 1.3.6.2 tls code = bpfjit_generate_code(&ctx, insns, insn_count);
320 1.3.6.2 tls ATF_REQUIRE(code != NULL);
321 1.3.6.2 tls
322 1.3.6.2 tls ATF_CHECK(code(&ctx, &args) == 13);
323 1.3.6.2 tls
324 1.3.6.2 tls bpfjit_free_code(code);
325 1.3.6.2 tls }
326 1.3.6.2 tls
327 1.3.6.2 tls ATF_TC(libbpfjit_cop_ret_preinited_mem);
328 1.3.6.2 tls ATF_TC_HEAD(libbpfjit_cop_ret_preinited_mem, tc)
329 1.3.6.2 tls {
330 1.3.6.2 tls atf_tc_set_md_var(tc, "descr", "Test coprocessor function that "
331 1.3.6.2 tls "returns a content of external pre-initialized memory word");
332 1.3.6.2 tls }
333 1.3.6.2 tls
334 1.3.6.2 tls ATF_TC_BODY(libbpfjit_cop_ret_preinited_mem, tc)
335 1.3.6.2 tls {
336 1.3.6.2 tls static struct bpf_insn insns[] = {
337 1.3.6.2 tls BPF_STMT(BPF_LD+BPF_IMM, 13),
338 1.3.6.2 tls BPF_STMT(BPF_ST, 2),
339 1.3.6.2 tls BPF_STMT(BPF_LD+BPF_IMM, 137),
340 1.3.6.2 tls BPF_STMT(BPF_ST, 1),
341 1.3.6.2 tls BPF_STMT(BPF_MISC+BPF_COP, 0), // retM
342 1.3.6.2 tls BPF_STMT(BPF_RET+BPF_A, 0)
343 1.3.6.2 tls };
344 1.3.6.2 tls
345 1.3.6.2 tls bpfjit_func_t code;
346 1.3.6.2 tls uint8_t pkt[1] = { 0 };
347 1.3.6.2 tls uint32_t mem[ctx.extwords];
348 1.3.6.2 tls void *arg = (void*)(uintptr_t)3;
349 1.3.6.2 tls
350 1.3.6.2 tls /* Pre-inited words. */
351 1.3.6.2 tls mem[0] = 0;
352 1.3.6.2 tls mem[3] = 3;
353 1.3.6.2 tls
354 1.3.6.2 tls bpf_args_t args = {
355 1.3.6.2 tls .pkt = pkt,
356 1.3.6.2 tls .buflen = sizeof(pkt),
357 1.3.6.2 tls .wirelen = sizeof(pkt),
358 1.3.6.2 tls .arg = arg,
359 1.3.6.2 tls .mem = mem,
360 1.3.6.2 tls };
361 1.3.6.2 tls
362 1.3.6.2 tls size_t insn_count = sizeof(insns) / sizeof(insns[0]);
363 1.3.6.2 tls
364 1.3.6.2 tls code = bpfjit_generate_code(&ctx, insns, insn_count);
365 1.3.6.2 tls ATF_REQUIRE(code != NULL);
366 1.3.6.2 tls
367 1.3.6.2 tls ATF_CHECK(code(&ctx, &args) == 3);
368 1.3.6.2 tls
369 1.3.6.2 tls bpfjit_free_code(code);
370 1.3.6.2 tls }
371 1.3.6.2 tls
372 1.3.6.2 tls ATF_TC(libbpfjit_copx_ret_mem);
373 1.3.6.2 tls ATF_TC_HEAD(libbpfjit_copx_ret_mem, tc)
374 1.3.6.2 tls {
375 1.3.6.2 tls atf_tc_set_md_var(tc, "descr", "Test coprocessor function "
376 1.3.6.2 tls "that returns a content of external memory word");
377 1.3.6.2 tls }
378 1.3.6.2 tls
379 1.3.6.2 tls ATF_TC_BODY(libbpfjit_copx_ret_mem, tc)
380 1.3.6.2 tls {
381 1.3.6.2 tls static struct bpf_insn insns[] = {
382 1.3.6.2 tls BPF_STMT(BPF_LD+BPF_IMM, 13),
383 1.3.6.2 tls BPF_STMT(BPF_ST, 2),
384 1.3.6.2 tls BPF_STMT(BPF_LD+BPF_IMM, 137),
385 1.3.6.2 tls BPF_STMT(BPF_ST, 1),
386 1.3.6.2 tls BPF_STMT(BPF_LDX+BPF_IMM, 0), // retM
387 1.3.6.2 tls BPF_STMT(BPF_MISC+BPF_COPX, 0),
388 1.3.6.2 tls BPF_STMT(BPF_RET+BPF_A, 0)
389 1.3.6.2 tls };
390 1.3.6.2 tls
391 1.3.6.2 tls bpfjit_func_t code;
392 1.3.6.2 tls uint8_t pkt[1] = { 0 };
393 1.3.6.2 tls uint32_t mem[ctx.extwords];
394 1.3.6.2 tls void *arg = (void*)(uintptr_t)2;
395 1.3.6.2 tls
396 1.3.6.2 tls /* Pre-inited words. */
397 1.3.6.2 tls mem[0] = 0;
398 1.3.6.2 tls mem[3] = 3;
399 1.3.6.2 tls
400 1.3.6.2 tls bpf_args_t args = {
401 1.3.6.2 tls .pkt = pkt,
402 1.3.6.2 tls .buflen = sizeof(pkt),
403 1.3.6.2 tls .wirelen = sizeof(pkt),
404 1.3.6.2 tls .arg = arg,
405 1.3.6.2 tls .mem = mem,
406 1.3.6.2 tls };
407 1.3.6.2 tls
408 1.3.6.2 tls size_t insn_count = sizeof(insns) / sizeof(insns[0]);
409 1.3.6.2 tls
410 1.3.6.2 tls code = bpfjit_generate_code(&ctx, insns, insn_count);
411 1.3.6.2 tls ATF_REQUIRE(code != NULL);
412 1.3.6.2 tls
413 1.3.6.2 tls ATF_CHECK(code(&ctx, &args) == 13);
414 1.3.6.2 tls
415 1.3.6.2 tls bpfjit_free_code(code);
416 1.3.6.2 tls }
417 1.3.6.2 tls
418 1.3.6.2 tls ATF_TC(libbpfjit_copx_ret_preinited_mem);
419 1.3.6.2 tls ATF_TC_HEAD(libbpfjit_copx_ret_preinited_mem, tc)
420 1.3.6.2 tls {
421 1.3.6.2 tls atf_tc_set_md_var(tc, "descr", "Test coprocessor function that "
422 1.3.6.2 tls "returns a content of external pre-initialized memory word");
423 1.3.6.2 tls }
424 1.3.6.2 tls
425 1.3.6.2 tls ATF_TC_BODY(libbpfjit_copx_ret_preinited_mem, tc)
426 1.3.6.2 tls {
427 1.3.6.2 tls static struct bpf_insn insns[] = {
428 1.3.6.2 tls BPF_STMT(BPF_LD+BPF_IMM, 13),
429 1.3.6.2 tls BPF_STMT(BPF_ST, 2),
430 1.3.6.2 tls BPF_STMT(BPF_LD+BPF_IMM, 137),
431 1.3.6.2 tls BPF_STMT(BPF_ST, 1),
432 1.3.6.2 tls BPF_STMT(BPF_LDX+BPF_IMM, 0), // retM
433 1.3.6.2 tls BPF_STMT(BPF_MISC+BPF_COPX, 0),
434 1.3.6.2 tls BPF_STMT(BPF_RET+BPF_A, 0)
435 1.3.6.2 tls };
436 1.3.6.2 tls
437 1.3.6.2 tls bpfjit_func_t code;
438 1.3.6.2 tls uint8_t pkt[1] = { 0 };
439 1.3.6.2 tls uint32_t mem[ctx.extwords];
440 1.3.6.2 tls void *arg = (void*)(uintptr_t)3;
441 1.3.6.2 tls
442 1.3.6.2 tls /* Pre-inited words. */
443 1.3.6.2 tls mem[0] = 0;
444 1.3.6.2 tls mem[3] = 3;
445 1.3.6.2 tls
446 1.3.6.2 tls bpf_args_t args = {
447 1.3.6.2 tls .pkt = pkt,
448 1.3.6.2 tls .buflen = sizeof(pkt),
449 1.3.6.2 tls .wirelen = sizeof(pkt),
450 1.3.6.2 tls .arg = arg,
451 1.3.6.2 tls .mem = mem,
452 1.3.6.2 tls };
453 1.3.6.2 tls
454 1.3.6.2 tls size_t insn_count = sizeof(insns) / sizeof(insns[0]);
455 1.3.6.2 tls
456 1.3.6.2 tls code = bpfjit_generate_code(&ctx, insns, insn_count);
457 1.3.6.2 tls ATF_REQUIRE(code != NULL);
458 1.3.6.2 tls
459 1.3.6.2 tls ATF_CHECK(code(&ctx, &args) == 3);
460 1.3.6.2 tls
461 1.3.6.2 tls bpfjit_free_code(code);
462 1.3.6.2 tls }
463 1.3.6.2 tls
464 1.3.6.2 tls ATF_TP_ADD_TCS(tp)
465 1.3.6.2 tls {
466 1.3.6.2 tls
467 1.3.6.2 tls /*
468 1.3.6.2 tls * For every new test please also add a similar test
469 1.3.6.2 tls * to ../../net/bpfjit/t_extmem.c
470 1.3.6.2 tls */
471 1.3.6.2 tls ATF_TP_ADD_TC(tp, libbpfjit_extmem_load_default);
472 1.3.6.2 tls ATF_TP_ADD_TC(tp, libbpfjit_extmem_load_preinited);
473 1.3.6.2 tls ATF_TP_ADD_TC(tp, libbpfjit_extmem_invalid_load);
474 1.3.6.2 tls ATF_TP_ADD_TC(tp, libbpfjit_extmem_store);
475 1.3.6.2 tls ATF_TP_ADD_TC(tp, libbpfjit_extmem_side_effect);
476 1.3.6.2 tls ATF_TP_ADD_TC(tp, libbpfjit_extmem_invalid_store);
477 1.3.6.2 tls ATF_TP_ADD_TC(tp, libbpfjit_cop_ret_mem);
478 1.3.6.2 tls ATF_TP_ADD_TC(tp, libbpfjit_cop_ret_preinited_mem);
479 1.3.6.2 tls ATF_TP_ADD_TC(tp, libbpfjit_copx_ret_mem);
480 1.3.6.2 tls ATF_TP_ADD_TC(tp, libbpfjit_copx_ret_preinited_mem);
481 1.3.6.2 tls
482 1.3.6.2 tls return atf_no_error();
483 1.3.6.2 tls }
484