diff options
author | 2019-03-19 13:12:18 +0000 | |
---|---|---|
committer | 2019-03-19 13:12:18 +0000 | |
commit | c9e48084c88cf901ad0d99a889f2628a5622d90b (patch) | |
tree | e95ef2305fa14e0c6e218a6aba8de8df4a0b5798 /kernel/bpf/arraymap.c | |
parent | regulator: axp20x: Use rdev_get_id at appropriate places (diff) | |
parent | Linux 5.1-rc1 (diff) | |
download | wireguard-linux-c9e48084c88cf901ad0d99a889f2628a5622d90b.tar.xz wireguard-linux-c9e48084c88cf901ad0d99a889f2628a5622d90b.zip |
Merge tag 'v5.1-rc1' into regulator-5.2
Linux 5.1-rc1
Diffstat (limited to 'kernel/bpf/arraymap.c')
-rw-r--r-- | kernel/bpf/arraymap.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c index 25632a75d630..c72e0d8e1e65 100644 --- a/kernel/bpf/arraymap.c +++ b/kernel/bpf/arraymap.c @@ -253,8 +253,9 @@ static int array_map_update_elem(struct bpf_map *map, void *key, void *value, { struct bpf_array *array = container_of(map, struct bpf_array, map); u32 index = *(u32 *)key; + char *val; - if (unlikely(map_flags > BPF_EXIST)) + if (unlikely((map_flags & ~BPF_F_LOCK) > BPF_EXIST)) /* unknown flags */ return -EINVAL; @@ -262,17 +263,25 @@ static int array_map_update_elem(struct bpf_map *map, void *key, void *value, /* all elements were pre-allocated, cannot insert a new one */ return -E2BIG; - if (unlikely(map_flags == BPF_NOEXIST)) + if (unlikely(map_flags & BPF_NOEXIST)) /* all elements already exist */ return -EEXIST; - if (array->map.map_type == BPF_MAP_TYPE_PERCPU_ARRAY) + if (unlikely((map_flags & BPF_F_LOCK) && + !map_value_has_spin_lock(map))) + return -EINVAL; + + if (array->map.map_type == BPF_MAP_TYPE_PERCPU_ARRAY) { memcpy(this_cpu_ptr(array->pptrs[index & array->index_mask]), value, map->value_size); - else - memcpy(array->value + - array->elem_size * (index & array->index_mask), - value, map->value_size); + } else { + val = array->value + + array->elem_size * (index & array->index_mask); + if (map_flags & BPF_F_LOCK) + copy_map_value_locked(map, val, value, false); + else + copy_map_value(map, val, value); + } return 0; } |