From patchwork Wed May 8 10:26:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Tissoires X-Patchwork-Id: 13658471 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-input@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 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/entrypoints/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 := .output -abs_out := $(abspath $(OUTPUT)) - -CLANG ?= clang -LLC ?= llc -LLVM_STRIP ?= llvm-strip - -TOOLS_PATH := $(abspath ../../../../tools) -BPFTOOL_SRC := $(TOOLS_PATH)/bpf/bpftool -BPFTOOL_OUTPUT := $(abs_out)/bpftool -DEFAULT_BPFTOOL := $(BPFTOOL_OUTPUT)/bootstrap/bpftool -BPFTOOL ?= $(DEFAULT_BPFTOOL) - -LIBBPF_SRC := $(TOOLS_PATH)/lib/bpf -LIBBPF_OUTPUT := $(abs_out)/libbpf -LIBBPF_DESTDIR := $(LIBBPF_OUTPUT) -LIBBPF_INCLUDE := $(LIBBPF_DESTDIR)/include -BPFOBJ := $(LIBBPF_OUTPUT)/libbpf.a - -INCLUDES := -I$(OUTPUT) -I$(LIBBPF_INCLUDE) -I$(TOOLS_PATH)/include/uapi -CFLAGS := -g -Wall - -VMLINUX_BTF_PATHS ?= $(if $(O),$(O)/vmlinux) \ - $(if $(KBUILD_OUTPUT),$(KBUILD_OUTPUT)/vmlinux) \ - ../../../../vmlinux \ - /sys/kernel/btf/vmlinux \ - /boot/vmlinux-$(shell uname -r) -VMLINUX_BTF ?= $(abspath $(firstword $(wildcard $(VMLINUX_BTF_PATHS)))) -ifeq ($(VMLINUX_BTF),) -$(error Cannot find a vmlinux for VMLINUX_BTF at any of "$(VMLINUX_BTF_PATHS)") -endif - -ifeq ($(V),1) -Q = -msg = -else -Q = @ -msg = @printf ' %-8s %s%s\n' "$(1)" "$(notdir $(2))" "$(if $(3), $(3))"; -MAKEFLAGS += --no-print-directory -submake_extras := feature_display=0 -endif - -.DELETE_ON_ERROR: - -.PHONY: all clean - -all: entrypoints.lskel.h - -clean: - $(call msg,CLEAN) - $(Q)rm -rf $(OUTPUT) entrypoints - -entrypoints.lskel.h: $(OUTPUT)/entrypoints.bpf.o | $(BPFTOOL) - $(call msg,GEN-SKEL,$@) - $(Q)$(BPFTOOL) gen skeleton -L $< > $@ - - -$(OUTPUT)/entrypoints.bpf.o: entrypoints.bpf.c $(OUTPUT)/vmlinux.h $(BPFOBJ) | $(OUTPUT) - $(call msg,BPF,$@) - $(Q)$(CLANG) -g -O2 --target=bpf $(INCLUDES) \ - -c $(filter %.c,$^) -o $@ && \ - $(LLVM_STRIP) -g $@ - -$(OUTPUT)/vmlinux.h: $(VMLINUX_BTF) $(BPFTOOL) | $(INCLUDE_DIR) -ifeq ($(VMLINUX_H),) - $(call msg,GEN,,$@) - $(Q)$(BPFTOOL) btf dump file $(VMLINUX_BTF) format c > $@ -else - $(call msg,CP,,$@) - $(Q)cp "$(VMLINUX_H)" $@ -endif - -$(OUTPUT) $(LIBBPF_OUTPUT) $(BPFTOOL_OUTPUT): - $(call msg,MKDIR,$@) - $(Q)mkdir -p $@ - -$(BPFOBJ): $(wildcard $(LIBBPF_SRC)/*.[ch] $(LIBBPF_SRC)/Makefile) | $(LIBBPF_OUTPUT) - $(Q)$(MAKE) $(submake_extras) -C $(LIBBPF_SRC) \ - OUTPUT=$(abspath $(dir $@))/ prefix= \ - DESTDIR=$(LIBBPF_DESTDIR) $(abspath $@) install_headers - -ifeq ($(CROSS_COMPILE),) -$(DEFAULT_BPFTOOL): $(BPFOBJ) | $(BPFTOOL_OUTPUT) - $(Q)$(MAKE) $(submake_extras) -C $(BPFTOOL_SRC) \ - OUTPUT=$(BPFTOOL_OUTPUT)/ \ - LIBBPF_BOOTSTRAP_OUTPUT=$(LIBBPF_OUTPUT)/ \ - LIBBPF_BOOTSTRAP_DESTDIR=$(LIBBPF_DESTDIR)/ bootstrap -else -$(DEFAULT_BPFTOOL): | $(BPFTOOL_OUTPUT) - $(Q)$(MAKE) $(submake_extras) -C $(BPFTOOL_SRC) \ - OUTPUT=$(BPFTOOL_OUTPUT)/ bootstrap -endif diff --git a/drivers/hid/bpf/entrypoints/README b/drivers/hid/bpf/entrypoints/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 rebuild "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/bpf/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") = "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 = skel->progs.hid_tail_call.prog_fd; - int fd = skel_raw_tracepoint_open(NULL, prog_fd); - - if (fd > 0) - skel->links.hid_tail_call_fd = fd; - return fd; -} - -static inline int -entrypoints_bpf__attach(struct entrypoints_bpf *skel) -{ - int ret = 0; - - ret = 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 = skel_alloc(sizeof(*skel)); - if (!skel) - goto cleanup; - skel->ctx.sz = (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 = {}; - int err; - - opts.ctx = (struct bpf_loader_ctx *)skel; - opts.data_sz = 2856; - opts.data = (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\x01\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\x03\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\x02\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\x01\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\x5f\ -\x65\x6e\x74\x72\x69\x65\x73\0\x6b\x65\x79\x5f\x73\x69\x7a\x65\0\x76\x61\x6c\ -\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\x61\ -\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\x2f\ -\x68\x69\x64\x2f\x62\x70\x66\x2f\x65\x6e\x74\x72\x79\x70\x6f\x69\x6e\x74\x73\ -\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\x69\ -\x6c\x5f\x63\x61\x6c\x6c\x2c\x20\x73\x74\x72\x75\x63\x74\x20\x68\x69\x64\x5f\ -\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\x6e\ -\x74\0\x68\x69\x64\x5f\x72\x65\x70\x6f\x72\x74\x5f\x74\x79\x70\x65\0\x48\x49\ -\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\x65\0\ -\x5f\x5f\x73\x33\x32\0\x30\x3a\x30\0\x09\x62\x70\x66\x5f\x74\x61\x69\x6c\x5f\ -\x63\x61\x6c\x6c\x28\x63\x74\x78\x2c\x20\x26\x68\x69\x64\x5f\x6a\x6d\x70\x5f\ -\x74\x61\x62\x6c\x65\x2c\x20\x68\x63\x74\x78\x2d\x3e\x69\x6e\x64\x65\x78\x29\ -\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\x5f\ -\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\x01\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\x5f\ -\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 = 1192; - opts.insns = (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\x02\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\x61\ -\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\x61\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\x78\ -\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\x90\ -\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\x18\ -\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\x0c\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\x60\ -\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\xd5\ -\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 = 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 = 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_dispatch.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" 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; } -static int do_hid_bpf_attach_prog(struct hid_device *hdev, int prog_fd, struct bpf_prog *prog, +static int do_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) { - int fd, err, prog_type; + int fd, err; - prog_type = hid_bpf_get_prog_attach_type(prog); - if (prog_type < 0) - return prog_type; + err = hid_bpf_allocate_event_data(hdev); + if (err) + return err; - if (prog_type >= HID_BPF_PROG_TYPE_MAX) - return -EINVAL; - - if (prog_type == HID_BPF_PROG_TYPE_DEVICE_EVENT) { - err = hid_bpf_allocate_event_data(hdev); - if (err) - return err; - } - - fd = __hid_bpf_attach_prog(hdev, prog_type, prog_fd, prog, flags); + fd = __hid_bpf_attach_prog(hdev, prog_type, prog_fn, prog, flags); if (fd < 0) return fd; @@ -277,10 +269,12 @@ hid_bpf_get_data(struct hid_bpf_ctx *ctx, unsigned int 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 = (struct bpf_prog_aux *)prog__aux; + struct bpf_prog *prog = aux->prog; struct hid_device *hdev; - struct bpf_prog *prog; struct device *dev; int err, fd; @@ -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; + if (prog_type < 0 || prog_type >= HID_BPF_PROG_TYPE_MAX) + return -EINVAL; + dev = bus_find_device(hid_bpf_ops->bus_type, NULL, &hid_id, device_match_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 = bpf_prog_get(prog_fd); + prog = bpf_prog_inc_not_zero(prog); if (IS_ERR(prog)) { err = PTR_ERR(prog); goto out_dev_put; } - fd = do_hid_bpf_attach_prog(hdev, prog_fd, prog, flags); + fd = do_hid_bpf_attach_prog(hdev, prog_type, prog_fn__async, prog, flags); if (fd < 0) { err = 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(); -/* - * 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 = { .set = &hid_bpf_kfunc_ids, }; -/* 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 = { - .owner = THIS_MODULE, - .set = &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 = { - .owner = THIS_MODULE, - .set = &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. */ - err = register_btf_fmodret_id_set(&hid_bpf_fmodret_set); - if (err) { - pr_warn("error while registering fmodret entrypoints: %d", err); - return 0; - } - - err = 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 bpf program */ - err = register_btf_kfunc_id_set(BPF_PROG_TYPE_TRACING, &hid_bpf_kfunc_set); - 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 program */ - err = register_btf_kfunc_id_set(BPF_PROG_TYPE_SYSCALL, &hid_bpf_syscall_kfunc_set); + err = register_btf_kfunc_id_set(BPF_PROG_TYPE_SYSCALL, &hid_bpf_kfunc_set); 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; } @@ -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(); } late_initcall(hid_bpf_init); diff --git a/drivers/hid/bpf/hid_bpf_dispatch.h b/drivers/hid/bpf/hid_bpf_dispatch.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; }; -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" #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; }; +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 mapping */ unsigned long enabled[BITS_TO_LONGS(HID_BPF_MAX_PROGS)]; }; @@ -56,10 +59,6 @@ static void hid_bpf_release_progs(struct work_struct *work); static DECLARE_WORK(release_work, hid_bpf_release_progs); -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 *hdev, return n; } -__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 = 0; rcu_read_lock(); @@ -123,7 +118,10 @@ int hid_bpf_prog_run(struct hid_device *hdev, enum hid_bpf_prog_type type, continue; ctx_kern->ctx.index = idx; - err = __hid_bpf_tail_call(&ctx_kern->ctx); + prog_fn = jmp_table.prog_cbs[idx].fn; + migrate_disable(); + err = 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 *hdev, enum hid_bpf_prog_type return 0; } -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] = NULL; + bpf_prog_put(jmp_table.prog_cbs[idx].prog); + jmp_table.prog_cbs[idx].prog = NULL; + jmp_table.prog_cbs[idx].fn = NULL; } static void hid_bpf_release_progs(struct work_struct *work) { - int i, j, n, map_fd = -1; + int i, j, n; bool hdev_destroyed; - if (!jmp_table.map) - return; - - /* retrieve a fd of our prog_array map in BPF */ - map_fd = 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 programs */ /* detach unused progs from HID devices */ @@ -264,7 +255,7 @@ static void hid_bpf_release_progs(struct work_struct *work) continue; if (entry->prog) - __hid_bpf_do_release_prog(map_fd, entry->idx); + __hid_bpf_do_release_prog(entry->idx); } /* compact the entry list */ @@ -282,46 +273,22 @@ static void hid_bpf_release_progs(struct work_struct *work) jmp_table.head = n; mutex_unlock(&hid_bpf_attach_lock); - - if (map_fd >= 0) - close_fd(map_fd); -} - -static void hid_bpf_release_prog_at(int idx) -{ - int map_fd = -1; - - /* retrieve a fd of our prog_array map in BPF */ - map_fd = 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); } /* - * 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 jmp 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 = -1, map_fd = -1, err = -EINVAL; - - /* retrieve a fd of our prog_array map in BPF */ - map_fd = skel_map_get_fd_by_id(jmp_table.map->id); - - if (map_fd < 0) { - err = -EINVAL; - goto out; - } + int i, index = -1, err = -EINVAL; /* find the first available index in the jmp_table */ for (i = 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] = prog; + jmp_table.prog_cbs[i].fn = prog_fn; + jmp_table.prog_cbs[i].prog = prog; index = i; __set_bit(i, jmp_table.enabled); } @@ -331,37 +298,15 @@ static int hid_bpf_insert_prog(int prog_fd, struct bpf_prog *prog) goto out; } - /* insert the program in the jump table */ - err = skel_map_update_elem(map_fd, &index, &prog_fd, 0); - if (err) - goto out; - /* return the index */ err = index; out: if (err < 0) - __hid_bpf_do_release_prog(map_fd, index); - if (map_fd >= 0) - close_fd(map_fd); + __hid_bpf_do_release_prog(index); return err; } -int hid_bpf_get_prog_attach_type(struct bpf_prog *prog) -{ - int prog_type = HID_BPF_PROG_TYPE_UNDEF; - int i; - - for (i = 0; i < HID_BPF_PROG_TYPE_MAX; i++) { - if (hid_bpf_btf_ids[i] == prog->aux->attach_btf_id) { - prog_type = i; - break; - } - } - - return prog_type; -} - static void hid_bpf_link_release(struct bpf_link *link) { struct hid_bpf_link *hid_link = @@ -395,7 +340,7 @@ static const struct bpf_link_ops hid_bpf_link_lops = { /* 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; } - prog_table_idx = hid_bpf_insert_prog(prog_fd, prog); + prog_table_idx = hid_bpf_insert_prog(prog, prog_fn); /* if the jmp table is full, abort */ if (prog_table_idx < 0) { err = 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 = 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; } @@ -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 = 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 = entrypoints_bpf__##__name##__attach(skel); \ - if (err) \ - goto out; \ - \ - links[idx] = bpf_link_get_from_fd(skel->links.__name##_fd); \ - if (IS_ERR(links[idx])) { \ - err = 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 = 0; \ - idx++; \ -} while (0) - -int hid_bpf_preload_skel(void) -{ - int err, idx = 0; - - skel = entrypoints_bpf__open(); - if (!skel) - return -ENOMEM; - - err = entrypoints_bpf__load(skel); - if (err) - goto out; - - jmp_table.map = bpf_map_get_with_uref(skel->maps.hid_jmp_table.map_fd); - if (IS_ERR(jmp_table.map)) { - err = 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 */ -/* 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) From patchwork Wed May 8 10:26:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Tissoires X-Patchwork-Id: 13658472 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-input@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 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/selftests/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[] = { static __u8 feature_data[] = { 1, 2 }; 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 programs[], err = hid__load(self->skel); ASSERT_OK(err) TH_LOG("hid_skel_load failed: %d", err); - attach_fd = bpf_program__fd(self->skel->progs.attach_prog); - ASSERT_GE(attach_fd, 0) TH_LOG("locate attach_prog: %d", attach_fd); - for (int i = 0; i < progs_count; i++) { struct bpf_program *prog; @@ -566,7 +562,7 @@ static void load_programs(const struct test_program programs[], programs[i].name); ASSERT_OK_PTR(prog) TH_LOG("can not find program by name '%s'", programs[i].name); - args.prog_fd = bpf_program__fd(prog); + attach_fd = bpf_program__fd(prog); args.hid = self->hid_id; args.insert_head = programs[i].insert_head; err = bpf_prog_test_run_opts(attach_fd, &tattr); diff --git a/tools/testing/selftests/hid/progs/hid.c b/tools/testing/selftests/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 @@ char _license[] SEC("license") = "GPL"; -struct attach_prog_args { - int prog_fd; - unsigned int hid; - int retval; - int insert_head; -}; - __u64 callback_check = 52; __u64 callback2_check = 52; -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 = hid_bpf_get_data(hid_ctx, 0 /* offset */, 3 /* size */); @@ -29,8 +21,7 @@ int BPF_PROG(hid_first_event, struct hid_bpf_ctx *hid_ctx) return hid_ctx->size; } -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 = hid_bpf_get_data(hid_ctx, 0 /* offset */, 4 /* size */); @@ -42,8 +33,7 @@ int BPF_PROG(hid_second_event, struct hid_bpf_ctx *hid_ctx) return hid_ctx->size; } -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 = hid_bpf_get_data(hid_ctx, 0 /* offset */, 3 /* size */); @@ -55,16 +45,6 @@ int BPF_PROG(hid_change_report_id, struct hid_bpf_ctx *hid_ctx) return 9; } -SEC("syscall") -int attach_prog(struct attach_prog_args *ctx) -{ - ctx->retval = 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[] = { 0xc0, /* END_COLLECTION */ }; -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 = hid_bpf_get_data(hid_ctx, 0 /* offset */, 4096 /* size */); if (!data) - return 0; /* EPERM check */ + return -22; /* EPERM check */ callback2_check = data[4]; @@ -200,8 +179,7 @@ int BPF_PROG(hid_rdesc_fixup, struct hid_bpf_ctx *hid_ctx) return sizeof(rdesc) + 73; } -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 = hid_bpf_get_data(hid_ctx, 0 /* offset */, 4 /* size */); @@ -217,8 +195,7 @@ int BPF_PROG(hid_test_insert1, struct hid_bpf_ctx *hid_ctx) return 0; } -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 = hid_bpf_get_data(hid_ctx, 0 /* offset */, 4 /* size */); @@ -234,8 +211,7 @@ int BPF_PROG(hid_test_insert2, struct hid_bpf_ctx *hid_ctx) return 0; } -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 = hid_bpf_get_data(hid_ctx, 0 /* offset */, 4 /* size */); diff --git a/tools/testing/selftests/hid/progs/hid_bpf_helpers.h b/tools/testing/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, }; +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 *ctx, __u8 *data, size_t buf__sz) __ksym; +#define __HID_BPF_PROG(type, name, arg) \ + static int __##name(arg); \ + SEC("syscall") \ + int name(struct attach_prog_args *ctx) \ + { \ + ctx->retval = 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_DEVICE_EVENT, name, arg) +#define HID_BPF_RDESC_FIXUP(name, arg) __HID_BPF_PROG(HID_BPF_PROG_TYPE_RDESC_FIXUP, name, arg) + #endif /* __HID_BPF_HELPERS_H */ From patchwork Wed May 8 10:26:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Tissoires X-Patchwork-Id: 13658473 X-Patchwork-Delegate: jikos@jikos.cz 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-input@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 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_dispatch.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, enum hid_report_type type memset(ctx_kern.data, 0, hdev->bpf.allocated_data); memcpy(ctx_kern.data, data, *size); - ret = hid_bpf_prog_run(hdev, HID_BPF_PROG_TYPE_DEVICE_EVENT, &ctx_kern); + ret = hid_bpf_prog_run(hdev, HID_BPF_PROG_TYPE_DEVICE_EVENT, &ctx_kern, false); if (ret < 0) return ERR_PTR(ret); @@ -122,7 +122,7 @@ u8 *call_hid_bpf_rdesc_fixup(struct hid_device *hdev, u8 *rdesc, unsigned int *s memcpy(ctx_kern.data, rdesc, min_t(unsigned int, *size, HID_MAX_DESCRIPTOR_SIZE)); - ret = hid_bpf_prog_run(hdev, HID_BPF_PROG_TYPE_RDESC_FIXUP, &ctx_kern); + ret = hid_bpf_prog_run(hdev, HID_BPF_PROG_TYPE_RDESC_FIXUP, &ctx_kern, false); if (ret < 0) goto ignore_bpf; @@ -205,7 +205,7 @@ int hid_bpf_reconnect(struct hid_device *hdev) static int do_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) + __u32 flags, bool sleepable) { int fd, err; @@ -213,7 +213,7 @@ static int do_hid_bpf_attach_prog(struct hid_device *hdev, enum hid_bpf_prog_typ if (err) return err; - fd = __hid_bpf_attach_prog(hdev, prog_type, prog_fn, prog, flags); + fd = __hid_bpf_attach_prog(hdev, prog_type, prog_fn, prog, flags, sleepable); if (fd < 0) return fd; @@ -228,6 +228,56 @@ static int do_hid_bpf_attach_prog(struct hid_device *hdev, enum hid_bpf_prog_typ return fd; } +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 = (struct bpf_prog_aux *)prog__aux; + struct bpf_prog *prog = 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 >= HID_BPF_PROG_TYPE_MAX) + return -EINVAL; + + dev = bus_find_device(hid_bpf_ops->bus_type, NULL, &hid_id, device_match_id); + if (!dev) + return -EINVAL; + + hdev = to_hid_device(dev); + + /* + * take a ref on the prog itself, it will be released + * on errors or when it'll be detached + */ + prog = bpf_prog_inc_not_zero(prog); + if (IS_ERR(prog)) { + err = PTR_ERR(prog); + goto out_dev_put; + } + + fd = do_hid_bpf_attach_prog(hdev, prog_type, prog_fn, prog, flags, sleepable); + if (fd < 0) { + err = 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(); @@ -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 = (struct bpf_prog_aux *)prog__aux; - struct bpf_prog *prog = 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 >= HID_BPF_PROG_TYPE_MAX) - return -EINVAL; + return hid_bpf_attach_prog(hid_id, prog_type, prog_fn__async, flags, prog__aux, false); +} - dev = bus_find_device(hid_bpf_ops->bus_type, NULL, &hid_id, device_match_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 = to_hid_device(dev); - - /* - * take a ref on the prog itself, it will be released - * on errors or when it'll be detached - */ - prog = bpf_prog_inc_not_zero(prog); - if (IS_ERR(prog)) { - err = PTR_ERR(prog); - goto out_dev_put; - } - - fd = do_hid_bpf_attach_prog(hdev, prog_type, prog_fn__async, prog, flags); - if (fd < 0) { - err = fd; - goto out_prog_put; } - 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, prog__aux, true); } /** @@ -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_dispatch.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); 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); 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; }; struct hid_bpf_jmp_table { @@ -99,14 +100,20 @@ static int hid_bpf_program_count(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) { struct hid_bpf_prog_list *prog_list; bpf_callback_t prog_fn; int i, idx, err = 0; - rcu_read_lock(); - prog_list = rcu_dereference(hdev->bpf.progs[type]); + if (is_sleepable) { + prog_list = READ_ONCE(hdev->bpf.progs[type]); + rcu_read_lock_trace(); + might_fault(); + } else { + rcu_read_lock(); + prog_list = rcu_dereference(hdev->bpf.progs[type]); + } 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; + /* 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 = idx; prog_fn = 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, } out_unlock: - rcu_read_unlock(); + if (is_sleepable) + rcu_read_unlock_trace(); + else + rcu_read_unlock(); return err; } @@ -279,7 +293,7 @@ static void hid_bpf_release_progs(struct work_struct *work) * Insert the given BPF program represented by its function call in the jmp 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 = -1, err = -EINVAL; @@ -289,6 +303,7 @@ static int hid_bpf_insert_prog(struct bpf_prog *prog, hid_bpf_cb_t prog_fn) /* mark the index as used */ jmp_table.prog_cbs[i].fn = prog_fn; jmp_table.prog_cbs[i].prog = prog; + jmp_table.prog_cbs[i].sleepable = sleepable; index = i; __set_bit(i, jmp_table.enabled); } @@ -340,7 +355,8 @@ static const struct bpf_link_ops hid_bpf_link_lops = { /* 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; } - prog_table_idx = hid_bpf_insert_prog(prog, prog_fn); + prog_table_idx = hid_bpf_insert_prog(prog, prog_fn, sleepable); /* if the jmp table is full, abort */ if (prog_table_idx < 0) { err = prog_table_idx; From patchwork Wed May 8 10:26:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Tissoires X-Patchwork-Id: 13658474 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-input@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 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_dispatch.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_ctx *ctx) u8 * dispatch_hid_bpf_device_event(struct hid_device *hdev, enum hid_report_type type, u8 *data, - u32 *size, int interrupt) + u32 *size, int interrupt, u64 source) { struct hid_bpf_ctx_kern ctx_kern = { .ctx = { @@ -55,6 +55,7 @@ dispatch_hid_bpf_device_event(struct hid_device *hdev, enum hid_report_type type .report_type = type, .allocated_size = hdev->bpf.allocated_data, .size = *size, + .source = source, }, .data = 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); 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) ret = hid_bpf_ops->hid_hw_output_report(hdev, dma_data, - size); + size, + (__u64)ctx); 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 hdev = (struct hid_device *)ctx->hid; /* discard const */ - 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(); 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, enum hid_report_type type, u8 * } EXPORT_SYMBOL_GPL(hid_report_raw_event); -/** - * 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 = hid->report_enum + type; hdrv = hid->driver; - data = dispatch_hid_bpf_device_event(hid, type, data, &size, interrupt); + data = dispatch_hid_bpf_device_event(hid, type, data, &size, interrupt, source); if (IS_ERR(data)) { ret = PTR_ERR(data); goto unlock; @@ -2093,6 +2083,23 @@ int hid_input_report(struct hid_device *hid, enum hid_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); 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); +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 = HID_MAX_BUFFER_SIZE; + + if (hdev->ll_driver->max_buffer_size) + max_buffer_size = 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 reqtype) +{ + 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 = HID_MAX_BUFFER_SIZE; @@ -2419,10 +2450,11 @@ int hid_hw_raw_request(struct hid_device *hdev, if (len < 1 || len > max_buffer_size || !buf) return -EINVAL; - 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); /** * 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 = HID_MAX_BUFFER_SIZE; - - if (hdev->ll_driver->max_buffer_size) - max_buffer_size = 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); @@ -2973,9 +2994,9 @@ EXPORT_SYMBOL_GPL(hid_check_keys_pressed); #ifdef CONFIG_HID_BPF static struct hid_bpf_ops hid_ops = { .hid_get_report = hid_get_report, - .hid_hw_raw_request = hid_hw_raw_request, - .hid_hw_output_report = hid_hw_output_report, - .hid_input_report = hid_input_report, + .hid_hw_raw_request = __hid_hw_raw_request, + .hid_hw_output_report = __hid_hw_output_report, + .hid_input_report = __hid_input_report, .owner = THIS_MODULE, .bus_type = &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, const char __user *buffer, if ((report_type == HID_OUTPUT_REPORT) && !(dev->quirks & HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP)) { - ret = hid_hw_output_report(dev, buf, count); + ret = __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, const char __user *buffer, goto out_free; } - ret = hid_hw_raw_request(dev, buf[0], buf, count, report_type, - HID_REQ_SET_REPORT); + ret = __hid_hw_raw_request(dev, buf[0], buf, count, report_type, + HID_REQ_SET_REPORT, (__u64)file); out_free: kfree(buf); @@ -227,8 +227,8 @@ static ssize_t hidraw_get_report(struct file *file, char __user *buffer, size_t goto out_free; } - ret = hid_hw_raw_request(dev, report_number, buf, count, report_type, - HID_REQ_GET_REPORT); + ret = __hid_hw_raw_request(dev, report_number, buf, count, report_type, + HID_REQ_GET_REPORT, (__u64)file); 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 len); + 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_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 { #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, enum 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) {} From patchwork Wed May 8 10:26:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Tissoires X-Patchwork-Id: 13658475 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-input@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 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_dispatch.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; } +__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_type type, u8 *data, u32 *size, int interrupt, u64 source) @@ -71,6 +76,9 @@ dispatch_hid_bpf_device_event(struct hid_device *hdev, enum hid_report_type type memset(ctx_kern.data, 0, hdev->bpf.allocated_data); memcpy(ctx_kern.data, data, *size); + if (*size) + ctx_kern.ctx.reportnum = data[0]; + ret = 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, enum hid_report_type type } EXPORT_SYMBOL_GPL(dispatch_hid_bpf_device_event); +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 = { + .ctx = { + .hid = hdev, + .report_type = rtype, + .reqtype = reqtype, + .allocated_size = *size, + .size = *size, + .source = source, + .reportnum = reportnum, + }, + .data = buf, + }; + int ret; + + if (rtype >= HID_REPORT_TYPES) + return ERR_PTR(-EINVAL); + + /* no program has been attached yet */ + // if (!hdev->bpf.device_data) + // return buf; + + ret = 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 = 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 type) { 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 = HID_MAX_BUFFER_SIZE; + u32 size = (u32)len; /* max_buffer_size is 16 KB */ if (hdev->ll_driver->max_buffer_size) max_buffer_size = 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; - return hdev->ll_driver->raw_request(hdev, reportnum, buf, len, + buf = 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); } 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; }; /** @@ -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); /* * Below is HID internal @@ -90,6 +93,7 @@ enum hid_bpf_prog_type { HID_BPF_PROG_TYPE_UNDEF = -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, }; @@ -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, enum 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) {} From patchwork Wed May 8 10:26:41 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Tissoires X-Patchwork-Id: 13658476 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-input@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 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/selftests/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 = 0; + // hid__detach(self->skel); + for (i = 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 programs[], self->hid_links[i] = args.retval; } + // hid__attach(self->skel); + self->hidraw_fd = 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); } +/* + * 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[] = { + { .name = "hid_test_filter_raw_request" }, + { .name = "hid_test_raw_request" }, + }; + __u8 buf[10] = {0}; + int err; + + LOAD_PROGRAMS(progs); + + /* first check that we did not attach to device_event */ + + /* inject one event */ + buf[0] = 1; + buf[1] = 42; + uhid_send_event(_metadata, self->uhid_fd, buf, 6); + + /* read the data from hidraw */ + memset(buf, 0, sizeof(buf)); + err = 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] = 0x1; /* Report Number */ + err = 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 = open_hidraw(self->dev_id); + ASSERT_GE(self->hidraw_fd, 0) TH_LOG("open_hidraw"); + + err = 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/selftests/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) 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 *hctx) +{ + struct test_report buf = { + .data = {2, 3, 4, 5, 6, 7}, + }; + __u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 2 /* size */); + int ret; + + bpf_printk("in %s, hctx: %llx source: %llx", __func__, (u64)hctx, hctx->source); + + 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] = hctx->reportnum; + + ret = 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/testing/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, }; -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 = 0x01, HID_REQ_GET_IDLE = 0x02, @@ -88,6 +77,20 @@ struct attach_prog_args { int insert_head; }; +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 *ctx, __u8 *data, size_t buf__sz) __ksym; -#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 = hid_bpf_attach_prog_impl(ctx->hid, \ + ctx->retval = 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) -#define HID_BPF_DEVICE_EVENT(name, arg) __HID_BPF_PROG(HID_BPF_PROG_TYPE_DEVICE_EVENT, name, arg) -#define HID_BPF_RDESC_FIXUP(name, arg) __HID_BPF_PROG(HID_BPF_PROG_TYPE_RDESC_FIXUP, name, arg) +#define HID_BPF_DEVICE_EVENT(name, arg) __HID_BPF_PROG(HID_BPF_PROG_TYPE_DEVICE_EVENT, name, arg, ) +#define HID_BPF_RDESC_FIXUP(name, arg) __HID_BPF_PROG(HID_BPF_PROG_TYPE_RDESC_FIXUP, name, arg, ) +#define HID_BPF_RAW_REQUEST(name, arg) __HID_BPF_PROG(HID_BPF_PROG_TYPE_RAW_REQUEST, name, arg, ) +#define HID_BPF_SLEEPABLE_RAW_REQUEST(name, arg) __HID_BPF_PROG(HID_BPF_PROG_TYPE_RAW_REQUEST, name, arg, sleepable_) #endif /* __HID_BPF_HELPERS_H */ From patchwork Wed May 8 10:26:42 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Tissoires X-Patchwork-Id: 13658477 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-input@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 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_dispatch.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 = { .ctx = { @@ -122,7 +122,7 @@ dispatch_hid_bpf_raw_requests(struct hid_device *hdev, // if (!hdev->bpf.device_data) // return buf; - ret = hid_bpf_prog_run(hdev, HID_BPF_PROG_TYPE_RAW_REQUEST, &ctx_kern, true); + ret = hid_bpf_prog_run(hdev, HID_BPF_PROG_TYPE_RAW_REQUEST, &ctx_kern, !from_bpf); if (ret < 0) return ERR_PTR(ret); @@ -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 */ 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 = HID_MAX_BUFFER_SIZE; u32 size = (u32)len; /* max_buffer_size is 16 KB */ @@ -2416,7 +2416,7 @@ int __hid_hw_raw_request(struct hid_device *hdev, return -EINVAL; buf = dispatch_hid_bpf_raw_requests(hdev, reportnum, buf, &size, rtype, - reqtype, source); + reqtype, source, from_bpf); if (IS_ERR(buf)) return PTR_ERR(buf); @@ -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 reqtype) { - 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); 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, const char __user *buffer, } ret = __hid_hw_raw_request(dev, buf[0], buf, count, report_type, - HID_REQ_SET_REPORT, (__u64)file); + HID_REQ_SET_REPORT, (__u64)file, false); out_free: kfree(buf); @@ -228,7 +228,7 @@ static ssize_t hidraw_get_report(struct file *file, char __user *buffer, size_t } ret = __hid_hw_raw_request(dev, report_number, buf, count, report_type, - HID_REQ_GET_REPORT, (__u64)file); + HID_REQ_GET_REPORT, (__u64)file, false); 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 len, __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 *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); 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) {}