diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/bpf/Makefile | 4 | ||||
-rw-r--r-- | kernel/bpf/test_stub.c | 116 |
2 files changed, 120 insertions, 0 deletions
diff --git a/kernel/bpf/Makefile b/kernel/bpf/Makefile index 3c726b0995b7..45427239f375 100644 --- a/kernel/bpf/Makefile +++ b/kernel/bpf/Makefile | |||
@@ -1 +1,5 @@ | |||
1 | obj-y := core.o syscall.o verifier.o | 1 | obj-y := core.o syscall.o verifier.o |
2 | |||
3 | ifdef CONFIG_TEST_BPF | ||
4 | obj-y += test_stub.o | ||
5 | endif | ||
diff --git a/kernel/bpf/test_stub.c b/kernel/bpf/test_stub.c new file mode 100644 index 000000000000..fcaddff4003e --- /dev/null +++ b/kernel/bpf/test_stub.c | |||
@@ -0,0 +1,116 @@ | |||
1 | /* Copyright (c) 2011-2014 PLUMgrid, http://plumgrid.com | ||
2 | * | ||
3 | * This program is free software; you can redistribute it and/or | ||
4 | * modify it under the terms of version 2 of the GNU General Public | ||
5 | * License as published by the Free Software Foundation. | ||
6 | */ | ||
7 | #include <linux/kernel.h> | ||
8 | #include <linux/types.h> | ||
9 | #include <linux/slab.h> | ||
10 | #include <linux/err.h> | ||
11 | #include <linux/bpf.h> | ||
12 | |||
13 | /* test stubs for BPF_MAP_TYPE_UNSPEC and for BPF_PROG_TYPE_UNSPEC | ||
14 | * to be used by user space verifier testsuite | ||
15 | */ | ||
16 | struct bpf_context { | ||
17 | u64 arg1; | ||
18 | u64 arg2; | ||
19 | }; | ||
20 | |||
21 | static u64 test_func(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5) | ||
22 | { | ||
23 | return 0; | ||
24 | } | ||
25 | |||
26 | static struct bpf_func_proto test_funcs[] = { | ||
27 | [BPF_FUNC_unspec] = { | ||
28 | .func = test_func, | ||
29 | .gpl_only = true, | ||
30 | .ret_type = RET_PTR_TO_MAP_VALUE_OR_NULL, | ||
31 | .arg1_type = ARG_CONST_MAP_PTR, | ||
32 | .arg2_type = ARG_PTR_TO_MAP_KEY, | ||
33 | }, | ||
34 | }; | ||
35 | |||
36 | static const struct bpf_func_proto *test_func_proto(enum bpf_func_id func_id) | ||
37 | { | ||
38 | if (func_id < 0 || func_id >= ARRAY_SIZE(test_funcs)) | ||
39 | return NULL; | ||
40 | return &test_funcs[func_id]; | ||
41 | } | ||
42 | |||
43 | static const struct bpf_context_access { | ||
44 | int size; | ||
45 | enum bpf_access_type type; | ||
46 | } test_ctx_access[] = { | ||
47 | [offsetof(struct bpf_context, arg1)] = { | ||
48 | FIELD_SIZEOF(struct bpf_context, arg1), | ||
49 | BPF_READ | ||
50 | }, | ||
51 | [offsetof(struct bpf_context, arg2)] = { | ||
52 | FIELD_SIZEOF(struct bpf_context, arg2), | ||
53 | BPF_READ | ||
54 | }, | ||
55 | }; | ||
56 | |||
57 | static bool test_is_valid_access(int off, int size, enum bpf_access_type type) | ||
58 | { | ||
59 | const struct bpf_context_access *access; | ||
60 | |||
61 | if (off < 0 || off >= ARRAY_SIZE(test_ctx_access)) | ||
62 | return false; | ||
63 | |||
64 | access = &test_ctx_access[off]; | ||
65 | if (access->size == size && (access->type & type)) | ||
66 | return true; | ||
67 | |||
68 | return false; | ||
69 | } | ||
70 | |||
71 | static struct bpf_verifier_ops test_ops = { | ||
72 | .get_func_proto = test_func_proto, | ||
73 | .is_valid_access = test_is_valid_access, | ||
74 | }; | ||
75 | |||
76 | static struct bpf_prog_type_list tl_prog = { | ||
77 | .ops = &test_ops, | ||
78 | .type = BPF_PROG_TYPE_UNSPEC, | ||
79 | }; | ||
80 | |||
81 | static struct bpf_map *test_map_alloc(union bpf_attr *attr) | ||
82 | { | ||
83 | struct bpf_map *map; | ||
84 | |||
85 | map = kzalloc(sizeof(*map), GFP_USER); | ||
86 | if (!map) | ||
87 | return ERR_PTR(-ENOMEM); | ||
88 | |||
89 | map->key_size = attr->key_size; | ||
90 | map->value_size = attr->value_size; | ||
91 | map->max_entries = attr->max_entries; | ||
92 | return map; | ||
93 | } | ||
94 | |||
95 | static void test_map_free(struct bpf_map *map) | ||
96 | { | ||
97 | kfree(map); | ||
98 | } | ||
99 | |||
100 | static struct bpf_map_ops test_map_ops = { | ||
101 | .map_alloc = test_map_alloc, | ||
102 | .map_free = test_map_free, | ||
103 | }; | ||
104 | |||
105 | static struct bpf_map_type_list tl_map = { | ||
106 | .ops = &test_map_ops, | ||
107 | .type = BPF_MAP_TYPE_UNSPEC, | ||
108 | }; | ||
109 | |||
110 | static int __init register_test_ops(void) | ||
111 | { | ||
112 | bpf_register_map_type(&tl_map); | ||
113 | bpf_register_prog_type(&tl_prog); | ||
114 | return 0; | ||
115 | } | ||
116 | late_initcall(register_test_ops); | ||