xref: /freebsd-src/contrib/netbsd-tests/net/bpfjit/t_extmem.c (revision 1a36faad54665288ed4eb839d2a4699ae2ead45e)
1*63d1fd59SEnji Cooper /*	$NetBSD: t_extmem.c,v 1.2 2017/01/13 21:30:42 christos Exp $ */
257718be8SEnji Cooper 
357718be8SEnji Cooper /*-
457718be8SEnji Cooper  * Copyright (c) 2014 Alexander Nasonov.
557718be8SEnji Cooper  * All rights reserved.
657718be8SEnji Cooper  *
757718be8SEnji Cooper  * Redistribution and use in source and binary forms, with or without
857718be8SEnji Cooper  * modification, are permitted provided that the following conditions
957718be8SEnji Cooper  * are met:
1057718be8SEnji Cooper  *
1157718be8SEnji Cooper  * 1. Redistributions of source code must retain the above copyright
1257718be8SEnji Cooper  *    notice, this list of conditions and the following disclaimer.
1357718be8SEnji Cooper  * 2. Redistributions in binary form must reproduce the above copyright
1457718be8SEnji Cooper  *    notice, this list of conditions and the following disclaimer in
1557718be8SEnji Cooper  *    the documentation and/or other materials provided with the
1657718be8SEnji Cooper  *    distribution.
1757718be8SEnji Cooper  *
1857718be8SEnji Cooper  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1957718be8SEnji Cooper  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2057718be8SEnji Cooper  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
2157718be8SEnji Cooper  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
2257718be8SEnji Cooper  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
2357718be8SEnji Cooper  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
2457718be8SEnji Cooper  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2557718be8SEnji Cooper  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
2657718be8SEnji Cooper  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2757718be8SEnji Cooper  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
2857718be8SEnji Cooper  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2957718be8SEnji Cooper  * SUCH DAMAGE.
3057718be8SEnji Cooper  */
3157718be8SEnji Cooper 
3257718be8SEnji Cooper #include <sys/cdefs.h>
33*63d1fd59SEnji Cooper __RCSID("$NetBSD: t_extmem.c,v 1.2 2017/01/13 21:30:42 christos Exp $");
3457718be8SEnji Cooper 
3557718be8SEnji Cooper #include <stdint.h>
3657718be8SEnji Cooper #include <string.h>
3757718be8SEnji Cooper 
3857718be8SEnji Cooper #define __BPF_PRIVATE
3957718be8SEnji Cooper #include <net/bpf.h>
4057718be8SEnji Cooper #include <net/bpfjit.h>
4157718be8SEnji Cooper 
4257718be8SEnji Cooper #include "../../net/bpf/h_bpf.h"
4357718be8SEnji Cooper 
4457718be8SEnji Cooper /* XXX: atf-c.h has collisions with mbuf */
4557718be8SEnji Cooper #undef m_type
4657718be8SEnji Cooper #undef m_data
4757718be8SEnji Cooper #include <atf-c.h>
4857718be8SEnji Cooper 
49*63d1fd59SEnji Cooper #include "h_macros.h"
5057718be8SEnji Cooper 
5157718be8SEnji Cooper static uint32_t retM(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A);
5257718be8SEnji Cooper 
5357718be8SEnji Cooper static const bpf_copfunc_t copfuncs[] = {
5457718be8SEnji Cooper 	&retM
5557718be8SEnji Cooper };
5657718be8SEnji Cooper 
5757718be8SEnji Cooper static const bpf_ctx_t ctx = {
5857718be8SEnji Cooper 	.copfuncs = copfuncs,
5957718be8SEnji Cooper 	.nfuncs = sizeof(copfuncs) / sizeof(copfuncs[0]),
6057718be8SEnji Cooper 	.extwords = 4,
6157718be8SEnji Cooper 	.preinited = BPF_MEMWORD_INIT(0) | BPF_MEMWORD_INIT(3),
6257718be8SEnji Cooper };
6357718be8SEnji Cooper 
6457718be8SEnji Cooper static uint32_t
retM(const bpf_ctx_t * bc,bpf_args_t * args,uint32_t A)6557718be8SEnji Cooper retM(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A)
6657718be8SEnji Cooper {
6757718be8SEnji Cooper 
6857718be8SEnji Cooper 	return args->mem[(uintptr_t)args->arg];
6957718be8SEnji Cooper }
7057718be8SEnji Cooper 
7157718be8SEnji Cooper 
7257718be8SEnji Cooper ATF_TC(bpfjit_extmem_load_preinited);
ATF_TC_HEAD(bpfjit_extmem_load_preinited,tc)7357718be8SEnji Cooper ATF_TC_HEAD(bpfjit_extmem_load_preinited, tc)
7457718be8SEnji Cooper {
7557718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Test a load of external "
7657718be8SEnji Cooper 	    "pre-initialized memory");
7757718be8SEnji Cooper }
7857718be8SEnji Cooper 
ATF_TC_BODY(bpfjit_extmem_load_preinited,tc)7957718be8SEnji Cooper ATF_TC_BODY(bpfjit_extmem_load_preinited, tc)
8057718be8SEnji Cooper {
8157718be8SEnji Cooper 	static struct bpf_insn insns[] = {
8257718be8SEnji Cooper 		BPF_STMT(BPF_LD+BPF_MEM, 3),
8357718be8SEnji Cooper 		BPF_STMT(BPF_RET+BPF_A, 0)
8457718be8SEnji Cooper 	};
8557718be8SEnji Cooper 
8657718be8SEnji Cooper 	bpfjit_func_t code;
8757718be8SEnji Cooper 	uint8_t pkt[1] = { 0 };
8857718be8SEnji Cooper 	uint32_t mem[ctx.extwords];
8957718be8SEnji Cooper 
9057718be8SEnji Cooper 	/* Pre-inited words. */
9157718be8SEnji Cooper 	mem[0] = 0;
9257718be8SEnji Cooper 	mem[3] = 3;
9357718be8SEnji Cooper 
9457718be8SEnji Cooper 	bpf_args_t args = {
9557718be8SEnji Cooper 		.pkt = pkt,
9657718be8SEnji Cooper 		.buflen = sizeof(pkt),
9757718be8SEnji Cooper 		.wirelen = sizeof(pkt),
9857718be8SEnji Cooper 		.mem = mem,
9957718be8SEnji Cooper 	};
10057718be8SEnji Cooper 
10157718be8SEnji Cooper 	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
10257718be8SEnji Cooper 
10357718be8SEnji Cooper 	RZ(rump_init());
10457718be8SEnji Cooper 
10557718be8SEnji Cooper 	rump_schedule();
10657718be8SEnji Cooper 	code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count);
10757718be8SEnji Cooper 	rump_unschedule();
10857718be8SEnji Cooper 	ATF_REQUIRE(code != NULL);
10957718be8SEnji Cooper 
11057718be8SEnji Cooper 	ATF_CHECK(code(&ctx, &args) == 3);
11157718be8SEnji Cooper 
11257718be8SEnji Cooper 	rump_schedule();
11357718be8SEnji Cooper 	rumpns_bpfjit_free_code(code);
11457718be8SEnji Cooper 	rump_unschedule();
11557718be8SEnji Cooper }
11657718be8SEnji Cooper 
11757718be8SEnji Cooper ATF_TC(bpfjit_extmem_invalid_load);
ATF_TC_HEAD(bpfjit_extmem_invalid_load,tc)11857718be8SEnji Cooper ATF_TC_HEAD(bpfjit_extmem_invalid_load, tc)
11957718be8SEnji Cooper {
12057718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Test that out-of-range load "
12157718be8SEnji Cooper 	    "fails validation");
12257718be8SEnji Cooper }
12357718be8SEnji Cooper 
ATF_TC_BODY(bpfjit_extmem_invalid_load,tc)12457718be8SEnji Cooper ATF_TC_BODY(bpfjit_extmem_invalid_load, tc)
12557718be8SEnji Cooper {
12657718be8SEnji Cooper 	static struct bpf_insn insns[] = {
12757718be8SEnji Cooper 		BPF_STMT(BPF_LD+BPF_MEM, 4),
12857718be8SEnji Cooper 		BPF_STMT(BPF_RET+BPF_A, 0)
12957718be8SEnji Cooper 	};
13057718be8SEnji Cooper 
13157718be8SEnji Cooper 	bpfjit_func_t code;
13257718be8SEnji Cooper 	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
13357718be8SEnji Cooper 
13457718be8SEnji Cooper 	RZ(rump_init());
13557718be8SEnji Cooper 
13657718be8SEnji Cooper 	rump_schedule();
13757718be8SEnji Cooper 	code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count);
13857718be8SEnji Cooper 	rump_unschedule();
13957718be8SEnji Cooper 	ATF_CHECK(code == NULL);
14057718be8SEnji Cooper }
14157718be8SEnji Cooper 
14257718be8SEnji Cooper ATF_TC(bpfjit_extmem_store);
ATF_TC_HEAD(bpfjit_extmem_store,tc)14357718be8SEnji Cooper ATF_TC_HEAD(bpfjit_extmem_store, tc)
14457718be8SEnji Cooper {
14557718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Test stores to external memory");
14657718be8SEnji Cooper }
14757718be8SEnji Cooper 
ATF_TC_BODY(bpfjit_extmem_store,tc)14857718be8SEnji Cooper ATF_TC_BODY(bpfjit_extmem_store, tc)
14957718be8SEnji Cooper {
15057718be8SEnji Cooper 	static struct bpf_insn insns[] = {
15157718be8SEnji Cooper 		BPF_STMT(BPF_LD+BPF_IMM, 1),        /* A <- 1     */
15257718be8SEnji Cooper 		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), /* X <- 2     */
15357718be8SEnji Cooper 		BPF_STMT(BPF_ST, 1),                /* M[1] <- A  */
15457718be8SEnji Cooper 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */
15557718be8SEnji Cooper 		BPF_STMT(BPF_STX, 2),               /* M[2] <- X  */
15657718be8SEnji Cooper 		BPF_STMT(BPF_ST, 3),                /* M[3] <- A  */
15757718be8SEnji Cooper 		BPF_STMT(BPF_RET+BPF_A, 0)          /* ret A      */
15857718be8SEnji Cooper 	};
15957718be8SEnji Cooper 
16057718be8SEnji Cooper 	bpfjit_func_t code;
16157718be8SEnji Cooper 	uint8_t pkt[1] = { 0 };
16257718be8SEnji Cooper 	uint32_t mem[ctx.extwords];
16357718be8SEnji Cooper 
16457718be8SEnji Cooper 	/* Pre-inited words. */
16557718be8SEnji Cooper 	mem[0] = 0;
16657718be8SEnji Cooper 	mem[3] = 7;
16757718be8SEnji Cooper 
16857718be8SEnji Cooper 	mem[1] = mem[2] = 0xdeadbeef;
16957718be8SEnji Cooper 
17057718be8SEnji Cooper 	bpf_args_t args = {
17157718be8SEnji Cooper 		.pkt = pkt,
17257718be8SEnji Cooper 		.buflen = sizeof(pkt),
17357718be8SEnji Cooper 		.wirelen = sizeof(pkt),
17457718be8SEnji Cooper 		.mem = mem,
17557718be8SEnji Cooper 	};
17657718be8SEnji Cooper 
17757718be8SEnji Cooper 	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
17857718be8SEnji Cooper 
17957718be8SEnji Cooper 	RZ(rump_init());
18057718be8SEnji Cooper 
18157718be8SEnji Cooper 	rump_schedule();
18257718be8SEnji Cooper 	code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count);
18357718be8SEnji Cooper 	rump_unschedule();
18457718be8SEnji Cooper 	ATF_REQUIRE(code != NULL);
18557718be8SEnji Cooper 
18657718be8SEnji Cooper 	ATF_CHECK(code(&ctx, &args) == 3);
18757718be8SEnji Cooper 
18857718be8SEnji Cooper 	rump_schedule();
18957718be8SEnji Cooper 	rumpns_bpfjit_free_code(code);
19057718be8SEnji Cooper 	rump_unschedule();
19157718be8SEnji Cooper 
19257718be8SEnji Cooper 	ATF_CHECK(mem[0] == 0);
19357718be8SEnji Cooper 	ATF_CHECK(mem[1] == 1);
19457718be8SEnji Cooper 	ATF_CHECK(mem[2] == 2);
19557718be8SEnji Cooper 	ATF_CHECK(mem[3] == 3);
19657718be8SEnji Cooper }
19757718be8SEnji Cooper 
19857718be8SEnji Cooper ATF_TC(bpfjit_extmem_side_effect);
ATF_TC_HEAD(bpfjit_extmem_side_effect,tc)19957718be8SEnji Cooper ATF_TC_HEAD(bpfjit_extmem_side_effect, tc)
20057718be8SEnji Cooper {
20157718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Test that ABC optimization doesn\'t "
20257718be8SEnji Cooper 	    "skip stores to external memory");
20357718be8SEnji Cooper }
20457718be8SEnji Cooper 
ATF_TC_BODY(bpfjit_extmem_side_effect,tc)20557718be8SEnji Cooper ATF_TC_BODY(bpfjit_extmem_side_effect, tc)
20657718be8SEnji Cooper {
20757718be8SEnji Cooper 	static struct bpf_insn insns[] = {
20857718be8SEnji Cooper 		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 0),  /* A <- P[0]  */
20957718be8SEnji Cooper 		BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), /* X <- 2     */
21057718be8SEnji Cooper 		BPF_STMT(BPF_ST, 1),                /* M[1] <- A  */
21157718be8SEnji Cooper 		BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */
21257718be8SEnji Cooper 		BPF_STMT(BPF_STX, 2),               /* M[2] <- X  */
21357718be8SEnji Cooper 		BPF_STMT(BPF_ST, 3),                /* M[3] <- A  */
21457718be8SEnji Cooper 		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 99), /* A <- P[99] */
21557718be8SEnji Cooper 		BPF_STMT(BPF_RET+BPF_A, 0)          /* ret A      */
21657718be8SEnji Cooper 	};
21757718be8SEnji Cooper 
21857718be8SEnji Cooper 	bpfjit_func_t code;
21957718be8SEnji Cooper 	uint8_t pkt[1] = { 1 };
22057718be8SEnji Cooper 	uint32_t mem[ctx.extwords];
22157718be8SEnji Cooper 
22257718be8SEnji Cooper 	/* Pre-inited words. */
22357718be8SEnji Cooper 	mem[0] = 0;
22457718be8SEnji Cooper 	mem[3] = 7;
22557718be8SEnji Cooper 
22657718be8SEnji Cooper 	mem[1] = mem[2] = 0xdeadbeef;
22757718be8SEnji Cooper 
22857718be8SEnji Cooper 	bpf_args_t args = {
22957718be8SEnji Cooper 		.pkt = pkt,
23057718be8SEnji Cooper 		.buflen = sizeof(pkt),
23157718be8SEnji Cooper 		.wirelen = sizeof(pkt),
23257718be8SEnji Cooper 		.mem = mem,
23357718be8SEnji Cooper 	};
23457718be8SEnji Cooper 
23557718be8SEnji Cooper 	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
23657718be8SEnji Cooper 
23757718be8SEnji Cooper 	RZ(rump_init());
23857718be8SEnji Cooper 
23957718be8SEnji Cooper 	rump_schedule();
24057718be8SEnji Cooper 	code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count);
24157718be8SEnji Cooper 	rump_unschedule();
24257718be8SEnji Cooper 	ATF_REQUIRE(code != NULL);
24357718be8SEnji Cooper 
24457718be8SEnji Cooper 	ATF_CHECK(code(&ctx, &args) == 0);
24557718be8SEnji Cooper 
24657718be8SEnji Cooper 	rump_schedule();
24757718be8SEnji Cooper 	rumpns_bpfjit_free_code(code);
24857718be8SEnji Cooper 	rump_unschedule();
24957718be8SEnji Cooper 
25057718be8SEnji Cooper 	ATF_CHECK(mem[0] == 0);
25157718be8SEnji Cooper 	ATF_CHECK(mem[1] == 1);
25257718be8SEnji Cooper 	ATF_CHECK(mem[2] == 2);
25357718be8SEnji Cooper 	ATF_CHECK(mem[3] == 3);
25457718be8SEnji Cooper }
25557718be8SEnji Cooper 
25657718be8SEnji Cooper ATF_TC(bpfjit_extmem_invalid_store);
ATF_TC_HEAD(bpfjit_extmem_invalid_store,tc)25757718be8SEnji Cooper ATF_TC_HEAD(bpfjit_extmem_invalid_store, tc)
25857718be8SEnji Cooper {
25957718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Test that out-of-range store "
26057718be8SEnji Cooper 	    "fails validation");
26157718be8SEnji Cooper }
26257718be8SEnji Cooper 
ATF_TC_BODY(bpfjit_extmem_invalid_store,tc)26357718be8SEnji Cooper ATF_TC_BODY(bpfjit_extmem_invalid_store, tc)
26457718be8SEnji Cooper {
26557718be8SEnji Cooper 	static struct bpf_insn insns[] = {
26657718be8SEnji Cooper 		BPF_STMT(BPF_ST, 4),
26757718be8SEnji Cooper 		BPF_STMT(BPF_RET+BPF_A, 0)
26857718be8SEnji Cooper 	};
26957718be8SEnji Cooper 
27057718be8SEnji Cooper 	bpfjit_func_t code;
27157718be8SEnji Cooper 	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
27257718be8SEnji Cooper 
27357718be8SEnji Cooper 	RZ(rump_init());
27457718be8SEnji Cooper 
27557718be8SEnji Cooper 	rump_schedule();
27657718be8SEnji Cooper 	code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count);
27757718be8SEnji Cooper 	rump_unschedule();
27857718be8SEnji Cooper 	ATF_CHECK(code == NULL);
27957718be8SEnji Cooper }
28057718be8SEnji Cooper 
28157718be8SEnji Cooper ATF_TC(bpfjit_cop_ret_mem);
ATF_TC_HEAD(bpfjit_cop_ret_mem,tc)28257718be8SEnji Cooper ATF_TC_HEAD(bpfjit_cop_ret_mem, tc)
28357718be8SEnji Cooper {
28457718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Test coprocessor function "
28557718be8SEnji Cooper 	    "that returns a content of external memory word");
28657718be8SEnji Cooper }
28757718be8SEnji Cooper 
ATF_TC_BODY(bpfjit_cop_ret_mem,tc)28857718be8SEnji Cooper ATF_TC_BODY(bpfjit_cop_ret_mem, tc)
28957718be8SEnji Cooper {
29057718be8SEnji Cooper 	static struct bpf_insn insns[] = {
29157718be8SEnji Cooper 		BPF_STMT(BPF_LD+BPF_IMM, 13),
29257718be8SEnji Cooper 		BPF_STMT(BPF_ST, 2),
29357718be8SEnji Cooper 		BPF_STMT(BPF_LD+BPF_IMM, 137),
29457718be8SEnji Cooper 		BPF_STMT(BPF_ST, 1),
29557718be8SEnji Cooper 		BPF_STMT(BPF_MISC+BPF_COP, 0), // retM
29657718be8SEnji Cooper 		BPF_STMT(BPF_RET+BPF_A, 0)
29757718be8SEnji Cooper 	};
29857718be8SEnji Cooper 
29957718be8SEnji Cooper 	bpfjit_func_t code;
30057718be8SEnji Cooper 	uint8_t pkt[1] = { 0 };
30157718be8SEnji Cooper 	uint32_t mem[ctx.extwords];
30257718be8SEnji Cooper 	void *arg = (void*)(uintptr_t)2;
30357718be8SEnji Cooper 
30457718be8SEnji Cooper 	/* Pre-inited words. */
30557718be8SEnji Cooper 	mem[0] = 0;
30657718be8SEnji Cooper 	mem[3] = 3;
30757718be8SEnji Cooper 
30857718be8SEnji Cooper 	bpf_args_t args = {
30957718be8SEnji Cooper 		.pkt = pkt,
31057718be8SEnji Cooper 		.buflen = sizeof(pkt),
31157718be8SEnji Cooper 		.wirelen = sizeof(pkt),
31257718be8SEnji Cooper 		.arg = arg,
31357718be8SEnji Cooper 		.mem = mem,
31457718be8SEnji Cooper 	};
31557718be8SEnji Cooper 
31657718be8SEnji Cooper 	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
31757718be8SEnji Cooper 
31857718be8SEnji Cooper 	RZ(rump_init());
31957718be8SEnji Cooper 
32057718be8SEnji Cooper 	rump_schedule();
32157718be8SEnji Cooper 	code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count);
32257718be8SEnji Cooper 	rump_unschedule();
32357718be8SEnji Cooper 	ATF_REQUIRE(code != NULL);
32457718be8SEnji Cooper 
32557718be8SEnji Cooper 	ATF_CHECK(code(&ctx, &args) == 13);
32657718be8SEnji Cooper 
32757718be8SEnji Cooper 	rump_schedule();
32857718be8SEnji Cooper 	rumpns_bpfjit_free_code(code);
32957718be8SEnji Cooper 	rump_unschedule();
33057718be8SEnji Cooper }
33157718be8SEnji Cooper 
33257718be8SEnji Cooper ATF_TC(bpfjit_cop_ret_preinited_mem);
ATF_TC_HEAD(bpfjit_cop_ret_preinited_mem,tc)33357718be8SEnji Cooper ATF_TC_HEAD(bpfjit_cop_ret_preinited_mem, tc)
33457718be8SEnji Cooper {
33557718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Test coprocessor function that "
33657718be8SEnji Cooper 	    "returns a content of external pre-initialized memory word");
33757718be8SEnji Cooper }
33857718be8SEnji Cooper 
ATF_TC_BODY(bpfjit_cop_ret_preinited_mem,tc)33957718be8SEnji Cooper ATF_TC_BODY(bpfjit_cop_ret_preinited_mem, tc)
34057718be8SEnji Cooper {
34157718be8SEnji Cooper 	static struct bpf_insn insns[] = {
34257718be8SEnji Cooper 		BPF_STMT(BPF_LD+BPF_IMM, 13),
34357718be8SEnji Cooper 		BPF_STMT(BPF_ST, 2),
34457718be8SEnji Cooper 		BPF_STMT(BPF_LD+BPF_IMM, 137),
34557718be8SEnji Cooper 		BPF_STMT(BPF_ST, 1),
34657718be8SEnji Cooper 		BPF_STMT(BPF_MISC+BPF_COP, 0), // retM
34757718be8SEnji Cooper 		BPF_STMT(BPF_RET+BPF_A, 0)
34857718be8SEnji Cooper 	};
34957718be8SEnji Cooper 
35057718be8SEnji Cooper 	bpfjit_func_t code;
35157718be8SEnji Cooper 	uint8_t pkt[1] = { 0 };
35257718be8SEnji Cooper 	uint32_t mem[ctx.extwords];
35357718be8SEnji Cooper 	void *arg = (void*)(uintptr_t)3;
35457718be8SEnji Cooper 
35557718be8SEnji Cooper 	/* Pre-inited words. */
35657718be8SEnji Cooper 	mem[0] = 0;
35757718be8SEnji Cooper 	mem[3] = 3;
35857718be8SEnji Cooper 
35957718be8SEnji Cooper 	bpf_args_t args = {
36057718be8SEnji Cooper 		.pkt = pkt,
36157718be8SEnji Cooper 		.buflen = sizeof(pkt),
36257718be8SEnji Cooper 		.wirelen = sizeof(pkt),
36357718be8SEnji Cooper 		.arg = arg,
36457718be8SEnji Cooper 		.mem = mem,
36557718be8SEnji Cooper 	};
36657718be8SEnji Cooper 
36757718be8SEnji Cooper 	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
36857718be8SEnji Cooper 
36957718be8SEnji Cooper 	RZ(rump_init());
37057718be8SEnji Cooper 
37157718be8SEnji Cooper 	rump_schedule();
37257718be8SEnji Cooper 	code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count);
37357718be8SEnji Cooper 	rump_unschedule();
37457718be8SEnji Cooper 	ATF_REQUIRE(code != NULL);
37557718be8SEnji Cooper 
37657718be8SEnji Cooper 	ATF_CHECK(code(&ctx, &args) == 3);
37757718be8SEnji Cooper 
37857718be8SEnji Cooper 	rump_schedule();
37957718be8SEnji Cooper 	rumpns_bpfjit_free_code(code);
38057718be8SEnji Cooper 	rump_unschedule();
38157718be8SEnji Cooper }
38257718be8SEnji Cooper 
38357718be8SEnji Cooper ATF_TC(bpfjit_copx_ret_mem);
ATF_TC_HEAD(bpfjit_copx_ret_mem,tc)38457718be8SEnji Cooper ATF_TC_HEAD(bpfjit_copx_ret_mem, tc)
38557718be8SEnji Cooper {
38657718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Test coprocessor function "
38757718be8SEnji Cooper 	    "that returns a content of external memory word");
38857718be8SEnji Cooper }
38957718be8SEnji Cooper 
ATF_TC_BODY(bpfjit_copx_ret_mem,tc)39057718be8SEnji Cooper ATF_TC_BODY(bpfjit_copx_ret_mem, tc)
39157718be8SEnji Cooper {
39257718be8SEnji Cooper 	static struct bpf_insn insns[] = {
39357718be8SEnji Cooper 		BPF_STMT(BPF_LD+BPF_IMM, 13),
39457718be8SEnji Cooper 		BPF_STMT(BPF_ST, 2),
39557718be8SEnji Cooper 		BPF_STMT(BPF_LD+BPF_IMM, 137),
39657718be8SEnji Cooper 		BPF_STMT(BPF_ST, 1),
39757718be8SEnji Cooper 		BPF_STMT(BPF_LDX+BPF_IMM, 0), // retM
39857718be8SEnji Cooper 		BPF_STMT(BPF_MISC+BPF_COPX, 0),
39957718be8SEnji Cooper 		BPF_STMT(BPF_RET+BPF_A, 0)
40057718be8SEnji Cooper 	};
40157718be8SEnji Cooper 
40257718be8SEnji Cooper 	bpfjit_func_t code;
40357718be8SEnji Cooper 	uint8_t pkt[1] = { 0 };
40457718be8SEnji Cooper 	uint32_t mem[ctx.extwords];
40557718be8SEnji Cooper 	void *arg = (void*)(uintptr_t)2;
40657718be8SEnji Cooper 
40757718be8SEnji Cooper 	/* Pre-inited words. */
40857718be8SEnji Cooper 	mem[0] = 0;
40957718be8SEnji Cooper 	mem[3] = 3;
41057718be8SEnji Cooper 
41157718be8SEnji Cooper 	bpf_args_t args = {
41257718be8SEnji Cooper 		.pkt = pkt,
41357718be8SEnji Cooper 		.buflen = sizeof(pkt),
41457718be8SEnji Cooper 		.wirelen = sizeof(pkt),
41557718be8SEnji Cooper 		.arg = arg,
41657718be8SEnji Cooper 		.mem = mem,
41757718be8SEnji Cooper 	};
41857718be8SEnji Cooper 
41957718be8SEnji Cooper 	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
42057718be8SEnji Cooper 
42157718be8SEnji Cooper 	RZ(rump_init());
42257718be8SEnji Cooper 
42357718be8SEnji Cooper 	rump_schedule();
42457718be8SEnji Cooper 	code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count);
42557718be8SEnji Cooper 	rump_unschedule();
42657718be8SEnji Cooper 	ATF_REQUIRE(code != NULL);
42757718be8SEnji Cooper 
42857718be8SEnji Cooper 	ATF_CHECK(code(&ctx, &args) == 13);
42957718be8SEnji Cooper 
43057718be8SEnji Cooper 	rump_schedule();
43157718be8SEnji Cooper 	rumpns_bpfjit_free_code(code);
43257718be8SEnji Cooper 	rump_unschedule();
43357718be8SEnji Cooper }
43457718be8SEnji Cooper 
43557718be8SEnji Cooper ATF_TC(bpfjit_copx_ret_preinited_mem);
ATF_TC_HEAD(bpfjit_copx_ret_preinited_mem,tc)43657718be8SEnji Cooper ATF_TC_HEAD(bpfjit_copx_ret_preinited_mem, tc)
43757718be8SEnji Cooper {
43857718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Test coprocessor function that "
43957718be8SEnji Cooper 	    "returns a content of external pre-initialized memory word");
44057718be8SEnji Cooper }
44157718be8SEnji Cooper 
ATF_TC_BODY(bpfjit_copx_ret_preinited_mem,tc)44257718be8SEnji Cooper ATF_TC_BODY(bpfjit_copx_ret_preinited_mem, tc)
44357718be8SEnji Cooper {
44457718be8SEnji Cooper 	static struct bpf_insn insns[] = {
44557718be8SEnji Cooper 		BPF_STMT(BPF_LD+BPF_IMM, 13),
44657718be8SEnji Cooper 		BPF_STMT(BPF_ST, 2),
44757718be8SEnji Cooper 		BPF_STMT(BPF_LD+BPF_IMM, 137),
44857718be8SEnji Cooper 		BPF_STMT(BPF_ST, 1),
44957718be8SEnji Cooper 		BPF_STMT(BPF_LDX+BPF_IMM, 0), // retM
45057718be8SEnji Cooper 		BPF_STMT(BPF_MISC+BPF_COPX, 0),
45157718be8SEnji Cooper 		BPF_STMT(BPF_RET+BPF_A, 0)
45257718be8SEnji Cooper 	};
45357718be8SEnji Cooper 
45457718be8SEnji Cooper 	bpfjit_func_t code;
45557718be8SEnji Cooper 	uint8_t pkt[1] = { 0 };
45657718be8SEnji Cooper 	uint32_t mem[ctx.extwords];
45757718be8SEnji Cooper 	void *arg = (void*)(uintptr_t)3;
45857718be8SEnji Cooper 
45957718be8SEnji Cooper 	/* Pre-inited words. */
46057718be8SEnji Cooper 	mem[0] = 0;
46157718be8SEnji Cooper 	mem[3] = 3;
46257718be8SEnji Cooper 
46357718be8SEnji Cooper 	bpf_args_t args = {
46457718be8SEnji Cooper 		.pkt = pkt,
46557718be8SEnji Cooper 		.buflen = sizeof(pkt),
46657718be8SEnji Cooper 		.wirelen = sizeof(pkt),
46757718be8SEnji Cooper 		.arg = arg,
46857718be8SEnji Cooper 		.mem = mem,
46957718be8SEnji Cooper 	};
47057718be8SEnji Cooper 
47157718be8SEnji Cooper 	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
47257718be8SEnji Cooper 
47357718be8SEnji Cooper 	RZ(rump_init());
47457718be8SEnji Cooper 
47557718be8SEnji Cooper 	rump_schedule();
47657718be8SEnji Cooper 	code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count);
47757718be8SEnji Cooper 	rump_unschedule();
47857718be8SEnji Cooper 	ATF_REQUIRE(code != NULL);
47957718be8SEnji Cooper 
48057718be8SEnji Cooper 	ATF_CHECK(code(&ctx, &args) == 3);
48157718be8SEnji Cooper 
48257718be8SEnji Cooper 	rump_schedule();
48357718be8SEnji Cooper 	rumpns_bpfjit_free_code(code);
48457718be8SEnji Cooper 	rump_unschedule();
48557718be8SEnji Cooper }
48657718be8SEnji Cooper 
ATF_TP_ADD_TCS(tp)48757718be8SEnji Cooper ATF_TP_ADD_TCS(tp)
48857718be8SEnji Cooper {
48957718be8SEnji Cooper 
49057718be8SEnji Cooper 	/*
49157718be8SEnji Cooper 	 * For every new test please also add a similar test
49257718be8SEnji Cooper 	 * to ../../lib/libbpfjit/t_extmem.c
49357718be8SEnji Cooper 	 */
49457718be8SEnji Cooper 	//ATF_TP_ADD_TC(tp, bpfjit_extmem_load_default);
49557718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, bpfjit_extmem_load_preinited);
49657718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, bpfjit_extmem_invalid_load);
49757718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, bpfjit_extmem_store);
49857718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, bpfjit_extmem_side_effect);
49957718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, bpfjit_extmem_invalid_store);
50057718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, bpfjit_cop_ret_mem);
50157718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, bpfjit_cop_ret_preinited_mem);
50257718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, bpfjit_copx_ret_mem);
50357718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, bpfjit_copx_ret_preinited_mem);
50457718be8SEnji Cooper 
50557718be8SEnji Cooper 	return atf_no_error();
50657718be8SEnji Cooper }
507