* Re: [PATCH RFC bpf-next v1 5/8] bpf: Introduce a new program type bpf_view.
@ 2022-01-10 7:06 kernel test robot
0 siblings, 0 replies; 3+ messages in thread
From: kernel test robot @ 2022-01-10 7:06 UTC (permalink / raw)
To: kbuild
[-- Attachment #1: Type: text/plain, Size: 15611 bytes --]
CC: llvm(a)lists.linux.dev
CC: kbuild-all(a)lists.01.org
In-Reply-To: <20220106215059.2308931-6-haoluo@google.com>
References: <20220106215059.2308931-6-haoluo@google.com>
TO: Hao Luo <haoluo@google.com>
Hi Hao,
[FYI, it's a private test report for your RFC patch.]
[auto build test WARNING on bpf-next/master]
url: https://github.com/0day-ci/linux/commits/Hao-Luo/Pinning-bpf-objects-outside-bpffs/20220107-055252
base: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master
:::::: branch date: 3 days ago
:::::: commit date: 3 days ago
config: arm-randconfig-c002-20220107 (https://download.01.org/0day-ci/archive/20220110/202201101429.2XquVD3A-lkp(a)intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 32167bfe64a4c5dd4eb3f7a58e24f4cba76f5ac2)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install arm cross compiling tool for clang build
# apt-get install binutils-arm-linux-gnueabi
# https://github.com/0day-ci/linux/commit/f3a5b66e45ed0d7bdc610cce2e0b6a3c606dbb95
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Hao-Luo/Pinning-bpf-objects-outside-bpffs/20220107-055252
git checkout f3a5b66e45ed0d7bdc610cce2e0b6a3c606dbb95
# save the config file to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=arm clang-analyzer
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
clang-analyzer warnings: (new ones prefixed by >>)
fs/ext4/mballoc.c:5817:3: note: Value stored to 'err' is never read
err = PTR_ERR(bitmap_bh);
^ ~~~~~~~~~~~~~~~~~~
Suppressed 2 warnings (2 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
1 warning generated.
Suppressed 1 warnings (1 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
2 warnings generated.
fs/xfs/libxfs/xfs_attr.c:1243:2: warning: Value stored to 'error' is never read [clang-analyzer-deadcode.DeadStores]
error = xfs_attr_node_removename(args, state);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
fs/xfs/libxfs/xfs_attr.c:1243:2: note: Value stored to 'error' is never read
error = xfs_attr_node_removename(args, state);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Suppressed 1 warnings (1 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
3 warnings generated.
fs/xfs/libxfs/xfs_attr_leaf.c:2243:29: warning: Value stored to 'drop_leaf' during its initialization is never read [clang-analyzer-deadcode.DeadStores]
struct xfs_attr_leafblock *drop_leaf = drop_blk->bp->b_addr;
^~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
fs/xfs/libxfs/xfs_attr_leaf.c:2243:29: note: Value stored to 'drop_leaf' during its initialization is never read
struct xfs_attr_leafblock *drop_leaf = drop_blk->bp->b_addr;
^~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
fs/xfs/libxfs/xfs_attr_leaf.c:2244:29: warning: Value stored to 'save_leaf' during its initialization is never read [clang-analyzer-deadcode.DeadStores]
struct xfs_attr_leafblock *save_leaf = save_blk->bp->b_addr;
^~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
fs/xfs/libxfs/xfs_attr_leaf.c:2244:29: note: Value stored to 'save_leaf' during its initialization is never read
struct xfs_attr_leafblock *save_leaf = save_blk->bp->b_addr;
^~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
Suppressed 1 warnings (1 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
1 warning generated.
Suppressed 1 warnings (1 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
1 warning generated.
Suppressed 1 warnings (1 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
1 warning generated.
Suppressed 1 warnings (1 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
1 warning generated.
Suppressed 1 warnings (1 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
1 warning generated.
Suppressed 1 warnings (1 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
1 warning generated.
Suppressed 1 warnings (1 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
1 warning generated.
Suppressed 1 warnings (1 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
4 warnings generated.
fs/xfs/xfs_reflink.c:1151:3: warning: Value stored to 'qdelta' is never read [clang-analyzer-deadcode.DeadStores]
qdelta += dmap->br_blockcount;
^ ~~~~~~~~~~~~~~~~~~~
fs/xfs/xfs_reflink.c:1151:3: note: Value stored to 'qdelta' is never read
qdelta += dmap->br_blockcount;
^ ~~~~~~~~~~~~~~~~~~~
fs/xfs/xfs_reflink.c:1326:2: warning: Value stored to 'ret' is never read [clang-analyzer-deadcode.DeadStores]
ret = -EINVAL;
^ ~~~~~~~
fs/xfs/xfs_reflink.c:1326:2: note: Value stored to 'ret' is never read
ret = -EINVAL;
^ ~~~~~~~
Suppressed 2 warnings (1 in non-user code, 1 with check filters).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
1 warning generated.
drivers/clk/clk-max9485.c:199:9: warning: Access to field 'out' results in a dereference of a null pointer (loaded from variable 'prev') [clang-analyzer-core.NullDereference]
return prev->out;
^~~~
drivers/clk/clk-max9485.c:165:36: note: 'prev' initialized to a null pointer value
const struct max9485_rate *curr, *prev = NULL;
^~~~
drivers/clk/clk-max9485.c:167:29: note: Assuming field 'out' is equal to 0
for (curr = max9485_rates; curr->out != 0; curr++) {
^~~~~~~~~~~~~~
drivers/clk/clk-max9485.c:167:2: note: Loop condition is false. Execution continues on line 199
for (curr = max9485_rates; curr->out != 0; curr++) {
^
drivers/clk/clk-max9485.c:199:9: note: Access to field 'out' results in a dereference of a null pointer (loaded from variable 'prev')
return prev->out;
^~~~
1 warning generated.
Suppressed 1 warnings (1 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
1 warning generated.
Suppressed 1 warnings (1 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
1 warning generated.
Suppressed 1 warnings (1 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
1 warning generated.
Suppressed 1 warnings (1 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
1 warning generated.
Suppressed 1 warnings (1 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
2 warnings generated.
>> kernel/bpf/bpf_view.c:151:36: warning: Array subscript is undefined [clang-analyzer-core.uninitialized.ArraySubscript]
target->ctx_arg_info[i].btf_id = bpf_view_btf_ids[idx[i]];
^
kernel/bpf/bpf_view.c:174:2: note: Calling 'register_bpf_view_target'
register_bpf_view_target(&cgroup_view_tinfo, cgroup_view_idx);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
kernel/bpf/bpf_view.c:150:14: note: Assuming 'i' is < field 'ctx_arg_info_size'
for (i = 0; i < target->ctx_arg_info_size; ++i)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
kernel/bpf/bpf_view.c:150:2: note: Loop condition is true. Entering loop body
for (i = 0; i < target->ctx_arg_info_size; ++i)
^
kernel/bpf/bpf_view.c:150:14: note: Assuming 'i' is < field 'ctx_arg_info_size'
for (i = 0; i < target->ctx_arg_info_size; ++i)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
kernel/bpf/bpf_view.c:150:2: note: Loop condition is true. Entering loop body
for (i = 0; i < target->ctx_arg_info_size; ++i)
^
kernel/bpf/bpf_view.c:150:45: note: The value 2 is assigned to 'i'
for (i = 0; i < target->ctx_arg_info_size; ++i)
^~~
kernel/bpf/bpf_view.c:150:14: note: Assuming 'i' is < field 'ctx_arg_info_size'
for (i = 0; i < target->ctx_arg_info_size; ++i)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
kernel/bpf/bpf_view.c:150:2: note: Loop condition is true. Entering loop body
for (i = 0; i < target->ctx_arg_info_size; ++i)
^
kernel/bpf/bpf_view.c:151:36: note: Array subscript is undefined
target->ctx_arg_info[i].btf_id = bpf_view_btf_ids[idx[i]];
^ ~~~~~~
Suppressed 1 warnings (1 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
1 warning generated.
Suppressed 1 warnings (1 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
1 warning generated.
Suppressed 1 warnings (1 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
3 warnings generated.
mm/slab.c:1645:2: warning: Assigned value is garbage or undefined [clang-analyzer-core.uninitialized.Assign]
list_for_each_entry_safe(page, n, list, slab_list) {
^
include/linux/list.h:718:7: note: expanded from macro 'list_for_each_entry_safe'
n = list_next_entry(pos, member); \
^
include/linux/list.h:557:2: note: expanded from macro 'list_next_entry'
list_entry((pos)->member.next, typeof(*(pos)), member)
^
include/linux/list.h:513:2: note: expanded from macro 'list_entry'
container_of(ptr, type, member)
^
include/linux/container_of.h:18:2: note: expanded from macro 'container_of'
void *__mptr = (void *)(ptr); \
^
mm/slab.c:4135:6: note: Assuming 'count' is <= MAX_SLABINFO_WRITE
if (count > MAX_SLABINFO_WRITE)
^~~~~~~~~~~~~~~~~~~~~~~~~~
mm/slab.c:4135:2: note: Taking false branch
if (count > MAX_SLABINFO_WRITE)
^
mm/slab.c:4137:2: note: Taking false branch
if (copy_from_user(&kbuf, buffer, count))
^
mm/slab.c:4142:6: note: Assuming 'tmp' is non-null
if (!tmp)
^~~~
mm/slab.c:4142:2: note: Taking false branch
if (!tmp)
^
mm/slab.c:4146:6: note: Assuming the condition is false
if (sscanf(tmp, " %d %d %d", &limit, &batchcount, &shared) != 3)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
mm/slab.c:4146:2: note: Taking false branch
if (sscanf(tmp, " %d %d %d", &limit, &batchcount, &shared) != 3)
^
mm/slab.c:4152:2: note: Loop condition is true. Entering loop body
list_for_each_entry(cachep, &slab_caches, list) {
^
include/linux/list.h:630:2: note: expanded from macro 'list_for_each_entry'
for (pos = list_first_entry(head, typeof(*pos), member); \
^
mm/slab.c:4153:7: note: Assuming the condition is true
if (!strcmp(cachep->name, kbuf)) {
^~~~~~~~~~~~~~~~~~~~~~~~~~~
mm/slab.c:4153:3: note: Taking true branch
if (!strcmp(cachep->name, kbuf)) {
^
mm/slab.c:4154:8: note: Assuming 'limit' is >= 1
if (limit < 1 || batchcount < 1 ||
^~~~~~~~~
mm/slab.c:4154:8: note: Left side of '||' is false
mm/slab.c:4154:21: note: Assuming 'batchcount' is >= 1
if (limit < 1 || batchcount < 1 ||
^~~~~~~~~~~~~~
mm/slab.c:4154:8: note: Left side of '||' is false
if (limit < 1 || batchcount < 1 ||
^
mm/slab.c:4155:6: note: Assuming 'batchcount' is <= 'limit'
batchcount > limit || shared < 0) {
^~~~~~~~~~~~~~~~~~
mm/slab.c:4154:8: note: Left side of '||' is false
vim +151 kernel/bpf/bpf_view.c
f3a5b66e45ed0d Hao Luo 2022-01-06 144
f3a5b66e45ed0d Hao Luo 2022-01-06 145 static void register_bpf_view_target(struct bpf_view_target_info *target,
f3a5b66e45ed0d Hao Luo 2022-01-06 146 int idx[BPF_VIEW_CTX_ARG_MAX])
f3a5b66e45ed0d Hao Luo 2022-01-06 147 {
f3a5b66e45ed0d Hao Luo 2022-01-06 148 int i;
f3a5b66e45ed0d Hao Luo 2022-01-06 149
f3a5b66e45ed0d Hao Luo 2022-01-06 150 for (i = 0; i < target->ctx_arg_info_size; ++i)
f3a5b66e45ed0d Hao Luo 2022-01-06 @151 target->ctx_arg_info[i].btf_id = bpf_view_btf_ids[idx[i]];
f3a5b66e45ed0d Hao Luo 2022-01-06 152
f3a5b66e45ed0d Hao Luo 2022-01-06 153 INIT_LIST_HEAD(&target->list);
f3a5b66e45ed0d Hao Luo 2022-01-06 154 list_add(&target->list, &targets);
f3a5b66e45ed0d Hao Luo 2022-01-06 155 }
f3a5b66e45ed0d Hao Luo 2022-01-06 156
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH RFC bpf-next v1 5/8] bpf: Introduce a new program type bpf_view.
2022-01-06 21:50 ` [PATCH RFC bpf-next v1 5/8] bpf: Introduce a new program type bpf_view Hao Luo
@ 2022-01-07 0:35 ` Yonghong Song
0 siblings, 0 replies; 3+ messages in thread
From: Yonghong Song @ 2022-01-07 0:35 UTC (permalink / raw)
To: Hao Luo, Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann
Cc: Martin KaFai Lau, Song Liu, KP Singh, Shakeel Butt, Joe Burton,
Stanislav Fomichev, bpf
On 1/6/22 1:50 PM, Hao Luo wrote:
> Introduce a new program type called "bpf_view", which can be used to
> print out a kernel object's state to a seq file. So the signature of
> this program consists of two parameters: a seq file and a kernel object.
> Currently only 'struct cgroup' is supported.
>
> The following patches will introduce a call site for this program type
> and allow users to customize the format of printing out the state of
> kernel objects to userspace.
>
> Signed-off-by: Hao Luo <haoluo@google.com>
> ---
> include/linux/bpf.h | 4 +
> include/uapi/linux/bpf.h | 2 +
> kernel/bpf/Makefile | 2 +-
> kernel/bpf/bpf_view.c | 179 +++++++++++++++++++++++++++++++++
> kernel/bpf/bpf_view.h | 24 +++++
> kernel/bpf/syscall.c | 3 +
> kernel/bpf/verifier.c | 6 ++
> kernel/trace/bpf_trace.c | 12 ++-
> tools/include/uapi/linux/bpf.h | 2 +
> 9 files changed, 230 insertions(+), 4 deletions(-)
> create mode 100644 kernel/bpf/bpf_view.c
> create mode 100644 kernel/bpf/bpf_view.h
>
> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> index 2ec693c3d6f6..16f582dfff7e 100644
> --- a/include/linux/bpf.h
> +++ b/include/linux/bpf.h
> @@ -1622,6 +1622,10 @@ void bpf_iter_map_show_fdinfo(const struct bpf_iter_aux_info *aux,
> int bpf_iter_map_fill_link_info(const struct bpf_iter_aux_info *aux,
> struct bpf_link_info *info);
>
> +bool bpf_view_prog_supported(struct bpf_prog *prog);
> +int bpf_view_link_attach(const union bpf_attr *attr, bpfptr_t uattr,
> + struct bpf_prog *prog);
> +
> int map_set_for_each_callback_args(struct bpf_verifier_env *env,
> struct bpf_func_state *caller,
> struct bpf_func_state *callee);
> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
> index b0383d371b9a..efa0f21d13ba 100644
> --- a/include/uapi/linux/bpf.h
> +++ b/include/uapi/linux/bpf.h
> @@ -982,6 +982,7 @@ enum bpf_attach_type {
> BPF_MODIFY_RETURN,
> BPF_LSM_MAC,
> BPF_TRACE_ITER,
> + BPF_TRACE_VIEW,
Please add the new entry to the end of enum list. Otherwise,
this will break backward compatibility.
> BPF_CGROUP_INET4_GETPEERNAME,
> BPF_CGROUP_INET6_GETPEERNAME,
> BPF_CGROUP_INET4_GETSOCKNAME,
> @@ -1009,6 +1010,7 @@ enum bpf_link_type {
> BPF_LINK_TYPE_NETNS = 5,
> BPF_LINK_TYPE_XDP = 6,
> BPF_LINK_TYPE_PERF_EVENT = 7,
> + BPF_LINK_TYPE_VIEW = 8,
>
> MAX_BPF_LINK_TYPE,
> };
[...]
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH RFC bpf-next v1 5/8] bpf: Introduce a new program type bpf_view.
2022-01-06 21:50 [PATCH RFC bpf-next v1 0/8] Pinning bpf objects outside bpffs Hao Luo
@ 2022-01-06 21:50 ` Hao Luo
2022-01-07 0:35 ` Yonghong Song
0 siblings, 1 reply; 3+ messages in thread
From: Hao Luo @ 2022-01-06 21:50 UTC (permalink / raw)
To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann
Cc: Martin KaFai Lau, Song Liu, Yonghong Song, KP Singh,
Shakeel Butt, Joe Burton, Stanislav Fomichev, bpf, Hao Luo
Introduce a new program type called "bpf_view", which can be used to
print out a kernel object's state to a seq file. So the signature of
this program consists of two parameters: a seq file and a kernel object.
Currently only 'struct cgroup' is supported.
The following patches will introduce a call site for this program type
and allow users to customize the format of printing out the state of
kernel objects to userspace.
Signed-off-by: Hao Luo <haoluo@google.com>
---
include/linux/bpf.h | 4 +
include/uapi/linux/bpf.h | 2 +
kernel/bpf/Makefile | 2 +-
kernel/bpf/bpf_view.c | 179 +++++++++++++++++++++++++++++++++
kernel/bpf/bpf_view.h | 24 +++++
kernel/bpf/syscall.c | 3 +
kernel/bpf/verifier.c | 6 ++
kernel/trace/bpf_trace.c | 12 ++-
tools/include/uapi/linux/bpf.h | 2 +
9 files changed, 230 insertions(+), 4 deletions(-)
create mode 100644 kernel/bpf/bpf_view.c
create mode 100644 kernel/bpf/bpf_view.h
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 2ec693c3d6f6..16f582dfff7e 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -1622,6 +1622,10 @@ void bpf_iter_map_show_fdinfo(const struct bpf_iter_aux_info *aux,
int bpf_iter_map_fill_link_info(const struct bpf_iter_aux_info *aux,
struct bpf_link_info *info);
+bool bpf_view_prog_supported(struct bpf_prog *prog);
+int bpf_view_link_attach(const union bpf_attr *attr, bpfptr_t uattr,
+ struct bpf_prog *prog);
+
int map_set_for_each_callback_args(struct bpf_verifier_env *env,
struct bpf_func_state *caller,
struct bpf_func_state *callee);
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index b0383d371b9a..efa0f21d13ba 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -982,6 +982,7 @@ enum bpf_attach_type {
BPF_MODIFY_RETURN,
BPF_LSM_MAC,
BPF_TRACE_ITER,
+ BPF_TRACE_VIEW,
BPF_CGROUP_INET4_GETPEERNAME,
BPF_CGROUP_INET6_GETPEERNAME,
BPF_CGROUP_INET4_GETSOCKNAME,
@@ -1009,6 +1010,7 @@ enum bpf_link_type {
BPF_LINK_TYPE_NETNS = 5,
BPF_LINK_TYPE_XDP = 6,
BPF_LINK_TYPE_PERF_EVENT = 7,
+ BPF_LINK_TYPE_VIEW = 8,
MAX_BPF_LINK_TYPE,
};
diff --git a/kernel/bpf/Makefile b/kernel/bpf/Makefile
index b1abf0d94b5b..c662734d83c5 100644
--- a/kernel/bpf/Makefile
+++ b/kernel/bpf/Makefile
@@ -8,7 +8,7 @@ CFLAGS_core.o += $(call cc-disable-warning, override-init) $(cflags-nogcse-yy)
obj-$(CONFIG_BPF_SYSCALL) += syscall.o verifier.o inode.o helpers.o tnum.o bpf_iter.o map_iter.o task_iter.o prog_iter.o
obj-$(CONFIG_BPF_SYSCALL) += hashtab.o arraymap.o percpu_freelist.o bpf_lru_list.o lpm_trie.o map_in_map.o bloom_filter.o
-obj-$(CONFIG_BPF_SYSCALL) += local_storage.o queue_stack_maps.o ringbuf.o kernfs_node.o
+obj-$(CONFIG_BPF_SYSCALL) += local_storage.o queue_stack_maps.o ringbuf.o kernfs_node.o bpf_view.o
obj-$(CONFIG_BPF_SYSCALL) += bpf_local_storage.o bpf_task_storage.o
obj-${CONFIG_BPF_LSM} += bpf_inode_storage.o
obj-$(CONFIG_BPF_SYSCALL) += disasm.o
diff --git a/kernel/bpf/bpf_view.c b/kernel/bpf/bpf_view.c
new file mode 100644
index 000000000000..967a9240bab4
--- /dev/null
+++ b/kernel/bpf/bpf_view.c
@@ -0,0 +1,179 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/bpf.h>
+#include <linux/btf_ids.h>
+#include <linux/cgroup.h>
+#include <linux/filter.h>
+#include "bpf_view.h"
+
+static struct list_head targets = LIST_HEAD_INIT(targets);
+
+/* bpf_view_link operations */
+
+struct bpf_view_target_info {
+ struct list_head list;
+ const char *target;
+ u32 ctx_arg_info_size;
+ struct bpf_ctx_arg_aux ctx_arg_info[BPF_VIEW_CTX_ARG_MAX];
+ u32 btf_id;
+};
+
+struct bpf_view_link {
+ struct bpf_link link;
+ struct bpf_view_target_info *tinfo;
+};
+
+static void bpf_view_link_release(struct bpf_link *link)
+{
+}
+
+static void bpf_view_link_dealloc(struct bpf_link *link)
+{
+ struct bpf_view_link *view_link =
+ container_of(link, struct bpf_view_link, link);
+ kfree(view_link);
+}
+
+static void bpf_view_link_show_fdinfo(const struct bpf_link *link,
+ struct seq_file *seq)
+{
+ struct bpf_view_link *view_link =
+ container_of(link, struct bpf_view_link, link);
+
+ seq_printf(seq, "attach_target:\t%s\n", view_link->tinfo->target);
+}
+
+static const struct bpf_link_ops bpf_view_link_lops = {
+ .release = bpf_view_link_release,
+ .dealloc = bpf_view_link_dealloc,
+ .show_fdinfo = bpf_view_link_show_fdinfo,
+};
+
+bool bpf_link_is_view(struct bpf_link *link)
+{
+ return link->ops == &bpf_view_link_lops;
+}
+
+int bpf_view_link_attach(const union bpf_attr *attr, bpfptr_t uattr,
+ struct bpf_prog *prog)
+{
+ struct bpf_link_primer link_primer;
+ struct bpf_view_target_info *tinfo;
+ struct bpf_view_link *link;
+ u32 prog_btf_id;
+ bool existed = false;
+ int err;
+
+ prog_btf_id = prog->aux->attach_btf_id;
+ list_for_each_entry(tinfo, &targets, list) {
+ if (tinfo->btf_id == prog_btf_id) {
+ existed = true;
+ break;
+ }
+ }
+ if (!existed)
+ return -ENOENT;
+
+ link = kzalloc(sizeof(*link), GFP_USER | __GFP_NOWARN);
+ if (!link)
+ return -ENOMEM;
+
+ bpf_link_init(&link->link, BPF_LINK_TYPE_VIEW, &bpf_view_link_lops, prog);
+ link->tinfo = tinfo;
+ err = bpf_link_prime(&link->link, &link_primer);
+ if (err) {
+ kfree(link);
+ return err;
+ }
+
+ return bpf_link_settle(&link_primer);
+}
+
+int run_view_prog(struct bpf_prog *prog, void *ctx)
+{
+ int ret;
+
+ rcu_read_lock();
+ migrate_disable();
+ ret = bpf_prog_run(prog, ctx);
+ migrate_enable();
+ rcu_read_unlock();
+
+ return ret;
+}
+
+bool bpf_view_prog_supported(struct bpf_prog *prog)
+{
+ const char *attach_fname = prog->aux->attach_func_name;
+ const char *prefix = BPF_VIEW_FUNC_PREFIX;
+ u32 prog_btf_id = prog->aux->attach_btf_id;
+ struct bpf_view_target_info *tinfo;
+ int prefix_len = strlen(prefix);
+ bool supported = false;
+
+ if (strncmp(attach_fname, prefix, prefix_len))
+ return false;
+
+ list_for_each_entry(tinfo, &targets, list) {
+ if (tinfo->btf_id && tinfo->btf_id == prog_btf_id) {
+ supported = true;
+ break;
+ }
+ if (!strcmp(attach_fname + prefix_len, tinfo->target)) {
+ tinfo->btf_id = prog->aux->attach_btf_id;
+ supported = true;
+ break;
+ }
+ }
+ if (supported) {
+ prog->aux->ctx_arg_info_size = tinfo->ctx_arg_info_size;
+ prog->aux->ctx_arg_info = tinfo->ctx_arg_info;
+ }
+ return supported;
+}
+
+/* Generate BTF_IDs */
+BTF_ID_LIST(bpf_view_btf_ids)
+BTF_ID(struct, seq_file)
+BTF_ID(struct, cgroup)
+
+/* Index of bpf_view_btf_ids */
+enum {
+ BTF_ID_SEQ_FILE = 0,
+ BTF_ID_CGROUP,
+};
+
+static void register_bpf_view_target(struct bpf_view_target_info *target,
+ int idx[BPF_VIEW_CTX_ARG_MAX])
+{
+ int i;
+
+ for (i = 0; i < target->ctx_arg_info_size; ++i)
+ target->ctx_arg_info[i].btf_id = bpf_view_btf_ids[idx[i]];
+
+ INIT_LIST_HEAD(&target->list);
+ list_add(&target->list, &targets);
+}
+
+DEFINE_BPF_VIEW_FUNC(cgroup, struct seq_file *seq, struct cgroup *cgroup)
+
+static struct bpf_view_target_info cgroup_view_tinfo = {
+ .target = "cgroup",
+ .ctx_arg_info_size = 2,
+ .ctx_arg_info = {
+ { offsetof(struct bpf_view_cgroup_ctx, seq), PTR_TO_BTF_ID },
+ { offsetof(struct bpf_view_cgroup_ctx, cgroup), PTR_TO_BTF_ID },
+ },
+ .btf_id = 0,
+};
+
+static int __init bpf_view_init(void)
+{
+ int cgroup_view_idx[BPF_VIEW_CTX_ARG_MAX] = {
+ BTF_ID_SEQ_FILE, BTF_ID_CGROUP };
+
+ register_bpf_view_target(&cgroup_view_tinfo, cgroup_view_idx);
+
+ return 0;
+}
+late_initcall(bpf_view_init);
+
diff --git a/kernel/bpf/bpf_view.h b/kernel/bpf/bpf_view.h
new file mode 100644
index 000000000000..1a1110a5727f
--- /dev/null
+++ b/kernel/bpf/bpf_view.h
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#ifndef _BPF_VIEW_H_
+#define _BPF_VIEW_H_
+
+#include <linux/bpf.h>
+
+#define BPF_VIEW_FUNC_PREFIX "bpf_view_"
+#define DEFINE_BPF_VIEW_FUNC(target, args...) \
+ extern int bpf_view_ ## target(args); \
+ int __init bpf_view_ ## target(args) { return 0; }
+
+#define BPF_VIEW_CTX_ARG_MAX 2
+
+struct bpf_view_cgroup_ctx {
+ __bpf_md_ptr(struct seq_file *, seq);
+ __bpf_md_ptr(struct cgroup *, cgroup);
+};
+
+bool bpf_link_is_view(struct bpf_link *link);
+
+/* Run a bpf_view program */
+int run_view_prog(struct bpf_prog *prog, void *ctx);
+
+#endif // _BPF_VIEW_H_
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index fa4505f9b611..32ac84d3ac0b 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -3175,6 +3175,7 @@ attach_type_to_prog_type(enum bpf_attach_type attach_type)
case BPF_CGROUP_SETSOCKOPT:
return BPF_PROG_TYPE_CGROUP_SOCKOPT;
case BPF_TRACE_ITER:
+ case BPF_TRACE_VIEW:
return BPF_PROG_TYPE_TRACING;
case BPF_SK_LOOKUP:
return BPF_PROG_TYPE_SK_LOOKUP;
@@ -4235,6 +4236,8 @@ static int tracing_bpf_link_attach(const union bpf_attr *attr, bpfptr_t uattr,
if (prog->expected_attach_type == BPF_TRACE_ITER)
return bpf_iter_link_attach(attr, uattr, prog);
+ else if (prog->expected_attach_type == BPF_TRACE_VIEW)
+ return bpf_view_link_attach(attr, uattr, prog);
else if (prog->type == BPF_PROG_TYPE_EXT)
return bpf_tracing_prog_attach(prog,
attr->link_create.target_fd,
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index bfb45381fb3f..ce7816519c93 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -9770,6 +9770,7 @@ static int check_return_code(struct bpf_verifier_env *env)
case BPF_MODIFY_RETURN:
return 0;
case BPF_TRACE_ITER:
+ case BPF_TRACE_VIEW:
break;
default:
return -ENOTSUPP;
@@ -13971,6 +13972,7 @@ int bpf_check_attach_target(struct bpf_verifier_log *log,
break;
case BPF_TRACE_ITER:
+ case BPF_TRACE_VIEW:
if (!btf_type_is_func(t)) {
bpf_log(log, "attach_btf_id %u is not a function\n",
btf_id);
@@ -14147,6 +14149,10 @@ static int check_attach_btf_id(struct bpf_verifier_env *env)
if (!bpf_iter_prog_supported(prog))
return -EINVAL;
return 0;
+ } else if (prog->expected_attach_type == BPF_TRACE_VIEW) {
+ if (!bpf_view_prog_supported(prog))
+ return -EINVAL;
+ return 0;
}
if (prog->type == BPF_PROG_TYPE_LSM) {
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index 21aa30644219..9413b5af6e2c 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -1630,6 +1630,12 @@ raw_tp_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
}
}
+static inline bool prog_support_seq_helpers(const struct bpf_prog *prog)
+{
+ return prog->expected_attach_type == BPF_TRACE_ITER ||
+ prog->expected_attach_type == BPF_TRACE_VIEW;
+}
+
const struct bpf_func_proto *
tracing_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
{
@@ -1663,15 +1669,15 @@ tracing_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
return &bpf_get_socket_ptr_cookie_proto;
#endif
case BPF_FUNC_seq_printf:
- return prog->expected_attach_type == BPF_TRACE_ITER ?
+ return prog_support_seq_helpers(prog) ?
&bpf_seq_printf_proto :
NULL;
case BPF_FUNC_seq_write:
- return prog->expected_attach_type == BPF_TRACE_ITER ?
+ return prog_support_seq_helpers(prog) ?
&bpf_seq_write_proto :
NULL;
case BPF_FUNC_seq_printf_btf:
- return prog->expected_attach_type == BPF_TRACE_ITER ?
+ return prog_support_seq_helpers(prog) ?
&bpf_seq_printf_btf_proto :
NULL;
case BPF_FUNC_d_path:
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index b0383d371b9a..efa0f21d13ba 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -982,6 +982,7 @@ enum bpf_attach_type {
BPF_MODIFY_RETURN,
BPF_LSM_MAC,
BPF_TRACE_ITER,
+ BPF_TRACE_VIEW,
BPF_CGROUP_INET4_GETPEERNAME,
BPF_CGROUP_INET6_GETPEERNAME,
BPF_CGROUP_INET4_GETSOCKNAME,
@@ -1009,6 +1010,7 @@ enum bpf_link_type {
BPF_LINK_TYPE_NETNS = 5,
BPF_LINK_TYPE_XDP = 6,
BPF_LINK_TYPE_PERF_EVENT = 7,
+ BPF_LINK_TYPE_VIEW = 8,
MAX_BPF_LINK_TYPE,
};
--
2.34.1.448.ga2b2bfdf31-goog
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2022-01-10 7:06 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-10 7:06 [PATCH RFC bpf-next v1 5/8] bpf: Introduce a new program type bpf_view kernel test robot
-- strict thread matches above, loose matches on Subject: below --
2022-01-06 21:50 [PATCH RFC bpf-next v1 0/8] Pinning bpf objects outside bpffs Hao Luo
2022-01-06 21:50 ` [PATCH RFC bpf-next v1 5/8] bpf: Introduce a new program type bpf_view Hao Luo
2022-01-07 0:35 ` Yonghong Song
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.