bpf-headers: add a package with kernel headers for ebpf
authorFelix Fietkau <nbd@nbd.name>
Tue, 26 Oct 2021 18:41:22 +0000 (20:41 +0200)
committerFelix Fietkau <nbd@nbd.name>
Mon, 1 Nov 2021 15:39:09 +0000 (16:39 +0100)
In order to genererate suitable kernel headers, a 5.10 kernel tree is
prepared with a default config for mips. The arch is forced to mips in
order to avoid issues with inline asm on various architectures in a way
that doesn't involve relying on the host toolchain/headers.
It also has the advantage of supporting both endian types

Signed-off-by: Felix Fietkau <nbd@nbd.name>
include/bpf.mk [new file with mode: 0644]
package/kernel/bpf-headers/Makefile [new file with mode: 0644]
package/kernel/bpf-headers/src/include/generated/bounds.h [new file with mode: 0644]

diff --git a/include/bpf.mk b/include/bpf.mk
new file mode 100644 (file)
index 0000000..3dc65c7
--- /dev/null
@@ -0,0 +1,65 @@
+ifneq ($(CONFIG_BPF_TOOLCHAIN_HOST),)
+  BPF_TOOLCHAIN_HOST_PATH:=$(call qstrip,$(CONFIG_BPF_TOOLCHAIN_HOST_PATH))
+  ifneq ($(BPF_TOOLCHAIN_HOST_PATH),)
+    BPF_PATH:=$(BPF_TOOLCHAIN_HOST_PATH)/bin:$(PATH)
+  else
+    BPF_PATH:=$(BPF_PATH)
+  endif
+  CLANG:=$(firstword $(shell PATH='$(BPF_PATH)' which clang clang-13 clang-12 clang-11))
+  LLVM_VER:=$(subst clang,,$(notdir $(CLANG)))
+else
+  CLANG:=$(STAGING_DIR_HOST)/bin/clang
+  LLVM_VER:=
+endif
+
+LLVM_PATH:=$(dir $(CLANG))
+LLVM_LLC:=$(LLVM_PATH)/llc$(LLVM_VER)
+LLVM_DIS:=$(LLVM_PATH)/llvm-dis$(LLVM_VER)
+LLVM_OPT:=$(LLVM_PATH)/opt$(LLVM_VER)
+LLVM_STRIP:=$(LLVM_PATH)/llvm-strip$(LLVM_VER)
+
+BPF_KARCH:=mips
+BPF_ARCH:=mips$(if $(CONFIG_BIG_ENDIAN),,el)
+
+BPF_HEADERS_DIR:=$(STAGING_DIR)/bpf-headers
+
+BPF_KERNEL_INCLUDE := \
+       -nostdinc -isystem $(TOOLCHAIN_DIR)/include \
+       -I$(BPF_HEADERS_DIR)/arch/$(BPF_KARCH)/include \
+       -I$(BPF_HEADERS_DIR)/arch/$(BPF_KARCH)/include/asm/mach-generic \
+       -I$(BPF_HEADERS_DIR)/arch/$(BPF_KARCH)/include/generated \
+       -I$(BPF_HEADERS_DIR)/include \
+       -I$(BPF_HEADERS_DIR)/arch/$(BPF_KARCH)/include/uapi \
+       -I$(BPF_HEADERS_DIR)/arch/$(BPF_KARCH)/include/generated/uapi \
+       -I$(BPF_HEADERS_DIR)/include/uapi \
+       -I$(BPF_HEADERS_DIR)/include/generated/uapi \
+       -I$(BPF_HEADERS_DIR)/tools/lib \
+       -I$(BPF_HEADERS_DIR)/tools/testing/selftests \
+       -I$(BPF_HEADERS_DIR)/samples/bpf \
+       -include linux/kconfig.h -include asm_goto_workaround.h
+
+BPF_CFLAGS := \
+       $(BPF_KERNEL_INCLUDE) -I$(PKG_BUILD_DIR) \
+       -D__KERNEL__ -D__BPF_TRACING__ \
+       -D__TARGET_ARCH_${BPF_KARCH} \
+       -m$(if $(CONFIG_BIG_ENDIAN),big,little)-endian \
+       -fno-stack-protector -Wall \
+       -Wno-unused-value -Wno-pointer-sign \
+       -Wno-compare-distinct-pointer-types \
+       -Wno-gnu-variable-sized-type-not-at-end \
+       -Wno-address-of-packed-member -Wno-tautological-compare \
+       -Wno-unknown-warning-option \
+       -fno-asynchronous-unwind-tables \
+       -Wno-uninitialized -Wno-unused-variable \
+       -Wno-unused-label \
+       -O2 -emit-llvm -Xclang -disable-llvm-passes
+
+define CompileBPF
+       $(CLANG) -g -target $(BPF_ARCH)-linux-gnu $(BPF_CFLAGS) $(2) \
+               -c $(1) -o $(patsubst %.c,%.bc,$(1))
+       $(LLVM_OPT) -O2 -mtriple=bpf-pc-linux < $(patsubst %.c,%.bc,$(1)) > $(patsubst %.c,%.opt,$(1))
+       $(LLVM_DIS) < $(patsubst %.c,%.opt,$(1)) > $(patsubst %.c,%.S,$(1))
+       $(LLVM_LLC) -march=bpf -filetype=obj -o $(patsubst %.c,%.o,$(1)) < $(patsubst %.c,%.S,$(1))
+       $(LLVM_STRIP) --strip-debug $(patsubst %.c,%.o,$(1))
+endef
+
diff --git a/package/kernel/bpf-headers/Makefile b/package/kernel/bpf-headers/Makefile
new file mode 100644 (file)
index 0000000..5f5b893
--- /dev/null
@@ -0,0 +1,99 @@
+#
+# Copyright (C) 2006-2009 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+
+override QUILT:=
+override HOST_QUILT:=
+
+include $(INCLUDE_DIR)/kernel.mk
+
+
+PKG_NAME:=linux
+PKG_PATCHVER:=5.10
+PKG_VERSION:=$(PKG_PATCHVER)$(strip $(LINUX_VERSION-$(PKG_PATCHVER)))
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=$(LINUX_SITE)
+PKG_HASH:=$(LINUX_KERNEL_HASH-$(strip $(PKG_VERSION)))
+PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/bpf-headers/$(PKG_NAME)-$(PKG_VERSION)
+
+GENERIC_BACKPORT_DIR := $(GENERIC_PLATFORM_DIR)/backport$(if $(wildcard $(GENERIC_PLATFORM_DIR)/backport-$(PKG_PATCHVER)),-$(PKG_PATCHVER))
+GENERIC_PATCH_DIR := $(GENERIC_PLATFORM_DIR)/pending$(if $(wildcard $(GENERIC_PLATFORM_DIR)/pending-$(PKG_PATCHVER)),-$(PKG_PATCHVER))
+GENERIC_HACK_DIR := $(GENERIC_PLATFORM_DIR)/hack$(if $(wildcard $(GENERIC_PLATFORM_DIR)/hack-$(PKG_PATCHVER)),-$(PKG_PATCHVER))
+GENERIC_FILES_DIR := $(foreach dir,$(wildcard $(GENERIC_PLATFORM_DIR)/files $(GENERIC_PLATFORM_DIR)/files-$(PKG_PATCHVER)),"$(dir)")
+PATCH_DIR := $(CURDIR)/patches
+FILES_DIR :=
+
+REAL_LINUX_DIR := $(LINUX_DIR)
+LINUX_DIR := $(PKG_BUILD_DIR)
+
+include $(INCLUDE_DIR)/bpf.mk
+include $(INCLUDE_DIR)/package.mk
+
+define Package/bpf-headers
+  SECTION:=kernel
+  CATEGORY:=Kernel
+  TITLE:=eBPF kernel headers
+  BUILDONLY:=1
+  HIDDEN:=1
+endef
+
+export HOST_EXTRACFLAGS=-I$(STAGING_DIR_HOST)/include
+
+KERNEL_MAKE := \
+       $(MAKE) -C $(PKG_BUILD_DIR) \
+               ARCH=$(BPF_KARCH) \
+               CROSS_COMPILE=$(BPF_ARCH)-linux- \
+               LLVM=1 CC="$(CLANG)" LD="$(TARGET_CROSS)ld" \
+               HOSTCC="$(HOSTCC)" \
+               HOSTCXX="$(HOSTCXX)" \
+               HOST_LOADLIBES="-L$(STAGING_DIR_HOST)/lib" \
+               KBUILD_HOSTLDLIBS="-L$(STAGING_DIR_HOST)/lib" \
+               CONFIG_SHELL="$(BASH)" \
+               INSTALL_HDR_PATH="$(PKG_BUILD_DIR)/user_headers"
+
+define Build/Patch
+       $(Kernel/Patch/Default)
+endef
+
+BPF_DOC = $(PKG_BUILD_DIR)/scripts/bpf_helpers_doc.py
+
+define Build/Configure
+       grep -vE 'CONFIG_(CPU_.*ENDIAN|HZ)' $(PKG_BUILD_DIR)/arch/mips/configs/generic_defconfig > $(PKG_BUILD_DIR)/.config
+       echo 'CONFIG_CPU_$(if $(CONFIG_BIG_ENDIAN),BIG,LITTLE)_ENDIAN=y' >> $(PKG_BUILD_DIR)/.config
+       grep CONFIG_HZ $(REAL_LINUX_DIR)/.config >> $(PKG_BUILD_DIR)/.config
+       yes '' | $(KERNEL_MAKE) oldconfig
+       grep 'CONFIG_HZ=' $(REAL_LINUX_DIR)/.config | \
+               cut -d= -f2 | \
+               bc -q $(LINUX_DIR)/kernel/time/timeconst.bc \
+               > $(LINUX_DIR)/include/generated/timeconst.h
+       $(BPF_DOC) --header \
+               --file $(LINUX_DIR)/tools/include/uapi/linux/bpf.h \
+               > $(PKG_BUILD_DIR)/tools/lib/bpf/bpf_helper_defs.h
+endef
+
+define Build/Compile
+       $(KERNEL_MAKE) archprepare headers_install
+endef
+
+define Build/InstallDev
+       mkdir -p $(1)/bpf-headers/arch $(1)/bpf-headers/tools
+       $(CP) \
+               $(PKG_BUILD_DIR)/arch/$(BPF_KARCH) \
+               $(1)/bpf-headers/arch/
+       $(CP) \
+               $(PKG_BUILD_DIR)/tools/lib \
+               $(PKG_BUILD_DIR)/tools/testing \
+               $(1)/bpf-headers/tools/
+       $(CP) \
+               $(PKG_BUILD_DIR)/include \
+               $(PKG_BUILD_DIR)/samples \
+               $(PKG_BUILD_DIR)/scripts \
+               $(PKG_BUILD_DIR)/user_headers \
+               $(1)/bpf-headers
+endef
+
+$(eval $(call BuildPackage,bpf-headers))
diff --git a/package/kernel/bpf-headers/src/include/generated/bounds.h b/package/kernel/bpf-headers/src/include/generated/bounds.h
new file mode 100644 (file)
index 0000000..82ff010
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef __LINUX_BOUNDS_H__
+#define __LINUX_BOUNDS_H__
+/*
+ * DO NOT MODIFY.
+ *
+ * This file was generated by Kbuild
+ */
+
+#define NR_PAGEFLAGS 23 /* __NR_PAGEFLAGS */
+#define MAX_NR_ZONES 4 /* __MAX_NR_ZONES */
+#define NR_CPUS_BITS 1 /* ilog2(CONFIG_NR_CPUS) */
+#define SPINLOCK_SIZE 64 /* sizeof(spinlock_t) */
+
+#endif