From nobody Wed Dec 17 05:48:13 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E56AF2575A; Wed, 8 May 2024 10:27:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715164024; cv=none; b=sq4bDhyL4R6uNuNkJgw/7Gip14GsjKBnxUa1dIlH/8JJ4a+3gscwHM310wkKMClmfSM/Me8N7orkrKMlMem6Na9kOE2nGU9sEeynSN/KOQpRxHayTGQOMfDvYaTbN6jNlUygx7jDABButL8YM9Qq9NPtoqlmefWqbbFI2hbeRCg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715164024; c=relaxed/simple; bh=a9LJVsfpkf9Px0ybdQKegPbSIpTN8PO6xfWRp8iYXlk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=szIr8OVJRt8y2/ty7t+r4+rN1Lh/5el36Q4OdkVc3yXhWJQd15fpmoxn45fGb4Q7khjVHXPvuTePoKFBCajHoXlPRkJDZLBnckzZcipChBWaO9C0HJley/0E89fAcF6DHSNvzxN/80gpETTvrtP4+UXd9GyAX3qTxgCfdbz6Ee4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=k/CYq3Lr; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="k/CYq3Lr" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 123B0C4AF17; Wed, 8 May 2024 10:26:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1715164023; bh=a9LJVsfpkf9Px0ybdQKegPbSIpTN8PO6xfWRp8iYXlk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=k/CYq3Lr1UdnWlpUXLveXvXXiP4RSHVPCRWu3FWSv0S6aovF7zswtOEofkR6/x+vF dN0KhvDeA4feDxlDi1wasmZMpuCRpLSiz3KzBU49UVD9x4lGUvbbAGWr4hTp3/oK+4 lVtr9qpVZczepZAi5TN6NFsqsVCn1G4KN/CsWk1RweeN1tVH5/m2rwE5UtVOTN8S28 TyZQhpEh7TVvPd/iUjPMdaj46lFSnxn9E5JHTsF/5EzTu0jKw2KShi+xEcarzM92ao buu57h8eqDNi74itwP+WLeukM4yaSQeVxxxQfWdrTnHneQD5NRGxTkj0cSEv8IIbOS By7Wwu61CgWPg== From: Benjamin Tissoires Date: Wed, 08 May 2024 12:26:36 +0200 Subject: [PATCH RFC HID 1/7] HID: bpf: change the prog run logic Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240508-hid_bpf_async_fun-v1-1-558375a25657@kernel.org> References: <20240508-hid_bpf_async_fun-v1-0-558375a25657@kernel.org> In-Reply-To: <20240508-hid_bpf_async_fun-v1-0-558375a25657@kernel.org> To: Benjamin Tissoires Cc: linux-kernel@vger.kernel.org, linux-input@vger.kernel.org, bpf@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=ed25519-sha256; t=1715164017; l=35499; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=a9LJVsfpkf9Px0ybdQKegPbSIpTN8PO6xfWRp8iYXlk=; b=RxicqOIkALqLIzq4dY160kp4fkAH4TScBDNkZhhnQKmwK0KUrVWs0aDSksO1rnHqxJidpyevV 4T52UFufWXWCZQ+u+b6JUQOp9i+/ZFlkL3hL8Qws7t/d84Yd2eoVUhK X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= We were previously relying on a pre-loaded tracing bpf program which runs bpf_tail_call(). However we can simplify this by a lot by relying on the new __async suffix which gives us basically a function pointer to the bpf program itself. This way, we rely on a much simpler process, ditching entirely the prog fd array and that tracing bpf program. Note the selftests will break and are handled in the later patch. Signed-off-by: Benjamin Tissoires --- drivers/hid/bpf/entrypoints/Makefile | 93 --------- drivers/hid/bpf/entrypoints/README | 4 - drivers/hid/bpf/entrypoints/entrypoints.bpf.c | 25 --- drivers/hid/bpf/entrypoints/entrypoints.lskel.h | 248 --------------------= ---- drivers/hid/bpf/hid_bpf_dispatch.c | 94 ++------- drivers/hid/bpf/hid_bpf_dispatch.h | 8 +- drivers/hid/bpf/hid_bpf_jmp_table.c | 174 +++-------------- include/linux/hid_bpf.h | 3 - 8 files changed, 51 insertions(+), 598 deletions(-) diff --git a/drivers/hid/bpf/entrypoints/Makefile b/drivers/hid/bpf/entrypo= ints/Makefile deleted file mode 100644 index 43b99b5575cf..000000000000 --- a/drivers/hid/bpf/entrypoints/Makefile +++ /dev/null @@ -1,93 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -OUTPUT :=3D .output -abs_out :=3D $(abspath $(OUTPUT)) - -CLANG ?=3D clang -LLC ?=3D llc -LLVM_STRIP ?=3D llvm-strip - -TOOLS_PATH :=3D $(abspath ../../../../tools) -BPFTOOL_SRC :=3D $(TOOLS_PATH)/bpf/bpftool -BPFTOOL_OUTPUT :=3D $(abs_out)/bpftool -DEFAULT_BPFTOOL :=3D $(BPFTOOL_OUTPUT)/bootstrap/bpftool -BPFTOOL ?=3D $(DEFAULT_BPFTOOL) - -LIBBPF_SRC :=3D $(TOOLS_PATH)/lib/bpf -LIBBPF_OUTPUT :=3D $(abs_out)/libbpf -LIBBPF_DESTDIR :=3D $(LIBBPF_OUTPUT) -LIBBPF_INCLUDE :=3D $(LIBBPF_DESTDIR)/include -BPFOBJ :=3D $(LIBBPF_OUTPUT)/libbpf.a - -INCLUDES :=3D -I$(OUTPUT) -I$(LIBBPF_INCLUDE) -I$(TOOLS_PATH)/include/uapi -CFLAGS :=3D -g -Wall - -VMLINUX_BTF_PATHS ?=3D $(if $(O),$(O)/vmlinux) \ - $(if $(KBUILD_OUTPUT),$(KBUILD_OUTPUT)/vmlinux) \ - ../../../../vmlinux \ - /sys/kernel/btf/vmlinux \ - /boot/vmlinux-$(shell uname -r) -VMLINUX_BTF ?=3D $(abspath $(firstword $(wildcard $(VMLINUX_BTF_PATHS)))) -ifeq ($(VMLINUX_BTF),) -$(error Cannot find a vmlinux for VMLINUX_BTF at any of "$(VMLINUX_BTF_PAT= HS)") -endif - -ifeq ($(V),1) -Q =3D -msg =3D -else -Q =3D @ -msg =3D @printf ' %-8s %s%s\n' "$(1)" "$(notdir $(2))" "$(if $(3), $(3))"; -MAKEFLAGS +=3D --no-print-directory -submake_extras :=3D feature_display=3D0 -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 $(BPFOB= J) | $(OUTPUT) - $(call msg,BPF,$@) - $(Q)$(CLANG) -g -O2 --target=3Dbpf $(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) | $(LIB= BPF_OUTPUT) - $(Q)$(MAKE) $(submake_extras) -C $(LIBBPF_SRC) \ - OUTPUT=3D$(abspath $(dir $@))/ prefix=3D \ - DESTDIR=3D$(LIBBPF_DESTDIR) $(abspath $@) install_headers - -ifeq ($(CROSS_COMPILE),) -$(DEFAULT_BPFTOOL): $(BPFOBJ) | $(BPFTOOL_OUTPUT) - $(Q)$(MAKE) $(submake_extras) -C $(BPFTOOL_SRC) \ - OUTPUT=3D$(BPFTOOL_OUTPUT)/ \ - LIBBPF_BOOTSTRAP_OUTPUT=3D$(LIBBPF_OUTPUT)/ \ - LIBBPF_BOOTSTRAP_DESTDIR=3D$(LIBBPF_DESTDIR)/ bootstrap -else -$(DEFAULT_BPFTOOL): | $(BPFTOOL_OUTPUT) - $(Q)$(MAKE) $(submake_extras) -C $(BPFTOOL_SRC) \ - OUTPUT=3D$(BPFTOOL_OUTPUT)/ bootstrap -endif diff --git a/drivers/hid/bpf/entrypoints/README b/drivers/hid/bpf/entrypoin= ts/README deleted file mode 100644 index 147e0d41509f..000000000000 --- a/drivers/hid/bpf/entrypoints/README +++ /dev/null @@ -1,4 +0,0 @@ -WARNING: -If you change "entrypoints.bpf.c" do "make -j" in this directory to rebuil= d "entrypoints.skel.h". -Make sure to have clang 10 installed. -See Documentation/bpf/bpf_devel_QA.rst diff --git a/drivers/hid/bpf/entrypoints/entrypoints.bpf.c b/drivers/hid/bp= f/entrypoints/entrypoints.bpf.c deleted file mode 100644 index c22921125a1a..000000000000 --- a/drivers/hid/bpf/entrypoints/entrypoints.bpf.c +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright (c) 2022 Benjamin Tissoires */ - -#include ".output/vmlinux.h" -#include -#include - -#define HID_BPF_MAX_PROGS 1024 - -struct { - __uint(type, BPF_MAP_TYPE_PROG_ARRAY); - __uint(max_entries, HID_BPF_MAX_PROGS); - __uint(key_size, sizeof(__u32)); - __uint(value_size, sizeof(__u32)); -} hid_jmp_table SEC(".maps"); - -SEC("fmod_ret/__hid_bpf_tail_call") -int BPF_PROG(hid_tail_call, struct hid_bpf_ctx *hctx) -{ - bpf_tail_call(ctx, &hid_jmp_table, hctx->index); - - return 0; -} - -char LICENSE[] SEC("license") =3D "GPL"; diff --git a/drivers/hid/bpf/entrypoints/entrypoints.lskel.h b/drivers/hid/= bpf/entrypoints/entrypoints.lskel.h deleted file mode 100644 index 35618051598c..000000000000 --- a/drivers/hid/bpf/entrypoints/entrypoints.lskel.h +++ /dev/null @@ -1,248 +0,0 @@ -/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ -/* THIS FILE IS AUTOGENERATED BY BPFTOOL! */ -#ifndef __ENTRYPOINTS_BPF_SKEL_H__ -#define __ENTRYPOINTS_BPF_SKEL_H__ - -#include - -struct entrypoints_bpf { - struct bpf_loader_ctx ctx; - struct { - struct bpf_map_desc hid_jmp_table; - } maps; - struct { - struct bpf_prog_desc hid_tail_call; - } progs; - struct { - int hid_tail_call_fd; - } links; -}; - -static inline int -entrypoints_bpf__hid_tail_call__attach(struct entrypoints_bpf *skel) -{ - int prog_fd =3D skel->progs.hid_tail_call.prog_fd; - int fd =3D skel_raw_tracepoint_open(NULL, prog_fd); - - if (fd > 0) - skel->links.hid_tail_call_fd =3D fd; - return fd; -} - -static inline int -entrypoints_bpf__attach(struct entrypoints_bpf *skel) -{ - int ret =3D 0; - - ret =3D ret < 0 ? ret : entrypoints_bpf__hid_tail_call__attach(skel); - return ret < 0 ? ret : 0; -} - -static inline void -entrypoints_bpf__detach(struct entrypoints_bpf *skel) -{ - skel_closenz(skel->links.hid_tail_call_fd); -} -static void -entrypoints_bpf__destroy(struct entrypoints_bpf *skel) -{ - if (!skel) - return; - entrypoints_bpf__detach(skel); - skel_closenz(skel->progs.hid_tail_call.prog_fd); - skel_closenz(skel->maps.hid_jmp_table.map_fd); - skel_free(skel); -} -static inline struct entrypoints_bpf * -entrypoints_bpf__open(void) -{ - struct entrypoints_bpf *skel; - - skel =3D skel_alloc(sizeof(*skel)); - if (!skel) - goto cleanup; - skel->ctx.sz =3D (void *)&skel->links - (void *)skel; - return skel; -cleanup: - entrypoints_bpf__destroy(skel); - return NULL; -} - -static inline int -entrypoints_bpf__load(struct entrypoints_bpf *skel) -{ - struct bpf_load_and_run_opts opts =3D {}; - int err; - - opts.ctx =3D (struct bpf_loader_ctx *)skel; - opts.data_sz =3D 2856; - opts.data =3D (void *)"\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x9f\xeb\x= 01\0\ -\x18\0\0\0\0\0\0\0\x60\x02\0\0\x60\x02\0\0\x12\x02\0\0\0\0\0\0\0\0\0\x02\x= 03\0\ -\0\0\x01\0\0\0\0\0\0\x01\x04\0\0\0\x20\0\0\x01\0\0\0\0\0\0\0\x03\0\0\0\0\x= 02\0\ -\0\0\x04\0\0\0\x03\0\0\0\x05\0\0\0\0\0\0\x01\x04\0\0\0\x20\0\0\0\0\0\0\0\0= \0\0\ -\x02\x06\0\0\0\0\0\0\0\0\0\0\x03\0\0\0\0\x02\0\0\0\x04\0\0\0\0\x04\0\0\0\0= \0\0\ -\0\0\0\x02\x08\0\0\0\0\0\0\0\0\0\0\x03\0\0\0\0\x02\0\0\0\x04\0\0\0\x04\0\0= \0\0\ -\0\0\0\x04\0\0\x04\x20\0\0\0\x19\0\0\0\x01\0\0\0\0\0\0\0\x1e\0\0\0\x05\0\0= \0\ -\x40\0\0\0\x2a\0\0\0\x07\0\0\0\x80\0\0\0\x33\0\0\0\x07\0\0\0\xc0\0\0\0\x3e= \0\0\ -\0\0\0\0\x0e\x09\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\x02\x0c\0\0\0\x4c\0\0\0\0\0= \0\ -\x01\x08\0\0\0\x40\0\0\0\0\0\0\0\x01\0\0\x0d\x02\0\0\0\x5f\0\0\0\x0b\0\0\0= \x63\ -\0\0\0\x01\0\0\x0c\x0d\0\0\0\x09\x01\0\0\x05\0\0\x04\x20\0\0\0\x15\x01\0\0= \x10\ -\0\0\0\0\0\0\0\x1b\x01\0\0\x12\0\0\0\x40\0\0\0\x1f\x01\0\0\x10\0\0\0\x80\0= \0\0\ -\x2e\x01\0\0\x14\0\0\0\xa0\0\0\0\0\0\0\0\x15\0\0\0\xc0\0\0\0\x3a\x01\0\0\0= \0\0\ -\x08\x11\0\0\0\x40\x01\0\0\0\0\0\x01\x04\0\0\0\x20\0\0\0\0\0\0\0\0\0\0\x02= \x13\ -\0\0\0\0\0\0\0\0\0\0\x0a\x1c\0\0\0\x4d\x01\0\0\x04\0\0\x06\x04\0\0\0\x5d\x= 01\0\ -\0\0\0\0\0\x6e\x01\0\0\x01\0\0\0\x80\x01\0\0\x02\0\0\0\x93\x01\0\0\x03\0\0= \0\0\ -\0\0\0\x02\0\0\x05\x04\0\0\0\xa4\x01\0\0\x16\0\0\0\0\0\0\0\xab\x01\0\0\x16= \0\0\ -\0\0\0\0\0\xb0\x01\0\0\0\0\0\x08\x02\0\0\0\xec\x01\0\0\0\0\0\x01\x01\0\0\0= \x08\ -\0\0\x01\0\0\0\0\0\0\0\x03\0\0\0\0\x17\0\0\0\x04\0\0\0\x04\0\0\0\xf1\x01\0= \0\0\ -\0\0\x0e\x18\0\0\0\x01\0\0\0\xf9\x01\0\0\x01\0\0\x0f\x20\0\0\0\x0a\0\0\0\0= \0\0\ -\0\x20\0\0\0\xff\x01\0\0\x01\0\0\x0f\x04\0\0\0\x19\0\0\0\0\0\0\0\x04\0\0\0= \x07\ -\x02\0\0\0\0\0\x07\0\0\0\0\0\x69\x6e\x74\0\x5f\x5f\x41\x52\x52\x41\x59\x5f= \x53\ -\x49\x5a\x45\x5f\x54\x59\x50\x45\x5f\x5f\0\x74\x79\x70\x65\0\x6d\x61\x78\x= 5f\ -\x65\x6e\x74\x72\x69\x65\x73\0\x6b\x65\x79\x5f\x73\x69\x7a\x65\0\x76\x61\x= 6c\ -\x75\x65\x5f\x73\x69\x7a\x65\0\x68\x69\x64\x5f\x6a\x6d\x70\x5f\x74\x61\x62= \x6c\ -\x65\0\x75\x6e\x73\x69\x67\x6e\x65\x64\x20\x6c\x6f\x6e\x67\x20\x6c\x6f\x6e= \x67\ -\0\x63\x74\x78\0\x68\x69\x64\x5f\x74\x61\x69\x6c\x5f\x63\x61\x6c\x6c\0\x66= \x6d\ -\x6f\x64\x5f\x72\x65\x74\x2f\x5f\x5f\x68\x69\x64\x5f\x62\x70\x66\x5f\x74\x= 61\ -\x69\x6c\x5f\x63\x61\x6c\x6c\0\x2f\x68\x6f\x6d\x65\x2f\x62\x74\x69\x73\x73= \x6f\ -\x69\x72\x2f\x53\x72\x63\x2f\x68\x69\x64\x2f\x64\x72\x69\x76\x65\x72\x73\x= 2f\ -\x68\x69\x64\x2f\x62\x70\x66\x2f\x65\x6e\x74\x72\x79\x70\x6f\x69\x6e\x74\x= 73\ -\x2f\x65\x6e\x74\x72\x79\x70\x6f\x69\x6e\x74\x73\x2e\x62\x70\x66\x2e\x63\0= \x69\ -\x6e\x74\x20\x42\x50\x46\x5f\x50\x52\x4f\x47\x28\x68\x69\x64\x5f\x74\x61\x= 69\ -\x6c\x5f\x63\x61\x6c\x6c\x2c\x20\x73\x74\x72\x75\x63\x74\x20\x68\x69\x64\x= 5f\ -\x62\x70\x66\x5f\x63\x74\x78\x20\x2a\x68\x63\x74\x78\x29\0\x68\x69\x64\x5f= \x62\ -\x70\x66\x5f\x63\x74\x78\0\x69\x6e\x64\x65\x78\0\x68\x69\x64\0\x61\x6c\x6c= \x6f\ -\x63\x61\x74\x65\x64\x5f\x73\x69\x7a\x65\0\x72\x65\x70\x6f\x72\x74\x5f\x74= \x79\ -\x70\x65\0\x5f\x5f\x75\x33\x32\0\x75\x6e\x73\x69\x67\x6e\x65\x64\x20\x69\x= 6e\ -\x74\0\x68\x69\x64\x5f\x72\x65\x70\x6f\x72\x74\x5f\x74\x79\x70\x65\0\x48\x= 49\ -\x44\x5f\x49\x4e\x50\x55\x54\x5f\x52\x45\x50\x4f\x52\x54\0\x48\x49\x44\x5f= \x4f\ -\x55\x54\x50\x55\x54\x5f\x52\x45\x50\x4f\x52\x54\0\x48\x49\x44\x5f\x46\x45= \x41\ -\x54\x55\x52\x45\x5f\x52\x45\x50\x4f\x52\x54\0\x48\x49\x44\x5f\x52\x45\x50= \x4f\ -\x52\x54\x5f\x54\x59\x50\x45\x53\0\x72\x65\x74\x76\x61\x6c\0\x73\x69\x7a\x= 65\0\ -\x5f\x5f\x73\x33\x32\0\x30\x3a\x30\0\x09\x62\x70\x66\x5f\x74\x61\x69\x6c\x= 5f\ -\x63\x61\x6c\x6c\x28\x63\x74\x78\x2c\x20\x26\x68\x69\x64\x5f\x6a\x6d\x70\x= 5f\ -\x74\x61\x62\x6c\x65\x2c\x20\x68\x63\x74\x78\x2d\x3e\x69\x6e\x64\x65\x78\x= 29\ -\x3b\0\x63\x68\x61\x72\0\x4c\x49\x43\x45\x4e\x53\x45\0\x2e\x6d\x61\x70\x73= \0\ -\x6c\x69\x63\x65\x6e\x73\x65\0\x68\x69\x64\x5f\x64\x65\x76\x69\x63\x65\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x8a\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \x03\ -\0\0\0\x04\0\0\0\x04\0\0\0\0\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x68\x69\x64\x= 5f\ -\x6a\x6d\x70\x5f\x74\x61\x62\x6c\x65\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\x47\x50\x4c\0\0\0\0\0\x79\x12\0\0\0\0\0\0\x61\x23\0\0= \0\0\ -\0\0\x18\x52\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x85\0\0\0\x0c\0\0\0\xb7\0\0\0\0\0= \0\0\ -\x95\0\0\0\0\0\0\0\0\0\0\0\x0e\0\0\0\0\0\0\0\x8e\0\0\0\xd3\0\0\0\x05\x48\0= \0\ -\x01\0\0\0\x8e\0\0\0\xba\x01\0\0\x02\x50\0\0\x05\0\0\0\x8e\0\0\0\xd3\0\0\0= \x05\ -\x48\0\0\x08\0\0\0\x0f\0\0\0\xb6\x01\0\0\0\0\0\0\x1a\0\0\0\x07\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x68= \x69\ -\x64\x5f\x74\x61\x69\x6c\x5f\x63\x61\x6c\x6c\0\0\0\0\0\0\0\x1a\0\0\0\0\0\0= \0\ -\x08\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\x10\0\0\0\0\0\0\0\0\0\0\0\x03\0\0\0\x= 01\0\ -\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\0\0\0\0\0\0\0\x= 5f\ -\x5f\x68\x69\x64\x5f\x62\x70\x66\x5f\x74\x61\x69\x6c\x5f\x63\x61\x6c\x6c\0= \0\0\ -\0\0"; - opts.insns_sz =3D 1192; - opts.insns =3D (void *)"\ -\xbf\x16\0\0\0\0\0\0\xbf\xa1\0\0\0\0\0\0\x07\x01\0\0\x78\xff\xff\xff\xb7\x= 02\0\ -\0\x88\0\0\0\xb7\x03\0\0\0\0\0\0\x85\0\0\0\x71\0\0\0\x05\0\x11\0\0\0\0\0\x= 61\ -\xa1\x78\xff\0\0\0\0\xd5\x01\x01\0\0\0\0\0\x85\0\0\0\xa8\0\0\0\x61\xa1\x7c= \xff\ -\0\0\0\0\xd5\x01\x01\0\0\0\0\0\x85\0\0\0\xa8\0\0\0\x61\xa1\x80\xff\0\0\0\0= \xd5\ -\x01\x01\0\0\0\0\0\x85\0\0\0\xa8\0\0\0\x18\x60\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \x61\ -\x01\0\0\0\0\0\0\xd5\x01\x02\0\0\0\0\0\xbf\x19\0\0\0\0\0\0\x85\0\0\0\xa8\0= \0\0\ -\xbf\x70\0\0\0\0\0\0\x95\0\0\0\0\0\0\0\x61\x60\x08\0\0\0\0\0\x18\x61\0\0\0= \0\0\ -\0\0\0\0\0\xa8\x09\0\0\x63\x01\0\0\0\0\0\0\x61\x60\x0c\0\0\0\0\0\x18\x61\0= \0\0\ -\0\0\0\0\0\0\0\xa4\x09\0\0\x63\x01\0\0\0\0\0\0\x79\x60\x10\0\0\0\0\0\x18\x= 61\0\ -\0\0\0\0\0\0\0\0\0\x98\x09\0\0\x7b\x01\0\0\0\0\0\0\x18\x60\0\0\0\0\0\0\0\0= \0\0\ -\0\x05\0\0\x18\x61\0\0\0\0\0\0\0\0\0\0\x90\x09\0\0\x7b\x01\0\0\0\0\0\0\xb7= \x01\ -\0\0\x12\0\0\0\x18\x62\0\0\0\0\0\0\0\0\0\0\x90\x09\0\0\xb7\x03\0\0\x1c\0\0= \0\ -\x85\0\0\0\xa6\0\0\0\xbf\x07\0\0\0\0\0\0\xc5\x07\xd7\xff\0\0\0\0\x63\x7a\x= 78\ -\xff\0\0\0\0\x61\x60\x1c\0\0\0\0\0\x15\0\x03\0\0\0\0\0\x18\x61\0\0\0\0\0\0= \0\0\ -\0\0\xbc\x09\0\0\x63\x01\0\0\0\0\0\0\xb7\x01\0\0\0\0\0\0\x18\x62\0\0\0\0\0= \0\0\ -\0\0\0\xb0\x09\0\0\xb7\x03\0\0\x48\0\0\0\x85\0\0\0\xa6\0\0\0\xbf\x07\0\0\0= \0\0\ -\0\xc5\x07\xca\xff\0\0\0\0\x18\x61\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x63\x71\0\0= \0\0\ -\0\0\x18\x60\0\0\0\0\0\0\0\0\0\0\xf8\x09\0\0\x18\x61\0\0\0\0\0\0\0\0\0\0\x= 90\ -\x0a\0\0\x7b\x01\0\0\0\0\0\0\x18\x60\0\0\0\0\0\0\0\0\0\0\0\x0a\0\0\x18\x61= \0\0\ -\0\0\0\0\0\0\0\0\x88\x0a\0\0\x7b\x01\0\0\0\0\0\0\x18\x60\0\0\0\0\0\0\0\0\0= \0\ -\x38\x0a\0\0\x18\x61\0\0\0\0\0\0\0\0\0\0\xd0\x0a\0\0\x7b\x01\0\0\0\0\0\0\x= 18\ -\x60\0\0\0\0\0\0\0\0\0\0\x40\x0a\0\0\x18\x61\0\0\0\0\0\0\0\0\0\0\xe0\x0a\0= \0\ -\x7b\x01\0\0\0\0\0\0\x18\x60\0\0\0\0\0\0\0\0\0\0\x70\x0a\0\0\x18\x61\0\0\0= \0\0\ -\0\0\0\0\0\0\x0b\0\0\x7b\x01\0\0\0\0\0\0\x18\x60\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\ -\x18\x61\0\0\0\0\0\0\0\0\0\0\xf8\x0a\0\0\x7b\x01\0\0\0\0\0\0\x61\x60\x08\0= \0\0\ -\0\0\x18\x61\0\0\0\0\0\0\0\0\0\0\x98\x0a\0\0\x63\x01\0\0\0\0\0\0\x61\x60\x= 0c\0\ -\0\0\0\0\x18\x61\0\0\0\0\0\0\0\0\0\0\x9c\x0a\0\0\x63\x01\0\0\0\0\0\0\x79\x= 60\ -\x10\0\0\0\0\0\x18\x61\0\0\0\0\0\0\0\0\0\0\xa0\x0a\0\0\x7b\x01\0\0\0\0\0\0= \x61\ -\xa0\x78\xff\0\0\0\0\x18\x61\0\0\0\0\0\0\0\0\0\0\xc8\x0a\0\0\x63\x01\0\0\0= \0\0\ -\0\x18\x61\0\0\0\0\0\0\0\0\0\0\x10\x0b\0\0\xb7\x02\0\0\x14\0\0\0\xb7\x03\0= \0\ -\x0c\0\0\0\xb7\x04\0\0\0\0\0\0\x85\0\0\0\xa7\0\0\0\xbf\x07\0\0\0\0\0\0\xc5= \x07\ -\x91\xff\0\0\0\0\x18\x60\0\0\0\0\0\0\0\0\0\0\x80\x0a\0\0\x63\x70\x6c\0\0\0= \0\0\ -\x77\x07\0\0\x20\0\0\0\x63\x70\x70\0\0\0\0\0\xb7\x01\0\0\x05\0\0\0\x18\x62= \0\0\ -\0\0\0\0\0\0\0\0\x80\x0a\0\0\xb7\x03\0\0\x8c\0\0\0\x85\0\0\0\xa6\0\0\0\xbf= \x07\ -\0\0\0\0\0\0\x18\x60\0\0\0\0\0\0\0\0\0\0\xf0\x0a\0\0\x61\x01\0\0\0\0\0\0\x= d5\ -\x01\x02\0\0\0\0\0\xbf\x19\0\0\0\0\0\0\x85\0\0\0\xa8\0\0\0\xc5\x07\x7f\xff= \0\0\ -\0\0\x63\x7a\x80\xff\0\0\0\0\x61\xa1\x78\xff\0\0\0\0\xd5\x01\x02\0\0\0\0\0= \xbf\ -\x19\0\0\0\0\0\0\x85\0\0\0\xa8\0\0\0\x61\xa0\x80\xff\0\0\0\0\x63\x06\x28\0= \0\0\ -\0\0\x18\x61\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x61\x10\0\0\0\0\0\0\x63\x06\x18\0= \0\0\ -\0\0\xb7\0\0\0\0\0\0\0\x95\0\0\0\0\0\0\0"; - err =3D bpf_load_and_run(&opts); - if (err < 0) - return err; - return 0; -} - -static inline struct entrypoints_bpf * -entrypoints_bpf__open_and_load(void) -{ - struct entrypoints_bpf *skel; - - skel =3D entrypoints_bpf__open(); - if (!skel) - return NULL; - if (entrypoints_bpf__load(skel)) { - entrypoints_bpf__destroy(skel); - return NULL; - } - return skel; -} - -__attribute__((unused)) static void -entrypoints_bpf__assert(struct entrypoints_bpf *s __attribute__((unused))) -{ -#ifdef __cplusplus -#define _Static_assert static_assert -#endif -#ifdef __cplusplus -#undef _Static_assert -#endif -} - -#endif /* __ENTRYPOINTS_BPF_SKEL_H__ */ diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_d= ispatch.c index 10289f44d0cc..81073db6c617 100644 --- a/drivers/hid/bpf/hid_bpf_dispatch.c +++ b/drivers/hid/bpf/hid_bpf_dispatch.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -19,7 +20,6 @@ #include #include #include "hid_bpf_dispatch.h" -#include "entrypoints/entrypoints.lskel.h" =20 struct hid_bpf_ops *hid_bpf_ops; EXPORT_SYMBOL(hid_bpf_ops); @@ -203,25 +203,17 @@ int hid_bpf_reconnect(struct hid_device *hdev) return 0; } =20 -static int do_hid_bpf_attach_prog(struct hid_device *hdev, int prog_fd, st= ruct bpf_prog *prog, +static int do_hid_bpf_attach_prog(struct hid_device *hdev, enum hid_bpf_pr= og_type prog_type, + hid_bpf_cb_t prog_fn, struct bpf_prog *prog, __u32 flags) { - int fd, err, prog_type; + int fd, err; =20 - prog_type =3D hid_bpf_get_prog_attach_type(prog); - if (prog_type < 0) - return prog_type; + err =3D hid_bpf_allocate_event_data(hdev); + if (err) + return err; =20 - if (prog_type >=3D HID_BPF_PROG_TYPE_MAX) - return -EINVAL; - - if (prog_type =3D=3D HID_BPF_PROG_TYPE_DEVICE_EVENT) { - err =3D hid_bpf_allocate_event_data(hdev); - if (err) - return err; - } - - fd =3D __hid_bpf_attach_prog(hdev, prog_type, prog_fd, prog, flags); + fd =3D __hid_bpf_attach_prog(hdev, prog_type, prog_fn, prog, flags); if (fd < 0) return fd; =20 @@ -277,10 +269,12 @@ hid_bpf_get_data(struct hid_bpf_ctx *ctx, unsigned in= t offset, const size_t rdwr */ /* called from syscall */ __bpf_kfunc int -hid_bpf_attach_prog(unsigned int hid_id, int prog_fd, __u32 flags) +hid_bpf_attach_prog_impl(unsigned int hid_id, enum hid_bpf_prog_type prog_= type, + hid_bpf_cb_t prog_fn__async, __u32 flags, void *prog__aux) { + struct bpf_prog_aux *aux =3D (struct bpf_prog_aux *)prog__aux; + struct bpf_prog *prog =3D aux->prog; struct hid_device *hdev; - struct bpf_prog *prog; struct device *dev; int err, fd; =20 @@ -290,6 +284,9 @@ hid_bpf_attach_prog(unsigned int hid_id, int prog_fd, _= _u32 flags) if ((flags & ~HID_BPF_FLAG_MASK)) return -EINVAL; =20 + if (prog_type < 0 || prog_type >=3D HID_BPF_PROG_TYPE_MAX) + return -EINVAL; + dev =3D bus_find_device(hid_bpf_ops->bus_type, NULL, &hid_id, device_matc= h_id); if (!dev) return -EINVAL; @@ -300,13 +297,13 @@ hid_bpf_attach_prog(unsigned int hid_id, int prog_fd,= __u32 flags) * take a ref on the prog itself, it will be released * on errors or when it'll be detached */ - prog =3D bpf_prog_get(prog_fd); + prog =3D bpf_prog_inc_not_zero(prog); if (IS_ERR(prog)) { err =3D PTR_ERR(prog); goto out_dev_put; } =20 - fd =3D do_hid_bpf_attach_prog(hdev, prog_fd, prog, flags); + fd =3D do_hid_bpf_attach_prog(hdev, prog_type, prog_fn__async, prog, flag= s); if (fd < 0) { err =3D fd; goto out_prog_put; @@ -538,12 +535,9 @@ hid_bpf_input_report(struct hid_bpf_ctx *ctx, enum hid= _report_type type, u8 *buf } __bpf_kfunc_end_defs(); =20 -/* - * The following set contains all functions we agree BPF programs - * can use. - */ BTF_KFUNCS_START(hid_bpf_kfunc_ids) BTF_ID_FLAGS(func, hid_bpf_get_data, KF_RET_NULL) +BTF_ID_FLAGS(func, hid_bpf_attach_prog_impl, KF_SLEEPABLE) BTF_ID_FLAGS(func, hid_bpf_allocate_context, KF_ACQUIRE | KF_RET_NULL | KF= _SLEEPABLE) BTF_ID_FLAGS(func, hid_bpf_release_context, KF_RELEASE | KF_SLEEPABLE) BTF_ID_FLAGS(func, hid_bpf_hw_request, KF_SLEEPABLE) @@ -556,33 +550,6 @@ static const struct btf_kfunc_id_set hid_bpf_kfunc_set= =3D { .set =3D &hid_bpf_kfunc_ids, }; =20 -/* our HID-BPF entrypoints */ -BTF_SET8_START(hid_bpf_fmodret_ids) -BTF_ID_FLAGS(func, hid_bpf_device_event) -BTF_ID_FLAGS(func, hid_bpf_rdesc_fixup) -BTF_ID_FLAGS(func, __hid_bpf_tail_call) -BTF_SET8_END(hid_bpf_fmodret_ids) - -static const struct btf_kfunc_id_set hid_bpf_fmodret_set =3D { - .owner =3D THIS_MODULE, - .set =3D &hid_bpf_fmodret_ids, -}; - -/* for syscall HID-BPF */ -BTF_KFUNCS_START(hid_bpf_syscall_kfunc_ids) -BTF_ID_FLAGS(func, hid_bpf_attach_prog) -BTF_ID_FLAGS(func, hid_bpf_allocate_context, KF_ACQUIRE | KF_RET_NULL) -BTF_ID_FLAGS(func, hid_bpf_release_context, KF_RELEASE) -BTF_ID_FLAGS(func, hid_bpf_hw_request) -BTF_ID_FLAGS(func, hid_bpf_hw_output_report) -BTF_ID_FLAGS(func, hid_bpf_input_report) -BTF_KFUNCS_END(hid_bpf_syscall_kfunc_ids) - -static const struct btf_kfunc_id_set hid_bpf_syscall_kfunc_set =3D { - .owner =3D THIS_MODULE, - .set =3D &hid_bpf_syscall_kfunc_ids, -}; - int hid_bpf_connect_device(struct hid_device *hdev) { struct hid_bpf_prog_list *prog_list; @@ -636,29 +603,9 @@ static int __init hid_bpf_init(void) * will not be available, so nobody will be able to use the functionality. */ =20 - err =3D register_btf_fmodret_id_set(&hid_bpf_fmodret_set); - if (err) { - pr_warn("error while registering fmodret entrypoints: %d", err); - return 0; - } - - err =3D hid_bpf_preload_skel(); - if (err) { - pr_warn("error while preloading HID BPF dispatcher: %d", err); - return 0; - } - - /* register tracing kfuncs after we are sure we can load our preloaded bp= f program */ - err =3D register_btf_kfunc_id_set(BPF_PROG_TYPE_TRACING, &hid_bpf_kfunc_s= et); - if (err) { - pr_warn("error while setting HID BPF tracing kfuncs: %d", err); - return 0; - } - - /* register syscalls after we are sure we can load our preloaded bpf prog= ram */ - err =3D register_btf_kfunc_id_set(BPF_PROG_TYPE_SYSCALL, &hid_bpf_syscall= _kfunc_set); + err =3D register_btf_kfunc_id_set(BPF_PROG_TYPE_SYSCALL, &hid_bpf_kfunc_s= et); if (err) { - pr_warn("error while setting HID BPF syscall kfuncs: %d", err); + pr_warn("error while setting HID BPF kfuncs: %d", err); return 0; } =20 @@ -670,7 +617,6 @@ static void __exit hid_bpf_exit(void) /* HID depends on us, so if we hit that code, we are guaranteed that hid * has been removed and thus we do not need to clear the HID devices */ - hid_bpf_free_links_and_skel(); } =20 late_initcall(hid_bpf_init); diff --git a/drivers/hid/bpf/hid_bpf_dispatch.h b/drivers/hid/bpf/hid_bpf_d= ispatch.h index fbe0639d09f2..60455a2af216 100644 --- a/drivers/hid/bpf/hid_bpf_dispatch.h +++ b/drivers/hid/bpf/hid_bpf_dispatch.h @@ -10,10 +10,10 @@ struct hid_bpf_ctx_kern { u8 *data; }; =20 -int hid_bpf_preload_skel(void); -void hid_bpf_free_links_and_skel(void); -int hid_bpf_get_prog_attach_type(struct bpf_prog *prog); -int __hid_bpf_attach_prog(struct hid_device *hdev, enum hid_bpf_prog_type = prog_type, int prog_fd, +typedef int (*hid_bpf_cb_t)(struct hid_bpf_ctx *hid_ctx); + +int __hid_bpf_attach_prog(struct hid_device *hdev, enum hid_bpf_prog_type = prog_type, + int (prog_fn__async)(struct hid_bpf_ctx *hid_ctx), struct bpf_prog *prog, __u32 flags); void __hid_bpf_destroy_device(struct hid_device *hdev); int hid_bpf_prog_run(struct hid_device *hdev, enum hid_bpf_prog_type type, diff --git a/drivers/hid/bpf/hid_bpf_jmp_table.c b/drivers/hid/bpf/hid_bpf_= jmp_table.c index aa8e1c79cdf5..8d53d41b599b 100644 --- a/drivers/hid/bpf/hid_bpf_jmp_table.c +++ b/drivers/hid/bpf/hid_bpf_jmp_table.c @@ -17,7 +17,6 @@ #include #include #include "hid_bpf_dispatch.h" -#include "entrypoints/entrypoints.lskel.h" =20 #define HID_BPF_MAX_PROGS 1024 /* keep this in sync with preloaded bpf, * needs to be a power of 2 as we use it as @@ -37,11 +36,15 @@ struct hid_bpf_prog_entry { u16 idx; }; =20 +struct hid_bpf_prog_cb { + struct bpf_prog *prog; + void *fn; +}; + struct hid_bpf_jmp_table { - struct bpf_map *map; struct hid_bpf_prog_entry entries[HID_BPF_MAX_PROGS]; /* compacted list, = circular buffer */ int tail, head; - struct bpf_prog *progs[HID_BPF_MAX_PROGS]; /* idx -> progs mapping */ + struct hid_bpf_prog_cb prog_cbs[HID_BPF_MAX_PROGS]; /* idx -> progs mappi= ng */ unsigned long enabled[BITS_TO_LONGS(HID_BPF_MAX_PROGS)]; }; =20 @@ -56,10 +59,6 @@ static void hid_bpf_release_progs(struct work_struct *wo= rk); =20 static DECLARE_WORK(release_work, hid_bpf_release_progs); =20 -BTF_ID_LIST(hid_bpf_btf_ids) -BTF_ID(func, hid_bpf_device_event) /* HID_BPF_PROG_TYPE_DEVICE_EVENT */ -BTF_ID(func, hid_bpf_rdesc_fixup) /* HID_BPF_PROG_TYPE_RDESC_FIXUP */ - static int hid_bpf_max_programs(enum hid_bpf_prog_type type) { switch (type) { @@ -99,15 +98,11 @@ static int hid_bpf_program_count(struct hid_device *hde= v, return n; } =20 -__weak noinline int __hid_bpf_tail_call(struct hid_bpf_ctx *ctx) -{ - return 0; -} - int hid_bpf_prog_run(struct hid_device *hdev, enum hid_bpf_prog_type type, struct hid_bpf_ctx_kern *ctx_kern) { struct hid_bpf_prog_list *prog_list; + bpf_callback_t prog_fn; int i, idx, err =3D 0; =20 rcu_read_lock(); @@ -123,7 +118,10 @@ int hid_bpf_prog_run(struct hid_device *hdev, enum hid= _bpf_prog_type type, continue; =20 ctx_kern->ctx.index =3D idx; - err =3D __hid_bpf_tail_call(&ctx_kern->ctx); + prog_fn =3D jmp_table.prog_cbs[idx].fn; + migrate_disable(); + err =3D prog_fn((u64)(long)&ctx_kern->ctx, 0, 0, 0, 0); + migrate_enable(); if (err < 0) break; if (err) @@ -187,25 +185,18 @@ static int hid_bpf_populate_hdev(struct hid_device *h= dev, enum hid_bpf_prog_type return 0; } =20 -static void __hid_bpf_do_release_prog(int map_fd, unsigned int idx) +static void __hid_bpf_do_release_prog(unsigned int idx) { - skel_map_delete_elem(map_fd, &idx); - jmp_table.progs[idx] =3D NULL; + bpf_prog_put(jmp_table.prog_cbs[idx].prog); + jmp_table.prog_cbs[idx].prog =3D NULL; + jmp_table.prog_cbs[idx].fn =3D NULL; } =20 static void hid_bpf_release_progs(struct work_struct *work) { - int i, j, n, map_fd =3D -1; + int i, j, n; bool hdev_destroyed; =20 - if (!jmp_table.map) - return; - - /* retrieve a fd of our prog_array map in BPF */ - map_fd =3D skel_map_get_fd_by_id(jmp_table.map->id); - if (map_fd < 0) - return; - mutex_lock(&hid_bpf_attach_lock); /* protects against attaching new progr= ams */ =20 /* detach unused progs from HID devices */ @@ -264,7 +255,7 @@ static void hid_bpf_release_progs(struct work_struct *w= ork) continue; =20 if (entry->prog) - __hid_bpf_do_release_prog(map_fd, entry->idx); + __hid_bpf_do_release_prog(entry->idx); } =20 /* compact the entry list */ @@ -282,46 +273,22 @@ static void hid_bpf_release_progs(struct work_struct = *work) jmp_table.head =3D n; =20 mutex_unlock(&hid_bpf_attach_lock); - - if (map_fd >=3D 0) - close_fd(map_fd); -} - -static void hid_bpf_release_prog_at(int idx) -{ - int map_fd =3D -1; - - /* retrieve a fd of our prog_array map in BPF */ - map_fd =3D skel_map_get_fd_by_id(jmp_table.map->id); - if (map_fd < 0) - return; - - __hid_bpf_do_release_prog(map_fd, idx); - - close(map_fd); } =20 /* - * Insert the given BPF program represented by its fd in the jmp table. + * Insert the given BPF program represented by its function call in the jm= p table. * Returns the index in the jump table or a negative error. */ -static int hid_bpf_insert_prog(int prog_fd, struct bpf_prog *prog) +static int hid_bpf_insert_prog(struct bpf_prog *prog, hid_bpf_cb_t prog_fn) { - int i, index =3D -1, map_fd =3D -1, err =3D -EINVAL; - - /* retrieve a fd of our prog_array map in BPF */ - map_fd =3D skel_map_get_fd_by_id(jmp_table.map->id); - - if (map_fd < 0) { - err =3D -EINVAL; - goto out; - } + int i, index =3D -1, err =3D -EINVAL; =20 /* find the first available index in the jmp_table */ for (i =3D 0; i < HID_BPF_MAX_PROGS; i++) { - if (!jmp_table.progs[i] && index < 0) { + if (!jmp_table.prog_cbs[i].prog && index < 0) { /* mark the index as used */ - jmp_table.progs[i] =3D prog; + jmp_table.prog_cbs[i].fn =3D prog_fn; + jmp_table.prog_cbs[i].prog =3D prog; index =3D i; __set_bit(i, jmp_table.enabled); } @@ -331,37 +298,15 @@ static int hid_bpf_insert_prog(int prog_fd, struct bp= f_prog *prog) goto out; } =20 - /* insert the program in the jump table */ - err =3D skel_map_update_elem(map_fd, &index, &prog_fd, 0); - if (err) - goto out; - /* return the index */ err =3D index; =20 out: if (err < 0) - __hid_bpf_do_release_prog(map_fd, index); - if (map_fd >=3D 0) - close_fd(map_fd); + __hid_bpf_do_release_prog(index); return err; } =20 -int hid_bpf_get_prog_attach_type(struct bpf_prog *prog) -{ - int prog_type =3D HID_BPF_PROG_TYPE_UNDEF; - int i; - - for (i =3D 0; i < HID_BPF_PROG_TYPE_MAX; i++) { - if (hid_bpf_btf_ids[i] =3D=3D prog->aux->attach_btf_id) { - prog_type =3D i; - break; - } - } - - return prog_type; -} - static void hid_bpf_link_release(struct bpf_link *link) { struct hid_bpf_link *hid_link =3D @@ -395,7 +340,7 @@ static const struct bpf_link_ops hid_bpf_link_lops =3D { /* called from syscall */ noinline int __hid_bpf_attach_prog(struct hid_device *hdev, enum hid_bpf_prog_type prog= _type, - int prog_fd, struct bpf_prog *prog, __u32 flags) + hid_bpf_cb_t prog_fn, struct bpf_prog *prog, __u32 flags) { struct bpf_link_primer link_primer; struct hid_bpf_link *link; @@ -425,7 +370,7 @@ __hid_bpf_attach_prog(struct hid_device *hdev, enum hid= _bpf_prog_type prog_type, goto err_unlock; } =20 - prog_table_idx =3D hid_bpf_insert_prog(prog_fd, prog); + prog_table_idx =3D hid_bpf_insert_prog(prog, prog_fn); /* if the jmp table is full, abort */ if (prog_table_idx < 0) { err =3D prog_table_idx; @@ -451,7 +396,7 @@ __hid_bpf_attach_prog(struct hid_device *hdev, enum hid= _bpf_prog_type prog_type, /* finally store the index in the device list */ err =3D hid_bpf_populate_hdev(hdev, prog_type); if (err) { - hid_bpf_release_prog_at(prog_table_idx); + __hid_bpf_do_release_prog(prog_table_idx); goto err_unlock; } =20 @@ -498,68 +443,3 @@ void __hid_bpf_destroy_device(struct hid_device *hdev) /* schedule release of all detached progs */ schedule_work(&release_work); } - -#define HID_BPF_PROGS_COUNT 1 - -static struct bpf_link *links[HID_BPF_PROGS_COUNT]; -static struct entrypoints_bpf *skel; - -void hid_bpf_free_links_and_skel(void) -{ - int i; - - /* the following is enough to release all programs attached to hid */ - if (jmp_table.map) - bpf_map_put_with_uref(jmp_table.map); - - for (i =3D 0; i < ARRAY_SIZE(links); i++) { - if (!IS_ERR_OR_NULL(links[i])) - bpf_link_put(links[i]); - } - entrypoints_bpf__destroy(skel); -} - -#define ATTACH_AND_STORE_LINK(__name) do { \ - err =3D entrypoints_bpf__##__name##__attach(skel); \ - if (err) \ - goto out; \ - \ - links[idx] =3D bpf_link_get_from_fd(skel->links.__name##_fd); \ - if (IS_ERR(links[idx])) { \ - err =3D PTR_ERR(links[idx]); \ - goto out; \ - } \ - \ - /* Avoid taking over stdin/stdout/stderr of init process. Zeroing out \ - * makes skel_closenz() a no-op later in iterators_bpf__destroy(). \ - */ \ - close_fd(skel->links.__name##_fd); \ - skel->links.__name##_fd =3D 0; \ - idx++; \ -} while (0) - -int hid_bpf_preload_skel(void) -{ - int err, idx =3D 0; - - skel =3D entrypoints_bpf__open(); - if (!skel) - return -ENOMEM; - - err =3D entrypoints_bpf__load(skel); - if (err) - goto out; - - jmp_table.map =3D bpf_map_get_with_uref(skel->maps.hid_jmp_table.map_fd); - if (IS_ERR(jmp_table.map)) { - err =3D PTR_ERR(jmp_table.map); - goto out; - } - - ATTACH_AND_STORE_LINK(hid_tail_call); - - return 0; -out: - hid_bpf_free_links_and_skel(); - return err; -} diff --git a/include/linux/hid_bpf.h b/include/linux/hid_bpf.h index 17b08f500098..99ebe7bbb02a 100644 --- a/include/linux/hid_bpf.h +++ b/include/linux/hid_bpf.h @@ -81,9 +81,6 @@ int hid_bpf_rdesc_fixup(struct hid_bpf_ctx *ctx); * Below is HID internal */ =20 -/* internal function to call eBPF programs, not to be used by anybody */ -int __hid_bpf_tail_call(struct hid_bpf_ctx *ctx); - #define HID_BPF_MAX_PROGS_PER_DEV 64 #define HID_BPF_FLAG_MASK (((HID_BPF_FLAG_MAX - 1) << 1) - 1) =20 --=20 2.44.0 From nobody Wed Dec 17 05:48:13 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 666D77B3F3; Wed, 8 May 2024 10:27:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715164027; cv=none; b=aZRq9E9FYDmBQrN1CSzjI7kydi2/WVqUdJU5SHCn5Q5U42wtqE/O5mKAo5vWOlDb7/3wxztWuHPJOJqCbjWB4mfHZoe8rCVzn8mqQbXj0dohfg07srb//7jMmg+X4fcCCLl4rprg97PZOz1JHvLnELD1C/w5A+MwXl3ozMAO3+0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715164027; c=relaxed/simple; bh=bd0bpoEpyiLdDsGWlz0RnhORzoCPz+ID4XTIfN6BdpY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=fi6wzyIcXAQu64eOkmzXY93Q+qOzXEhF/VCoBkgpVKySfXVk50FPBDuMeQ1OoGw0H5q1ftqd/QAdq2oOyoeBt62nrpZRbX0OAbeA3544dMmLHLP7ehkLS5gqoE8nIJq0JBIPgUqh8w5gnvZCz4WAEPElGhETIw7oJOWSQ5c6rgI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=p57F73eg; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="p57F73eg" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 10D8FC113CC; Wed, 8 May 2024 10:27:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1715164027; bh=bd0bpoEpyiLdDsGWlz0RnhORzoCPz+ID4XTIfN6BdpY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=p57F73eg6+Cuv4pzTtpVG5k7Vp8P00tYl1jA07QvzNhFVGOHKguaGmK0FlxZclNAq 9NLlXEH0qhXPBduigM7huFareruneH+0MhmZ8BQCvc1MwgUdaBkJumiF8DoV+hHjmC cIT+ZM2C3SAV4km1NoifpisYDJMIRIrj41uQ/XSdc80KLRRaob39cJuQYG5x3tUquT vOpD8lOO7ZPnHIe31j1PRGhrTNDMxvCM57Fdjzv3sQORWIdxb71VNGjCcLqtNibg1J /bdR8W++yCqtsyG4bxcdV0MAYUn+go9q+pya4KZrQJYb34Bf5XYa+Hl/crV/UkmWMt zQkq60jdU6xXg== From: Benjamin Tissoires Date: Wed, 08 May 2024 12:26:37 +0200 Subject: [PATCH RFC HID 2/7] selftests/hid: fix bpf programs for the new attachment logic Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240508-hid_bpf_async_fun-v1-2-558375a25657@kernel.org> References: <20240508-hid_bpf_async_fun-v1-0-558375a25657@kernel.org> In-Reply-To: <20240508-hid_bpf_async_fun-v1-0-558375a25657@kernel.org> To: Benjamin Tissoires Cc: linux-kernel@vger.kernel.org, linux-input@vger.kernel.org, bpf@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=ed25519-sha256; t=1715164017; l=7780; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=bd0bpoEpyiLdDsGWlz0RnhORzoCPz+ID4XTIfN6BdpY=; b=mH6bdPSwcblq8+CUzC9rHRJxufsXsTLq/qcKkKsIW8FdyaHkhLr9xo47pKu7Fs+8xPSqrUcct KSsNmdbPASVBN2VQdRf0AeVqDhfrX14BtCD83r1zv1PFcYhddoqy9aZ X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= Now each program needs to ship its own attach prog. To make things simpler we define __HID_BPF_PROG() and the various sub-macros per hid-bpf type of program. Signed-off-by: Benjamin Tissoires --- tools/testing/selftests/hid/hid_bpf.c | 6 +--- tools/testing/selftests/hid/progs/hid.c | 40 +++++-------------= ---- .../testing/selftests/hid/progs/hid_bpf_helpers.h | 29 +++++++++++++++- 3 files changed, 37 insertions(+), 38 deletions(-) diff --git a/tools/testing/selftests/hid/hid_bpf.c b/tools/testing/selftest= s/hid/hid_bpf.c index f825623e3edc..7fed9f599b62 100644 --- a/tools/testing/selftests/hid/hid_bpf.c +++ b/tools/testing/selftests/hid/hid_bpf.c @@ -90,7 +90,6 @@ static unsigned char rdesc[] =3D { static __u8 feature_data[] =3D { 1, 2 }; =20 struct attach_prog_args { - int prog_fd; unsigned int hid; int retval; int insert_head; @@ -556,9 +555,6 @@ static void load_programs(const struct test_program pro= grams[], err =3D hid__load(self->skel); ASSERT_OK(err) TH_LOG("hid_skel_load failed: %d", err); =20 - attach_fd =3D bpf_program__fd(self->skel->progs.attach_prog); - ASSERT_GE(attach_fd, 0) TH_LOG("locate attach_prog: %d", attach_fd); - for (int i =3D 0; i < progs_count; i++) { struct bpf_program *prog; =20 @@ -566,7 +562,7 @@ static void load_programs(const struct test_program pro= grams[], programs[i].name); ASSERT_OK_PTR(prog) TH_LOG("can not find program by name '%s'", programs= [i].name); =20 - args.prog_fd =3D bpf_program__fd(prog); + attach_fd =3D bpf_program__fd(prog); args.hid =3D self->hid_id; args.insert_head =3D programs[i].insert_head; err =3D bpf_prog_test_run_opts(attach_fd, &tattr); diff --git a/tools/testing/selftests/hid/progs/hid.c b/tools/testing/selfte= sts/hid/progs/hid.c index f67d35def142..b721d1256836 100644 --- a/tools/testing/selftests/hid/progs/hid.c +++ b/tools/testing/selftests/hid/progs/hid.c @@ -4,18 +4,10 @@ =20 char _license[] SEC("license") =3D "GPL"; =20 -struct attach_prog_args { - int prog_fd; - unsigned int hid; - int retval; - int insert_head; -}; - __u64 callback_check =3D 52; __u64 callback2_check =3D 52; =20 -SEC("?fmod_ret/hid_bpf_device_event") -int BPF_PROG(hid_first_event, struct hid_bpf_ctx *hid_ctx) +HID_BPF_DEVICE_EVENT(hid_first_event, struct hid_bpf_ctx *hid_ctx) { __u8 *rw_data =3D hid_bpf_get_data(hid_ctx, 0 /* offset */, 3 /* size */); =20 @@ -29,8 +21,7 @@ int BPF_PROG(hid_first_event, struct hid_bpf_ctx *hid_ctx) return hid_ctx->size; } =20 -SEC("?fmod_ret/hid_bpf_device_event") -int BPF_PROG(hid_second_event, struct hid_bpf_ctx *hid_ctx) +HID_BPF_DEVICE_EVENT(hid_second_event, struct hid_bpf_ctx *hid_ctx) { __u8 *rw_data =3D hid_bpf_get_data(hid_ctx, 0 /* offset */, 4 /* size */); =20 @@ -42,8 +33,7 @@ int BPF_PROG(hid_second_event, struct hid_bpf_ctx *hid_ct= x) return hid_ctx->size; } =20 -SEC("?fmod_ret/hid_bpf_device_event") -int BPF_PROG(hid_change_report_id, struct hid_bpf_ctx *hid_ctx) +HID_BPF_DEVICE_EVENT(hid_change_report_id, struct hid_bpf_ctx *hid_ctx) { __u8 *rw_data =3D hid_bpf_get_data(hid_ctx, 0 /* offset */, 3 /* size */); =20 @@ -55,16 +45,6 @@ int BPF_PROG(hid_change_report_id, struct hid_bpf_ctx *h= id_ctx) return 9; } =20 -SEC("syscall") -int attach_prog(struct attach_prog_args *ctx) -{ - ctx->retval =3D hid_bpf_attach_prog(ctx->hid, - ctx->prog_fd, - ctx->insert_head ? HID_BPF_FLAG_INSERT_HEAD : - HID_BPF_FLAG_NONE); - return 0; -} - struct hid_hw_request_syscall_args { /* data needs to come at offset 0 so we can use it in calls */ __u8 data[10]; @@ -181,13 +161,12 @@ static const __u8 rdesc[] =3D { 0xc0, /* END_COLLECTION */ }; =20 -SEC("?fmod_ret/hid_bpf_rdesc_fixup") -int BPF_PROG(hid_rdesc_fixup, struct hid_bpf_ctx *hid_ctx) +HID_BPF_RDESC_FIXUP(hid_rdesc_fixup, struct hid_bpf_ctx *hid_ctx) { __u8 *data =3D hid_bpf_get_data(hid_ctx, 0 /* offset */, 4096 /* size */); =20 if (!data) - return 0; /* EPERM check */ + return -22; /* EPERM check */ =20 callback2_check =3D data[4]; =20 @@ -200,8 +179,7 @@ int BPF_PROG(hid_rdesc_fixup, struct hid_bpf_ctx *hid_c= tx) return sizeof(rdesc) + 73; } =20 -SEC("?fmod_ret/hid_bpf_device_event") -int BPF_PROG(hid_test_insert1, struct hid_bpf_ctx *hid_ctx) +HID_BPF_DEVICE_EVENT(hid_test_insert1, struct hid_bpf_ctx *hid_ctx) { __u8 *data =3D hid_bpf_get_data(hid_ctx, 0 /* offset */, 4 /* size */); =20 @@ -217,8 +195,7 @@ int BPF_PROG(hid_test_insert1, struct hid_bpf_ctx *hid_= ctx) return 0; } =20 -SEC("?fmod_ret/hid_bpf_device_event") -int BPF_PROG(hid_test_insert2, struct hid_bpf_ctx *hid_ctx) +HID_BPF_DEVICE_EVENT(hid_test_insert2, struct hid_bpf_ctx *hid_ctx) { __u8 *data =3D hid_bpf_get_data(hid_ctx, 0 /* offset */, 4 /* size */); =20 @@ -234,8 +211,7 @@ int BPF_PROG(hid_test_insert2, struct hid_bpf_ctx *hid_= ctx) return 0; } =20 -SEC("?fmod_ret/hid_bpf_device_event") -int BPF_PROG(hid_test_insert3, struct hid_bpf_ctx *hid_ctx) +HID_BPF_DEVICE_EVENT(hid_test_insert3, struct hid_bpf_ctx *hid_ctx) { __u8 *data =3D hid_bpf_get_data(hid_ctx, 0 /* offset */, 4 /* size */); =20 diff --git a/tools/testing/selftests/hid/progs/hid_bpf_helpers.h b/tools/te= sting/selftests/hid/progs/hid_bpf_helpers.h index 9cd56821d0f1..9826880e88d1 100644 --- a/tools/testing/selftests/hid/progs/hid_bpf_helpers.h +++ b/tools/testing/selftests/hid/progs/hid_bpf_helpers.h @@ -82,11 +82,20 @@ enum hid_bpf_attach_flags { HID_BPF_FLAG_MAX, }; =20 +struct attach_prog_args { + unsigned int hid; + int retval; + int insert_head; +}; + /* following are kfuncs exported by HID for HID-BPF */ extern __u8 *hid_bpf_get_data(struct hid_bpf_ctx *ctx, unsigned int offset, const size_t __sz) __ksym; -extern int hid_bpf_attach_prog(unsigned int hid_id, int prog_fd, u32 flags= ) __ksym; +extern int hid_bpf_attach_prog_impl(unsigned int hid_id, + enum hid_bpf_prog_type type, + int (prog_fn)(struct hid_bpf_ctx *hid_ctx), + u32 flags, void *aux) __ksym; extern struct hid_bpf_ctx *hid_bpf_allocate_context(unsigned int hid_id) _= _ksym; extern void hid_bpf_release_context(struct hid_bpf_ctx *ctx) __ksym; extern int hid_bpf_hw_request(struct hid_bpf_ctx *ctx, @@ -101,4 +110,22 @@ extern int hid_bpf_input_report(struct hid_bpf_ctx *ct= x, __u8 *data, size_t buf__sz) __ksym; =20 +#define __HID_BPF_PROG(type, name, arg) = \ + static int __##name(arg); = \ + SEC("syscall") = \ + int name(struct attach_prog_args *ctx) = \ + { = \ + ctx->retval =3D hid_bpf_attach_prog_impl(ctx->hid, = \ + type, \ + __##name, \ + ctx->insert_head ? HID_BPF_FLAG_INSERT_HEAD : \ + HID_BPF_FLAG_NONE, \ + NULL); \ + return 0; = \ + } = \ + static int __##name(arg) + +#define HID_BPF_DEVICE_EVENT(name, arg) __HID_BPF_PROG(HID_BPF_PROG_TYPE_D= EVICE_EVENT, name, arg) +#define HID_BPF_RDESC_FIXUP(name, arg) __HID_BPF_PROG(HID_BPF_PROG_TYPE_RD= ESC_FIXUP, name, arg) + #endif /* __HID_BPF_HELPERS_H */ --=20 2.44.0 From nobody Wed Dec 17 05:48:13 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 858557F495; Wed, 8 May 2024 10:27:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715164032; cv=none; b=DtuZGZ4YkEG9zu8IYQEvB1AwPYr5QKF+EdWOwbgs17nW8tvJwOGwSDeK6D/sQ5rDUxRtLiuCo7rAcNvFtPa/VY+iuAcnIa8bgisMP0ot6LegIo+T4sRf6/bCed9NytfuE1E3Qt/4x83RU4byckWM0Em0QAxnq91Cv/1JLTgps+U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715164032; c=relaxed/simple; bh=yRElYtxSrjJS1S+NuYjEj+esa/1rVxgpScohSpbdgc4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=fWAyETcBIN5i2jAw4CYkbn31fiNMg4FZteBaT6aULlPfpF6AAmgMl8HDum6R1+1sne0HoSyvCZEm0kGxII6HN2JA+82v9T7VrLIOaZOrVQKPLN9KM+bo8EMEAbFjJXkrIiHecz/TLShx6SspQ9zA8gEiFd8HahhfS2PxO0EuQy4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=dozZWbA7; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="dozZWbA7" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5DE6CC113CC; Wed, 8 May 2024 10:27:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1715164032; bh=yRElYtxSrjJS1S+NuYjEj+esa/1rVxgpScohSpbdgc4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=dozZWbA7Udmqltz21rs6/txk/ZyuLvUSu8sZRDh+dRSyzKSTqkbVtKGuTTG86S4eY DIarepV3ngCrtn81Nh8Xkv24kNr1aZ+9K61Sjx0Y2eKZ6vxW3FGu4HB/RXLL9xI9BS a2L5Oo6hHdzB5A8vYSaf77uUWsMkvUYTu0GuqmRVMAR6xv+hz9c3uXNwmBFfhquC8H AogVnRwvXefw2dvQSY45EZmiwezmAriUbDb8uPJNCZBQB+mVAfuP+kE8QxPHQuCajW olnycBuUP1ukhNGQvE+5JI5PfPbHQ79cjnKNVKmnSmuf5mJc2dagPREhbGLA0HPffg 9oaSkrhCJnzuQ== From: Benjamin Tissoires Date: Wed, 08 May 2024 12:26:38 +0200 Subject: [PATCH RFC HID 3/7] HID: bpf: allow for sleepable bpf hooks Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240508-hid_bpf_async_fun-v1-3-558375a25657@kernel.org> References: <20240508-hid_bpf_async_fun-v1-0-558375a25657@kernel.org> In-Reply-To: <20240508-hid_bpf_async_fun-v1-0-558375a25657@kernel.org> To: Benjamin Tissoires Cc: linux-kernel@vger.kernel.org, linux-input@vger.kernel.org, bpf@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=ed25519-sha256; t=1715164017; l=9599; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=yRElYtxSrjJS1S+NuYjEj+esa/1rVxgpScohSpbdgc4=; b=enS81y14TCoq9l82YaO3J5dTidgfDU+CWpMW7s6skXSuJy/PDKOlP6grCCEKVDcReW5YT7XOD ph5OhtvimcPC9c6inZB6SQyuYFN2kf91Jbpm+SVqmxNqCy7hpgJ/IL5 X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= Signed-off-by: Benjamin Tissoires --- drivers/hid/bpf/hid_bpf_dispatch.c | 111 ++++++++++++++++++++++----------= ---- drivers/hid/bpf/hid_bpf_dispatch.h | 4 +- drivers/hid/bpf/hid_bpf_jmp_table.c | 30 +++++++--- 3 files changed, 92 insertions(+), 53 deletions(-) diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_d= ispatch.c index 81073db6c617..7ede657f459b 100644 --- a/drivers/hid/bpf/hid_bpf_dispatch.c +++ b/drivers/hid/bpf/hid_bpf_dispatch.c @@ -70,7 +70,7 @@ dispatch_hid_bpf_device_event(struct hid_device *hdev, en= um hid_report_type type memset(ctx_kern.data, 0, hdev->bpf.allocated_data); memcpy(ctx_kern.data, data, *size); =20 - ret =3D hid_bpf_prog_run(hdev, HID_BPF_PROG_TYPE_DEVICE_EVENT, &ctx_kern); + ret =3D hid_bpf_prog_run(hdev, HID_BPF_PROG_TYPE_DEVICE_EVENT, &ctx_kern,= false); if (ret < 0) return ERR_PTR(ret); =20 @@ -122,7 +122,7 @@ u8 *call_hid_bpf_rdesc_fixup(struct hid_device *hdev, u= 8 *rdesc, unsigned int *s =20 memcpy(ctx_kern.data, rdesc, min_t(unsigned int, *size, HID_MAX_DESCRIPTO= R_SIZE)); =20 - ret =3D hid_bpf_prog_run(hdev, HID_BPF_PROG_TYPE_RDESC_FIXUP, &ctx_kern); + ret =3D hid_bpf_prog_run(hdev, HID_BPF_PROG_TYPE_RDESC_FIXUP, &ctx_kern, = false); if (ret < 0) goto ignore_bpf; =20 @@ -205,7 +205,7 @@ int hid_bpf_reconnect(struct hid_device *hdev) =20 static int do_hid_bpf_attach_prog(struct hid_device *hdev, enum hid_bpf_pr= og_type prog_type, hid_bpf_cb_t prog_fn, struct bpf_prog *prog, - __u32 flags) + __u32 flags, bool sleepable) { int fd, err; =20 @@ -213,7 +213,7 @@ static int do_hid_bpf_attach_prog(struct hid_device *hd= ev, enum hid_bpf_prog_typ if (err) return err; =20 - fd =3D __hid_bpf_attach_prog(hdev, prog_type, prog_fn, prog, flags); + fd =3D __hid_bpf_attach_prog(hdev, prog_type, prog_fn, prog, flags, sleep= able); if (fd < 0) return fd; =20 @@ -228,6 +228,56 @@ static int do_hid_bpf_attach_prog(struct hid_device *h= dev, enum hid_bpf_prog_typ return fd; } =20 +static int +hid_bpf_attach_prog(unsigned int hid_id, enum hid_bpf_prog_type prog_type, + hid_bpf_cb_t prog_fn, __u32 flags, void *prog__aux, + bool sleepable) +{ + struct bpf_prog_aux *aux =3D (struct bpf_prog_aux *)prog__aux; + struct bpf_prog *prog =3D aux->prog; + struct hid_device *hdev; + struct device *dev; + int err, fd; + + if (!hid_bpf_ops) + return -EINVAL; + + if ((flags & ~HID_BPF_FLAG_MASK)) + return -EINVAL; + + if (prog_type < 0 || prog_type >=3D HID_BPF_PROG_TYPE_MAX) + return -EINVAL; + + dev =3D bus_find_device(hid_bpf_ops->bus_type, NULL, &hid_id, device_matc= h_id); + if (!dev) + return -EINVAL; + + hdev =3D to_hid_device(dev); + + /* + * take a ref on the prog itself, it will be released + * on errors or when it'll be detached + */ + prog =3D bpf_prog_inc_not_zero(prog); + if (IS_ERR(prog)) { + err =3D PTR_ERR(prog); + goto out_dev_put; + } + + fd =3D do_hid_bpf_attach_prog(hdev, prog_type, prog_fn, prog, flags, slee= pable); + if (fd < 0) { + err =3D fd; + goto out_prog_put; + } + + return fd; + + out_prog_put: + bpf_prog_put(prog); + out_dev_put: + put_device(dev); + return err; +} /* Disables missing prototype warnings */ __bpf_kfunc_start_defs(); =20 @@ -272,50 +322,22 @@ __bpf_kfunc int hid_bpf_attach_prog_impl(unsigned int hid_id, enum hid_bpf_prog_type prog_= type, hid_bpf_cb_t prog_fn__async, __u32 flags, void *prog__aux) { - struct bpf_prog_aux *aux =3D (struct bpf_prog_aux *)prog__aux; - struct bpf_prog *prog =3D aux->prog; - struct hid_device *hdev; - struct device *dev; - int err, fd; - - if (!hid_bpf_ops) - return -EINVAL; - - if ((flags & ~HID_BPF_FLAG_MASK)) - return -EINVAL; - - if (prog_type < 0 || prog_type >=3D HID_BPF_PROG_TYPE_MAX) - return -EINVAL; + return hid_bpf_attach_prog(hid_id, prog_type, prog_fn__async, flags, prog= __aux, false); +} =20 - dev =3D bus_find_device(hid_bpf_ops->bus_type, NULL, &hid_id, device_matc= h_id); - if (!dev) +__bpf_kfunc int +hid_bpf_attach_sleepable_prog_impl(unsigned int hid_id, enum hid_bpf_prog_= type prog_type, + hid_bpf_cb_t prog_fn__s_async, __u32 flags, void *prog__aux) +{ + switch (prog_type) { + case HID_BPF_PROG_TYPE_RAW_REQUEST: + /* OK */ + break; + default: return -EINVAL; - - hdev =3D to_hid_device(dev); - - /* - * take a ref on the prog itself, it will be released - * on errors or when it'll be detached - */ - prog =3D bpf_prog_inc_not_zero(prog); - if (IS_ERR(prog)) { - err =3D PTR_ERR(prog); - goto out_dev_put; - } - - fd =3D do_hid_bpf_attach_prog(hdev, prog_type, prog_fn__async, prog, flag= s); - if (fd < 0) { - err =3D fd; - goto out_prog_put; } =20 - return fd; - - out_prog_put: - bpf_prog_put(prog); - out_dev_put: - put_device(dev); - return err; + return hid_bpf_attach_prog(hid_id, prog_type, prog_fn__s_async, flags, pr= og__aux, true); } =20 /** @@ -538,6 +560,7 @@ __bpf_kfunc_end_defs(); BTF_KFUNCS_START(hid_bpf_kfunc_ids) BTF_ID_FLAGS(func, hid_bpf_get_data, KF_RET_NULL) BTF_ID_FLAGS(func, hid_bpf_attach_prog_impl, KF_SLEEPABLE) +BTF_ID_FLAGS(func, hid_bpf_attach_sleepable_prog_impl, KF_SLEEPABLE) BTF_ID_FLAGS(func, hid_bpf_allocate_context, KF_ACQUIRE | KF_RET_NULL | KF= _SLEEPABLE) BTF_ID_FLAGS(func, hid_bpf_release_context, KF_RELEASE | KF_SLEEPABLE) BTF_ID_FLAGS(func, hid_bpf_hw_request, KF_SLEEPABLE) diff --git a/drivers/hid/bpf/hid_bpf_dispatch.h b/drivers/hid/bpf/hid_bpf_d= ispatch.h index 60455a2af216..f9833603e49f 100644 --- a/drivers/hid/bpf/hid_bpf_dispatch.h +++ b/drivers/hid/bpf/hid_bpf_dispatch.h @@ -14,10 +14,10 @@ typedef int (*hid_bpf_cb_t)(struct hid_bpf_ctx *hid_ctx= ); =20 int __hid_bpf_attach_prog(struct hid_device *hdev, enum hid_bpf_prog_type = prog_type, int (prog_fn__async)(struct hid_bpf_ctx *hid_ctx), - struct bpf_prog *prog, __u32 flags); + struct bpf_prog *prog, __u32 flags, bool sleepable); void __hid_bpf_destroy_device(struct hid_device *hdev); int hid_bpf_prog_run(struct hid_device *hdev, enum hid_bpf_prog_type type, - struct hid_bpf_ctx_kern *ctx_kern); + struct hid_bpf_ctx_kern *ctx_kern, bool is_sleepable); int hid_bpf_reconnect(struct hid_device *hdev); =20 struct bpf_prog; diff --git a/drivers/hid/bpf/hid_bpf_jmp_table.c b/drivers/hid/bpf/hid_bpf_= jmp_table.c index 8d53d41b599b..4cceff354962 100644 --- a/drivers/hid/bpf/hid_bpf_jmp_table.c +++ b/drivers/hid/bpf/hid_bpf_jmp_table.c @@ -39,6 +39,7 @@ struct hid_bpf_prog_entry { struct hid_bpf_prog_cb { struct bpf_prog *prog; void *fn; + bool sleepable; }; =20 struct hid_bpf_jmp_table { @@ -99,14 +100,20 @@ static int hid_bpf_program_count(struct hid_device *hd= ev, } =20 int hid_bpf_prog_run(struct hid_device *hdev, enum hid_bpf_prog_type type, - struct hid_bpf_ctx_kern *ctx_kern) + struct hid_bpf_ctx_kern *ctx_kern, bool is_sleepable) { struct hid_bpf_prog_list *prog_list; bpf_callback_t prog_fn; int i, idx, err =3D 0; =20 - rcu_read_lock(); - prog_list =3D rcu_dereference(hdev->bpf.progs[type]); + if (is_sleepable) { + prog_list =3D READ_ONCE(hdev->bpf.progs[type]); + rcu_read_lock_trace(); + might_fault(); + } else { + rcu_read_lock(); + prog_list =3D rcu_dereference(hdev->bpf.progs[type]); + } =20 if (!prog_list) goto out_unlock; @@ -117,6 +124,10 @@ int hid_bpf_prog_run(struct hid_device *hdev, enum hid= _bpf_prog_type type, if (!test_bit(idx, jmp_table.enabled)) continue; =20 + /* prevent a sleepable program to be run in a non sleepable context */ + if (!is_sleepable && jmp_table.prog_cbs[idx].sleepable) + continue; + ctx_kern->ctx.index =3D idx; prog_fn =3D jmp_table.prog_cbs[idx].fn; migrate_disable(); @@ -129,7 +140,10 @@ int hid_bpf_prog_run(struct hid_device *hdev, enum hid= _bpf_prog_type type, } =20 out_unlock: - rcu_read_unlock(); + if (is_sleepable) + rcu_read_unlock_trace(); + else + rcu_read_unlock(); =20 return err; } @@ -279,7 +293,7 @@ static void hid_bpf_release_progs(struct work_struct *w= ork) * Insert the given BPF program represented by its function call in the jm= p table. * Returns the index in the jump table or a negative error. */ -static int hid_bpf_insert_prog(struct bpf_prog *prog, hid_bpf_cb_t prog_fn) +static int hid_bpf_insert_prog(struct bpf_prog *prog, hid_bpf_cb_t prog_fn= , bool sleepable) { int i, index =3D -1, err =3D -EINVAL; =20 @@ -289,6 +303,7 @@ static int hid_bpf_insert_prog(struct bpf_prog *prog, h= id_bpf_cb_t prog_fn) /* mark the index as used */ jmp_table.prog_cbs[i].fn =3D prog_fn; jmp_table.prog_cbs[i].prog =3D prog; + jmp_table.prog_cbs[i].sleepable =3D sleepable; index =3D i; __set_bit(i, jmp_table.enabled); } @@ -340,7 +355,8 @@ static const struct bpf_link_ops hid_bpf_link_lops =3D { /* called from syscall */ noinline int __hid_bpf_attach_prog(struct hid_device *hdev, enum hid_bpf_prog_type prog= _type, - hid_bpf_cb_t prog_fn, struct bpf_prog *prog, __u32 flags) + hid_bpf_cb_t prog_fn, struct bpf_prog *prog, __u32 flags, + bool sleepable) { struct bpf_link_primer link_primer; struct hid_bpf_link *link; @@ -370,7 +386,7 @@ __hid_bpf_attach_prog(struct hid_device *hdev, enum hid= _bpf_prog_type prog_type, goto err_unlock; } =20 - prog_table_idx =3D hid_bpf_insert_prog(prog, prog_fn); + prog_table_idx =3D hid_bpf_insert_prog(prog, prog_fn, sleepable); /* if the jmp table is full, abort */ if (prog_table_idx < 0) { err =3D prog_table_idx; --=20 2.44.0 From nobody Wed Dec 17 05:48:13 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C2BBC7FBC3; Wed, 8 May 2024 10:27:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715164036; cv=none; b=Ey7TZAVIVYfcXqmmkeSR65Q+KM7zy/btPCEcItCA3TGP+vzzpSbgS9/48tIWKA6TL0EDKPj0Z5ms9x/U5EbtptvuWJyuC4arG/KhKRsY5+sPmirwNbVDTsiJkEloiaJzwPHzFKPxK41mBOBm0gHARfVY2OpDqypCfwfhyjrSkvI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715164036; c=relaxed/simple; bh=QftTIl+0wkJZCH+Lrp6cD6bPgP7GsHhL1DjA/BXgbXo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=sY3g906KzIHqlCzssbd9ykdU6kUGSOW/z9PoqEX1IPJMgR2AfNyh4vRSw6bn8Qzpk01BdGEUuRQwuki/Em8saloayijakKGNqfZ+XMS3PM0G3JCGodnOf0eR203KNdFzinBIk0yImuOSr5SiKJTxpdCZSaIddGwa4NJl/RVD/W8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=IWXo+zV3; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="IWXo+zV3" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D442CC113CC; Wed, 8 May 2024 10:27:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1715164036; bh=QftTIl+0wkJZCH+Lrp6cD6bPgP7GsHhL1DjA/BXgbXo=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=IWXo+zV3IUH4v68Mg7onrb8YXeW5h+vdC97PPkHMRMF/I1tnwON38S69ghDoUBps7 aiQK0/KYEkkb9KPcArT2KgyKhl6SsnG8W8YolHsSRDbQ0HrK92uhjQNS+8Ccspky56 jqxKwVBYFp598Kwspxo5d/Ede8YqykPK9l03M1/oCk1PMlb30IhZQrPCVznnt7xsiZ B3rsvuA6JElQBilXY075lX4QNmlWfIwp7h+G7QgfYhp9Xt1NR8aCITciRSIA27W4sR QYkP7Zc0OL+sOLaFo8Pmrk0pmmaU+LV7Q4KVX4ELxCXcPmlo2Tc9LfiMwKBxha83Nj 9IYyhvCDUlmqA== From: Benjamin Tissoires Date: Wed, 08 May 2024 12:26:39 +0200 Subject: [PATCH RFC HID 4/7] HID: add source argument to HID low level functions Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240508-hid_bpf_async_fun-v1-4-558375a25657@kernel.org> References: <20240508-hid_bpf_async_fun-v1-0-558375a25657@kernel.org> In-Reply-To: <20240508-hid_bpf_async_fun-v1-0-558375a25657@kernel.org> To: Benjamin Tissoires Cc: linux-kernel@vger.kernel.org, linux-input@vger.kernel.org, bpf@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=ed25519-sha256; t=1715164017; l=11681; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=QftTIl+0wkJZCH+Lrp6cD6bPgP7GsHhL1DjA/BXgbXo=; b=RtlkKlyG6QlTinCSzRb8csYtaUbWMKGHM0np5rqv0GpNR0O1JdYG69sKX2WIzIccmFb/+I5lI z3EJ4R7eGjJDKji7ofWNPbNVn0slLYdLwNNJKiMHXWkrFKsTlwZ1qUv X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= This allows to know who actually sent what when we process the request to the device. This will be useful for a BPF firewall program to allow or not requests coming from a dedicated hidraw node client. Signed-off-by: Benjamin Tissoires --- drivers/hid/bpf/hid_bpf_dispatch.c | 11 +++-- drivers/hid/hid-core.c | 85 ++++++++++++++++++++++++----------= ---- drivers/hid/hidraw.c | 10 ++--- include/linux/hid.h | 6 +++ include/linux/hid_bpf.h | 16 ++++--- 5 files changed, 81 insertions(+), 47 deletions(-) diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_d= ispatch.c index 7ede657f459b..55c9e74c2465 100644 --- a/drivers/hid/bpf/hid_bpf_dispatch.c +++ b/drivers/hid/bpf/hid_bpf_dispatch.c @@ -47,7 +47,7 @@ __weak noinline int hid_bpf_device_event(struct hid_bpf_c= tx *ctx) =20 u8 * dispatch_hid_bpf_device_event(struct hid_device *hdev, enum hid_report_typ= e type, u8 *data, - u32 *size, int interrupt) + u32 *size, int interrupt, u64 source) { struct hid_bpf_ctx_kern ctx_kern =3D { .ctx =3D { @@ -55,6 +55,7 @@ dispatch_hid_bpf_device_event(struct hid_device *hdev, en= um hid_report_type type .report_type =3D type, .allocated_size =3D hdev->bpf.allocated_data, .size =3D *size, + .source =3D source, }, .data =3D hdev->bpf.device_data, }; @@ -483,7 +484,8 @@ hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8 *buf, = size_t buf__sz, dma_data, size, rtype, - reqtype); + reqtype, + (__u64)ctx); =20 if (ret > 0) memcpy(buf, dma_data, ret); @@ -522,7 +524,8 @@ hid_bpf_hw_output_report(struct hid_bpf_ctx *ctx, __u8 = *buf, size_t buf__sz) =20 ret =3D hid_bpf_ops->hid_hw_output_report(hdev, dma_data, - size); + size, + (__u64)ctx); =20 kfree(dma_data); return ret; @@ -553,7 +556,7 @@ hid_bpf_input_report(struct hid_bpf_ctx *ctx, enum hid_= report_type type, u8 *buf =20 hdev =3D (struct hid_device *)ctx->hid; /* discard const */ =20 - return hid_bpf_ops->hid_input_report(hdev, type, buf, size, 0); + return hid_bpf_ops->hid_input_report(hdev, type, buf, size, 0, (__u64)ctx= ); } __bpf_kfunc_end_defs(); =20 diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index b1fa0378e8f4..b8414ce62e7b 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -2026,19 +2026,9 @@ int hid_report_raw_event(struct hid_device *hid, enu= m hid_report_type type, u8 * } EXPORT_SYMBOL_GPL(hid_report_raw_event); =20 -/** - * hid_input_report - report data from lower layer (usb, bt...) - * - * @hid: hid device - * @type: HID report type (HID_*_REPORT) - * @data: report contents - * @size: size of data parameter - * @interrupt: distinguish between interrupt and control transfers - * - * This is data entry for lower layers. - */ -int hid_input_report(struct hid_device *hid, enum hid_report_type type, u8= *data, u32 size, - int interrupt) + +static int __hid_input_report(struct hid_device *hid, enum hid_report_type= type, + u8 *data, u32 size, int interrupt, u64 source) { struct hid_report_enum *report_enum; struct hid_driver *hdrv; @@ -2058,7 +2048,7 @@ int hid_input_report(struct hid_device *hid, enum hid= _report_type type, u8 *data report_enum =3D hid->report_enum + type; hdrv =3D hid->driver; =20 - data =3D dispatch_hid_bpf_device_event(hid, type, data, &size, interrupt); + data =3D dispatch_hid_bpf_device_event(hid, type, data, &size, interrupt,= source); if (IS_ERR(data)) { ret =3D PTR_ERR(data); goto unlock; @@ -2093,6 +2083,23 @@ int hid_input_report(struct hid_device *hid, enum hi= d_report_type type, u8 *data up(&hid->driver_input_lock); return ret; } + +/** + * hid_input_report - report data from lower layer (usb, bt...) + * + * @hid: hid device + * @type: HID report type (HID_*_REPORT) + * @data: report contents + * @size: size of data parameter + * @interrupt: distinguish between interrupt and control transfers + * + * This is data entry for lower layers. + */ +int hid_input_report(struct hid_device *hid, enum hid_report_type type, u8= *data, u32 size, + int interrupt) +{ + return __hid_input_report(hid, type, data, size, interrupt, 0); +} EXPORT_SYMBOL_GPL(hid_input_report); =20 bool hid_match_one_id(const struct hid_device *hdev, @@ -2393,6 +2400,24 @@ void hid_hw_request(struct hid_device *hdev, } EXPORT_SYMBOL_GPL(hid_hw_request); =20 +int __hid_hw_raw_request(struct hid_device *hdev, + unsigned char reportnum, __u8 *buf, + size_t len, enum hid_report_type rtype, + enum hid_class_request reqtype, + __u64 source) +{ + unsigned int max_buffer_size =3D HID_MAX_BUFFER_SIZE; + + if (hdev->ll_driver->max_buffer_size) + max_buffer_size =3D hdev->ll_driver->max_buffer_size; + + if (len < 1 || len > max_buffer_size || !buf) + return -EINVAL; + + return hdev->ll_driver->raw_request(hdev, reportnum, buf, len, + rtype, reqtype); +} + /** * hid_hw_raw_request - send report request to device * @@ -2410,6 +2435,12 @@ EXPORT_SYMBOL_GPL(hid_hw_request); int hid_hw_raw_request(struct hid_device *hdev, unsigned char reportnum, __u8 *buf, size_t len, enum hid_report_type rtype, enum hid_class_request re= qtype) +{ + return __hid_hw_raw_request(hdev, reportnum, buf, len, rtype, reqtype, 0); +} +EXPORT_SYMBOL_GPL(hid_hw_raw_request); + +int __hid_hw_output_report(struct hid_device *hdev, __u8 *buf, size_t len,= __u64 source) { unsigned int max_buffer_size =3D HID_MAX_BUFFER_SIZE; =20 @@ -2419,10 +2450,11 @@ int hid_hw_raw_request(struct hid_device *hdev, if (len < 1 || len > max_buffer_size || !buf) return -EINVAL; =20 - return hdev->ll_driver->raw_request(hdev, reportnum, buf, len, - rtype, reqtype); + if (hdev->ll_driver->output_report) + return hdev->ll_driver->output_report(hdev, buf, len); + + return -ENOSYS; } -EXPORT_SYMBOL_GPL(hid_hw_raw_request); =20 /** * hid_hw_output_report - send output report to device @@ -2435,18 +2467,7 @@ EXPORT_SYMBOL_GPL(hid_hw_raw_request); */ int hid_hw_output_report(struct hid_device *hdev, __u8 *buf, size_t len) { - unsigned int max_buffer_size =3D HID_MAX_BUFFER_SIZE; - - if (hdev->ll_driver->max_buffer_size) - max_buffer_size =3D hdev->ll_driver->max_buffer_size; - - if (len < 1 || len > max_buffer_size || !buf) - return -EINVAL; - - if (hdev->ll_driver->output_report) - return hdev->ll_driver->output_report(hdev, buf, len); - - return -ENOSYS; + return __hid_hw_output_report(hdev, buf, len, 0); } EXPORT_SYMBOL_GPL(hid_hw_output_report); =20 @@ -2973,9 +2994,9 @@ EXPORT_SYMBOL_GPL(hid_check_keys_pressed); #ifdef CONFIG_HID_BPF static struct hid_bpf_ops hid_ops =3D { .hid_get_report =3D hid_get_report, - .hid_hw_raw_request =3D hid_hw_raw_request, - .hid_hw_output_report =3D hid_hw_output_report, - .hid_input_report =3D hid_input_report, + .hid_hw_raw_request =3D __hid_hw_raw_request, + .hid_hw_output_report =3D __hid_hw_output_report, + .hid_input_report =3D __hid_input_report, .owner =3D THIS_MODULE, .bus_type =3D &hid_bus_type, }; diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index 2bc762d31ac7..6d2a6d38e42a 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c @@ -140,7 +140,7 @@ static ssize_t hidraw_send_report(struct file *file, co= nst char __user *buffer, =20 if ((report_type =3D=3D HID_OUTPUT_REPORT) && !(dev->quirks & HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP)) { - ret =3D hid_hw_output_report(dev, buf, count); + ret =3D __hid_hw_output_report(dev, buf, count, (__u64)file); /* * compatibility with old implementation of USB-HID and I2C-HID: * if the device does not support receiving output reports, @@ -150,8 +150,8 @@ static ssize_t hidraw_send_report(struct file *file, co= nst char __user *buffer, goto out_free; } =20 - ret =3D hid_hw_raw_request(dev, buf[0], buf, count, report_type, - HID_REQ_SET_REPORT); + ret =3D __hid_hw_raw_request(dev, buf[0], buf, count, report_type, + HID_REQ_SET_REPORT, (__u64)file); =20 out_free: kfree(buf); @@ -227,8 +227,8 @@ static ssize_t hidraw_get_report(struct file *file, cha= r __user *buffer, size_t goto out_free; } =20 - ret =3D hid_hw_raw_request(dev, report_number, buf, count, report_type, - HID_REQ_GET_REPORT); + ret =3D __hid_hw_raw_request(dev, report_number, buf, count, report_type, + HID_REQ_GET_REPORT, (__u64)file); =20 if (ret < 0) goto out_free; diff --git a/include/linux/hid.h b/include/linux/hid.h index 8e06d89698e6..dac2804b4562 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -1125,6 +1125,12 @@ int __must_check hid_hw_open(struct hid_device *hdev= ); void hid_hw_close(struct hid_device *hdev); void hid_hw_request(struct hid_device *hdev, struct hid_report *report, enum hid_class_request reqtype); +int __hid_hw_raw_request(struct hid_device *hdev, + unsigned char reportnum, __u8 *buf, + size_t len, enum hid_report_type rtype, + enum hid_class_request reqtype, + __u64 source); +int __hid_hw_output_report(struct hid_device *hdev, __u8 *buf, size_t len,= __u64 source); int hid_hw_raw_request(struct hid_device *hdev, unsigned char reportnum, __u8 *buf, size_t len, enum hid_report_type rtype, diff --git a/include/linux/hid_bpf.h b/include/linux/hid_bpf.h index 99ebe7bbb02a..6bcaf19f1cc2 100644 --- a/include/linux/hid_bpf.h +++ b/include/linux/hid_bpf.h @@ -48,8 +48,9 @@ struct hid_device; */ struct hid_bpf_ctx { __u32 index; - const struct hid_device *hid; __u32 allocated_size; + __u64 source; + const struct hid_device *hid; enum hid_report_type report_type; union { __s32 retval; @@ -99,10 +100,12 @@ struct hid_bpf_ops { int (*hid_hw_raw_request)(struct hid_device *hdev, unsigned char reportnum, __u8 *buf, size_t len, enum hid_report_type rtype, - enum hid_class_request reqtype); - int (*hid_hw_output_report)(struct hid_device *hdev, __u8 *buf, size_t le= n); + enum hid_class_request reqtype, + __u64 source); + int (*hid_hw_output_report)(struct hid_device *hdev, __u8 *buf, size_t le= n, + __u64 source); int (*hid_input_report)(struct hid_device *hid, enum hid_report_type type, - u8 *data, u32 size, int interrupt); + u8 *data, u32 size, int interrupt, u64 source); struct module *owner; const struct bus_type *bus_type; }; @@ -136,7 +139,7 @@ struct hid_bpf_link { =20 #ifdef CONFIG_HID_BPF u8 *dispatch_hid_bpf_device_event(struct hid_device *hid, enum hid_report_= type type, u8 *data, - u32 *size, int interrupt); + u32 *size, int interrupt, u64 source); int hid_bpf_connect_device(struct hid_device *hdev); void hid_bpf_disconnect_device(struct hid_device *hdev); void hid_bpf_destroy_device(struct hid_device *hid); @@ -144,7 +147,8 @@ void hid_bpf_device_init(struct hid_device *hid); u8 *call_hid_bpf_rdesc_fixup(struct hid_device *hdev, u8 *rdesc, unsigned = int *size); #else /* CONFIG_HID_BPF */ static inline u8 *dispatch_hid_bpf_device_event(struct hid_device *hid, en= um hid_report_type type, - u8 *data, u32 *size, int interrupt) { return data; } + u8 *data, u32 *size, int interrupt, + u64 source) { return data; } static inline int hid_bpf_connect_device(struct hid_device *hdev) { return= 0; } static inline void hid_bpf_disconnect_device(struct hid_device *hdev) {} static inline void hid_bpf_destroy_device(struct hid_device *hid) {} --=20 2.44.0 From nobody Wed Dec 17 05:48:13 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C5A027E0E8; Wed, 8 May 2024 10:27:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715164040; cv=none; b=atvHGMBNG/2u74C/F4zWgCmbiT5DHW7W54nt1CodldYPzmifW7lExF0XwfxKHya1PSLOUPHw91yjYo1w3JPjUDFFWZ2ODMc+ui9zoPkZeei8g3BaouGZmrxeaWRbAWDB5UoIBCjMtsOuEIJ7Cc9u6p6+UPmUonzHt0JNXX9EHBg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715164040; c=relaxed/simple; bh=txXRaEv7XsztZIwd1QMmXQ5xKR9I4Ul3ciQ/A1mmLcA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=WV5/6LRgqDPXd4oQ5FkMBaqKNQ6ftPK5mjAZeLoCaGF0d3A1njyZloNehLS3/64WvUrQBt7hFQ91VYdJw1b2R6zRMDn0WKUQbxsNjGSfrrMAJz7jf9NhfxINUFhR0Bh133spM3zzKFsoKT+fxaMxdoJamkqaiIWrcxYjKow2xkg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=L2QLi5fR; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="L2QLi5fR" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D41BCC4AF18; Wed, 8 May 2024 10:27:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1715164039; bh=txXRaEv7XsztZIwd1QMmXQ5xKR9I4Ul3ciQ/A1mmLcA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=L2QLi5fRZV/71Rjv1JJblXbwrMhWq9Vy3QlW3Ly4C9Z/PYBrfEhepzmVpw0j/gF50 SPPzN5oKGK1mHB5QBzzTos/oFhDQcVZ+9jsCIJU6ynNs+ZbrgwkSZ6y2Hp8eh6pBna 4IzVLtT9RQCgPYnMzbhFdFqpkZQBxWyGcrHOg5Z5Zh7z+ask5bz+IWKhh5xsJ/3Dck fNVk0lIHrxmlLlWHIr6aPG/VRUvXa8Wc4oWb2tKwPvkHxHSQQ6DVfL38xFaGXvQrQ8 GQJfsX8W/8vtlJMpHN64s0trzmEjTYUIzFJWyu9q6Oul9l0DwWpA8En8XFkLEGEFXE Te0XxqfDvQbvg== From: Benjamin Tissoires Date: Wed, 08 May 2024 12:26:40 +0200 Subject: [PATCH RFC HID 5/7] WIP: add HID-BPF hooks for hid_hw_raw_requests Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240508-hid_bpf_async_fun-v1-5-558375a25657@kernel.org> References: <20240508-hid_bpf_async_fun-v1-0-558375a25657@kernel.org> In-Reply-To: <20240508-hid_bpf_async_fun-v1-0-558375a25657@kernel.org> To: Benjamin Tissoires Cc: linux-kernel@vger.kernel.org, linux-input@vger.kernel.org, bpf@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=ed25519-sha256; t=1715164017; l=6301; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=txXRaEv7XsztZIwd1QMmXQ5xKR9I4Ul3ciQ/A1mmLcA=; b=L5vkE3xhw8Z/gzOf0YnEwlQX83vc50UzQR01r/jIQk8ZrQryPIXJGR8MxbYYKFaR2ous+QCEl PuOab/R8o2YBSEdLwWKb51LeHgojBUF6LLf8e7gW4Yzq3xO30BW163u X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= --- drivers/hid/bpf/hid_bpf_dispatch.c | 51 +++++++++++++++++++++++++++++++++= ++++ drivers/hid/bpf/hid_bpf_jmp_table.c | 1 + drivers/hid/hid-core.c | 8 +++++- include/linux/hid_bpf.h | 14 ++++++++++ 4 files changed, 73 insertions(+), 1 deletion(-) diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_d= ispatch.c index 55c9e74c2465..7aeab3f9f2c7 100644 --- a/drivers/hid/bpf/hid_bpf_dispatch.c +++ b/drivers/hid/bpf/hid_bpf_dispatch.c @@ -45,6 +45,11 @@ __weak noinline int hid_bpf_device_event(struct hid_bpf_= ctx *ctx) return 0; } =20 +__weak noinline int hid_bpf_raw_request(struct hid_bpf_ctx *ctx) +{ + return 0; +} + u8 * dispatch_hid_bpf_device_event(struct hid_device *hdev, enum hid_report_typ= e type, u8 *data, u32 *size, int interrupt, u64 source) @@ -71,6 +76,9 @@ dispatch_hid_bpf_device_event(struct hid_device *hdev, en= um hid_report_type type memset(ctx_kern.data, 0, hdev->bpf.allocated_data); memcpy(ctx_kern.data, data, *size); =20 + if (*size) + ctx_kern.ctx.reportnum =3D data[0]; + ret =3D hid_bpf_prog_run(hdev, HID_BPF_PROG_TYPE_DEVICE_EVENT, &ctx_kern,= false); if (ret < 0) return ERR_PTR(ret); @@ -86,6 +94,49 @@ dispatch_hid_bpf_device_event(struct hid_device *hdev, e= num hid_report_type type } EXPORT_SYMBOL_GPL(dispatch_hid_bpf_device_event); =20 +u8 * +dispatch_hid_bpf_raw_requests(struct hid_device *hdev, + unsigned char reportnum, u8 *buf, + u32 *size, enum hid_report_type rtype, + enum hid_class_request reqtype, + u64 source) +{ + struct hid_bpf_ctx_kern ctx_kern =3D { + .ctx =3D { + .hid =3D hdev, + .report_type =3D rtype, + .reqtype =3D reqtype, + .allocated_size =3D *size, + .size =3D *size, + .source =3D source, + .reportnum =3D reportnum, + }, + .data =3D buf, + }; + int ret; + + if (rtype >=3D HID_REPORT_TYPES) + return ERR_PTR(-EINVAL); + + /* no program has been attached yet */ + // if (!hdev->bpf.device_data) + // return buf; + + ret =3D hid_bpf_prog_run(hdev, HID_BPF_PROG_TYPE_RAW_REQUEST, &ctx_kern, = true); + if (ret < 0) + return ERR_PTR(ret); + + if (ret) { + if (ret > ctx_kern.ctx.allocated_size) + return ERR_PTR(-EINVAL); + + *size =3D ret; + } + + return ctx_kern.data; +} +EXPORT_SYMBOL_GPL(dispatch_hid_bpf_raw_requests); + /** * hid_bpf_rdesc_fixup - Called when the probe function parses the report * descriptor of the HID device diff --git a/drivers/hid/bpf/hid_bpf_jmp_table.c b/drivers/hid/bpf/hid_bpf_= jmp_table.c index 4cceff354962..e183dc2835c7 100644 --- a/drivers/hid/bpf/hid_bpf_jmp_table.c +++ b/drivers/hid/bpf/hid_bpf_jmp_table.c @@ -64,6 +64,7 @@ static int hid_bpf_max_programs(enum hid_bpf_prog_type ty= pe) { switch (type) { case HID_BPF_PROG_TYPE_DEVICE_EVENT: + case HID_BPF_PROG_TYPE_RAW_REQUEST: return HID_BPF_MAX_PROGS_PER_DEV; case HID_BPF_PROG_TYPE_RDESC_FIXUP: return 1; diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index b8414ce62e7b..7d468f6dbefe 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -2407,6 +2407,7 @@ int __hid_hw_raw_request(struct hid_device *hdev, __u64 source) { unsigned int max_buffer_size =3D HID_MAX_BUFFER_SIZE; + u32 size =3D (u32)len; /* max_buffer_size is 16 KB */ =20 if (hdev->ll_driver->max_buffer_size) max_buffer_size =3D hdev->ll_driver->max_buffer_size; @@ -2414,7 +2415,12 @@ int __hid_hw_raw_request(struct hid_device *hdev, if (len < 1 || len > max_buffer_size || !buf) return -EINVAL; =20 - return hdev->ll_driver->raw_request(hdev, reportnum, buf, len, + buf =3D dispatch_hid_bpf_raw_requests(hdev, reportnum, buf, &size, rtype, + reqtype, source); + if (IS_ERR(buf)) + return PTR_ERR(buf); + + return hdev->ll_driver->raw_request(hdev, reportnum, buf, size, rtype, reqtype); } =20 diff --git a/include/linux/hid_bpf.h b/include/linux/hid_bpf.h index 6bcaf19f1cc2..1cd36bfdd608 100644 --- a/include/linux/hid_bpf.h +++ b/include/linux/hid_bpf.h @@ -52,10 +52,12 @@ struct hid_bpf_ctx { __u64 source; const struct hid_device *hid; enum hid_report_type report_type; + enum hid_class_request reqtype; /* for HID_BPF_PROG_TYPE_RAW_REQUEST */ union { __s32 retval; __s32 size; }; + __u8 reportnum; }; =20 /** @@ -77,6 +79,7 @@ enum hid_bpf_attach_flags { /* Following functions are tracepoints that BPF programs can attach to */ int hid_bpf_device_event(struct hid_bpf_ctx *ctx); int hid_bpf_rdesc_fixup(struct hid_bpf_ctx *ctx); +int hid_bpf_raw_request(struct hid_bpf_ctx *ctx); =20 /* * Below is HID internal @@ -90,6 +93,7 @@ enum hid_bpf_prog_type { HID_BPF_PROG_TYPE_UNDEF =3D -1, HID_BPF_PROG_TYPE_DEVICE_EVENT, /* an event is emitted from the device = */ HID_BPF_PROG_TYPE_RDESC_FIXUP, + HID_BPF_PROG_TYPE_RAW_REQUEST, HID_BPF_PROG_TYPE_MAX, }; =20 @@ -140,6 +144,11 @@ struct hid_bpf_link { #ifdef CONFIG_HID_BPF u8 *dispatch_hid_bpf_device_event(struct hid_device *hid, enum hid_report_= type type, u8 *data, u32 *size, int interrupt, u64 source); +u8 *dispatch_hid_bpf_raw_requests(struct hid_device *hdev, + unsigned char reportnum, __u8 *buf, + u32 *size, enum hid_report_type rtype, + enum hid_class_request reqtype, + __u64 source); int hid_bpf_connect_device(struct hid_device *hdev); void hid_bpf_disconnect_device(struct hid_device *hdev); void hid_bpf_destroy_device(struct hid_device *hid); @@ -149,6 +158,11 @@ u8 *call_hid_bpf_rdesc_fixup(struct hid_device *hdev, = u8 *rdesc, unsigned int *s static inline u8 *dispatch_hid_bpf_device_event(struct hid_device *hid, en= um hid_report_type type, u8 *data, u32 *size, int interrupt, u64 source) { return data; } +static inline u8 *dispatch_hid_bpf_raw_requests(struct hid_device *hdev, + unsigned char reportnum, u8 *buf, + u32 *size, enum hid_report_type rtype, + enum hid_class_request reqtype, + u64 source) { return buf; } static inline int hid_bpf_connect_device(struct hid_device *hdev) { return= 0; } static inline void hid_bpf_disconnect_device(struct hid_device *hdev) {} static inline void hid_bpf_destroy_device(struct hid_device *hid) {} --=20 2.44.0 From nobody Wed Dec 17 05:48:13 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A913180BE3; Wed, 8 May 2024 10:27:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715164043; cv=none; b=mT0Nw1tDFSKbbbgXPhH0m/208SMrOho6z4Dt51jng8mWVExDXTkLhl7QOxraMrTIeOj8c/WcJVHeQ8R/mGdt51F3iSALeUglm1AQM2NvDJ33mrolpknBdnAbfN7Oi5CPX8uffX9bLJjz490I7oztGjcS0MpV1vItTr7k8vFb0so= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715164043; c=relaxed/simple; bh=9waEZf/wX6l7KSv3TGWZ2a108xaQGTbk2eaVsTu2CFc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZQpotUruvX8iUNP6wd9/va9LAU2snu+fKPWwXlkQLM3CvRcRyi+sMr34mXEP7ANwStPu8dOlCB77DGBPZxN61Vv1DIv9x14jCQgD9W0ob2RtJi0geQ0Vaf29NF51kXLFZuTfZiRzjT5Sr/5D3GBiU3NIrdE4hgUIW8BGvWjjtzg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=twAoqDhV; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="twAoqDhV" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 45CCBC113CC; Wed, 8 May 2024 10:27:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1715164043; bh=9waEZf/wX6l7KSv3TGWZ2a108xaQGTbk2eaVsTu2CFc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=twAoqDhVc6j+5cG9bW/+SnuFXZ3pnTIo2y+Gk+ayDG0rjPn4uPRlGk2H9ojZ2RPHf jC5xlsET5/XMxYps4uA2N8IVhKu8/8S+H6n7qWZXavKTVQ8DLwNqB58gPV4xM3ebH/ iYuONRYgXYBbmhLI/pPziCOnwqiY9UL/salBWxBSoXJBH89rm0DpZNmREPoZS+XAti yKLp/URvcrbf/hs6PkyB8689xqahuHt4dDHjRz5b/oc3+FRjvu05k12cNTlUbY2R9p oZ/OspzoWTtshJiljk7jVX6+kxivQUE+QKyFd7Rpz21/hWYuCKbXPXdd7BYqxG5Ze5 xagE4OLoPb6jA== From: Benjamin Tissoires Date: Wed, 08 May 2024 12:26:41 +0200 Subject: [PATCH RFC HID 6/7] WIP: selftests/hid: add tests for hid_hw_raw_request HID-BPF hooks Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240508-hid_bpf_async_fun-v1-6-558375a25657@kernel.org> References: <20240508-hid_bpf_async_fun-v1-0-558375a25657@kernel.org> In-Reply-To: <20240508-hid_bpf_async_fun-v1-0-558375a25657@kernel.org> To: Benjamin Tissoires Cc: linux-kernel@vger.kernel.org, linux-input@vger.kernel.org, bpf@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=ed25519-sha256; t=1715164017; l=8381; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=9waEZf/wX6l7KSv3TGWZ2a108xaQGTbk2eaVsTu2CFc=; b=HYLnB3YF5tVYYctI5AVxJ0cl2CSHeXhATB4kXQdS4os/a2n8SPgf/9Ta30cNl2pc2X4p1Y5yK DshsY4hqrQHDCHCd0UR+0sFqMypD9zTVGD6HxnBy1EzEVrqUA7uFCNJ X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= Signed-off-by: Benjamin Tissoires --- tools/testing/selftests/hid/hid_bpf.c | 55 ++++++++++++++++++= ++++ tools/testing/selftests/hid/progs/hid.c | 51 ++++++++++++++++++= ++ .../testing/selftests/hid/progs/hid_bpf_helpers.h | 39 +++++++++------ 3 files changed, 130 insertions(+), 15 deletions(-) diff --git a/tools/testing/selftests/hid/hid_bpf.c b/tools/testing/selftest= s/hid/hid_bpf.c index 7fed9f599b62..522fc32a5c38 100644 --- a/tools/testing/selftests/hid/hid_bpf.c +++ b/tools/testing/selftests/hid/hid_bpf.c @@ -469,6 +469,8 @@ static void detach_bpf(FIXTURE_DATA(hid_bpf) * self) close(self->hidraw_fd); self->hidraw_fd =3D 0; =20 + // hid__detach(self->skel); + for (i =3D 0; i < ARRAY_SIZE(self->hid_links); i++) { if (self->hid_links[i]) close(self->hid_links[i]); @@ -572,6 +574,8 @@ static void load_programs(const struct test_program pro= grams[], self->hid_links[i] =3D args.retval; } =20 + // hid__attach(self->skel); + self->hidraw_fd =3D open_hidraw(self->dev_id); ASSERT_GE(self->hidraw_fd, 0) TH_LOG("open_hidraw"); } @@ -871,6 +875,57 @@ TEST_F(hid_bpf, test_hid_user_raw_request_call) ASSERT_EQ(args.data[1], 2); } =20 +/* + * Call hid_hw_raw_request against the given uhid device, + * check that the program is called and does the expected. + */ +TEST_F(hid_bpf, test_hid_filter_raw_request_call) +{ + const struct test_program progs[] =3D { + { .name =3D "hid_test_filter_raw_request" }, + { .name =3D "hid_test_raw_request" }, + }; + __u8 buf[10] =3D {0}; + int err; + + LOAD_PROGRAMS(progs); + + /* first check that we did not attach to device_event */ + + /* inject one event */ + buf[0] =3D 1; + buf[1] =3D 42; + uhid_send_event(_metadata, self->uhid_fd, buf, 6); + + /* read the data from hidraw */ + memset(buf, 0, sizeof(buf)); + err =3D read(self->hidraw_fd, buf, sizeof(buf)); + ASSERT_EQ(err, 6) TH_LOG("read_hidraw"); + ASSERT_EQ(buf[0], 1); + ASSERT_EQ(buf[1], 42); + ASSERT_EQ(buf[2], 0) TH_LOG("leftovers_from_previous_test"); + + /* now check that our program is preventing hid_hw_raw_request() */ + + /* emit hid_hw_raw_request from hidraw */ + /* Get Feature */ + memset(buf, 0, sizeof(buf)); + buf[0] =3D 0x1; /* Report Number */ + err =3D ioctl(self->hidraw_fd, HIDIOCGFEATURE(sizeof(buf)), buf); + ASSERT_LT(err, 0) TH_LOG("unexpected success while reading HIDIOCGFEATURE= : %d", err); + + /* remove our bpf program and check that we can now emit commands */ + + /* detach the program */ + detach_bpf(self); + + self->hidraw_fd =3D open_hidraw(self->dev_id); + ASSERT_GE(self->hidraw_fd, 0) TH_LOG("open_hidraw"); + + err =3D ioctl(self->hidraw_fd, HIDIOCGFEATURE(sizeof(buf)), buf); + ASSERT_GE(err, 0) TH_LOG("error while reading HIDIOCGFEATURE: %d", err); +} + /* * Attach hid_insert{0,1,2} to the given uhid device, * retrieve and open the matching hidraw node, diff --git a/tools/testing/selftests/hid/progs/hid.c b/tools/testing/selfte= sts/hid/progs/hid.c index b721d1256836..64aaa279bec4 100644 --- a/tools/testing/selftests/hid/progs/hid.c +++ b/tools/testing/selftests/hid/progs/hid.c @@ -226,3 +226,54 @@ HID_BPF_DEVICE_EVENT(hid_test_insert3, struct hid_bpf_= ctx *hid_ctx) =20 return 0; } + +// SEC("fentry/hidraw_open") +// int BPF_PROG(hidraw_open, struct inode *inode, struct file *file) +// { +// bpf_printk("inode: %llx, file: %llx", (u64)inode, (u64)file); +// return 0; +// } + +HID_BPF_RAW_REQUEST(hid_test_filter_raw_request, struct hid_bpf_ctx *hctx) +{ + bpf_printk("in %s:%d", __func__, __LINE__); + return 0; +} + +HID_BPF_SLEEPABLE_RAW_REQUEST(hid_test_raw_request, struct hid_bpf_ctx *hc= tx) +{ + struct test_report buf =3D { + .data =3D {2, 3, 4, 5, 6, 7}, + }; + __u8 *data =3D hid_bpf_get_data(hctx, 0 /* offset */, 2 /* size */); + int ret; + + bpf_printk("in %s, hctx: %llx source: %llx", __func__, (u64)hctx, hctx->s= ource); + + if (!data) + return 0; /* EPERM check */ + bpf_printk("in %s:%d", __func__, __LINE__); + + if (hctx->source) { + hid_bpf_input_report(hctx, HID_INPUT_REPORT, buf.data, sizeof(buf.data)); + + /* still forward the request as-is to the device, hid-bpf will not + * call us again. + */ + + data[0] =3D hctx->reportnum; + + ret =3D hid_bpf_hw_request(hctx, + data, + 2, + hctx->report_type, + hctx->reqtype); + bpf_printk("ret: %d", ret); + if (ret) + return ret; + return -1; + } + + bpf_printk("in %s:%d", __func__, __LINE__); + return 0; +} diff --git a/tools/testing/selftests/hid/progs/hid_bpf_helpers.h b/tools/te= sting/selftests/hid/progs/hid_bpf_helpers.h index 9826880e88d1..779ec151c717 100644 --- a/tools/testing/selftests/hid/progs/hid_bpf_helpers.h +++ b/tools/testing/selftests/hid/progs/hid_bpf_helpers.h @@ -56,17 +56,6 @@ enum hid_report_type { HID_REPORT_TYPES, }; =20 -struct hid_bpf_ctx { - __u32 index; - const struct hid_device *hid; - __u32 allocated_size; - enum hid_report_type report_type; - union { - __s32 retval; - __s32 size; - }; -} __attribute__((preserve_access_index)); - enum hid_class_request { HID_REQ_GET_REPORT =3D 0x01, HID_REQ_GET_IDLE =3D 0x02, @@ -88,6 +77,20 @@ struct attach_prog_args { int insert_head; }; =20 +struct hid_bpf_ctx { + __u32 index; + __u32 allocated_size; + __u64 source; + const struct hid_device *hid; + enum hid_report_type report_type; + enum hid_class_request reqtype; /* for HID_BPF_PROG_TYPE_RAW_REQUEST */ + union { + __s32 retval; + __s32 size; + }; + __u8 reportnum; +} __attribute__((preserve_access_index)); + /* following are kfuncs exported by HID for HID-BPF */ extern __u8 *hid_bpf_get_data(struct hid_bpf_ctx *ctx, unsigned int offset, @@ -96,6 +99,10 @@ extern int hid_bpf_attach_prog_impl(unsigned int hid_id, enum hid_bpf_prog_type type, int (prog_fn)(struct hid_bpf_ctx *hid_ctx), u32 flags, void *aux) __ksym; +extern int hid_bpf_attach_sleepable_prog_impl(unsigned int hid_id, + enum hid_bpf_prog_type type, + int (prog_fn)(struct hid_bpf_ctx *hid_ctx), + u32 flags, void *aux) __ksym; extern struct hid_bpf_ctx *hid_bpf_allocate_context(unsigned int hid_id) _= _ksym; extern void hid_bpf_release_context(struct hid_bpf_ctx *ctx) __ksym; extern int hid_bpf_hw_request(struct hid_bpf_ctx *ctx, @@ -110,12 +117,12 @@ extern int hid_bpf_input_report(struct hid_bpf_ctx *c= tx, __u8 *data, size_t buf__sz) __ksym; =20 -#define __HID_BPF_PROG(type, name, arg) = \ +#define __HID_BPF_PROG(type, name, arg, sleepable) = \ static int __##name(arg); = \ SEC("syscall") = \ int name(struct attach_prog_args *ctx) = \ { = \ - ctx->retval =3D hid_bpf_attach_prog_impl(ctx->hid, = \ + ctx->retval =3D hid_bpf_attach_##sleepable##prog_impl(ctx->hid, = \ type, \ __##name, \ ctx->insert_head ? HID_BPF_FLAG_INSERT_HEAD : \ @@ -125,7 +132,9 @@ extern int hid_bpf_input_report(struct hid_bpf_ctx *ctx, } = \ static int __##name(arg) =20 -#define HID_BPF_DEVICE_EVENT(name, arg) __HID_BPF_PROG(HID_BPF_PROG_TYPE_D= EVICE_EVENT, name, arg) -#define HID_BPF_RDESC_FIXUP(name, arg) __HID_BPF_PROG(HID_BPF_PROG_TYPE_RD= ESC_FIXUP, name, arg) +#define HID_BPF_DEVICE_EVENT(name, arg) __HID_BPF_PROG(HID_BPF_PROG_TYPE_D= EVICE_EVENT, name, arg, ) +#define HID_BPF_RDESC_FIXUP(name, arg) __HID_BPF_PROG(HID_BPF_PROG_TYPE_RD= ESC_FIXUP, name, arg, ) +#define HID_BPF_RAW_REQUEST(name, arg) __HID_BPF_PROG(HID_BPF_PROG_TYPE_RA= W_REQUEST, name, arg, ) +#define HID_BPF_SLEEPABLE_RAW_REQUEST(name, arg) __HID_BPF_PROG(HID_BPF_PR= OG_TYPE_RAW_REQUEST, name, arg, sleepable_) =20 #endif /* __HID_BPF_HELPERS_H */ --=20 2.44.0 From nobody Wed Dec 17 05:48:13 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4D9D981205; Wed, 8 May 2024 10:27:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715164047; cv=none; b=dHEpGDOvhKDKVT4xYZqpgRiywgsliYblr7/i+aSd1zFeUcXpy1utrnqaj2ykJ8wtXaIkEtYT4pAhonMvBj6Wc1dSLxhQDyIrrnxKTVEXYUIla534nS7gBmI/5knM8bvzd/cjhSfOS8XhkhHIGzkGe+1SlIMlwF8UepR5Mo9fKlw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715164047; c=relaxed/simple; bh=gUKFJUJPIS9WSId/kAlnSuXYsqfcoTxB16GBAeCmvtM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=iBKS7nZbMkrmCtTMRKHWUj5Sr1rhNOylokKVymU7G4886rF7RLBFcjAAT298uf+nf/wD9GgQycWQwso4wIekCKLUJWemmOZOtsZrH/CPQq0iKhDmt2J362JhSjqMuY2rOGXL6WR+X7waHyr00M0HZsFELFthgwh1WwGUVxKYag8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=BW/Vy9Ib; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="BW/Vy9Ib" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E2C82C113CC; Wed, 8 May 2024 10:27:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1715164046; bh=gUKFJUJPIS9WSId/kAlnSuXYsqfcoTxB16GBAeCmvtM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=BW/Vy9IbQHb6Xu1wRBvlOofA1YOU0lJykkWaritCmqUuu82LaZPvVSmzavHJHYAGv KJ5e5cVTv51gGM8WAgzeyss9pf7Y+bKSe/O4h1YJzKVmRdU33YNxSYvrYmaTXaC85M 31PQ0G7uuQp/3CelVX7u/yVbr9ouxiaY/X724DKJM+rO7XjdyJm9nPSedm22ewCyYc KIc3uWMU7INsxwsblwsfFTrRqiKsL02mRHapHByqGH3WACX1NGHTk5znv+yYj4YmcS qf0OEjbCznyTHLkdJQ3cKWEjxWRCEGFzvlBMAqY+9sASq9q/T2p3NJVBtwGHtacuU0 rB9y1qGx0hMKg== From: Benjamin Tissoires Date: Wed, 08 May 2024 12:26:42 +0200 Subject: [PATCH RFC HID 7/7] HID: bpf: prevent infinite recursions with hid_hw_raw_requests hooks Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240508-hid_bpf_async_fun-v1-7-558375a25657@kernel.org> References: <20240508-hid_bpf_async_fun-v1-0-558375a25657@kernel.org> In-Reply-To: <20240508-hid_bpf_async_fun-v1-0-558375a25657@kernel.org> To: Benjamin Tissoires Cc: linux-kernel@vger.kernel.org, linux-input@vger.kernel.org, bpf@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=ed25519-sha256; t=1715164017; l=6266; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=gUKFJUJPIS9WSId/kAlnSuXYsqfcoTxB16GBAeCmvtM=; b=0bdx+qfpQLf9Bz1Uqnyq7kMhIlO/zMh96gqCYtYn9gWtjJlHx6wCndVGc6OyN4s5jmDj+RZtN HrqpptNkGzUCZCimmxCtyLvnNQ/y3DJ1PkfkFrenAxEd8/e00SPShD6 X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= When we attach a sleepable hook to hid_hw_raw_requests, we can (and in many cases should) call ourself hid_bpf_raw_request(), to actaully fetch data from the device itself. However, this means that we might enter an infinite loop between hid_hw_raw_requests trace and hid_bpf_raw_request() call. To prevent that, if a hid_bpf_raw_request() call is emitted, we prevent any sleepable bpf trace to hid_hw_raw_requests(). This way we can always trace/monitor/filter the incoming bpf requests, while preventing those loops to happen. Signed-off-by: Benjamin Tissoires --- drivers/hid/bpf/hid_bpf_dispatch.c | 7 ++++--- drivers/hid/hid-core.c | 6 +++--- drivers/hid/hidraw.c | 4 ++-- include/linux/hid.h | 2 +- include/linux/hid_bpf.h | 6 +++--- 5 files changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_d= ispatch.c index 7aeab3f9f2c7..79cac293ba29 100644 --- a/drivers/hid/bpf/hid_bpf_dispatch.c +++ b/drivers/hid/bpf/hid_bpf_dispatch.c @@ -99,7 +99,7 @@ dispatch_hid_bpf_raw_requests(struct hid_device *hdev, unsigned char reportnum, u8 *buf, u32 *size, enum hid_report_type rtype, enum hid_class_request reqtype, - u64 source) + u64 source, bool from_bpf) { struct hid_bpf_ctx_kern ctx_kern =3D { .ctx =3D { @@ -122,7 +122,7 @@ dispatch_hid_bpf_raw_requests(struct hid_device *hdev, // if (!hdev->bpf.device_data) // return buf; =20 - ret =3D hid_bpf_prog_run(hdev, HID_BPF_PROG_TYPE_RAW_REQUEST, &ctx_kern, = true); + ret =3D hid_bpf_prog_run(hdev, HID_BPF_PROG_TYPE_RAW_REQUEST, &ctx_kern, = !from_bpf); if (ret < 0) return ERR_PTR(ret); =20 @@ -536,7 +536,8 @@ hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8 *buf, = size_t buf__sz, size, rtype, reqtype, - (__u64)ctx); + (__u64)ctx, + true); /* prevent infinite recursions */ =20 if (ret > 0) memcpy(buf, dma_data, ret); diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 7d468f6dbefe..d53f465a4ccb 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -2404,7 +2404,7 @@ int __hid_hw_raw_request(struct hid_device *hdev, unsigned char reportnum, __u8 *buf, size_t len, enum hid_report_type rtype, enum hid_class_request reqtype, - __u64 source) + __u64 source, bool from_bpf) { unsigned int max_buffer_size =3D HID_MAX_BUFFER_SIZE; u32 size =3D (u32)len; /* max_buffer_size is 16 KB */ @@ -2416,7 +2416,7 @@ int __hid_hw_raw_request(struct hid_device *hdev, return -EINVAL; =20 buf =3D dispatch_hid_bpf_raw_requests(hdev, reportnum, buf, &size, rtype, - reqtype, source); + reqtype, source, from_bpf); if (IS_ERR(buf)) return PTR_ERR(buf); =20 @@ -2442,7 +2442,7 @@ int hid_hw_raw_request(struct hid_device *hdev, unsigned char reportnum, __u8 *buf, size_t len, enum hid_report_type rtype, enum hid_class_request re= qtype) { - return __hid_hw_raw_request(hdev, reportnum, buf, len, rtype, reqtype, 0); + return __hid_hw_raw_request(hdev, reportnum, buf, len, rtype, reqtype, 0,= false); } EXPORT_SYMBOL_GPL(hid_hw_raw_request); =20 diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index 6d2a6d38e42a..4ba3131de614 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c @@ -151,7 +151,7 @@ static ssize_t hidraw_send_report(struct file *file, co= nst char __user *buffer, } =20 ret =3D __hid_hw_raw_request(dev, buf[0], buf, count, report_type, - HID_REQ_SET_REPORT, (__u64)file); + HID_REQ_SET_REPORT, (__u64)file, false); =20 out_free: kfree(buf); @@ -228,7 +228,7 @@ static ssize_t hidraw_get_report(struct file *file, cha= r __user *buffer, size_t } =20 ret =3D __hid_hw_raw_request(dev, report_number, buf, count, report_type, - HID_REQ_GET_REPORT, (__u64)file); + HID_REQ_GET_REPORT, (__u64)file, false); =20 if (ret < 0) goto out_free; diff --git a/include/linux/hid.h b/include/linux/hid.h index dac2804b4562..24d0d7c0bd33 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -1129,7 +1129,7 @@ int __hid_hw_raw_request(struct hid_device *hdev, unsigned char reportnum, __u8 *buf, size_t len, enum hid_report_type rtype, enum hid_class_request reqtype, - __u64 source); + __u64 source, bool from_bpf); int __hid_hw_output_report(struct hid_device *hdev, __u8 *buf, size_t len,= __u64 source); int hid_hw_raw_request(struct hid_device *hdev, unsigned char reportnum, __u8 *buf, diff --git a/include/linux/hid_bpf.h b/include/linux/hid_bpf.h index 1cd36bfdd608..6b2ac815572c 100644 --- a/include/linux/hid_bpf.h +++ b/include/linux/hid_bpf.h @@ -105,7 +105,7 @@ struct hid_bpf_ops { unsigned char reportnum, __u8 *buf, size_t len, enum hid_report_type rtype, enum hid_class_request reqtype, - __u64 source); + __u64 source, bool from_bpf); int (*hid_hw_output_report)(struct hid_device *hdev, __u8 *buf, size_t le= n, __u64 source); int (*hid_input_report)(struct hid_device *hid, enum hid_report_type type, @@ -148,7 +148,7 @@ u8 *dispatch_hid_bpf_raw_requests(struct hid_device *hd= ev, unsigned char reportnum, __u8 *buf, u32 *size, enum hid_report_type rtype, enum hid_class_request reqtype, - __u64 source); + __u64 source, bool from_bpf); int hid_bpf_connect_device(struct hid_device *hdev); void hid_bpf_disconnect_device(struct hid_device *hdev); void hid_bpf_destroy_device(struct hid_device *hid); @@ -162,7 +162,7 @@ static inline u8 *dispatch_hid_bpf_raw_requests(struct = hid_device *hdev, unsigned char reportnum, u8 *buf, u32 *size, enum hid_report_type rtype, enum hid_class_request reqtype, - u64 source) { return buf; } + u64 source, bool from_bpf) { return buf; } static inline int hid_bpf_connect_device(struct hid_device *hdev) { return= 0; } static inline void hid_bpf_disconnect_device(struct hid_device *hdev) {} static inline void hid_bpf_destroy_device(struct hid_device *hid) {} --=20 2.44.0