|
@@ -67,7 +67,7 @@ nfp_map_ptr_record(struct nfp_app_bpf *bpf, struct nfp_prog *nfp_prog,
|
|
ASSERT_RTNL();
|
|
ASSERT_RTNL();
|
|
|
|
|
|
/* Reuse path - other offloaded program is already tracking this map. */
|
|
/* Reuse path - other offloaded program is already tracking this map. */
|
|
- record = rhashtable_lookup_fast(&bpf->maps_neutral, &map,
|
|
|
|
|
|
+ record = rhashtable_lookup_fast(&bpf->maps_neutral, &map->id,
|
|
nfp_bpf_maps_neutral_params);
|
|
nfp_bpf_maps_neutral_params);
|
|
if (record) {
|
|
if (record) {
|
|
nfp_prog->map_records[nfp_prog->map_records_cnt++] = record;
|
|
nfp_prog->map_records[nfp_prog->map_records_cnt++] = record;
|
|
@@ -89,6 +89,7 @@ nfp_map_ptr_record(struct nfp_app_bpf *bpf, struct nfp_prog *nfp_prog,
|
|
}
|
|
}
|
|
|
|
|
|
record->ptr = map;
|
|
record->ptr = map;
|
|
|
|
+ record->map_id = map->id;
|
|
record->count = 1;
|
|
record->count = 1;
|
|
|
|
|
|
err = rhashtable_insert_fast(&bpf->maps_neutral, &record->l,
|
|
err = rhashtable_insert_fast(&bpf->maps_neutral, &record->l,
|
|
@@ -379,11 +380,23 @@ nfp_bpf_map_alloc(struct nfp_app_bpf *bpf, struct bpf_offloaded_map *offmap)
|
|
bpf->maps.max_elems - bpf->map_elems_in_use);
|
|
bpf->maps.max_elems - bpf->map_elems_in_use);
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
}
|
|
}
|
|
- if (offmap->map.key_size > bpf->maps.max_key_sz ||
|
|
|
|
- offmap->map.value_size > bpf->maps.max_val_sz ||
|
|
|
|
- round_up(offmap->map.key_size, 8) +
|
|
|
|
|
|
+
|
|
|
|
+ if (round_up(offmap->map.key_size, 8) +
|
|
round_up(offmap->map.value_size, 8) > bpf->maps.max_elem_sz) {
|
|
round_up(offmap->map.value_size, 8) > bpf->maps.max_elem_sz) {
|
|
- pr_info("elements don't fit in device constraints\n");
|
|
|
|
|
|
+ pr_info("map elements too large: %u, FW max element size (key+value): %u\n",
|
|
|
|
+ round_up(offmap->map.key_size, 8) +
|
|
|
|
+ round_up(offmap->map.value_size, 8),
|
|
|
|
+ bpf->maps.max_elem_sz);
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+ }
|
|
|
|
+ if (offmap->map.key_size > bpf->maps.max_key_sz) {
|
|
|
|
+ pr_info("map key size %u, FW max is %u\n",
|
|
|
|
+ offmap->map.key_size, bpf->maps.max_key_sz);
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+ }
|
|
|
|
+ if (offmap->map.value_size > bpf->maps.max_val_sz) {
|
|
|
|
+ pr_info("map value size %u, FW max is %u\n",
|
|
|
|
+ offmap->map.value_size, bpf->maps.max_val_sz);
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -453,43 +466,43 @@ nfp_bpf_perf_event_copy(void *dst, const void *src,
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-int nfp_bpf_event_output(struct nfp_app_bpf *bpf, struct sk_buff *skb)
|
|
|
|
|
|
+int nfp_bpf_event_output(struct nfp_app_bpf *bpf, const void *data,
|
|
|
|
+ unsigned int len)
|
|
{
|
|
{
|
|
- struct cmsg_bpf_event *cbe = (void *)skb->data;
|
|
|
|
- u32 pkt_size, data_size;
|
|
|
|
- struct bpf_map *map;
|
|
|
|
|
|
+ struct cmsg_bpf_event *cbe = (void *)data;
|
|
|
|
+ struct nfp_bpf_neutral_map *record;
|
|
|
|
+ u32 pkt_size, data_size, map_id;
|
|
|
|
+ u64 map_id_full;
|
|
|
|
|
|
- if (skb->len < sizeof(struct cmsg_bpf_event))
|
|
|
|
- goto err_drop;
|
|
|
|
|
|
+ if (len < sizeof(struct cmsg_bpf_event))
|
|
|
|
+ return -EINVAL;
|
|
|
|
|
|
pkt_size = be32_to_cpu(cbe->pkt_size);
|
|
pkt_size = be32_to_cpu(cbe->pkt_size);
|
|
data_size = be32_to_cpu(cbe->data_size);
|
|
data_size = be32_to_cpu(cbe->data_size);
|
|
- map = (void *)(unsigned long)be64_to_cpu(cbe->map_ptr);
|
|
|
|
|
|
+ map_id_full = be64_to_cpu(cbe->map_ptr);
|
|
|
|
+ map_id = map_id_full;
|
|
|
|
|
|
- if (skb->len < sizeof(struct cmsg_bpf_event) + pkt_size + data_size)
|
|
|
|
- goto err_drop;
|
|
|
|
|
|
+ if (len < sizeof(struct cmsg_bpf_event) + pkt_size + data_size)
|
|
|
|
+ return -EINVAL;
|
|
if (cbe->hdr.ver != CMSG_MAP_ABI_VERSION)
|
|
if (cbe->hdr.ver != CMSG_MAP_ABI_VERSION)
|
|
- goto err_drop;
|
|
|
|
|
|
+ return -EINVAL;
|
|
|
|
|
|
rcu_read_lock();
|
|
rcu_read_lock();
|
|
- if (!rhashtable_lookup_fast(&bpf->maps_neutral, &map,
|
|
|
|
- nfp_bpf_maps_neutral_params)) {
|
|
|
|
|
|
+ record = rhashtable_lookup_fast(&bpf->maps_neutral, &map_id,
|
|
|
|
+ nfp_bpf_maps_neutral_params);
|
|
|
|
+ if (!record || map_id_full > U32_MAX) {
|
|
rcu_read_unlock();
|
|
rcu_read_unlock();
|
|
- pr_warn("perf event: dest map pointer %px not recognized, dropping event\n",
|
|
|
|
- map);
|
|
|
|
- goto err_drop;
|
|
|
|
|
|
+ cmsg_warn(bpf, "perf event: map id %lld (0x%llx) not recognized, dropping event\n",
|
|
|
|
+ map_id_full, map_id_full);
|
|
|
|
+ return -EINVAL;
|
|
}
|
|
}
|
|
|
|
|
|
- bpf_event_output(map, be32_to_cpu(cbe->cpu_id),
|
|
|
|
|
|
+ bpf_event_output(record->ptr, be32_to_cpu(cbe->cpu_id),
|
|
&cbe->data[round_up(pkt_size, 4)], data_size,
|
|
&cbe->data[round_up(pkt_size, 4)], data_size,
|
|
cbe->data, pkt_size, nfp_bpf_perf_event_copy);
|
|
cbe->data, pkt_size, nfp_bpf_perf_event_copy);
|
|
rcu_read_unlock();
|
|
rcu_read_unlock();
|
|
|
|
|
|
- dev_consume_skb_any(skb);
|
|
|
|
return 0;
|
|
return 0;
|
|
-err_drop:
|
|
|
|
- dev_kfree_skb_any(skb);
|
|
|
|
- return -EINVAL;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
static int
|
|
static int
|