1 /* Copyright (c) 2011-2014 PLUMgrid, http://plumgrid.com
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.
7 * This program is distributed in the hope that it will be useful, but
8 * WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * General Public License for more details.
12 #include <linux/bpf.h>
13 #include <linux/rcupdate.h>
14 #include <linux/random.h>
15 #include <linux/smp.h>
17 /* If kernel subsystem is allowing eBPF programs to call this function,
18 * inside its own verifier_ops->get_func_proto() callback it should return
19 * bpf_map_lookup_elem_proto, so that verifier can properly check the arguments
21 * Different map implementations will rely on rcu in map methods
22 * lookup/update/delete, therefore eBPF programs must run under rcu lock
23 * if program is allowed to access maps, so check rcu_read_lock_held in
24 * all three functions.
26 static u64
bpf_map_lookup_elem(u64 r1
, u64 r2
, u64 r3
, u64 r4
, u64 r5
)
28 /* verifier checked that R1 contains a valid pointer to bpf_map
29 * and R2 points to a program stack and map->key_size bytes were
32 struct bpf_map
*map
= (struct bpf_map
*) (unsigned long) r1
;
33 void *key
= (void *) (unsigned long) r2
;
36 WARN_ON_ONCE(!rcu_read_lock_held());
38 value
= map
->ops
->map_lookup_elem(map
, key
);
40 /* lookup() returns either pointer to element value or NULL
41 * which is the meaning of PTR_TO_MAP_VALUE_OR_NULL type
43 return (unsigned long) value
;
46 const struct bpf_func_proto bpf_map_lookup_elem_proto
= {
47 .func
= bpf_map_lookup_elem
,
49 .ret_type
= RET_PTR_TO_MAP_VALUE_OR_NULL
,
50 .arg1_type
= ARG_CONST_MAP_PTR
,
51 .arg2_type
= ARG_PTR_TO_MAP_KEY
,
54 static u64
bpf_map_update_elem(u64 r1
, u64 r2
, u64 r3
, u64 r4
, u64 r5
)
56 struct bpf_map
*map
= (struct bpf_map
*) (unsigned long) r1
;
57 void *key
= (void *) (unsigned long) r2
;
58 void *value
= (void *) (unsigned long) r3
;
60 WARN_ON_ONCE(!rcu_read_lock_held());
62 return map
->ops
->map_update_elem(map
, key
, value
, r4
);
65 const struct bpf_func_proto bpf_map_update_elem_proto
= {
66 .func
= bpf_map_update_elem
,
68 .ret_type
= RET_INTEGER
,
69 .arg1_type
= ARG_CONST_MAP_PTR
,
70 .arg2_type
= ARG_PTR_TO_MAP_KEY
,
71 .arg3_type
= ARG_PTR_TO_MAP_VALUE
,
72 .arg4_type
= ARG_ANYTHING
,
75 static u64
bpf_map_delete_elem(u64 r1
, u64 r2
, u64 r3
, u64 r4
, u64 r5
)
77 struct bpf_map
*map
= (struct bpf_map
*) (unsigned long) r1
;
78 void *key
= (void *) (unsigned long) r2
;
80 WARN_ON_ONCE(!rcu_read_lock_held());
82 return map
->ops
->map_delete_elem(map
, key
);
85 const struct bpf_func_proto bpf_map_delete_elem_proto
= {
86 .func
= bpf_map_delete_elem
,
88 .ret_type
= RET_INTEGER
,
89 .arg1_type
= ARG_CONST_MAP_PTR
,
90 .arg2_type
= ARG_PTR_TO_MAP_KEY
,
93 static u64
bpf_get_prandom_u32(u64 r1
, u64 r2
, u64 r3
, u64 r4
, u64 r5
)
98 const struct bpf_func_proto bpf_get_prandom_u32_proto
= {
99 .func
= bpf_get_prandom_u32
,
101 .ret_type
= RET_INTEGER
,
104 static u64
bpf_get_smp_processor_id(u64 r1
, u64 r2
, u64 r3
, u64 r4
, u64 r5
)
106 return raw_smp_processor_id();
109 const struct bpf_func_proto bpf_get_smp_processor_id_proto
= {
110 .func
= bpf_get_smp_processor_id
,
112 .ret_type
= RET_INTEGER
,