[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20220328175033.2437312-15-roberto.sassu@huawei.com>
Date: Mon, 28 Mar 2022 19:50:29 +0200
From: Roberto Sassu <roberto.sassu@...wei.com>
To: <corbet@....net>, <viro@...iv.linux.org.uk>, <ast@...nel.org>,
<daniel@...earbox.net>, <andrii@...nel.org>, <kpsingh@...nel.org>,
<shuah@...nel.org>, <mcoquelin.stm32@...il.com>,
<alexandre.torgue@...s.st.com>, <zohar@...ux.ibm.com>
CC: <linux-doc@...r.kernel.org>, <linux-fsdevel@...r.kernel.org>,
<netdev@...r.kernel.org>, <bpf@...r.kernel.org>,
<linux-kselftest@...r.kernel.org>,
<linux-stm32@...md-mailman.stormreply.com>,
<linux-arm-kernel@...ts.infradead.org>,
<linux-integrity@...r.kernel.org>,
<linux-security-module@...r.kernel.org>,
<linux-kernel@...r.kernel.org>,
Roberto Sassu <roberto.sassu@...wei.com>
Subject: [PATCH 14/18] bpf-preload: Switch to new preload registration method
Modify the automatic generator of the light skeleton by adding three calls
to bpf_preload_set_ops() for registering and unregistering a preload
method, two in load_skel() (set and unset if there is an error) and one in
free_objs_and_skel().
Regenerate the light skeleton of the already preloaded eBPF program
iterators_bpf, which will now use the new registration method, and directly
call load_skel() and free_objs_and_skel() in the init and fini module
entrypoints.
Finally, allow users to specify a customized list of eBPF programs to
preload with the CONFIG_BPF_PRELOAD_LIST option in the kernel
configuration, at build time, or with new kernel option bpf_preload_list=,
at run-time.
By default, set CONFIG_BPF_PRELOAD_LIST to 'bpf_preload', so that the
current preloading behavior is kept unchanged.
Signed-off-by: Roberto Sassu <roberto.sassu@...wei.com>
---
.../admin-guide/kernel-parameters.txt | 8 ++++++
kernel/bpf/inode.c | 16 ++++++++++--
kernel/bpf/preload/Kconfig | 25 +++++++++++++------
kernel/bpf/preload/bpf_preload_kern.c | 20 ++-------------
.../bpf/preload/iterators/iterators.lskel.h | 9 +++++--
tools/bpf/bpftool/gen.c | 15 ++++++++---
6 files changed, 60 insertions(+), 33 deletions(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 9927564db88e..732d83764e6e 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -482,6 +482,14 @@
bgrt_disable [ACPI][X86]
Disable BGRT to avoid flickering OEM logo.
+ bpf_preload_list= [BPF]
+ Specify a list of eBPF programs to preload.
+ Format: obj_name1,obj_name2,...
+ Default: bpf_preload
+
+ Specify the list of eBPF programs to preload when the
+ bpf filesystem is mounted.
+
bttv.card= [HW,V4L] bttv (bt848 + bt878 based grabber cards)
bttv.radio= Most important insmod options are available as
kernel args too.
diff --git a/kernel/bpf/inode.c b/kernel/bpf/inode.c
index 619cdef0ba54..c1941c65ce95 100644
--- a/kernel/bpf/inode.c
+++ b/kernel/bpf/inode.c
@@ -22,7 +22,14 @@
#include <linux/bpf_trace.h>
#include <linux/bpf_preload.h>
-static char *bpf_preload_list_str;
+static char *bpf_preload_list_str = CONFIG_BPF_PRELOAD_LIST;
+
+static int __init bpf_preload_list_setup(char *str)
+{
+ bpf_preload_list_str = str;
+ return 1;
+}
+__setup("bpf_preload_list=", bpf_preload_list_setup);
static void *bpf_any_get(void *raw, enum bpf_type type)
{
@@ -732,7 +739,12 @@ static bool bpf_preload_list_mod_get(void)
struct bpf_preload_ops_item *cur;
bool ret = false;
- ret |= bpf_preload_mod_get("bpf_preload", &bpf_preload_ops);
+ /*
+ * Keep the legacy registration method, but do not attempt to load
+ * bpf_preload.ko, as it switched to the new registration method.
+ */
+ if (bpf_preload_ops)
+ ret |= bpf_preload_mod_get("bpf_preload", &bpf_preload_ops);
list_for_each_entry(cur, &preload_list, list)
ret |= bpf_preload_mod_get(cur->obj_name, &cur->ops);
diff --git a/kernel/bpf/preload/Kconfig b/kernel/bpf/preload/Kconfig
index c9d45c9d6918..f878e537b0ff 100644
--- a/kernel/bpf/preload/Kconfig
+++ b/kernel/bpf/preload/Kconfig
@@ -4,7 +4,7 @@ config USERMODE_DRIVER
default n
menuconfig BPF_PRELOAD
- bool "Preload BPF file system with kernel specific program and map iterators"
+ bool "Preload eBPF programs"
depends on BPF
depends on BPF_SYSCALL
# The dependency on !COMPILE_TEST prevents it from being enabled
@@ -12,15 +12,26 @@ menuconfig BPF_PRELOAD
depends on !COMPILE_TEST
select USERMODE_DRIVER
help
- This builds kernel module with several embedded BPF programs that are
- pinned into BPF FS mount point as human readable files that are
- useful in debugging and introspection of BPF programs and maps.
+ This enables preloading eBPF programs chosen from the kernel
+ configuration or from the kernel option bpf_preload_list=.
if BPF_PRELOAD
config BPF_PRELOAD_UMD
- tristate "bpf_preload kernel module"
+ tristate "Preload BPF file system with kernel specific program and map iterators"
default m
help
- This builds bpf_preload kernel module with embedded BPF programs for
- introspection in bpffs.
+ This builds bpf_preload kernel module with several embedded BPF
+ programs that are pinned into BPF FS mount point as human readable
+ files that are useful in debugging and introspection of BPF programs
+ and maps.
+
+config BPF_PRELOAD_LIST
+ string "Ordered list of eBPF programs to preload"
+ default "bpf_preload"
+ help
+ A comma-separated list of eBPF programs to preload. Any eBPF program
+ left off this list will be ignored. This can be controlled at boot
+ with the "bpf_preload_list=" parameter.
+
+ If unsure, leave this as the default.
endif
diff --git a/kernel/bpf/preload/bpf_preload_kern.c b/kernel/bpf/preload/bpf_preload_kern.c
index 3839af367200..c6d97872225b 100644
--- a/kernel/bpf/preload/bpf_preload_kern.c
+++ b/kernel/bpf/preload/bpf_preload_kern.c
@@ -5,22 +5,6 @@
#include <linux/bpf_preload.h>
#include "iterators/iterators.lskel.h"
-static int __init load(void)
-{
- int err;
-
- err = load_skel();
- if (err)
- return err;
- bpf_preload_ops = &ops;
- return err;
-}
-
-static void __exit fini(void)
-{
- bpf_preload_ops = NULL;
- free_objs_and_skel();
-}
-late_initcall(load);
-module_exit(fini);
+late_initcall(load_skel);
+module_exit(free_objs_and_skel);
MODULE_LICENSE("GPL");
diff --git a/kernel/bpf/preload/iterators/iterators.lskel.h b/kernel/bpf/preload/iterators/iterators.lskel.h
index 7595fc283a65..5e999564cc7a 100644
--- a/kernel/bpf/preload/iterators/iterators.lskel.h
+++ b/kernel/bpf/preload/iterators/iterators.lskel.h
@@ -440,6 +440,8 @@ static struct iterators_bpf *skel;
static void free_objs_and_skel(void)
{
+ bpf_preload_set_ops("bpf_preload", THIS_MODULE, NULL);
+
if (!IS_ERR_OR_NULL(dump_bpf_map_link))
bpf_link_put(dump_bpf_map_link);
if (!IS_ERR_OR_NULL(dump_bpf_prog_link))
@@ -481,11 +483,14 @@ static struct bpf_preload_ops ops = {
static int load_skel(void)
{
- int err;
+ int err = -ENOMEM;
+
+ if (!bpf_preload_set_ops("bpf_preload", THIS_MODULE, &ops))
+ return 0;
skel = iterators_bpf__open();
if (!skel)
- return -ENOMEM;
+ goto out;
err = iterators_bpf__load(skel);
if (err)
diff --git a/tools/bpf/bpftool/gen.c b/tools/bpf/bpftool/gen.c
index 5593cbee1846..af939183f57a 100644
--- a/tools/bpf/bpftool/gen.c
+++ b/tools/bpf/bpftool/gen.c
@@ -700,7 +700,10 @@ static void codegen_preload_free(struct bpf_object *obj, const char *obj_name)
\n\
static void free_objs_and_skel(void) \n\
{ \n\
- ");
+ bpf_preload_set_ops(\"%s\", THIS_MODULE, NULL); \n\
+ \n\
+ ", !strcmp(obj_name, "iterators_bpf") ?
+ "bpf_preload" : obj_name);
bpf_object__for_each_program(prog, obj) {
codegen("\
@@ -864,11 +867,14 @@ static void codegen_preload_load(struct bpf_object *obj, const char *obj_name)
\n\
static int load_skel(void) \n\
{ \n\
- int err; \n\
+ int err = -ENOMEM; \n\
+ \n\
+ if (!bpf_preload_set_ops(\"%2$s\", THIS_MODULE, &ops)) \n\
+ return 0; \n\
\n\
skel = %1$s__open(); \n\
if (!skel) \n\
- return -ENOMEM; \n\
+ goto out; \n\
\n\
err = %1$s__load(skel); \n\
if (err) \n\
@@ -877,7 +883,8 @@ static void codegen_preload_load(struct bpf_object *obj, const char *obj_name)
err = %1$s__attach(skel); \n\
if (err) \n\
goto out; \n\
- ", obj_name);
+ ", obj_name, !strcmp(obj_name, "iterators_bpf") ?
+ "bpf_preload" : obj_name);
bpf_object__for_each_program(prog, obj) {
codegen("\
--
2.32.0
Powered by blists - more mailing lists