OSDN Git Service

Revert "usb: dwc3: turn off VBUS when leaving host mode"
[sagit-ice-cold/kernel_xiaomi_msm8998.git] / kernel / bpf / arraymap.c
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  * 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.
11  */
12 #include <linux/bpf.h>
13 #include <linux/err.h>
14 #include <linux/vmalloc.h>
15 #include <linux/slab.h>
16 #include <linux/mm.h>
17 #include <linux/filter.h>
18 #include <linux/perf_event.h>
19
20 /* Called from syscall */
21 static struct bpf_map *array_map_alloc(union bpf_attr *attr)
22 {
23         u32 elem_size, array_size, index_mask, max_entries;
24         bool unpriv = !capable(CAP_SYS_ADMIN);
25         struct bpf_array *array;
26         u64 mask64;
27
28         /* check sanity of attributes */
29         if (attr->max_entries == 0 || attr->key_size != 4 ||
30             attr->value_size == 0)
31                 return ERR_PTR(-EINVAL);
32
33         if (attr->value_size >= 1 << (KMALLOC_SHIFT_MAX - 1))
34                 /* if value_size is bigger, the user space won't be able to
35                  * access the elements.
36                  */
37                 return ERR_PTR(-E2BIG);
38
39         elem_size = round_up(attr->value_size, 8);
40
41         max_entries = attr->max_entries;
42
43         /* On 32 bit archs roundup_pow_of_two() with max_entries that has
44          * upper most bit set in u32 space is undefined behavior due to
45          * resulting 1U << 32, so do it manually here in u64 space.
46          */
47         mask64 = fls_long(max_entries - 1);
48         mask64 = 1ULL << mask64;
49         mask64 -= 1;
50
51         index_mask = mask64;
52         if (unpriv) {
53                 /* round up array size to nearest power of 2,
54                  * since cpu will speculate within index_mask limits
55                  */
56                 max_entries = index_mask + 1;
57                 /* Check for overflows. */
58                 if (max_entries < attr->max_entries)
59                         return ERR_PTR(-E2BIG);
60         }
61
62         /* check round_up into zero and u32 overflow */
63         if (elem_size == 0 ||
64             max_entries > (U32_MAX - PAGE_SIZE - sizeof(*array)) / elem_size)
65                 return ERR_PTR(-ENOMEM);
66
67         array_size = sizeof(*array) + max_entries * elem_size;
68
69         /* allocate all map elements and zero-initialize them */
70         array = kzalloc(array_size, GFP_USER | __GFP_NOWARN);
71         if (!array) {
72                 array = vzalloc(array_size);
73                 if (!array)
74                         return ERR_PTR(-ENOMEM);
75         }
76         array->index_mask = index_mask;
77         array->map.unpriv_array = unpriv;
78
79         /* copy mandatory map attributes */
80         array->map.key_size = attr->key_size;
81         array->map.value_size = attr->value_size;
82         array->map.max_entries = attr->max_entries;
83         array->map.pages = round_up(array_size, PAGE_SIZE) >> PAGE_SHIFT;
84         array->elem_size = elem_size;
85
86         return &array->map;
87 }
88
89 /* Called from syscall or from eBPF program */
90 static void *array_map_lookup_elem(struct bpf_map *map, void *key)
91 {
92         struct bpf_array *array = container_of(map, struct bpf_array, map);
93         u32 index = *(u32 *)key;
94
95         if (index >= array->map.max_entries)
96                 return NULL;
97
98         return array->value + array->elem_size * (index & array->index_mask);
99 }
100
101 /* Called from syscall */
102 static int array_map_get_next_key(struct bpf_map *map, void *key, void *next_key)
103 {
104         struct bpf_array *array = container_of(map, struct bpf_array, map);
105         u32 index = key ? *(u32 *)key : U32_MAX;
106         u32 *next = (u32 *)next_key;
107
108         if (index >= array->map.max_entries) {
109                 *next = 0;
110                 return 0;
111         }
112
113         if (index == array->map.max_entries - 1)
114                 return -ENOENT;
115
116         *next = index + 1;
117         return 0;
118 }
119
120 /* Called from syscall or from eBPF program */
121 static int array_map_update_elem(struct bpf_map *map, void *key, void *value,
122                                  u64 map_flags)
123 {
124         struct bpf_array *array = container_of(map, struct bpf_array, map);
125         u32 index = *(u32 *)key;
126
127         if (map_flags > BPF_EXIST)
128                 /* unknown flags */
129                 return -EINVAL;
130
131         if (index >= array->map.max_entries)
132                 /* all elements were pre-allocated, cannot insert a new one */
133                 return -E2BIG;
134
135         if (map_flags == BPF_NOEXIST)
136                 /* all elements already exist */
137                 return -EEXIST;
138
139         memcpy(array->value +
140                array->elem_size * (index & array->index_mask),
141                value, map->value_size);
142         return 0;
143 }
144
145 /* Called from syscall or from eBPF program */
146 static int array_map_delete_elem(struct bpf_map *map, void *key)
147 {
148         return -EINVAL;
149 }
150
151 /* Called when map->refcnt goes to zero, either from workqueue or from syscall */
152 static void array_map_free(struct bpf_map *map)
153 {
154         struct bpf_array *array = container_of(map, struct bpf_array, map);
155
156         /* at this point bpf_prog->aux->refcnt == 0 and this map->refcnt == 0,
157          * so the programs (can be more than one that used this map) were
158          * disconnected from events. Wait for outstanding programs to complete
159          * and free the array
160          */
161         synchronize_rcu();
162
163         kvfree(array);
164 }
165
166 static const struct bpf_map_ops array_ops = {
167         .map_alloc = array_map_alloc,
168         .map_free = array_map_free,
169         .map_get_next_key = array_map_get_next_key,
170         .map_lookup_elem = array_map_lookup_elem,
171         .map_update_elem = array_map_update_elem,
172         .map_delete_elem = array_map_delete_elem,
173 };
174
175 static struct bpf_map_type_list array_type __read_mostly = {
176         .ops = &array_ops,
177         .type = BPF_MAP_TYPE_ARRAY,
178 };
179
180 static int __init register_array_map(void)
181 {
182         bpf_register_map_type(&array_type);
183         return 0;
184 }
185 late_initcall(register_array_map);
186
187 static struct bpf_map *fd_array_map_alloc(union bpf_attr *attr)
188 {
189         /* only file descriptors can be stored in this type of map */
190         if (attr->value_size != sizeof(u32))
191                 return ERR_PTR(-EINVAL);
192         return array_map_alloc(attr);
193 }
194
195 static void fd_array_map_free(struct bpf_map *map)
196 {
197         struct bpf_array *array = container_of(map, struct bpf_array, map);
198         int i;
199
200         synchronize_rcu();
201
202         /* make sure it's empty */
203         for (i = 0; i < array->map.max_entries; i++)
204                 BUG_ON(array->ptrs[i] != NULL);
205         kvfree(array);
206 }
207
208 static void *fd_array_map_lookup_elem(struct bpf_map *map, void *key)
209 {
210         return NULL;
211 }
212
213 /* only called from syscall */
214 static int fd_array_map_update_elem(struct bpf_map *map, void *key,
215                                     void *value, u64 map_flags)
216 {
217         struct bpf_array *array = container_of(map, struct bpf_array, map);
218         void *new_ptr, *old_ptr;
219         u32 index = *(u32 *)key, ufd;
220
221         if (map_flags != BPF_ANY)
222                 return -EINVAL;
223
224         if (index >= array->map.max_entries)
225                 return -E2BIG;
226
227         ufd = *(u32 *)value;
228         new_ptr = map->ops->map_fd_get_ptr(map, ufd);
229         if (IS_ERR(new_ptr))
230                 return PTR_ERR(new_ptr);
231
232         old_ptr = xchg(array->ptrs + index, new_ptr);
233         if (old_ptr)
234                 map->ops->map_fd_put_ptr(old_ptr);
235
236         return 0;
237 }
238
239 static int fd_array_map_delete_elem(struct bpf_map *map, void *key)
240 {
241         struct bpf_array *array = container_of(map, struct bpf_array, map);
242         void *old_ptr;
243         u32 index = *(u32 *)key;
244
245         if (index >= array->map.max_entries)
246                 return -E2BIG;
247
248         old_ptr = xchg(array->ptrs + index, NULL);
249         if (old_ptr) {
250                 map->ops->map_fd_put_ptr(old_ptr);
251                 return 0;
252         } else {
253                 return -ENOENT;
254         }
255 }
256
257 static void *prog_fd_array_get_ptr(struct bpf_map *map, int fd)
258 {
259         struct bpf_array *array = container_of(map, struct bpf_array, map);
260         struct bpf_prog *prog = bpf_prog_get(fd);
261         if (IS_ERR(prog))
262                 return prog;
263
264         if (!bpf_prog_array_compatible(array, prog)) {
265                 bpf_prog_put(prog);
266                 return ERR_PTR(-EINVAL);
267         }
268         return prog;
269 }
270
271 static void prog_fd_array_put_ptr(void *ptr)
272 {
273         bpf_prog_put(ptr);
274 }
275
276 /* decrement refcnt of all bpf_progs that are stored in this map */
277 void bpf_fd_array_map_clear(struct bpf_map *map)
278 {
279         struct bpf_array *array = container_of(map, struct bpf_array, map);
280         int i;
281
282         for (i = 0; i < array->map.max_entries; i++)
283                 fd_array_map_delete_elem(map, &i);
284 }
285
286 static const struct bpf_map_ops prog_array_ops = {
287         .map_alloc = fd_array_map_alloc,
288         .map_free = fd_array_map_free,
289         .map_get_next_key = array_map_get_next_key,
290         .map_lookup_elem = fd_array_map_lookup_elem,
291         .map_update_elem = fd_array_map_update_elem,
292         .map_delete_elem = fd_array_map_delete_elem,
293         .map_fd_get_ptr = prog_fd_array_get_ptr,
294         .map_fd_put_ptr = prog_fd_array_put_ptr,
295 };
296
297 static struct bpf_map_type_list prog_array_type __read_mostly = {
298         .ops = &prog_array_ops,
299         .type = BPF_MAP_TYPE_PROG_ARRAY,
300 };
301
302 static int __init register_prog_array_map(void)
303 {
304         bpf_register_map_type(&prog_array_type);
305         return 0;
306 }
307 late_initcall(register_prog_array_map);
308
309 static void perf_event_array_map_free(struct bpf_map *map)
310 {
311         bpf_fd_array_map_clear(map);
312         fd_array_map_free(map);
313 }
314
315 static void *perf_event_fd_array_get_ptr(struct bpf_map *map, int fd)
316 {
317         struct perf_event *event;
318         const struct perf_event_attr *attr;
319
320         event = perf_event_get(fd);
321         if (IS_ERR(event))
322                 return event;
323
324         attr = perf_event_attrs(event);
325         if (IS_ERR(attr))
326                 goto err;
327
328         if (attr->inherit)
329                 goto err;
330
331         if (attr->type == PERF_TYPE_RAW)
332                 return event;
333
334         if (attr->type == PERF_TYPE_HARDWARE)
335                 return event;
336
337         if (attr->type == PERF_TYPE_SOFTWARE &&
338             attr->config == PERF_COUNT_SW_BPF_OUTPUT)
339                 return event;
340 err:
341         perf_event_release_kernel(event);
342         return ERR_PTR(-EINVAL);
343 }
344
345 static void perf_event_fd_array_put_ptr(void *ptr)
346 {
347         struct perf_event *event = ptr;
348
349         perf_event_release_kernel(event);
350 }
351
352 static const struct bpf_map_ops perf_event_array_ops = {
353         .map_alloc = fd_array_map_alloc,
354         .map_free = perf_event_array_map_free,
355         .map_get_next_key = array_map_get_next_key,
356         .map_lookup_elem = fd_array_map_lookup_elem,
357         .map_update_elem = fd_array_map_update_elem,
358         .map_delete_elem = fd_array_map_delete_elem,
359         .map_fd_get_ptr = perf_event_fd_array_get_ptr,
360         .map_fd_put_ptr = perf_event_fd_array_put_ptr,
361 };
362
363 static struct bpf_map_type_list perf_event_array_type __read_mostly = {
364         .ops = &perf_event_array_ops,
365         .type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
366 };
367
368 static int __init register_perf_event_array_map(void)
369 {
370         bpf_register_map_type(&perf_event_array_type);
371         return 0;
372 }
373 late_initcall(register_perf_event_array_map);