aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2018-07-29 00:02:21 -0400
committerDavid S. Miller <davem@davemloft.net>2018-07-29 00:02:21 -0400
commit958b4cd8fa4c2eff0c257b07f2bb753b7c7a6f52 (patch)
treecc6a3a903383ded1ab81996266098a5a4beedea8
parentb0753408aadf32c7ece9e6b765017881e54af833 (diff)
parent71eb5255f55bdb484d35ff7c9a1803f453dfbf82 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
Daniel Borkmann says: ==================== pull-request: bpf 2018-07-28 The following pull-request contains BPF updates for your *net* tree. The main changes are: 1) API fixes for libbpf's BTF mapping of map key/value types in order to make them compatible with iproute2's BPF_ANNOTATE_KV_PAIR() markings, from Martin. 2) Fix AF_XDP to not report POLLIN prematurely by using the non-cached consumer pointer of the RX queue, from Björn. 3) Fix __xdp_return() to check for NULL pointer after the rhashtable lookup that retrieves the allocator object, from Taehee. 4) Fix x86-32 JIT to adjust ebp register in prologue and epilogue by 4 bytes which got removed from overall stack usage, from Wang. 5) Fix bpf_skb_load_bytes_relative() length check to use actual packet length, from Daniel. 6) Fix uninitialized return code in libbpf bpf_perf_event_read_simple() handler, from Thomas. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--arch/x86/net/bpf_jit_comp32.c8
-rw-r--r--kernel/bpf/arraymap.c2
-rw-r--r--kernel/bpf/btf.c14
-rw-r--r--net/core/filter.c12
-rw-r--r--net/core/lwt_bpf.c2
-rw-r--r--net/core/xdp.c3
-rw-r--r--net/xdp/xsk_queue.h2
-rw-r--r--tools/include/uapi/linux/btf.h2
-rw-r--r--tools/lib/bpf/btf.c39
-rw-r--r--tools/lib/bpf/btf.h10
-rw-r--r--tools/lib/bpf/libbpf.c87
-rw-r--r--tools/lib/bpf/libbpf.h4
-rw-r--r--tools/testing/selftests/bpf/bpf_helpers.h9
-rw-r--r--tools/testing/selftests/bpf/test_btf.c114
-rw-r--r--tools/testing/selftests/bpf/test_btf_haskv.c7
15 files changed, 225 insertions, 90 deletions
diff --git a/arch/x86/net/bpf_jit_comp32.c b/arch/x86/net/bpf_jit_comp32.c
index 55799873ebe5..8f6cc71e0848 100644
--- a/arch/x86/net/bpf_jit_comp32.c
+++ b/arch/x86/net/bpf_jit_comp32.c
@@ -1441,8 +1441,8 @@ static void emit_prologue(u8 **pprog, u32 stack_depth)
1441 1441
1442 /* sub esp,STACK_SIZE */ 1442 /* sub esp,STACK_SIZE */
1443 EMIT2_off32(0x81, 0xEC, STACK_SIZE); 1443 EMIT2_off32(0x81, 0xEC, STACK_SIZE);
1444 /* sub ebp,SCRATCH_SIZE+4+12*/ 1444 /* sub ebp,SCRATCH_SIZE+12*/
1445 EMIT3(0x83, add_1reg(0xE8, IA32_EBP), SCRATCH_SIZE + 16); 1445 EMIT3(0x83, add_1reg(0xE8, IA32_EBP), SCRATCH_SIZE + 12);
1446 /* xor ebx,ebx */ 1446 /* xor ebx,ebx */
1447 EMIT2(0x31, add_2reg(0xC0, IA32_EBX, IA32_EBX)); 1447 EMIT2(0x31, add_2reg(0xC0, IA32_EBX, IA32_EBX));
1448 1448
@@ -1475,8 +1475,8 @@ static void emit_epilogue(u8 **pprog, u32 stack_depth)
1475 /* mov edx,dword ptr [ebp+off]*/ 1475 /* mov edx,dword ptr [ebp+off]*/
1476 EMIT3(0x8B, add_2reg(0x40, IA32_EBP, IA32_EDX), STACK_VAR(r0[1])); 1476 EMIT3(0x8B, add_2reg(0x40, IA32_EBP, IA32_EDX), STACK_VAR(r0[1]));
1477 1477
1478 /* add ebp,SCRATCH_SIZE+4+12*/ 1478 /* add ebp,SCRATCH_SIZE+12*/
1479 EMIT3(0x83, add_1reg(0xC0, IA32_EBP), SCRATCH_SIZE + 16); 1479 EMIT3(0x83, add_1reg(0xC0, IA32_EBP), SCRATCH_SIZE + 12);
1480 1480
1481 /* mov ebx,dword ptr [ebp-12]*/ 1481 /* mov ebx,dword ptr [ebp-12]*/
1482 EMIT3(0x8B, add_2reg(0x40, IA32_EBP, IA32_EBX), -12); 1482 EMIT3(0x8B, add_2reg(0x40, IA32_EBP, IA32_EBX), -12);
diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c
index 544e58f5f642..2aa55d030c77 100644
--- a/kernel/bpf/arraymap.c
+++ b/kernel/bpf/arraymap.c
@@ -378,7 +378,7 @@ static int array_map_check_btf(const struct bpf_map *map, const struct btf *btf,
378 return -EINVAL; 378 return -EINVAL;
379 379
380 value_type = btf_type_id_size(btf, &btf_value_id, &value_size); 380 value_type = btf_type_id_size(btf, &btf_value_id, &value_size);
381 if (!value_type || value_size > map->value_size) 381 if (!value_type || value_size != map->value_size)
382 return -EINVAL; 382 return -EINVAL;
383 383
384 return 0; 384 return 0;
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index 9704934252b3..2590700237c1 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -1519,9 +1519,9 @@ static s32 btf_struct_check_meta(struct btf_verifier_env *env,
1519{ 1519{
1520 bool is_union = BTF_INFO_KIND(t->info) == BTF_KIND_UNION; 1520 bool is_union = BTF_INFO_KIND(t->info) == BTF_KIND_UNION;
1521 const struct btf_member *member; 1521 const struct btf_member *member;
1522 u32 meta_needed, last_offset;
1522 struct btf *btf = env->btf; 1523 struct btf *btf = env->btf;
1523 u32 struct_size = t->size; 1524 u32 struct_size = t->size;
1524 u32 meta_needed;
1525 u16 i; 1525 u16 i;
1526 1526
1527 meta_needed = btf_type_vlen(t) * sizeof(*member); 1527 meta_needed = btf_type_vlen(t) * sizeof(*member);
@@ -1534,6 +1534,7 @@ static s32 btf_struct_check_meta(struct btf_verifier_env *env,
1534 1534
1535 btf_verifier_log_type(env, t, NULL); 1535 btf_verifier_log_type(env, t, NULL);
1536 1536
1537 last_offset = 0;
1537 for_each_member(i, t, member) { 1538 for_each_member(i, t, member) {
1538 if (!btf_name_offset_valid(btf, member->name_off)) { 1539 if (!btf_name_offset_valid(btf, member->name_off)) {
1539 btf_verifier_log_member(env, t, member, 1540 btf_verifier_log_member(env, t, member,
@@ -1555,6 +1556,16 @@ static s32 btf_struct_check_meta(struct btf_verifier_env *env,
1555 return -EINVAL; 1556 return -EINVAL;
1556 } 1557 }
1557 1558
1559 /*
1560 * ">" instead of ">=" because the last member could be
1561 * "char a[0];"
1562 */
1563 if (last_offset > member->offset) {
1564 btf_verifier_log_member(env, t, member,
1565 "Invalid member bits_offset");
1566 return -EINVAL;
1567 }
1568
1558 if (BITS_ROUNDUP_BYTES(member->offset) > struct_size) { 1569 if (BITS_ROUNDUP_BYTES(member->offset) > struct_size) {
1559 btf_verifier_log_member(env, t, member, 1570 btf_verifier_log_member(env, t, member,
1560 "Memmber bits_offset exceeds its struct size"); 1571 "Memmber bits_offset exceeds its struct size");
@@ -1562,6 +1573,7 @@ static s32 btf_struct_check_meta(struct btf_verifier_env *env,
1562 } 1573 }
1563 1574
1564 btf_verifier_log_member(env, t, member, NULL); 1575 btf_verifier_log_member(env, t, member, NULL);
1576 last_offset = member->offset;
1565 } 1577 }
1566 1578
1567 return meta_needed; 1579 return meta_needed;
diff --git a/net/core/filter.c b/net/core/filter.c
index 06da770f543f..9dfd145eedcc 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -1712,24 +1712,26 @@ static const struct bpf_func_proto bpf_skb_load_bytes_proto = {
1712BPF_CALL_5(bpf_skb_load_bytes_relative, const struct sk_buff *, skb, 1712BPF_CALL_5(bpf_skb_load_bytes_relative, const struct sk_buff *, skb,
1713 u32, offset, void *, to, u32, len, u32, start_header) 1713 u32, offset, void *, to, u32, len, u32, start_header)
1714{ 1714{
1715 u8 *end = skb_tail_pointer(skb);
1716 u8 *net = skb_network_header(skb);
1717 u8 *mac = skb_mac_header(skb);
1715 u8 *ptr; 1718 u8 *ptr;
1716 1719
1717 if (unlikely(offset > 0xffff || len > skb_headlen(skb))) 1720 if (unlikely(offset > 0xffff || len > (end - mac)))
1718 goto err_clear; 1721 goto err_clear;
1719 1722
1720 switch (start_header) { 1723 switch (start_header) {
1721 case BPF_HDR_START_MAC: 1724 case BPF_HDR_START_MAC:
1722 ptr = skb_mac_header(skb) + offset; 1725 ptr = mac + offset;
1723 break; 1726 break;
1724 case BPF_HDR_START_NET: 1727 case BPF_HDR_START_NET:
1725 ptr = skb_network_header(skb) + offset; 1728 ptr = net + offset;
1726 break; 1729 break;
1727 default: 1730 default:
1728 goto err_clear; 1731 goto err_clear;
1729 } 1732 }
1730 1733
1731 if (likely(ptr >= skb_mac_header(skb) && 1734 if (likely(ptr >= mac && ptr + len <= end)) {
1732 ptr + len <= skb_tail_pointer(skb))) {
1733 memcpy(to, ptr, len); 1735 memcpy(to, ptr, len);
1734 return 0; 1736 return 0;
1735 } 1737 }
diff --git a/net/core/lwt_bpf.c b/net/core/lwt_bpf.c
index e7e626fb87bb..e45098593dc0 100644
--- a/net/core/lwt_bpf.c
+++ b/net/core/lwt_bpf.c
@@ -217,7 +217,7 @@ static int bpf_parse_prog(struct nlattr *attr, struct bpf_lwt_prog *prog,
217 if (!tb[LWT_BPF_PROG_FD] || !tb[LWT_BPF_PROG_NAME]) 217 if (!tb[LWT_BPF_PROG_FD] || !tb[LWT_BPF_PROG_NAME])
218 return -EINVAL; 218 return -EINVAL;
219 219
220 prog->name = nla_memdup(tb[LWT_BPF_PROG_NAME], GFP_KERNEL); 220 prog->name = nla_memdup(tb[LWT_BPF_PROG_NAME], GFP_ATOMIC);
221 if (!prog->name) 221 if (!prog->name)
222 return -ENOMEM; 222 return -ENOMEM;
223 223
diff --git a/net/core/xdp.c b/net/core/xdp.c
index 9d1f22072d5d..6771f1855b96 100644
--- a/net/core/xdp.c
+++ b/net/core/xdp.c
@@ -345,7 +345,8 @@ static void __xdp_return(void *data, struct xdp_mem_info *mem, bool napi_direct,
345 rcu_read_lock(); 345 rcu_read_lock();
346 /* mem->id is valid, checked in xdp_rxq_info_reg_mem_model() */ 346 /* mem->id is valid, checked in xdp_rxq_info_reg_mem_model() */
347 xa = rhashtable_lookup(mem_id_ht, &mem->id, mem_id_rht_params); 347 xa = rhashtable_lookup(mem_id_ht, &mem->id, mem_id_rht_params);
348 xa->zc_alloc->free(xa->zc_alloc, handle); 348 if (!WARN_ON_ONCE(!xa))
349 xa->zc_alloc->free(xa->zc_alloc, handle);
349 rcu_read_unlock(); 350 rcu_read_unlock();
350 default: 351 default:
351 /* Not possible, checked in xdp_rxq_info_reg_mem_model() */ 352 /* Not possible, checked in xdp_rxq_info_reg_mem_model() */
diff --git a/net/xdp/xsk_queue.h b/net/xdp/xsk_queue.h
index 52ecaf770642..8a64b150be54 100644
--- a/net/xdp/xsk_queue.h
+++ b/net/xdp/xsk_queue.h
@@ -250,7 +250,7 @@ static inline bool xskq_full_desc(struct xsk_queue *q)
250 250
251static inline bool xskq_empty_desc(struct xsk_queue *q) 251static inline bool xskq_empty_desc(struct xsk_queue *q)
252{ 252{
253 return xskq_nb_free(q, q->prod_tail, 1) == q->nentries; 253 return xskq_nb_free(q, q->prod_tail, q->nentries) == q->nentries;
254} 254}
255 255
256void xskq_set_umem(struct xsk_queue *q, struct xdp_umem_props *umem_props); 256void xskq_set_umem(struct xsk_queue *q, struct xdp_umem_props *umem_props);
diff --git a/tools/include/uapi/linux/btf.h b/tools/include/uapi/linux/btf.h
index 0b5ddbe135a4..972265f32871 100644
--- a/tools/include/uapi/linux/btf.h
+++ b/tools/include/uapi/linux/btf.h
@@ -76,7 +76,7 @@ struct btf_type {
76 */ 76 */
77#define BTF_INT_ENCODING(VAL) (((VAL) & 0x0f000000) >> 24) 77#define BTF_INT_ENCODING(VAL) (((VAL) & 0x0f000000) >> 24)
78#define BTF_INT_OFFSET(VAL) (((VAL & 0x00ff0000)) >> 16) 78#define BTF_INT_OFFSET(VAL) (((VAL & 0x00ff0000)) >> 16)
79#define BTF_INT_BITS(VAL) ((VAL) & 0x0000ffff) 79#define BTF_INT_BITS(VAL) ((VAL) & 0x000000ff)
80 80
81/* Attributes stored in the BTF_INT_ENCODING */ 81/* Attributes stored in the BTF_INT_ENCODING */
82#define BTF_INT_SIGNED (1 << 0) 82#define BTF_INT_SIGNED (1 << 0)
diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
index 8c54a4b6f187..2d270c560df3 100644
--- a/tools/lib/bpf/btf.c
+++ b/tools/lib/bpf/btf.c
@@ -2,7 +2,6 @@
2/* Copyright (c) 2018 Facebook */ 2/* Copyright (c) 2018 Facebook */
3 3
4#include <stdlib.h> 4#include <stdlib.h>
5#include <stdint.h>
6#include <string.h> 5#include <string.h>
7#include <unistd.h> 6#include <unistd.h>
8#include <errno.h> 7#include <errno.h>
@@ -27,13 +26,13 @@ struct btf {
27 struct btf_type **types; 26 struct btf_type **types;
28 const char *strings; 27 const char *strings;
29 void *nohdr_data; 28 void *nohdr_data;
30 uint32_t nr_types; 29 __u32 nr_types;
31 uint32_t types_size; 30 __u32 types_size;
32 uint32_t data_size; 31 __u32 data_size;
33 int fd; 32 int fd;
34}; 33};
35 34
36static const char *btf_name_by_offset(const struct btf *btf, uint32_t offset) 35static const char *btf_name_by_offset(const struct btf *btf, __u32 offset)
37{ 36{
38 if (offset < btf->hdr->str_len) 37 if (offset < btf->hdr->str_len)
39 return &btf->strings[offset]; 38 return &btf->strings[offset];
@@ -45,7 +44,7 @@ static int btf_add_type(struct btf *btf, struct btf_type *t)
45{ 44{
46 if (btf->types_size - btf->nr_types < 2) { 45 if (btf->types_size - btf->nr_types < 2) {
47 struct btf_type **new_types; 46 struct btf_type **new_types;
48 u32 expand_by, new_size; 47 __u32 expand_by, new_size;
49 48
50 if (btf->types_size == BTF_MAX_NR_TYPES) 49 if (btf->types_size == BTF_MAX_NR_TYPES)
51 return -E2BIG; 50 return -E2BIG;
@@ -72,7 +71,7 @@ static int btf_add_type(struct btf *btf, struct btf_type *t)
72static int btf_parse_hdr(struct btf *btf, btf_print_fn_t err_log) 71static int btf_parse_hdr(struct btf *btf, btf_print_fn_t err_log)
73{ 72{
74 const struct btf_header *hdr = btf->hdr; 73 const struct btf_header *hdr = btf->hdr;
75 u32 meta_left; 74 __u32 meta_left;
76 75
77 if (btf->data_size < sizeof(struct btf_header)) { 76 if (btf->data_size < sizeof(struct btf_header)) {
78 elog("BTF header not found\n"); 77 elog("BTF header not found\n");
@@ -151,7 +150,7 @@ static int btf_parse_type_sec(struct btf *btf, btf_print_fn_t err_log)
151 150
152 while (next_type < end_type) { 151 while (next_type < end_type) {
153 struct btf_type *t = next_type; 152 struct btf_type *t = next_type;
154 uint16_t vlen = BTF_INFO_VLEN(t->info); 153 __u16 vlen = BTF_INFO_VLEN(t->info);
155 int err; 154 int err;
156 155
157 next_type += sizeof(*t); 156 next_type += sizeof(*t);
@@ -190,8 +189,7 @@ static int btf_parse_type_sec(struct btf *btf, btf_print_fn_t err_log)
190 return 0; 189 return 0;
191} 190}
192 191
193static const struct btf_type *btf_type_by_id(const struct btf *btf, 192const struct btf_type *btf__type_by_id(const struct btf *btf, __u32 type_id)
194 uint32_t type_id)
195{ 193{
196 if (type_id > btf->nr_types) 194 if (type_id > btf->nr_types)
197 return NULL; 195 return NULL;
@@ -209,7 +207,7 @@ static bool btf_type_is_void_or_null(const struct btf_type *t)
209 return !t || btf_type_is_void(t); 207 return !t || btf_type_is_void(t);
210} 208}
211 209
212static int64_t btf_type_size(const struct btf_type *t) 210static __s64 btf_type_size(const struct btf_type *t)
213{ 211{
214 switch (BTF_INFO_KIND(t->info)) { 212 switch (BTF_INFO_KIND(t->info)) {
215 case BTF_KIND_INT: 213 case BTF_KIND_INT:
@@ -226,15 +224,15 @@ static int64_t btf_type_size(const struct btf_type *t)
226 224
227#define MAX_RESOLVE_DEPTH 32 225#define MAX_RESOLVE_DEPTH 32
228 226
229int64_t btf__resolve_size(const struct btf *btf, uint32_t type_id) 227__s64 btf__resolve_size(const struct btf *btf, __u32 type_id)
230{ 228{
231 const struct btf_array *array; 229 const struct btf_array *array;
232 const struct btf_type *t; 230 const struct btf_type *t;
233 uint32_t nelems = 1; 231 __u32 nelems = 1;
234 int64_t size = -1; 232 __s64 size = -1;
235 int i; 233 int i;
236 234
237 t = btf_type_by_id(btf, type_id); 235 t = btf__type_by_id(btf, type_id);
238 for (i = 0; i < MAX_RESOLVE_DEPTH && !btf_type_is_void_or_null(t); 236 for (i = 0; i < MAX_RESOLVE_DEPTH && !btf_type_is_void_or_null(t);
239 i++) { 237 i++) {
240 size = btf_type_size(t); 238 size = btf_type_size(t);
@@ -259,7 +257,7 @@ int64_t btf__resolve_size(const struct btf *btf, uint32_t type_id)
259 return -EINVAL; 257 return -EINVAL;
260 } 258 }
261 259
262 t = btf_type_by_id(btf, type_id); 260 t = btf__type_by_id(btf, type_id);
263 } 261 }
264 262
265 if (size < 0) 263 if (size < 0)
@@ -271,9 +269,9 @@ int64_t btf__resolve_size(const struct btf *btf, uint32_t type_id)
271 return nelems * size; 269 return nelems * size;
272} 270}
273 271
274int32_t btf__find_by_name(const struct btf *btf, const char *type_name) 272__s32 btf__find_by_name(const struct btf *btf, const char *type_name)
275{ 273{
276 uint32_t i; 274 __u32 i;
277 275
278 if (!strcmp(type_name, "void")) 276 if (!strcmp(type_name, "void"))
279 return 0; 277 return 0;
@@ -302,10 +300,9 @@ void btf__free(struct btf *btf)
302 free(btf); 300 free(btf);
303} 301}
304 302
305struct btf *btf__new(uint8_t *data, uint32_t size, 303struct btf *btf__new(__u8 *data, __u32 size, btf_print_fn_t err_log)
306 btf_print_fn_t err_log)
307{ 304{
308 uint32_t log_buf_size = 0; 305 __u32 log_buf_size = 0;
309 char *log_buf = NULL; 306 char *log_buf = NULL;
310 struct btf *btf; 307 struct btf *btf;
311 int err; 308 int err;
diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h
index 74bb344035bb..e2a09a155f84 100644
--- a/tools/lib/bpf/btf.h
+++ b/tools/lib/bpf/btf.h
@@ -4,19 +4,21 @@
4#ifndef __BPF_BTF_H 4#ifndef __BPF_BTF_H
5#define __BPF_BTF_H 5#define __BPF_BTF_H
6 6
7#include <stdint.h> 7#include <linux/types.h>
8 8
9#define BTF_ELF_SEC ".BTF" 9#define BTF_ELF_SEC ".BTF"
10 10
11struct btf; 11struct btf;
12struct btf_type;
12 13
13typedef int (*btf_print_fn_t)(const char *, ...) 14typedef int (*btf_print_fn_t)(const char *, ...)
14 __attribute__((format(printf, 1, 2))); 15 __attribute__((format(printf, 1, 2)));
15 16
16void btf__free(struct btf *btf); 17void btf__free(struct btf *btf);
17struct btf *btf__new(uint8_t *data, uint32_t size, btf_print_fn_t err_log); 18struct btf *btf__new(__u8 *data, __u32 size, btf_print_fn_t err_log);
18int32_t btf__find_by_name(const struct btf *btf, const char *type_name); 19__s32 btf__find_by_name(const struct btf *btf, const char *type_name);
19int64_t btf__resolve_size(const struct btf *btf, uint32_t type_id); 20const struct btf_type *btf__type_by_id(const struct btf *btf, __u32 id);
21__s64 btf__resolve_size(const struct btf *btf, __u32 type_id);
20int btf__fd(const struct btf *btf); 22int btf__fd(const struct btf *btf);
21 23
22#endif 24#endif
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index a1e96b5de5ff..1aafdbe827fe 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -36,6 +36,7 @@
36#include <linux/err.h> 36#include <linux/err.h>
37#include <linux/kernel.h> 37#include <linux/kernel.h>
38#include <linux/bpf.h> 38#include <linux/bpf.h>
39#include <linux/btf.h>
39#include <linux/list.h> 40#include <linux/list.h>
40#include <linux/limits.h> 41#include <linux/limits.h>
41#include <sys/stat.h> 42#include <sys/stat.h>
@@ -216,8 +217,8 @@ struct bpf_map {
216 size_t offset; 217 size_t offset;
217 int map_ifindex; 218 int map_ifindex;
218 struct bpf_map_def def; 219 struct bpf_map_def def;
219 uint32_t btf_key_type_id; 220 __u32 btf_key_type_id;
220 uint32_t btf_value_type_id; 221 __u32 btf_value_type_id;
221 void *priv; 222 void *priv;
222 bpf_map_clear_priv_t clear_priv; 223 bpf_map_clear_priv_t clear_priv;
223}; 224};
@@ -1014,68 +1015,72 @@ bpf_program__collect_reloc(struct bpf_program *prog, GElf_Shdr *shdr,
1014 1015
1015static int bpf_map_find_btf_info(struct bpf_map *map, const struct btf *btf) 1016static int bpf_map_find_btf_info(struct bpf_map *map, const struct btf *btf)
1016{ 1017{
1018 const struct btf_type *container_type;
1019 const struct btf_member *key, *value;
1017 struct bpf_map_def *def = &map->def; 1020 struct bpf_map_def *def = &map->def;
1018 const size_t max_name = 256; 1021 const size_t max_name = 256;
1019 int64_t key_size, value_size; 1022 char container_name[max_name];
1020 int32_t key_id, value_id; 1023 __s64 key_size, value_size;
1021 char name[max_name]; 1024 __s32 container_id;
1022 1025
1023 /* Find key type by name from BTF */ 1026 if (snprintf(container_name, max_name, "____btf_map_%s", map->name) ==
1024 if (snprintf(name, max_name, "%s_key", map->name) == max_name) { 1027 max_name) {
1025 pr_warning("map:%s length of BTF key_type:%s_key is too long\n", 1028 pr_warning("map:%s length of '____btf_map_%s' is too long\n",
1026 map->name, map->name); 1029 map->name, map->name);
1027 return -EINVAL; 1030 return -EINVAL;
1028 } 1031 }
1029 1032
1030 key_id = btf__find_by_name(btf, name); 1033 container_id = btf__find_by_name(btf, container_name);
1031 if (key_id < 0) { 1034 if (container_id < 0) {
1032 pr_debug("map:%s key_type:%s cannot be found in BTF\n", 1035 pr_debug("map:%s container_name:%s cannot be found in BTF. Missing BPF_ANNOTATE_KV_PAIR?\n",
1033 map->name, name); 1036 map->name, container_name);
1034 return key_id; 1037 return container_id;
1035 } 1038 }
1036 1039
1037 key_size = btf__resolve_size(btf, key_id); 1040 container_type = btf__type_by_id(btf, container_id);
1038 if (key_size < 0) { 1041 if (!container_type) {
1039 pr_warning("map:%s key_type:%s cannot get the BTF type_size\n", 1042 pr_warning("map:%s cannot find BTF type for container_id:%u\n",
1040 map->name, name); 1043 map->name, container_id);
1041 return key_size; 1044 return -EINVAL;
1042 } 1045 }
1043 1046
1044 if (def->key_size != key_size) { 1047 if (BTF_INFO_KIND(container_type->info) != BTF_KIND_STRUCT ||
1045 pr_warning("map:%s key_type:%s has BTF type_size:%u != key_size:%u\n", 1048 BTF_INFO_VLEN(container_type->info) < 2) {
1046 map->name, name, (unsigned int)key_size, def->key_size); 1049 pr_warning("map:%s container_name:%s is an invalid container struct\n",
1050 map->name, container_name);
1047 return -EINVAL; 1051 return -EINVAL;
1048 } 1052 }
1049 1053
1050 /* Find value type from BTF */ 1054 key = (struct btf_member *)(container_type + 1);
1051 if (snprintf(name, max_name, "%s_value", map->name) == max_name) { 1055 value = key + 1;
1052 pr_warning("map:%s length of BTF value_type:%s_value is too long\n", 1056
1053 map->name, map->name); 1057 key_size = btf__resolve_size(btf, key->type);
1054 return -EINVAL; 1058 if (key_size < 0) {
1059 pr_warning("map:%s invalid BTF key_type_size\n",
1060 map->name);
1061 return key_size;
1055 } 1062 }
1056 1063
1057 value_id = btf__find_by_name(btf, name); 1064 if (def->key_size != key_size) {
1058 if (value_id < 0) { 1065 pr_warning("map:%s btf_key_type_size:%u != map_def_key_size:%u\n",
1059 pr_debug("map:%s value_type:%s cannot be found in BTF\n", 1066 map->name, (__u32)key_size, def->key_size);
1060 map->name, name); 1067 return -EINVAL;
1061 return value_id;
1062 } 1068 }
1063 1069
1064 value_size = btf__resolve_size(btf, value_id); 1070 value_size = btf__resolve_size(btf, value->type);
1065 if (value_size < 0) { 1071 if (value_size < 0) {
1066 pr_warning("map:%s value_type:%s cannot get the BTF type_size\n", 1072 pr_warning("map:%s invalid BTF value_type_size\n", map->name);
1067 map->name, name);
1068 return value_size; 1073 return value_size;
1069 } 1074 }
1070 1075
1071 if (def->value_size != value_size) { 1076 if (def->value_size != value_size) {
1072 pr_warning("map:%s value_type:%s has BTF type_size:%u != value_size:%u\n", 1077 pr_warning("map:%s btf_value_type_size:%u != map_def_value_size:%u\n",
1073 map->name, name, (unsigned int)value_size, def->value_size); 1078 map->name, (__u32)value_size, def->value_size);
1074 return -EINVAL; 1079 return -EINVAL;
1075 } 1080 }
1076 1081
1077 map->btf_key_type_id = key_id; 1082 map->btf_key_type_id = key->type;
1078 map->btf_value_type_id = value_id; 1083 map->btf_value_type_id = value->type;
1079 1084
1080 return 0; 1085 return 0;
1081} 1086}
@@ -2089,12 +2094,12 @@ const char *bpf_map__name(struct bpf_map *map)
2089 return map ? map->name : NULL; 2094 return map ? map->name : NULL;
2090} 2095}
2091 2096
2092uint32_t bpf_map__btf_key_type_id(const struct bpf_map *map) 2097__u32 bpf_map__btf_key_type_id(const struct bpf_map *map)
2093{ 2098{
2094 return map ? map->btf_key_type_id : 0; 2099 return map ? map->btf_key_type_id : 0;
2095} 2100}
2096 2101
2097uint32_t bpf_map__btf_value_type_id(const struct bpf_map *map) 2102__u32 bpf_map__btf_value_type_id(const struct bpf_map *map)
2098{ 2103{
2099 return map ? map->btf_value_type_id : 0; 2104 return map ? map->btf_value_type_id : 0;
2100} 2105}
@@ -2268,8 +2273,8 @@ bpf_perf_event_read_simple(void *mem, unsigned long size,
2268 volatile struct perf_event_mmap_page *header = mem; 2273 volatile struct perf_event_mmap_page *header = mem;
2269 __u64 data_tail = header->data_tail; 2274 __u64 data_tail = header->data_tail;
2270 __u64 data_head = header->data_head; 2275 __u64 data_head = header->data_head;
2276 int ret = LIBBPF_PERF_EVENT_ERROR;
2271 void *base, *begin, *end; 2277 void *base, *begin, *end;
2272 int ret;
2273 2278
2274 asm volatile("" ::: "memory"); /* in real code it should be smp_rmb() */ 2279 asm volatile("" ::: "memory"); /* in real code it should be smp_rmb() */
2275 if (data_head == data_tail) 2280 if (data_head == data_tail)
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 09976531aa74..b33ae02f7d0e 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -244,8 +244,8 @@ bpf_map__next(struct bpf_map *map, struct bpf_object *obj);
244int bpf_map__fd(struct bpf_map *map); 244int bpf_map__fd(struct bpf_map *map);
245const struct bpf_map_def *bpf_map__def(struct bpf_map *map); 245const struct bpf_map_def *bpf_map__def(struct bpf_map *map);
246const char *bpf_map__name(struct bpf_map *map); 246const char *bpf_map__name(struct bpf_map *map);
247uint32_t bpf_map__btf_key_type_id(const struct bpf_map *map); 247__u32 bpf_map__btf_key_type_id(const struct bpf_map *map);
248uint32_t bpf_map__btf_value_type_id(const struct bpf_map *map); 248__u32 bpf_map__btf_value_type_id(const struct bpf_map *map);
249 249
250typedef void (*bpf_map_clear_priv_t)(struct bpf_map *, void *); 250typedef void (*bpf_map_clear_priv_t)(struct bpf_map *, void *);
251int bpf_map__set_priv(struct bpf_map *map, void *priv, 251int bpf_map__set_priv(struct bpf_map *map, void *priv,
diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h
index f2f28b6c8915..810de20e8e26 100644
--- a/tools/testing/selftests/bpf/bpf_helpers.h
+++ b/tools/testing/selftests/bpf/bpf_helpers.h
@@ -158,6 +158,15 @@ struct bpf_map_def {
158 unsigned int numa_node; 158 unsigned int numa_node;
159}; 159};
160 160
161#define BPF_ANNOTATE_KV_PAIR(name, type_key, type_val) \
162 struct ____btf_map_##name { \
163 type_key key; \
164 type_val value; \
165 }; \
166 struct ____btf_map_##name \
167 __attribute__ ((section(".maps." #name), used)) \
168 ____btf_map_##name = { }
169
161static int (*bpf_skb_load_bytes)(void *ctx, int off, void *to, int len) = 170static int (*bpf_skb_load_bytes)(void *ctx, int off, void *to, int len) =
162 (void *) BPF_FUNC_skb_load_bytes; 171 (void *) BPF_FUNC_skb_load_bytes;
163static int (*bpf_skb_store_bytes)(void *ctx, int off, void *from, int len, int flags) = 172static int (*bpf_skb_store_bytes)(void *ctx, int off, void *from, int len, int flags) =
diff --git a/tools/testing/selftests/bpf/test_btf.c b/tools/testing/selftests/bpf/test_btf.c
index 3619f3023088..ffdd27737c9e 100644
--- a/tools/testing/selftests/bpf/test_btf.c
+++ b/tools/testing/selftests/bpf/test_btf.c
@@ -247,6 +247,34 @@ static struct btf_raw_test raw_tests[] = {
247 .max_entries = 4, 247 .max_entries = 4,
248}, 248},
249 249
250{
251 .descr = "struct test #3 Invalid member offset",
252 .raw_types = {
253 /* int */ /* [1] */
254 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
255 /* int64 */ /* [2] */
256 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 64, 8),
257
258 /* struct A { */ /* [3] */
259 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 16),
260 BTF_MEMBER_ENC(NAME_TBD, 1, 64), /* int m; */
261 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* int64 n; */
262 /* } */
263 BTF_END_RAW,
264 },
265 .str_sec = "\0A\0m\0n\0",
266 .str_sec_size = sizeof("\0A\0m\0n\0"),
267 .map_type = BPF_MAP_TYPE_ARRAY,
268 .map_name = "struct_test3_map",
269 .key_size = sizeof(int),
270 .value_size = 16,
271 .key_type_id = 1,
272 .value_type_id = 3,
273 .max_entries = 4,
274 .btf_load_err = true,
275 .err_str = "Invalid member bits_offset",
276},
277
250/* Test member exceeds the size of struct. 278/* Test member exceeds the size of struct.
251 * 279 *
252 * struct A { 280 * struct A {
@@ -479,7 +507,7 @@ static struct btf_raw_test raw_tests[] = {
479 .key_size = sizeof(int), 507 .key_size = sizeof(int),
480 .value_size = sizeof(void *) * 4, 508 .value_size = sizeof(void *) * 4,
481 .key_type_id = 1, 509 .key_type_id = 1,
482 .value_type_id = 4, 510 .value_type_id = 5,
483 .max_entries = 4, 511 .max_entries = 4,
484}, 512},
485 513
@@ -1264,6 +1292,88 @@ static struct btf_raw_test raw_tests[] = {
1264 .err_str = "type != 0", 1292 .err_str = "type != 0",
1265}, 1293},
1266 1294
1295{
1296 .descr = "arraymap invalid btf key (a bit field)",
1297 .raw_types = {
1298 /* int */ /* [1] */
1299 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1300 /* 32 bit int with 32 bit offset */ /* [2] */
1301 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 32, 32, 8),
1302 BTF_END_RAW,
1303 },
1304 .str_sec = "",
1305 .str_sec_size = sizeof(""),
1306 .map_type = BPF_MAP_TYPE_ARRAY,
1307 .map_name = "array_map_check_btf",
1308 .key_size = sizeof(int),
1309 .value_size = sizeof(int),
1310 .key_type_id = 2,
1311 .value_type_id = 1,
1312 .max_entries = 4,
1313 .map_create_err = true,
1314},
1315
1316{
1317 .descr = "arraymap invalid btf key (!= 32 bits)",
1318 .raw_types = {
1319 /* int */ /* [1] */
1320 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1321 /* 16 bit int with 0 bit offset */ /* [2] */
1322 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 16, 2),
1323 BTF_END_RAW,
1324 },
1325 .str_sec = "",
1326 .str_sec_size = sizeof(""),
1327 .map_type = BPF_MAP_TYPE_ARRAY,
1328 .map_name = "array_map_check_btf",
1329 .key_size = sizeof(int),
1330 .value_size = sizeof(int),
1331 .key_type_id = 2,
1332 .value_type_id = 1,
1333 .max_entries = 4,
1334 .map_create_err = true,
1335},
1336
1337{
1338 .descr = "arraymap invalid btf value (too small)",
1339 .raw_types = {
1340 /* int */ /* [1] */
1341 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1342 BTF_END_RAW,
1343 },
1344 .str_sec = "",
1345 .str_sec_size = sizeof(""),
1346 .map_type = BPF_MAP_TYPE_ARRAY,
1347 .map_name = "array_map_check_btf",
1348 .key_size = sizeof(int),
1349 /* btf_value_size < map->value_size */
1350 .value_size = sizeof(__u64),
1351 .key_type_id = 1,
1352 .value_type_id = 1,
1353 .max_entries = 4,
1354 .map_create_err = true,
1355},
1356
1357{
1358 .descr = "arraymap invalid btf value (too big)",
1359 .raw_types = {
1360 /* int */ /* [1] */
1361 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
1362 BTF_END_RAW,
1363 },
1364 .str_sec = "",
1365 .str_sec_size = sizeof(""),
1366 .map_type = BPF_MAP_TYPE_ARRAY,
1367 .map_name = "array_map_check_btf",
1368 .key_size = sizeof(int),
1369 /* btf_value_size > map->value_size */
1370 .value_size = sizeof(__u16),
1371 .key_type_id = 1,
1372 .value_type_id = 1,
1373 .max_entries = 4,
1374 .map_create_err = true,
1375},
1376
1267}; /* struct btf_raw_test raw_tests[] */ 1377}; /* struct btf_raw_test raw_tests[] */
1268 1378
1269static const char *get_next_str(const char *start, const char *end) 1379static const char *get_next_str(const char *start, const char *end)
@@ -2023,7 +2133,7 @@ static struct btf_raw_test pprint_test = {
2023 BTF_ENUM_ENC(NAME_TBD, 2), 2133 BTF_ENUM_ENC(NAME_TBD, 2),
2024 BTF_ENUM_ENC(NAME_TBD, 3), 2134 BTF_ENUM_ENC(NAME_TBD, 3),
2025 /* struct pprint_mapv */ /* [16] */ 2135 /* struct pprint_mapv */ /* [16] */
2026 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 8), 28), 2136 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 8), 32),
2027 BTF_MEMBER_ENC(NAME_TBD, 11, 0), /* uint32_t ui32 */ 2137 BTF_MEMBER_ENC(NAME_TBD, 11, 0), /* uint32_t ui32 */
2028 BTF_MEMBER_ENC(NAME_TBD, 10, 32), /* uint16_t ui16 */ 2138 BTF_MEMBER_ENC(NAME_TBD, 10, 32), /* uint16_t ui16 */
2029 BTF_MEMBER_ENC(NAME_TBD, 12, 64), /* int32_t si32 */ 2139 BTF_MEMBER_ENC(NAME_TBD, 12, 64), /* int32_t si32 */
diff --git a/tools/testing/selftests/bpf/test_btf_haskv.c b/tools/testing/selftests/bpf/test_btf_haskv.c
index 8c7ca096ecf2..b21b876f475d 100644
--- a/tools/testing/selftests/bpf/test_btf_haskv.c
+++ b/tools/testing/selftests/bpf/test_btf_haskv.c
@@ -10,11 +10,6 @@ struct ipv_counts {
10 unsigned int v6; 10 unsigned int v6;
11}; 11};
12 12
13typedef int btf_map_key;
14typedef struct ipv_counts btf_map_value;
15btf_map_key dumm_key;
16btf_map_value dummy_value;
17
18struct bpf_map_def SEC("maps") btf_map = { 13struct bpf_map_def SEC("maps") btf_map = {
19 .type = BPF_MAP_TYPE_ARRAY, 14 .type = BPF_MAP_TYPE_ARRAY,
20 .key_size = sizeof(int), 15 .key_size = sizeof(int),
@@ -22,6 +17,8 @@ struct bpf_map_def SEC("maps") btf_map = {
22 .max_entries = 4, 17 .max_entries = 4,
23}; 18};
24 19
20BPF_ANNOTATE_KV_PAIR(btf_map, int, struct ipv_counts);
21
25struct dummy_tracepoint_args { 22struct dummy_tracepoint_args {
26 unsigned long long pad; 23 unsigned long long pad;
27 struct sock *sock; 24 struct sock *sock;