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