Skip to content

Commit f7d522b

Browse files
Pingfan LiuKernel Patches Daemon
authored andcommitted
kexec: Introduce a bpf-prog lskel to parse PE file
Analague to kernel/bpf/preload/iterators/Makefile, this Makefile is not invoked by the Kbuild system. It needs to be invoked manually when kexec_pe_parser_bpf.c is changed so that kexec_pe_parser_bpf.lskel.h can be re-generated by the command "bpftool gen skeleton -L kexec_pe_parser_bpf.o". kexec_pe_parser_bpf.lskel.h is used directly by the kernel kexec code in later patch. For this patch, there are bpf bytecode contained in opts_data[] and opts_insn[] in kexec_pe_parser_bpf.lskel.h, but in the following patch, they will be removed and only the function API in kexec_pe_parser_bpf.lskel.h left. As exposed in kexec_pe_parser_bpf.lskel.h, the interface between bpf-prog and the kernel are constituted by: four maps: struct bpf_map_desc ringbuf_1; struct bpf_map_desc ringbuf_2; struct bpf_map_desc ringbuf_3; struct bpf_map_desc ringbuf_4; four sections: struct bpf_map_desc rodata; struct bpf_map_desc data; struct bpf_map_desc bss; struct bpf_map_desc rodata_str1_1; two progs: SEC("fentry.s/bpf_handle_pefile") SEC("fentry.s/bpf_post_handle_pefile") They are fixed and provided for all kinds of bpf-prog which interacts with the kexec kernel component. Signed-off-by: Pingfan Liu <[email protected]> Cc: Alexei Starovoitov <[email protected]> Cc: Baoquan He <[email protected]> Cc: Dave Young <[email protected]> Cc: Andrew Morton <[email protected]> Cc: Philipp Rudo <[email protected]> Cc: [email protected] To: [email protected]
1 parent 8b250a1 commit f7d522b

File tree

3 files changed

+561
-0
lines changed

3 files changed

+561
-0
lines changed

