From: Quentin Monnet <quentin@isovalent.com>
To: Benjamin Tissoires <benjamin.tissoires@redhat.com>,
Greg KH <gregkh@linuxfoundation.org>,
Jiri Kosina <jikos@kernel.org>,
Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Andrii Nakryiko <andrii@kernel.org>,
Martin KaFai Lau <kafai@fb.com>, Song Liu <songliubraving@fb.com>,
Yonghong Song <yhs@fb.com>,
John Fastabend <john.fastabend@gmail.com>,
KP Singh <kpsingh@kernel.org>, Shuah Khan <shuah@kernel.org>,
Dave Marchevsky <davemarchevsky@fb.com>,
Joe Stringer <joe@cilium.io>, Jonathan Corbet <corbet@lwn.net>
Cc: Tero Kristo <tero.kristo@linux.intel.com>,
linux-kernel@vger.kernel.org, linux-input@vger.kernel.org,
netdev@vger.kernel.org, bpf@vger.kernel.org,
linux-kselftest@vger.kernel.org, linux-doc@vger.kernel.org,
Pu Lehui <pulehui@huawei.com>
Subject: Re: [PATCH bpf-next v6 12/23] HID: initial BPF implementation
Date: Wed, 13 Jul 2022 09:48:43 +0100 [thread overview]
Message-ID: <668a2f86-9446-61de-494c-f2d2ee15f09e@isovalent.com> (raw)
In-Reply-To: <20220712145850.599666-13-benjamin.tissoires@redhat.com>
On 12/07/2022 15:58, Benjamin Tissoires wrote:
> Declare an entry point that can use fmod_ret BPF programs, and
> also an API to access and change the incoming data.
>
> A simpler implementation would consist in just calling
> hid_bpf_device_event() for any incoming event and let users deal
> with the fact that they will be called for any event of any device.
>
> The goal of HID-BPF is to partially replace drivers, so this situation
> can be problematic because we might have programs which will step on
> each other toes.
>
> For that, we add a new API hid_bpf_attach_prog() that can be called
> from a syscall and we manually deal with a jump table in hid-bpf.
>
> Whenever we add a program to the jump table (in other words, when we
> attach a program to a HID device), we keep the number of time we added
> this program in the jump table so we can release it whenever there are
> no other users.
>
> HID devices have an RCU protected list of available programs in the
> jump table, and those programs are called one after the other thanks
> to bpf_tail_call().
>
> To achieve the detection of users losing their fds on the programs we
> attached, we add 2 tracing facilities on bpf_prog_release() (for when
> a fd is closed) and bpf_free_inode() (for when a pinned program gets
> unpinned).
>
> Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
>
> ---
>
> changes in v6:
> - use BTF_ID to get the btf_id of hid_bpf_device_event instead of
> loading/unloading a dummy eBPF program.
>
> changes in v5:
> - all the HID bpf operations are in their dedicated module
> - a bpf program is preloaded on startup so we can call subsequent
> calls with bpf_tail_call
> - make hid_bpf_ctx more compact
> - add a dedicated hid_bpf_attach_prog() API
> - store the list of progs in each hdev
> - monitor the calls to bpf_prog_release to automatically release
> attached progs when there are no other users
> - add kernel docs directly when functions are defined
>
> new-ish in v4:
> - far from complete, but gives an overview of what we can do now.
>
> fix initial HID-bpf
> ---
> drivers/hid/Kconfig | 2 +
> drivers/hid/Makefile | 2 +
> drivers/hid/bpf/Kconfig | 19 +
> drivers/hid/bpf/Makefile | 11 +
> drivers/hid/bpf/entrypoints/Makefile | 88 +++
> drivers/hid/bpf/entrypoints/README | 4 +
> drivers/hid/bpf/entrypoints/entrypoints.bpf.c | 66 ++
> .../hid/bpf/entrypoints/entrypoints.lskel.h | 682 ++++++++++++++++++
> drivers/hid/bpf/hid_bpf_dispatch.c | 235 ++++++
> drivers/hid/bpf/hid_bpf_dispatch.h | 27 +
> drivers/hid/bpf/hid_bpf_jmp_table.c | 568 +++++++++++++++
> drivers/hid/hid-core.c | 15 +
> include/linux/hid.h | 5 +
> include/linux/hid_bpf.h | 99 +++
> include/uapi/linux/hid_bpf.h | 25 +
> tools/include/uapi/linux/hid.h | 62 ++
> tools/include/uapi/linux/hid_bpf.h | 25 +
> 17 files changed, 1935 insertions(+)
> create mode 100644 drivers/hid/bpf/Kconfig
> create mode 100644 drivers/hid/bpf/Makefile
> create mode 100644 drivers/hid/bpf/entrypoints/Makefile
> create mode 100644 drivers/hid/bpf/entrypoints/README
> create mode 100644 drivers/hid/bpf/entrypoints/entrypoints.bpf.c
> create mode 100644 drivers/hid/bpf/entrypoints/entrypoints.lskel.h
> create mode 100644 drivers/hid/bpf/hid_bpf_dispatch.c
> create mode 100644 drivers/hid/bpf/hid_bpf_dispatch.h
> create mode 100644 drivers/hid/bpf/hid_bpf_jmp_table.c
> create mode 100644 include/linux/hid_bpf.h
> create mode 100644 include/uapi/linux/hid_bpf.h
> create mode 100644 tools/include/uapi/linux/hid.h
> create mode 100644 tools/include/uapi/linux/hid_bpf.h
>
> diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
> index 70da5931082f..4bedced90545 100644
> --- a/drivers/hid/Kconfig
> +++ b/drivers/hid/Kconfig
> @@ -1310,6 +1310,8 @@ endmenu
>
> endif # HID
>
> +source "drivers/hid/bpf/Kconfig"
> +
> source "drivers/hid/usbhid/Kconfig"
>
> source "drivers/hid/i2c-hid/Kconfig"
> diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
> index cac2cbe26d11..94672a2d4fbb 100644
> --- a/drivers/hid/Makefile
> +++ b/drivers/hid/Makefile
> @@ -5,6 +5,8 @@
> hid-y := hid-core.o hid-input.o hid-quirks.o
> hid-$(CONFIG_DEBUG_FS) += hid-debug.o
>
> +obj-$(CONFIG_HID_BPF) += bpf/
> +
> obj-$(CONFIG_HID) += hid.o
> obj-$(CONFIG_UHID) += uhid.o
>
> diff --git a/drivers/hid/bpf/Kconfig b/drivers/hid/bpf/Kconfig
> new file mode 100644
> index 000000000000..c54a2f07b8d7
> --- /dev/null
> +++ b/drivers/hid/bpf/Kconfig
> @@ -0,0 +1,19 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +menu "HID-BPF support"
> + #depends on x86_64
> +
> +config HID_BPF
> + bool "HID-BPF support"
> + default y
> + depends on BPF && BPF_SYSCALL
> + select HID
> + help
> + This option allows to support eBPF programs on the HID subsystem.
> + eBPF programs can fix HID devices in a lighter way than a full
> + kernel patch and allow a lot more flexibility.
> +
> + For documentation, see Documentation/hid/hid-bpf.rst
> +
> + If unsure, say Y.
> +
> +endmenu
> diff --git a/drivers/hid/bpf/Makefile b/drivers/hid/bpf/Makefile
> new file mode 100644
> index 000000000000..cf55120cf7d6
> --- /dev/null
> +++ b/drivers/hid/bpf/Makefile
> @@ -0,0 +1,11 @@
> +# SPDX-License-Identifier: GPL-2.0
> +#
> +# Makefile for HID-BPF
> +#
> +
> +LIBBPF_INCLUDE = $(srctree)/tools/lib
> +
> +obj-$(CONFIG_HID_BPF) += hid_bpf.o
> +CFLAGS_hid_bpf_dispatch.o += -I$(LIBBPF_INCLUDE)
> +CFLAGS_hid_bpf_jmp_table.o += -I$(LIBBPF_INCLUDE)
> +hid_bpf-objs += hid_bpf_dispatch.o hid_bpf_jmp_table.o
> diff --git a/drivers/hid/bpf/entrypoints/Makefile b/drivers/hid/bpf/entrypoints/Makefile
> new file mode 100644
> index 000000000000..dd60a460c6c4
> --- /dev/null
> +++ b/drivers/hid/bpf/entrypoints/Makefile
> @@ -0,0 +1,88 @@
> +# SPDX-License-Identifier: GPL-2.0
> +OUTPUT := .output
> +abs_out := $(abspath $(OUTPUT))
> +
> +CLANG ?= clang
> +LLC ?= llc
> +LLVM_STRIP ?= llvm-strip
> +
> +TOOLS_PATH := $(abspath ../../../../tools)
> +BPFTOOL_SRC := $(TOOLS_PATH)/bpf/bpftool
> +BPFTOOL_OUTPUT := $(abs_out)/bpftool
> +DEFAULT_BPFTOOL := $(OUTPUT)/sbin/bpftool
> +BPFTOOL ?= $(DEFAULT_BPFTOOL)
> +
> +LIBBPF_SRC := $(TOOLS_PATH)/lib/bpf
> +LIBBPF_OUTPUT := $(abs_out)/libbpf
> +LIBBPF_DESTDIR := $(LIBBPF_OUTPUT)
> +LIBBPF_INCLUDE := $(LIBBPF_DESTDIR)/include
> +BPFOBJ := $(LIBBPF_OUTPUT)/libbpf.a
> +
> +INCLUDES := -I$(OUTPUT) -I$(LIBBPF_INCLUDE) -I$(TOOLS_PATH)/include/uapi
> +CFLAGS := -g -Wall
> +
> +VMLINUX_BTF_PATHS ?= $(if $(O),$(O)/vmlinux) \
> + $(if $(KBUILD_OUTPUT),$(KBUILD_OUTPUT)/vmlinux) \
> + ../../../../vmlinux \
> + /sys/kernel/btf/vmlinux \
> + /boot/vmlinux-$(shell uname -r)
> +VMLINUX_BTF ?= $(abspath $(firstword $(wildcard $(VMLINUX_BTF_PATHS))))
> +ifeq ($(VMLINUX_BTF),)
> +$(error Cannot find a vmlinux for VMLINUX_BTF at any of "$(VMLINUX_BTF_PATHS)")
> +endif
> +
> +ifeq ($(V),1)
> +Q =
> +msg =
> +else
> +Q = @
> +msg = @printf ' %-8s %s%s\n' "$(1)" "$(notdir $(2))" "$(if $(3), $(3))";
> +MAKEFLAGS += --no-print-directory
> +submake_extras := feature_display=0
> +endif
> +
> +.DELETE_ON_ERROR:
> +
> +.PHONY: all clean
> +
> +all: entrypoints.lskel.h
> +
> +clean:
> + $(call msg,CLEAN)
> + $(Q)rm -rf $(OUTPUT) entrypoints
> +
> +entrypoints.lskel.h: $(OUTPUT)/entrypoints.bpf.o | $(BPFTOOL)
> + $(call msg,GEN-SKEL,$@)
> + $(Q)$(BPFTOOL) gen skeleton -L $< > $@
> +
> +
> +$(OUTPUT)/entrypoints.bpf.o: entrypoints.bpf.c $(OUTPUT)/vmlinux.h $(BPFOBJ) | $(OUTPUT)
> + $(call msg,BPF,$@)
> + $(Q)$(CLANG) -g -O2 -target bpf $(INCLUDES) \
> + -c $(filter %.c,$^) -o $@ && \
> + $(LLVM_STRIP) -g $@
> +
> +$(OUTPUT)/vmlinux.h: $(VMLINUX_BTF) $(BPFTOOL) | $(INCLUDE_DIR)
> +ifeq ($(VMLINUX_H),)
> + $(call msg,GEN,,$@)
> + $(Q)$(BPFTOOL) btf dump file $(VMLINUX_BTF) format c > $@
> +else
> + $(call msg,CP,,$@)
> + $(Q)cp "$(VMLINUX_H)" $@
> +endif
> +
> +$(OUTPUT) $(LIBBPF_OUTPUT) $(BPFTOOL_OUTPUT):
> + $(call msg,MKDIR,$@)
> + $(Q)mkdir -p $@
> +
> +$(BPFOBJ): $(wildcard $(LIBBPF_SRC)/*.[ch] $(LIBBPF_SRC)/Makefile) | $(LIBBPF_OUTPUT)
> + $(Q)$(MAKE) $(submake_extras) -C $(LIBBPF_SRC) \
> + OUTPUT=$(abspath $(dir $@))/ prefix= \
> + DESTDIR=$(LIBBPF_DESTDIR) $(abspath $@) install_headers
> +
> +$(DEFAULT_BPFTOOL): $(BPFOBJ) | $(BPFTOOL_OUTPUT)
> + $(Q)$(MAKE) $(submake_extras) -C $(BPFTOOL_SRC) \
> + OUTPUT=$(BPFTOOL_OUTPUT)/ \
> + LIBBPF_OUTPUT=$(LIBBPF_OUTPUT)/ \
> + LIBBPF_DESTDIR=$(LIBBPF_DESTDIR)/ \
> + prefix= DESTDIR=$(abs_out)/ install-bin
Hi Benjamin,
Note that, at other locations where bpftool is needed to generate the
vmlinux.h or the skeletons, there is some work in progress to use only
the "bootstrap" version of bpftool (the intermediary bpftool binary used
to generate skeletons required for the final bpftool binary) [0]. This
is enough to generate these objects, it makes compiling the bpftool
binary faster, and solves some issues related to cross-compilation. It's
probably worth exploring in your case (or as a follow-up) as well.
Quentin
[0]
https://lore.kernel.org/all/20220712030813.865410-1-pulehui@huawei.com/t/#u
next prev parent reply other threads:[~2022-07-13 8:49 UTC|newest]
Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-07-12 14:58 [PATCH bpf-next v6 00/23] Introduce eBPF support for HID devices Benjamin Tissoires
2022-07-12 14:58 ` [PATCH bpf-next v6 01/23] selftests/bpf: fix config for CLS_BPF Benjamin Tissoires
2022-07-15 23:55 ` Yonghong Song
2022-07-12 14:58 ` [PATCH bpf-next v6 02/23] bpf/verifier: allow kfunc to read user provided context Benjamin Tissoires
2022-07-15 23:56 ` Yonghong Song
2022-07-16 19:47 ` Kumar Kartikeya Dwivedi
2022-07-18 13:53 ` Benjamin Tissoires
2022-07-12 14:58 ` [PATCH bpf-next v6 03/23] bpf/verifier: do not clear meta in check_mem_size Benjamin Tissoires
2022-07-16 0:03 ` Yonghong Song
2022-07-12 14:58 ` [PATCH bpf-next v6 04/23] selftests/bpf: add test for accessing ctx from syscall program type Benjamin Tissoires
2022-07-16 0:17 ` Yonghong Song
2022-07-12 14:58 ` [PATCH bpf-next v6 05/23] bpf/verifier: allow kfunc to return an allocated mem Benjamin Tissoires
2022-07-16 4:29 ` Yonghong Song
2022-07-18 14:36 ` Benjamin Tissoires
2022-07-19 16:05 ` Yonghong Song
2022-07-16 20:32 ` Kumar Kartikeya Dwivedi
2022-07-18 15:28 ` Benjamin Tissoires
2022-07-12 14:58 ` [PATCH bpf-next v6 06/23] selftests/bpf: Add tests for kfunc returning a memory pointer Benjamin Tissoires
2022-07-16 4:33 ` Yonghong Song
2022-07-18 8:42 ` Benjamin Tissoires
2022-07-12 14:58 ` [PATCH bpf-next v6 07/23] bpf: prepare for more bpf syscall to be used from kernel and user space Benjamin Tissoires
2022-07-16 4:37 ` Yonghong Song
2022-07-12 14:58 ` [PATCH bpf-next v6 08/23] libbpf: add map_get_fd_by_id and map_delete_elem in light skeleton Benjamin Tissoires
2022-07-16 4:41 ` Yonghong Song
2022-07-12 14:58 ` [PATCH bpf-next v6 09/23] HID: core: store the unique system identifier in hid_device Benjamin Tissoires
2022-07-15 5:00 ` Greg KH
2022-07-12 14:58 ` [PATCH bpf-next v6 10/23] HID: export hid_report_type to uapi Benjamin Tissoires
2022-07-15 5:00 ` Greg KH
2022-07-12 14:58 ` [PATCH bpf-next v6 11/23] HID: convert defines of HID class requests into a proper enum Benjamin Tissoires
2022-07-15 5:01 ` Greg KH
2022-07-12 14:58 ` [PATCH bpf-next v6 12/23] HID: initial BPF implementation Benjamin Tissoires
2022-07-13 8:48 ` Quentin Monnet [this message]
2022-07-13 11:36 ` Benjamin Tissoires
2022-07-15 5:02 ` Greg KH
2022-07-15 9:56 ` Benjamin Tissoires
2022-07-15 11:43 ` Greg KH
2022-07-12 14:58 ` [PATCH bpf-next v6 13/23] selftests/bpf: add tests for the HID-bpf initial implementation Benjamin Tissoires
2022-07-12 14:58 ` [PATCH bpf-next v6 14/23] HID: bpf: allocate data memory for device_event BPF programs Benjamin Tissoires
2022-07-12 14:58 ` [PATCH bpf-next v6 15/23] selftests/bpf/hid: add test to change the report size Benjamin Tissoires
2022-07-12 14:58 ` [PATCH bpf-next v6 16/23] HID: bpf: introduce hid_hw_request() Benjamin Tissoires
2022-07-12 14:58 ` [PATCH bpf-next v6 17/23] selftests/bpf: add tests for bpf_hid_hw_request Benjamin Tissoires
2022-07-12 14:58 ` [PATCH bpf-next v6 18/23] HID: bpf: allow to change the report descriptor Benjamin Tissoires
2022-07-12 14:58 ` [PATCH bpf-next v6 19/23] selftests/bpf: add report descriptor fixup tests Benjamin Tissoires
2022-07-12 14:58 ` [PATCH bpf-next v6 20/23] selftests/bpf: Add a test for BPF_F_INSERT_HEAD Benjamin Tissoires
2022-07-12 14:58 ` [PATCH bpf-next v6 21/23] samples/bpf: add new hid_mouse example Benjamin Tissoires
2022-07-13 12:06 ` Dominique Martinet
2022-07-13 12:32 ` Benjamin Tissoires
2022-07-12 14:58 ` [PATCH bpf-next v6 22/23] HID: bpf: add Surface Dial example Benjamin Tissoires
2022-07-12 14:58 ` [PATCH bpf-next v6 23/23] Documentation: add HID-BPF docs Benjamin Tissoires
2022-07-14 21:39 ` [PATCH bpf-next v6 00/23] Introduce eBPF support for HID devices Alexei Starovoitov
2022-07-15 17:34 ` Kumar Kartikeya Dwivedi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=668a2f86-9446-61de-494c-f2d2ee15f09e@isovalent.com \
--to=quentin@isovalent.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=benjamin.tissoires@redhat.com \
--cc=bpf@vger.kernel.org \
--cc=corbet@lwn.net \
--cc=daniel@iogearbox.net \
--cc=davemarchevsky@fb.com \
--cc=gregkh@linuxfoundation.org \
--cc=jikos@kernel.org \
--cc=joe@cilium.io \
--cc=john.fastabend@gmail.com \
--cc=kafai@fb.com \
--cc=kpsingh@kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-input@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pulehui@huawei.com \
--cc=shuah@kernel.org \
--cc=songliubraving@fb.com \
--cc=tero.kristo@linux.intel.com \
--cc=yhs@fb.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox