2014-05-09 04:10:52 +07:00
|
|
|
/*
|
|
|
|
* Testsuite for BPF interpreter and BPF JIT compiler
|
|
|
|
*
|
|
|
|
* Copyright (c) 2011-2014 PLUMgrid, http://plumgrid.com
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of version 2 of the GNU General Public
|
|
|
|
* License as published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* General Public License for more details.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
|
|
|
|
|
|
|
#include <linux/init.h>
|
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/filter.h>
|
2015-07-21 10:34:19 +07:00
|
|
|
#include <linux/bpf.h>
|
2014-05-09 04:10:52 +07:00
|
|
|
#include <linux/skbuff.h>
|
|
|
|
#include <linux/netdevice.h>
|
|
|
|
#include <linux/if_vlan.h>
|
2015-05-13 18:12:43 +07:00
|
|
|
#include <linux/random.h>
|
2015-08-04 20:19:08 +07:00
|
|
|
#include <linux/highmem.h>
|
2018-02-27 01:52:46 +07:00
|
|
|
#include <linux/sched.h>
|
2014-05-09 04:10:52 +07:00
|
|
|
|
2014-05-23 23:44:00 +07:00
|
|
|
/* General test specific settings */
|
2014-05-09 04:10:52 +07:00
|
|
|
#define MAX_SUBTESTS 3
|
2018-02-28 23:39:20 +07:00
|
|
|
#define MAX_TESTRUNS 1000
|
2014-05-09 04:10:52 +07:00
|
|
|
#define MAX_DATA 128
|
|
|
|
#define MAX_INSNS 512
|
|
|
|
#define MAX_K 0xffffFFFF
|
|
|
|
|
2014-05-23 23:44:00 +07:00
|
|
|
/* Few constants used to init test 'skb' */
|
2014-05-09 04:10:52 +07:00
|
|
|
#define SKB_TYPE 3
|
|
|
|
#define SKB_MARK 0x1234aaaa
|
|
|
|
#define SKB_HASH 0x1234aaab
|
|
|
|
#define SKB_QUEUE_MAP 123
|
|
|
|
#define SKB_VLAN_TCI 0xffff
|
|
|
|
#define SKB_DEV_IFINDEX 577
|
|
|
|
#define SKB_DEV_TYPE 588
|
|
|
|
|
2014-05-23 23:44:00 +07:00
|
|
|
/* Redefine REGs to make tests less verbose */
|
|
|
|
#define R0 BPF_REG_0
|
|
|
|
#define R1 BPF_REG_1
|
|
|
|
#define R2 BPF_REG_2
|
|
|
|
#define R3 BPF_REG_3
|
|
|
|
#define R4 BPF_REG_4
|
|
|
|
#define R5 BPF_REG_5
|
|
|
|
#define R6 BPF_REG_6
|
|
|
|
#define R7 BPF_REG_7
|
|
|
|
#define R8 BPF_REG_8
|
|
|
|
#define R9 BPF_REG_9
|
|
|
|
#define R10 BPF_REG_10
|
|
|
|
|
|
|
|
/* Flags that can be passed to test cases */
|
|
|
|
#define FLAG_NO_DATA BIT(0)
|
|
|
|
#define FLAG_EXPECTED_FAIL BIT(1)
|
2015-08-04 20:19:08 +07:00
|
|
|
#define FLAG_SKB_FRAG BIT(2)
|
2014-05-23 23:44:00 +07:00
|
|
|
|
|
|
|
enum {
|
|
|
|
CLASSIC = BIT(6), /* Old BPF instructions only. */
|
|
|
|
INTERNAL = BIT(7), /* Extended instruction set. */
|
|
|
|
};
|
|
|
|
|
|
|
|
#define TEST_TYPE_MASK (CLASSIC | INTERNAL)
|
2014-05-09 04:10:52 +07:00
|
|
|
|
|
|
|
struct bpf_test {
|
|
|
|
const char *descr;
|
|
|
|
union {
|
|
|
|
struct sock_filter insns[MAX_INSNS];
|
2014-07-25 06:38:21 +07:00
|
|
|
struct bpf_insn insns_int[MAX_INSNS];
|
2015-05-13 18:12:43 +07:00
|
|
|
struct {
|
|
|
|
void *insns;
|
|
|
|
unsigned int len;
|
|
|
|
} ptr;
|
2014-05-23 00:16:46 +07:00
|
|
|
} u;
|
2014-05-23 23:44:00 +07:00
|
|
|
__u8 aux;
|
2014-05-09 04:10:52 +07:00
|
|
|
__u8 data[MAX_DATA];
|
|
|
|
struct {
|
|
|
|
int data_size;
|
|
|
|
__u32 result;
|
|
|
|
} test[MAX_SUBTESTS];
|
2015-05-13 18:12:43 +07:00
|
|
|
int (*fill_helper)(struct bpf_test *self);
|
bpf: fix selftests/bpf test_kmod.sh failure when CONFIG_BPF_JIT_ALWAYS_ON=y
With CONFIG_BPF_JIT_ALWAYS_ON is defined in the config file,
tools/testing/selftests/bpf/test_kmod.sh failed like below:
[root@localhost bpf]# ./test_kmod.sh
sysctl: setting key "net.core.bpf_jit_enable": Invalid argument
[ JIT enabled:0 hardened:0 ]
[ 132.175681] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 132.458834] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:0 ]
[ 133.456025] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 133.730935] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:1 ]
[ 134.769730] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 135.050864] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:2 ]
[ 136.442882] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 136.821810] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[root@localhost bpf]#
The test_kmod.sh load/remove test_bpf.ko multiple times with different
settings for sysctl net.core.bpf_jit_{enable,harden}. The failed test #297
of test_bpf.ko is designed such that JIT always fails.
Commit 290af86629b2 (bpf: introduce BPF_JIT_ALWAYS_ON config)
introduced the following tightening logic:
...
if (!bpf_prog_is_dev_bound(fp->aux)) {
fp = bpf_int_jit_compile(fp);
#ifdef CONFIG_BPF_JIT_ALWAYS_ON
if (!fp->jited) {
*err = -ENOTSUPP;
return fp;
}
#endif
...
With this logic, Test #297 always gets return value -ENOTSUPP
when CONFIG_BPF_JIT_ALWAYS_ON is defined, causing the test failure.
This patch fixed the failure by marking Test #297 as expected failure
when CONFIG_BPF_JIT_ALWAYS_ON is defined.
Fixes: 290af86629b2 (bpf: introduce BPF_JIT_ALWAYS_ON config)
Signed-off-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
2018-02-03 13:37:15 +07:00
|
|
|
int expected_errcode; /* used when FLAG_EXPECTED_FAIL is set in the aux */
|
2015-08-04 20:19:08 +07:00
|
|
|
__u8 frag_data[MAX_DATA];
|
2017-05-31 03:31:32 +07:00
|
|
|
int stack_depth; /* for eBPF only, since tests don't call verifier */
|
2014-05-09 04:10:52 +07:00
|
|
|
};
|
|
|
|
|
2015-05-13 18:12:43 +07:00
|
|
|
/* Large test cases need separate allocation and fill handler. */
|
|
|
|
|
|
|
|
static int bpf_fill_maxinsns1(struct bpf_test *self)
|
|
|
|
{
|
|
|
|
unsigned int len = BPF_MAXINSNS;
|
|
|
|
struct sock_filter *insn;
|
|
|
|
__u32 k = ~0;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL);
|
|
|
|
if (!insn)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
for (i = 0; i < len; i++, k--)
|
|
|
|
insn[i] = __BPF_STMT(BPF_RET | BPF_K, k);
|
|
|
|
|
|
|
|
self->u.ptr.insns = insn;
|
|
|
|
self->u.ptr.len = len;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int bpf_fill_maxinsns2(struct bpf_test *self)
|
|
|
|
{
|
|
|
|
unsigned int len = BPF_MAXINSNS;
|
|
|
|
struct sock_filter *insn;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL);
|
|
|
|
if (!insn)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
for (i = 0; i < len; i++)
|
|
|
|
insn[i] = __BPF_STMT(BPF_RET | BPF_K, 0xfefefefe);
|
|
|
|
|
|
|
|
self->u.ptr.insns = insn;
|
|
|
|
self->u.ptr.len = len;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int bpf_fill_maxinsns3(struct bpf_test *self)
|
|
|
|
{
|
|
|
|
unsigned int len = BPF_MAXINSNS;
|
|
|
|
struct sock_filter *insn;
|
|
|
|
struct rnd_state rnd;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL);
|
|
|
|
if (!insn)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
prandom_seed_state(&rnd, 3141592653589793238ULL);
|
|
|
|
|
|
|
|
for (i = 0; i < len - 1; i++) {
|
|
|
|
__u32 k = prandom_u32_state(&rnd);
|
|
|
|
|
|
|
|
insn[i] = __BPF_STMT(BPF_ALU | BPF_ADD | BPF_K, k);
|
|
|
|
}
|
|
|
|
|
|
|
|
insn[len - 1] = __BPF_STMT(BPF_RET | BPF_A, 0);
|
|
|
|
|
|
|
|
self->u.ptr.insns = insn;
|
|
|
|
self->u.ptr.len = len;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int bpf_fill_maxinsns4(struct bpf_test *self)
|
|
|
|
{
|
|
|
|
unsigned int len = BPF_MAXINSNS + 1;
|
|
|
|
struct sock_filter *insn;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL);
|
|
|
|
if (!insn)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
for (i = 0; i < len; i++)
|
|
|
|
insn[i] = __BPF_STMT(BPF_RET | BPF_K, 0xfefefefe);
|
|
|
|
|
|
|
|
self->u.ptr.insns = insn;
|
|
|
|
self->u.ptr.len = len;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int bpf_fill_maxinsns5(struct bpf_test *self)
|
|
|
|
{
|
|
|
|
unsigned int len = BPF_MAXINSNS;
|
|
|
|
struct sock_filter *insn;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL);
|
|
|
|
if (!insn)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
insn[0] = __BPF_JUMP(BPF_JMP | BPF_JA, len - 2, 0, 0);
|
|
|
|
|
|
|
|
for (i = 1; i < len - 1; i++)
|
|
|
|
insn[i] = __BPF_STMT(BPF_RET | BPF_K, 0xfefefefe);
|
|
|
|
|
|
|
|
insn[len - 1] = __BPF_STMT(BPF_RET | BPF_K, 0xabababab);
|
|
|
|
|
|
|
|
self->u.ptr.insns = insn;
|
|
|
|
self->u.ptr.len = len;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int bpf_fill_maxinsns6(struct bpf_test *self)
|
|
|
|
{
|
|
|
|
unsigned int len = BPF_MAXINSNS;
|
|
|
|
struct sock_filter *insn;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL);
|
|
|
|
if (!insn)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
for (i = 0; i < len - 1; i++)
|
|
|
|
insn[i] = __BPF_STMT(BPF_LD | BPF_W | BPF_ABS, SKF_AD_OFF +
|
|
|
|
SKF_AD_VLAN_TAG_PRESENT);
|
|
|
|
|
|
|
|
insn[len - 1] = __BPF_STMT(BPF_RET | BPF_A, 0);
|
|
|
|
|
|
|
|
self->u.ptr.insns = insn;
|
|
|
|
self->u.ptr.len = len;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int bpf_fill_maxinsns7(struct bpf_test *self)
|
|
|
|
{
|
|
|
|
unsigned int len = BPF_MAXINSNS;
|
|
|
|
struct sock_filter *insn;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL);
|
|
|
|
if (!insn)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
for (i = 0; i < len - 4; i++)
|
|
|
|
insn[i] = __BPF_STMT(BPF_LD | BPF_W | BPF_ABS, SKF_AD_OFF +
|
|
|
|
SKF_AD_CPU);
|
|
|
|
|
|
|
|
insn[len - 4] = __BPF_STMT(BPF_MISC | BPF_TAX, 0);
|
|
|
|
insn[len - 3] = __BPF_STMT(BPF_LD | BPF_W | BPF_ABS, SKF_AD_OFF +
|
|
|
|
SKF_AD_CPU);
|
|
|
|
insn[len - 2] = __BPF_STMT(BPF_ALU | BPF_SUB | BPF_X, 0);
|
|
|
|
insn[len - 1] = __BPF_STMT(BPF_RET | BPF_A, 0);
|
|
|
|
|
|
|
|
self->u.ptr.insns = insn;
|
|
|
|
self->u.ptr.len = len;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int bpf_fill_maxinsns8(struct bpf_test *self)
|
|
|
|
{
|
|
|
|
unsigned int len = BPF_MAXINSNS;
|
|
|
|
struct sock_filter *insn;
|
|
|
|
int i, jmp_off = len - 3;
|
|
|
|
|
|
|
|
insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL);
|
|
|
|
if (!insn)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
insn[0] = __BPF_STMT(BPF_LD | BPF_IMM, 0xffffffff);
|
|
|
|
|
|
|
|
for (i = 1; i < len - 1; i++)
|
|
|
|
insn[i] = __BPF_JUMP(BPF_JMP | BPF_JGT, 0xffffffff, jmp_off--, 0);
|
|
|
|
|
|
|
|
insn[len - 1] = __BPF_STMT(BPF_RET | BPF_A, 0);
|
|
|
|
|
|
|
|
self->u.ptr.insns = insn;
|
|
|
|
self->u.ptr.len = len;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-05-23 06:10:07 +07:00
|
|
|
static int bpf_fill_maxinsns9(struct bpf_test *self)
|
|
|
|
{
|
|
|
|
unsigned int len = BPF_MAXINSNS;
|
|
|
|
struct bpf_insn *insn;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL);
|
|
|
|
if (!insn)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
insn[0] = BPF_JMP_IMM(BPF_JA, 0, 0, len - 2);
|
|
|
|
insn[1] = BPF_ALU32_IMM(BPF_MOV, R0, 0xcbababab);
|
|
|
|
insn[2] = BPF_EXIT_INSN();
|
|
|
|
|
|
|
|
for (i = 3; i < len - 2; i++)
|
|
|
|
insn[i] = BPF_ALU32_IMM(BPF_MOV, R0, 0xfefefefe);
|
|
|
|
|
|
|
|
insn[len - 2] = BPF_EXIT_INSN();
|
|
|
|
insn[len - 1] = BPF_JMP_IMM(BPF_JA, 0, 0, -(len - 1));
|
|
|
|
|
|
|
|
self->u.ptr.insns = insn;
|
|
|
|
self->u.ptr.len = len;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int bpf_fill_maxinsns10(struct bpf_test *self)
|
|
|
|
{
|
|
|
|
unsigned int len = BPF_MAXINSNS, hlen = len - 2;
|
|
|
|
struct bpf_insn *insn;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL);
|
|
|
|
if (!insn)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
for (i = 0; i < hlen / 2; i++)
|
|
|
|
insn[i] = BPF_JMP_IMM(BPF_JA, 0, 0, hlen - 2 - 2 * i);
|
|
|
|
for (i = hlen - 1; i > hlen / 2; i--)
|
|
|
|
insn[i] = BPF_JMP_IMM(BPF_JA, 0, 0, hlen - 1 - 2 * i);
|
|
|
|
|
|
|
|
insn[hlen / 2] = BPF_JMP_IMM(BPF_JA, 0, 0, hlen / 2 - 1);
|
|
|
|
insn[hlen] = BPF_ALU32_IMM(BPF_MOV, R0, 0xabababac);
|
|
|
|
insn[hlen + 1] = BPF_EXIT_INSN();
|
|
|
|
|
|
|
|
self->u.ptr.insns = insn;
|
|
|
|
self->u.ptr.len = len;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-05-27 03:35:43 +07:00
|
|
|
static int __bpf_fill_ja(struct bpf_test *self, unsigned int len,
|
|
|
|
unsigned int plen)
|
|
|
|
{
|
|
|
|
struct sock_filter *insn;
|
|
|
|
unsigned int rlen;
|
|
|
|
int i, j;
|
|
|
|
|
|
|
|
insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL);
|
|
|
|
if (!insn)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
rlen = (len % plen) - 1;
|
|
|
|
|
|
|
|
for (i = 0; i + plen < len; i += plen)
|
|
|
|
for (j = 0; j < plen; j++)
|
|
|
|
insn[i + j] = __BPF_JUMP(BPF_JMP | BPF_JA,
|
|
|
|
plen - 1 - j, 0, 0);
|
|
|
|
for (j = 0; j < rlen; j++)
|
|
|
|
insn[i + j] = __BPF_JUMP(BPF_JMP | BPF_JA, rlen - 1 - j,
|
|
|
|
0, 0);
|
|
|
|
|
|
|
|
insn[len - 1] = __BPF_STMT(BPF_RET | BPF_K, 0xababcbac);
|
|
|
|
|
|
|
|
self->u.ptr.insns = insn;
|
|
|
|
self->u.ptr.len = len;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int bpf_fill_maxinsns11(struct bpf_test *self)
|
|
|
|
{
|
|
|
|
/* Hits 70 passes on x86_64, so cannot get JITed there. */
|
|
|
|
return __bpf_fill_ja(self, BPF_MAXINSNS, 68);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int bpf_fill_ja(struct bpf_test *self)
|
|
|
|
{
|
|
|
|
/* Hits exactly 11 passes on x86_64 JIT. */
|
|
|
|
return __bpf_fill_ja(self, 12, 9);
|
|
|
|
}
|
|
|
|
|
2015-07-21 10:34:19 +07:00
|
|
|
static int bpf_fill_ld_abs_get_processor_id(struct bpf_test *self)
|
|
|
|
{
|
|
|
|
unsigned int len = BPF_MAXINSNS;
|
|
|
|
struct sock_filter *insn;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL);
|
|
|
|
if (!insn)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
for (i = 0; i < len - 1; i += 2) {
|
|
|
|
insn[i] = __BPF_STMT(BPF_LD | BPF_B | BPF_ABS, 0);
|
|
|
|
insn[i + 1] = __BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
|
|
|
SKF_AD_OFF + SKF_AD_CPU);
|
|
|
|
}
|
|
|
|
|
|
|
|
insn[len - 1] = __BPF_STMT(BPF_RET | BPF_K, 0xbee);
|
|
|
|
|
|
|
|
self->u.ptr.insns = insn;
|
|
|
|
self->u.ptr.len = len;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define PUSH_CNT 68
|
|
|
|
/* test: {skb->data[0], vlan_push} x 68 + {skb->data[0], vlan_pop} x 68 */
|
|
|
|
static int bpf_fill_ld_abs_vlan_push_pop(struct bpf_test *self)
|
|
|
|
{
|
|
|
|
unsigned int len = BPF_MAXINSNS;
|
|
|
|
struct bpf_insn *insn;
|
|
|
|
int i = 0, j, k = 0;
|
|
|
|
|
|
|
|
insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL);
|
|
|
|
if (!insn)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
insn[i++] = BPF_MOV64_REG(R6, R1);
|
|
|
|
loop:
|
|
|
|
for (j = 0; j < PUSH_CNT; j++) {
|
|
|
|
insn[i++] = BPF_LD_ABS(BPF_B, 0);
|
|
|
|
insn[i] = BPF_JMP_IMM(BPF_JNE, R0, 0x34, len - i - 2);
|
|
|
|
i++;
|
|
|
|
insn[i++] = BPF_MOV64_REG(R1, R6);
|
|
|
|
insn[i++] = BPF_MOV64_IMM(R2, 1);
|
|
|
|
insn[i++] = BPF_MOV64_IMM(R3, 2);
|
|
|
|
insn[i++] = BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
|
|
|
|
bpf_skb_vlan_push_proto.func - __bpf_call_base);
|
|
|
|
insn[i] = BPF_JMP_IMM(BPF_JNE, R0, 0, len - i - 2);
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (j = 0; j < PUSH_CNT; j++) {
|
|
|
|
insn[i++] = BPF_LD_ABS(BPF_B, 0);
|
|
|
|
insn[i] = BPF_JMP_IMM(BPF_JNE, R0, 0x34, len - i - 2);
|
|
|
|
i++;
|
|
|
|
insn[i++] = BPF_MOV64_REG(R1, R6);
|
|
|
|
insn[i++] = BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
|
|
|
|
bpf_skb_vlan_pop_proto.func - __bpf_call_base);
|
|
|
|
insn[i] = BPF_JMP_IMM(BPF_JNE, R0, 0, len - i - 2);
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
if (++k < 5)
|
|
|
|
goto loop;
|
|
|
|
|
|
|
|
for (; i < len - 1; i++)
|
|
|
|
insn[i] = BPF_ALU32_IMM(BPF_MOV, R0, 0xbef);
|
|
|
|
|
|
|
|
insn[len - 1] = BPF_EXIT_INSN();
|
|
|
|
|
|
|
|
self->u.ptr.insns = insn;
|
|
|
|
self->u.ptr.len = len;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-12-15 03:07:27 +07:00
|
|
|
static int bpf_fill_ld_abs_vlan_push_pop2(struct bpf_test *self)
|
|
|
|
{
|
|
|
|
struct bpf_insn *insn;
|
|
|
|
|
|
|
|
insn = kmalloc_array(16, sizeof(*insn), GFP_KERNEL);
|
|
|
|
if (!insn)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
/* Due to func address being non-const, we need to
|
|
|
|
* assemble this here.
|
|
|
|
*/
|
|
|
|
insn[0] = BPF_MOV64_REG(R6, R1);
|
|
|
|
insn[1] = BPF_LD_ABS(BPF_B, 0);
|
|
|
|
insn[2] = BPF_LD_ABS(BPF_H, 0);
|
|
|
|
insn[3] = BPF_LD_ABS(BPF_W, 0);
|
|
|
|
insn[4] = BPF_MOV64_REG(R7, R6);
|
|
|
|
insn[5] = BPF_MOV64_IMM(R6, 0);
|
|
|
|
insn[6] = BPF_MOV64_REG(R1, R7);
|
|
|
|
insn[7] = BPF_MOV64_IMM(R2, 1);
|
|
|
|
insn[8] = BPF_MOV64_IMM(R3, 2);
|
|
|
|
insn[9] = BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
|
|
|
|
bpf_skb_vlan_push_proto.func - __bpf_call_base);
|
|
|
|
insn[10] = BPF_MOV64_REG(R6, R7);
|
|
|
|
insn[11] = BPF_LD_ABS(BPF_B, 0);
|
|
|
|
insn[12] = BPF_LD_ABS(BPF_H, 0);
|
|
|
|
insn[13] = BPF_LD_ABS(BPF_W, 0);
|
|
|
|
insn[14] = BPF_MOV64_IMM(R0, 42);
|
|
|
|
insn[15] = BPF_EXIT_INSN();
|
|
|
|
|
|
|
|
self->u.ptr.insns = insn;
|
|
|
|
self->u.ptr.len = 16;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-06-14 06:49:36 +07:00
|
|
|
static int bpf_fill_jump_around_ld_abs(struct bpf_test *self)
|
|
|
|
{
|
|
|
|
unsigned int len = BPF_MAXINSNS;
|
|
|
|
struct bpf_insn *insn;
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL);
|
|
|
|
if (!insn)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
insn[i++] = BPF_MOV64_REG(R6, R1);
|
|
|
|
insn[i++] = BPF_LD_ABS(BPF_B, 0);
|
|
|
|
insn[i] = BPF_JMP_IMM(BPF_JEQ, R0, 10, len - i - 2);
|
|
|
|
i++;
|
|
|
|
while (i < len - 1)
|
|
|
|
insn[i++] = BPF_LD_ABS(BPF_B, 1);
|
|
|
|
insn[i] = BPF_EXIT_INSN();
|
|
|
|
|
|
|
|
self->u.ptr.insns = insn;
|
|
|
|
self->u.ptr.len = len;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
bpf, arm64: implement jiting of BPF_XADD
This work adds BPF_XADD for BPF_W/BPF_DW to the arm64 JIT and therefore
completes JITing of all BPF instructions, meaning we can thus also remove
the 'notyet' label and do not need to fall back to the interpreter when
BPF_XADD is used in a program!
This now also brings arm64 JIT in line with x86_64, s390x, ppc64, sparc64,
where all current eBPF features are supported.
BPF_W example from test_bpf:
.u.insns_int = {
BPF_ALU32_IMM(BPF_MOV, R0, 0x12),
BPF_ST_MEM(BPF_W, R10, -40, 0x10),
BPF_STX_XADD(BPF_W, R10, R0, -40),
BPF_LDX_MEM(BPF_W, R0, R10, -40),
BPF_EXIT_INSN(),
},
[...]
00000020: 52800247 mov w7, #0x12 // #18
00000024: 928004eb mov x11, #0xffffffffffffffd8 // #-40
00000028: d280020a mov x10, #0x10 // #16
0000002c: b82b6b2a str w10, [x25,x11]
// start of xadd mapping:
00000030: 928004ea mov x10, #0xffffffffffffffd8 // #-40
00000034: 8b19014a add x10, x10, x25
00000038: f9800151 prfm pstl1strm, [x10]
0000003c: 885f7d4b ldxr w11, [x10]
00000040: 0b07016b add w11, w11, w7
00000044: 880b7d4b stxr w11, w11, [x10]
00000048: 35ffffab cbnz w11, 0x0000003c
// end of xadd mapping:
[...]
BPF_DW example from test_bpf:
.u.insns_int = {
BPF_ALU32_IMM(BPF_MOV, R0, 0x12),
BPF_ST_MEM(BPF_DW, R10, -40, 0x10),
BPF_STX_XADD(BPF_DW, R10, R0, -40),
BPF_LDX_MEM(BPF_DW, R0, R10, -40),
BPF_EXIT_INSN(),
},
[...]
00000020: 52800247 mov w7, #0x12 // #18
00000024: 928004eb mov x11, #0xffffffffffffffd8 // #-40
00000028: d280020a mov x10, #0x10 // #16
0000002c: f82b6b2a str x10, [x25,x11]
// start of xadd mapping:
00000030: 928004ea mov x10, #0xffffffffffffffd8 // #-40
00000034: 8b19014a add x10, x10, x25
00000038: f9800151 prfm pstl1strm, [x10]
0000003c: c85f7d4b ldxr x11, [x10]
00000040: 8b07016b add x11, x11, x7
00000044: c80b7d4b stxr w11, x11, [x10]
00000048: 35ffffab cbnz w11, 0x0000003c
// end of xadd mapping:
[...]
Tested on Cavium ThunderX ARMv8, test suite results after the patch:
No JIT: [ 3751.855362] test_bpf: Summary: 311 PASSED, 0 FAILED, [0/303 JIT'ed]
With JIT: [ 3573.759527] test_bpf: Summary: 311 PASSED, 0 FAILED, [303/303 JIT'ed]
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-05-01 07:57:20 +07:00
|
|
|
static int __bpf_fill_stxdw(struct bpf_test *self, int size)
|
|
|
|
{
|
|
|
|
unsigned int len = BPF_MAXINSNS;
|
|
|
|
struct bpf_insn *insn;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL);
|
|
|
|
if (!insn)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
insn[0] = BPF_ALU32_IMM(BPF_MOV, R0, 1);
|
|
|
|
insn[1] = BPF_ST_MEM(size, R10, -40, 42);
|
|
|
|
|
|
|
|
for (i = 2; i < len - 2; i++)
|
|
|
|
insn[i] = BPF_STX_XADD(size, R10, R0, -40);
|
|
|
|
|
|
|
|
insn[len - 2] = BPF_LDX_MEM(size, R0, R10, -40);
|
|
|
|
insn[len - 1] = BPF_EXIT_INSN();
|
|
|
|
|
|
|
|
self->u.ptr.insns = insn;
|
|
|
|
self->u.ptr.len = len;
|
2017-05-31 03:31:32 +07:00
|
|
|
self->stack_depth = 40;
|
bpf, arm64: implement jiting of BPF_XADD
This work adds BPF_XADD for BPF_W/BPF_DW to the arm64 JIT and therefore
completes JITing of all BPF instructions, meaning we can thus also remove
the 'notyet' label and do not need to fall back to the interpreter when
BPF_XADD is used in a program!
This now also brings arm64 JIT in line with x86_64, s390x, ppc64, sparc64,
where all current eBPF features are supported.
BPF_W example from test_bpf:
.u.insns_int = {
BPF_ALU32_IMM(BPF_MOV, R0, 0x12),
BPF_ST_MEM(BPF_W, R10, -40, 0x10),
BPF_STX_XADD(BPF_W, R10, R0, -40),
BPF_LDX_MEM(BPF_W, R0, R10, -40),
BPF_EXIT_INSN(),
},
[...]
00000020: 52800247 mov w7, #0x12 // #18
00000024: 928004eb mov x11, #0xffffffffffffffd8 // #-40
00000028: d280020a mov x10, #0x10 // #16
0000002c: b82b6b2a str w10, [x25,x11]
// start of xadd mapping:
00000030: 928004ea mov x10, #0xffffffffffffffd8 // #-40
00000034: 8b19014a add x10, x10, x25
00000038: f9800151 prfm pstl1strm, [x10]
0000003c: 885f7d4b ldxr w11, [x10]
00000040: 0b07016b add w11, w11, w7
00000044: 880b7d4b stxr w11, w11, [x10]
00000048: 35ffffab cbnz w11, 0x0000003c
// end of xadd mapping:
[...]
BPF_DW example from test_bpf:
.u.insns_int = {
BPF_ALU32_IMM(BPF_MOV, R0, 0x12),
BPF_ST_MEM(BPF_DW, R10, -40, 0x10),
BPF_STX_XADD(BPF_DW, R10, R0, -40),
BPF_LDX_MEM(BPF_DW, R0, R10, -40),
BPF_EXIT_INSN(),
},
[...]
00000020: 52800247 mov w7, #0x12 // #18
00000024: 928004eb mov x11, #0xffffffffffffffd8 // #-40
00000028: d280020a mov x10, #0x10 // #16
0000002c: f82b6b2a str x10, [x25,x11]
// start of xadd mapping:
00000030: 928004ea mov x10, #0xffffffffffffffd8 // #-40
00000034: 8b19014a add x10, x10, x25
00000038: f9800151 prfm pstl1strm, [x10]
0000003c: c85f7d4b ldxr x11, [x10]
00000040: 8b07016b add x11, x11, x7
00000044: c80b7d4b stxr w11, x11, [x10]
00000048: 35ffffab cbnz w11, 0x0000003c
// end of xadd mapping:
[...]
Tested on Cavium ThunderX ARMv8, test suite results after the patch:
No JIT: [ 3751.855362] test_bpf: Summary: 311 PASSED, 0 FAILED, [0/303 JIT'ed]
With JIT: [ 3573.759527] test_bpf: Summary: 311 PASSED, 0 FAILED, [303/303 JIT'ed]
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-05-01 07:57:20 +07:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int bpf_fill_stxw(struct bpf_test *self)
|
|
|
|
{
|
|
|
|
return __bpf_fill_stxdw(self, BPF_W);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int bpf_fill_stxdw(struct bpf_test *self)
|
|
|
|
{
|
|
|
|
return __bpf_fill_stxdw(self, BPF_DW);
|
|
|
|
}
|
|
|
|
|
2014-05-09 04:10:52 +07:00
|
|
|
static struct bpf_test tests[] = {
|
|
|
|
{
|
|
|
|
"TAX",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-05-09 04:10:52 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_IMM, 1),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TAX, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_IMM, 2),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_NEG, 0), /* A == -3 */
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TAX, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_LEN, 0),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TAX, 0), /* X == len - 3 */
|
|
|
|
BPF_STMT(BPF_LD | BPF_B | BPF_IND, 1),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0)
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC,
|
2014-05-09 04:10:52 +07:00
|
|
|
{ 10, 20, 30, 40, 50 },
|
|
|
|
{ { 2, 10 }, { 3, 20 }, { 4, 30 } },
|
|
|
|
},
|
2014-05-09 04:10:53 +07:00
|
|
|
{
|
|
|
|
"TXA",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_LDX | BPF_LEN, 0),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TXA, 0),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0) /* A == len * 2 */
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ 10, 20, 30, 40, 50 },
|
|
|
|
{ { 1, 2 }, { 3, 6 }, { 4, 8 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ADD_SUB_MUL_K",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_IMM, 1),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_K, 2),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 3),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_SUB | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_K, 0xffffffff),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_MUL | BPF_K, 3),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0)
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC | FLAG_NO_DATA,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ },
|
|
|
|
{ { 0, 0xfffffffd } }
|
|
|
|
},
|
|
|
|
{
|
2014-12-01 17:12:25 +07:00
|
|
|
"DIV_MOD_KX",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_IMM, 8),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_DIV | BPF_K, 2),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TAX, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_IMM, 0xffffffff),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_DIV | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TAX, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_IMM, 0xffffffff),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_DIV | BPF_K, 0x70000000),
|
2014-12-01 17:12:25 +07:00
|
|
|
BPF_STMT(BPF_MISC | BPF_TAX, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_IMM, 0xffffffff),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_MOD | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TAX, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_IMM, 0xffffffff),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_MOD | BPF_K, 0x70000000),
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0)
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC | FLAG_NO_DATA,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ },
|
2014-12-01 17:12:25 +07:00
|
|
|
{ { 0, 0x20000000 } }
|
2014-05-09 04:10:53 +07:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"AND_OR_LSH_K",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_IMM, 0xff),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0xf0),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_LSH | BPF_K, 27),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TAX, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_IMM, 0xf),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_OR | BPF_K, 0xf0),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0)
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC | FLAG_NO_DATA,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ },
|
|
|
|
{ { 0, 0x800000ff }, { 1, 0x800000ff } },
|
|
|
|
},
|
net: filter: fix length calculation in BPF testsuite
The current probe_filter_length() (the function that calculates the
length of a test BPF filter) behavior is to declare the end of the
filter as soon as it finds {0, *, *, 0}. This is actually a valid
insn ("ld #0"), so any filter with includes "BPF_STMT(BPF_LD | BPF_IMM, 0)"
fails (its length is cut short).
We are changing probe_filter_length() so as to start from the end, and
declare the end of the filter as the first instruction which is not
{0, *, *, 0}. This solution produces a simpler patch than the
alternative of using an explicit end-of-filter mark. It is technically
incorrect if your filter ends up with "ld #0", but that should not
happen anyway.
We also add a new test (LD_IMM_0) that includes ld #0 (does not work
without this patch).
Signed-off-by: Chema Gonzalez <chema@google.com>
Acked-by: Daniel Borkmann <dborkman@redhat.com>
Acked-by: Alexei Starovoitov <ast@plumgrid.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-05-31 00:15:12 +07:00
|
|
|
{
|
|
|
|
"LD_IMM_0",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LD | BPF_IMM, 0), /* ld #0 */
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 1, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 1),
|
|
|
|
},
|
|
|
|
CLASSIC,
|
|
|
|
{ },
|
|
|
|
{ { 1, 1 } },
|
|
|
|
},
|
2014-05-09 04:10:53 +07:00
|
|
|
{
|
|
|
|
"LD_IND",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_LDX | BPF_LEN, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_IND, MAX_K),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 1)
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ },
|
|
|
|
{ { 1, 0 }, { 10, 0 }, { 60, 0 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_ABS",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, 1000),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 1)
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ },
|
|
|
|
{ { 1, 0 }, { 10, 0 }, { 60, 0 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_ABS_LL",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_B | BPF_ABS, SKF_LL_OFF),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TAX, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_B | BPF_ABS, SKF_LL_OFF + 1),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0)
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ 1, 2, 3 },
|
|
|
|
{ { 1, 0 }, { 2, 3 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_IND_LL",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_IMM, SKF_LL_OFF - 1),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_LEN, 0),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TAX, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_B | BPF_IND, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0)
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ 1, 2, 3, 0xff },
|
|
|
|
{ { 1, 1 }, { 3, 3 }, { 4, 0xff } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_ABS_NET",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_B | BPF_ABS, SKF_NET_OFF),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TAX, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_B | BPF_ABS, SKF_NET_OFF + 1),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0)
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3 },
|
|
|
|
{ { 15, 0 }, { 16, 3 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_IND_NET",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_IMM, SKF_NET_OFF - 15),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_LEN, 0),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TAX, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_B | BPF_IND, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0)
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3 },
|
|
|
|
{ { 14, 0 }, { 15, 1 }, { 17, 3 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_PKTTYPE",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
|
|
|
SKF_AD_OFF + SKF_AD_PKTTYPE),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, SKB_TYPE, 1, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 1),
|
|
|
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
|
|
|
SKF_AD_OFF + SKF_AD_PKTTYPE),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, SKB_TYPE, 1, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 1),
|
|
|
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
|
|
|
SKF_AD_OFF + SKF_AD_PKTTYPE),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, SKB_TYPE, 1, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 1),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0)
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ },
|
|
|
|
{ { 1, 3 }, { 10, 3 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_MARK",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
|
|
|
SKF_AD_OFF + SKF_AD_MARK),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0)
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ },
|
|
|
|
{ { 1, SKB_MARK}, { 10, SKB_MARK} },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_RXHASH",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
|
|
|
SKF_AD_OFF + SKF_AD_RXHASH),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0)
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ },
|
|
|
|
{ { 1, SKB_HASH}, { 10, SKB_HASH} },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_QUEUE",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
|
|
|
SKF_AD_OFF + SKF_AD_QUEUE),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0)
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ },
|
|
|
|
{ { 1, SKB_QUEUE_MAP }, { 10, SKB_QUEUE_MAP } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_PROTOCOL",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_B | BPF_ABS, 1),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 20, 1, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
|
|
|
SKF_AD_OFF + SKF_AD_PROTOCOL),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TAX, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_B | BPF_ABS, 2),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 30, 1, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 0),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TXA, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0)
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ 10, 20, 30 },
|
|
|
|
{ { 10, ETH_P_IP }, { 100, ETH_P_IP } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_VLAN_TAG",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
|
|
|
SKF_AD_OFF + SKF_AD_VLAN_TAG),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0)
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ },
|
|
|
|
{
|
|
|
|
{ 1, SKB_VLAN_TCI & ~VLAN_TAG_PRESENT },
|
|
|
|
{ 10, SKB_VLAN_TCI & ~VLAN_TAG_PRESENT }
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_VLAN_TAG_PRESENT",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
|
|
|
SKF_AD_OFF + SKF_AD_VLAN_TAG_PRESENT),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0)
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ },
|
|
|
|
{
|
|
|
|
{ 1, !!(SKB_VLAN_TCI & VLAN_TAG_PRESENT) },
|
|
|
|
{ 10, !!(SKB_VLAN_TCI & VLAN_TAG_PRESENT) }
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_IFINDEX",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
|
|
|
SKF_AD_OFF + SKF_AD_IFINDEX),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0)
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ },
|
|
|
|
{ { 1, SKB_DEV_IFINDEX }, { 10, SKB_DEV_IFINDEX } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_HATYPE",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
|
|
|
SKF_AD_OFF + SKF_AD_HATYPE),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0)
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ },
|
|
|
|
{ { 1, SKB_DEV_TYPE }, { 10, SKB_DEV_TYPE } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_CPU",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
|
|
|
SKF_AD_OFF + SKF_AD_CPU),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TAX, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
|
|
|
SKF_AD_OFF + SKF_AD_CPU),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_SUB | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0)
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ },
|
|
|
|
{ { 1, 0 }, { 10, 0 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_NLATTR",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-06-07 07:48:20 +07:00
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 2),
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_MISC | BPF_TXA, 0),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 3),
|
|
|
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
|
|
|
SKF_AD_OFF + SKF_AD_NLATTR),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0)
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC,
|
2014-06-07 07:48:20 +07:00
|
|
|
#ifdef __BIG_ENDIAN
|
|
|
|
{ 0xff, 0xff, 0, 4, 0, 2, 0, 4, 0, 3 },
|
|
|
|
#else
|
|
|
|
{ 0xff, 0xff, 4, 0, 2, 0, 4, 0, 3, 0 },
|
|
|
|
#endif
|
|
|
|
{ { 4, 0 }, { 20, 6 } },
|
2014-05-09 04:10:53 +07:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_NLATTR_NEST",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-06-07 07:48:20 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_IMM, 2),
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 3),
|
|
|
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
|
|
|
SKF_AD_OFF + SKF_AD_NLATTR_NEST),
|
2014-06-07 07:48:20 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_IMM, 2),
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
|
|
|
SKF_AD_OFF + SKF_AD_NLATTR_NEST),
|
2014-06-07 07:48:20 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_IMM, 2),
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
|
|
|
SKF_AD_OFF + SKF_AD_NLATTR_NEST),
|
2014-06-07 07:48:20 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_IMM, 2),
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
|
|
|
SKF_AD_OFF + SKF_AD_NLATTR_NEST),
|
2014-06-07 07:48:20 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_IMM, 2),
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
|
|
|
SKF_AD_OFF + SKF_AD_NLATTR_NEST),
|
2014-06-07 07:48:20 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_IMM, 2),
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
|
|
|
SKF_AD_OFF + SKF_AD_NLATTR_NEST),
|
2014-06-07 07:48:20 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_IMM, 2),
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
|
|
|
SKF_AD_OFF + SKF_AD_NLATTR_NEST),
|
2014-06-07 07:48:20 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_IMM, 2),
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
|
|
|
SKF_AD_OFF + SKF_AD_NLATTR_NEST),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0)
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC,
|
2014-06-07 07:48:20 +07:00
|
|
|
#ifdef __BIG_ENDIAN
|
|
|
|
{ 0xff, 0xff, 0, 12, 0, 1, 0, 4, 0, 2, 0, 4, 0, 3 },
|
|
|
|
#else
|
|
|
|
{ 0xff, 0xff, 12, 0, 1, 0, 4, 0, 2, 0, 4, 0, 3, 0 },
|
|
|
|
#endif
|
|
|
|
{ { 4, 0 }, { 20, 10 } },
|
2014-05-09 04:10:53 +07:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_PAYLOAD_OFF",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
|
|
|
SKF_AD_OFF + SKF_AD_PAY_OFFSET),
|
|
|
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
|
|
|
SKF_AD_OFF + SKF_AD_PAY_OFFSET),
|
|
|
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
|
|
|
SKF_AD_OFF + SKF_AD_PAY_OFFSET),
|
|
|
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
|
|
|
SKF_AD_OFF + SKF_AD_PAY_OFFSET),
|
|
|
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
|
|
|
SKF_AD_OFF + SKF_AD_PAY_OFFSET),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0)
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC,
|
2014-05-09 04:10:53 +07:00
|
|
|
/* 00:00:00:00:00:00 > 00:00:00:00:00:00, ethtype IPv4 (0x0800),
|
|
|
|
* length 98: 127.0.0.1 > 127.0.0.1: ICMP echo request,
|
|
|
|
* id 9737, seq 1, length 64
|
|
|
|
*/
|
|
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
0x08, 0x00,
|
|
|
|
0x45, 0x00, 0x00, 0x54, 0xac, 0x8b, 0x40, 0x00, 0x40,
|
|
|
|
0x01, 0x90, 0x1b, 0x7f, 0x00, 0x00, 0x01 },
|
|
|
|
{ { 30, 0 }, { 100, 42 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_ANC_XOR",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_IMM, 10),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 300),
|
|
|
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
|
|
|
SKF_AD_OFF + SKF_AD_ALU_XOR_X),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0)
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ },
|
|
|
|
{ { 4, 10 ^ 300 }, { 20, 10 ^ 300 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"SPILL_FILL",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_LDX | BPF_LEN, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_IMM, 2),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_RSH, 1),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_XOR | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_ST, 1), /* M1 = 1 ^ len */
|
|
|
|
BPF_STMT(BPF_ALU | BPF_XOR | BPF_K, 0x80000000),
|
|
|
|
BPF_STMT(BPF_ST, 2), /* M2 = 1 ^ len ^ 0x80000000 */
|
|
|
|
BPF_STMT(BPF_STX, 15), /* M3 = len */
|
|
|
|
BPF_STMT(BPF_LDX | BPF_MEM, 1),
|
|
|
|
BPF_STMT(BPF_LD | BPF_MEM, 2),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_XOR | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_MEM, 15),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_XOR | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0)
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ },
|
|
|
|
{ { 1, 0x80000001 }, { 2, 0x80000002 }, { 60, 0x80000000 ^ 60 } }
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"JEQ",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_LDX | BPF_LEN, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_B | BPF_ABS, 2),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_X, 0, 0, 1),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 1),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, MAX_K)
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ 3, 3, 3, 3, 3 },
|
|
|
|
{ { 1, 0 }, { 3, 1 }, { 4, MAX_K } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"JGT",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_LDX | BPF_LEN, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_B | BPF_ABS, 2),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JGT | BPF_X, 0, 0, 1),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 1),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, MAX_K)
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ 4, 4, 4, 3, 3 },
|
|
|
|
{ { 2, 0 }, { 3, 1 }, { 4, MAX_K } },
|
|
|
|
},
|
bpf: add BPF_J{LT,LE,SLT,SLE} instructions
Currently, eBPF only understands BPF_JGT (>), BPF_JGE (>=),
BPF_JSGT (s>), BPF_JSGE (s>=) instructions, this means that
particularly *JLT/*JLE counterparts involving immediates need
to be rewritten from e.g. X < [IMM] by swapping arguments into
[IMM] > X, meaning the immediate first is required to be loaded
into a register Y := [IMM], such that then we can compare with
Y > X. Note that the destination operand is always required to
be a register.
This has the downside of having unnecessarily increased register
pressure, meaning complex program would need to spill other
registers temporarily to stack in order to obtain an unused
register for the [IMM]. Loading to registers will thus also
affect state pruning since we need to account for that register
use and potentially those registers that had to be spilled/filled
again. As a consequence slightly more stack space might have
been used due to spilling, and BPF programs are a bit longer
due to extra code involving the register load and potentially
required spill/fills.
Thus, add BPF_JLT (<), BPF_JLE (<=), BPF_JSLT (s<), BPF_JSLE (s<=)
counterparts to the eBPF instruction set. Modifying LLVM to
remove the NegateCC() workaround in a PoC patch at [1] and
allowing it to also emit the new instructions resulted in
cilium's BPF programs that are injected into the fast-path to
have a reduced program length in the range of 2-3% (e.g.
accumulated main and tail call sections from one of the object
file reduced from 4864 to 4729 insns), reduced complexity in
the range of 10-30% (e.g. accumulated sections reduced in one
of the cases from 116432 to 88428 insns), and reduced stack
usage in the range of 1-5% (e.g. accumulated sections from one
of the object files reduced from 824 to 784b).
The modification for LLVM will be incorporated in a backwards
compatible way. Plan is for LLVM to have i) a target specific
option to offer a possibility to explicitly enable the extension
by the user (as we have with -m target specific extensions today
for various CPU insns), and ii) have the kernel checked for
presence of the extensions and enable them transparently when
the user is selecting more aggressive options such as -march=native
in a bpf target context. (Other frontends generating BPF byte
code, e.g. ply can probe the kernel directly for its code
generation.)
[1] https://github.com/borkmann/llvm/tree/bpf-insns
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-08-10 06:39:55 +07:00
|
|
|
{
|
|
|
|
"JGE (jt 0), test 1",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LDX | BPF_LEN, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_B | BPF_ABS, 2),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JGE | BPF_X, 0, 0, 1),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 1),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, MAX_K)
|
|
|
|
},
|
|
|
|
CLASSIC,
|
|
|
|
{ 4, 4, 4, 3, 3 },
|
|
|
|
{ { 2, 0 }, { 3, 1 }, { 4, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"JGE (jt 0), test 2",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LDX | BPF_LEN, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_B | BPF_ABS, 2),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JGE | BPF_X, 0, 0, 1),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 1),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, MAX_K)
|
|
|
|
},
|
|
|
|
CLASSIC,
|
|
|
|
{ 4, 4, 5, 3, 3 },
|
|
|
|
{ { 4, 1 }, { 5, 1 }, { 6, MAX_K } },
|
|
|
|
},
|
2014-05-09 04:10:53 +07:00
|
|
|
{
|
|
|
|
"JGE",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_LDX | BPF_LEN, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_B | BPF_IND, MAX_K),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 1, 1, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 10),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 2, 1, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 20),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 3, 1, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 30),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 4, 1, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 40),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, MAX_K)
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ 1, 2, 3, 4, 5 },
|
|
|
|
{ { 1, 20 }, { 3, 40 }, { 5, MAX_K } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"JSET",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_JUMP(BPF_JMP | BPF_JA, 0, 0, 0),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JA, 1, 1, 1),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JA, 0, 0, 0),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JA, 0, 0, 0),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_LEN, 0),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TXA, 0),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_SUB | BPF_K, 4),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TAX, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_W | BPF_IND, 0),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JSET | BPF_K, 1, 0, 1),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 10),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JSET | BPF_K, 0x80000000, 0, 1),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 20),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JSET | BPF_K, 0xffffff, 1, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 30),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JSET | BPF_K, 0xffffff, 1, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 30),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JSET | BPF_K, 0xffffff, 1, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 30),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JSET | BPF_K, 0xffffff, 1, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 30),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JSET | BPF_K, 0xffffff, 1, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 30),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, MAX_K)
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ 0, 0xAA, 0x55, 1 },
|
|
|
|
{ { 4, 10 }, { 5, 20 }, { 6, MAX_K } },
|
|
|
|
},
|
2014-05-09 04:10:52 +07:00
|
|
|
{
|
|
|
|
"tcpdump port 22",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-05-27 01:17:35 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 12),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x86dd, 0, 8), /* IPv6 */
|
|
|
|
BPF_STMT(BPF_LD | BPF_B | BPF_ABS, 20),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x84, 2, 0),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x6, 1, 0),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x11, 0, 17),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 54),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 22, 14, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 56),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 22, 12, 13),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x0800, 0, 12), /* IPv4 */
|
|
|
|
BPF_STMT(BPF_LD | BPF_B | BPF_ABS, 23),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x84, 2, 0),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x6, 1, 0),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x11, 0, 8),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 20),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JSET | BPF_K, 0x1fff, 6, 0),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_B | BPF_MSH, 14),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_IND, 14),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 22, 2, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_IND, 16),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 22, 0, 1),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 0xffff),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 0),
|
2014-05-09 04:10:52 +07:00
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC,
|
2014-05-09 04:10:52 +07:00
|
|
|
/* 3c:07:54:43:e5:76 > 10:bf:48:d6:43:d6, ethertype IPv4(0x0800)
|
|
|
|
* length 114: 10.1.1.149.49700 > 10.1.2.10.22: Flags [P.],
|
|
|
|
* seq 1305692979:1305693027, ack 3650467037, win 65535,
|
|
|
|
* options [nop,nop,TS val 2502645400 ecr 3971138], length 48
|
|
|
|
*/
|
|
|
|
{ 0x10, 0xbf, 0x48, 0xd6, 0x43, 0xd6,
|
|
|
|
0x3c, 0x07, 0x54, 0x43, 0xe5, 0x76,
|
|
|
|
0x08, 0x00,
|
|
|
|
0x45, 0x10, 0x00, 0x64, 0x75, 0xb5,
|
|
|
|
0x40, 0x00, 0x40, 0x06, 0xad, 0x2e, /* IP header */
|
|
|
|
0x0a, 0x01, 0x01, 0x95, /* ip src */
|
|
|
|
0x0a, 0x01, 0x02, 0x0a, /* ip dst */
|
|
|
|
0xc2, 0x24,
|
|
|
|
0x00, 0x16 /* dst port */ },
|
|
|
|
{ { 10, 0 }, { 30, 0 }, { 100, 65535 } },
|
|
|
|
},
|
2014-05-09 04:10:53 +07:00
|
|
|
{
|
|
|
|
"tcpdump complex",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-05-09 04:10:53 +07:00
|
|
|
/* tcpdump -nei eth0 'tcp port 22 and (((ip[2:2] -
|
|
|
|
* ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0) and
|
|
|
|
* (len > 115 or len < 30000000000)' -d
|
|
|
|
*/
|
2014-05-27 01:17:35 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 12),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x86dd, 30, 0),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x800, 0, 29),
|
|
|
|
BPF_STMT(BPF_LD | BPF_B | BPF_ABS, 23),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x6, 0, 27),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 20),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JSET | BPF_K, 0x1fff, 25, 0),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_B | BPF_MSH, 14),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_IND, 14),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 22, 2, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_IND, 16),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 22, 0, 20),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 16),
|
|
|
|
BPF_STMT(BPF_ST, 1),
|
|
|
|
BPF_STMT(BPF_LD | BPF_B | BPF_ABS, 14),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0xf),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_LSH | BPF_K, 2),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TAX, 0x5), /* libpcap emits K on TAX */
|
|
|
|
BPF_STMT(BPF_LD | BPF_MEM, 1),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_SUB | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_ST, 5),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_B | BPF_MSH, 14),
|
|
|
|
BPF_STMT(BPF_LD | BPF_B | BPF_IND, 26),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0xf0),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_RSH | BPF_K, 2),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TAX, 0x9), /* libpcap emits K on TAX */
|
|
|
|
BPF_STMT(BPF_LD | BPF_MEM, 5),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_X, 0, 4, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_LEN, 0),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JGT | BPF_K, 0x73, 1, 0),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 0xfc23ac00, 1, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 0xffff),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 0),
|
2014-05-09 04:10:53 +07:00
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ 0x10, 0xbf, 0x48, 0xd6, 0x43, 0xd6,
|
|
|
|
0x3c, 0x07, 0x54, 0x43, 0xe5, 0x76,
|
|
|
|
0x08, 0x00,
|
|
|
|
0x45, 0x10, 0x00, 0x64, 0x75, 0xb5,
|
|
|
|
0x40, 0x00, 0x40, 0x06, 0xad, 0x2e, /* IP header */
|
|
|
|
0x0a, 0x01, 0x01, 0x95, /* ip src */
|
|
|
|
0x0a, 0x01, 0x02, 0x0a, /* ip dst */
|
|
|
|
0xc2, 0x24,
|
|
|
|
0x00, 0x16 /* dst port */ },
|
|
|
|
{ { 10, 0 }, { 30, 0 }, { 100, 65535 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"RET_A",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-05-09 04:10:53 +07:00
|
|
|
/* check that unitialized X and A contain zeros */
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TXA, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0)
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC,
|
|
|
|
{ },
|
2014-05-09 04:10:53 +07:00
|
|
|
{ {1, 0}, {2, 0} },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"INT: ADD trivial",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns_int = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_ALU64_IMM(BPF_MOV, R1, 1),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R1, 2),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R2, 3),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R1, R2),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R1, -1),
|
|
|
|
BPF_ALU64_IMM(BPF_MUL, R1, 3),
|
|
|
|
BPF_ALU64_REG(BPF_MOV, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
INTERNAL,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ },
|
|
|
|
{ { 0, 0xfffffffd } }
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"INT: MUL_X",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns_int = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_ALU64_IMM(BPF_MOV, R0, -1),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R1, -1),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R2, 3),
|
|
|
|
BPF_ALU64_REG(BPF_MUL, R1, R2),
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R1, 0xfffffffd, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
INTERNAL,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ },
|
|
|
|
{ { 0, 1 } }
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"INT: MUL_X2",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns_int = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, -1),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, -1),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R2, 3),
|
|
|
|
BPF_ALU64_REG(BPF_MUL, R1, R2),
|
|
|
|
BPF_ALU64_IMM(BPF_RSH, R1, 8),
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R1, 0x2ffffff, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
INTERNAL,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ },
|
|
|
|
{ { 0, 1 } }
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"INT: MUL32_X",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns_int = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, -1),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R1, -1),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R2, 3),
|
|
|
|
BPF_ALU32_REG(BPF_MUL, R1, R2),
|
|
|
|
BPF_ALU64_IMM(BPF_RSH, R1, 8),
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R1, 0xffffff, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
INTERNAL,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ },
|
|
|
|
{ { 0, 1 } }
|
|
|
|
},
|
|
|
|
{
|
|
|
|
/* Have to test all register combinations, since
|
|
|
|
* JITing of different registers will produce
|
|
|
|
* different asm code.
|
|
|
|
*/
|
|
|
|
"INT: ADD 64-bit",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns_int = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_ALU64_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R1, 1),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R2, 2),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R3, 3),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R4, 4),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R5, 5),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R6, 6),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R7, 7),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R8, 8),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R9, 9),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R0, 20),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R1, 20),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R2, 20),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R3, 20),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R4, 20),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R5, 20),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R6, 20),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R7, 20),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R8, 20),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R9, 20),
|
|
|
|
BPF_ALU64_IMM(BPF_SUB, R0, 10),
|
|
|
|
BPF_ALU64_IMM(BPF_SUB, R1, 10),
|
|
|
|
BPF_ALU64_IMM(BPF_SUB, R2, 10),
|
|
|
|
BPF_ALU64_IMM(BPF_SUB, R3, 10),
|
|
|
|
BPF_ALU64_IMM(BPF_SUB, R4, 10),
|
|
|
|
BPF_ALU64_IMM(BPF_SUB, R5, 10),
|
|
|
|
BPF_ALU64_IMM(BPF_SUB, R6, 10),
|
|
|
|
BPF_ALU64_IMM(BPF_SUB, R7, 10),
|
|
|
|
BPF_ALU64_IMM(BPF_SUB, R8, 10),
|
|
|
|
BPF_ALU64_IMM(BPF_SUB, R9, 10),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R0),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R1),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R2),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R3),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R4),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R5),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R6),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R7),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R8),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R9), /* R0 == 155 */
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R0, 155, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R1, R0),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R1, R1),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R1, R2),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R1, R3),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R1, R4),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R1, R5),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R1, R6),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R1, R7),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R1, R8),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R1, R9), /* R1 == 456 */
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R1, 456, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R2, R0),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R2, R1),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R2, R2),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R2, R3),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R2, R4),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R2, R5),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R2, R6),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R2, R7),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R2, R8),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R2, R9), /* R2 == 1358 */
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R2, 1358, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R3, R0),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R3, R1),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R3, R2),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R3, R3),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R3, R4),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R3, R5),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R3, R6),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R3, R7),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R3, R8),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R3, R9), /* R3 == 4063 */
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R3, 4063, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R4, R0),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R4, R1),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R4, R2),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R4, R3),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R4, R4),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R4, R5),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R4, R6),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R4, R7),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R4, R8),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R4, R9), /* R4 == 12177 */
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R4, 12177, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R5, R0),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R5, R1),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R5, R2),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R5, R3),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R5, R4),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R5, R5),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R5, R6),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R5, R7),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R5, R8),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R5, R9), /* R5 == 36518 */
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R5, 36518, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R6, R0),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R6, R1),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R6, R2),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R6, R3),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R6, R4),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R6, R5),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R6, R6),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R6, R7),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R6, R8),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R6, R9), /* R6 == 109540 */
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R6, 109540, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R7, R0),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R7, R1),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R7, R2),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R7, R3),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R7, R4),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R7, R5),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R7, R6),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R7, R7),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R7, R8),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R7, R9), /* R7 == 328605 */
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R7, 328605, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R8, R0),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R8, R1),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R8, R2),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R8, R3),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R8, R4),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R8, R5),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R8, R6),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R8, R7),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R8, R8),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R8, R9), /* R8 == 985799 */
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R8, 985799, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R9, R0),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R9, R1),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R9, R2),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R9, R3),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R9, R4),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R9, R5),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R9, R6),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R9, R7),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R9, R8),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R9, R9), /* R9 == 2957380 */
|
|
|
|
BPF_ALU64_REG(BPF_MOV, R0, R9),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
INTERNAL,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ },
|
|
|
|
{ { 0, 2957380 } }
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"INT: ADD 32-bit",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns_int = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 20),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 1),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R2, 2),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R3, 3),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R4, 4),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R5, 5),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R6, 6),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R7, 7),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R8, 8),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R9, 9),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R1, 10),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R2, 10),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R3, 10),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R4, 10),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R5, 10),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R6, 10),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R7, 10),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R8, 10),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R9, 10),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R0, R1),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R0, R2),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R0, R3),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R0, R4),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R0, R5),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R0, R6),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R0, R7),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R0, R8),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R0, R9), /* R0 == 155 */
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R0, 155, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R1, R0),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R1, R1),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R1, R2),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R1, R3),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R1, R4),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R1, R5),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R1, R6),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R1, R7),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R1, R8),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R1, R9), /* R1 == 456 */
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R1, 456, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R2, R0),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R2, R1),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R2, R2),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R2, R3),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R2, R4),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R2, R5),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R2, R6),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R2, R7),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R2, R8),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R2, R9), /* R2 == 1358 */
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R2, 1358, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R3, R0),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R3, R1),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R3, R2),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R3, R3),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R3, R4),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R3, R5),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R3, R6),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R3, R7),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R3, R8),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R3, R9), /* R3 == 4063 */
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R3, 4063, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R4, R0),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R4, R1),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R4, R2),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R4, R3),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R4, R4),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R4, R5),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R4, R6),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R4, R7),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R4, R8),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R4, R9), /* R4 == 12177 */
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R4, 12177, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R5, R0),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R5, R1),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R5, R2),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R5, R3),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R5, R4),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R5, R5),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R5, R6),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R5, R7),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R5, R8),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R5, R9), /* R5 == 36518 */
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R5, 36518, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R6, R0),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R6, R1),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R6, R2),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R6, R3),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R6, R4),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R6, R5),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R6, R6),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R6, R7),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R6, R8),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R6, R9), /* R6 == 109540 */
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R6, 109540, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R7, R0),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R7, R1),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R7, R2),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R7, R3),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R7, R4),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R7, R5),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R7, R6),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R7, R7),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R7, R8),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R7, R9), /* R7 == 328605 */
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R7, 328605, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R8, R0),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R8, R1),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R8, R2),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R8, R3),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R8, R4),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R8, R5),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R8, R6),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R8, R7),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R8, R8),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R8, R9), /* R8 == 985799 */
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R8, 985799, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R9, R0),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R9, R1),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R9, R2),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R9, R3),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R9, R4),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R9, R5),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R9, R6),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R9, R7),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R9, R8),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R9, R9), /* R9 == 2957380 */
|
|
|
|
BPF_ALU32_REG(BPF_MOV, R0, R9),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
INTERNAL,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ },
|
|
|
|
{ { 0, 2957380 } }
|
|
|
|
},
|
|
|
|
{ /* Mainly checking JIT here. */
|
|
|
|
"INT: SUB",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns_int = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_ALU64_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R1, 1),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R2, 2),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R3, 3),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R4, 4),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R5, 5),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R6, 6),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R7, 7),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R8, 8),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R9, 9),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R0, R0),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R0, R1),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R0, R2),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R0, R3),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R0, R4),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R0, R5),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R0, R6),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R0, R7),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R0, R8),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R0, R9),
|
|
|
|
BPF_ALU64_IMM(BPF_SUB, R0, 10),
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R0, -55, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R1, R0),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R1, R2),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R1, R3),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R1, R4),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R1, R5),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R1, R6),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R1, R7),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R1, R8),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R1, R9),
|
|
|
|
BPF_ALU64_IMM(BPF_SUB, R1, 10),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R2, R0),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R2, R1),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R2, R3),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R2, R4),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R2, R5),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R2, R6),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R2, R7),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R2, R8),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R2, R9),
|
|
|
|
BPF_ALU64_IMM(BPF_SUB, R2, 10),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R3, R0),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R3, R1),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R3, R2),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R3, R4),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R3, R5),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R3, R6),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R3, R7),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R3, R8),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R3, R9),
|
|
|
|
BPF_ALU64_IMM(BPF_SUB, R3, 10),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R4, R0),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R4, R1),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R4, R2),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R4, R3),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R4, R5),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R4, R6),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R4, R7),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R4, R8),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R4, R9),
|
|
|
|
BPF_ALU64_IMM(BPF_SUB, R4, 10),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R5, R0),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R5, R1),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R5, R2),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R5, R3),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R5, R4),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R5, R6),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R5, R7),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R5, R8),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R5, R9),
|
|
|
|
BPF_ALU64_IMM(BPF_SUB, R5, 10),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R6, R0),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R6, R1),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R6, R2),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R6, R3),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R6, R4),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R6, R5),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R6, R7),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R6, R8),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R6, R9),
|
|
|
|
BPF_ALU64_IMM(BPF_SUB, R6, 10),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R7, R0),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R7, R1),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R7, R2),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R7, R3),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R7, R4),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R7, R5),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R7, R6),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R7, R8),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R7, R9),
|
|
|
|
BPF_ALU64_IMM(BPF_SUB, R7, 10),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R8, R0),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R8, R1),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R8, R2),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R8, R3),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R8, R4),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R8, R5),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R8, R6),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R8, R7),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R8, R9),
|
|
|
|
BPF_ALU64_IMM(BPF_SUB, R8, 10),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R9, R0),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R9, R1),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R9, R2),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R9, R3),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R9, R4),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R9, R5),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R9, R6),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R9, R7),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R9, R8),
|
|
|
|
BPF_ALU64_IMM(BPF_SUB, R9, 10),
|
|
|
|
BPF_ALU64_IMM(BPF_SUB, R0, 10),
|
|
|
|
BPF_ALU64_IMM(BPF_NEG, R0, 0),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R0, R1),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R0, R2),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R0, R3),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R0, R4),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R0, R5),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R0, R6),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R0, R7),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R0, R8),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R0, R9),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
INTERNAL,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ },
|
|
|
|
{ { 0, 11 } }
|
|
|
|
},
|
|
|
|
{ /* Mainly checking JIT here. */
|
|
|
|
"INT: XOR",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns_int = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_ALU64_REG(BPF_SUB, R0, R0),
|
|
|
|
BPF_ALU64_REG(BPF_XOR, R1, R1),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R0, R1, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R0, 10),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R1, -1),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R1, R1),
|
|
|
|
BPF_ALU64_REG(BPF_XOR, R2, R2),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R1, R2, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R2, R2),
|
|
|
|
BPF_ALU64_REG(BPF_XOR, R3, R3),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R0, 10),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R1, -1),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R2, R3, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R3, R3),
|
|
|
|
BPF_ALU64_REG(BPF_XOR, R4, R4),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R2, 1),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R5, -1),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R3, R4, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R4, R4),
|
|
|
|
BPF_ALU64_REG(BPF_XOR, R5, R5),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R3, 1),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R7, -1),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R5, R4, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R5, 1),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R5, R5),
|
|
|
|
BPF_ALU64_REG(BPF_XOR, R6, R6),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R1, 1),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R8, -1),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R5, R6, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R6, R6),
|
|
|
|
BPF_ALU64_REG(BPF_XOR, R7, R7),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R7, R6, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R7, R7),
|
|
|
|
BPF_ALU64_REG(BPF_XOR, R8, R8),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R7, R8, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R8, R8),
|
|
|
|
BPF_ALU64_REG(BPF_XOR, R9, R9),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R9, R8, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R9, R9),
|
|
|
|
BPF_ALU64_REG(BPF_XOR, R0, R0),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R9, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R1, R1),
|
|
|
|
BPF_ALU64_REG(BPF_XOR, R0, R0),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R9, R0, 2),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
INTERNAL,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ },
|
|
|
|
{ { 0, 1 } }
|
|
|
|
},
|
|
|
|
{ /* Mainly checking JIT here. */
|
|
|
|
"INT: MUL",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns_int = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_ALU64_IMM(BPF_MOV, R0, 11),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R1, 1),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R2, 2),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R3, 3),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R4, 4),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R5, 5),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R6, 6),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R7, 7),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R8, 8),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R9, 9),
|
|
|
|
BPF_ALU64_REG(BPF_MUL, R0, R0),
|
|
|
|
BPF_ALU64_REG(BPF_MUL, R0, R1),
|
|
|
|
BPF_ALU64_REG(BPF_MUL, R0, R2),
|
|
|
|
BPF_ALU64_REG(BPF_MUL, R0, R3),
|
|
|
|
BPF_ALU64_REG(BPF_MUL, R0, R4),
|
|
|
|
BPF_ALU64_REG(BPF_MUL, R0, R5),
|
|
|
|
BPF_ALU64_REG(BPF_MUL, R0, R6),
|
|
|
|
BPF_ALU64_REG(BPF_MUL, R0, R7),
|
|
|
|
BPF_ALU64_REG(BPF_MUL, R0, R8),
|
|
|
|
BPF_ALU64_REG(BPF_MUL, R0, R9),
|
|
|
|
BPF_ALU64_IMM(BPF_MUL, R0, 10),
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R0, 439084800, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU64_REG(BPF_MUL, R1, R0),
|
|
|
|
BPF_ALU64_REG(BPF_MUL, R1, R2),
|
|
|
|
BPF_ALU64_REG(BPF_MUL, R1, R3),
|
|
|
|
BPF_ALU64_REG(BPF_MUL, R1, R4),
|
|
|
|
BPF_ALU64_REG(BPF_MUL, R1, R5),
|
|
|
|
BPF_ALU64_REG(BPF_MUL, R1, R6),
|
|
|
|
BPF_ALU64_REG(BPF_MUL, R1, R7),
|
|
|
|
BPF_ALU64_REG(BPF_MUL, R1, R8),
|
|
|
|
BPF_ALU64_REG(BPF_MUL, R1, R9),
|
|
|
|
BPF_ALU64_IMM(BPF_MUL, R1, 10),
|
|
|
|
BPF_ALU64_REG(BPF_MOV, R2, R1),
|
|
|
|
BPF_ALU64_IMM(BPF_RSH, R2, 32),
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R2, 0x5a924, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU64_IMM(BPF_LSH, R1, 32),
|
|
|
|
BPF_ALU64_IMM(BPF_ARSH, R1, 32),
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R1, 0xebb90000, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU64_REG(BPF_MUL, R2, R0),
|
|
|
|
BPF_ALU64_REG(BPF_MUL, R2, R1),
|
|
|
|
BPF_ALU64_REG(BPF_MUL, R2, R3),
|
|
|
|
BPF_ALU64_REG(BPF_MUL, R2, R4),
|
|
|
|
BPF_ALU64_REG(BPF_MUL, R2, R5),
|
|
|
|
BPF_ALU64_REG(BPF_MUL, R2, R6),
|
|
|
|
BPF_ALU64_REG(BPF_MUL, R2, R7),
|
|
|
|
BPF_ALU64_REG(BPF_MUL, R2, R8),
|
|
|
|
BPF_ALU64_REG(BPF_MUL, R2, R9),
|
|
|
|
BPF_ALU64_IMM(BPF_MUL, R2, 10),
|
|
|
|
BPF_ALU64_IMM(BPF_RSH, R2, 32),
|
|
|
|
BPF_ALU64_REG(BPF_MOV, R0, R2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
INTERNAL,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ },
|
|
|
|
{ { 0, 0x35d97ef2 } }
|
|
|
|
},
|
2015-12-18 05:51:57 +07:00
|
|
|
{ /* Mainly checking JIT here. */
|
|
|
|
"MOV REG64",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 0xffffffffffffffffLL),
|
|
|
|
BPF_MOV64_REG(R1, R0),
|
|
|
|
BPF_MOV64_REG(R2, R1),
|
|
|
|
BPF_MOV64_REG(R3, R2),
|
|
|
|
BPF_MOV64_REG(R4, R3),
|
|
|
|
BPF_MOV64_REG(R5, R4),
|
|
|
|
BPF_MOV64_REG(R6, R5),
|
|
|
|
BPF_MOV64_REG(R7, R6),
|
|
|
|
BPF_MOV64_REG(R8, R7),
|
|
|
|
BPF_MOV64_REG(R9, R8),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R1, 0),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R2, 0),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R3, 0),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R4, 0),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R5, 0),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R6, 0),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R7, 0),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R8, 0),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R9, 0),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R0),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R1),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R2),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R3),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R4),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R5),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R6),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R7),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R8),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R9),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R0, 0xfefe),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xfefe } }
|
|
|
|
},
|
|
|
|
{ /* Mainly checking JIT here. */
|
|
|
|
"MOV REG32",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 0xffffffffffffffffLL),
|
|
|
|
BPF_MOV64_REG(R1, R0),
|
|
|
|
BPF_MOV64_REG(R2, R1),
|
|
|
|
BPF_MOV64_REG(R3, R2),
|
|
|
|
BPF_MOV64_REG(R4, R3),
|
|
|
|
BPF_MOV64_REG(R5, R4),
|
|
|
|
BPF_MOV64_REG(R6, R5),
|
|
|
|
BPF_MOV64_REG(R7, R6),
|
|
|
|
BPF_MOV64_REG(R8, R7),
|
|
|
|
BPF_MOV64_REG(R9, R8),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 0),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R2, 0),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R3, 0),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R4, 0),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R5, 0),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R6, 0),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R7, 0),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R8, 0),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R9, 0),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R0),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R1),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R2),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R3),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R4),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R5),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R6),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R7),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R8),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R9),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R0, 0xfefe),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xfefe } }
|
|
|
|
},
|
|
|
|
{ /* Mainly checking JIT here. */
|
|
|
|
"LD IMM64",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 0xffffffffffffffffLL),
|
|
|
|
BPF_MOV64_REG(R1, R0),
|
|
|
|
BPF_MOV64_REG(R2, R1),
|
|
|
|
BPF_MOV64_REG(R3, R2),
|
|
|
|
BPF_MOV64_REG(R4, R3),
|
|
|
|
BPF_MOV64_REG(R5, R4),
|
|
|
|
BPF_MOV64_REG(R6, R5),
|
|
|
|
BPF_MOV64_REG(R7, R6),
|
|
|
|
BPF_MOV64_REG(R8, R7),
|
|
|
|
BPF_MOV64_REG(R9, R8),
|
|
|
|
BPF_LD_IMM64(R0, 0x0LL),
|
|
|
|
BPF_LD_IMM64(R1, 0x0LL),
|
|
|
|
BPF_LD_IMM64(R2, 0x0LL),
|
|
|
|
BPF_LD_IMM64(R3, 0x0LL),
|
|
|
|
BPF_LD_IMM64(R4, 0x0LL),
|
|
|
|
BPF_LD_IMM64(R5, 0x0LL),
|
|
|
|
BPF_LD_IMM64(R6, 0x0LL),
|
|
|
|
BPF_LD_IMM64(R7, 0x0LL),
|
|
|
|
BPF_LD_IMM64(R8, 0x0LL),
|
|
|
|
BPF_LD_IMM64(R9, 0x0LL),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R0),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R1),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R2),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R3),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R4),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R5),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R6),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R7),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R8),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R9),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R0, 0xfefe),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xfefe } }
|
|
|
|
},
|
2014-05-09 04:10:53 +07:00
|
|
|
{
|
|
|
|
"INT: ALU MIX",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns_int = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_ALU64_IMM(BPF_MOV, R0, 11),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R0, -1),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R2, 2),
|
|
|
|
BPF_ALU64_IMM(BPF_XOR, R2, 3),
|
|
|
|
BPF_ALU64_REG(BPF_DIV, R0, R2),
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R0, 10, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU64_IMM(BPF_MOD, R0, 3),
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R0, 1, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R0, -1),
|
2014-08-26 02:27:02 +07:00
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, -1 } }
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"INT: shifts by register",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_MOV64_IMM(R0, -1234),
|
|
|
|
BPF_MOV64_IMM(R1, 1),
|
|
|
|
BPF_ALU32_REG(BPF_RSH, R0, R1),
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R0, 0x7ffffd97, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV64_IMM(R2, 1),
|
|
|
|
BPF_ALU64_REG(BPF_LSH, R0, R2),
|
|
|
|
BPF_MOV32_IMM(R4, -1234),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R0, R4, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU64_IMM(BPF_AND, R4, 63),
|
|
|
|
BPF_ALU64_REG(BPF_LSH, R0, R4), /* R0 <= 46 */
|
|
|
|
BPF_MOV64_IMM(R3, 47),
|
|
|
|
BPF_ALU64_REG(BPF_ARSH, R0, R3),
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R0, -617, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV64_IMM(R2, 1),
|
|
|
|
BPF_ALU64_REG(BPF_LSH, R4, R2), /* R4 = 46 << 1 */
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R4, 92, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV64_IMM(R4, 4),
|
|
|
|
BPF_ALU64_REG(BPF_LSH, R4, R4), /* R4 = 4 << 4 */
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R4, 64, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV64_IMM(R4, 5),
|
|
|
|
BPF_ALU32_REG(BPF_LSH, R4, R4), /* R4 = 5 << 5 */
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R4, 160, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV64_IMM(R0, -1),
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
INTERNAL,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ },
|
|
|
|
{ { 0, -1 } }
|
|
|
|
},
|
2014-05-09 04:10:52 +07:00
|
|
|
{
|
|
|
|
"INT: DIV + ABS",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns_int = {
|
2014-05-09 04:10:52 +07:00
|
|
|
BPF_ALU64_REG(BPF_MOV, R6, R1),
|
|
|
|
BPF_LD_ABS(BPF_B, 3),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R2, 2),
|
|
|
|
BPF_ALU32_REG(BPF_DIV, R0, R2),
|
|
|
|
BPF_ALU64_REG(BPF_MOV, R8, R0),
|
|
|
|
BPF_LD_ABS(BPF_B, 4),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R8, R0),
|
|
|
|
BPF_LD_IND(BPF_B, R8, -70),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
INTERNAL,
|
2014-05-09 04:10:52 +07:00
|
|
|
{ 10, 20, 30, 40, 50 },
|
|
|
|
{ { 4, 0 }, { 5, 10 } }
|
|
|
|
},
|
2014-05-09 04:10:53 +07:00
|
|
|
{
|
2018-01-27 05:33:48 +07:00
|
|
|
/* This one doesn't go through verifier, but is just raw insn
|
|
|
|
* as opposed to cBPF tests from here. Thus div by 0 tests are
|
|
|
|
* done in test_verifier in BPF kselftests.
|
|
|
|
*/
|
|
|
|
"INT: DIV by -1",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns_int = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_ALU64_REG(BPF_MOV, R6, R1),
|
2018-01-27 05:33:48 +07:00
|
|
|
BPF_ALU64_IMM(BPF_MOV, R7, -1),
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_LD_ABS(BPF_B, 3),
|
|
|
|
BPF_ALU32_REG(BPF_DIV, R0, R7),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
INTERNAL,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ 10, 20, 30, 40, 50 },
|
|
|
|
{ { 3, 0 }, { 4, 0 } }
|
|
|
|
},
|
2014-05-09 04:10:52 +07:00
|
|
|
{
|
|
|
|
"check: missing ret",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-05-09 04:10:52 +07:00
|
|
|
BPF_STMT(BPF_LD | BPF_IMM, 1),
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC | FLAG_NO_DATA | FLAG_EXPECTED_FAIL,
|
2014-05-09 04:10:52 +07:00
|
|
|
{ },
|
bpf: fix selftests/bpf test_kmod.sh failure when CONFIG_BPF_JIT_ALWAYS_ON=y
With CONFIG_BPF_JIT_ALWAYS_ON is defined in the config file,
tools/testing/selftests/bpf/test_kmod.sh failed like below:
[root@localhost bpf]# ./test_kmod.sh
sysctl: setting key "net.core.bpf_jit_enable": Invalid argument
[ JIT enabled:0 hardened:0 ]
[ 132.175681] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 132.458834] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:0 ]
[ 133.456025] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 133.730935] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:1 ]
[ 134.769730] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 135.050864] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:2 ]
[ 136.442882] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 136.821810] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[root@localhost bpf]#
The test_kmod.sh load/remove test_bpf.ko multiple times with different
settings for sysctl net.core.bpf_jit_{enable,harden}. The failed test #297
of test_bpf.ko is designed such that JIT always fails.
Commit 290af86629b2 (bpf: introduce BPF_JIT_ALWAYS_ON config)
introduced the following tightening logic:
...
if (!bpf_prog_is_dev_bound(fp->aux)) {
fp = bpf_int_jit_compile(fp);
#ifdef CONFIG_BPF_JIT_ALWAYS_ON
if (!fp->jited) {
*err = -ENOTSUPP;
return fp;
}
#endif
...
With this logic, Test #297 always gets return value -ENOTSUPP
when CONFIG_BPF_JIT_ALWAYS_ON is defined, causing the test failure.
This patch fixed the failure by marking Test #297 as expected failure
when CONFIG_BPF_JIT_ALWAYS_ON is defined.
Fixes: 290af86629b2 (bpf: introduce BPF_JIT_ALWAYS_ON config)
Signed-off-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
2018-02-03 13:37:15 +07:00
|
|
|
{ },
|
|
|
|
.fill_helper = NULL,
|
|
|
|
.expected_errcode = -EINVAL,
|
2014-05-09 04:10:52 +07:00
|
|
|
},
|
2014-05-09 04:10:53 +07:00
|
|
|
{
|
|
|
|
"check: div_k_0",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_ALU | BPF_DIV | BPF_K, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 0)
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC | FLAG_NO_DATA | FLAG_EXPECTED_FAIL,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ },
|
bpf: fix selftests/bpf test_kmod.sh failure when CONFIG_BPF_JIT_ALWAYS_ON=y
With CONFIG_BPF_JIT_ALWAYS_ON is defined in the config file,
tools/testing/selftests/bpf/test_kmod.sh failed like below:
[root@localhost bpf]# ./test_kmod.sh
sysctl: setting key "net.core.bpf_jit_enable": Invalid argument
[ JIT enabled:0 hardened:0 ]
[ 132.175681] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 132.458834] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:0 ]
[ 133.456025] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 133.730935] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:1 ]
[ 134.769730] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 135.050864] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:2 ]
[ 136.442882] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 136.821810] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[root@localhost bpf]#
The test_kmod.sh load/remove test_bpf.ko multiple times with different
settings for sysctl net.core.bpf_jit_{enable,harden}. The failed test #297
of test_bpf.ko is designed such that JIT always fails.
Commit 290af86629b2 (bpf: introduce BPF_JIT_ALWAYS_ON config)
introduced the following tightening logic:
...
if (!bpf_prog_is_dev_bound(fp->aux)) {
fp = bpf_int_jit_compile(fp);
#ifdef CONFIG_BPF_JIT_ALWAYS_ON
if (!fp->jited) {
*err = -ENOTSUPP;
return fp;
}
#endif
...
With this logic, Test #297 always gets return value -ENOTSUPP
when CONFIG_BPF_JIT_ALWAYS_ON is defined, causing the test failure.
This patch fixed the failure by marking Test #297 as expected failure
when CONFIG_BPF_JIT_ALWAYS_ON is defined.
Fixes: 290af86629b2 (bpf: introduce BPF_JIT_ALWAYS_ON config)
Signed-off-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
2018-02-03 13:37:15 +07:00
|
|
|
{ },
|
|
|
|
.fill_helper = NULL,
|
|
|
|
.expected_errcode = -EINVAL,
|
2014-05-09 04:10:53 +07:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"check: unknown insn",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-05-09 04:10:53 +07:00
|
|
|
/* seccomp insn, rejected in socket filter */
|
|
|
|
BPF_STMT(BPF_LDX | BPF_W | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 0)
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC | FLAG_EXPECTED_FAIL,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ },
|
bpf: fix selftests/bpf test_kmod.sh failure when CONFIG_BPF_JIT_ALWAYS_ON=y
With CONFIG_BPF_JIT_ALWAYS_ON is defined in the config file,
tools/testing/selftests/bpf/test_kmod.sh failed like below:
[root@localhost bpf]# ./test_kmod.sh
sysctl: setting key "net.core.bpf_jit_enable": Invalid argument
[ JIT enabled:0 hardened:0 ]
[ 132.175681] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 132.458834] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:0 ]
[ 133.456025] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 133.730935] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:1 ]
[ 134.769730] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 135.050864] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:2 ]
[ 136.442882] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 136.821810] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[root@localhost bpf]#
The test_kmod.sh load/remove test_bpf.ko multiple times with different
settings for sysctl net.core.bpf_jit_{enable,harden}. The failed test #297
of test_bpf.ko is designed such that JIT always fails.
Commit 290af86629b2 (bpf: introduce BPF_JIT_ALWAYS_ON config)
introduced the following tightening logic:
...
if (!bpf_prog_is_dev_bound(fp->aux)) {
fp = bpf_int_jit_compile(fp);
#ifdef CONFIG_BPF_JIT_ALWAYS_ON
if (!fp->jited) {
*err = -ENOTSUPP;
return fp;
}
#endif
...
With this logic, Test #297 always gets return value -ENOTSUPP
when CONFIG_BPF_JIT_ALWAYS_ON is defined, causing the test failure.
This patch fixed the failure by marking Test #297 as expected failure
when CONFIG_BPF_JIT_ALWAYS_ON is defined.
Fixes: 290af86629b2 (bpf: introduce BPF_JIT_ALWAYS_ON config)
Signed-off-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
2018-02-03 13:37:15 +07:00
|
|
|
{ },
|
|
|
|
.fill_helper = NULL,
|
|
|
|
.expected_errcode = -EINVAL,
|
2014-05-09 04:10:53 +07:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"check: out of range spill/fill",
|
2014-05-23 00:16:46 +07:00
|
|
|
.u.insns = {
|
2014-05-09 04:10:53 +07:00
|
|
|
BPF_STMT(BPF_STX, 16),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 0)
|
|
|
|
},
|
2014-05-23 23:44:00 +07:00
|
|
|
CLASSIC | FLAG_NO_DATA | FLAG_EXPECTED_FAIL,
|
2014-05-09 04:10:53 +07:00
|
|
|
{ },
|
bpf: fix selftests/bpf test_kmod.sh failure when CONFIG_BPF_JIT_ALWAYS_ON=y
With CONFIG_BPF_JIT_ALWAYS_ON is defined in the config file,
tools/testing/selftests/bpf/test_kmod.sh failed like below:
[root@localhost bpf]# ./test_kmod.sh
sysctl: setting key "net.core.bpf_jit_enable": Invalid argument
[ JIT enabled:0 hardened:0 ]
[ 132.175681] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 132.458834] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:0 ]
[ 133.456025] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 133.730935] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:1 ]
[ 134.769730] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 135.050864] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:2 ]
[ 136.442882] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 136.821810] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[root@localhost bpf]#
The test_kmod.sh load/remove test_bpf.ko multiple times with different
settings for sysctl net.core.bpf_jit_{enable,harden}. The failed test #297
of test_bpf.ko is designed such that JIT always fails.
Commit 290af86629b2 (bpf: introduce BPF_JIT_ALWAYS_ON config)
introduced the following tightening logic:
...
if (!bpf_prog_is_dev_bound(fp->aux)) {
fp = bpf_int_jit_compile(fp);
#ifdef CONFIG_BPF_JIT_ALWAYS_ON
if (!fp->jited) {
*err = -ENOTSUPP;
return fp;
}
#endif
...
With this logic, Test #297 always gets return value -ENOTSUPP
when CONFIG_BPF_JIT_ALWAYS_ON is defined, causing the test failure.
This patch fixed the failure by marking Test #297 as expected failure
when CONFIG_BPF_JIT_ALWAYS_ON is defined.
Fixes: 290af86629b2 (bpf: introduce BPF_JIT_ALWAYS_ON config)
Signed-off-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
2018-02-03 13:37:15 +07:00
|
|
|
{ },
|
|
|
|
.fill_helper = NULL,
|
|
|
|
.expected_errcode = -EINVAL,
|
2014-05-09 04:10:53 +07:00
|
|
|
},
|
2014-05-23 23:44:01 +07:00
|
|
|
{
|
|
|
|
"JUMPS + HOLES",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JGE, 0, 13, 15),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JEQ, 0x90c2894d, 3, 4),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JEQ, 0x90c2894d, 1, 2),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JGE, 0, 14, 15),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JGE, 0, 13, 14),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JEQ, 0x2ac28349, 2, 3),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JEQ, 0x2ac28349, 1, 2),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JGE, 0, 14, 15),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JGE, 0, 13, 14),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JEQ, 0x90d2ff41, 2, 3),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JEQ, 0x90d2ff41, 1, 2),
|
|
|
|
BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0),
|
|
|
|
},
|
|
|
|
CLASSIC,
|
2014-05-27 01:17:35 +07:00
|
|
|
{ 0x00, 0x1b, 0x21, 0x3c, 0x9d, 0xf8,
|
|
|
|
0x90, 0xe2, 0xba, 0x0a, 0x56, 0xb4,
|
|
|
|
0x08, 0x00,
|
|
|
|
0x45, 0x00, 0x00, 0x28, 0x00, 0x00,
|
|
|
|
0x20, 0x00, 0x40, 0x11, 0x00, 0x00, /* IP header */
|
|
|
|
0xc0, 0xa8, 0x33, 0x01,
|
|
|
|
0xc0, 0xa8, 0x33, 0x02,
|
|
|
|
0xbb, 0xb6,
|
|
|
|
0xa9, 0xfa,
|
|
|
|
0x00, 0x14, 0x00, 0x00,
|
|
|
|
0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
|
|
|
|
0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
|
|
|
|
0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
|
|
|
|
0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
|
|
|
|
0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
|
|
|
|
0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
|
|
|
|
0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
|
|
|
|
0xcc, 0xcc, 0xcc, 0xcc },
|
2014-05-23 23:44:01 +07:00
|
|
|
{ { 88, 0x001b } }
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"check: RET X",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_RET | BPF_X, 0),
|
|
|
|
},
|
|
|
|
CLASSIC | FLAG_NO_DATA | FLAG_EXPECTED_FAIL,
|
|
|
|
{ },
|
|
|
|
{ },
|
bpf: fix selftests/bpf test_kmod.sh failure when CONFIG_BPF_JIT_ALWAYS_ON=y
With CONFIG_BPF_JIT_ALWAYS_ON is defined in the config file,
tools/testing/selftests/bpf/test_kmod.sh failed like below:
[root@localhost bpf]# ./test_kmod.sh
sysctl: setting key "net.core.bpf_jit_enable": Invalid argument
[ JIT enabled:0 hardened:0 ]
[ 132.175681] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 132.458834] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:0 ]
[ 133.456025] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 133.730935] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:1 ]
[ 134.769730] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 135.050864] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:2 ]
[ 136.442882] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 136.821810] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[root@localhost bpf]#
The test_kmod.sh load/remove test_bpf.ko multiple times with different
settings for sysctl net.core.bpf_jit_{enable,harden}. The failed test #297
of test_bpf.ko is designed such that JIT always fails.
Commit 290af86629b2 (bpf: introduce BPF_JIT_ALWAYS_ON config)
introduced the following tightening logic:
...
if (!bpf_prog_is_dev_bound(fp->aux)) {
fp = bpf_int_jit_compile(fp);
#ifdef CONFIG_BPF_JIT_ALWAYS_ON
if (!fp->jited) {
*err = -ENOTSUPP;
return fp;
}
#endif
...
With this logic, Test #297 always gets return value -ENOTSUPP
when CONFIG_BPF_JIT_ALWAYS_ON is defined, causing the test failure.
This patch fixed the failure by marking Test #297 as expected failure
when CONFIG_BPF_JIT_ALWAYS_ON is defined.
Fixes: 290af86629b2 (bpf: introduce BPF_JIT_ALWAYS_ON config)
Signed-off-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
2018-02-03 13:37:15 +07:00
|
|
|
.fill_helper = NULL,
|
|
|
|
.expected_errcode = -EINVAL,
|
2014-05-23 23:44:01 +07:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"check: LDX + RET X",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 42),
|
|
|
|
BPF_STMT(BPF_RET | BPF_X, 0),
|
|
|
|
},
|
|
|
|
CLASSIC | FLAG_NO_DATA | FLAG_EXPECTED_FAIL,
|
|
|
|
{ },
|
|
|
|
{ },
|
bpf: fix selftests/bpf test_kmod.sh failure when CONFIG_BPF_JIT_ALWAYS_ON=y
With CONFIG_BPF_JIT_ALWAYS_ON is defined in the config file,
tools/testing/selftests/bpf/test_kmod.sh failed like below:
[root@localhost bpf]# ./test_kmod.sh
sysctl: setting key "net.core.bpf_jit_enable": Invalid argument
[ JIT enabled:0 hardened:0 ]
[ 132.175681] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 132.458834] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:0 ]
[ 133.456025] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 133.730935] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:1 ]
[ 134.769730] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 135.050864] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:2 ]
[ 136.442882] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 136.821810] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[root@localhost bpf]#
The test_kmod.sh load/remove test_bpf.ko multiple times with different
settings for sysctl net.core.bpf_jit_{enable,harden}. The failed test #297
of test_bpf.ko is designed such that JIT always fails.
Commit 290af86629b2 (bpf: introduce BPF_JIT_ALWAYS_ON config)
introduced the following tightening logic:
...
if (!bpf_prog_is_dev_bound(fp->aux)) {
fp = bpf_int_jit_compile(fp);
#ifdef CONFIG_BPF_JIT_ALWAYS_ON
if (!fp->jited) {
*err = -ENOTSUPP;
return fp;
}
#endif
...
With this logic, Test #297 always gets return value -ENOTSUPP
when CONFIG_BPF_JIT_ALWAYS_ON is defined, causing the test failure.
This patch fixed the failure by marking Test #297 as expected failure
when CONFIG_BPF_JIT_ALWAYS_ON is defined.
Fixes: 290af86629b2 (bpf: introduce BPF_JIT_ALWAYS_ON config)
Signed-off-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
2018-02-03 13:37:15 +07:00
|
|
|
.fill_helper = NULL,
|
|
|
|
.expected_errcode = -EINVAL,
|
2014-05-23 23:44:01 +07:00
|
|
|
},
|
2014-05-27 01:17:34 +07:00
|
|
|
{ /* Mainly checking JIT here. */
|
2014-05-29 15:22:48 +07:00
|
|
|
"M[]: alt STX + LDX",
|
2014-05-27 01:17:34 +07:00
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 100),
|
|
|
|
BPF_STMT(BPF_STX, 0),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_MEM, 0),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TXA, 0),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_K, 1),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TAX, 0),
|
|
|
|
BPF_STMT(BPF_STX, 1),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_MEM, 1),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TXA, 0),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_K, 1),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TAX, 0),
|
|
|
|
BPF_STMT(BPF_STX, 2),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_MEM, 2),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TXA, 0),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_K, 1),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TAX, 0),
|
|
|
|
BPF_STMT(BPF_STX, 3),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_MEM, 3),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TXA, 0),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_K, 1),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TAX, 0),
|
|
|
|
BPF_STMT(BPF_STX, 4),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_MEM, 4),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TXA, 0),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_K, 1),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TAX, 0),
|
|
|
|
BPF_STMT(BPF_STX, 5),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_MEM, 5),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TXA, 0),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_K, 1),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TAX, 0),
|
|
|
|
BPF_STMT(BPF_STX, 6),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_MEM, 6),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TXA, 0),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_K, 1),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TAX, 0),
|
|
|
|
BPF_STMT(BPF_STX, 7),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_MEM, 7),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TXA, 0),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_K, 1),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TAX, 0),
|
|
|
|
BPF_STMT(BPF_STX, 8),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_MEM, 8),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TXA, 0),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_K, 1),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TAX, 0),
|
|
|
|
BPF_STMT(BPF_STX, 9),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_MEM, 9),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TXA, 0),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_K, 1),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TAX, 0),
|
|
|
|
BPF_STMT(BPF_STX, 10),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_MEM, 10),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TXA, 0),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_K, 1),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TAX, 0),
|
|
|
|
BPF_STMT(BPF_STX, 11),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_MEM, 11),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TXA, 0),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_K, 1),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TAX, 0),
|
|
|
|
BPF_STMT(BPF_STX, 12),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_MEM, 12),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TXA, 0),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_K, 1),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TAX, 0),
|
|
|
|
BPF_STMT(BPF_STX, 13),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_MEM, 13),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TXA, 0),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_K, 1),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TAX, 0),
|
|
|
|
BPF_STMT(BPF_STX, 14),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_MEM, 14),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TXA, 0),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_K, 1),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TAX, 0),
|
|
|
|
BPF_STMT(BPF_STX, 15),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_MEM, 15),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TXA, 0),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_K, 1),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TAX, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0),
|
|
|
|
},
|
|
|
|
CLASSIC | FLAG_NO_DATA,
|
|
|
|
{ },
|
|
|
|
{ { 0, 116 } },
|
|
|
|
},
|
2014-05-29 15:22:48 +07:00
|
|
|
{ /* Mainly checking JIT here. */
|
|
|
|
"M[]: full STX + full LDX",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 0xbadfeedb),
|
|
|
|
BPF_STMT(BPF_STX, 0),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 0xecabedae),
|
|
|
|
BPF_STMT(BPF_STX, 1),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 0xafccfeaf),
|
|
|
|
BPF_STMT(BPF_STX, 2),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 0xbffdcedc),
|
|
|
|
BPF_STMT(BPF_STX, 3),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 0xfbbbdccb),
|
|
|
|
BPF_STMT(BPF_STX, 4),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 0xfbabcbda),
|
|
|
|
BPF_STMT(BPF_STX, 5),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 0xaedecbdb),
|
|
|
|
BPF_STMT(BPF_STX, 6),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 0xadebbade),
|
|
|
|
BPF_STMT(BPF_STX, 7),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 0xfcfcfaec),
|
|
|
|
BPF_STMT(BPF_STX, 8),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 0xbcdddbdc),
|
|
|
|
BPF_STMT(BPF_STX, 9),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 0xfeefdfac),
|
|
|
|
BPF_STMT(BPF_STX, 10),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 0xcddcdeea),
|
|
|
|
BPF_STMT(BPF_STX, 11),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 0xaccfaebb),
|
|
|
|
BPF_STMT(BPF_STX, 12),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 0xbdcccdcf),
|
|
|
|
BPF_STMT(BPF_STX, 13),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 0xaaedecde),
|
|
|
|
BPF_STMT(BPF_STX, 14),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 0xfaeacdad),
|
|
|
|
BPF_STMT(BPF_STX, 15),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_MEM, 0),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TXA, 0),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_MEM, 1),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_MEM, 2),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_MEM, 3),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_MEM, 4),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_MEM, 5),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_MEM, 6),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_MEM, 7),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_MEM, 8),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_MEM, 9),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_MEM, 10),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_MEM, 11),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_MEM, 12),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_MEM, 13),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_MEM, 14),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_LDX | BPF_MEM, 15),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0),
|
|
|
|
},
|
|
|
|
CLASSIC | FLAG_NO_DATA,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x2a5a5e5 } },
|
|
|
|
},
|
2014-05-29 15:22:49 +07:00
|
|
|
{
|
|
|
|
"check: SKF_AD_MAX",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
|
|
|
SKF_AD_OFF + SKF_AD_MAX),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0),
|
|
|
|
},
|
|
|
|
CLASSIC | FLAG_NO_DATA | FLAG_EXPECTED_FAIL,
|
|
|
|
{ },
|
|
|
|
{ },
|
bpf: fix selftests/bpf test_kmod.sh failure when CONFIG_BPF_JIT_ALWAYS_ON=y
With CONFIG_BPF_JIT_ALWAYS_ON is defined in the config file,
tools/testing/selftests/bpf/test_kmod.sh failed like below:
[root@localhost bpf]# ./test_kmod.sh
sysctl: setting key "net.core.bpf_jit_enable": Invalid argument
[ JIT enabled:0 hardened:0 ]
[ 132.175681] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 132.458834] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:0 ]
[ 133.456025] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 133.730935] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:1 ]
[ 134.769730] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 135.050864] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:2 ]
[ 136.442882] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 136.821810] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[root@localhost bpf]#
The test_kmod.sh load/remove test_bpf.ko multiple times with different
settings for sysctl net.core.bpf_jit_{enable,harden}. The failed test #297
of test_bpf.ko is designed such that JIT always fails.
Commit 290af86629b2 (bpf: introduce BPF_JIT_ALWAYS_ON config)
introduced the following tightening logic:
...
if (!bpf_prog_is_dev_bound(fp->aux)) {
fp = bpf_int_jit_compile(fp);
#ifdef CONFIG_BPF_JIT_ALWAYS_ON
if (!fp->jited) {
*err = -ENOTSUPP;
return fp;
}
#endif
...
With this logic, Test #297 always gets return value -ENOTSUPP
when CONFIG_BPF_JIT_ALWAYS_ON is defined, causing the test failure.
This patch fixed the failure by marking Test #297 as expected failure
when CONFIG_BPF_JIT_ALWAYS_ON is defined.
Fixes: 290af86629b2 (bpf: introduce BPF_JIT_ALWAYS_ON config)
Signed-off-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
2018-02-03 13:37:15 +07:00
|
|
|
.fill_helper = NULL,
|
|
|
|
.expected_errcode = -EINVAL,
|
2014-05-29 15:22:49 +07:00
|
|
|
},
|
|
|
|
{ /* Passes checker but fails during runtime. */
|
|
|
|
"LD [SKF_AD_OFF-1]",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
|
|
|
SKF_AD_OFF - 1),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 1),
|
|
|
|
},
|
|
|
|
CLASSIC,
|
|
|
|
{ },
|
|
|
|
{ { 1, 0 } },
|
|
|
|
},
|
net: filter: add "load 64-bit immediate" eBPF instruction
add BPF_LD_IMM64 instruction to load 64-bit immediate value into a register.
All previous instructions were 8-byte. This is first 16-byte instruction.
Two consecutive 'struct bpf_insn' blocks are interpreted as single instruction:
insn[0].code = BPF_LD | BPF_DW | BPF_IMM
insn[0].dst_reg = destination register
insn[0].imm = lower 32-bit
insn[1].code = 0
insn[1].imm = upper 32-bit
All unused fields must be zero.
Classic BPF has similar instruction: BPF_LD | BPF_W | BPF_IMM
which loads 32-bit immediate value into a register.
x64 JITs it as single 'movabsq %rax, imm64'
arm64 may JIT as sequence of four 'movk x0, #imm16, lsl #shift' insn
Note that old eBPF programs are binary compatible with new interpreter.
It helps eBPF programs load 64-bit constant into a register with one
instruction instead of using two registers and 4 instructions:
BPF_MOV32_IMM(R1, imm32)
BPF_ALU64_IMM(BPF_LSH, R1, 32)
BPF_MOV32_IMM(R2, imm32)
BPF_ALU64_REG(BPF_OR, R1, R2)
User space generated programs will use this instruction to load constants only.
To tell kernel that user space needs a pointer the _pseudo_ variant of
this instruction may be added later, which will use extra bits of encoding
to indicate what type of pointer user space is asking kernel to provide.
For example 'off' or 'src_reg' fields can be used for such purpose.
src_reg = 1 could mean that user space is asking kernel to validate and
load in-kernel map pointer.
src_reg = 2 could mean that user space needs readonly data section pointer
src_reg = 3 could mean that user space needs a pointer to per-cpu local data
All such future pseudo instructions will not be carrying the actual pointer
as part of the instruction, but rather will be treated as a request to kernel
to provide one. The kernel will verify the request_for_a_pointer, then
will drop _pseudo_ marking and will store actual internal pointer inside
the instruction, so the end result is the interpreter and JITs never
see pseudo BPF_LD_IMM64 insns and only operate on generic BPF_LD_IMM64 that
loads 64-bit immediate into a register. User space never operates on direct
pointers and verifier can easily recognize request_for_pointer vs other
instructions.
Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-09-05 12:17:17 +07:00
|
|
|
{
|
|
|
|
"load 64-bit immediate",
|
|
|
|
.u.insns_int = {
|
2014-09-20 03:53:51 +07:00
|
|
|
BPF_LD_IMM64(R1, 0x567800001234LL),
|
net: filter: add "load 64-bit immediate" eBPF instruction
add BPF_LD_IMM64 instruction to load 64-bit immediate value into a register.
All previous instructions were 8-byte. This is first 16-byte instruction.
Two consecutive 'struct bpf_insn' blocks are interpreted as single instruction:
insn[0].code = BPF_LD | BPF_DW | BPF_IMM
insn[0].dst_reg = destination register
insn[0].imm = lower 32-bit
insn[1].code = 0
insn[1].imm = upper 32-bit
All unused fields must be zero.
Classic BPF has similar instruction: BPF_LD | BPF_W | BPF_IMM
which loads 32-bit immediate value into a register.
x64 JITs it as single 'movabsq %rax, imm64'
arm64 may JIT as sequence of four 'movk x0, #imm16, lsl #shift' insn
Note that old eBPF programs are binary compatible with new interpreter.
It helps eBPF programs load 64-bit constant into a register with one
instruction instead of using two registers and 4 instructions:
BPF_MOV32_IMM(R1, imm32)
BPF_ALU64_IMM(BPF_LSH, R1, 32)
BPF_MOV32_IMM(R2, imm32)
BPF_ALU64_REG(BPF_OR, R1, R2)
User space generated programs will use this instruction to load constants only.
To tell kernel that user space needs a pointer the _pseudo_ variant of
this instruction may be added later, which will use extra bits of encoding
to indicate what type of pointer user space is asking kernel to provide.
For example 'off' or 'src_reg' fields can be used for such purpose.
src_reg = 1 could mean that user space is asking kernel to validate and
load in-kernel map pointer.
src_reg = 2 could mean that user space needs readonly data section pointer
src_reg = 3 could mean that user space needs a pointer to per-cpu local data
All such future pseudo instructions will not be carrying the actual pointer
as part of the instruction, but rather will be treated as a request to kernel
to provide one. The kernel will verify the request_for_a_pointer, then
will drop _pseudo_ marking and will store actual internal pointer inside
the instruction, so the end result is the interpreter and JITs never
see pseudo BPF_LD_IMM64 insns and only operate on generic BPF_LD_IMM64 that
loads 64-bit immediate into a register. User space never operates on direct
pointers and verifier can easily recognize request_for_pointer vs other
instructions.
Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-09-05 12:17:17 +07:00
|
|
|
BPF_MOV64_REG(R2, R1),
|
|
|
|
BPF_MOV64_REG(R3, R2),
|
|
|
|
BPF_ALU64_IMM(BPF_RSH, R2, 32),
|
|
|
|
BPF_ALU64_IMM(BPF_LSH, R3, 32),
|
|
|
|
BPF_ALU64_IMM(BPF_RSH, R3, 32),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R2, 0x5678, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R3, 0x1234, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
2015-05-09 15:14:30 +07:00
|
|
|
BPF_LD_IMM64(R0, 0x1ffffffffLL),
|
|
|
|
BPF_ALU64_IMM(BPF_RSH, R0, 32), /* R0 = 1 */
|
net: filter: add "load 64-bit immediate" eBPF instruction
add BPF_LD_IMM64 instruction to load 64-bit immediate value into a register.
All previous instructions were 8-byte. This is first 16-byte instruction.
Two consecutive 'struct bpf_insn' blocks are interpreted as single instruction:
insn[0].code = BPF_LD | BPF_DW | BPF_IMM
insn[0].dst_reg = destination register
insn[0].imm = lower 32-bit
insn[1].code = 0
insn[1].imm = upper 32-bit
All unused fields must be zero.
Classic BPF has similar instruction: BPF_LD | BPF_W | BPF_IMM
which loads 32-bit immediate value into a register.
x64 JITs it as single 'movabsq %rax, imm64'
arm64 may JIT as sequence of four 'movk x0, #imm16, lsl #shift' insn
Note that old eBPF programs are binary compatible with new interpreter.
It helps eBPF programs load 64-bit constant into a register with one
instruction instead of using two registers and 4 instructions:
BPF_MOV32_IMM(R1, imm32)
BPF_ALU64_IMM(BPF_LSH, R1, 32)
BPF_MOV32_IMM(R2, imm32)
BPF_ALU64_REG(BPF_OR, R1, R2)
User space generated programs will use this instruction to load constants only.
To tell kernel that user space needs a pointer the _pseudo_ variant of
this instruction may be added later, which will use extra bits of encoding
to indicate what type of pointer user space is asking kernel to provide.
For example 'off' or 'src_reg' fields can be used for such purpose.
src_reg = 1 could mean that user space is asking kernel to validate and
load in-kernel map pointer.
src_reg = 2 could mean that user space needs readonly data section pointer
src_reg = 3 could mean that user space needs a pointer to per-cpu local data
All such future pseudo instructions will not be carrying the actual pointer
as part of the instruction, but rather will be treated as a request to kernel
to provide one. The kernel will verify the request_for_a_pointer, then
will drop _pseudo_ marking and will store actual internal pointer inside
the instruction, so the end result is the interpreter and JITs never
see pseudo BPF_LD_IMM64 insns and only operate on generic BPF_LD_IMM64 that
loads 64-bit immediate into a register. User space never operates on direct
pointers and verifier can easily recognize request_for_pointer vs other
instructions.
Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-09-05 12:17:17 +07:00
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } }
|
|
|
|
},
|
2014-10-29 05:11:43 +07:00
|
|
|
{
|
|
|
|
"nmap reduced",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_MOV64_REG(R6, R1),
|
|
|
|
BPF_LD_ABS(BPF_H, 12),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, R0, 0x806, 28),
|
|
|
|
BPF_LD_ABS(BPF_H, 12),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, R0, 0x806, 26),
|
|
|
|
BPF_MOV32_IMM(R0, 18),
|
|
|
|
BPF_STX_MEM(BPF_W, R10, R0, -64),
|
|
|
|
BPF_LDX_MEM(BPF_W, R7, R10, -64),
|
|
|
|
BPF_LD_IND(BPF_W, R7, 14),
|
|
|
|
BPF_STX_MEM(BPF_W, R10, R0, -60),
|
|
|
|
BPF_MOV32_IMM(R0, 280971478),
|
|
|
|
BPF_STX_MEM(BPF_W, R10, R0, -56),
|
|
|
|
BPF_LDX_MEM(BPF_W, R7, R10, -56),
|
|
|
|
BPF_LDX_MEM(BPF_W, R0, R10, -60),
|
|
|
|
BPF_ALU32_REG(BPF_SUB, R0, R7),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, R0, 0, 15),
|
|
|
|
BPF_LD_ABS(BPF_H, 12),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, R0, 0x806, 13),
|
|
|
|
BPF_MOV32_IMM(R0, 22),
|
|
|
|
BPF_STX_MEM(BPF_W, R10, R0, -56),
|
|
|
|
BPF_LDX_MEM(BPF_W, R7, R10, -56),
|
|
|
|
BPF_LD_IND(BPF_H, R7, 14),
|
|
|
|
BPF_STX_MEM(BPF_W, R10, R0, -52),
|
|
|
|
BPF_MOV32_IMM(R0, 17366),
|
|
|
|
BPF_STX_MEM(BPF_W, R10, R0, -48),
|
|
|
|
BPF_LDX_MEM(BPF_W, R7, R10, -48),
|
|
|
|
BPF_LDX_MEM(BPF_W, R0, R10, -52),
|
|
|
|
BPF_ALU32_REG(BPF_SUB, R0, R7),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, R0, 0, 2),
|
|
|
|
BPF_MOV32_IMM(R0, 256),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV32_IMM(R0, 0),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0x06, 0, 0,
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
0x10, 0xbf, 0x48, 0xd6, 0x43, 0xd6},
|
2017-05-31 03:31:32 +07:00
|
|
|
{ { 38, 256 } },
|
|
|
|
.stack_depth = 64,
|
2014-10-29 05:11:43 +07:00
|
|
|
},
|
2015-05-12 12:22:44 +07:00
|
|
|
/* BPF_ALU | BPF_MOV | BPF_X */
|
|
|
|
{
|
|
|
|
"ALU_MOV_X: dst = 2",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 2),
|
|
|
|
BPF_ALU32_REG(BPF_MOV, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 2 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_MOV_X: dst = 4294967295",
|
|
|
|
.u.insns_int = {
|
2015-05-14 10:40:39 +07:00
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 4294967295U),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_ALU32_REG(BPF_MOV, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
2015-05-14 10:40:39 +07:00
|
|
|
{ { 0, 4294967295U } },
|
2015-05-12 12:22:44 +07:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_MOV_X: dst = 2",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 2),
|
|
|
|
BPF_ALU64_REG(BPF_MOV, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 2 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_MOV_X: dst = 4294967295",
|
|
|
|
.u.insns_int = {
|
2015-05-14 10:40:39 +07:00
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 4294967295U),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_ALU64_REG(BPF_MOV, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
2015-05-14 10:40:39 +07:00
|
|
|
{ { 0, 4294967295U } },
|
2015-05-12 12:22:44 +07:00
|
|
|
},
|
|
|
|
/* BPF_ALU | BPF_MOV | BPF_K */
|
|
|
|
{
|
|
|
|
"ALU_MOV_K: dst = 2",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 2 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_MOV_K: dst = 4294967295",
|
|
|
|
.u.insns_int = {
|
2015-05-14 10:40:39 +07:00
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 4294967295U),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
2015-05-14 10:40:39 +07:00
|
|
|
{ { 0, 4294967295U } },
|
2015-05-12 12:22:44 +07:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_MOV_K: 0x0000ffffffff0000 = 0x00000000ffffffff",
|
|
|
|
.u.insns_int = {
|
2015-05-14 10:40:39 +07:00
|
|
|
BPF_LD_IMM64(R2, 0x0000ffffffff0000LL),
|
|
|
|
BPF_LD_IMM64(R3, 0x00000000ffffffffLL),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_ALU32_IMM(BPF_MOV, R2, 0xffffffff),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
|
|
|
|
BPF_MOV32_IMM(R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV32_IMM(R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_MOV_K: dst = 2",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 2 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_MOV_K: dst = 2147483647",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R0, 2147483647),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 2147483647 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_OR_K: dst = 0x0",
|
|
|
|
.u.insns_int = {
|
2015-05-14 10:40:39 +07:00
|
|
|
BPF_LD_IMM64(R2, 0x0000ffffffff0000LL),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_LD_IMM64(R3, 0x0),
|
|
|
|
BPF_ALU64_IMM(BPF_MOV, R2, 0x0),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
|
|
|
|
BPF_MOV32_IMM(R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV32_IMM(R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_MOV_K: dst = -1",
|
|
|
|
.u.insns_int = {
|
2015-05-14 10:40:39 +07:00
|
|
|
BPF_LD_IMM64(R2, 0x0000ffffffff0000LL),
|
|
|
|
BPF_LD_IMM64(R3, 0xffffffffffffffffLL),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_ALU64_IMM(BPF_MOV, R2, 0xffffffff),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
|
|
|
|
BPF_MOV32_IMM(R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV32_IMM(R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x1 } },
|
|
|
|
},
|
|
|
|
/* BPF_ALU | BPF_ADD | BPF_X */
|
|
|
|
{
|
|
|
|
"ALU_ADD_X: 1 + 2 = 3",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 1),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 2),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 3 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_ADD_X: 1 + 4294967294 = 4294967295",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 1),
|
2015-05-14 10:40:39 +07:00
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 4294967294U),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_ALU32_REG(BPF_ADD, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
2015-05-14 10:40:39 +07:00
|
|
|
{ { 0, 4294967295U } },
|
2015-05-12 12:22:44 +07:00
|
|
|
},
|
2016-04-05 17:02:55 +07:00
|
|
|
{
|
|
|
|
"ALU_ADD_X: 2 + 4294967294 = 0",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 2),
|
|
|
|
BPF_LD_IMM64(R1, 4294967294U),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R0, R1),
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R0, 0, 2),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
2015-05-12 12:22:44 +07:00
|
|
|
{
|
|
|
|
"ALU64_ADD_X: 1 + 2 = 3",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 1),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 2),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 3 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_ADD_X: 1 + 4294967294 = 4294967295",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 1),
|
2015-05-14 10:40:39 +07:00
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 4294967294U),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
2015-05-14 10:40:39 +07:00
|
|
|
{ { 0, 4294967295U } },
|
2015-05-12 12:22:44 +07:00
|
|
|
},
|
2016-04-05 17:02:55 +07:00
|
|
|
{
|
|
|
|
"ALU64_ADD_X: 2 + 4294967294 = 4294967296",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 2),
|
|
|
|
BPF_LD_IMM64(R1, 4294967294U),
|
|
|
|
BPF_LD_IMM64(R2, 4294967296ULL),
|
|
|
|
BPF_ALU64_REG(BPF_ADD, R0, R1),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R0, R2, 2),
|
|
|
|
BPF_MOV32_IMM(R0, 0),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV32_IMM(R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
2015-05-12 12:22:44 +07:00
|
|
|
/* BPF_ALU | BPF_ADD | BPF_K */
|
|
|
|
{
|
|
|
|
"ALU_ADD_K: 1 + 2 = 3",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 1),
|
|
|
|
BPF_ALU32_IMM(BPF_ADD, R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 3 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_ADD_K: 3 + 0 = 3",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 3),
|
|
|
|
BPF_ALU32_IMM(BPF_ADD, R0, 0),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 3 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_ADD_K: 1 + 4294967294 = 4294967295",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 1),
|
2015-05-14 10:40:39 +07:00
|
|
|
BPF_ALU32_IMM(BPF_ADD, R0, 4294967294U),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
2015-05-14 10:40:39 +07:00
|
|
|
{ { 0, 4294967295U } },
|
2015-05-12 12:22:44 +07:00
|
|
|
},
|
2016-04-05 17:02:55 +07:00
|
|
|
{
|
|
|
|
"ALU_ADD_K: 4294967294 + 2 = 0",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 4294967294U),
|
|
|
|
BPF_ALU32_IMM(BPF_ADD, R0, 2),
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R0, 0, 2),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
2015-05-12 12:22:44 +07:00
|
|
|
{
|
|
|
|
"ALU_ADD_K: 0 + (-1) = 0x00000000ffffffff",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R2, 0x0),
|
|
|
|
BPF_LD_IMM64(R3, 0x00000000ffffffff),
|
|
|
|
BPF_ALU32_IMM(BPF_ADD, R2, 0xffffffff),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
|
|
|
|
BPF_MOV32_IMM(R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV32_IMM(R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x1 } },
|
|
|
|
},
|
2016-04-05 17:02:56 +07:00
|
|
|
{
|
|
|
|
"ALU_ADD_K: 0 + 0xffff = 0xffff",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R2, 0x0),
|
|
|
|
BPF_LD_IMM64(R3, 0xffff),
|
|
|
|
BPF_ALU32_IMM(BPF_ADD, R2, 0xffff),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
|
|
|
|
BPF_MOV32_IMM(R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV32_IMM(R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_ADD_K: 0 + 0x7fffffff = 0x7fffffff",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R2, 0x0),
|
|
|
|
BPF_LD_IMM64(R3, 0x7fffffff),
|
|
|
|
BPF_ALU32_IMM(BPF_ADD, R2, 0x7fffffff),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
|
|
|
|
BPF_MOV32_IMM(R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV32_IMM(R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_ADD_K: 0 + 0x80000000 = 0x80000000",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R2, 0x0),
|
|
|
|
BPF_LD_IMM64(R3, 0x80000000),
|
|
|
|
BPF_ALU32_IMM(BPF_ADD, R2, 0x80000000),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
|
|
|
|
BPF_MOV32_IMM(R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV32_IMM(R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_ADD_K: 0 + 0x80008000 = 0x80008000",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R2, 0x0),
|
|
|
|
BPF_LD_IMM64(R3, 0x80008000),
|
|
|
|
BPF_ALU32_IMM(BPF_ADD, R2, 0x80008000),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
|
|
|
|
BPF_MOV32_IMM(R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV32_IMM(R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x1 } },
|
|
|
|
},
|
2015-05-12 12:22:44 +07:00
|
|
|
{
|
|
|
|
"ALU64_ADD_K: 1 + 2 = 3",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 1),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 3 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_ADD_K: 3 + 0 = 3",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 3),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R0, 0),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 3 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_ADD_K: 1 + 2147483646 = 2147483647",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 1),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R0, 2147483646),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 2147483647 } },
|
|
|
|
},
|
2016-04-05 17:02:55 +07:00
|
|
|
{
|
|
|
|
"ALU64_ADD_K: 4294967294 + 2 = 4294967296",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 4294967294U),
|
|
|
|
BPF_LD_IMM64(R1, 4294967296ULL),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R0, 2),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R0, R1, 2),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
2015-05-12 12:22:44 +07:00
|
|
|
{
|
|
|
|
"ALU64_ADD_K: 2147483646 + -2147483647 = -1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 2147483646),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R0, -2147483647),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, -1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_ADD_K: 1 + 0 = 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R2, 0x1),
|
|
|
|
BPF_LD_IMM64(R3, 0x1),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R2, 0x0),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
|
|
|
|
BPF_MOV32_IMM(R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV32_IMM(R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_ADD_K: 0 + (-1) = 0xffffffffffffffff",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R2, 0x0),
|
2015-05-14 10:40:39 +07:00
|
|
|
BPF_LD_IMM64(R3, 0xffffffffffffffffLL),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_ALU64_IMM(BPF_ADD, R2, 0xffffffff),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
|
|
|
|
BPF_MOV32_IMM(R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV32_IMM(R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x1 } },
|
|
|
|
},
|
2016-04-05 17:02:56 +07:00
|
|
|
{
|
|
|
|
"ALU64_ADD_K: 0 + 0xffff = 0xffff",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R2, 0x0),
|
|
|
|
BPF_LD_IMM64(R3, 0xffff),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R2, 0xffff),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
|
|
|
|
BPF_MOV32_IMM(R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV32_IMM(R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_ADD_K: 0 + 0x7fffffff = 0x7fffffff",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R2, 0x0),
|
|
|
|
BPF_LD_IMM64(R3, 0x7fffffff),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R2, 0x7fffffff),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
|
|
|
|
BPF_MOV32_IMM(R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV32_IMM(R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_ADD_K: 0 + 0x80000000 = 0xffffffff80000000",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R2, 0x0),
|
|
|
|
BPF_LD_IMM64(R3, 0xffffffff80000000LL),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R2, 0x80000000),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
|
|
|
|
BPF_MOV32_IMM(R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV32_IMM(R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_ADD_K: 0 + 0x80008000 = 0xffffffff80008000",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R2, 0x0),
|
|
|
|
BPF_LD_IMM64(R3, 0xffffffff80008000LL),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R2, 0x80008000),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
|
|
|
|
BPF_MOV32_IMM(R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV32_IMM(R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x1 } },
|
|
|
|
},
|
2015-05-12 12:22:44 +07:00
|
|
|
/* BPF_ALU | BPF_SUB | BPF_X */
|
|
|
|
{
|
|
|
|
"ALU_SUB_X: 3 - 1 = 2",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 3),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 1),
|
|
|
|
BPF_ALU32_REG(BPF_SUB, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 2 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_SUB_X: 4294967295 - 4294967294 = 1",
|
|
|
|
.u.insns_int = {
|
2015-05-14 10:40:39 +07:00
|
|
|
BPF_LD_IMM64(R0, 4294967295U),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 4294967294U),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_ALU32_REG(BPF_SUB, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_SUB_X: 3 - 1 = 2",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 3),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 1),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 2 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_SUB_X: 4294967295 - 4294967294 = 1",
|
|
|
|
.u.insns_int = {
|
2015-05-14 10:40:39 +07:00
|
|
|
BPF_LD_IMM64(R0, 4294967295U),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 4294967294U),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_ALU64_REG(BPF_SUB, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
/* BPF_ALU | BPF_SUB | BPF_K */
|
|
|
|
{
|
|
|
|
"ALU_SUB_K: 3 - 1 = 2",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 3),
|
|
|
|
BPF_ALU32_IMM(BPF_SUB, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 2 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_SUB_K: 3 - 0 = 3",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 3),
|
|
|
|
BPF_ALU32_IMM(BPF_SUB, R0, 0),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 3 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_SUB_K: 4294967295 - 4294967294 = 1",
|
|
|
|
.u.insns_int = {
|
2015-05-14 10:40:39 +07:00
|
|
|
BPF_LD_IMM64(R0, 4294967295U),
|
|
|
|
BPF_ALU32_IMM(BPF_SUB, R0, 4294967294U),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_SUB_K: 3 - 1 = 2",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 3),
|
|
|
|
BPF_ALU64_IMM(BPF_SUB, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 2 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_SUB_K: 3 - 0 = 3",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 3),
|
|
|
|
BPF_ALU64_IMM(BPF_SUB, R0, 0),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 3 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_SUB_K: 4294967294 - 4294967295 = -1",
|
|
|
|
.u.insns_int = {
|
2015-05-14 10:40:39 +07:00
|
|
|
BPF_LD_IMM64(R0, 4294967294U),
|
|
|
|
BPF_ALU64_IMM(BPF_SUB, R0, 4294967295U),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, -1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_ADD_K: 2147483646 - 2147483647 = -1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 2147483646),
|
|
|
|
BPF_ALU64_IMM(BPF_SUB, R0, 2147483647),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, -1 } },
|
|
|
|
},
|
|
|
|
/* BPF_ALU | BPF_MUL | BPF_X */
|
|
|
|
{
|
|
|
|
"ALU_MUL_X: 2 * 3 = 6",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 2),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 3),
|
|
|
|
BPF_ALU32_REG(BPF_MUL, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 6 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_MUL_X: 2 * 0x7FFFFFF8 = 0xFFFFFFF0",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 2),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 0x7FFFFFF8),
|
|
|
|
BPF_ALU32_REG(BPF_MUL, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xFFFFFFF0 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_MUL_X: -1 * -1 = 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, -1),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, -1),
|
|
|
|
BPF_ALU32_REG(BPF_MUL, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_MUL_X: 2 * 3 = 6",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 2),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 3),
|
|
|
|
BPF_ALU64_REG(BPF_MUL, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 6 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_MUL_X: 1 * 2147483647 = 2147483647",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 1),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 2147483647),
|
|
|
|
BPF_ALU64_REG(BPF_MUL, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 2147483647 } },
|
|
|
|
},
|
|
|
|
/* BPF_ALU | BPF_MUL | BPF_K */
|
|
|
|
{
|
|
|
|
"ALU_MUL_K: 2 * 3 = 6",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 2),
|
|
|
|
BPF_ALU32_IMM(BPF_MUL, R0, 3),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 6 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_MUL_K: 3 * 1 = 3",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 3),
|
|
|
|
BPF_ALU32_IMM(BPF_MUL, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 3 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_MUL_K: 2 * 0x7FFFFFF8 = 0xFFFFFFF0",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 2),
|
|
|
|
BPF_ALU32_IMM(BPF_MUL, R0, 0x7FFFFFF8),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xFFFFFFF0 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_MUL_K: 1 * (-1) = 0x00000000ffffffff",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R2, 0x1),
|
|
|
|
BPF_LD_IMM64(R3, 0x00000000ffffffff),
|
|
|
|
BPF_ALU32_IMM(BPF_MUL, R2, 0xffffffff),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
|
|
|
|
BPF_MOV32_IMM(R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV32_IMM(R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_MUL_K: 2 * 3 = 6",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 2),
|
|
|
|
BPF_ALU64_IMM(BPF_MUL, R0, 3),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 6 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_MUL_K: 3 * 1 = 3",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 3),
|
|
|
|
BPF_ALU64_IMM(BPF_MUL, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 3 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_MUL_K: 1 * 2147483647 = 2147483647",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 1),
|
|
|
|
BPF_ALU64_IMM(BPF_MUL, R0, 2147483647),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 2147483647 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_MUL_K: 1 * -2147483647 = -2147483647",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 1),
|
|
|
|
BPF_ALU64_IMM(BPF_MUL, R0, -2147483647),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, -2147483647 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_MUL_K: 1 * (-1) = 0xffffffffffffffff",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R2, 0x1),
|
2015-05-14 10:40:39 +07:00
|
|
|
BPF_LD_IMM64(R3, 0xffffffffffffffffLL),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_ALU64_IMM(BPF_MUL, R2, 0xffffffff),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
|
|
|
|
BPF_MOV32_IMM(R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV32_IMM(R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x1 } },
|
|
|
|
},
|
|
|
|
/* BPF_ALU | BPF_DIV | BPF_X */
|
|
|
|
{
|
|
|
|
"ALU_DIV_X: 6 / 2 = 3",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 6),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 2),
|
|
|
|
BPF_ALU32_REG(BPF_DIV, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 3 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_DIV_X: 4294967295 / 4294967295 = 1",
|
|
|
|
.u.insns_int = {
|
2015-05-14 10:40:39 +07:00
|
|
|
BPF_LD_IMM64(R0, 4294967295U),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 4294967295U),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_ALU32_REG(BPF_DIV, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_DIV_X: 6 / 2 = 3",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 6),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 2),
|
|
|
|
BPF_ALU64_REG(BPF_DIV, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 3 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_DIV_X: 2147483647 / 2147483647 = 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 2147483647),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 2147483647),
|
|
|
|
BPF_ALU64_REG(BPF_DIV, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_DIV_X: 0xffffffffffffffff / (-1) = 0x0000000000000001",
|
|
|
|
.u.insns_int = {
|
2015-05-14 10:40:39 +07:00
|
|
|
BPF_LD_IMM64(R2, 0xffffffffffffffffLL),
|
|
|
|
BPF_LD_IMM64(R4, 0xffffffffffffffffLL),
|
|
|
|
BPF_LD_IMM64(R3, 0x0000000000000001LL),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_ALU64_REG(BPF_DIV, R2, R4),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
|
|
|
|
BPF_MOV32_IMM(R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV32_IMM(R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x1 } },
|
|
|
|
},
|
|
|
|
/* BPF_ALU | BPF_DIV | BPF_K */
|
|
|
|
{
|
|
|
|
"ALU_DIV_K: 6 / 2 = 3",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 6),
|
|
|
|
BPF_ALU32_IMM(BPF_DIV, R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 3 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_DIV_K: 3 / 1 = 3",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 3),
|
|
|
|
BPF_ALU32_IMM(BPF_DIV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 3 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_DIV_K: 4294967295 / 4294967295 = 1",
|
|
|
|
.u.insns_int = {
|
2015-05-14 10:40:39 +07:00
|
|
|
BPF_LD_IMM64(R0, 4294967295U),
|
|
|
|
BPF_ALU32_IMM(BPF_DIV, R0, 4294967295U),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_DIV_K: 0xffffffffffffffff / (-1) = 0x1",
|
|
|
|
.u.insns_int = {
|
2015-05-14 10:40:39 +07:00
|
|
|
BPF_LD_IMM64(R2, 0xffffffffffffffffLL),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_LD_IMM64(R3, 0x1UL),
|
|
|
|
BPF_ALU32_IMM(BPF_DIV, R2, 0xffffffff),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
|
|
|
|
BPF_MOV32_IMM(R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV32_IMM(R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_DIV_K: 6 / 2 = 3",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 6),
|
|
|
|
BPF_ALU64_IMM(BPF_DIV, R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 3 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_DIV_K: 3 / 1 = 3",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 3),
|
|
|
|
BPF_ALU64_IMM(BPF_DIV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 3 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_DIV_K: 2147483647 / 2147483647 = 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 2147483647),
|
|
|
|
BPF_ALU64_IMM(BPF_DIV, R0, 2147483647),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_DIV_K: 0xffffffffffffffff / (-1) = 0x0000000000000001",
|
|
|
|
.u.insns_int = {
|
2015-05-14 10:40:39 +07:00
|
|
|
BPF_LD_IMM64(R2, 0xffffffffffffffffLL),
|
|
|
|
BPF_LD_IMM64(R3, 0x0000000000000001LL),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_ALU64_IMM(BPF_DIV, R2, 0xffffffff),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
|
|
|
|
BPF_MOV32_IMM(R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV32_IMM(R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x1 } },
|
|
|
|
},
|
|
|
|
/* BPF_ALU | BPF_MOD | BPF_X */
|
|
|
|
{
|
|
|
|
"ALU_MOD_X: 3 % 2 = 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 3),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 2),
|
|
|
|
BPF_ALU32_REG(BPF_MOD, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_MOD_X: 4294967295 % 4294967293 = 2",
|
|
|
|
.u.insns_int = {
|
2015-05-14 10:40:39 +07:00
|
|
|
BPF_LD_IMM64(R0, 4294967295U),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 4294967293U),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_ALU32_REG(BPF_MOD, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 2 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_MOD_X: 3 % 2 = 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 3),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 2),
|
|
|
|
BPF_ALU64_REG(BPF_MOD, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_MOD_X: 2147483647 % 2147483645 = 2",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 2147483647),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 2147483645),
|
|
|
|
BPF_ALU64_REG(BPF_MOD, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 2 } },
|
|
|
|
},
|
|
|
|
/* BPF_ALU | BPF_MOD | BPF_K */
|
|
|
|
{
|
|
|
|
"ALU_MOD_K: 3 % 2 = 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 3),
|
|
|
|
BPF_ALU32_IMM(BPF_MOD, R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_MOD_K: 3 % 1 = 0",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 3),
|
|
|
|
BPF_ALU32_IMM(BPF_MOD, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_MOD_K: 4294967295 % 4294967293 = 2",
|
|
|
|
.u.insns_int = {
|
2015-05-14 10:40:39 +07:00
|
|
|
BPF_LD_IMM64(R0, 4294967295U),
|
|
|
|
BPF_ALU32_IMM(BPF_MOD, R0, 4294967293U),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 2 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_MOD_K: 3 % 2 = 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 3),
|
|
|
|
BPF_ALU64_IMM(BPF_MOD, R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_MOD_K: 3 % 1 = 0",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 3),
|
|
|
|
BPF_ALU64_IMM(BPF_MOD, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_MOD_K: 2147483647 % 2147483645 = 2",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 2147483647),
|
|
|
|
BPF_ALU64_IMM(BPF_MOD, R0, 2147483645),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 2 } },
|
|
|
|
},
|
|
|
|
/* BPF_ALU | BPF_AND | BPF_X */
|
|
|
|
{
|
|
|
|
"ALU_AND_X: 3 & 2 = 2",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 3),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 2),
|
|
|
|
BPF_ALU32_REG(BPF_AND, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 2 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_AND_X: 0xffffffff & 0xffffffff = 0xffffffff",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 0xffffffff),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 0xffffffff),
|
|
|
|
BPF_ALU32_REG(BPF_AND, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xffffffff } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_AND_X: 3 & 2 = 2",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 3),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 2),
|
|
|
|
BPF_ALU64_REG(BPF_AND, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 2 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_AND_X: 0xffffffff & 0xffffffff = 0xffffffff",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 0xffffffff),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 0xffffffff),
|
|
|
|
BPF_ALU64_REG(BPF_AND, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xffffffff } },
|
|
|
|
},
|
|
|
|
/* BPF_ALU | BPF_AND | BPF_K */
|
|
|
|
{
|
|
|
|
"ALU_AND_K: 3 & 2 = 2",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 3),
|
|
|
|
BPF_ALU32_IMM(BPF_AND, R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 2 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_AND_K: 0xffffffff & 0xffffffff = 0xffffffff",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 0xffffffff),
|
|
|
|
BPF_ALU32_IMM(BPF_AND, R0, 0xffffffff),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xffffffff } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_AND_K: 3 & 2 = 2",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 3),
|
|
|
|
BPF_ALU64_IMM(BPF_AND, R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 2 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_AND_K: 0xffffffff & 0xffffffff = 0xffffffff",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 0xffffffff),
|
|
|
|
BPF_ALU64_IMM(BPF_AND, R0, 0xffffffff),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xffffffff } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_AND_K: 0x0000ffffffff0000 & 0x0 = 0x0000ffff00000000",
|
|
|
|
.u.insns_int = {
|
2015-05-14 10:40:39 +07:00
|
|
|
BPF_LD_IMM64(R2, 0x0000ffffffff0000LL),
|
|
|
|
BPF_LD_IMM64(R3, 0x0000000000000000LL),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_ALU64_IMM(BPF_AND, R2, 0x0),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
|
|
|
|
BPF_MOV32_IMM(R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV32_IMM(R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_AND_K: 0x0000ffffffff0000 & -1 = 0x0000ffffffffffff",
|
|
|
|
.u.insns_int = {
|
2015-05-14 10:40:39 +07:00
|
|
|
BPF_LD_IMM64(R2, 0x0000ffffffff0000LL),
|
|
|
|
BPF_LD_IMM64(R3, 0x0000ffffffff0000LL),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_ALU64_IMM(BPF_AND, R2, 0xffffffff),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
|
|
|
|
BPF_MOV32_IMM(R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV32_IMM(R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_AND_K: 0xffffffffffffffff & -1 = 0xffffffffffffffff",
|
|
|
|
.u.insns_int = {
|
2015-05-14 10:40:39 +07:00
|
|
|
BPF_LD_IMM64(R2, 0xffffffffffffffffLL),
|
|
|
|
BPF_LD_IMM64(R3, 0xffffffffffffffffLL),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_ALU64_IMM(BPF_AND, R2, 0xffffffff),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
|
|
|
|
BPF_MOV32_IMM(R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV32_IMM(R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x1 } },
|
|
|
|
},
|
|
|
|
/* BPF_ALU | BPF_OR | BPF_X */
|
|
|
|
{
|
|
|
|
"ALU_OR_X: 1 | 2 = 3",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 1),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 2),
|
|
|
|
BPF_ALU32_REG(BPF_OR, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 3 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_OR_X: 0x0 | 0xffffffff = 0xffffffff",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 0),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 0xffffffff),
|
|
|
|
BPF_ALU32_REG(BPF_OR, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xffffffff } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_OR_X: 1 | 2 = 3",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 1),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 2),
|
|
|
|
BPF_ALU64_REG(BPF_OR, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 3 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_OR_X: 0 | 0xffffffff = 0xffffffff",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 0),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 0xffffffff),
|
|
|
|
BPF_ALU64_REG(BPF_OR, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xffffffff } },
|
|
|
|
},
|
|
|
|
/* BPF_ALU | BPF_OR | BPF_K */
|
|
|
|
{
|
|
|
|
"ALU_OR_K: 1 | 2 = 3",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 1),
|
|
|
|
BPF_ALU32_IMM(BPF_OR, R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 3 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_OR_K: 0 & 0xffffffff = 0xffffffff",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 0),
|
|
|
|
BPF_ALU32_IMM(BPF_OR, R0, 0xffffffff),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xffffffff } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_OR_K: 1 | 2 = 3",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 1),
|
|
|
|
BPF_ALU64_IMM(BPF_OR, R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 3 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_OR_K: 0 & 0xffffffff = 0xffffffff",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 0),
|
|
|
|
BPF_ALU64_IMM(BPF_OR, R0, 0xffffffff),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xffffffff } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_OR_K: 0x0000ffffffff0000 | 0x0 = 0x0000ffff00000000",
|
|
|
|
.u.insns_int = {
|
2015-05-14 10:40:39 +07:00
|
|
|
BPF_LD_IMM64(R2, 0x0000ffffffff0000LL),
|
|
|
|
BPF_LD_IMM64(R3, 0x0000ffffffff0000LL),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_ALU64_IMM(BPF_OR, R2, 0x0),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
|
|
|
|
BPF_MOV32_IMM(R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV32_IMM(R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_OR_K: 0x0000ffffffff0000 | -1 = 0xffffffffffffffff",
|
|
|
|
.u.insns_int = {
|
2015-05-14 10:40:39 +07:00
|
|
|
BPF_LD_IMM64(R2, 0x0000ffffffff0000LL),
|
|
|
|
BPF_LD_IMM64(R3, 0xffffffffffffffffLL),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_ALU64_IMM(BPF_OR, R2, 0xffffffff),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
|
|
|
|
BPF_MOV32_IMM(R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV32_IMM(R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_OR_K: 0x000000000000000 | -1 = 0xffffffffffffffff",
|
|
|
|
.u.insns_int = {
|
2015-05-14 10:40:39 +07:00
|
|
|
BPF_LD_IMM64(R2, 0x0000000000000000LL),
|
|
|
|
BPF_LD_IMM64(R3, 0xffffffffffffffffLL),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_ALU64_IMM(BPF_OR, R2, 0xffffffff),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
|
|
|
|
BPF_MOV32_IMM(R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV32_IMM(R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x1 } },
|
|
|
|
},
|
|
|
|
/* BPF_ALU | BPF_XOR | BPF_X */
|
|
|
|
{
|
|
|
|
"ALU_XOR_X: 5 ^ 6 = 3",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 5),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 6),
|
|
|
|
BPF_ALU32_REG(BPF_XOR, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 3 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_XOR_X: 0x1 ^ 0xffffffff = 0xfffffffe",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 1),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 0xffffffff),
|
|
|
|
BPF_ALU32_REG(BPF_XOR, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xfffffffe } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_XOR_X: 5 ^ 6 = 3",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 5),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 6),
|
|
|
|
BPF_ALU64_REG(BPF_XOR, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 3 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_XOR_X: 1 ^ 0xffffffff = 0xfffffffe",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 1),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 0xffffffff),
|
|
|
|
BPF_ALU64_REG(BPF_XOR, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xfffffffe } },
|
|
|
|
},
|
|
|
|
/* BPF_ALU | BPF_XOR | BPF_K */
|
|
|
|
{
|
|
|
|
"ALU_XOR_K: 5 ^ 6 = 3",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 5),
|
|
|
|
BPF_ALU32_IMM(BPF_XOR, R0, 6),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 3 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_XOR_K: 1 ^ 0xffffffff = 0xfffffffe",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 1),
|
|
|
|
BPF_ALU32_IMM(BPF_XOR, R0, 0xffffffff),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xfffffffe } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_XOR_K: 5 ^ 6 = 3",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 5),
|
|
|
|
BPF_ALU64_IMM(BPF_XOR, R0, 6),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 3 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_XOR_K: 1 & 0xffffffff = 0xfffffffe",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 1),
|
|
|
|
BPF_ALU64_IMM(BPF_XOR, R0, 0xffffffff),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xfffffffe } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_XOR_K: 0x0000ffffffff0000 ^ 0x0 = 0x0000ffffffff0000",
|
|
|
|
.u.insns_int = {
|
2015-05-14 10:40:39 +07:00
|
|
|
BPF_LD_IMM64(R2, 0x0000ffffffff0000LL),
|
|
|
|
BPF_LD_IMM64(R3, 0x0000ffffffff0000LL),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_ALU64_IMM(BPF_XOR, R2, 0x0),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
|
|
|
|
BPF_MOV32_IMM(R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV32_IMM(R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_XOR_K: 0x0000ffffffff0000 ^ -1 = 0xffff00000000ffff",
|
|
|
|
.u.insns_int = {
|
2015-05-14 10:40:39 +07:00
|
|
|
BPF_LD_IMM64(R2, 0x0000ffffffff0000LL),
|
|
|
|
BPF_LD_IMM64(R3, 0xffff00000000ffffLL),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_ALU64_IMM(BPF_XOR, R2, 0xffffffff),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
|
|
|
|
BPF_MOV32_IMM(R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV32_IMM(R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_XOR_K: 0x000000000000000 ^ -1 = 0xffffffffffffffff",
|
|
|
|
.u.insns_int = {
|
2015-05-14 10:40:39 +07:00
|
|
|
BPF_LD_IMM64(R2, 0x0000000000000000LL),
|
|
|
|
BPF_LD_IMM64(R3, 0xffffffffffffffffLL),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_ALU64_IMM(BPF_XOR, R2, 0xffffffff),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
|
|
|
|
BPF_MOV32_IMM(R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV32_IMM(R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x1 } },
|
|
|
|
},
|
|
|
|
/* BPF_ALU | BPF_LSH | BPF_X */
|
|
|
|
{
|
|
|
|
"ALU_LSH_X: 1 << 1 = 2",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 1),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 1),
|
|
|
|
BPF_ALU32_REG(BPF_LSH, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 2 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_LSH_X: 1 << 31 = 0x80000000",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 1),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 31),
|
|
|
|
BPF_ALU32_REG(BPF_LSH, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x80000000 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_LSH_X: 1 << 1 = 2",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 1),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 1),
|
|
|
|
BPF_ALU64_REG(BPF_LSH, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 2 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_LSH_X: 1 << 31 = 0x80000000",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 1),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 31),
|
|
|
|
BPF_ALU64_REG(BPF_LSH, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x80000000 } },
|
|
|
|
},
|
|
|
|
/* BPF_ALU | BPF_LSH | BPF_K */
|
|
|
|
{
|
|
|
|
"ALU_LSH_K: 1 << 1 = 2",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 1),
|
|
|
|
BPF_ALU32_IMM(BPF_LSH, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 2 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_LSH_K: 1 << 31 = 0x80000000",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 1),
|
|
|
|
BPF_ALU32_IMM(BPF_LSH, R0, 31),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x80000000 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_LSH_K: 1 << 1 = 2",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 1),
|
|
|
|
BPF_ALU64_IMM(BPF_LSH, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 2 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_LSH_K: 1 << 31 = 0x80000000",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 1),
|
|
|
|
BPF_ALU64_IMM(BPF_LSH, R0, 31),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x80000000 } },
|
|
|
|
},
|
|
|
|
/* BPF_ALU | BPF_RSH | BPF_X */
|
|
|
|
{
|
|
|
|
"ALU_RSH_X: 2 >> 1 = 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 2),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 1),
|
|
|
|
BPF_ALU32_REG(BPF_RSH, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_RSH_X: 0x80000000 >> 31 = 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 0x80000000),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 31),
|
|
|
|
BPF_ALU32_REG(BPF_RSH, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_RSH_X: 2 >> 1 = 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 2),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 1),
|
|
|
|
BPF_ALU64_REG(BPF_RSH, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_RSH_X: 0x80000000 >> 31 = 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 0x80000000),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 31),
|
|
|
|
BPF_ALU64_REG(BPF_RSH, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
/* BPF_ALU | BPF_RSH | BPF_K */
|
|
|
|
{
|
|
|
|
"ALU_RSH_K: 2 >> 1 = 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 2),
|
|
|
|
BPF_ALU32_IMM(BPF_RSH, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_RSH_K: 0x80000000 >> 31 = 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 0x80000000),
|
|
|
|
BPF_ALU32_IMM(BPF_RSH, R0, 31),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_RSH_K: 2 >> 1 = 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 2),
|
|
|
|
BPF_ALU64_IMM(BPF_RSH, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_RSH_K: 0x80000000 >> 31 = 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 0x80000000),
|
|
|
|
BPF_ALU64_IMM(BPF_RSH, R0, 31),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
/* BPF_ALU | BPF_ARSH | BPF_X */
|
|
|
|
{
|
|
|
|
"ALU_ARSH_X: 0xff00ff0000000000 >> 40 = 0xffffffffffff00ff",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 0xff00ff0000000000LL),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 40),
|
|
|
|
BPF_ALU64_REG(BPF_ARSH, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xffff00ff } },
|
|
|
|
},
|
|
|
|
/* BPF_ALU | BPF_ARSH | BPF_K */
|
|
|
|
{
|
|
|
|
"ALU_ARSH_K: 0xff00ff0000000000 >> 40 = 0xffffffffffff00ff",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 0xff00ff0000000000LL),
|
|
|
|
BPF_ALU64_IMM(BPF_ARSH, R0, 40),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xffff00ff } },
|
|
|
|
},
|
|
|
|
/* BPF_ALU | BPF_NEG */
|
|
|
|
{
|
|
|
|
"ALU_NEG: -(3) = -3",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 3),
|
|
|
|
BPF_ALU32_IMM(BPF_NEG, R0, 0),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, -3 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_NEG: -(-3) = 3",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, -3),
|
|
|
|
BPF_ALU32_IMM(BPF_NEG, R0, 0),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 3 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_NEG: -(3) = -3",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 3),
|
|
|
|
BPF_ALU64_IMM(BPF_NEG, R0, 0),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, -3 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU64_NEG: -(-3) = 3",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, -3),
|
|
|
|
BPF_ALU64_IMM(BPF_NEG, R0, 0),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 3 } },
|
|
|
|
},
|
|
|
|
/* BPF_ALU | BPF_END | BPF_FROM_BE */
|
|
|
|
{
|
|
|
|
"ALU_END_FROM_BE 16: 0x0123456789abcdef -> 0xcdef",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 0x0123456789abcdefLL),
|
|
|
|
BPF_ENDIAN(BPF_FROM_BE, R0, 16),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, cpu_to_be16(0xcdef) } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_END_FROM_BE 32: 0x0123456789abcdef -> 0x89abcdef",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 0x0123456789abcdefLL),
|
|
|
|
BPF_ENDIAN(BPF_FROM_BE, R0, 32),
|
2015-07-09 04:00:56 +07:00
|
|
|
BPF_ALU64_REG(BPF_MOV, R1, R0),
|
|
|
|
BPF_ALU64_IMM(BPF_RSH, R1, 32),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R0, R1), /* R1 = 0 */
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, cpu_to_be32(0x89abcdef) } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_END_FROM_BE 64: 0x0123456789abcdef -> 0x89abcdef",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 0x0123456789abcdefLL),
|
|
|
|
BPF_ENDIAN(BPF_FROM_BE, R0, 64),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, (u32) cpu_to_be64(0x0123456789abcdefLL) } },
|
|
|
|
},
|
|
|
|
/* BPF_ALU | BPF_END | BPF_FROM_LE */
|
|
|
|
{
|
|
|
|
"ALU_END_FROM_LE 16: 0x0123456789abcdef -> 0xefcd",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 0x0123456789abcdefLL),
|
|
|
|
BPF_ENDIAN(BPF_FROM_LE, R0, 16),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, cpu_to_le16(0xcdef) } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_END_FROM_LE 32: 0x0123456789abcdef -> 0xefcdab89",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 0x0123456789abcdefLL),
|
|
|
|
BPF_ENDIAN(BPF_FROM_LE, R0, 32),
|
2015-07-09 04:00:56 +07:00
|
|
|
BPF_ALU64_REG(BPF_MOV, R1, R0),
|
|
|
|
BPF_ALU64_IMM(BPF_RSH, R1, 32),
|
|
|
|
BPF_ALU32_REG(BPF_ADD, R0, R1), /* R1 = 0 */
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, cpu_to_le32(0x89abcdef) } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ALU_END_FROM_LE 64: 0x0123456789abcdef -> 0x67452301",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 0x0123456789abcdefLL),
|
|
|
|
BPF_ENDIAN(BPF_FROM_LE, R0, 64),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, (u32) cpu_to_le64(0x0123456789abcdefLL) } },
|
|
|
|
},
|
|
|
|
/* BPF_ST(X) | BPF_MEM | BPF_B/H/W/DW */
|
|
|
|
{
|
|
|
|
"ST_MEM_B: Store/Load byte: max negative",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_ST_MEM(BPF_B, R10, -40, 0xff),
|
|
|
|
BPF_LDX_MEM(BPF_B, R0, R10, -40),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xff } },
|
2017-05-31 03:31:32 +07:00
|
|
|
.stack_depth = 40,
|
2015-05-12 12:22:44 +07:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"ST_MEM_B: Store/Load byte: max positive",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_ST_MEM(BPF_H, R10, -40, 0x7f),
|
|
|
|
BPF_LDX_MEM(BPF_H, R0, R10, -40),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x7f } },
|
2017-05-31 03:31:32 +07:00
|
|
|
.stack_depth = 40,
|
2015-05-12 12:22:44 +07:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"STX_MEM_B: Store/Load byte: max negative",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 0xffLL),
|
|
|
|
BPF_STX_MEM(BPF_B, R10, R1, -40),
|
|
|
|
BPF_LDX_MEM(BPF_B, R0, R10, -40),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xff } },
|
2017-05-31 03:31:32 +07:00
|
|
|
.stack_depth = 40,
|
2015-05-12 12:22:44 +07:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"ST_MEM_H: Store/Load half word: max negative",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_ST_MEM(BPF_H, R10, -40, 0xffff),
|
|
|
|
BPF_LDX_MEM(BPF_H, R0, R10, -40),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xffff } },
|
2017-05-31 03:31:32 +07:00
|
|
|
.stack_depth = 40,
|
2015-05-12 12:22:44 +07:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"ST_MEM_H: Store/Load half word: max positive",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_ST_MEM(BPF_H, R10, -40, 0x7fff),
|
|
|
|
BPF_LDX_MEM(BPF_H, R0, R10, -40),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x7fff } },
|
2017-05-31 03:31:32 +07:00
|
|
|
.stack_depth = 40,
|
2015-05-12 12:22:44 +07:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"STX_MEM_H: Store/Load half word: max negative",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 0xffffLL),
|
|
|
|
BPF_STX_MEM(BPF_H, R10, R1, -40),
|
|
|
|
BPF_LDX_MEM(BPF_H, R0, R10, -40),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xffff } },
|
2017-05-31 03:31:32 +07:00
|
|
|
.stack_depth = 40,
|
2015-05-12 12:22:44 +07:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"ST_MEM_W: Store/Load word: max negative",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_ST_MEM(BPF_W, R10, -40, 0xffffffff),
|
|
|
|
BPF_LDX_MEM(BPF_W, R0, R10, -40),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xffffffff } },
|
2017-05-31 03:31:32 +07:00
|
|
|
.stack_depth = 40,
|
2015-05-12 12:22:44 +07:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"ST_MEM_W: Store/Load word: max positive",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_ST_MEM(BPF_W, R10, -40, 0x7fffffff),
|
|
|
|
BPF_LDX_MEM(BPF_W, R0, R10, -40),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x7fffffff } },
|
2017-05-31 03:31:32 +07:00
|
|
|
.stack_depth = 40,
|
2015-05-12 12:22:44 +07:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"STX_MEM_W: Store/Load word: max negative",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 0xffffffffLL),
|
|
|
|
BPF_STX_MEM(BPF_W, R10, R1, -40),
|
|
|
|
BPF_LDX_MEM(BPF_W, R0, R10, -40),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xffffffff } },
|
2017-05-31 03:31:32 +07:00
|
|
|
.stack_depth = 40,
|
2015-05-12 12:22:44 +07:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"ST_MEM_DW: Store/Load double word: max negative",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_ST_MEM(BPF_DW, R10, -40, 0xffffffff),
|
|
|
|
BPF_LDX_MEM(BPF_DW, R0, R10, -40),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xffffffff } },
|
2017-05-31 03:31:32 +07:00
|
|
|
.stack_depth = 40,
|
2015-05-12 12:22:44 +07:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"ST_MEM_DW: Store/Load double word: max negative 2",
|
|
|
|
.u.insns_int = {
|
2015-05-14 10:40:39 +07:00
|
|
|
BPF_LD_IMM64(R2, 0xffff00000000ffffLL),
|
|
|
|
BPF_LD_IMM64(R3, 0xffffffffffffffffLL),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_ST_MEM(BPF_DW, R10, -40, 0xffffffff),
|
|
|
|
BPF_LDX_MEM(BPF_DW, R2, R10, -40),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
|
|
|
|
BPF_MOV32_IMM(R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_MOV32_IMM(R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x1 } },
|
2017-05-31 03:31:32 +07:00
|
|
|
.stack_depth = 40,
|
2015-05-12 12:22:44 +07:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"ST_MEM_DW: Store/Load double word: max positive",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_ST_MEM(BPF_DW, R10, -40, 0x7fffffff),
|
|
|
|
BPF_LDX_MEM(BPF_DW, R0, R10, -40),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x7fffffff } },
|
2017-05-31 03:31:32 +07:00
|
|
|
.stack_depth = 40,
|
2015-05-12 12:22:44 +07:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"STX_MEM_DW: Store/Load double word: max negative",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 0xffffffffffffffffLL),
|
|
|
|
BPF_STX_MEM(BPF_W, R10, R1, -40),
|
|
|
|
BPF_LDX_MEM(BPF_W, R0, R10, -40),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xffffffff } },
|
2017-05-31 03:31:32 +07:00
|
|
|
.stack_depth = 40,
|
2015-05-12 12:22:44 +07:00
|
|
|
},
|
|
|
|
/* BPF_STX | BPF_XADD | BPF_W/DW */
|
|
|
|
{
|
|
|
|
"STX_XADD_W: Test: 0x12 + 0x10 = 0x22",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0x12),
|
|
|
|
BPF_ST_MEM(BPF_W, R10, -40, 0x10),
|
|
|
|
BPF_STX_XADD(BPF_W, R10, R0, -40),
|
|
|
|
BPF_LDX_MEM(BPF_W, R0, R10, -40),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x22 } },
|
2017-05-31 03:31:32 +07:00
|
|
|
.stack_depth = 40,
|
2015-05-12 12:22:44 +07:00
|
|
|
},
|
bpf, arm64: implement jiting of BPF_XADD
This work adds BPF_XADD for BPF_W/BPF_DW to the arm64 JIT and therefore
completes JITing of all BPF instructions, meaning we can thus also remove
the 'notyet' label and do not need to fall back to the interpreter when
BPF_XADD is used in a program!
This now also brings arm64 JIT in line with x86_64, s390x, ppc64, sparc64,
where all current eBPF features are supported.
BPF_W example from test_bpf:
.u.insns_int = {
BPF_ALU32_IMM(BPF_MOV, R0, 0x12),
BPF_ST_MEM(BPF_W, R10, -40, 0x10),
BPF_STX_XADD(BPF_W, R10, R0, -40),
BPF_LDX_MEM(BPF_W, R0, R10, -40),
BPF_EXIT_INSN(),
},
[...]
00000020: 52800247 mov w7, #0x12 // #18
00000024: 928004eb mov x11, #0xffffffffffffffd8 // #-40
00000028: d280020a mov x10, #0x10 // #16
0000002c: b82b6b2a str w10, [x25,x11]
// start of xadd mapping:
00000030: 928004ea mov x10, #0xffffffffffffffd8 // #-40
00000034: 8b19014a add x10, x10, x25
00000038: f9800151 prfm pstl1strm, [x10]
0000003c: 885f7d4b ldxr w11, [x10]
00000040: 0b07016b add w11, w11, w7
00000044: 880b7d4b stxr w11, w11, [x10]
00000048: 35ffffab cbnz w11, 0x0000003c
// end of xadd mapping:
[...]
BPF_DW example from test_bpf:
.u.insns_int = {
BPF_ALU32_IMM(BPF_MOV, R0, 0x12),
BPF_ST_MEM(BPF_DW, R10, -40, 0x10),
BPF_STX_XADD(BPF_DW, R10, R0, -40),
BPF_LDX_MEM(BPF_DW, R0, R10, -40),
BPF_EXIT_INSN(),
},
[...]
00000020: 52800247 mov w7, #0x12 // #18
00000024: 928004eb mov x11, #0xffffffffffffffd8 // #-40
00000028: d280020a mov x10, #0x10 // #16
0000002c: f82b6b2a str x10, [x25,x11]
// start of xadd mapping:
00000030: 928004ea mov x10, #0xffffffffffffffd8 // #-40
00000034: 8b19014a add x10, x10, x25
00000038: f9800151 prfm pstl1strm, [x10]
0000003c: c85f7d4b ldxr x11, [x10]
00000040: 8b07016b add x11, x11, x7
00000044: c80b7d4b stxr w11, x11, [x10]
00000048: 35ffffab cbnz w11, 0x0000003c
// end of xadd mapping:
[...]
Tested on Cavium ThunderX ARMv8, test suite results after the patch:
No JIT: [ 3751.855362] test_bpf: Summary: 311 PASSED, 0 FAILED, [0/303 JIT'ed]
With JIT: [ 3573.759527] test_bpf: Summary: 311 PASSED, 0 FAILED, [303/303 JIT'ed]
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-05-01 07:57:20 +07:00
|
|
|
{
|
|
|
|
"STX_XADD_W: Test side-effects, r10: 0x12 + 0x10 = 0x22",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU64_REG(BPF_MOV, R1, R10),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0x12),
|
|
|
|
BPF_ST_MEM(BPF_W, R10, -40, 0x10),
|
|
|
|
BPF_STX_XADD(BPF_W, R10, R0, -40),
|
|
|
|
BPF_ALU64_REG(BPF_MOV, R0, R10),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0 } },
|
2017-05-31 03:31:32 +07:00
|
|
|
.stack_depth = 40,
|
bpf, arm64: implement jiting of BPF_XADD
This work adds BPF_XADD for BPF_W/BPF_DW to the arm64 JIT and therefore
completes JITing of all BPF instructions, meaning we can thus also remove
the 'notyet' label and do not need to fall back to the interpreter when
BPF_XADD is used in a program!
This now also brings arm64 JIT in line with x86_64, s390x, ppc64, sparc64,
where all current eBPF features are supported.
BPF_W example from test_bpf:
.u.insns_int = {
BPF_ALU32_IMM(BPF_MOV, R0, 0x12),
BPF_ST_MEM(BPF_W, R10, -40, 0x10),
BPF_STX_XADD(BPF_W, R10, R0, -40),
BPF_LDX_MEM(BPF_W, R0, R10, -40),
BPF_EXIT_INSN(),
},
[...]
00000020: 52800247 mov w7, #0x12 // #18
00000024: 928004eb mov x11, #0xffffffffffffffd8 // #-40
00000028: d280020a mov x10, #0x10 // #16
0000002c: b82b6b2a str w10, [x25,x11]
// start of xadd mapping:
00000030: 928004ea mov x10, #0xffffffffffffffd8 // #-40
00000034: 8b19014a add x10, x10, x25
00000038: f9800151 prfm pstl1strm, [x10]
0000003c: 885f7d4b ldxr w11, [x10]
00000040: 0b07016b add w11, w11, w7
00000044: 880b7d4b stxr w11, w11, [x10]
00000048: 35ffffab cbnz w11, 0x0000003c
// end of xadd mapping:
[...]
BPF_DW example from test_bpf:
.u.insns_int = {
BPF_ALU32_IMM(BPF_MOV, R0, 0x12),
BPF_ST_MEM(BPF_DW, R10, -40, 0x10),
BPF_STX_XADD(BPF_DW, R10, R0, -40),
BPF_LDX_MEM(BPF_DW, R0, R10, -40),
BPF_EXIT_INSN(),
},
[...]
00000020: 52800247 mov w7, #0x12 // #18
00000024: 928004eb mov x11, #0xffffffffffffffd8 // #-40
00000028: d280020a mov x10, #0x10 // #16
0000002c: f82b6b2a str x10, [x25,x11]
// start of xadd mapping:
00000030: 928004ea mov x10, #0xffffffffffffffd8 // #-40
00000034: 8b19014a add x10, x10, x25
00000038: f9800151 prfm pstl1strm, [x10]
0000003c: c85f7d4b ldxr x11, [x10]
00000040: 8b07016b add x11, x11, x7
00000044: c80b7d4b stxr w11, x11, [x10]
00000048: 35ffffab cbnz w11, 0x0000003c
// end of xadd mapping:
[...]
Tested on Cavium ThunderX ARMv8, test suite results after the patch:
No JIT: [ 3751.855362] test_bpf: Summary: 311 PASSED, 0 FAILED, [0/303 JIT'ed]
With JIT: [ 3573.759527] test_bpf: Summary: 311 PASSED, 0 FAILED, [303/303 JIT'ed]
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-05-01 07:57:20 +07:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"STX_XADD_W: Test side-effects, r0: 0x12 + 0x10 = 0x22",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0x12),
|
|
|
|
BPF_ST_MEM(BPF_W, R10, -40, 0x10),
|
|
|
|
BPF_STX_XADD(BPF_W, R10, R0, -40),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x12 } },
|
2017-05-31 03:31:32 +07:00
|
|
|
.stack_depth = 40,
|
bpf, arm64: implement jiting of BPF_XADD
This work adds BPF_XADD for BPF_W/BPF_DW to the arm64 JIT and therefore
completes JITing of all BPF instructions, meaning we can thus also remove
the 'notyet' label and do not need to fall back to the interpreter when
BPF_XADD is used in a program!
This now also brings arm64 JIT in line with x86_64, s390x, ppc64, sparc64,
where all current eBPF features are supported.
BPF_W example from test_bpf:
.u.insns_int = {
BPF_ALU32_IMM(BPF_MOV, R0, 0x12),
BPF_ST_MEM(BPF_W, R10, -40, 0x10),
BPF_STX_XADD(BPF_W, R10, R0, -40),
BPF_LDX_MEM(BPF_W, R0, R10, -40),
BPF_EXIT_INSN(),
},
[...]
00000020: 52800247 mov w7, #0x12 // #18
00000024: 928004eb mov x11, #0xffffffffffffffd8 // #-40
00000028: d280020a mov x10, #0x10 // #16
0000002c: b82b6b2a str w10, [x25,x11]
// start of xadd mapping:
00000030: 928004ea mov x10, #0xffffffffffffffd8 // #-40
00000034: 8b19014a add x10, x10, x25
00000038: f9800151 prfm pstl1strm, [x10]
0000003c: 885f7d4b ldxr w11, [x10]
00000040: 0b07016b add w11, w11, w7
00000044: 880b7d4b stxr w11, w11, [x10]
00000048: 35ffffab cbnz w11, 0x0000003c
// end of xadd mapping:
[...]
BPF_DW example from test_bpf:
.u.insns_int = {
BPF_ALU32_IMM(BPF_MOV, R0, 0x12),
BPF_ST_MEM(BPF_DW, R10, -40, 0x10),
BPF_STX_XADD(BPF_DW, R10, R0, -40),
BPF_LDX_MEM(BPF_DW, R0, R10, -40),
BPF_EXIT_INSN(),
},
[...]
00000020: 52800247 mov w7, #0x12 // #18
00000024: 928004eb mov x11, #0xffffffffffffffd8 // #-40
00000028: d280020a mov x10, #0x10 // #16
0000002c: f82b6b2a str x10, [x25,x11]
// start of xadd mapping:
00000030: 928004ea mov x10, #0xffffffffffffffd8 // #-40
00000034: 8b19014a add x10, x10, x25
00000038: f9800151 prfm pstl1strm, [x10]
0000003c: c85f7d4b ldxr x11, [x10]
00000040: 8b07016b add x11, x11, x7
00000044: c80b7d4b stxr w11, x11, [x10]
00000048: 35ffffab cbnz w11, 0x0000003c
// end of xadd mapping:
[...]
Tested on Cavium ThunderX ARMv8, test suite results after the patch:
No JIT: [ 3751.855362] test_bpf: Summary: 311 PASSED, 0 FAILED, [0/303 JIT'ed]
With JIT: [ 3573.759527] test_bpf: Summary: 311 PASSED, 0 FAILED, [303/303 JIT'ed]
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-05-01 07:57:20 +07:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"STX_XADD_W: X + 1 + 1 + 1 + ...",
|
|
|
|
{ },
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 4134 } },
|
|
|
|
.fill_helper = bpf_fill_stxw,
|
|
|
|
},
|
2015-05-12 12:22:44 +07:00
|
|
|
{
|
|
|
|
"STX_XADD_DW: Test: 0x12 + 0x10 = 0x22",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0x12),
|
|
|
|
BPF_ST_MEM(BPF_DW, R10, -40, 0x10),
|
|
|
|
BPF_STX_XADD(BPF_DW, R10, R0, -40),
|
|
|
|
BPF_LDX_MEM(BPF_DW, R0, R10, -40),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x22 } },
|
2017-05-31 03:31:32 +07:00
|
|
|
.stack_depth = 40,
|
2015-05-12 12:22:44 +07:00
|
|
|
},
|
bpf, arm64: implement jiting of BPF_XADD
This work adds BPF_XADD for BPF_W/BPF_DW to the arm64 JIT and therefore
completes JITing of all BPF instructions, meaning we can thus also remove
the 'notyet' label and do not need to fall back to the interpreter when
BPF_XADD is used in a program!
This now also brings arm64 JIT in line with x86_64, s390x, ppc64, sparc64,
where all current eBPF features are supported.
BPF_W example from test_bpf:
.u.insns_int = {
BPF_ALU32_IMM(BPF_MOV, R0, 0x12),
BPF_ST_MEM(BPF_W, R10, -40, 0x10),
BPF_STX_XADD(BPF_W, R10, R0, -40),
BPF_LDX_MEM(BPF_W, R0, R10, -40),
BPF_EXIT_INSN(),
},
[...]
00000020: 52800247 mov w7, #0x12 // #18
00000024: 928004eb mov x11, #0xffffffffffffffd8 // #-40
00000028: d280020a mov x10, #0x10 // #16
0000002c: b82b6b2a str w10, [x25,x11]
// start of xadd mapping:
00000030: 928004ea mov x10, #0xffffffffffffffd8 // #-40
00000034: 8b19014a add x10, x10, x25
00000038: f9800151 prfm pstl1strm, [x10]
0000003c: 885f7d4b ldxr w11, [x10]
00000040: 0b07016b add w11, w11, w7
00000044: 880b7d4b stxr w11, w11, [x10]
00000048: 35ffffab cbnz w11, 0x0000003c
// end of xadd mapping:
[...]
BPF_DW example from test_bpf:
.u.insns_int = {
BPF_ALU32_IMM(BPF_MOV, R0, 0x12),
BPF_ST_MEM(BPF_DW, R10, -40, 0x10),
BPF_STX_XADD(BPF_DW, R10, R0, -40),
BPF_LDX_MEM(BPF_DW, R0, R10, -40),
BPF_EXIT_INSN(),
},
[...]
00000020: 52800247 mov w7, #0x12 // #18
00000024: 928004eb mov x11, #0xffffffffffffffd8 // #-40
00000028: d280020a mov x10, #0x10 // #16
0000002c: f82b6b2a str x10, [x25,x11]
// start of xadd mapping:
00000030: 928004ea mov x10, #0xffffffffffffffd8 // #-40
00000034: 8b19014a add x10, x10, x25
00000038: f9800151 prfm pstl1strm, [x10]
0000003c: c85f7d4b ldxr x11, [x10]
00000040: 8b07016b add x11, x11, x7
00000044: c80b7d4b stxr w11, x11, [x10]
00000048: 35ffffab cbnz w11, 0x0000003c
// end of xadd mapping:
[...]
Tested on Cavium ThunderX ARMv8, test suite results after the patch:
No JIT: [ 3751.855362] test_bpf: Summary: 311 PASSED, 0 FAILED, [0/303 JIT'ed]
With JIT: [ 3573.759527] test_bpf: Summary: 311 PASSED, 0 FAILED, [303/303 JIT'ed]
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-05-01 07:57:20 +07:00
|
|
|
{
|
|
|
|
"STX_XADD_DW: Test side-effects, r10: 0x12 + 0x10 = 0x22",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU64_REG(BPF_MOV, R1, R10),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0x12),
|
|
|
|
BPF_ST_MEM(BPF_DW, R10, -40, 0x10),
|
|
|
|
BPF_STX_XADD(BPF_DW, R10, R0, -40),
|
|
|
|
BPF_ALU64_REG(BPF_MOV, R0, R10),
|
|
|
|
BPF_ALU64_REG(BPF_SUB, R0, R1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0 } },
|
2017-05-31 03:31:32 +07:00
|
|
|
.stack_depth = 40,
|
bpf, arm64: implement jiting of BPF_XADD
This work adds BPF_XADD for BPF_W/BPF_DW to the arm64 JIT and therefore
completes JITing of all BPF instructions, meaning we can thus also remove
the 'notyet' label and do not need to fall back to the interpreter when
BPF_XADD is used in a program!
This now also brings arm64 JIT in line with x86_64, s390x, ppc64, sparc64,
where all current eBPF features are supported.
BPF_W example from test_bpf:
.u.insns_int = {
BPF_ALU32_IMM(BPF_MOV, R0, 0x12),
BPF_ST_MEM(BPF_W, R10, -40, 0x10),
BPF_STX_XADD(BPF_W, R10, R0, -40),
BPF_LDX_MEM(BPF_W, R0, R10, -40),
BPF_EXIT_INSN(),
},
[...]
00000020: 52800247 mov w7, #0x12 // #18
00000024: 928004eb mov x11, #0xffffffffffffffd8 // #-40
00000028: d280020a mov x10, #0x10 // #16
0000002c: b82b6b2a str w10, [x25,x11]
// start of xadd mapping:
00000030: 928004ea mov x10, #0xffffffffffffffd8 // #-40
00000034: 8b19014a add x10, x10, x25
00000038: f9800151 prfm pstl1strm, [x10]
0000003c: 885f7d4b ldxr w11, [x10]
00000040: 0b07016b add w11, w11, w7
00000044: 880b7d4b stxr w11, w11, [x10]
00000048: 35ffffab cbnz w11, 0x0000003c
// end of xadd mapping:
[...]
BPF_DW example from test_bpf:
.u.insns_int = {
BPF_ALU32_IMM(BPF_MOV, R0, 0x12),
BPF_ST_MEM(BPF_DW, R10, -40, 0x10),
BPF_STX_XADD(BPF_DW, R10, R0, -40),
BPF_LDX_MEM(BPF_DW, R0, R10, -40),
BPF_EXIT_INSN(),
},
[...]
00000020: 52800247 mov w7, #0x12 // #18
00000024: 928004eb mov x11, #0xffffffffffffffd8 // #-40
00000028: d280020a mov x10, #0x10 // #16
0000002c: f82b6b2a str x10, [x25,x11]
// start of xadd mapping:
00000030: 928004ea mov x10, #0xffffffffffffffd8 // #-40
00000034: 8b19014a add x10, x10, x25
00000038: f9800151 prfm pstl1strm, [x10]
0000003c: c85f7d4b ldxr x11, [x10]
00000040: 8b07016b add x11, x11, x7
00000044: c80b7d4b stxr w11, x11, [x10]
00000048: 35ffffab cbnz w11, 0x0000003c
// end of xadd mapping:
[...]
Tested on Cavium ThunderX ARMv8, test suite results after the patch:
No JIT: [ 3751.855362] test_bpf: Summary: 311 PASSED, 0 FAILED, [0/303 JIT'ed]
With JIT: [ 3573.759527] test_bpf: Summary: 311 PASSED, 0 FAILED, [303/303 JIT'ed]
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-05-01 07:57:20 +07:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"STX_XADD_DW: Test side-effects, r0: 0x12 + 0x10 = 0x22",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0x12),
|
|
|
|
BPF_ST_MEM(BPF_DW, R10, -40, 0x10),
|
|
|
|
BPF_STX_XADD(BPF_DW, R10, R0, -40),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x12 } },
|
2017-05-31 03:31:32 +07:00
|
|
|
.stack_depth = 40,
|
bpf, arm64: implement jiting of BPF_XADD
This work adds BPF_XADD for BPF_W/BPF_DW to the arm64 JIT and therefore
completes JITing of all BPF instructions, meaning we can thus also remove
the 'notyet' label and do not need to fall back to the interpreter when
BPF_XADD is used in a program!
This now also brings arm64 JIT in line with x86_64, s390x, ppc64, sparc64,
where all current eBPF features are supported.
BPF_W example from test_bpf:
.u.insns_int = {
BPF_ALU32_IMM(BPF_MOV, R0, 0x12),
BPF_ST_MEM(BPF_W, R10, -40, 0x10),
BPF_STX_XADD(BPF_W, R10, R0, -40),
BPF_LDX_MEM(BPF_W, R0, R10, -40),
BPF_EXIT_INSN(),
},
[...]
00000020: 52800247 mov w7, #0x12 // #18
00000024: 928004eb mov x11, #0xffffffffffffffd8 // #-40
00000028: d280020a mov x10, #0x10 // #16
0000002c: b82b6b2a str w10, [x25,x11]
// start of xadd mapping:
00000030: 928004ea mov x10, #0xffffffffffffffd8 // #-40
00000034: 8b19014a add x10, x10, x25
00000038: f9800151 prfm pstl1strm, [x10]
0000003c: 885f7d4b ldxr w11, [x10]
00000040: 0b07016b add w11, w11, w7
00000044: 880b7d4b stxr w11, w11, [x10]
00000048: 35ffffab cbnz w11, 0x0000003c
// end of xadd mapping:
[...]
BPF_DW example from test_bpf:
.u.insns_int = {
BPF_ALU32_IMM(BPF_MOV, R0, 0x12),
BPF_ST_MEM(BPF_DW, R10, -40, 0x10),
BPF_STX_XADD(BPF_DW, R10, R0, -40),
BPF_LDX_MEM(BPF_DW, R0, R10, -40),
BPF_EXIT_INSN(),
},
[...]
00000020: 52800247 mov w7, #0x12 // #18
00000024: 928004eb mov x11, #0xffffffffffffffd8 // #-40
00000028: d280020a mov x10, #0x10 // #16
0000002c: f82b6b2a str x10, [x25,x11]
// start of xadd mapping:
00000030: 928004ea mov x10, #0xffffffffffffffd8 // #-40
00000034: 8b19014a add x10, x10, x25
00000038: f9800151 prfm pstl1strm, [x10]
0000003c: c85f7d4b ldxr x11, [x10]
00000040: 8b07016b add x11, x11, x7
00000044: c80b7d4b stxr w11, x11, [x10]
00000048: 35ffffab cbnz w11, 0x0000003c
// end of xadd mapping:
[...]
Tested on Cavium ThunderX ARMv8, test suite results after the patch:
No JIT: [ 3751.855362] test_bpf: Summary: 311 PASSED, 0 FAILED, [0/303 JIT'ed]
With JIT: [ 3573.759527] test_bpf: Summary: 311 PASSED, 0 FAILED, [303/303 JIT'ed]
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-05-01 07:57:20 +07:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"STX_XADD_DW: X + 1 + 1 + 1 + ...",
|
|
|
|
{ },
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 4134 } },
|
|
|
|
.fill_helper = bpf_fill_stxdw,
|
|
|
|
},
|
2015-05-12 12:22:44 +07:00
|
|
|
/* BPF_JMP | BPF_EXIT */
|
|
|
|
{
|
|
|
|
"JMP_EXIT",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0x4711),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0x4712),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x4711 } },
|
|
|
|
},
|
|
|
|
/* BPF_JMP | BPF_JA */
|
|
|
|
{
|
|
|
|
"JMP_JA: Unconditional jump: if (true) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_JMP_IMM(BPF_JA, 0, 0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
bpf: add BPF_J{LT,LE,SLT,SLE} instructions
Currently, eBPF only understands BPF_JGT (>), BPF_JGE (>=),
BPF_JSGT (s>), BPF_JSGE (s>=) instructions, this means that
particularly *JLT/*JLE counterparts involving immediates need
to be rewritten from e.g. X < [IMM] by swapping arguments into
[IMM] > X, meaning the immediate first is required to be loaded
into a register Y := [IMM], such that then we can compare with
Y > X. Note that the destination operand is always required to
be a register.
This has the downside of having unnecessarily increased register
pressure, meaning complex program would need to spill other
registers temporarily to stack in order to obtain an unused
register for the [IMM]. Loading to registers will thus also
affect state pruning since we need to account for that register
use and potentially those registers that had to be spilled/filled
again. As a consequence slightly more stack space might have
been used due to spilling, and BPF programs are a bit longer
due to extra code involving the register load and potentially
required spill/fills.
Thus, add BPF_JLT (<), BPF_JLE (<=), BPF_JSLT (s<), BPF_JSLE (s<=)
counterparts to the eBPF instruction set. Modifying LLVM to
remove the NegateCC() workaround in a PoC patch at [1] and
allowing it to also emit the new instructions resulted in
cilium's BPF programs that are injected into the fast-path to
have a reduced program length in the range of 2-3% (e.g.
accumulated main and tail call sections from one of the object
file reduced from 4864 to 4729 insns), reduced complexity in
the range of 10-30% (e.g. accumulated sections reduced in one
of the cases from 116432 to 88428 insns), and reduced stack
usage in the range of 1-5% (e.g. accumulated sections from one
of the object files reduced from 824 to 784b).
The modification for LLVM will be incorporated in a backwards
compatible way. Plan is for LLVM to have i) a target specific
option to offer a possibility to explicitly enable the extension
by the user (as we have with -m target specific extensions today
for various CPU insns), and ii) have the kernel checked for
presence of the extensions and enable them transparently when
the user is selecting more aggressive options such as -march=native
in a bpf target context. (Other frontends generating BPF byte
code, e.g. ply can probe the kernel directly for its code
generation.)
[1] https://github.com/borkmann/llvm/tree/bpf-insns
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-08-10 06:39:55 +07:00
|
|
|
/* BPF_JMP | BPF_JSLT | BPF_K */
|
|
|
|
{
|
|
|
|
"JMP_JSLT_K: Signed jump: if (-2 < -1) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 0xfffffffffffffffeLL),
|
|
|
|
BPF_JMP_IMM(BPF_JSLT, R1, -1, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"JMP_JSLT_K: Signed jump: if (-1 < -1) return 0",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_LD_IMM64(R1, 0xffffffffffffffffLL),
|
|
|
|
BPF_JMP_IMM(BPF_JSLT, R1, -1, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
2015-05-12 12:22:44 +07:00
|
|
|
/* BPF_JMP | BPF_JSGT | BPF_K */
|
|
|
|
{
|
|
|
|
"JMP_JSGT_K: Signed jump: if (-1 > -2) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 0xffffffffffffffffLL),
|
|
|
|
BPF_JMP_IMM(BPF_JSGT, R1, -2, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"JMP_JSGT_K: Signed jump: if (-1 > -1) return 0",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_LD_IMM64(R1, 0xffffffffffffffffLL),
|
|
|
|
BPF_JMP_IMM(BPF_JSGT, R1, -1, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
bpf: add BPF_J{LT,LE,SLT,SLE} instructions
Currently, eBPF only understands BPF_JGT (>), BPF_JGE (>=),
BPF_JSGT (s>), BPF_JSGE (s>=) instructions, this means that
particularly *JLT/*JLE counterparts involving immediates need
to be rewritten from e.g. X < [IMM] by swapping arguments into
[IMM] > X, meaning the immediate first is required to be loaded
into a register Y := [IMM], such that then we can compare with
Y > X. Note that the destination operand is always required to
be a register.
This has the downside of having unnecessarily increased register
pressure, meaning complex program would need to spill other
registers temporarily to stack in order to obtain an unused
register for the [IMM]. Loading to registers will thus also
affect state pruning since we need to account for that register
use and potentially those registers that had to be spilled/filled
again. As a consequence slightly more stack space might have
been used due to spilling, and BPF programs are a bit longer
due to extra code involving the register load and potentially
required spill/fills.
Thus, add BPF_JLT (<), BPF_JLE (<=), BPF_JSLT (s<), BPF_JSLE (s<=)
counterparts to the eBPF instruction set. Modifying LLVM to
remove the NegateCC() workaround in a PoC patch at [1] and
allowing it to also emit the new instructions resulted in
cilium's BPF programs that are injected into the fast-path to
have a reduced program length in the range of 2-3% (e.g.
accumulated main and tail call sections from one of the object
file reduced from 4864 to 4729 insns), reduced complexity in
the range of 10-30% (e.g. accumulated sections reduced in one
of the cases from 116432 to 88428 insns), and reduced stack
usage in the range of 1-5% (e.g. accumulated sections from one
of the object files reduced from 824 to 784b).
The modification for LLVM will be incorporated in a backwards
compatible way. Plan is for LLVM to have i) a target specific
option to offer a possibility to explicitly enable the extension
by the user (as we have with -m target specific extensions today
for various CPU insns), and ii) have the kernel checked for
presence of the extensions and enable them transparently when
the user is selecting more aggressive options such as -march=native
in a bpf target context. (Other frontends generating BPF byte
code, e.g. ply can probe the kernel directly for its code
generation.)
[1] https://github.com/borkmann/llvm/tree/bpf-insns
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-08-10 06:39:55 +07:00
|
|
|
/* BPF_JMP | BPF_JSLE | BPF_K */
|
|
|
|
{
|
|
|
|
"JMP_JSLE_K: Signed jump: if (-2 <= -1) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 0xfffffffffffffffeLL),
|
|
|
|
BPF_JMP_IMM(BPF_JSLE, R1, -1, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"JMP_JSLE_K: Signed jump: if (-1 <= -1) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 0xffffffffffffffffLL),
|
|
|
|
BPF_JMP_IMM(BPF_JSLE, R1, -1, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"JMP_JSLE_K: Signed jump: value walk 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 3),
|
|
|
|
BPF_JMP_IMM(BPF_JSLE, R1, 0, 6),
|
|
|
|
BPF_ALU64_IMM(BPF_SUB, R1, 1),
|
|
|
|
BPF_JMP_IMM(BPF_JSLE, R1, 0, 4),
|
|
|
|
BPF_ALU64_IMM(BPF_SUB, R1, 1),
|
|
|
|
BPF_JMP_IMM(BPF_JSLE, R1, 0, 2),
|
|
|
|
BPF_ALU64_IMM(BPF_SUB, R1, 1),
|
|
|
|
BPF_JMP_IMM(BPF_JSLE, R1, 0, 1),
|
|
|
|
BPF_EXIT_INSN(), /* bad exit */
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1), /* good exit */
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"JMP_JSLE_K: Signed jump: value walk 2",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 3),
|
|
|
|
BPF_JMP_IMM(BPF_JSLE, R1, 0, 4),
|
|
|
|
BPF_ALU64_IMM(BPF_SUB, R1, 2),
|
|
|
|
BPF_JMP_IMM(BPF_JSLE, R1, 0, 2),
|
|
|
|
BPF_ALU64_IMM(BPF_SUB, R1, 2),
|
|
|
|
BPF_JMP_IMM(BPF_JSLE, R1, 0, 1),
|
|
|
|
BPF_EXIT_INSN(), /* bad exit */
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1), /* good exit */
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
2015-05-12 12:22:44 +07:00
|
|
|
/* BPF_JMP | BPF_JSGE | BPF_K */
|
|
|
|
{
|
|
|
|
"JMP_JSGE_K: Signed jump: if (-1 >= -2) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 0xffffffffffffffffLL),
|
|
|
|
BPF_JMP_IMM(BPF_JSGE, R1, -2, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"JMP_JSGE_K: Signed jump: if (-1 >= -1) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 0xffffffffffffffffLL),
|
|
|
|
BPF_JMP_IMM(BPF_JSGE, R1, -1, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
2017-05-25 06:35:49 +07:00
|
|
|
{
|
|
|
|
"JMP_JSGE_K: Signed jump: value walk 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, -3),
|
|
|
|
BPF_JMP_IMM(BPF_JSGE, R1, 0, 6),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R1, 1),
|
|
|
|
BPF_JMP_IMM(BPF_JSGE, R1, 0, 4),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R1, 1),
|
|
|
|
BPF_JMP_IMM(BPF_JSGE, R1, 0, 2),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R1, 1),
|
|
|
|
BPF_JMP_IMM(BPF_JSGE, R1, 0, 1),
|
|
|
|
BPF_EXIT_INSN(), /* bad exit */
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1), /* good exit */
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"JMP_JSGE_K: Signed jump: value walk 2",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, -3),
|
|
|
|
BPF_JMP_IMM(BPF_JSGE, R1, 0, 4),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R1, 2),
|
|
|
|
BPF_JMP_IMM(BPF_JSGE, R1, 0, 2),
|
|
|
|
BPF_ALU64_IMM(BPF_ADD, R1, 2),
|
|
|
|
BPF_JMP_IMM(BPF_JSGE, R1, 0, 1),
|
|
|
|
BPF_EXIT_INSN(), /* bad exit */
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1), /* good exit */
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
2015-05-12 12:22:44 +07:00
|
|
|
/* BPF_JMP | BPF_JGT | BPF_K */
|
|
|
|
{
|
|
|
|
"JMP_JGT_K: if (3 > 2) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 3),
|
|
|
|
BPF_JMP_IMM(BPF_JGT, R1, 2, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
2016-04-05 17:02:54 +07:00
|
|
|
{
|
|
|
|
"JMP_JGT_K: Unsigned jump: if (-1 > 1) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, -1),
|
|
|
|
BPF_JMP_IMM(BPF_JGT, R1, 1, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
bpf: add BPF_J{LT,LE,SLT,SLE} instructions
Currently, eBPF only understands BPF_JGT (>), BPF_JGE (>=),
BPF_JSGT (s>), BPF_JSGE (s>=) instructions, this means that
particularly *JLT/*JLE counterparts involving immediates need
to be rewritten from e.g. X < [IMM] by swapping arguments into
[IMM] > X, meaning the immediate first is required to be loaded
into a register Y := [IMM], such that then we can compare with
Y > X. Note that the destination operand is always required to
be a register.
This has the downside of having unnecessarily increased register
pressure, meaning complex program would need to spill other
registers temporarily to stack in order to obtain an unused
register for the [IMM]. Loading to registers will thus also
affect state pruning since we need to account for that register
use and potentially those registers that had to be spilled/filled
again. As a consequence slightly more stack space might have
been used due to spilling, and BPF programs are a bit longer
due to extra code involving the register load and potentially
required spill/fills.
Thus, add BPF_JLT (<), BPF_JLE (<=), BPF_JSLT (s<), BPF_JSLE (s<=)
counterparts to the eBPF instruction set. Modifying LLVM to
remove the NegateCC() workaround in a PoC patch at [1] and
allowing it to also emit the new instructions resulted in
cilium's BPF programs that are injected into the fast-path to
have a reduced program length in the range of 2-3% (e.g.
accumulated main and tail call sections from one of the object
file reduced from 4864 to 4729 insns), reduced complexity in
the range of 10-30% (e.g. accumulated sections reduced in one
of the cases from 116432 to 88428 insns), and reduced stack
usage in the range of 1-5% (e.g. accumulated sections from one
of the object files reduced from 824 to 784b).
The modification for LLVM will be incorporated in a backwards
compatible way. Plan is for LLVM to have i) a target specific
option to offer a possibility to explicitly enable the extension
by the user (as we have with -m target specific extensions today
for various CPU insns), and ii) have the kernel checked for
presence of the extensions and enable them transparently when
the user is selecting more aggressive options such as -march=native
in a bpf target context. (Other frontends generating BPF byte
code, e.g. ply can probe the kernel directly for its code
generation.)
[1] https://github.com/borkmann/llvm/tree/bpf-insns
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-08-10 06:39:55 +07:00
|
|
|
/* BPF_JMP | BPF_JLT | BPF_K */
|
|
|
|
{
|
|
|
|
"JMP_JLT_K: if (2 < 3) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 2),
|
|
|
|
BPF_JMP_IMM(BPF_JLT, R1, 3, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"JMP_JGT_K: Unsigned jump: if (1 < -1) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 1),
|
|
|
|
BPF_JMP_IMM(BPF_JLT, R1, -1, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
2015-05-12 12:22:44 +07:00
|
|
|
/* BPF_JMP | BPF_JGE | BPF_K */
|
|
|
|
{
|
|
|
|
"JMP_JGE_K: if (3 >= 2) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 3),
|
|
|
|
BPF_JMP_IMM(BPF_JGE, R1, 2, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
bpf: add BPF_J{LT,LE,SLT,SLE} instructions
Currently, eBPF only understands BPF_JGT (>), BPF_JGE (>=),
BPF_JSGT (s>), BPF_JSGE (s>=) instructions, this means that
particularly *JLT/*JLE counterparts involving immediates need
to be rewritten from e.g. X < [IMM] by swapping arguments into
[IMM] > X, meaning the immediate first is required to be loaded
into a register Y := [IMM], such that then we can compare with
Y > X. Note that the destination operand is always required to
be a register.
This has the downside of having unnecessarily increased register
pressure, meaning complex program would need to spill other
registers temporarily to stack in order to obtain an unused
register for the [IMM]. Loading to registers will thus also
affect state pruning since we need to account for that register
use and potentially those registers that had to be spilled/filled
again. As a consequence slightly more stack space might have
been used due to spilling, and BPF programs are a bit longer
due to extra code involving the register load and potentially
required spill/fills.
Thus, add BPF_JLT (<), BPF_JLE (<=), BPF_JSLT (s<), BPF_JSLE (s<=)
counterparts to the eBPF instruction set. Modifying LLVM to
remove the NegateCC() workaround in a PoC patch at [1] and
allowing it to also emit the new instructions resulted in
cilium's BPF programs that are injected into the fast-path to
have a reduced program length in the range of 2-3% (e.g.
accumulated main and tail call sections from one of the object
file reduced from 4864 to 4729 insns), reduced complexity in
the range of 10-30% (e.g. accumulated sections reduced in one
of the cases from 116432 to 88428 insns), and reduced stack
usage in the range of 1-5% (e.g. accumulated sections from one
of the object files reduced from 824 to 784b).
The modification for LLVM will be incorporated in a backwards
compatible way. Plan is for LLVM to have i) a target specific
option to offer a possibility to explicitly enable the extension
by the user (as we have with -m target specific extensions today
for various CPU insns), and ii) have the kernel checked for
presence of the extensions and enable them transparently when
the user is selecting more aggressive options such as -march=native
in a bpf target context. (Other frontends generating BPF byte
code, e.g. ply can probe the kernel directly for its code
generation.)
[1] https://github.com/borkmann/llvm/tree/bpf-insns
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-08-10 06:39:55 +07:00
|
|
|
/* BPF_JMP | BPF_JLE | BPF_K */
|
|
|
|
{
|
|
|
|
"JMP_JLE_K: if (2 <= 3) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 2),
|
|
|
|
BPF_JMP_IMM(BPF_JLE, R1, 3, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
2015-05-22 22:36:40 +07:00
|
|
|
/* BPF_JMP | BPF_JGT | BPF_K jump backwards */
|
|
|
|
{
|
|
|
|
"JMP_JGT_K: if (3 > 2) return 1 (jump backwards)",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_JMP_IMM(BPF_JA, 0, 0, 2), /* goto start */
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1), /* out: */
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0), /* start: */
|
|
|
|
BPF_LD_IMM64(R1, 3), /* note: this takes 2 insns */
|
|
|
|
BPF_JMP_IMM(BPF_JGT, R1, 2, -6), /* goto out */
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
2015-05-12 12:22:44 +07:00
|
|
|
{
|
|
|
|
"JMP_JGE_K: if (3 >= 3) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 3),
|
|
|
|
BPF_JMP_IMM(BPF_JGE, R1, 3, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
bpf: add BPF_J{LT,LE,SLT,SLE} instructions
Currently, eBPF only understands BPF_JGT (>), BPF_JGE (>=),
BPF_JSGT (s>), BPF_JSGE (s>=) instructions, this means that
particularly *JLT/*JLE counterparts involving immediates need
to be rewritten from e.g. X < [IMM] by swapping arguments into
[IMM] > X, meaning the immediate first is required to be loaded
into a register Y := [IMM], such that then we can compare with
Y > X. Note that the destination operand is always required to
be a register.
This has the downside of having unnecessarily increased register
pressure, meaning complex program would need to spill other
registers temporarily to stack in order to obtain an unused
register for the [IMM]. Loading to registers will thus also
affect state pruning since we need to account for that register
use and potentially those registers that had to be spilled/filled
again. As a consequence slightly more stack space might have
been used due to spilling, and BPF programs are a bit longer
due to extra code involving the register load and potentially
required spill/fills.
Thus, add BPF_JLT (<), BPF_JLE (<=), BPF_JSLT (s<), BPF_JSLE (s<=)
counterparts to the eBPF instruction set. Modifying LLVM to
remove the NegateCC() workaround in a PoC patch at [1] and
allowing it to also emit the new instructions resulted in
cilium's BPF programs that are injected into the fast-path to
have a reduced program length in the range of 2-3% (e.g.
accumulated main and tail call sections from one of the object
file reduced from 4864 to 4729 insns), reduced complexity in
the range of 10-30% (e.g. accumulated sections reduced in one
of the cases from 116432 to 88428 insns), and reduced stack
usage in the range of 1-5% (e.g. accumulated sections from one
of the object files reduced from 824 to 784b).
The modification for LLVM will be incorporated in a backwards
compatible way. Plan is for LLVM to have i) a target specific
option to offer a possibility to explicitly enable the extension
by the user (as we have with -m target specific extensions today
for various CPU insns), and ii) have the kernel checked for
presence of the extensions and enable them transparently when
the user is selecting more aggressive options such as -march=native
in a bpf target context. (Other frontends generating BPF byte
code, e.g. ply can probe the kernel directly for its code
generation.)
[1] https://github.com/borkmann/llvm/tree/bpf-insns
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-08-10 06:39:55 +07:00
|
|
|
/* BPF_JMP | BPF_JLT | BPF_K jump backwards */
|
|
|
|
{
|
|
|
|
"JMP_JGT_K: if (2 < 3) return 1 (jump backwards)",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_JMP_IMM(BPF_JA, 0, 0, 2), /* goto start */
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1), /* out: */
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0), /* start: */
|
|
|
|
BPF_LD_IMM64(R1, 2), /* note: this takes 2 insns */
|
|
|
|
BPF_JMP_IMM(BPF_JLT, R1, 3, -6), /* goto out */
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"JMP_JLE_K: if (3 <= 3) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 3),
|
|
|
|
BPF_JMP_IMM(BPF_JLE, R1, 3, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
2015-05-12 12:22:44 +07:00
|
|
|
/* BPF_JMP | BPF_JNE | BPF_K */
|
|
|
|
{
|
|
|
|
"JMP_JNE_K: if (3 != 2) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 3),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, R1, 2, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
/* BPF_JMP | BPF_JEQ | BPF_K */
|
|
|
|
{
|
|
|
|
"JMP_JEQ_K: if (3 == 3) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 3),
|
|
|
|
BPF_JMP_IMM(BPF_JEQ, R1, 3, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
/* BPF_JMP | BPF_JSET | BPF_K */
|
|
|
|
{
|
|
|
|
"JMP_JSET_K: if (0x3 & 0x2) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 3),
|
2016-04-05 17:02:53 +07:00
|
|
|
BPF_JMP_IMM(BPF_JSET, R1, 2, 1),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"JMP_JSET_K: if (0x3 & 0xffffffff) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 3),
|
2016-04-05 17:02:53 +07:00
|
|
|
BPF_JMP_IMM(BPF_JSET, R1, 0xffffffff, 1),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
/* BPF_JMP | BPF_JSGT | BPF_X */
|
|
|
|
{
|
|
|
|
"JMP_JSGT_X: Signed jump: if (-1 > -2) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, -1),
|
|
|
|
BPF_LD_IMM64(R2, -2),
|
|
|
|
BPF_JMP_REG(BPF_JSGT, R1, R2, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"JMP_JSGT_X: Signed jump: if (-1 > -1) return 0",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_LD_IMM64(R1, -1),
|
|
|
|
BPF_LD_IMM64(R2, -1),
|
|
|
|
BPF_JMP_REG(BPF_JSGT, R1, R2, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
bpf: add BPF_J{LT,LE,SLT,SLE} instructions
Currently, eBPF only understands BPF_JGT (>), BPF_JGE (>=),
BPF_JSGT (s>), BPF_JSGE (s>=) instructions, this means that
particularly *JLT/*JLE counterparts involving immediates need
to be rewritten from e.g. X < [IMM] by swapping arguments into
[IMM] > X, meaning the immediate first is required to be loaded
into a register Y := [IMM], such that then we can compare with
Y > X. Note that the destination operand is always required to
be a register.
This has the downside of having unnecessarily increased register
pressure, meaning complex program would need to spill other
registers temporarily to stack in order to obtain an unused
register for the [IMM]. Loading to registers will thus also
affect state pruning since we need to account for that register
use and potentially those registers that had to be spilled/filled
again. As a consequence slightly more stack space might have
been used due to spilling, and BPF programs are a bit longer
due to extra code involving the register load and potentially
required spill/fills.
Thus, add BPF_JLT (<), BPF_JLE (<=), BPF_JSLT (s<), BPF_JSLE (s<=)
counterparts to the eBPF instruction set. Modifying LLVM to
remove the NegateCC() workaround in a PoC patch at [1] and
allowing it to also emit the new instructions resulted in
cilium's BPF programs that are injected into the fast-path to
have a reduced program length in the range of 2-3% (e.g.
accumulated main and tail call sections from one of the object
file reduced from 4864 to 4729 insns), reduced complexity in
the range of 10-30% (e.g. accumulated sections reduced in one
of the cases from 116432 to 88428 insns), and reduced stack
usage in the range of 1-5% (e.g. accumulated sections from one
of the object files reduced from 824 to 784b).
The modification for LLVM will be incorporated in a backwards
compatible way. Plan is for LLVM to have i) a target specific
option to offer a possibility to explicitly enable the extension
by the user (as we have with -m target specific extensions today
for various CPU insns), and ii) have the kernel checked for
presence of the extensions and enable them transparently when
the user is selecting more aggressive options such as -march=native
in a bpf target context. (Other frontends generating BPF byte
code, e.g. ply can probe the kernel directly for its code
generation.)
[1] https://github.com/borkmann/llvm/tree/bpf-insns
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-08-10 06:39:55 +07:00
|
|
|
/* BPF_JMP | BPF_JSLT | BPF_X */
|
|
|
|
{
|
|
|
|
"JMP_JSLT_X: Signed jump: if (-2 < -1) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, -1),
|
|
|
|
BPF_LD_IMM64(R2, -2),
|
|
|
|
BPF_JMP_REG(BPF_JSLT, R2, R1, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"JMP_JSLT_X: Signed jump: if (-1 < -1) return 0",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_LD_IMM64(R1, -1),
|
|
|
|
BPF_LD_IMM64(R2, -1),
|
|
|
|
BPF_JMP_REG(BPF_JSLT, R1, R2, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
2015-05-12 12:22:44 +07:00
|
|
|
/* BPF_JMP | BPF_JSGE | BPF_X */
|
|
|
|
{
|
|
|
|
"JMP_JSGE_X: Signed jump: if (-1 >= -2) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, -1),
|
|
|
|
BPF_LD_IMM64(R2, -2),
|
|
|
|
BPF_JMP_REG(BPF_JSGE, R1, R2, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"JMP_JSGE_X: Signed jump: if (-1 >= -1) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, -1),
|
|
|
|
BPF_LD_IMM64(R2, -1),
|
|
|
|
BPF_JMP_REG(BPF_JSGE, R1, R2, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
bpf: add BPF_J{LT,LE,SLT,SLE} instructions
Currently, eBPF only understands BPF_JGT (>), BPF_JGE (>=),
BPF_JSGT (s>), BPF_JSGE (s>=) instructions, this means that
particularly *JLT/*JLE counterparts involving immediates need
to be rewritten from e.g. X < [IMM] by swapping arguments into
[IMM] > X, meaning the immediate first is required to be loaded
into a register Y := [IMM], such that then we can compare with
Y > X. Note that the destination operand is always required to
be a register.
This has the downside of having unnecessarily increased register
pressure, meaning complex program would need to spill other
registers temporarily to stack in order to obtain an unused
register for the [IMM]. Loading to registers will thus also
affect state pruning since we need to account for that register
use and potentially those registers that had to be spilled/filled
again. As a consequence slightly more stack space might have
been used due to spilling, and BPF programs are a bit longer
due to extra code involving the register load and potentially
required spill/fills.
Thus, add BPF_JLT (<), BPF_JLE (<=), BPF_JSLT (s<), BPF_JSLE (s<=)
counterparts to the eBPF instruction set. Modifying LLVM to
remove the NegateCC() workaround in a PoC patch at [1] and
allowing it to also emit the new instructions resulted in
cilium's BPF programs that are injected into the fast-path to
have a reduced program length in the range of 2-3% (e.g.
accumulated main and tail call sections from one of the object
file reduced from 4864 to 4729 insns), reduced complexity in
the range of 10-30% (e.g. accumulated sections reduced in one
of the cases from 116432 to 88428 insns), and reduced stack
usage in the range of 1-5% (e.g. accumulated sections from one
of the object files reduced from 824 to 784b).
The modification for LLVM will be incorporated in a backwards
compatible way. Plan is for LLVM to have i) a target specific
option to offer a possibility to explicitly enable the extension
by the user (as we have with -m target specific extensions today
for various CPU insns), and ii) have the kernel checked for
presence of the extensions and enable them transparently when
the user is selecting more aggressive options such as -march=native
in a bpf target context. (Other frontends generating BPF byte
code, e.g. ply can probe the kernel directly for its code
generation.)
[1] https://github.com/borkmann/llvm/tree/bpf-insns
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-08-10 06:39:55 +07:00
|
|
|
/* BPF_JMP | BPF_JSLE | BPF_X */
|
|
|
|
{
|
|
|
|
"JMP_JSLE_X: Signed jump: if (-2 <= -1) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, -1),
|
|
|
|
BPF_LD_IMM64(R2, -2),
|
|
|
|
BPF_JMP_REG(BPF_JSLE, R2, R1, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"JMP_JSLE_X: Signed jump: if (-1 <= -1) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, -1),
|
|
|
|
BPF_LD_IMM64(R2, -1),
|
|
|
|
BPF_JMP_REG(BPF_JSLE, R1, R2, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
2015-05-12 12:22:44 +07:00
|
|
|
/* BPF_JMP | BPF_JGT | BPF_X */
|
|
|
|
{
|
|
|
|
"JMP_JGT_X: if (3 > 2) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 3),
|
|
|
|
BPF_LD_IMM64(R2, 2),
|
|
|
|
BPF_JMP_REG(BPF_JGT, R1, R2, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
2016-04-05 17:02:54 +07:00
|
|
|
{
|
|
|
|
"JMP_JGT_X: Unsigned jump: if (-1 > 1) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, -1),
|
|
|
|
BPF_LD_IMM64(R2, 1),
|
|
|
|
BPF_JMP_REG(BPF_JGT, R1, R2, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
bpf: add BPF_J{LT,LE,SLT,SLE} instructions
Currently, eBPF only understands BPF_JGT (>), BPF_JGE (>=),
BPF_JSGT (s>), BPF_JSGE (s>=) instructions, this means that
particularly *JLT/*JLE counterparts involving immediates need
to be rewritten from e.g. X < [IMM] by swapping arguments into
[IMM] > X, meaning the immediate first is required to be loaded
into a register Y := [IMM], such that then we can compare with
Y > X. Note that the destination operand is always required to
be a register.
This has the downside of having unnecessarily increased register
pressure, meaning complex program would need to spill other
registers temporarily to stack in order to obtain an unused
register for the [IMM]. Loading to registers will thus also
affect state pruning since we need to account for that register
use and potentially those registers that had to be spilled/filled
again. As a consequence slightly more stack space might have
been used due to spilling, and BPF programs are a bit longer
due to extra code involving the register load and potentially
required spill/fills.
Thus, add BPF_JLT (<), BPF_JLE (<=), BPF_JSLT (s<), BPF_JSLE (s<=)
counterparts to the eBPF instruction set. Modifying LLVM to
remove the NegateCC() workaround in a PoC patch at [1] and
allowing it to also emit the new instructions resulted in
cilium's BPF programs that are injected into the fast-path to
have a reduced program length in the range of 2-3% (e.g.
accumulated main and tail call sections from one of the object
file reduced from 4864 to 4729 insns), reduced complexity in
the range of 10-30% (e.g. accumulated sections reduced in one
of the cases from 116432 to 88428 insns), and reduced stack
usage in the range of 1-5% (e.g. accumulated sections from one
of the object files reduced from 824 to 784b).
The modification for LLVM will be incorporated in a backwards
compatible way. Plan is for LLVM to have i) a target specific
option to offer a possibility to explicitly enable the extension
by the user (as we have with -m target specific extensions today
for various CPU insns), and ii) have the kernel checked for
presence of the extensions and enable them transparently when
the user is selecting more aggressive options such as -march=native
in a bpf target context. (Other frontends generating BPF byte
code, e.g. ply can probe the kernel directly for its code
generation.)
[1] https://github.com/borkmann/llvm/tree/bpf-insns
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-08-10 06:39:55 +07:00
|
|
|
/* BPF_JMP | BPF_JLT | BPF_X */
|
|
|
|
{
|
|
|
|
"JMP_JLT_X: if (2 < 3) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 3),
|
|
|
|
BPF_LD_IMM64(R2, 2),
|
|
|
|
BPF_JMP_REG(BPF_JLT, R2, R1, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"JMP_JLT_X: Unsigned jump: if (1 < -1) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, -1),
|
|
|
|
BPF_LD_IMM64(R2, 1),
|
|
|
|
BPF_JMP_REG(BPF_JLT, R2, R1, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
2015-05-12 12:22:44 +07:00
|
|
|
/* BPF_JMP | BPF_JGE | BPF_X */
|
|
|
|
{
|
|
|
|
"JMP_JGE_X: if (3 >= 2) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 3),
|
|
|
|
BPF_LD_IMM64(R2, 2),
|
|
|
|
BPF_JMP_REG(BPF_JGE, R1, R2, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"JMP_JGE_X: if (3 >= 3) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 3),
|
|
|
|
BPF_LD_IMM64(R2, 3),
|
|
|
|
BPF_JMP_REG(BPF_JGE, R1, R2, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
bpf: add BPF_J{LT,LE,SLT,SLE} instructions
Currently, eBPF only understands BPF_JGT (>), BPF_JGE (>=),
BPF_JSGT (s>), BPF_JSGE (s>=) instructions, this means that
particularly *JLT/*JLE counterparts involving immediates need
to be rewritten from e.g. X < [IMM] by swapping arguments into
[IMM] > X, meaning the immediate first is required to be loaded
into a register Y := [IMM], such that then we can compare with
Y > X. Note that the destination operand is always required to
be a register.
This has the downside of having unnecessarily increased register
pressure, meaning complex program would need to spill other
registers temporarily to stack in order to obtain an unused
register for the [IMM]. Loading to registers will thus also
affect state pruning since we need to account for that register
use and potentially those registers that had to be spilled/filled
again. As a consequence slightly more stack space might have
been used due to spilling, and BPF programs are a bit longer
due to extra code involving the register load and potentially
required spill/fills.
Thus, add BPF_JLT (<), BPF_JLE (<=), BPF_JSLT (s<), BPF_JSLE (s<=)
counterparts to the eBPF instruction set. Modifying LLVM to
remove the NegateCC() workaround in a PoC patch at [1] and
allowing it to also emit the new instructions resulted in
cilium's BPF programs that are injected into the fast-path to
have a reduced program length in the range of 2-3% (e.g.
accumulated main and tail call sections from one of the object
file reduced from 4864 to 4729 insns), reduced complexity in
the range of 10-30% (e.g. accumulated sections reduced in one
of the cases from 116432 to 88428 insns), and reduced stack
usage in the range of 1-5% (e.g. accumulated sections from one
of the object files reduced from 824 to 784b).
The modification for LLVM will be incorporated in a backwards
compatible way. Plan is for LLVM to have i) a target specific
option to offer a possibility to explicitly enable the extension
by the user (as we have with -m target specific extensions today
for various CPU insns), and ii) have the kernel checked for
presence of the extensions and enable them transparently when
the user is selecting more aggressive options such as -march=native
in a bpf target context. (Other frontends generating BPF byte
code, e.g. ply can probe the kernel directly for its code
generation.)
[1] https://github.com/borkmann/llvm/tree/bpf-insns
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-08-10 06:39:55 +07:00
|
|
|
/* BPF_JMP | BPF_JLE | BPF_X */
|
|
|
|
{
|
|
|
|
"JMP_JLE_X: if (2 <= 3) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 3),
|
|
|
|
BPF_LD_IMM64(R2, 2),
|
|
|
|
BPF_JMP_REG(BPF_JLE, R2, R1, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"JMP_JLE_X: if (3 <= 3) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 3),
|
|
|
|
BPF_LD_IMM64(R2, 3),
|
|
|
|
BPF_JMP_REG(BPF_JLE, R1, R2, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
bpf, arm64: fix jit branch offset related to ldimm64
When the instruction right before the branch destination is
a 64 bit load immediate, we currently calculate the wrong
jump offset in the ctx->offset[] array as we only account
one instruction slot for the 64 bit load immediate although
it uses two BPF instructions. Fix it up by setting the offset
into the right slot after we incremented the index.
Before (ldimm64 test 1):
[...]
00000020: 52800007 mov w7, #0x0 // #0
00000024: d2800060 mov x0, #0x3 // #3
00000028: d2800041 mov x1, #0x2 // #2
0000002c: eb01001f cmp x0, x1
00000030: 54ffff82 b.cs 0x00000020
00000034: d29fffe7 mov x7, #0xffff // #65535
00000038: f2bfffe7 movk x7, #0xffff, lsl #16
0000003c: f2dfffe7 movk x7, #0xffff, lsl #32
00000040: f2ffffe7 movk x7, #0xffff, lsl #48
00000044: d29dddc7 mov x7, #0xeeee // #61166
00000048: f2bdddc7 movk x7, #0xeeee, lsl #16
0000004c: f2ddddc7 movk x7, #0xeeee, lsl #32
00000050: f2fdddc7 movk x7, #0xeeee, lsl #48
[...]
After (ldimm64 test 1):
[...]
00000020: 52800007 mov w7, #0x0 // #0
00000024: d2800060 mov x0, #0x3 // #3
00000028: d2800041 mov x1, #0x2 // #2
0000002c: eb01001f cmp x0, x1
00000030: 540000a2 b.cs 0x00000044
00000034: d29fffe7 mov x7, #0xffff // #65535
00000038: f2bfffe7 movk x7, #0xffff, lsl #16
0000003c: f2dfffe7 movk x7, #0xffff, lsl #32
00000040: f2ffffe7 movk x7, #0xffff, lsl #48
00000044: d29dddc7 mov x7, #0xeeee // #61166
00000048: f2bdddc7 movk x7, #0xeeee, lsl #16
0000004c: f2ddddc7 movk x7, #0xeeee, lsl #32
00000050: f2fdddc7 movk x7, #0xeeee, lsl #48
[...]
Also, add a couple of test cases to make sure JITs pass
this test. Tested on Cavium ThunderX ARMv8. The added
test cases all pass after the fix.
Fixes: 8eee539ddea0 ("arm64: bpf: fix out-of-bounds read in bpf2a64_offset()")
Reported-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Cc: Xi Wang <xi.wang@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-05-03 01:34:54 +07:00
|
|
|
{
|
|
|
|
/* Mainly testing JIT + imm64 here. */
|
|
|
|
"JMP_JGE_X: ldimm64 test 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 3),
|
|
|
|
BPF_LD_IMM64(R2, 2),
|
|
|
|
BPF_JMP_REG(BPF_JGE, R1, R2, 2),
|
2017-05-03 18:31:04 +07:00
|
|
|
BPF_LD_IMM64(R0, 0xffffffffffffffffULL),
|
|
|
|
BPF_LD_IMM64(R0, 0xeeeeeeeeeeeeeeeeULL),
|
bpf, arm64: fix jit branch offset related to ldimm64
When the instruction right before the branch destination is
a 64 bit load immediate, we currently calculate the wrong
jump offset in the ctx->offset[] array as we only account
one instruction slot for the 64 bit load immediate although
it uses two BPF instructions. Fix it up by setting the offset
into the right slot after we incremented the index.
Before (ldimm64 test 1):
[...]
00000020: 52800007 mov w7, #0x0 // #0
00000024: d2800060 mov x0, #0x3 // #3
00000028: d2800041 mov x1, #0x2 // #2
0000002c: eb01001f cmp x0, x1
00000030: 54ffff82 b.cs 0x00000020
00000034: d29fffe7 mov x7, #0xffff // #65535
00000038: f2bfffe7 movk x7, #0xffff, lsl #16
0000003c: f2dfffe7 movk x7, #0xffff, lsl #32
00000040: f2ffffe7 movk x7, #0xffff, lsl #48
00000044: d29dddc7 mov x7, #0xeeee // #61166
00000048: f2bdddc7 movk x7, #0xeeee, lsl #16
0000004c: f2ddddc7 movk x7, #0xeeee, lsl #32
00000050: f2fdddc7 movk x7, #0xeeee, lsl #48
[...]
After (ldimm64 test 1):
[...]
00000020: 52800007 mov w7, #0x0 // #0
00000024: d2800060 mov x0, #0x3 // #3
00000028: d2800041 mov x1, #0x2 // #2
0000002c: eb01001f cmp x0, x1
00000030: 540000a2 b.cs 0x00000044
00000034: d29fffe7 mov x7, #0xffff // #65535
00000038: f2bfffe7 movk x7, #0xffff, lsl #16
0000003c: f2dfffe7 movk x7, #0xffff, lsl #32
00000040: f2ffffe7 movk x7, #0xffff, lsl #48
00000044: d29dddc7 mov x7, #0xeeee // #61166
00000048: f2bdddc7 movk x7, #0xeeee, lsl #16
0000004c: f2ddddc7 movk x7, #0xeeee, lsl #32
00000050: f2fdddc7 movk x7, #0xeeee, lsl #48
[...]
Also, add a couple of test cases to make sure JITs pass
this test. Tested on Cavium ThunderX ARMv8. The added
test cases all pass after the fix.
Fixes: 8eee539ddea0 ("arm64: bpf: fix out-of-bounds read in bpf2a64_offset()")
Reported-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Cc: Xi Wang <xi.wang@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-05-03 01:34:54 +07:00
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xeeeeeeeeU } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"JMP_JGE_X: ldimm64 test 2",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 3),
|
|
|
|
BPF_LD_IMM64(R2, 2),
|
|
|
|
BPF_JMP_REG(BPF_JGE, R1, R2, 0),
|
2017-05-03 18:31:04 +07:00
|
|
|
BPF_LD_IMM64(R0, 0xffffffffffffffffULL),
|
bpf, arm64: fix jit branch offset related to ldimm64
When the instruction right before the branch destination is
a 64 bit load immediate, we currently calculate the wrong
jump offset in the ctx->offset[] array as we only account
one instruction slot for the 64 bit load immediate although
it uses two BPF instructions. Fix it up by setting the offset
into the right slot after we incremented the index.
Before (ldimm64 test 1):
[...]
00000020: 52800007 mov w7, #0x0 // #0
00000024: d2800060 mov x0, #0x3 // #3
00000028: d2800041 mov x1, #0x2 // #2
0000002c: eb01001f cmp x0, x1
00000030: 54ffff82 b.cs 0x00000020
00000034: d29fffe7 mov x7, #0xffff // #65535
00000038: f2bfffe7 movk x7, #0xffff, lsl #16
0000003c: f2dfffe7 movk x7, #0xffff, lsl #32
00000040: f2ffffe7 movk x7, #0xffff, lsl #48
00000044: d29dddc7 mov x7, #0xeeee // #61166
00000048: f2bdddc7 movk x7, #0xeeee, lsl #16
0000004c: f2ddddc7 movk x7, #0xeeee, lsl #32
00000050: f2fdddc7 movk x7, #0xeeee, lsl #48
[...]
After (ldimm64 test 1):
[...]
00000020: 52800007 mov w7, #0x0 // #0
00000024: d2800060 mov x0, #0x3 // #3
00000028: d2800041 mov x1, #0x2 // #2
0000002c: eb01001f cmp x0, x1
00000030: 540000a2 b.cs 0x00000044
00000034: d29fffe7 mov x7, #0xffff // #65535
00000038: f2bfffe7 movk x7, #0xffff, lsl #16
0000003c: f2dfffe7 movk x7, #0xffff, lsl #32
00000040: f2ffffe7 movk x7, #0xffff, lsl #48
00000044: d29dddc7 mov x7, #0xeeee // #61166
00000048: f2bdddc7 movk x7, #0xeeee, lsl #16
0000004c: f2ddddc7 movk x7, #0xeeee, lsl #32
00000050: f2fdddc7 movk x7, #0xeeee, lsl #48
[...]
Also, add a couple of test cases to make sure JITs pass
this test. Tested on Cavium ThunderX ARMv8. The added
test cases all pass after the fix.
Fixes: 8eee539ddea0 ("arm64: bpf: fix out-of-bounds read in bpf2a64_offset()")
Reported-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Cc: Xi Wang <xi.wang@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-05-03 01:34:54 +07:00
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xffffffffU } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"JMP_JGE_X: ldimm64 test 3",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_LD_IMM64(R1, 3),
|
|
|
|
BPF_LD_IMM64(R2, 2),
|
|
|
|
BPF_JMP_REG(BPF_JGE, R1, R2, 4),
|
2017-05-03 18:31:04 +07:00
|
|
|
BPF_LD_IMM64(R0, 0xffffffffffffffffULL),
|
|
|
|
BPF_LD_IMM64(R0, 0xeeeeeeeeeeeeeeeeULL),
|
bpf, arm64: fix jit branch offset related to ldimm64
When the instruction right before the branch destination is
a 64 bit load immediate, we currently calculate the wrong
jump offset in the ctx->offset[] array as we only account
one instruction slot for the 64 bit load immediate although
it uses two BPF instructions. Fix it up by setting the offset
into the right slot after we incremented the index.
Before (ldimm64 test 1):
[...]
00000020: 52800007 mov w7, #0x0 // #0
00000024: d2800060 mov x0, #0x3 // #3
00000028: d2800041 mov x1, #0x2 // #2
0000002c: eb01001f cmp x0, x1
00000030: 54ffff82 b.cs 0x00000020
00000034: d29fffe7 mov x7, #0xffff // #65535
00000038: f2bfffe7 movk x7, #0xffff, lsl #16
0000003c: f2dfffe7 movk x7, #0xffff, lsl #32
00000040: f2ffffe7 movk x7, #0xffff, lsl #48
00000044: d29dddc7 mov x7, #0xeeee // #61166
00000048: f2bdddc7 movk x7, #0xeeee, lsl #16
0000004c: f2ddddc7 movk x7, #0xeeee, lsl #32
00000050: f2fdddc7 movk x7, #0xeeee, lsl #48
[...]
After (ldimm64 test 1):
[...]
00000020: 52800007 mov w7, #0x0 // #0
00000024: d2800060 mov x0, #0x3 // #3
00000028: d2800041 mov x1, #0x2 // #2
0000002c: eb01001f cmp x0, x1
00000030: 540000a2 b.cs 0x00000044
00000034: d29fffe7 mov x7, #0xffff // #65535
00000038: f2bfffe7 movk x7, #0xffff, lsl #16
0000003c: f2dfffe7 movk x7, #0xffff, lsl #32
00000040: f2ffffe7 movk x7, #0xffff, lsl #48
00000044: d29dddc7 mov x7, #0xeeee // #61166
00000048: f2bdddc7 movk x7, #0xeeee, lsl #16
0000004c: f2ddddc7 movk x7, #0xeeee, lsl #32
00000050: f2fdddc7 movk x7, #0xeeee, lsl #48
[...]
Also, add a couple of test cases to make sure JITs pass
this test. Tested on Cavium ThunderX ARMv8. The added
test cases all pass after the fix.
Fixes: 8eee539ddea0 ("arm64: bpf: fix out-of-bounds read in bpf2a64_offset()")
Reported-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Cc: Xi Wang <xi.wang@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-05-03 01:34:54 +07:00
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
bpf: add BPF_J{LT,LE,SLT,SLE} instructions
Currently, eBPF only understands BPF_JGT (>), BPF_JGE (>=),
BPF_JSGT (s>), BPF_JSGE (s>=) instructions, this means that
particularly *JLT/*JLE counterparts involving immediates need
to be rewritten from e.g. X < [IMM] by swapping arguments into
[IMM] > X, meaning the immediate first is required to be loaded
into a register Y := [IMM], such that then we can compare with
Y > X. Note that the destination operand is always required to
be a register.
This has the downside of having unnecessarily increased register
pressure, meaning complex program would need to spill other
registers temporarily to stack in order to obtain an unused
register for the [IMM]. Loading to registers will thus also
affect state pruning since we need to account for that register
use and potentially those registers that had to be spilled/filled
again. As a consequence slightly more stack space might have
been used due to spilling, and BPF programs are a bit longer
due to extra code involving the register load and potentially
required spill/fills.
Thus, add BPF_JLT (<), BPF_JLE (<=), BPF_JSLT (s<), BPF_JSLE (s<=)
counterparts to the eBPF instruction set. Modifying LLVM to
remove the NegateCC() workaround in a PoC patch at [1] and
allowing it to also emit the new instructions resulted in
cilium's BPF programs that are injected into the fast-path to
have a reduced program length in the range of 2-3% (e.g.
accumulated main and tail call sections from one of the object
file reduced from 4864 to 4729 insns), reduced complexity in
the range of 10-30% (e.g. accumulated sections reduced in one
of the cases from 116432 to 88428 insns), and reduced stack
usage in the range of 1-5% (e.g. accumulated sections from one
of the object files reduced from 824 to 784b).
The modification for LLVM will be incorporated in a backwards
compatible way. Plan is for LLVM to have i) a target specific
option to offer a possibility to explicitly enable the extension
by the user (as we have with -m target specific extensions today
for various CPU insns), and ii) have the kernel checked for
presence of the extensions and enable them transparently when
the user is selecting more aggressive options such as -march=native
in a bpf target context. (Other frontends generating BPF byte
code, e.g. ply can probe the kernel directly for its code
generation.)
[1] https://github.com/borkmann/llvm/tree/bpf-insns
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-08-10 06:39:55 +07:00
|
|
|
{
|
|
|
|
"JMP_JLE_X: ldimm64 test 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 3),
|
|
|
|
BPF_LD_IMM64(R2, 2),
|
|
|
|
BPF_JMP_REG(BPF_JLE, R2, R1, 2),
|
|
|
|
BPF_LD_IMM64(R0, 0xffffffffffffffffULL),
|
|
|
|
BPF_LD_IMM64(R0, 0xeeeeeeeeeeeeeeeeULL),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xeeeeeeeeU } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"JMP_JLE_X: ldimm64 test 2",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 3),
|
|
|
|
BPF_LD_IMM64(R2, 2),
|
|
|
|
BPF_JMP_REG(BPF_JLE, R2, R1, 0),
|
|
|
|
BPF_LD_IMM64(R0, 0xffffffffffffffffULL),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xffffffffU } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"JMP_JLE_X: ldimm64 test 3",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_LD_IMM64(R1, 3),
|
|
|
|
BPF_LD_IMM64(R2, 2),
|
|
|
|
BPF_JMP_REG(BPF_JLE, R2, R1, 4),
|
|
|
|
BPF_LD_IMM64(R0, 0xffffffffffffffffULL),
|
|
|
|
BPF_LD_IMM64(R0, 0xeeeeeeeeeeeeeeeeULL),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
2015-05-12 12:22:44 +07:00
|
|
|
/* BPF_JMP | BPF_JNE | BPF_X */
|
|
|
|
{
|
|
|
|
"JMP_JNE_X: if (3 != 2) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 3),
|
|
|
|
BPF_LD_IMM64(R2, 2),
|
|
|
|
BPF_JMP_REG(BPF_JNE, R1, R2, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
/* BPF_JMP | BPF_JEQ | BPF_X */
|
|
|
|
{
|
|
|
|
"JMP_JEQ_X: if (3 == 3) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 3),
|
|
|
|
BPF_LD_IMM64(R2, 3),
|
|
|
|
BPF_JMP_REG(BPF_JEQ, R1, R2, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
/* BPF_JMP | BPF_JSET | BPF_X */
|
|
|
|
{
|
|
|
|
"JMP_JSET_X: if (0x3 & 0x2) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 3),
|
|
|
|
BPF_LD_IMM64(R2, 2),
|
2016-04-05 17:02:53 +07:00
|
|
|
BPF_JMP_REG(BPF_JSET, R1, R2, 1),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"JMP_JSET_X: if (0x3 & 0xffffffff) return 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 0),
|
|
|
|
BPF_LD_IMM64(R1, 3),
|
|
|
|
BPF_LD_IMM64(R2, 0xffffffff),
|
2016-04-05 17:02:53 +07:00
|
|
|
BPF_JMP_REG(BPF_JSET, R1, R2, 1),
|
2015-05-12 12:22:44 +07:00
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
2015-05-27 03:35:43 +07:00
|
|
|
{
|
|
|
|
"JMP_JA: Jump, gap, jump, ...",
|
|
|
|
{ },
|
|
|
|
CLASSIC | FLAG_NO_DATA,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xababcbac } },
|
|
|
|
.fill_helper = bpf_fill_ja,
|
|
|
|
},
|
2015-05-13 18:12:43 +07:00
|
|
|
{ /* Mainly checking JIT here. */
|
|
|
|
"BPF_MAXINSNS: Maximum possible literals",
|
|
|
|
{ },
|
|
|
|
CLASSIC | FLAG_NO_DATA,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xffffffff } },
|
|
|
|
.fill_helper = bpf_fill_maxinsns1,
|
|
|
|
},
|
|
|
|
{ /* Mainly checking JIT here. */
|
|
|
|
"BPF_MAXINSNS: Single literal",
|
|
|
|
{ },
|
|
|
|
CLASSIC | FLAG_NO_DATA,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xfefefefe } },
|
|
|
|
.fill_helper = bpf_fill_maxinsns2,
|
|
|
|
},
|
|
|
|
{ /* Mainly checking JIT here. */
|
|
|
|
"BPF_MAXINSNS: Run/add until end",
|
|
|
|
{ },
|
|
|
|
CLASSIC | FLAG_NO_DATA,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0x947bf368 } },
|
|
|
|
.fill_helper = bpf_fill_maxinsns3,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"BPF_MAXINSNS: Too many instructions",
|
|
|
|
{ },
|
|
|
|
CLASSIC | FLAG_NO_DATA | FLAG_EXPECTED_FAIL,
|
|
|
|
{ },
|
|
|
|
{ },
|
|
|
|
.fill_helper = bpf_fill_maxinsns4,
|
bpf: fix selftests/bpf test_kmod.sh failure when CONFIG_BPF_JIT_ALWAYS_ON=y
With CONFIG_BPF_JIT_ALWAYS_ON is defined in the config file,
tools/testing/selftests/bpf/test_kmod.sh failed like below:
[root@localhost bpf]# ./test_kmod.sh
sysctl: setting key "net.core.bpf_jit_enable": Invalid argument
[ JIT enabled:0 hardened:0 ]
[ 132.175681] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 132.458834] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:0 ]
[ 133.456025] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 133.730935] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:1 ]
[ 134.769730] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 135.050864] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:2 ]
[ 136.442882] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 136.821810] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[root@localhost bpf]#
The test_kmod.sh load/remove test_bpf.ko multiple times with different
settings for sysctl net.core.bpf_jit_{enable,harden}. The failed test #297
of test_bpf.ko is designed such that JIT always fails.
Commit 290af86629b2 (bpf: introduce BPF_JIT_ALWAYS_ON config)
introduced the following tightening logic:
...
if (!bpf_prog_is_dev_bound(fp->aux)) {
fp = bpf_int_jit_compile(fp);
#ifdef CONFIG_BPF_JIT_ALWAYS_ON
if (!fp->jited) {
*err = -ENOTSUPP;
return fp;
}
#endif
...
With this logic, Test #297 always gets return value -ENOTSUPP
when CONFIG_BPF_JIT_ALWAYS_ON is defined, causing the test failure.
This patch fixed the failure by marking Test #297 as expected failure
when CONFIG_BPF_JIT_ALWAYS_ON is defined.
Fixes: 290af86629b2 (bpf: introduce BPF_JIT_ALWAYS_ON config)
Signed-off-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
2018-02-03 13:37:15 +07:00
|
|
|
.expected_errcode = -EINVAL,
|
2015-05-13 18:12:43 +07:00
|
|
|
},
|
|
|
|
{ /* Mainly checking JIT here. */
|
|
|
|
"BPF_MAXINSNS: Very long jump",
|
|
|
|
{ },
|
|
|
|
CLASSIC | FLAG_NO_DATA,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xabababab } },
|
|
|
|
.fill_helper = bpf_fill_maxinsns5,
|
|
|
|
},
|
|
|
|
{ /* Mainly checking JIT here. */
|
|
|
|
"BPF_MAXINSNS: Ctx heavy transformations",
|
|
|
|
{ },
|
|
|
|
CLASSIC,
|
|
|
|
{ },
|
|
|
|
{
|
|
|
|
{ 1, !!(SKB_VLAN_TCI & VLAN_TAG_PRESENT) },
|
|
|
|
{ 10, !!(SKB_VLAN_TCI & VLAN_TAG_PRESENT) }
|
|
|
|
},
|
|
|
|
.fill_helper = bpf_fill_maxinsns6,
|
|
|
|
},
|
|
|
|
{ /* Mainly checking JIT here. */
|
|
|
|
"BPF_MAXINSNS: Call heavy transformations",
|
|
|
|
{ },
|
|
|
|
CLASSIC | FLAG_NO_DATA,
|
|
|
|
{ },
|
|
|
|
{ { 1, 0 }, { 10, 0 } },
|
|
|
|
.fill_helper = bpf_fill_maxinsns7,
|
|
|
|
},
|
|
|
|
{ /* Mainly checking JIT here. */
|
|
|
|
"BPF_MAXINSNS: Jump heavy test",
|
|
|
|
{ },
|
|
|
|
CLASSIC | FLAG_NO_DATA,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xffffffff } },
|
|
|
|
.fill_helper = bpf_fill_maxinsns8,
|
|
|
|
},
|
2015-05-23 06:10:07 +07:00
|
|
|
{ /* Mainly checking JIT here. */
|
|
|
|
"BPF_MAXINSNS: Very long jump backwards",
|
|
|
|
{ },
|
|
|
|
INTERNAL | FLAG_NO_DATA,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xcbababab } },
|
|
|
|
.fill_helper = bpf_fill_maxinsns9,
|
|
|
|
},
|
|
|
|
{ /* Mainly checking JIT here. */
|
|
|
|
"BPF_MAXINSNS: Edge hopping nuthouse",
|
|
|
|
{ },
|
|
|
|
INTERNAL | FLAG_NO_DATA,
|
|
|
|
{ },
|
|
|
|
{ { 0, 0xabababac } },
|
|
|
|
.fill_helper = bpf_fill_maxinsns10,
|
|
|
|
},
|
2015-05-27 03:35:43 +07:00
|
|
|
{
|
|
|
|
"BPF_MAXINSNS: Jump, gap, jump, ...",
|
|
|
|
{ },
|
2018-03-20 19:58:51 +07:00
|
|
|
#if defined(CONFIG_BPF_JIT_ALWAYS_ON) && defined(CONFIG_X86)
|
bpf: fix selftests/bpf test_kmod.sh failure when CONFIG_BPF_JIT_ALWAYS_ON=y
With CONFIG_BPF_JIT_ALWAYS_ON is defined in the config file,
tools/testing/selftests/bpf/test_kmod.sh failed like below:
[root@localhost bpf]# ./test_kmod.sh
sysctl: setting key "net.core.bpf_jit_enable": Invalid argument
[ JIT enabled:0 hardened:0 ]
[ 132.175681] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 132.458834] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:0 ]
[ 133.456025] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 133.730935] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:1 ]
[ 134.769730] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 135.050864] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:2 ]
[ 136.442882] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 136.821810] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[root@localhost bpf]#
The test_kmod.sh load/remove test_bpf.ko multiple times with different
settings for sysctl net.core.bpf_jit_{enable,harden}. The failed test #297
of test_bpf.ko is designed such that JIT always fails.
Commit 290af86629b2 (bpf: introduce BPF_JIT_ALWAYS_ON config)
introduced the following tightening logic:
...
if (!bpf_prog_is_dev_bound(fp->aux)) {
fp = bpf_int_jit_compile(fp);
#ifdef CONFIG_BPF_JIT_ALWAYS_ON
if (!fp->jited) {
*err = -ENOTSUPP;
return fp;
}
#endif
...
With this logic, Test #297 always gets return value -ENOTSUPP
when CONFIG_BPF_JIT_ALWAYS_ON is defined, causing the test failure.
This patch fixed the failure by marking Test #297 as expected failure
when CONFIG_BPF_JIT_ALWAYS_ON is defined.
Fixes: 290af86629b2 (bpf: introduce BPF_JIT_ALWAYS_ON config)
Signed-off-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
2018-02-03 13:37:15 +07:00
|
|
|
CLASSIC | FLAG_NO_DATA | FLAG_EXPECTED_FAIL,
|
|
|
|
#else
|
2015-05-27 03:35:43 +07:00
|
|
|
CLASSIC | FLAG_NO_DATA,
|
bpf: fix selftests/bpf test_kmod.sh failure when CONFIG_BPF_JIT_ALWAYS_ON=y
With CONFIG_BPF_JIT_ALWAYS_ON is defined in the config file,
tools/testing/selftests/bpf/test_kmod.sh failed like below:
[root@localhost bpf]# ./test_kmod.sh
sysctl: setting key "net.core.bpf_jit_enable": Invalid argument
[ JIT enabled:0 hardened:0 ]
[ 132.175681] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 132.458834] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:0 ]
[ 133.456025] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 133.730935] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:1 ]
[ 134.769730] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 135.050864] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:2 ]
[ 136.442882] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 136.821810] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[root@localhost bpf]#
The test_kmod.sh load/remove test_bpf.ko multiple times with different
settings for sysctl net.core.bpf_jit_{enable,harden}. The failed test #297
of test_bpf.ko is designed such that JIT always fails.
Commit 290af86629b2 (bpf: introduce BPF_JIT_ALWAYS_ON config)
introduced the following tightening logic:
...
if (!bpf_prog_is_dev_bound(fp->aux)) {
fp = bpf_int_jit_compile(fp);
#ifdef CONFIG_BPF_JIT_ALWAYS_ON
if (!fp->jited) {
*err = -ENOTSUPP;
return fp;
}
#endif
...
With this logic, Test #297 always gets return value -ENOTSUPP
when CONFIG_BPF_JIT_ALWAYS_ON is defined, causing the test failure.
This patch fixed the failure by marking Test #297 as expected failure
when CONFIG_BPF_JIT_ALWAYS_ON is defined.
Fixes: 290af86629b2 (bpf: introduce BPF_JIT_ALWAYS_ON config)
Signed-off-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
2018-02-03 13:37:15 +07:00
|
|
|
#endif
|
2015-05-27 03:35:43 +07:00
|
|
|
{ },
|
|
|
|
{ { 0, 0xababcbac } },
|
|
|
|
.fill_helper = bpf_fill_maxinsns11,
|
bpf: fix selftests/bpf test_kmod.sh failure when CONFIG_BPF_JIT_ALWAYS_ON=y
With CONFIG_BPF_JIT_ALWAYS_ON is defined in the config file,
tools/testing/selftests/bpf/test_kmod.sh failed like below:
[root@localhost bpf]# ./test_kmod.sh
sysctl: setting key "net.core.bpf_jit_enable": Invalid argument
[ JIT enabled:0 hardened:0 ]
[ 132.175681] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 132.458834] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:0 ]
[ 133.456025] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 133.730935] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:1 ]
[ 134.769730] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 135.050864] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:2 ]
[ 136.442882] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 136.821810] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[root@localhost bpf]#
The test_kmod.sh load/remove test_bpf.ko multiple times with different
settings for sysctl net.core.bpf_jit_{enable,harden}. The failed test #297
of test_bpf.ko is designed such that JIT always fails.
Commit 290af86629b2 (bpf: introduce BPF_JIT_ALWAYS_ON config)
introduced the following tightening logic:
...
if (!bpf_prog_is_dev_bound(fp->aux)) {
fp = bpf_int_jit_compile(fp);
#ifdef CONFIG_BPF_JIT_ALWAYS_ON
if (!fp->jited) {
*err = -ENOTSUPP;
return fp;
}
#endif
...
With this logic, Test #297 always gets return value -ENOTSUPP
when CONFIG_BPF_JIT_ALWAYS_ON is defined, causing the test failure.
This patch fixed the failure by marking Test #297 as expected failure
when CONFIG_BPF_JIT_ALWAYS_ON is defined.
Fixes: 290af86629b2 (bpf: introduce BPF_JIT_ALWAYS_ON config)
Signed-off-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
2018-02-03 13:37:15 +07:00
|
|
|
.expected_errcode = -ENOTSUPP,
|
2015-05-27 03:35:43 +07:00
|
|
|
},
|
2015-07-21 10:34:19 +07:00
|
|
|
{
|
|
|
|
"BPF_MAXINSNS: ld_abs+get_processor_id",
|
|
|
|
{ },
|
|
|
|
CLASSIC,
|
|
|
|
{ },
|
|
|
|
{ { 1, 0xbee } },
|
|
|
|
.fill_helper = bpf_fill_ld_abs_get_processor_id,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"BPF_MAXINSNS: ld_abs+vlan_push/pop",
|
|
|
|
{ },
|
|
|
|
INTERNAL,
|
|
|
|
{ 0x34 },
|
bpf, test: fix ld_abs + vlan push/pop stress test
After commit 636c2628086e ("net: skbuff: Remove errornous length
validation in skb_vlan_pop()") mentioned test case stopped working,
throwing a -12 (ENOMEM) return code. The issue however is not due to
636c2628086e, but rather due to a buggy test case that got uncovered
from the change in behaviour in 636c2628086e.
The data_size of that test case for the skb was set to 1. In the
bpf_fill_ld_abs_vlan_push_pop() handler bpf insns are generated that
loop with: reading skb data, pushing 68 tags, reading skb data,
popping 68 tags, reading skb data, etc, in order to force a skb
expansion and thus trigger that JITs recache skb->data. Problem is
that initial data_size is too small.
While before 636c2628086e, the test silently bailed out due to the
skb->len < VLAN_ETH_HLEN check with returning 0, and now throwing an
error from failing skb_ensure_writable(). Set at least minimum of
ETH_HLEN as an initial length so that on first push of data, equivalent
pop will succeed.
Fixes: 4d9c5c53ac99 ("test_bpf: add bpf_skb_vlan_push/pop() tests")
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2016-10-20 22:13:53 +07:00
|
|
|
{ { ETH_HLEN, 0xbef } },
|
2015-07-21 10:34:19 +07:00
|
|
|
.fill_helper = bpf_fill_ld_abs_vlan_push_pop,
|
|
|
|
},
|
2017-06-14 06:49:36 +07:00
|
|
|
{
|
|
|
|
"BPF_MAXINSNS: jump around ld_abs",
|
|
|
|
{ },
|
|
|
|
INTERNAL,
|
|
|
|
{ 10, 11 },
|
|
|
|
{ { 2, 10 } },
|
|
|
|
.fill_helper = bpf_fill_jump_around_ld_abs,
|
|
|
|
},
|
2015-08-04 20:19:09 +07:00
|
|
|
/*
|
|
|
|
* LD_IND / LD_ABS on fragmented SKBs
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
"LD_IND byte frag",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 0x40),
|
|
|
|
BPF_STMT(BPF_LD | BPF_IND | BPF_B, 0x0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC | FLAG_SKB_FRAG,
|
|
|
|
{ },
|
|
|
|
{ {0x40, 0x42} },
|
|
|
|
.frag_data = {
|
|
|
|
0x42, 0x00, 0x00, 0x00,
|
|
|
|
0x43, 0x44, 0x00, 0x00,
|
|
|
|
0x21, 0x07, 0x19, 0x83,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_IND halfword frag",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 0x40),
|
|
|
|
BPF_STMT(BPF_LD | BPF_IND | BPF_H, 0x4),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC | FLAG_SKB_FRAG,
|
|
|
|
{ },
|
|
|
|
{ {0x40, 0x4344} },
|
|
|
|
.frag_data = {
|
|
|
|
0x42, 0x00, 0x00, 0x00,
|
|
|
|
0x43, 0x44, 0x00, 0x00,
|
|
|
|
0x21, 0x07, 0x19, 0x83,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_IND word frag",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 0x40),
|
|
|
|
BPF_STMT(BPF_LD | BPF_IND | BPF_W, 0x8),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC | FLAG_SKB_FRAG,
|
|
|
|
{ },
|
|
|
|
{ {0x40, 0x21071983} },
|
|
|
|
.frag_data = {
|
|
|
|
0x42, 0x00, 0x00, 0x00,
|
|
|
|
0x43, 0x44, 0x00, 0x00,
|
|
|
|
0x21, 0x07, 0x19, 0x83,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_IND halfword mixed head/frag",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 0x40),
|
|
|
|
BPF_STMT(BPF_LD | BPF_IND | BPF_H, -0x1),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC | FLAG_SKB_FRAG,
|
|
|
|
{ [0x3e] = 0x25, [0x3f] = 0x05, },
|
|
|
|
{ {0x40, 0x0519} },
|
|
|
|
.frag_data = { 0x19, 0x82 },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_IND word mixed head/frag",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 0x40),
|
|
|
|
BPF_STMT(BPF_LD | BPF_IND | BPF_W, -0x2),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC | FLAG_SKB_FRAG,
|
|
|
|
{ [0x3e] = 0x25, [0x3f] = 0x05, },
|
|
|
|
{ {0x40, 0x25051982} },
|
|
|
|
.frag_data = { 0x19, 0x82 },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_ABS byte frag",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LD | BPF_ABS | BPF_B, 0x40),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC | FLAG_SKB_FRAG,
|
|
|
|
{ },
|
|
|
|
{ {0x40, 0x42} },
|
|
|
|
.frag_data = {
|
|
|
|
0x42, 0x00, 0x00, 0x00,
|
|
|
|
0x43, 0x44, 0x00, 0x00,
|
|
|
|
0x21, 0x07, 0x19, 0x83,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_ABS halfword frag",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LD | BPF_ABS | BPF_H, 0x44),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC | FLAG_SKB_FRAG,
|
|
|
|
{ },
|
|
|
|
{ {0x40, 0x4344} },
|
|
|
|
.frag_data = {
|
|
|
|
0x42, 0x00, 0x00, 0x00,
|
|
|
|
0x43, 0x44, 0x00, 0x00,
|
|
|
|
0x21, 0x07, 0x19, 0x83,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_ABS word frag",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LD | BPF_ABS | BPF_W, 0x48),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC | FLAG_SKB_FRAG,
|
|
|
|
{ },
|
|
|
|
{ {0x40, 0x21071983} },
|
|
|
|
.frag_data = {
|
|
|
|
0x42, 0x00, 0x00, 0x00,
|
|
|
|
0x43, 0x44, 0x00, 0x00,
|
|
|
|
0x21, 0x07, 0x19, 0x83,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_ABS halfword mixed head/frag",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LD | BPF_ABS | BPF_H, 0x3f),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC | FLAG_SKB_FRAG,
|
|
|
|
{ [0x3e] = 0x25, [0x3f] = 0x05, },
|
|
|
|
{ {0x40, 0x0519} },
|
|
|
|
.frag_data = { 0x19, 0x82 },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_ABS word mixed head/frag",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LD | BPF_ABS | BPF_W, 0x3e),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC | FLAG_SKB_FRAG,
|
|
|
|
{ [0x3e] = 0x25, [0x3f] = 0x05, },
|
|
|
|
{ {0x40, 0x25051982} },
|
|
|
|
.frag_data = { 0x19, 0x82 },
|
|
|
|
},
|
2015-08-04 20:19:11 +07:00
|
|
|
/*
|
|
|
|
* LD_IND / LD_ABS on non fragmented SKBs
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* this tests that the JIT/interpreter correctly resets X
|
|
|
|
* before using it in an LD_IND instruction.
|
|
|
|
*/
|
|
|
|
"LD_IND byte default X",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LD | BPF_IND | BPF_B, 0x1),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC,
|
|
|
|
{ [0x1] = 0x42 },
|
|
|
|
{ {0x40, 0x42 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_IND byte positive offset",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 0x3e),
|
|
|
|
BPF_STMT(BPF_LD | BPF_IND | BPF_B, 0x1),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC,
|
|
|
|
{ [0x3c] = 0x25, [0x3d] = 0x05, [0x3e] = 0x19, [0x3f] = 0x82 },
|
|
|
|
{ {0x40, 0x82 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_IND byte negative offset",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 0x3e),
|
|
|
|
BPF_STMT(BPF_LD | BPF_IND | BPF_B, -0x1),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC,
|
|
|
|
{ [0x3c] = 0x25, [0x3d] = 0x05, [0x3e] = 0x19, [0x3f] = 0x82 },
|
|
|
|
{ {0x40, 0x05 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_IND halfword positive offset",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 0x20),
|
|
|
|
BPF_STMT(BPF_LD | BPF_IND | BPF_H, 0x2),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC,
|
|
|
|
{
|
|
|
|
[0x1c] = 0xaa, [0x1d] = 0x55,
|
|
|
|
[0x1e] = 0xbb, [0x1f] = 0x66,
|
|
|
|
[0x20] = 0xcc, [0x21] = 0x77,
|
|
|
|
[0x22] = 0xdd, [0x23] = 0x88,
|
|
|
|
},
|
|
|
|
{ {0x40, 0xdd88 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_IND halfword negative offset",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 0x20),
|
|
|
|
BPF_STMT(BPF_LD | BPF_IND | BPF_H, -0x2),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC,
|
|
|
|
{
|
|
|
|
[0x1c] = 0xaa, [0x1d] = 0x55,
|
|
|
|
[0x1e] = 0xbb, [0x1f] = 0x66,
|
|
|
|
[0x20] = 0xcc, [0x21] = 0x77,
|
|
|
|
[0x22] = 0xdd, [0x23] = 0x88,
|
|
|
|
},
|
|
|
|
{ {0x40, 0xbb66 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_IND halfword unaligned",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 0x20),
|
|
|
|
BPF_STMT(BPF_LD | BPF_IND | BPF_H, -0x1),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC,
|
|
|
|
{
|
|
|
|
[0x1c] = 0xaa, [0x1d] = 0x55,
|
|
|
|
[0x1e] = 0xbb, [0x1f] = 0x66,
|
|
|
|
[0x20] = 0xcc, [0x21] = 0x77,
|
|
|
|
[0x22] = 0xdd, [0x23] = 0x88,
|
|
|
|
},
|
|
|
|
{ {0x40, 0x66cc } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_IND word positive offset",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 0x20),
|
|
|
|
BPF_STMT(BPF_LD | BPF_IND | BPF_W, 0x4),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC,
|
|
|
|
{
|
|
|
|
[0x1c] = 0xaa, [0x1d] = 0x55,
|
|
|
|
[0x1e] = 0xbb, [0x1f] = 0x66,
|
|
|
|
[0x20] = 0xcc, [0x21] = 0x77,
|
|
|
|
[0x22] = 0xdd, [0x23] = 0x88,
|
|
|
|
[0x24] = 0xee, [0x25] = 0x99,
|
|
|
|
[0x26] = 0xff, [0x27] = 0xaa,
|
|
|
|
},
|
|
|
|
{ {0x40, 0xee99ffaa } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_IND word negative offset",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 0x20),
|
|
|
|
BPF_STMT(BPF_LD | BPF_IND | BPF_W, -0x4),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC,
|
|
|
|
{
|
|
|
|
[0x1c] = 0xaa, [0x1d] = 0x55,
|
|
|
|
[0x1e] = 0xbb, [0x1f] = 0x66,
|
|
|
|
[0x20] = 0xcc, [0x21] = 0x77,
|
|
|
|
[0x22] = 0xdd, [0x23] = 0x88,
|
|
|
|
[0x24] = 0xee, [0x25] = 0x99,
|
|
|
|
[0x26] = 0xff, [0x27] = 0xaa,
|
|
|
|
},
|
|
|
|
{ {0x40, 0xaa55bb66 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_IND word unaligned (addr & 3 == 2)",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 0x20),
|
|
|
|
BPF_STMT(BPF_LD | BPF_IND | BPF_W, -0x2),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC,
|
|
|
|
{
|
|
|
|
[0x1c] = 0xaa, [0x1d] = 0x55,
|
|
|
|
[0x1e] = 0xbb, [0x1f] = 0x66,
|
|
|
|
[0x20] = 0xcc, [0x21] = 0x77,
|
|
|
|
[0x22] = 0xdd, [0x23] = 0x88,
|
|
|
|
[0x24] = 0xee, [0x25] = 0x99,
|
|
|
|
[0x26] = 0xff, [0x27] = 0xaa,
|
|
|
|
},
|
|
|
|
{ {0x40, 0xbb66cc77 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_IND word unaligned (addr & 3 == 1)",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 0x20),
|
|
|
|
BPF_STMT(BPF_LD | BPF_IND | BPF_W, -0x3),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC,
|
|
|
|
{
|
|
|
|
[0x1c] = 0xaa, [0x1d] = 0x55,
|
|
|
|
[0x1e] = 0xbb, [0x1f] = 0x66,
|
|
|
|
[0x20] = 0xcc, [0x21] = 0x77,
|
|
|
|
[0x22] = 0xdd, [0x23] = 0x88,
|
|
|
|
[0x24] = 0xee, [0x25] = 0x99,
|
|
|
|
[0x26] = 0xff, [0x27] = 0xaa,
|
|
|
|
},
|
|
|
|
{ {0x40, 0x55bb66cc } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_IND word unaligned (addr & 3 == 3)",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LDX | BPF_IMM, 0x20),
|
|
|
|
BPF_STMT(BPF_LD | BPF_IND | BPF_W, -0x1),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC,
|
|
|
|
{
|
|
|
|
[0x1c] = 0xaa, [0x1d] = 0x55,
|
|
|
|
[0x1e] = 0xbb, [0x1f] = 0x66,
|
|
|
|
[0x20] = 0xcc, [0x21] = 0x77,
|
|
|
|
[0x22] = 0xdd, [0x23] = 0x88,
|
|
|
|
[0x24] = 0xee, [0x25] = 0x99,
|
|
|
|
[0x26] = 0xff, [0x27] = 0xaa,
|
|
|
|
},
|
|
|
|
{ {0x40, 0x66cc77dd } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_ABS byte",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LD | BPF_ABS | BPF_B, 0x20),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC,
|
|
|
|
{
|
|
|
|
[0x1c] = 0xaa, [0x1d] = 0x55,
|
|
|
|
[0x1e] = 0xbb, [0x1f] = 0x66,
|
|
|
|
[0x20] = 0xcc, [0x21] = 0x77,
|
|
|
|
[0x22] = 0xdd, [0x23] = 0x88,
|
|
|
|
[0x24] = 0xee, [0x25] = 0x99,
|
|
|
|
[0x26] = 0xff, [0x27] = 0xaa,
|
|
|
|
},
|
|
|
|
{ {0x40, 0xcc } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_ABS halfword",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LD | BPF_ABS | BPF_H, 0x22),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC,
|
|
|
|
{
|
|
|
|
[0x1c] = 0xaa, [0x1d] = 0x55,
|
|
|
|
[0x1e] = 0xbb, [0x1f] = 0x66,
|
|
|
|
[0x20] = 0xcc, [0x21] = 0x77,
|
|
|
|
[0x22] = 0xdd, [0x23] = 0x88,
|
|
|
|
[0x24] = 0xee, [0x25] = 0x99,
|
|
|
|
[0x26] = 0xff, [0x27] = 0xaa,
|
|
|
|
},
|
|
|
|
{ {0x40, 0xdd88 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_ABS halfword unaligned",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LD | BPF_ABS | BPF_H, 0x25),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC,
|
|
|
|
{
|
|
|
|
[0x1c] = 0xaa, [0x1d] = 0x55,
|
|
|
|
[0x1e] = 0xbb, [0x1f] = 0x66,
|
|
|
|
[0x20] = 0xcc, [0x21] = 0x77,
|
|
|
|
[0x22] = 0xdd, [0x23] = 0x88,
|
|
|
|
[0x24] = 0xee, [0x25] = 0x99,
|
|
|
|
[0x26] = 0xff, [0x27] = 0xaa,
|
|
|
|
},
|
|
|
|
{ {0x40, 0x99ff } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_ABS word",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LD | BPF_ABS | BPF_W, 0x1c),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC,
|
|
|
|
{
|
|
|
|
[0x1c] = 0xaa, [0x1d] = 0x55,
|
|
|
|
[0x1e] = 0xbb, [0x1f] = 0x66,
|
|
|
|
[0x20] = 0xcc, [0x21] = 0x77,
|
|
|
|
[0x22] = 0xdd, [0x23] = 0x88,
|
|
|
|
[0x24] = 0xee, [0x25] = 0x99,
|
|
|
|
[0x26] = 0xff, [0x27] = 0xaa,
|
|
|
|
},
|
|
|
|
{ {0x40, 0xaa55bb66 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_ABS word unaligned (addr & 3 == 2)",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LD | BPF_ABS | BPF_W, 0x22),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC,
|
|
|
|
{
|
|
|
|
[0x1c] = 0xaa, [0x1d] = 0x55,
|
|
|
|
[0x1e] = 0xbb, [0x1f] = 0x66,
|
|
|
|
[0x20] = 0xcc, [0x21] = 0x77,
|
|
|
|
[0x22] = 0xdd, [0x23] = 0x88,
|
|
|
|
[0x24] = 0xee, [0x25] = 0x99,
|
|
|
|
[0x26] = 0xff, [0x27] = 0xaa,
|
|
|
|
},
|
|
|
|
{ {0x40, 0xdd88ee99 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_ABS word unaligned (addr & 3 == 1)",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LD | BPF_ABS | BPF_W, 0x21),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC,
|
|
|
|
{
|
|
|
|
[0x1c] = 0xaa, [0x1d] = 0x55,
|
|
|
|
[0x1e] = 0xbb, [0x1f] = 0x66,
|
|
|
|
[0x20] = 0xcc, [0x21] = 0x77,
|
|
|
|
[0x22] = 0xdd, [0x23] = 0x88,
|
|
|
|
[0x24] = 0xee, [0x25] = 0x99,
|
|
|
|
[0x26] = 0xff, [0x27] = 0xaa,
|
|
|
|
},
|
|
|
|
{ {0x40, 0x77dd88ee } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"LD_ABS word unaligned (addr & 3 == 3)",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LD | BPF_ABS | BPF_W, 0x23),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC,
|
|
|
|
{
|
|
|
|
[0x1c] = 0xaa, [0x1d] = 0x55,
|
|
|
|
[0x1e] = 0xbb, [0x1f] = 0x66,
|
|
|
|
[0x20] = 0xcc, [0x21] = 0x77,
|
|
|
|
[0x22] = 0xdd, [0x23] = 0x88,
|
|
|
|
[0x24] = 0xee, [0x25] = 0x99,
|
|
|
|
[0x26] = 0xff, [0x27] = 0xaa,
|
|
|
|
},
|
|
|
|
{ {0x40, 0x88ee99ff } },
|
|
|
|
},
|
2015-08-04 20:19:12 +07:00
|
|
|
/*
|
|
|
|
* verify that the interpreter or JIT correctly sets A and X
|
|
|
|
* to 0.
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
"ADD default X",
|
|
|
|
.u.insns = {
|
|
|
|
/*
|
|
|
|
* A = 0x42
|
|
|
|
* A = A + X
|
|
|
|
* ret A
|
|
|
|
*/
|
|
|
|
BPF_STMT(BPF_LD | BPF_IMM, 0x42),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC | FLAG_NO_DATA,
|
|
|
|
{},
|
|
|
|
{ {0x1, 0x42 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ADD default A",
|
|
|
|
.u.insns = {
|
|
|
|
/*
|
|
|
|
* A = A + 0x42
|
|
|
|
* ret A
|
|
|
|
*/
|
|
|
|
BPF_STMT(BPF_ALU | BPF_ADD | BPF_K, 0x42),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC | FLAG_NO_DATA,
|
|
|
|
{},
|
|
|
|
{ {0x1, 0x42 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"SUB default X",
|
|
|
|
.u.insns = {
|
|
|
|
/*
|
|
|
|
* A = 0x66
|
|
|
|
* A = A - X
|
|
|
|
* ret A
|
|
|
|
*/
|
|
|
|
BPF_STMT(BPF_LD | BPF_IMM, 0x66),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_SUB | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC | FLAG_NO_DATA,
|
|
|
|
{},
|
|
|
|
{ {0x1, 0x66 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"SUB default A",
|
|
|
|
.u.insns = {
|
|
|
|
/*
|
|
|
|
* A = A - -0x66
|
|
|
|
* ret A
|
|
|
|
*/
|
|
|
|
BPF_STMT(BPF_ALU | BPF_SUB | BPF_K, -0x66),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC | FLAG_NO_DATA,
|
|
|
|
{},
|
|
|
|
{ {0x1, 0x66 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"MUL default X",
|
|
|
|
.u.insns = {
|
|
|
|
/*
|
|
|
|
* A = 0x42
|
|
|
|
* A = A * X
|
|
|
|
* ret A
|
|
|
|
*/
|
|
|
|
BPF_STMT(BPF_LD | BPF_IMM, 0x42),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_MUL | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC | FLAG_NO_DATA,
|
|
|
|
{},
|
|
|
|
{ {0x1, 0x0 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"MUL default A",
|
|
|
|
.u.insns = {
|
|
|
|
/*
|
|
|
|
* A = A * 0x66
|
|
|
|
* ret A
|
|
|
|
*/
|
|
|
|
BPF_STMT(BPF_ALU | BPF_MUL | BPF_K, 0x66),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC | FLAG_NO_DATA,
|
|
|
|
{},
|
|
|
|
{ {0x1, 0x0 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"DIV default X",
|
|
|
|
.u.insns = {
|
|
|
|
/*
|
|
|
|
* A = 0x42
|
|
|
|
* A = A / X ; this halt the filter execution if X is 0
|
|
|
|
* ret 0x42
|
|
|
|
*/
|
|
|
|
BPF_STMT(BPF_LD | BPF_IMM, 0x42),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_DIV | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 0x42),
|
|
|
|
},
|
|
|
|
CLASSIC | FLAG_NO_DATA,
|
|
|
|
{},
|
|
|
|
{ {0x1, 0x0 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"DIV default A",
|
|
|
|
.u.insns = {
|
|
|
|
/*
|
|
|
|
* A = A / 1
|
|
|
|
* ret A
|
|
|
|
*/
|
|
|
|
BPF_STMT(BPF_ALU | BPF_DIV | BPF_K, 0x1),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC | FLAG_NO_DATA,
|
|
|
|
{},
|
|
|
|
{ {0x1, 0x0 } },
|
|
|
|
},
|
2015-11-05 02:36:37 +07:00
|
|
|
{
|
|
|
|
"MOD default X",
|
|
|
|
.u.insns = {
|
|
|
|
/*
|
|
|
|
* A = 0x42
|
|
|
|
* A = A mod X ; this halt the filter execution if X is 0
|
|
|
|
* ret 0x42
|
|
|
|
*/
|
|
|
|
BPF_STMT(BPF_LD | BPF_IMM, 0x42),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_MOD | BPF_X, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 0x42),
|
|
|
|
},
|
|
|
|
CLASSIC | FLAG_NO_DATA,
|
|
|
|
{},
|
|
|
|
{ {0x1, 0x0 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"MOD default A",
|
|
|
|
.u.insns = {
|
|
|
|
/*
|
|
|
|
* A = A mod 1
|
|
|
|
* ret A
|
|
|
|
*/
|
|
|
|
BPF_STMT(BPF_ALU | BPF_MOD | BPF_K, 0x1),
|
|
|
|
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
|
|
|
},
|
|
|
|
CLASSIC | FLAG_NO_DATA,
|
|
|
|
{},
|
|
|
|
{ {0x1, 0x0 } },
|
|
|
|
},
|
2015-08-04 20:19:12 +07:00
|
|
|
{
|
|
|
|
"JMP EQ default A",
|
|
|
|
.u.insns = {
|
|
|
|
/*
|
|
|
|
* cmp A, 0x0, 0, 1
|
|
|
|
* ret 0x42
|
|
|
|
* ret 0x66
|
|
|
|
*/
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x0, 0, 1),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 0x42),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 0x66),
|
|
|
|
},
|
|
|
|
CLASSIC | FLAG_NO_DATA,
|
|
|
|
{},
|
|
|
|
{ {0x1, 0x42 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"JMP EQ default X",
|
|
|
|
.u.insns = {
|
|
|
|
/*
|
|
|
|
* A = 0x0
|
|
|
|
* cmp A, X, 0, 1
|
|
|
|
* ret 0x42
|
|
|
|
* ret 0x66
|
|
|
|
*/
|
|
|
|
BPF_STMT(BPF_LD | BPF_IMM, 0x0),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_X, 0x0, 0, 1),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 0x42),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 0x66),
|
|
|
|
},
|
|
|
|
CLASSIC | FLAG_NO_DATA,
|
|
|
|
{},
|
|
|
|
{ {0x1, 0x42 } },
|
|
|
|
},
|
2017-12-15 03:07:27 +07:00
|
|
|
{
|
|
|
|
"LD_ABS with helper changing skb data",
|
|
|
|
{ },
|
|
|
|
INTERNAL,
|
|
|
|
{ 0x34 },
|
|
|
|
{ { ETH_HLEN, 42 } },
|
|
|
|
.fill_helper = bpf_fill_ld_abs_vlan_push_pop2,
|
|
|
|
},
|
2018-01-20 07:24:31 +07:00
|
|
|
/* Checking interpreter vs JIT wrt signed extended imms. */
|
|
|
|
{
|
|
|
|
"JNE signed compare, test 1",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 0xfefbbc12),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R3, 0xffff0000),
|
|
|
|
BPF_MOV64_REG(R2, R1),
|
|
|
|
BPF_ALU64_REG(BPF_AND, R2, R3),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, R2, -17104896, 1),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"JNE signed compare, test 2",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 0xfefbbc12),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R3, 0xffff0000),
|
|
|
|
BPF_MOV64_REG(R2, R1),
|
|
|
|
BPF_ALU64_REG(BPF_AND, R2, R3),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, R2, 0xfefb0000, 1),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"JNE signed compare, test 3",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R1, 0xfefbbc12),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R3, 0xffff0000),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R4, 0xfefb0000),
|
|
|
|
BPF_MOV64_REG(R2, R1),
|
|
|
|
BPF_ALU64_REG(BPF_AND, R2, R3),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_JMP_REG(BPF_JNE, R2, R4, 1),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 2 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"JNE signed compare, test 4",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R1, -17104896),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, R1, -17104896, 1),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 2 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"JNE signed compare, test 5",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R1, 0xfefb0000),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, R1, 0xfefb0000, 1),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 1 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"JNE signed compare, test 6",
|
|
|
|
.u.insns_int = {
|
|
|
|
BPF_LD_IMM64(R1, 0x7efb0000),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 1),
|
|
|
|
BPF_JMP_IMM(BPF_JNE, R1, 0x7efb0000, 1),
|
|
|
|
BPF_ALU32_IMM(BPF_MOV, R0, 2),
|
|
|
|
BPF_EXIT_INSN(),
|
|
|
|
},
|
|
|
|
INTERNAL,
|
|
|
|
{ },
|
|
|
|
{ { 0, 2 } },
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"JNE signed compare, test 7",
|
|
|
|
.u.insns = {
|
|
|
|
BPF_STMT(BPF_LD | BPF_IMM, 0xffff0000),
|
|
|
|
BPF_STMT(BPF_MISC | BPF_TAX, 0),
|
|
|
|
BPF_STMT(BPF_LD | BPF_IMM, 0xfefbbc12),
|
|
|
|
BPF_STMT(BPF_ALU | BPF_AND | BPF_X, 0),
|
|
|
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0xfefb0000, 1, 0),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 1),
|
|
|
|
BPF_STMT(BPF_RET | BPF_K, 2),
|
|
|
|
},
|
|
|
|
CLASSIC | FLAG_NO_DATA,
|
|
|
|
{},
|
|
|
|
{ { 0, 2 } },
|
|
|
|
},
|
2014-05-09 04:10:52 +07:00
|
|
|
};
|
|
|
|
|
2014-05-23 23:44:00 +07:00
|
|
|
static struct net_device dev;
|
2014-05-09 04:10:52 +07:00
|
|
|
|
2014-05-23 23:44:00 +07:00
|
|
|
static struct sk_buff *populate_skb(char *buf, int size)
|
2014-05-09 04:10:52 +07:00
|
|
|
{
|
|
|
|
struct sk_buff *skb;
|
|
|
|
|
|
|
|
if (size >= MAX_DATA)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
skb = alloc_skb(MAX_DATA, GFP_KERNEL);
|
|
|
|
if (!skb)
|
|
|
|
return NULL;
|
|
|
|
|
net: introduce __skb_put_[zero, data, u8]
follow Johannes Berg, semantic patch file as below,
@@
identifier p, p2;
expression len;
expression skb;
type t, t2;
@@
(
-p = __skb_put(skb, len);
+p = __skb_put_zero(skb, len);
|
-p = (t)__skb_put(skb, len);
+p = __skb_put_zero(skb, len);
)
... when != p
(
p2 = (t2)p;
-memset(p2, 0, len);
|
-memset(p, 0, len);
)
@@
identifier p;
expression len;
expression skb;
type t;
@@
(
-t p = __skb_put(skb, len);
+t p = __skb_put_zero(skb, len);
)
... when != p
(
-memset(p, 0, len);
)
@@
type t, t2;
identifier p, p2;
expression skb;
@@
t *p;
...
(
-p = __skb_put(skb, sizeof(t));
+p = __skb_put_zero(skb, sizeof(t));
|
-p = (t *)__skb_put(skb, sizeof(t));
+p = __skb_put_zero(skb, sizeof(t));
)
... when != p
(
p2 = (t2)p;
-memset(p2, 0, sizeof(*p));
|
-memset(p, 0, sizeof(*p));
)
@@
expression skb, len;
@@
-memset(__skb_put(skb, len), 0, len);
+__skb_put_zero(skb, len);
@@
expression skb, len, data;
@@
-memcpy(__skb_put(skb, len), data, len);
+__skb_put_data(skb, data, len);
@@
expression SKB, C, S;
typedef u8;
identifier fn = {__skb_put};
fresh identifier fn2 = fn ## "_u8";
@@
- *(u8 *)fn(SKB, S) = C;
+ fn2(SKB, C);
Signed-off-by: yuan linyu <Linyu.Yuan@alcatel-sbell.com.cn>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-06-18 21:48:17 +07:00
|
|
|
__skb_put_data(skb, buf, size);
|
2014-05-23 23:44:00 +07:00
|
|
|
|
|
|
|
/* Initialize a fake skb with test pattern. */
|
2014-05-09 04:10:52 +07:00
|
|
|
skb_reset_mac_header(skb);
|
|
|
|
skb->protocol = htons(ETH_P_IP);
|
|
|
|
skb->pkt_type = SKB_TYPE;
|
|
|
|
skb->mark = SKB_MARK;
|
|
|
|
skb->hash = SKB_HASH;
|
|
|
|
skb->queue_mapping = SKB_QUEUE_MAP;
|
|
|
|
skb->vlan_tci = SKB_VLAN_TCI;
|
2016-09-12 19:04:57 +07:00
|
|
|
skb->vlan_proto = htons(ETH_P_IP);
|
2014-05-09 04:10:52 +07:00
|
|
|
skb->dev = &dev;
|
|
|
|
skb->dev->ifindex = SKB_DEV_IFINDEX;
|
|
|
|
skb->dev->type = SKB_DEV_TYPE;
|
|
|
|
skb_set_network_header(skb, min(size, ETH_HLEN));
|
|
|
|
|
|
|
|
return skb;
|
|
|
|
}
|
|
|
|
|
2014-05-23 23:44:00 +07:00
|
|
|
static void *generate_test_data(struct bpf_test *test, int sub)
|
2014-05-09 04:10:52 +07:00
|
|
|
{
|
2015-08-04 20:19:08 +07:00
|
|
|
struct sk_buff *skb;
|
|
|
|
struct page *page;
|
|
|
|
|
2014-05-23 23:44:00 +07:00
|
|
|
if (test->aux & FLAG_NO_DATA)
|
|
|
|
return NULL;
|
2014-05-09 04:10:52 +07:00
|
|
|
|
2014-05-23 23:44:00 +07:00
|
|
|
/* Test case expects an skb, so populate one. Various
|
|
|
|
* subtests generate skbs of different sizes based on
|
|
|
|
* the same data.
|
|
|
|
*/
|
2015-08-04 20:19:08 +07:00
|
|
|
skb = populate_skb(test->data, test->test[sub].data_size);
|
|
|
|
if (!skb)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (test->aux & FLAG_SKB_FRAG) {
|
|
|
|
/*
|
|
|
|
* when the test requires a fragmented skb, add a
|
|
|
|
* single fragment to the skb, filled with
|
|
|
|
* test->frag_data.
|
|
|
|
*/
|
|
|
|
void *ptr;
|
|
|
|
|
|
|
|
page = alloc_page(GFP_KERNEL);
|
|
|
|
|
|
|
|
if (!page)
|
|
|
|
goto err_kfree_skb;
|
|
|
|
|
|
|
|
ptr = kmap(page);
|
|
|
|
if (!ptr)
|
|
|
|
goto err_free_page;
|
|
|
|
memcpy(ptr, test->frag_data, MAX_DATA);
|
|
|
|
kunmap(page);
|
|
|
|
skb_add_rx_frag(skb, 0, page, 0, MAX_DATA, MAX_DATA);
|
|
|
|
}
|
|
|
|
|
|
|
|
return skb;
|
|
|
|
|
|
|
|
err_free_page:
|
|
|
|
__free_page(page);
|
|
|
|
err_kfree_skb:
|
|
|
|
kfree_skb(skb);
|
|
|
|
return NULL;
|
2014-05-23 23:44:00 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void release_test_data(const struct bpf_test *test, void *data)
|
|
|
|
{
|
|
|
|
if (test->aux & FLAG_NO_DATA)
|
|
|
|
return;
|
|
|
|
|
|
|
|
kfree_skb(data);
|
|
|
|
}
|
|
|
|
|
2015-05-13 18:12:43 +07:00
|
|
|
static int filter_length(int which)
|
2014-05-23 23:44:00 +07:00
|
|
|
{
|
2015-05-13 18:12:43 +07:00
|
|
|
struct sock_filter *fp;
|
|
|
|
int len;
|
2014-05-23 23:44:00 +07:00
|
|
|
|
2015-05-13 18:12:43 +07:00
|
|
|
if (tests[which].fill_helper)
|
|
|
|
return tests[which].u.ptr.len;
|
|
|
|
|
|
|
|
fp = tests[which].u.insns;
|
net: filter: fix length calculation in BPF testsuite
The current probe_filter_length() (the function that calculates the
length of a test BPF filter) behavior is to declare the end of the
filter as soon as it finds {0, *, *, 0}. This is actually a valid
insn ("ld #0"), so any filter with includes "BPF_STMT(BPF_LD | BPF_IMM, 0)"
fails (its length is cut short).
We are changing probe_filter_length() so as to start from the end, and
declare the end of the filter as the first instruction which is not
{0, *, *, 0}. This solution produces a simpler patch than the
alternative of using an explicit end-of-filter mark. It is technically
incorrect if your filter ends up with "ld #0", but that should not
happen anyway.
We also add a new test (LD_IMM_0) that includes ld #0 (does not work
without this patch).
Signed-off-by: Chema Gonzalez <chema@google.com>
Acked-by: Daniel Borkmann <dborkman@redhat.com>
Acked-by: Alexei Starovoitov <ast@plumgrid.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-05-31 00:15:12 +07:00
|
|
|
for (len = MAX_INSNS - 1; len > 0; --len)
|
|
|
|
if (fp[len].code != 0 || fp[len].k != 0)
|
|
|
|
break;
|
2014-05-23 23:44:00 +07:00
|
|
|
|
net: filter: fix length calculation in BPF testsuite
The current probe_filter_length() (the function that calculates the
length of a test BPF filter) behavior is to declare the end of the
filter as soon as it finds {0, *, *, 0}. This is actually a valid
insn ("ld #0"), so any filter with includes "BPF_STMT(BPF_LD | BPF_IMM, 0)"
fails (its length is cut short).
We are changing probe_filter_length() so as to start from the end, and
declare the end of the filter as the first instruction which is not
{0, *, *, 0}. This solution produces a simpler patch than the
alternative of using an explicit end-of-filter mark. It is technically
incorrect if your filter ends up with "ld #0", but that should not
happen anyway.
We also add a new test (LD_IMM_0) that includes ld #0 (does not work
without this patch).
Signed-off-by: Chema Gonzalez <chema@google.com>
Acked-by: Daniel Borkmann <dborkman@redhat.com>
Acked-by: Alexei Starovoitov <ast@plumgrid.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-05-31 00:15:12 +07:00
|
|
|
return len + 1;
|
2014-05-23 23:44:00 +07:00
|
|
|
}
|
|
|
|
|
2015-05-13 18:12:43 +07:00
|
|
|
static void *filter_pointer(int which)
|
|
|
|
{
|
|
|
|
if (tests[which].fill_helper)
|
|
|
|
return tests[which].u.ptr.insns;
|
|
|
|
else
|
|
|
|
return tests[which].u.insns;
|
|
|
|
}
|
|
|
|
|
net: filter: split 'struct sk_filter' into socket and bpf parts
clean up names related to socket filtering and bpf in the following way:
- everything that deals with sockets keeps 'sk_*' prefix
- everything that is pure BPF is changed to 'bpf_*' prefix
split 'struct sk_filter' into
struct sk_filter {
atomic_t refcnt;
struct rcu_head rcu;
struct bpf_prog *prog;
};
and
struct bpf_prog {
u32 jited:1,
len:31;
struct sock_fprog_kern *orig_prog;
unsigned int (*bpf_func)(const struct sk_buff *skb,
const struct bpf_insn *filter);
union {
struct sock_filter insns[0];
struct bpf_insn insnsi[0];
struct work_struct work;
};
};
so that 'struct bpf_prog' can be used independent of sockets and cleans up
'unattached' bpf use cases
split SK_RUN_FILTER macro into:
SK_RUN_FILTER to be used with 'struct sk_filter *' and
BPF_PROG_RUN to be used with 'struct bpf_prog *'
__sk_filter_release(struct sk_filter *) gains
__bpf_prog_release(struct bpf_prog *) helper function
also perform related renames for the functions that work
with 'struct bpf_prog *', since they're on the same lines:
sk_filter_size -> bpf_prog_size
sk_filter_select_runtime -> bpf_prog_select_runtime
sk_filter_free -> bpf_prog_free
sk_unattached_filter_create -> bpf_prog_create
sk_unattached_filter_destroy -> bpf_prog_destroy
sk_store_orig_filter -> bpf_prog_store_orig_filter
sk_release_orig_filter -> bpf_release_orig_filter
__sk_migrate_filter -> bpf_migrate_filter
__sk_prepare_filter -> bpf_prepare_filter
API for attaching classic BPF to a socket stays the same:
sk_attach_filter(prog, struct sock *)/sk_detach_filter(struct sock *)
and SK_RUN_FILTER(struct sk_filter *, ctx) to execute a program
which is used by sockets, tun, af_packet
API for 'unattached' BPF programs becomes:
bpf_prog_create(struct bpf_prog **)/bpf_prog_destroy(struct bpf_prog *)
and BPF_PROG_RUN(struct bpf_prog *, ctx) to execute a program
which is used by isdn, ppp, team, seccomp, ptp, xt_bpf, cls_bpf, test_bpf
Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-07-31 10:34:16 +07:00
|
|
|
static struct bpf_prog *generate_filter(int which, int *err)
|
2014-05-23 23:44:00 +07:00
|
|
|
{
|
|
|
|
__u8 test_type = tests[which].aux & TEST_TYPE_MASK;
|
2015-05-13 18:12:43 +07:00
|
|
|
unsigned int flen = filter_length(which);
|
|
|
|
void *fptr = filter_pointer(which);
|
|
|
|
struct sock_fprog_kern fprog;
|
|
|
|
struct bpf_prog *fp;
|
2014-05-23 23:44:00 +07:00
|
|
|
|
|
|
|
switch (test_type) {
|
|
|
|
case CLASSIC:
|
2015-05-13 18:12:43 +07:00
|
|
|
fprog.filter = fptr;
|
2014-05-23 23:44:00 +07:00
|
|
|
fprog.len = flen;
|
|
|
|
|
net: filter: split 'struct sk_filter' into socket and bpf parts
clean up names related to socket filtering and bpf in the following way:
- everything that deals with sockets keeps 'sk_*' prefix
- everything that is pure BPF is changed to 'bpf_*' prefix
split 'struct sk_filter' into
struct sk_filter {
atomic_t refcnt;
struct rcu_head rcu;
struct bpf_prog *prog;
};
and
struct bpf_prog {
u32 jited:1,
len:31;
struct sock_fprog_kern *orig_prog;
unsigned int (*bpf_func)(const struct sk_buff *skb,
const struct bpf_insn *filter);
union {
struct sock_filter insns[0];
struct bpf_insn insnsi[0];
struct work_struct work;
};
};
so that 'struct bpf_prog' can be used independent of sockets and cleans up
'unattached' bpf use cases
split SK_RUN_FILTER macro into:
SK_RUN_FILTER to be used with 'struct sk_filter *' and
BPF_PROG_RUN to be used with 'struct bpf_prog *'
__sk_filter_release(struct sk_filter *) gains
__bpf_prog_release(struct bpf_prog *) helper function
also perform related renames for the functions that work
with 'struct bpf_prog *', since they're on the same lines:
sk_filter_size -> bpf_prog_size
sk_filter_select_runtime -> bpf_prog_select_runtime
sk_filter_free -> bpf_prog_free
sk_unattached_filter_create -> bpf_prog_create
sk_unattached_filter_destroy -> bpf_prog_destroy
sk_store_orig_filter -> bpf_prog_store_orig_filter
sk_release_orig_filter -> bpf_release_orig_filter
__sk_migrate_filter -> bpf_migrate_filter
__sk_prepare_filter -> bpf_prepare_filter
API for attaching classic BPF to a socket stays the same:
sk_attach_filter(prog, struct sock *)/sk_detach_filter(struct sock *)
and SK_RUN_FILTER(struct sk_filter *, ctx) to execute a program
which is used by sockets, tun, af_packet
API for 'unattached' BPF programs becomes:
bpf_prog_create(struct bpf_prog **)/bpf_prog_destroy(struct bpf_prog *)
and BPF_PROG_RUN(struct bpf_prog *, ctx) to execute a program
which is used by isdn, ppp, team, seccomp, ptp, xt_bpf, cls_bpf, test_bpf
Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-07-31 10:34:16 +07:00
|
|
|
*err = bpf_prog_create(&fp, &fprog);
|
2014-05-23 23:44:00 +07:00
|
|
|
if (tests[which].aux & FLAG_EXPECTED_FAIL) {
|
bpf: fix selftests/bpf test_kmod.sh failure when CONFIG_BPF_JIT_ALWAYS_ON=y
With CONFIG_BPF_JIT_ALWAYS_ON is defined in the config file,
tools/testing/selftests/bpf/test_kmod.sh failed like below:
[root@localhost bpf]# ./test_kmod.sh
sysctl: setting key "net.core.bpf_jit_enable": Invalid argument
[ JIT enabled:0 hardened:0 ]
[ 132.175681] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 132.458834] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:0 ]
[ 133.456025] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 133.730935] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:1 ]
[ 134.769730] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 135.050864] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[ JIT enabled:1 hardened:2 ]
[ 136.442882] test_bpf: #297 BPF_MAXINSNS: Jump, gap, jump, ... FAIL to prog_create err=-524 len=4096
[ 136.821810] test_bpf: Summary: 348 PASSED, 1 FAILED, [340/340 JIT'ed]
[root@localhost bpf]#
The test_kmod.sh load/remove test_bpf.ko multiple times with different
settings for sysctl net.core.bpf_jit_{enable,harden}. The failed test #297
of test_bpf.ko is designed such that JIT always fails.
Commit 290af86629b2 (bpf: introduce BPF_JIT_ALWAYS_ON config)
introduced the following tightening logic:
...
if (!bpf_prog_is_dev_bound(fp->aux)) {
fp = bpf_int_jit_compile(fp);
#ifdef CONFIG_BPF_JIT_ALWAYS_ON
if (!fp->jited) {
*err = -ENOTSUPP;
return fp;
}
#endif
...
With this logic, Test #297 always gets return value -ENOTSUPP
when CONFIG_BPF_JIT_ALWAYS_ON is defined, causing the test failure.
This patch fixed the failure by marking Test #297 as expected failure
when CONFIG_BPF_JIT_ALWAYS_ON is defined.
Fixes: 290af86629b2 (bpf: introduce BPF_JIT_ALWAYS_ON config)
Signed-off-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
2018-02-03 13:37:15 +07:00
|
|
|
if (*err == tests[which].expected_errcode) {
|
2014-05-23 23:44:00 +07:00
|
|
|
pr_cont("PASS\n");
|
|
|
|
/* Verifier rejected filter as expected. */
|
|
|
|
*err = 0;
|
|
|
|
return NULL;
|
|
|
|
} else {
|
|
|
|
pr_cont("UNEXPECTED_PASS\n");
|
|
|
|
/* Verifier didn't reject the test that's
|
|
|
|
* bad enough, just return!
|
|
|
|
*/
|
|
|
|
*err = -EINVAL;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (*err) {
|
bpf: introduce BPF_JIT_ALWAYS_ON config
The BPF interpreter has been used as part of the spectre 2 attack CVE-2017-5715.
A quote from goolge project zero blog:
"At this point, it would normally be necessary to locate gadgets in
the host kernel code that can be used to actually leak data by reading
from an attacker-controlled location, shifting and masking the result
appropriately and then using the result of that as offset to an
attacker-controlled address for a load. But piecing gadgets together
and figuring out which ones work in a speculation context seems annoying.
So instead, we decided to use the eBPF interpreter, which is built into
the host kernel - while there is no legitimate way to invoke it from inside
a VM, the presence of the code in the host kernel's text section is sufficient
to make it usable for the attack, just like with ordinary ROP gadgets."
To make attacker job harder introduce BPF_JIT_ALWAYS_ON config
option that removes interpreter from the kernel in favor of JIT-only mode.
So far eBPF JIT is supported by:
x64, arm64, arm32, sparc64, s390, powerpc64, mips64
The start of JITed program is randomized and code page is marked as read-only.
In addition "constant blinding" can be turned on with net.core.bpf_jit_harden
v2->v3:
- move __bpf_prog_ret0 under ifdef (Daniel)
v1->v2:
- fix init order, test_bpf and cBPF (Daniel's feedback)
- fix offloaded bpf (Jakub's feedback)
- add 'return 0' dummy in case something can invoke prog->bpf_func
- retarget bpf tree. For bpf-next the patch would need one extra hunk.
It will be sent when the trees are merged back to net-next
Considered doing:
int bpf_jit_enable __read_mostly = BPF_EBPF_JIT_DEFAULT;
but it seems better to land the patch as-is and in bpf-next remove
bpf_jit_enable global variable from all JITs, consolidate in one place
and remove this jit_init() function.
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
2018-01-10 01:04:29 +07:00
|
|
|
pr_cont("FAIL to prog_create err=%d len=%d\n",
|
2014-05-23 23:44:00 +07:00
|
|
|
*err, fprog.len);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case INTERNAL:
|
2014-09-03 03:53:44 +07:00
|
|
|
fp = bpf_prog_alloc(bpf_prog_size(flen), 0);
|
2014-05-23 23:44:00 +07:00
|
|
|
if (fp == NULL) {
|
|
|
|
pr_cont("UNEXPECTED_FAIL no memory left\n");
|
|
|
|
*err = -ENOMEM;
|
|
|
|
return NULL;
|
2014-05-09 04:10:52 +07:00
|
|
|
}
|
|
|
|
|
2014-05-23 23:44:00 +07:00
|
|
|
fp->len = flen;
|
2015-07-30 17:42:46 +07:00
|
|
|
/* Type doesn't really matter here as long as it's not unspec. */
|
|
|
|
fp->type = BPF_PROG_TYPE_SOCKET_FILTER;
|
2015-05-13 18:12:43 +07:00
|
|
|
memcpy(fp->insnsi, fptr, fp->len * sizeof(struct bpf_insn));
|
2017-05-31 03:31:32 +07:00
|
|
|
fp->aux->stack_depth = tests[which].stack_depth;
|
2014-05-09 04:10:52 +07:00
|
|
|
|
2016-05-14 00:08:31 +07:00
|
|
|
/* We cannot error here as we don't need type compatibility
|
|
|
|
* checks.
|
|
|
|
*/
|
|
|
|
fp = bpf_prog_select_runtime(fp, err);
|
bpf: introduce BPF_JIT_ALWAYS_ON config
The BPF interpreter has been used as part of the spectre 2 attack CVE-2017-5715.
A quote from goolge project zero blog:
"At this point, it would normally be necessary to locate gadgets in
the host kernel code that can be used to actually leak data by reading
from an attacker-controlled location, shifting and masking the result
appropriately and then using the result of that as offset to an
attacker-controlled address for a load. But piecing gadgets together
and figuring out which ones work in a speculation context seems annoying.
So instead, we decided to use the eBPF interpreter, which is built into
the host kernel - while there is no legitimate way to invoke it from inside
a VM, the presence of the code in the host kernel's text section is sufficient
to make it usable for the attack, just like with ordinary ROP gadgets."
To make attacker job harder introduce BPF_JIT_ALWAYS_ON config
option that removes interpreter from the kernel in favor of JIT-only mode.
So far eBPF JIT is supported by:
x64, arm64, arm32, sparc64, s390, powerpc64, mips64
The start of JITed program is randomized and code page is marked as read-only.
In addition "constant blinding" can be turned on with net.core.bpf_jit_harden
v2->v3:
- move __bpf_prog_ret0 under ifdef (Daniel)
v1->v2:
- fix init order, test_bpf and cBPF (Daniel's feedback)
- fix offloaded bpf (Jakub's feedback)
- add 'return 0' dummy in case something can invoke prog->bpf_func
- retarget bpf tree. For bpf-next the patch would need one extra hunk.
It will be sent when the trees are merged back to net-next
Considered doing:
int bpf_jit_enable __read_mostly = BPF_EBPF_JIT_DEFAULT;
but it seems better to land the patch as-is and in bpf-next remove
bpf_jit_enable global variable from all JITs, consolidate in one place
and remove this jit_init() function.
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
2018-01-10 01:04:29 +07:00
|
|
|
if (*err) {
|
|
|
|
pr_cont("FAIL to select_runtime err=%d\n", *err);
|
|
|
|
return NULL;
|
|
|
|
}
|
2014-05-23 23:44:00 +07:00
|
|
|
break;
|
|
|
|
}
|
2014-05-09 04:10:52 +07:00
|
|
|
|
2014-05-23 23:44:00 +07:00
|
|
|
*err = 0;
|
|
|
|
return fp;
|
|
|
|
}
|
2014-05-09 04:10:52 +07:00
|
|
|
|
net: filter: split 'struct sk_filter' into socket and bpf parts
clean up names related to socket filtering and bpf in the following way:
- everything that deals with sockets keeps 'sk_*' prefix
- everything that is pure BPF is changed to 'bpf_*' prefix
split 'struct sk_filter' into
struct sk_filter {
atomic_t refcnt;
struct rcu_head rcu;
struct bpf_prog *prog;
};
and
struct bpf_prog {
u32 jited:1,
len:31;
struct sock_fprog_kern *orig_prog;
unsigned int (*bpf_func)(const struct sk_buff *skb,
const struct bpf_insn *filter);
union {
struct sock_filter insns[0];
struct bpf_insn insnsi[0];
struct work_struct work;
};
};
so that 'struct bpf_prog' can be used independent of sockets and cleans up
'unattached' bpf use cases
split SK_RUN_FILTER macro into:
SK_RUN_FILTER to be used with 'struct sk_filter *' and
BPF_PROG_RUN to be used with 'struct bpf_prog *'
__sk_filter_release(struct sk_filter *) gains
__bpf_prog_release(struct bpf_prog *) helper function
also perform related renames for the functions that work
with 'struct bpf_prog *', since they're on the same lines:
sk_filter_size -> bpf_prog_size
sk_filter_select_runtime -> bpf_prog_select_runtime
sk_filter_free -> bpf_prog_free
sk_unattached_filter_create -> bpf_prog_create
sk_unattached_filter_destroy -> bpf_prog_destroy
sk_store_orig_filter -> bpf_prog_store_orig_filter
sk_release_orig_filter -> bpf_release_orig_filter
__sk_migrate_filter -> bpf_migrate_filter
__sk_prepare_filter -> bpf_prepare_filter
API for attaching classic BPF to a socket stays the same:
sk_attach_filter(prog, struct sock *)/sk_detach_filter(struct sock *)
and SK_RUN_FILTER(struct sk_filter *, ctx) to execute a program
which is used by sockets, tun, af_packet
API for 'unattached' BPF programs becomes:
bpf_prog_create(struct bpf_prog **)/bpf_prog_destroy(struct bpf_prog *)
and BPF_PROG_RUN(struct bpf_prog *, ctx) to execute a program
which is used by isdn, ppp, team, seccomp, ptp, xt_bpf, cls_bpf, test_bpf
Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-07-31 10:34:16 +07:00
|
|
|
static void release_filter(struct bpf_prog *fp, int which)
|
2014-05-23 23:44:00 +07:00
|
|
|
{
|
|
|
|
__u8 test_type = tests[which].aux & TEST_TYPE_MASK;
|
2014-05-09 04:10:52 +07:00
|
|
|
|
2014-05-23 23:44:00 +07:00
|
|
|
switch (test_type) {
|
|
|
|
case CLASSIC:
|
net: filter: split 'struct sk_filter' into socket and bpf parts
clean up names related to socket filtering and bpf in the following way:
- everything that deals with sockets keeps 'sk_*' prefix
- everything that is pure BPF is changed to 'bpf_*' prefix
split 'struct sk_filter' into
struct sk_filter {
atomic_t refcnt;
struct rcu_head rcu;
struct bpf_prog *prog;
};
and
struct bpf_prog {
u32 jited:1,
len:31;
struct sock_fprog_kern *orig_prog;
unsigned int (*bpf_func)(const struct sk_buff *skb,
const struct bpf_insn *filter);
union {
struct sock_filter insns[0];
struct bpf_insn insnsi[0];
struct work_struct work;
};
};
so that 'struct bpf_prog' can be used independent of sockets and cleans up
'unattached' bpf use cases
split SK_RUN_FILTER macro into:
SK_RUN_FILTER to be used with 'struct sk_filter *' and
BPF_PROG_RUN to be used with 'struct bpf_prog *'
__sk_filter_release(struct sk_filter *) gains
__bpf_prog_release(struct bpf_prog *) helper function
also perform related renames for the functions that work
with 'struct bpf_prog *', since they're on the same lines:
sk_filter_size -> bpf_prog_size
sk_filter_select_runtime -> bpf_prog_select_runtime
sk_filter_free -> bpf_prog_free
sk_unattached_filter_create -> bpf_prog_create
sk_unattached_filter_destroy -> bpf_prog_destroy
sk_store_orig_filter -> bpf_prog_store_orig_filter
sk_release_orig_filter -> bpf_release_orig_filter
__sk_migrate_filter -> bpf_migrate_filter
__sk_prepare_filter -> bpf_prepare_filter
API for attaching classic BPF to a socket stays the same:
sk_attach_filter(prog, struct sock *)/sk_detach_filter(struct sock *)
and SK_RUN_FILTER(struct sk_filter *, ctx) to execute a program
which is used by sockets, tun, af_packet
API for 'unattached' BPF programs becomes:
bpf_prog_create(struct bpf_prog **)/bpf_prog_destroy(struct bpf_prog *)
and BPF_PROG_RUN(struct bpf_prog *, ctx) to execute a program
which is used by isdn, ppp, team, seccomp, ptp, xt_bpf, cls_bpf, test_bpf
Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-07-31 10:34:16 +07:00
|
|
|
bpf_prog_destroy(fp);
|
2014-05-23 23:44:00 +07:00
|
|
|
break;
|
|
|
|
case INTERNAL:
|
net: filter: split 'struct sk_filter' into socket and bpf parts
clean up names related to socket filtering and bpf in the following way:
- everything that deals with sockets keeps 'sk_*' prefix
- everything that is pure BPF is changed to 'bpf_*' prefix
split 'struct sk_filter' into
struct sk_filter {
atomic_t refcnt;
struct rcu_head rcu;
struct bpf_prog *prog;
};
and
struct bpf_prog {
u32 jited:1,
len:31;
struct sock_fprog_kern *orig_prog;
unsigned int (*bpf_func)(const struct sk_buff *skb,
const struct bpf_insn *filter);
union {
struct sock_filter insns[0];
struct bpf_insn insnsi[0];
struct work_struct work;
};
};
so that 'struct bpf_prog' can be used independent of sockets and cleans up
'unattached' bpf use cases
split SK_RUN_FILTER macro into:
SK_RUN_FILTER to be used with 'struct sk_filter *' and
BPF_PROG_RUN to be used with 'struct bpf_prog *'
__sk_filter_release(struct sk_filter *) gains
__bpf_prog_release(struct bpf_prog *) helper function
also perform related renames for the functions that work
with 'struct bpf_prog *', since they're on the same lines:
sk_filter_size -> bpf_prog_size
sk_filter_select_runtime -> bpf_prog_select_runtime
sk_filter_free -> bpf_prog_free
sk_unattached_filter_create -> bpf_prog_create
sk_unattached_filter_destroy -> bpf_prog_destroy
sk_store_orig_filter -> bpf_prog_store_orig_filter
sk_release_orig_filter -> bpf_release_orig_filter
__sk_migrate_filter -> bpf_migrate_filter
__sk_prepare_filter -> bpf_prepare_filter
API for attaching classic BPF to a socket stays the same:
sk_attach_filter(prog, struct sock *)/sk_detach_filter(struct sock *)
and SK_RUN_FILTER(struct sk_filter *, ctx) to execute a program
which is used by sockets, tun, af_packet
API for 'unattached' BPF programs becomes:
bpf_prog_create(struct bpf_prog **)/bpf_prog_destroy(struct bpf_prog *)
and BPF_PROG_RUN(struct bpf_prog *, ctx) to execute a program
which is used by isdn, ppp, team, seccomp, ptp, xt_bpf, cls_bpf, test_bpf
Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-07-31 10:34:16 +07:00
|
|
|
bpf_prog_free(fp);
|
2014-05-23 23:44:00 +07:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
net: filter: split 'struct sk_filter' into socket and bpf parts
clean up names related to socket filtering and bpf in the following way:
- everything that deals with sockets keeps 'sk_*' prefix
- everything that is pure BPF is changed to 'bpf_*' prefix
split 'struct sk_filter' into
struct sk_filter {
atomic_t refcnt;
struct rcu_head rcu;
struct bpf_prog *prog;
};
and
struct bpf_prog {
u32 jited:1,
len:31;
struct sock_fprog_kern *orig_prog;
unsigned int (*bpf_func)(const struct sk_buff *skb,
const struct bpf_insn *filter);
union {
struct sock_filter insns[0];
struct bpf_insn insnsi[0];
struct work_struct work;
};
};
so that 'struct bpf_prog' can be used independent of sockets and cleans up
'unattached' bpf use cases
split SK_RUN_FILTER macro into:
SK_RUN_FILTER to be used with 'struct sk_filter *' and
BPF_PROG_RUN to be used with 'struct bpf_prog *'
__sk_filter_release(struct sk_filter *) gains
__bpf_prog_release(struct bpf_prog *) helper function
also perform related renames for the functions that work
with 'struct bpf_prog *', since they're on the same lines:
sk_filter_size -> bpf_prog_size
sk_filter_select_runtime -> bpf_prog_select_runtime
sk_filter_free -> bpf_prog_free
sk_unattached_filter_create -> bpf_prog_create
sk_unattached_filter_destroy -> bpf_prog_destroy
sk_store_orig_filter -> bpf_prog_store_orig_filter
sk_release_orig_filter -> bpf_release_orig_filter
__sk_migrate_filter -> bpf_migrate_filter
__sk_prepare_filter -> bpf_prepare_filter
API for attaching classic BPF to a socket stays the same:
sk_attach_filter(prog, struct sock *)/sk_detach_filter(struct sock *)
and SK_RUN_FILTER(struct sk_filter *, ctx) to execute a program
which is used by sockets, tun, af_packet
API for 'unattached' BPF programs becomes:
bpf_prog_create(struct bpf_prog **)/bpf_prog_destroy(struct bpf_prog *)
and BPF_PROG_RUN(struct bpf_prog *, ctx) to execute a program
which is used by isdn, ppp, team, seccomp, ptp, xt_bpf, cls_bpf, test_bpf
Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-07-31 10:34:16 +07:00
|
|
|
static int __run_one(const struct bpf_prog *fp, const void *data,
|
2014-05-23 23:44:00 +07:00
|
|
|
int runs, u64 *duration)
|
|
|
|
{
|
|
|
|
u64 start, finish;
|
2014-09-20 03:53:51 +07:00
|
|
|
int ret = 0, i;
|
2014-05-23 23:44:00 +07:00
|
|
|
|
2015-07-21 10:34:19 +07:00
|
|
|
start = ktime_get_ns();
|
2014-05-23 23:44:00 +07:00
|
|
|
|
|
|
|
for (i = 0; i < runs; i++)
|
net: filter: split 'struct sk_filter' into socket and bpf parts
clean up names related to socket filtering and bpf in the following way:
- everything that deals with sockets keeps 'sk_*' prefix
- everything that is pure BPF is changed to 'bpf_*' prefix
split 'struct sk_filter' into
struct sk_filter {
atomic_t refcnt;
struct rcu_head rcu;
struct bpf_prog *prog;
};
and
struct bpf_prog {
u32 jited:1,
len:31;
struct sock_fprog_kern *orig_prog;
unsigned int (*bpf_func)(const struct sk_buff *skb,
const struct bpf_insn *filter);
union {
struct sock_filter insns[0];
struct bpf_insn insnsi[0];
struct work_struct work;
};
};
so that 'struct bpf_prog' can be used independent of sockets and cleans up
'unattached' bpf use cases
split SK_RUN_FILTER macro into:
SK_RUN_FILTER to be used with 'struct sk_filter *' and
BPF_PROG_RUN to be used with 'struct bpf_prog *'
__sk_filter_release(struct sk_filter *) gains
__bpf_prog_release(struct bpf_prog *) helper function
also perform related renames for the functions that work
with 'struct bpf_prog *', since they're on the same lines:
sk_filter_size -> bpf_prog_size
sk_filter_select_runtime -> bpf_prog_select_runtime
sk_filter_free -> bpf_prog_free
sk_unattached_filter_create -> bpf_prog_create
sk_unattached_filter_destroy -> bpf_prog_destroy
sk_store_orig_filter -> bpf_prog_store_orig_filter
sk_release_orig_filter -> bpf_release_orig_filter
__sk_migrate_filter -> bpf_migrate_filter
__sk_prepare_filter -> bpf_prepare_filter
API for attaching classic BPF to a socket stays the same:
sk_attach_filter(prog, struct sock *)/sk_detach_filter(struct sock *)
and SK_RUN_FILTER(struct sk_filter *, ctx) to execute a program
which is used by sockets, tun, af_packet
API for 'unattached' BPF programs becomes:
bpf_prog_create(struct bpf_prog **)/bpf_prog_destroy(struct bpf_prog *)
and BPF_PROG_RUN(struct bpf_prog *, ctx) to execute a program
which is used by isdn, ppp, team, seccomp, ptp, xt_bpf, cls_bpf, test_bpf
Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-07-31 10:34:16 +07:00
|
|
|
ret = BPF_PROG_RUN(fp, data);
|
2014-05-23 23:44:00 +07:00
|
|
|
|
2015-07-21 10:34:19 +07:00
|
|
|
finish = ktime_get_ns();
|
2014-05-23 23:44:00 +07:00
|
|
|
|
2015-07-21 10:34:19 +07:00
|
|
|
*duration = finish - start;
|
2014-05-23 23:44:00 +07:00
|
|
|
do_div(*duration, runs);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
net: filter: split 'struct sk_filter' into socket and bpf parts
clean up names related to socket filtering and bpf in the following way:
- everything that deals with sockets keeps 'sk_*' prefix
- everything that is pure BPF is changed to 'bpf_*' prefix
split 'struct sk_filter' into
struct sk_filter {
atomic_t refcnt;
struct rcu_head rcu;
struct bpf_prog *prog;
};
and
struct bpf_prog {
u32 jited:1,
len:31;
struct sock_fprog_kern *orig_prog;
unsigned int (*bpf_func)(const struct sk_buff *skb,
const struct bpf_insn *filter);
union {
struct sock_filter insns[0];
struct bpf_insn insnsi[0];
struct work_struct work;
};
};
so that 'struct bpf_prog' can be used independent of sockets and cleans up
'unattached' bpf use cases
split SK_RUN_FILTER macro into:
SK_RUN_FILTER to be used with 'struct sk_filter *' and
BPF_PROG_RUN to be used with 'struct bpf_prog *'
__sk_filter_release(struct sk_filter *) gains
__bpf_prog_release(struct bpf_prog *) helper function
also perform related renames for the functions that work
with 'struct bpf_prog *', since they're on the same lines:
sk_filter_size -> bpf_prog_size
sk_filter_select_runtime -> bpf_prog_select_runtime
sk_filter_free -> bpf_prog_free
sk_unattached_filter_create -> bpf_prog_create
sk_unattached_filter_destroy -> bpf_prog_destroy
sk_store_orig_filter -> bpf_prog_store_orig_filter
sk_release_orig_filter -> bpf_release_orig_filter
__sk_migrate_filter -> bpf_migrate_filter
__sk_prepare_filter -> bpf_prepare_filter
API for attaching classic BPF to a socket stays the same:
sk_attach_filter(prog, struct sock *)/sk_detach_filter(struct sock *)
and SK_RUN_FILTER(struct sk_filter *, ctx) to execute a program
which is used by sockets, tun, af_packet
API for 'unattached' BPF programs becomes:
bpf_prog_create(struct bpf_prog **)/bpf_prog_destroy(struct bpf_prog *)
and BPF_PROG_RUN(struct bpf_prog *, ctx) to execute a program
which is used by isdn, ppp, team, seccomp, ptp, xt_bpf, cls_bpf, test_bpf
Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-07-31 10:34:16 +07:00
|
|
|
static int run_one(const struct bpf_prog *fp, struct bpf_test *test)
|
2014-05-23 23:44:00 +07:00
|
|
|
{
|
|
|
|
int err_cnt = 0, i, runs = MAX_TESTRUNS;
|
|
|
|
|
|
|
|
for (i = 0; i < MAX_SUBTESTS; i++) {
|
|
|
|
void *data;
|
|
|
|
u64 duration;
|
|
|
|
u32 ret;
|
|
|
|
|
|
|
|
if (test->test[i].data_size == 0 &&
|
|
|
|
test->test[i].result == 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
data = generate_test_data(test, i);
|
2015-08-04 20:19:07 +07:00
|
|
|
if (!data && !(test->aux & FLAG_NO_DATA)) {
|
|
|
|
pr_cont("data generation failed ");
|
|
|
|
err_cnt++;
|
|
|
|
break;
|
|
|
|
}
|
2014-05-23 23:44:00 +07:00
|
|
|
ret = __run_one(fp, data, runs, &duration);
|
|
|
|
release_test_data(test, data);
|
|
|
|
|
|
|
|
if (ret == test->test[i].result) {
|
|
|
|
pr_cont("%lld ", duration);
|
|
|
|
} else {
|
|
|
|
pr_cont("ret %d != %d ", ret,
|
|
|
|
test->test[i].result);
|
2014-05-09 04:10:52 +07:00
|
|
|
err_cnt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return err_cnt;
|
|
|
|
}
|
|
|
|
|
2015-08-04 20:19:10 +07:00
|
|
|
static char test_name[64];
|
|
|
|
module_param_string(test_name, test_name, sizeof(test_name), 0);
|
|
|
|
|
|
|
|
static int test_id = -1;
|
|
|
|
module_param(test_id, int, 0);
|
|
|
|
|
|
|
|
static int test_range[2] = { 0, ARRAY_SIZE(tests) - 1 };
|
|
|
|
module_param_array(test_range, int, NULL, 0);
|
|
|
|
|
|
|
|
static __init int find_test_index(const char *test_name)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(tests); i++) {
|
|
|
|
if (!strcmp(tests[i].descr, test_name))
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2015-05-13 18:12:43 +07:00
|
|
|
static __init int prepare_bpf_tests(void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
2015-08-04 20:19:10 +07:00
|
|
|
if (test_id >= 0) {
|
|
|
|
/*
|
|
|
|
* if a test_id was specified, use test_range to
|
|
|
|
* cover only that test.
|
|
|
|
*/
|
|
|
|
if (test_id >= ARRAY_SIZE(tests)) {
|
|
|
|
pr_err("test_bpf: invalid test_id specified.\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
test_range[0] = test_id;
|
|
|
|
test_range[1] = test_id;
|
|
|
|
} else if (*test_name) {
|
|
|
|
/*
|
|
|
|
* if a test_name was specified, find it and setup
|
|
|
|
* test_range to cover only that test.
|
|
|
|
*/
|
|
|
|
int idx = find_test_index(test_name);
|
|
|
|
|
|
|
|
if (idx < 0) {
|
|
|
|
pr_err("test_bpf: no test named '%s' found.\n",
|
|
|
|
test_name);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
test_range[0] = idx;
|
|
|
|
test_range[1] = idx;
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* check that the supplied test_range is valid.
|
|
|
|
*/
|
|
|
|
if (test_range[0] >= ARRAY_SIZE(tests) ||
|
|
|
|
test_range[1] >= ARRAY_SIZE(tests) ||
|
|
|
|
test_range[0] < 0 || test_range[1] < 0) {
|
|
|
|
pr_err("test_bpf: test_range is out of bound.\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (test_range[1] < test_range[0]) {
|
|
|
|
pr_err("test_bpf: test_range is ending before it starts.\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-13 18:12:43 +07:00
|
|
|
for (i = 0; i < ARRAY_SIZE(tests); i++) {
|
|
|
|
if (tests[i].fill_helper &&
|
|
|
|
tests[i].fill_helper(&tests[i]) < 0)
|
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static __init void destroy_bpf_tests(void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(tests); i++) {
|
|
|
|
if (tests[i].fill_helper)
|
|
|
|
kfree(tests[i].u.ptr.insns);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-04 20:19:10 +07:00
|
|
|
static bool exclude_test(int test_id)
|
|
|
|
{
|
|
|
|
return test_id < test_range[0] || test_id > test_range[1];
|
|
|
|
}
|
|
|
|
|
2018-03-22 06:31:04 +07:00
|
|
|
static __init struct sk_buff *build_test_skb(void)
|
|
|
|
{
|
|
|
|
u32 headroom = NET_SKB_PAD + NET_IP_ALIGN + ETH_HLEN;
|
|
|
|
struct sk_buff *skb[2];
|
|
|
|
struct page *page[2];
|
|
|
|
int i, data_size = 8;
|
|
|
|
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
|
|
page[i] = alloc_page(GFP_KERNEL);
|
|
|
|
if (!page[i]) {
|
|
|
|
if (i == 0)
|
|
|
|
goto err_page0;
|
|
|
|
else
|
|
|
|
goto err_page1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* this will set skb[i]->head_frag */
|
|
|
|
skb[i] = dev_alloc_skb(headroom + data_size);
|
|
|
|
if (!skb[i]) {
|
|
|
|
if (i == 0)
|
|
|
|
goto err_skb0;
|
|
|
|
else
|
|
|
|
goto err_skb1;
|
|
|
|
}
|
|
|
|
|
|
|
|
skb_reserve(skb[i], headroom);
|
|
|
|
skb_put(skb[i], data_size);
|
|
|
|
skb[i]->protocol = htons(ETH_P_IP);
|
|
|
|
skb_reset_network_header(skb[i]);
|
|
|
|
skb_set_mac_header(skb[i], -ETH_HLEN);
|
|
|
|
|
|
|
|
skb_add_rx_frag(skb[i], 0, page[i], 0, 64, 64);
|
|
|
|
// skb_headlen(skb[i]): 8, skb[i]->head_frag = 1
|
|
|
|
}
|
|
|
|
|
|
|
|
/* setup shinfo */
|
|
|
|
skb_shinfo(skb[0])->gso_size = 1448;
|
|
|
|
skb_shinfo(skb[0])->gso_type = SKB_GSO_TCPV4;
|
|
|
|
skb_shinfo(skb[0])->gso_type |= SKB_GSO_DODGY;
|
|
|
|
skb_shinfo(skb[0])->gso_segs = 0;
|
|
|
|
skb_shinfo(skb[0])->frag_list = skb[1];
|
|
|
|
|
|
|
|
/* adjust skb[0]'s len */
|
|
|
|
skb[0]->len += skb[1]->len;
|
|
|
|
skb[0]->data_len += skb[1]->data_len;
|
|
|
|
skb[0]->truesize += skb[1]->truesize;
|
|
|
|
|
|
|
|
return skb[0];
|
|
|
|
|
|
|
|
err_skb1:
|
|
|
|
__free_page(page[1]);
|
|
|
|
err_page1:
|
|
|
|
kfree_skb(skb[0]);
|
|
|
|
err_skb0:
|
|
|
|
__free_page(page[0]);
|
|
|
|
err_page0:
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static __init int test_skb_segment(void)
|
|
|
|
{
|
|
|
|
netdev_features_t features;
|
|
|
|
struct sk_buff *skb, *segs;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
features = NETIF_F_SG | NETIF_F_GSO_PARTIAL | NETIF_F_IP_CSUM |
|
|
|
|
NETIF_F_IPV6_CSUM;
|
|
|
|
features |= NETIF_F_RXCSUM;
|
|
|
|
skb = build_test_skb();
|
|
|
|
if (!skb) {
|
|
|
|
pr_info("%s: failed to build_test_skb", __func__);
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
segs = skb_segment(skb, features);
|
2018-03-28 18:48:36 +07:00
|
|
|
if (!IS_ERR(segs)) {
|
2018-03-22 06:31:04 +07:00
|
|
|
kfree_skb_list(segs);
|
|
|
|
ret = 0;
|
|
|
|
pr_info("%s: success in skb_segment!", __func__);
|
|
|
|
} else {
|
|
|
|
pr_info("%s: failed in skb_segment!", __func__);
|
|
|
|
}
|
|
|
|
kfree_skb(skb);
|
|
|
|
done:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2014-05-09 04:10:52 +07:00
|
|
|
static __init int test_bpf(void)
|
|
|
|
{
|
2014-05-23 23:44:00 +07:00
|
|
|
int i, err_cnt = 0, pass_cnt = 0;
|
2015-04-30 21:17:27 +07:00
|
|
|
int jit_cnt = 0, run_cnt = 0;
|
2014-05-09 04:10:52 +07:00
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(tests); i++) {
|
net: filter: split 'struct sk_filter' into socket and bpf parts
clean up names related to socket filtering and bpf in the following way:
- everything that deals with sockets keeps 'sk_*' prefix
- everything that is pure BPF is changed to 'bpf_*' prefix
split 'struct sk_filter' into
struct sk_filter {
atomic_t refcnt;
struct rcu_head rcu;
struct bpf_prog *prog;
};
and
struct bpf_prog {
u32 jited:1,
len:31;
struct sock_fprog_kern *orig_prog;
unsigned int (*bpf_func)(const struct sk_buff *skb,
const struct bpf_insn *filter);
union {
struct sock_filter insns[0];
struct bpf_insn insnsi[0];
struct work_struct work;
};
};
so that 'struct bpf_prog' can be used independent of sockets and cleans up
'unattached' bpf use cases
split SK_RUN_FILTER macro into:
SK_RUN_FILTER to be used with 'struct sk_filter *' and
BPF_PROG_RUN to be used with 'struct bpf_prog *'
__sk_filter_release(struct sk_filter *) gains
__bpf_prog_release(struct bpf_prog *) helper function
also perform related renames for the functions that work
with 'struct bpf_prog *', since they're on the same lines:
sk_filter_size -> bpf_prog_size
sk_filter_select_runtime -> bpf_prog_select_runtime
sk_filter_free -> bpf_prog_free
sk_unattached_filter_create -> bpf_prog_create
sk_unattached_filter_destroy -> bpf_prog_destroy
sk_store_orig_filter -> bpf_prog_store_orig_filter
sk_release_orig_filter -> bpf_release_orig_filter
__sk_migrate_filter -> bpf_migrate_filter
__sk_prepare_filter -> bpf_prepare_filter
API for attaching classic BPF to a socket stays the same:
sk_attach_filter(prog, struct sock *)/sk_detach_filter(struct sock *)
and SK_RUN_FILTER(struct sk_filter *, ctx) to execute a program
which is used by sockets, tun, af_packet
API for 'unattached' BPF programs becomes:
bpf_prog_create(struct bpf_prog **)/bpf_prog_destroy(struct bpf_prog *)
and BPF_PROG_RUN(struct bpf_prog *, ctx) to execute a program
which is used by isdn, ppp, team, seccomp, ptp, xt_bpf, cls_bpf, test_bpf
Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-07-31 10:34:16 +07:00
|
|
|
struct bpf_prog *fp;
|
2014-05-23 23:44:00 +07:00
|
|
|
int err;
|
2014-05-09 04:10:52 +07:00
|
|
|
|
2018-02-27 01:52:46 +07:00
|
|
|
cond_resched();
|
2015-08-04 20:19:10 +07:00
|
|
|
if (exclude_test(i))
|
|
|
|
continue;
|
|
|
|
|
2014-05-23 23:44:00 +07:00
|
|
|
pr_info("#%d %s ", i, tests[i].descr);
|
2014-05-09 04:10:52 +07:00
|
|
|
|
2014-05-23 23:44:00 +07:00
|
|
|
fp = generate_filter(i, &err);
|
|
|
|
if (fp == NULL) {
|
|
|
|
if (err == 0) {
|
|
|
|
pass_cnt++;
|
|
|
|
continue;
|
2014-05-09 04:10:52 +07:00
|
|
|
}
|
bpf: introduce BPF_JIT_ALWAYS_ON config
The BPF interpreter has been used as part of the spectre 2 attack CVE-2017-5715.
A quote from goolge project zero blog:
"At this point, it would normally be necessary to locate gadgets in
the host kernel code that can be used to actually leak data by reading
from an attacker-controlled location, shifting and masking the result
appropriately and then using the result of that as offset to an
attacker-controlled address for a load. But piecing gadgets together
and figuring out which ones work in a speculation context seems annoying.
So instead, we decided to use the eBPF interpreter, which is built into
the host kernel - while there is no legitimate way to invoke it from inside
a VM, the presence of the code in the host kernel's text section is sufficient
to make it usable for the attack, just like with ordinary ROP gadgets."
To make attacker job harder introduce BPF_JIT_ALWAYS_ON config
option that removes interpreter from the kernel in favor of JIT-only mode.
So far eBPF JIT is supported by:
x64, arm64, arm32, sparc64, s390, powerpc64, mips64
The start of JITed program is randomized and code page is marked as read-only.
In addition "constant blinding" can be turned on with net.core.bpf_jit_harden
v2->v3:
- move __bpf_prog_ret0 under ifdef (Daniel)
v1->v2:
- fix init order, test_bpf and cBPF (Daniel's feedback)
- fix offloaded bpf (Jakub's feedback)
- add 'return 0' dummy in case something can invoke prog->bpf_func
- retarget bpf tree. For bpf-next the patch would need one extra hunk.
It will be sent when the trees are merged back to net-next
Considered doing:
int bpf_jit_enable __read_mostly = BPF_EBPF_JIT_DEFAULT;
but it seems better to land the patch as-is and in bpf-next remove
bpf_jit_enable global variable from all JITs, consolidate in one place
and remove this jit_init() function.
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
2018-01-10 01:04:29 +07:00
|
|
|
err_cnt++;
|
|
|
|
continue;
|
2014-05-23 23:44:00 +07:00
|
|
|
}
|
2015-04-30 21:17:27 +07:00
|
|
|
|
|
|
|
pr_cont("jited:%u ", fp->jited);
|
|
|
|
|
|
|
|
run_cnt++;
|
|
|
|
if (fp->jited)
|
|
|
|
jit_cnt++;
|
|
|
|
|
2014-05-09 04:10:52 +07:00
|
|
|
err = run_one(fp, &tests[i]);
|
2014-05-23 23:44:00 +07:00
|
|
|
release_filter(fp, i);
|
2014-05-09 04:10:52 +07:00
|
|
|
|
|
|
|
if (err) {
|
2014-05-23 23:44:00 +07:00
|
|
|
pr_cont("FAIL (%d times)\n", err);
|
2014-05-09 04:10:52 +07:00
|
|
|
err_cnt++;
|
|
|
|
} else {
|
|
|
|
pr_cont("PASS\n");
|
2014-05-23 23:44:00 +07:00
|
|
|
pass_cnt++;
|
2014-05-09 04:10:52 +07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-30 21:17:27 +07:00
|
|
|
pr_info("Summary: %d PASSED, %d FAILED, [%d/%d JIT'ed]\n",
|
|
|
|
pass_cnt, err_cnt, jit_cnt, run_cnt);
|
|
|
|
|
2014-05-23 23:44:00 +07:00
|
|
|
return err_cnt ? -EINVAL : 0;
|
2014-05-09 04:10:52 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
static int __init test_bpf_init(void)
|
|
|
|
{
|
2015-05-13 18:12:43 +07:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = prepare_bpf_tests();
|
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
ret = test_bpf();
|
|
|
|
destroy_bpf_tests();
|
2018-03-22 06:31:04 +07:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
return test_skb_segment();
|
2014-05-09 04:10:52 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void __exit test_bpf_exit(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
module_init(test_bpf_init);
|
|
|
|
module_exit(test_bpf_exit);
|
2014-05-23 23:44:00 +07:00
|
|
|
|
2014-05-09 04:10:52 +07:00
|
|
|
MODULE_LICENSE("GPL");
|