bpf: Dynptr support for ring buffers
[linux-2.6-microblaze.git] / kernel / bpf / ringbuf.c
index 311264a..ded4fae 100644 (file)
@@ -475,3 +475,81 @@ const struct bpf_func_proto bpf_ringbuf_query_proto = {
        .arg1_type      = ARG_CONST_MAP_PTR,
        .arg2_type      = ARG_ANYTHING,
 };
+
+BPF_CALL_4(bpf_ringbuf_reserve_dynptr, struct bpf_map *, map, u32, size, u64, flags,
+          struct bpf_dynptr_kern *, ptr)
+{
+       struct bpf_ringbuf_map *rb_map;
+       void *sample;
+       int err;
+
+       if (unlikely(flags)) {
+               bpf_dynptr_set_null(ptr);
+               return -EINVAL;
+       }
+
+       err = bpf_dynptr_check_size(size);
+       if (err) {
+               bpf_dynptr_set_null(ptr);
+               return err;
+       }
+
+       rb_map = container_of(map, struct bpf_ringbuf_map, map);
+
+       sample = __bpf_ringbuf_reserve(rb_map->rb, size);
+       if (!sample) {
+               bpf_dynptr_set_null(ptr);
+               return -EINVAL;
+       }
+
+       bpf_dynptr_init(ptr, sample, BPF_DYNPTR_TYPE_RINGBUF, 0, size);
+
+       return 0;
+}
+
+const struct bpf_func_proto bpf_ringbuf_reserve_dynptr_proto = {
+       .func           = bpf_ringbuf_reserve_dynptr,
+       .ret_type       = RET_INTEGER,
+       .arg1_type      = ARG_CONST_MAP_PTR,
+       .arg2_type      = ARG_ANYTHING,
+       .arg3_type      = ARG_ANYTHING,
+       .arg4_type      = ARG_PTR_TO_DYNPTR | DYNPTR_TYPE_RINGBUF | MEM_UNINIT,
+};
+
+BPF_CALL_2(bpf_ringbuf_submit_dynptr, struct bpf_dynptr_kern *, ptr, u64, flags)
+{
+       if (!ptr->data)
+               return 0;
+
+       bpf_ringbuf_commit(ptr->data, flags, false /* discard */);
+
+       bpf_dynptr_set_null(ptr);
+
+       return 0;
+}
+
+const struct bpf_func_proto bpf_ringbuf_submit_dynptr_proto = {
+       .func           = bpf_ringbuf_submit_dynptr,
+       .ret_type       = RET_VOID,
+       .arg1_type      = ARG_PTR_TO_DYNPTR | DYNPTR_TYPE_RINGBUF | OBJ_RELEASE,
+       .arg2_type      = ARG_ANYTHING,
+};
+
+BPF_CALL_2(bpf_ringbuf_discard_dynptr, struct bpf_dynptr_kern *, ptr, u64, flags)
+{
+       if (!ptr->data)
+               return 0;
+
+       bpf_ringbuf_commit(ptr->data, flags, true /* discard */);
+
+       bpf_dynptr_set_null(ptr);
+
+       return 0;
+}
+
+const struct bpf_func_proto bpf_ringbuf_discard_dynptr_proto = {
+       .func           = bpf_ringbuf_discard_dynptr,
+       .ret_type       = RET_VOID,
+       .arg1_type      = ARG_PTR_TO_DYNPTR | DYNPTR_TYPE_RINGBUF | OBJ_RELEASE,
+       .arg2_type      = ARG_ANYTHING,
+};