kernel/kexec_bpf/Makefile

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# SPDX-License-Identifier: GPL-2.0
2+
OUTPUT := .output
3+
CLANG ?= clang
4+
LLC ?= llc
5+
LLVM_STRIP ?= llvm-strip
6+
DEFAULT_BPFTOOL := $(OUTPUT)/sbin/bpftool
7+
BPFTOOL ?= $(DEFAULT_BPFTOOL)
8+
LIBBPF_SRC := $(abspath ../../tools/lib/bpf)
9+
BPFOBJ := $(OUTPUT)/libbpf.a
10+
BPF_INCLUDE := $(OUTPUT)
11+
INCLUDES := -I$(OUTPUT) -I$(BPF_INCLUDE) -I$(abspath ../../tools/lib) \
12+
-I$(abspath ../../tools/include/uapi)
13+
CFLAGS := -g -Wall
14+
15+
srctree := $(patsubst %/kernel/kexec_bpf,%,$(CURDIR))
16+
VMLINUX = $(srctree)/vmlinux
17+
18+
abs_out := $(abspath $(OUTPUT))
19+
ifeq ($(V),1)
20+
Q =
21+
msg =
22+
else
23+
Q = @
24+
msg = @printf ' %-8s %s%s\n' "$(1)" "$(notdir $(2))" "$(if $(3), $(3))";
25+
MAKEFLAGS += --no-print-directory
26+
submake_extras := feature_display=0
27+
endif
28+
29+
.DELETE_ON_ERROR:
30+
31+
.PHONY: all clean
32+
33+
all: kexec_pe_parser_bpf.lskel.h
34+
35+
clean:
36+
$(call msg,CLEAN)
37+
$(Q)rm -rf $(OUTPUT) kexec_pe_parser_bpf.lskel.h
38+
39+
kexec_pe_parser_bpf.lskel.h: $(OUTPUT)/kexec_pe_parser_bpf.o | $(BPFTOOL)
40+
$(call msg,GEN-SKEL,$@)
41+
$(Q)$(BPFTOOL) gen skeleton -L $< > $@
42+
43+
$(OUTPUT)/vmlinux.h: $(VMLINUX) $(BPFOBJ) | $(OUTPUT)
44+
@$(BPFTOOL) btf dump file $(VMLINUX) format c > $(OUTPUT)/vmlinux.h
45+
46+
47+
$(OUTPUT)/kexec_pe_parser_bpf.o: kexec_pe_parser_bpf.c $(BPFOBJ) | $(OUTPUT)
48+
$(call msg,BPF,$@)
49+
$(Q)$(CLANG) -g -O2 -target bpf $(INCLUDES) \
50+
-c $(filter %.c,$^) -o $@ && \
51+
$(LLVM_STRIP) -g $@
52+
53+
$(OUTPUT):
54+
$(call msg,MKDIR,$@)
55+
$(Q)mkdir -p $(OUTPUT)
56+
57+
$(BPFOBJ): $(wildcard $(LIBBPF_SRC)/*.[ch] $(LIBBPF_SRC)/Makefile) | $(OUTPUT)
58+
$(Q)$(MAKE) $(submake_extras) -C $(LIBBPF_SRC) \
59+
OUTPUT=$(abspath $(dir $@))/ $(abspath $@)
60+
61+
$(DEFAULT_BPFTOOL):
62+
$(Q)$(MAKE) $(submake_extras) -C ../../tools/bpf/bpftool \
63+
prefix= OUTPUT=$(abs_out)/ DESTDIR=$(abs_out) install
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
#include "vmlinux.h"
3+
#include <bpf/bpf_helpers.h>
4+
#include <bpf/bpf_core_read.h>
5+
#include <bpf/bpf_endian.h>
6+
#include <bpf/bpf_tracing.h>
7+
8+
/*
9+
* The ringbufs can have different capacity. But only four ringbuf are provided.
10+
*/
11+
#define RINGBUF1_SIZE 4
12+
#define RINGBUF2_SIZE 4
13+
#define RINGBUF3_SIZE 4
14+
#define RINGBUF4_SIZE 4
15+
16+
#define KEXEC_RES_KERNEL_NAME "kexec:kernel"
17+
#define KEXEC_RES_INITRD_NAME "kexec:initrd"
18+
#define KEXEC_RES_CMDLINE_NAME "kexec:cmdline"
19+
20+
/* ringbuf is safe since the user space has no write access to them */
21+
struct {
22+
__uint(type, BPF_MAP_TYPE_RINGBUF);
23+
__uint(max_entries, RINGBUF1_SIZE);
24+
} ringbuf_1 SEC(".maps");
25+
26+
struct {
27+
__uint(type, BPF_MAP_TYPE_RINGBUF);
28+
__uint(max_entries, RINGBUF2_SIZE);
29+
} ringbuf_2 SEC(".maps");
30+
31+
struct {
32+
__uint(type, BPF_MAP_TYPE_RINGBUF);
33+
__uint(max_entries, RINGBUF3_SIZE);
34+
} ringbuf_3 SEC(".maps");
35+
36+
struct {
37+
__uint(type, BPF_MAP_TYPE_RINGBUF);
38+
__uint(max_entries, RINGBUF4_SIZE);
39+
} ringbuf_4 SEC(".maps");
40+
41+
char LICENSE[] SEC("license") = "GPL";
42+
43+
/*
44+
* This function ensures that the sections .rodata, .data .bss and .rodata.str1.1
45+
* are created for a bpf prog.
46+
*/
47+
__attribute__((used)) static int dummy(void)
48+
{
49+
static const char res_kernel[16] __attribute__((used, section(".rodata"))) = KEXEC_RES_KERNEL_NAME;
50+
static char local_name[16] __attribute__((used, section(".data"))) = KEXEC_RES_CMDLINE_NAME;
51+
static char res_cmdline[16] __attribute__((used, section(".bss")));
52+
53+
__builtin_memcpy(local_name, KEXEC_RES_INITRD_NAME, 16);
54+
return __builtin_memcmp(local_name, res_kernel, 4);
55+
}
56+
57+
SEC("fentry.s/bpf_handle_pefile")
58+
__attribute__((used)) int BPF_PROG(parse_pe, struct kexec_context *context)
59+
{
60+
return 0;
61+
}
62+
63+
SEC("fentry.s/bpf_post_handle_pefile")
64+
__attribute__((used)) int BPF_PROG(post_parse_pe, struct kexec_context *context)
65+
{
66+
return 0;
67+
}

0 commit comments

Comments
 (0)