bpf, net: introduce bpf_struct_ops_desc.
[linux-2.6-microblaze.git] / kernel / bpf / bpf_struct_ops.c
index 5b3ebcb..9774f78 100644 (file)
@@ -32,7 +32,7 @@ struct bpf_struct_ops_value {
 struct bpf_struct_ops_map {
        struct bpf_map map;
        struct rcu_head rcu;
-       const struct bpf_struct_ops *st_ops;
+       const struct bpf_struct_ops_desc *st_ops_desc;
        /* protect map_update */
        struct mutex lock;
        /* link has all the bpf_links that is populated
@@ -92,9 +92,9 @@ enum {
        __NR_BPF_STRUCT_OPS_TYPE,
 };
 
-static struct bpf_struct_ops * const bpf_struct_ops[] = {
+static struct bpf_struct_ops_desc bpf_struct_ops[] = {
 #define BPF_STRUCT_OPS_TYPE(_name)                             \
-       [BPF_STRUCT_OPS_TYPE_##_name] = &bpf_##_name,
+       [BPF_STRUCT_OPS_TYPE_##_name] = { .st_ops = &bpf_##_name },
 #include "bpf_struct_ops_types.h"
 #undef BPF_STRUCT_OPS_TYPE
 };
@@ -115,10 +115,11 @@ enum {
        IDX_MODULE_ID,
 };
 
-static void bpf_struct_ops_init_one(struct bpf_struct_ops *st_ops,
-                                   struct btf *btf,
-                                   struct bpf_verifier_log *log)
+static void bpf_struct_ops_desc_init(struct bpf_struct_ops_desc *st_ops_desc,
+                                    struct btf *btf,
+                                    struct bpf_verifier_log *log)
 {
+       struct bpf_struct_ops *st_ops = st_ops_desc->st_ops;
        const struct btf_member *member;
        const struct btf_type *t;
        s32 type_id, value_id;
@@ -190,18 +191,18 @@ static void bpf_struct_ops_init_one(struct bpf_struct_ops *st_ops,
                        pr_warn("Error in init bpf_struct_ops %s\n",
                                st_ops->name);
                } else {
-                       st_ops->type_id = type_id;
-                       st_ops->type = t;
-                       st_ops->value_id = value_id;
-                       st_ops->value_type = btf_type_by_id(btf,
-                                                           value_id);
+                       st_ops_desc->type_id = type_id;
+                       st_ops_desc->type = t;
+                       st_ops_desc->value_id = value_id;
+                       st_ops_desc->value_type = btf_type_by_id(btf,
+                                                                value_id);
                }
        }
 }
 
 void bpf_struct_ops_init(struct btf *btf, struct bpf_verifier_log *log)
 {
-       struct bpf_struct_ops *st_ops;
+       struct bpf_struct_ops_desc *st_ops_desc;
        u32 i;
 
        /* Ensure BTF type is emitted for "struct bpf_struct_ops_##_name" */
@@ -210,14 +211,14 @@ void bpf_struct_ops_init(struct btf *btf, struct bpf_verifier_log *log)
 #undef BPF_STRUCT_OPS_TYPE
 
        for (i = 0; i < ARRAY_SIZE(bpf_struct_ops); i++) {
-               st_ops = bpf_struct_ops[i];
-               bpf_struct_ops_init_one(st_ops, btf, log);
+               st_ops_desc = &bpf_struct_ops[i];
+               bpf_struct_ops_desc_init(st_ops_desc, btf, log);
        }
 }
 
 extern struct btf *btf_vmlinux;
 
-static const struct bpf_struct_ops *
+static const struct bpf_struct_ops_desc *
 bpf_struct_ops_find_value(u32 value_id)
 {
        unsigned int i;
@@ -226,14 +227,14 @@ bpf_struct_ops_find_value(u32 value_id)
                return NULL;
 
        for (i = 0; i < ARRAY_SIZE(bpf_struct_ops); i++) {
-               if (bpf_struct_ops[i]->value_id == value_id)
-                       return bpf_struct_ops[i];
+               if (bpf_struct_ops[i].value_id == value_id)
+                       return &bpf_struct_ops[i];
        }
 
        return NULL;
 }
 
-const struct bpf_struct_ops *bpf_struct_ops_find(u32 type_id)
+const struct bpf_struct_ops_desc *bpf_struct_ops_find(u32 type_id)
 {
        unsigned int i;
 
@@ -241,8 +242,8 @@ const struct bpf_struct_ops *bpf_struct_ops_find(u32 type_id)
                return NULL;
 
        for (i = 0; i < ARRAY_SIZE(bpf_struct_ops); i++) {
-               if (bpf_struct_ops[i]->type_id == type_id)
-                       return bpf_struct_ops[i];
+               if (bpf_struct_ops[i].type_id == type_id)
+                       return &bpf_struct_ops[i];
        }
 
        return NULL;
@@ -302,7 +303,7 @@ static void *bpf_struct_ops_map_lookup_elem(struct bpf_map *map, void *key)
 
 static void bpf_struct_ops_map_put_progs(struct bpf_struct_ops_map *st_map)
 {
-       const struct btf_type *t = st_map->st_ops->type;
+       const struct btf_type *t = st_map->st_ops_desc->type;
        u32 i;
 
        for (i = 0; i < btf_type_vlen(t); i++) {
@@ -382,11 +383,12 @@ static long bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key,
                                           void *value, u64 flags)
 {
        struct bpf_struct_ops_map *st_map = (struct bpf_struct_ops_map *)map;
-       const struct bpf_struct_ops *st_ops = st_map->st_ops;
+       const struct bpf_struct_ops_desc *st_ops_desc = st_map->st_ops_desc;
+       const struct bpf_struct_ops *st_ops = st_ops_desc->st_ops;
        struct bpf_struct_ops_value *uvalue, *kvalue;
        const struct btf_type *module_type;
        const struct btf_member *member;
-       const struct btf_type *t = st_ops->type;
+       const struct btf_type *t = st_ops_desc->type;
        struct bpf_tramp_links *tlinks;
        void *udata, *kdata;
        int prog_fd, err;
@@ -399,7 +401,7 @@ static long bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key,
        if (*(u32 *)key != 0)
                return -E2BIG;
 
-       err = check_zero_holes(st_ops->value_type, value);
+       err = check_zero_holes(st_ops_desc->value_type, value);
        if (err)
                return err;
 
@@ -492,7 +494,7 @@ static long bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key,
                }
 
                if (prog->type != BPF_PROG_TYPE_STRUCT_OPS ||
-                   prog->aux->attach_btf_id != st_ops->type_id ||
+                   prog->aux->attach_btf_id != st_ops_desc->type_id ||
                    prog->expected_attach_type != i) {
                        bpf_prog_put(prog);
                        err = -EINVAL;
@@ -588,7 +590,7 @@ static long bpf_struct_ops_map_delete_elem(struct bpf_map *map, void *key)
                             BPF_STRUCT_OPS_STATE_TOBEFREE);
        switch (prev_state) {
        case BPF_STRUCT_OPS_STATE_INUSE:
-               st_map->st_ops->unreg(&st_map->kvalue.data);
+               st_map->st_ops_desc->st_ops->unreg(&st_map->kvalue.data);
                bpf_map_put(map);
                return 0;
        case BPF_STRUCT_OPS_STATE_TOBEFREE:
@@ -669,22 +671,22 @@ static int bpf_struct_ops_map_alloc_check(union bpf_attr *attr)
 
 static struct bpf_map *bpf_struct_ops_map_alloc(union bpf_attr *attr)
 {
-       const struct bpf_struct_ops *st_ops;
+       const struct bpf_struct_ops_desc *st_ops_desc;
        size_t st_map_size;
        struct bpf_struct_ops_map *st_map;
        const struct btf_type *t, *vt;
        struct bpf_map *map;
        int ret;
 
-       st_ops = bpf_struct_ops_find_value(attr->btf_vmlinux_value_type_id);
-       if (!st_ops)
+       st_ops_desc = bpf_struct_ops_find_value(attr->btf_vmlinux_value_type_id);
+       if (!st_ops_desc)
                return ERR_PTR(-ENOTSUPP);
 
-       vt = st_ops->value_type;
+       vt = st_ops_desc->value_type;
        if (attr->value_size != vt->size)
                return ERR_PTR(-EINVAL);
 
-       t = st_ops->type;
+       t = st_ops_desc->type;
 
        st_map_size = sizeof(*st_map) +
                /* kvalue stores the
@@ -696,7 +698,7 @@ static struct bpf_map *bpf_struct_ops_map_alloc(union bpf_attr *attr)
        if (!st_map)
                return ERR_PTR(-ENOMEM);
 
-       st_map->st_ops = st_ops;
+       st_map->st_ops_desc = st_ops_desc;
        map = &st_map->map;
 
        ret = bpf_jit_charge_modmem(PAGE_SIZE);
@@ -733,8 +735,8 @@ static struct bpf_map *bpf_struct_ops_map_alloc(union bpf_attr *attr)
 static u64 bpf_struct_ops_map_mem_usage(const struct bpf_map *map)
 {
        struct bpf_struct_ops_map *st_map = (struct bpf_struct_ops_map *)map;
-       const struct bpf_struct_ops *st_ops = st_map->st_ops;
-       const struct btf_type *vt = st_ops->value_type;
+       const struct bpf_struct_ops_desc *st_ops_desc = st_map->st_ops_desc;
+       const struct btf_type *vt = st_ops_desc->value_type;
        u64 usage;
 
        usage = sizeof(*st_map) +
@@ -808,7 +810,7 @@ static void bpf_struct_ops_map_link_dealloc(struct bpf_link *link)
                /* st_link->map can be NULL if
                 * bpf_struct_ops_link_create() fails to register.
                 */
-               st_map->st_ops->unreg(&st_map->kvalue.data);
+               st_map->st_ops_desc->st_ops->unreg(&st_map->kvalue.data);
                bpf_map_put(&st_map->map);
        }
        kfree(st_link);
@@ -855,7 +857,7 @@ static int bpf_struct_ops_map_link_update(struct bpf_link *link, struct bpf_map
        if (!bpf_struct_ops_valid_to_reg(new_map))
                return -EINVAL;
 
-       if (!st_map->st_ops->update)
+       if (!st_map->st_ops_desc->st_ops->update)
                return -EOPNOTSUPP;
 
        mutex_lock(&update_mutex);
@@ -868,12 +870,12 @@ static int bpf_struct_ops_map_link_update(struct bpf_link *link, struct bpf_map
 
        old_st_map = container_of(old_map, struct bpf_struct_ops_map, map);
        /* The new and old struct_ops must be the same type. */
-       if (st_map->st_ops != old_st_map->st_ops) {
+       if (st_map->st_ops_desc != old_st_map->st_ops_desc) {
                err = -EINVAL;
                goto err_out;
        }
 
-       err = st_map->st_ops->update(st_map->kvalue.data, old_st_map->kvalue.data);
+       err = st_map->st_ops_desc->st_ops->update(st_map->kvalue.data, old_st_map->kvalue.data);
        if (err)
                goto err_out;
 
@@ -924,7 +926,7 @@ int bpf_struct_ops_link_create(union bpf_attr *attr)
        if (err)
                goto err_out;
 
-       err = st_map->st_ops->reg(st_map->kvalue.data);
+       err = st_map->st_ops_desc->st_ops->reg(st_map->kvalue.data);
        if (err) {
                bpf_link_cleanup(&link_primer);
                link = NULL;