xref: /openbmc/linux/kernel/bpf/bpf_task_storage.c (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
14cf1bc1fSKP Singh // SPDX-License-Identifier: GPL-2.0
24cf1bc1fSKP Singh /*
34cf1bc1fSKP Singh  * Copyright (c) 2020 Facebook
44cf1bc1fSKP Singh  * Copyright 2020 Google LLC.
54cf1bc1fSKP Singh  */
64cf1bc1fSKP Singh 
74cf1bc1fSKP Singh #include <linux/pid.h>
84cf1bc1fSKP Singh #include <linux/sched.h>
94cf1bc1fSKP Singh #include <linux/rculist.h>
104cf1bc1fSKP Singh #include <linux/list.h>
114cf1bc1fSKP Singh #include <linux/hash.h>
124cf1bc1fSKP Singh #include <linux/types.h>
134cf1bc1fSKP Singh #include <linux/spinlock.h>
144cf1bc1fSKP Singh #include <linux/bpf.h>
154cf1bc1fSKP Singh #include <linux/bpf_local_storage.h>
164cf1bc1fSKP Singh #include <linux/filter.h>
174cf1bc1fSKP Singh #include <uapi/linux/btf.h>
184cf1bc1fSKP Singh #include <linux/btf_ids.h>
194cf1bc1fSKP Singh #include <linux/fdtable.h>
200fe4b381SKP Singh #include <linux/rcupdate_trace.h>
214cf1bc1fSKP Singh 
224cf1bc1fSKP Singh DEFINE_BPF_STORAGE_CACHE(task_cache);
234cf1bc1fSKP Singh 
244d0b9389SWei Yongjun static DEFINE_PER_CPU(int, bpf_task_storage_busy);
25bc235cdbSSong Liu 
bpf_task_storage_lock(void)26bc235cdbSSong Liu static void bpf_task_storage_lock(void)
27bc235cdbSSong Liu {
28bc235cdbSSong Liu 	migrate_disable();
29197827a0SHou Tao 	this_cpu_inc(bpf_task_storage_busy);
30bc235cdbSSong Liu }
31bc235cdbSSong Liu 
bpf_task_storage_unlock(void)32bc235cdbSSong Liu static void bpf_task_storage_unlock(void)
33bc235cdbSSong Liu {
34197827a0SHou Tao 	this_cpu_dec(bpf_task_storage_busy);
35bc235cdbSSong Liu 	migrate_enable();
36bc235cdbSSong Liu }
37bc235cdbSSong Liu 
bpf_task_storage_trylock(void)38bc235cdbSSong Liu static bool bpf_task_storage_trylock(void)
39bc235cdbSSong Liu {
40bc235cdbSSong Liu 	migrate_disable();
41197827a0SHou Tao 	if (unlikely(this_cpu_inc_return(bpf_task_storage_busy) != 1)) {
42197827a0SHou Tao 		this_cpu_dec(bpf_task_storage_busy);
43bc235cdbSSong Liu 		migrate_enable();
44bc235cdbSSong Liu 		return false;
45bc235cdbSSong Liu 	}
46bc235cdbSSong Liu 	return true;
47bc235cdbSSong Liu }
48bc235cdbSSong Liu 
task_storage_ptr(void * owner)494cf1bc1fSKP Singh static struct bpf_local_storage __rcu **task_storage_ptr(void *owner)
504cf1bc1fSKP Singh {
514cf1bc1fSKP Singh 	struct task_struct *task = owner;
524cf1bc1fSKP Singh 
53a10787e6SSong Liu 	return &task->bpf_storage;
544cf1bc1fSKP Singh }
554cf1bc1fSKP Singh 
564cf1bc1fSKP Singh static struct bpf_local_storage_data *
task_storage_lookup(struct task_struct * task,struct bpf_map * map,bool cacheit_lockit)574cf1bc1fSKP Singh task_storage_lookup(struct task_struct *task, struct bpf_map *map,
584cf1bc1fSKP Singh 		    bool cacheit_lockit)
594cf1bc1fSKP Singh {
604cf1bc1fSKP Singh 	struct bpf_local_storage *task_storage;
614cf1bc1fSKP Singh 	struct bpf_local_storage_map *smap;
624cf1bc1fSKP Singh 
630fe4b381SKP Singh 	task_storage =
640fe4b381SKP Singh 		rcu_dereference_check(task->bpf_storage, bpf_rcu_lock_held());
654cf1bc1fSKP Singh 	if (!task_storage)
664cf1bc1fSKP Singh 		return NULL;
674cf1bc1fSKP Singh 
684cf1bc1fSKP Singh 	smap = (struct bpf_local_storage_map *)map;
694cf1bc1fSKP Singh 	return bpf_local_storage_lookup(task_storage, smap, cacheit_lockit);
704cf1bc1fSKP Singh }
714cf1bc1fSKP Singh 
bpf_task_storage_free(struct task_struct * task)724cf1bc1fSKP Singh void bpf_task_storage_free(struct task_struct *task)
734cf1bc1fSKP Singh {
744cf1bc1fSKP Singh 	struct bpf_local_storage *local_storage;
754cf1bc1fSKP Singh 
764cf1bc1fSKP Singh 	rcu_read_lock();
774cf1bc1fSKP Singh 
78a10787e6SSong Liu 	local_storage = rcu_dereference(task->bpf_storage);
794cf1bc1fSKP Singh 	if (!local_storage) {
804cf1bc1fSKP Singh 		rcu_read_unlock();
814cf1bc1fSKP Singh 		return;
824cf1bc1fSKP Singh 	}
834cf1bc1fSKP Singh 
84bc235cdbSSong Liu 	bpf_task_storage_lock();
852ffcb6fcSMartin KaFai Lau 	bpf_local_storage_destroy(local_storage);
86bc235cdbSSong Liu 	bpf_task_storage_unlock();
874cf1bc1fSKP Singh 	rcu_read_unlock();
884cf1bc1fSKP Singh }
894cf1bc1fSKP Singh 
bpf_pid_task_storage_lookup_elem(struct bpf_map * map,void * key)904cf1bc1fSKP Singh static void *bpf_pid_task_storage_lookup_elem(struct bpf_map *map, void *key)
914cf1bc1fSKP Singh {
924cf1bc1fSKP Singh 	struct bpf_local_storage_data *sdata;
934cf1bc1fSKP Singh 	struct task_struct *task;
944cf1bc1fSKP Singh 	unsigned int f_flags;
954cf1bc1fSKP Singh 	struct pid *pid;
964cf1bc1fSKP Singh 	int fd, err;
974cf1bc1fSKP Singh 
984cf1bc1fSKP Singh 	fd = *(int *)key;
994cf1bc1fSKP Singh 	pid = pidfd_get_pid(fd, &f_flags);
1004cf1bc1fSKP Singh 	if (IS_ERR(pid))
1014cf1bc1fSKP Singh 		return ERR_CAST(pid);
1024cf1bc1fSKP Singh 
1034cf1bc1fSKP Singh 	/* We should be in an RCU read side critical section, it should be safe
1044cf1bc1fSKP Singh 	 * to call pid_task.
1054cf1bc1fSKP Singh 	 */
1064cf1bc1fSKP Singh 	WARN_ON_ONCE(!rcu_read_lock_held());
1074cf1bc1fSKP Singh 	task = pid_task(pid, PIDTYPE_PID);
1084cf1bc1fSKP Singh 	if (!task) {
1094cf1bc1fSKP Singh 		err = -ENOENT;
1104cf1bc1fSKP Singh 		goto out;
1114cf1bc1fSKP Singh 	}
1124cf1bc1fSKP Singh 
113bc235cdbSSong Liu 	bpf_task_storage_lock();
1144cf1bc1fSKP Singh 	sdata = task_storage_lookup(task, map, true);
115bc235cdbSSong Liu 	bpf_task_storage_unlock();
1164cf1bc1fSKP Singh 	put_pid(pid);
1174cf1bc1fSKP Singh 	return sdata ? sdata->data : NULL;
1184cf1bc1fSKP Singh out:
1194cf1bc1fSKP Singh 	put_pid(pid);
1204cf1bc1fSKP Singh 	return ERR_PTR(err);
1214cf1bc1fSKP Singh }
1224cf1bc1fSKP Singh 
bpf_pid_task_storage_update_elem(struct bpf_map * map,void * key,void * value,u64 map_flags)123d7ba4cc9SJP Kobryn static long bpf_pid_task_storage_update_elem(struct bpf_map *map, void *key,
1244cf1bc1fSKP Singh 					     void *value, u64 map_flags)
1254cf1bc1fSKP Singh {
1264cf1bc1fSKP Singh 	struct bpf_local_storage_data *sdata;
1274cf1bc1fSKP Singh 	struct task_struct *task;
1284cf1bc1fSKP Singh 	unsigned int f_flags;
1294cf1bc1fSKP Singh 	struct pid *pid;
1304cf1bc1fSKP Singh 	int fd, err;
1314cf1bc1fSKP Singh 
1324cf1bc1fSKP Singh 	fd = *(int *)key;
1334cf1bc1fSKP Singh 	pid = pidfd_get_pid(fd, &f_flags);
1344cf1bc1fSKP Singh 	if (IS_ERR(pid))
1354cf1bc1fSKP Singh 		return PTR_ERR(pid);
1364cf1bc1fSKP Singh 
1374cf1bc1fSKP Singh 	/* We should be in an RCU read side critical section, it should be safe
1384cf1bc1fSKP Singh 	 * to call pid_task.
1394cf1bc1fSKP Singh 	 */
1404cf1bc1fSKP Singh 	WARN_ON_ONCE(!rcu_read_lock_held());
1414cf1bc1fSKP Singh 	task = pid_task(pid, PIDTYPE_PID);
142a10787e6SSong Liu 	if (!task) {
1434cf1bc1fSKP Singh 		err = -ENOENT;
1444cf1bc1fSKP Singh 		goto out;
1454cf1bc1fSKP Singh 	}
1464cf1bc1fSKP Singh 
147bc235cdbSSong Liu 	bpf_task_storage_lock();
1484cf1bc1fSKP Singh 	sdata = bpf_local_storage_update(
149b00fa38aSJoanne Koong 		task, (struct bpf_local_storage_map *)map, value, map_flags,
150b00fa38aSJoanne Koong 		GFP_ATOMIC);
151bc235cdbSSong Liu 	bpf_task_storage_unlock();
1524cf1bc1fSKP Singh 
1534cf1bc1fSKP Singh 	err = PTR_ERR_OR_ZERO(sdata);
1544cf1bc1fSKP Singh out:
1554cf1bc1fSKP Singh 	put_pid(pid);
1564cf1bc1fSKP Singh 	return err;
1574cf1bc1fSKP Singh }
1584cf1bc1fSKP Singh 
task_storage_delete(struct task_struct * task,struct bpf_map * map,bool nobusy)159fda64ae0SMartin KaFai Lau static int task_storage_delete(struct task_struct *task, struct bpf_map *map,
160fda64ae0SMartin KaFai Lau 			       bool nobusy)
1614cf1bc1fSKP Singh {
1624cf1bc1fSKP Singh 	struct bpf_local_storage_data *sdata;
1634cf1bc1fSKP Singh 
1644cf1bc1fSKP Singh 	sdata = task_storage_lookup(task, map, false);
1654cf1bc1fSKP Singh 	if (!sdata)
1664cf1bc1fSKP Singh 		return -ENOENT;
1674cf1bc1fSKP Singh 
168fda64ae0SMartin KaFai Lau 	if (!nobusy)
169fda64ae0SMartin KaFai Lau 		return -EBUSY;
170fda64ae0SMartin KaFai Lau 
171a47eabf2SMartin KaFai Lau 	bpf_selem_unlink(SELEM(sdata), false);
1724cf1bc1fSKP Singh 
1734cf1bc1fSKP Singh 	return 0;
1744cf1bc1fSKP Singh }
1754cf1bc1fSKP Singh 
bpf_pid_task_storage_delete_elem(struct bpf_map * map,void * key)176d7ba4cc9SJP Kobryn static long bpf_pid_task_storage_delete_elem(struct bpf_map *map, void *key)
1774cf1bc1fSKP Singh {
1784cf1bc1fSKP Singh 	struct task_struct *task;
1794cf1bc1fSKP Singh 	unsigned int f_flags;
1804cf1bc1fSKP Singh 	struct pid *pid;
1814cf1bc1fSKP Singh 	int fd, err;
1824cf1bc1fSKP Singh 
1834cf1bc1fSKP Singh 	fd = *(int *)key;
1844cf1bc1fSKP Singh 	pid = pidfd_get_pid(fd, &f_flags);
1854cf1bc1fSKP Singh 	if (IS_ERR(pid))
1864cf1bc1fSKP Singh 		return PTR_ERR(pid);
1874cf1bc1fSKP Singh 
1884cf1bc1fSKP Singh 	/* We should be in an RCU read side critical section, it should be safe
1894cf1bc1fSKP Singh 	 * to call pid_task.
1904cf1bc1fSKP Singh 	 */
1914cf1bc1fSKP Singh 	WARN_ON_ONCE(!rcu_read_lock_held());
1924cf1bc1fSKP Singh 	task = pid_task(pid, PIDTYPE_PID);
1934cf1bc1fSKP Singh 	if (!task) {
1944cf1bc1fSKP Singh 		err = -ENOENT;
1954cf1bc1fSKP Singh 		goto out;
1964cf1bc1fSKP Singh 	}
1974cf1bc1fSKP Singh 
198bc235cdbSSong Liu 	bpf_task_storage_lock();
199fda64ae0SMartin KaFai Lau 	err = task_storage_delete(task, map, true);
200bc235cdbSSong Liu 	bpf_task_storage_unlock();
2014cf1bc1fSKP Singh out:
2024cf1bc1fSKP Singh 	put_pid(pid);
2034cf1bc1fSKP Singh 	return err;
2044cf1bc1fSKP Singh }
2054cf1bc1fSKP Singh 
2066d65500cSMartin KaFai Lau /* Called by bpf_task_storage_get*() helpers */
__bpf_task_storage_get(struct bpf_map * map,struct task_struct * task,void * value,u64 flags,gfp_t gfp_flags,bool nobusy)2076d65500cSMartin KaFai Lau static void *__bpf_task_storage_get(struct bpf_map *map,
2086d65500cSMartin KaFai Lau 				    struct task_struct *task, void *value,
209e8b02296SMartin KaFai Lau 				    u64 flags, gfp_t gfp_flags, bool nobusy)
2106d65500cSMartin KaFai Lau {
2116d65500cSMartin KaFai Lau 	struct bpf_local_storage_data *sdata;
2126d65500cSMartin KaFai Lau 
213e8b02296SMartin KaFai Lau 	sdata = task_storage_lookup(task, map, nobusy);
2146d65500cSMartin KaFai Lau 	if (sdata)
2156d65500cSMartin KaFai Lau 		return sdata->data;
2166d65500cSMartin KaFai Lau 
2176d65500cSMartin KaFai Lau 	/* only allocate new storage, when the task is refcounted */
2186d65500cSMartin KaFai Lau 	if (refcount_read(&task->usage) &&
219e8b02296SMartin KaFai Lau 	    (flags & BPF_LOCAL_STORAGE_GET_F_CREATE) && nobusy) {
2206d65500cSMartin KaFai Lau 		sdata = bpf_local_storage_update(
2216d65500cSMartin KaFai Lau 			task, (struct bpf_local_storage_map *)map, value,
2226d65500cSMartin KaFai Lau 			BPF_NOEXIST, gfp_flags);
2236d65500cSMartin KaFai Lau 		return IS_ERR(sdata) ? NULL : sdata->data;
2246d65500cSMartin KaFai Lau 	}
2256d65500cSMartin KaFai Lau 
2266d65500cSMartin KaFai Lau 	return NULL;
2276d65500cSMartin KaFai Lau }
2286d65500cSMartin KaFai Lau 
229b00fa38aSJoanne Koong /* *gfp_flags* is a hidden argument provided by the verifier */
BPF_CALL_5(bpf_task_storage_get_recur,struct bpf_map *,map,struct task_struct *,task,void *,value,u64,flags,gfp_t,gfp_flags)2300593dd34SMartin KaFai Lau BPF_CALL_5(bpf_task_storage_get_recur, struct bpf_map *, map, struct task_struct *,
231b00fa38aSJoanne Koong 	   task, void *, value, u64, flags, gfp_t, gfp_flags)
2324cf1bc1fSKP Singh {
233e8b02296SMartin KaFai Lau 	bool nobusy;
2346d65500cSMartin KaFai Lau 	void *data;
2354cf1bc1fSKP Singh 
2360fe4b381SKP Singh 	WARN_ON_ONCE(!bpf_rcu_lock_held());
2376d65500cSMartin KaFai Lau 	if (flags & ~BPF_LOCAL_STORAGE_GET_F_CREATE || !task)
2384cf1bc1fSKP Singh 		return (unsigned long)NULL;
2394cf1bc1fSKP Singh 
240e8b02296SMartin KaFai Lau 	nobusy = bpf_task_storage_trylock();
2416d65500cSMartin KaFai Lau 	data = __bpf_task_storage_get(map, task, value, flags,
242e8b02296SMartin KaFai Lau 				      gfp_flags, nobusy);
243e8b02296SMartin KaFai Lau 	if (nobusy)
244bc235cdbSSong Liu 		bpf_task_storage_unlock();
2456d65500cSMartin KaFai Lau 	return (unsigned long)data;
2464cf1bc1fSKP Singh }
2474cf1bc1fSKP Singh 
2484279adb0SMartin KaFai Lau /* *gfp_flags* is a hidden argument provided by the verifier */
BPF_CALL_5(bpf_task_storage_get,struct bpf_map *,map,struct task_struct *,task,void *,value,u64,flags,gfp_t,gfp_flags)2494279adb0SMartin KaFai Lau BPF_CALL_5(bpf_task_storage_get, struct bpf_map *, map, struct task_struct *,
2504279adb0SMartin KaFai Lau 	   task, void *, value, u64, flags, gfp_t, gfp_flags)
2514279adb0SMartin KaFai Lau {
2524279adb0SMartin KaFai Lau 	void *data;
2534279adb0SMartin KaFai Lau 
2544279adb0SMartin KaFai Lau 	WARN_ON_ONCE(!bpf_rcu_lock_held());
2554279adb0SMartin KaFai Lau 	if (flags & ~BPF_LOCAL_STORAGE_GET_F_CREATE || !task)
2564279adb0SMartin KaFai Lau 		return (unsigned long)NULL;
2574279adb0SMartin KaFai Lau 
2584279adb0SMartin KaFai Lau 	bpf_task_storage_lock();
2594279adb0SMartin KaFai Lau 	data = __bpf_task_storage_get(map, task, value, flags,
2604279adb0SMartin KaFai Lau 				      gfp_flags, true);
2614279adb0SMartin KaFai Lau 	bpf_task_storage_unlock();
2624279adb0SMartin KaFai Lau 	return (unsigned long)data;
2634279adb0SMartin KaFai Lau }
2644279adb0SMartin KaFai Lau 
BPF_CALL_2(bpf_task_storage_delete_recur,struct bpf_map *,map,struct task_struct *,task)2650593dd34SMartin KaFai Lau BPF_CALL_2(bpf_task_storage_delete_recur, struct bpf_map *, map, struct task_struct *,
2664cf1bc1fSKP Singh 	   task)
2674cf1bc1fSKP Singh {
268fda64ae0SMartin KaFai Lau 	bool nobusy;
269bc235cdbSSong Liu 	int ret;
270bc235cdbSSong Liu 
2710fe4b381SKP Singh 	WARN_ON_ONCE(!bpf_rcu_lock_held());
2721a9c72adSKP Singh 	if (!task)
2731a9c72adSKP Singh 		return -EINVAL;
2741a9c72adSKP Singh 
275fda64ae0SMartin KaFai Lau 	nobusy = bpf_task_storage_trylock();
2764cf1bc1fSKP Singh 	/* This helper must only be called from places where the lifetime of the task
2774cf1bc1fSKP Singh 	 * is guaranteed. Either by being refcounted or by being protected
2784cf1bc1fSKP Singh 	 * by an RCU read-side critical section.
2794cf1bc1fSKP Singh 	 */
280fda64ae0SMartin KaFai Lau 	ret = task_storage_delete(task, map, nobusy);
281fda64ae0SMartin KaFai Lau 	if (nobusy)
282bc235cdbSSong Liu 		bpf_task_storage_unlock();
283bc235cdbSSong Liu 	return ret;
2844cf1bc1fSKP Singh }
2854cf1bc1fSKP Singh 
BPF_CALL_2(bpf_task_storage_delete,struct bpf_map *,map,struct task_struct *,task)2868a7dac37SMartin KaFai Lau BPF_CALL_2(bpf_task_storage_delete, struct bpf_map *, map, struct task_struct *,
2878a7dac37SMartin KaFai Lau 	   task)
2888a7dac37SMartin KaFai Lau {
2898a7dac37SMartin KaFai Lau 	int ret;
2908a7dac37SMartin KaFai Lau 
2918a7dac37SMartin KaFai Lau 	WARN_ON_ONCE(!bpf_rcu_lock_held());
2928a7dac37SMartin KaFai Lau 	if (!task)
2938a7dac37SMartin KaFai Lau 		return -EINVAL;
2948a7dac37SMartin KaFai Lau 
2958a7dac37SMartin KaFai Lau 	bpf_task_storage_lock();
2968a7dac37SMartin KaFai Lau 	/* This helper must only be called from places where the lifetime of the task
2978a7dac37SMartin KaFai Lau 	 * is guaranteed. Either by being refcounted or by being protected
2988a7dac37SMartin KaFai Lau 	 * by an RCU read-side critical section.
2998a7dac37SMartin KaFai Lau 	 */
3008a7dac37SMartin KaFai Lau 	ret = task_storage_delete(task, map, true);
3018a7dac37SMartin KaFai Lau 	bpf_task_storage_unlock();
3028a7dac37SMartin KaFai Lau 	return ret;
3038a7dac37SMartin KaFai Lau }
3048a7dac37SMartin KaFai Lau 
notsupp_get_next_key(struct bpf_map * map,void * key,void * next_key)3054cf1bc1fSKP Singh static int notsupp_get_next_key(struct bpf_map *map, void *key, void *next_key)
3064cf1bc1fSKP Singh {
3074cf1bc1fSKP Singh 	return -ENOTSUPP;
3084cf1bc1fSKP Singh }
3094cf1bc1fSKP Singh 
task_storage_map_alloc(union bpf_attr * attr)3104cf1bc1fSKP Singh static struct bpf_map *task_storage_map_alloc(union bpf_attr *attr)
3114cf1bc1fSKP Singh {
31208a7ce38SMartin KaFai Lau 	return bpf_local_storage_map_alloc(attr, &task_cache, true);
3134cf1bc1fSKP Singh }
3144cf1bc1fSKP Singh 
task_storage_map_free(struct bpf_map * map)3154cf1bc1fSKP Singh static void task_storage_map_free(struct bpf_map *map)
3164cf1bc1fSKP Singh {
317c83597faSYonghong Song 	bpf_local_storage_map_free(map, &task_cache, &bpf_task_storage_busy);
3184cf1bc1fSKP Singh }
3194cf1bc1fSKP Singh 
3203144bfa5SYonghong Song BTF_ID_LIST_GLOBAL_SINGLE(bpf_local_storage_map_btf_id, struct, bpf_local_storage_map)
3214cf1bc1fSKP Singh const struct bpf_map_ops task_storage_map_ops = {
3224cf1bc1fSKP Singh 	.map_meta_equal = bpf_map_meta_equal,
3234cf1bc1fSKP Singh 	.map_alloc_check = bpf_local_storage_map_alloc_check,
3244cf1bc1fSKP Singh 	.map_alloc = task_storage_map_alloc,
3254cf1bc1fSKP Singh 	.map_free = task_storage_map_free,
3264cf1bc1fSKP Singh 	.map_get_next_key = notsupp_get_next_key,
3274cf1bc1fSKP Singh 	.map_lookup_elem = bpf_pid_task_storage_lookup_elem,
3284cf1bc1fSKP Singh 	.map_update_elem = bpf_pid_task_storage_update_elem,
3294cf1bc1fSKP Singh 	.map_delete_elem = bpf_pid_task_storage_delete_elem,
3304cf1bc1fSKP Singh 	.map_check_btf = bpf_local_storage_map_check_btf,
3317490b7f1SYafang Shao 	.map_mem_usage = bpf_local_storage_map_mem_usage,
3323144bfa5SYonghong Song 	.map_btf_id = &bpf_local_storage_map_btf_id[0],
3334cf1bc1fSKP Singh 	.map_owner_storage_ptr = task_storage_ptr,
3344cf1bc1fSKP Singh };
3354cf1bc1fSKP Singh 
3360593dd34SMartin KaFai Lau const struct bpf_func_proto bpf_task_storage_get_recur_proto = {
3370593dd34SMartin KaFai Lau 	.func = bpf_task_storage_get_recur,
3384cf1bc1fSKP Singh 	.gpl_only = false,
3394cf1bc1fSKP Singh 	.ret_type = RET_PTR_TO_MAP_VALUE_OR_NULL,
3404cf1bc1fSKP Singh 	.arg1_type = ARG_CONST_MAP_PTR,
341*91571a51SAlexei Starovoitov 	.arg2_type = ARG_PTR_TO_BTF_ID_OR_NULL,
342d19ddb47SSong Liu 	.arg2_btf_id = &btf_tracing_ids[BTF_TRACING_TYPE_TASK],
3434cf1bc1fSKP Singh 	.arg3_type = ARG_PTR_TO_MAP_VALUE_OR_NULL,
3444cf1bc1fSKP Singh 	.arg4_type = ARG_ANYTHING,
3454cf1bc1fSKP Singh };
3464cf1bc1fSKP Singh 
3474279adb0SMartin KaFai Lau const struct bpf_func_proto bpf_task_storage_get_proto = {
3484279adb0SMartin KaFai Lau 	.func = bpf_task_storage_get,
3494279adb0SMartin KaFai Lau 	.gpl_only = false,
3504279adb0SMartin KaFai Lau 	.ret_type = RET_PTR_TO_MAP_VALUE_OR_NULL,
3514279adb0SMartin KaFai Lau 	.arg1_type = ARG_CONST_MAP_PTR,
352*91571a51SAlexei Starovoitov 	.arg2_type = ARG_PTR_TO_BTF_ID_OR_NULL,
3534279adb0SMartin KaFai Lau 	.arg2_btf_id = &btf_tracing_ids[BTF_TRACING_TYPE_TASK],
3544279adb0SMartin KaFai Lau 	.arg3_type = ARG_PTR_TO_MAP_VALUE_OR_NULL,
3554279adb0SMartin KaFai Lau 	.arg4_type = ARG_ANYTHING,
3564279adb0SMartin KaFai Lau };
3574279adb0SMartin KaFai Lau 
3580593dd34SMartin KaFai Lau const struct bpf_func_proto bpf_task_storage_delete_recur_proto = {
3590593dd34SMartin KaFai Lau 	.func = bpf_task_storage_delete_recur,
3604cf1bc1fSKP Singh 	.gpl_only = false,
3614cf1bc1fSKP Singh 	.ret_type = RET_INTEGER,
3624cf1bc1fSKP Singh 	.arg1_type = ARG_CONST_MAP_PTR,
363*91571a51SAlexei Starovoitov 	.arg2_type = ARG_PTR_TO_BTF_ID_OR_NULL,
364d19ddb47SSong Liu 	.arg2_btf_id = &btf_tracing_ids[BTF_TRACING_TYPE_TASK],
3654cf1bc1fSKP Singh };
3668a7dac37SMartin KaFai Lau 
3678a7dac37SMartin KaFai Lau const struct bpf_func_proto bpf_task_storage_delete_proto = {
3688a7dac37SMartin KaFai Lau 	.func = bpf_task_storage_delete,
3698a7dac37SMartin KaFai Lau 	.gpl_only = false,
3708a7dac37SMartin KaFai Lau 	.ret_type = RET_INTEGER,
3718a7dac37SMartin KaFai Lau 	.arg1_type = ARG_CONST_MAP_PTR,
372*91571a51SAlexei Starovoitov 	.arg2_type = ARG_PTR_TO_BTF_ID_OR_NULL,
3738a7dac37SMartin KaFai Lau 	.arg2_btf_id = &btf_tracing_ids[BTF_TRACING_TYPE_TASK],
3748a7dac37SMartin KaFai Lau };
375