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