From nobody Fri Dec 19 21:10:08 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9B3BC177980; Sat, 8 Jun 2024 09:01:24 +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=1717837284; cv=none; b=nq88XuWGvkQ+IhnmLsfVL0VFSprm9+fWijWErN9s6BdErVw/Cx7kHbhPth8ZU9T9rP0F4MOdpzdmz4acQyPYJdNdiy/NrcDcV8as0/9ul/fzAwMIjmsQnP5q4oGemRgJ16yHR0OTaZtcz+9OdRyD2FbuRQA18/rdWA0nrFJ189I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717837284; c=relaxed/simple; bh=SqWBE4A1R6EX1/tAq/E6TPVDDWLh4zwW64KIjuXOJ/s=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Kj25ftfI7KN9mKI5xLM7Mm/+hkTx1sH1X9togFpv3rHWieZd2uXhsDV6ZU6rv5y0o8CEd4wNBXkwkXGwdybrF5+y9ew5I36071oVT5V3WN3XYy0+YkOHfNXSImBZewLTO8AWgbVOJwWG/SZuL465z10wAoRvrgNgI9ij/3VbH+o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=LNgjYxGA; 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="LNgjYxGA" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 69438C4AF07; Sat, 8 Jun 2024 09:01:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1717837284; bh=SqWBE4A1R6EX1/tAq/E6TPVDDWLh4zwW64KIjuXOJ/s=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=LNgjYxGAy0lGwbi3PctrZqslXdqHKQWx/1aslH/2ndaf1FcSUhI1t/LKBxGPzKAKb GAQVL+LEA18H08yLc0Fc4ZZQv2k/+O7ZYHtnk7Rz9CnW8eLpcSpGoK60kmGUEq26/e qy6ZIGYHHkaRj3ciANHsSbbzUg7gFetQ+Dt/bT+k/PWxqcqNodCojtKTayQJYY4QO1 8AIdOJE9djRaxp0M+nQgi9+0UbhPgS0iGNDifWfDyB9+kFEtFsVOimAFtC10fYaZAQ izsYfilJCCiNlbVvHA4Snr7TqXf9MNf2jQ8hwkhFdn7nJyDFTjzes/5cyCbYvk/sEO EMnNdk40+o1vA== From: Benjamin Tissoires Date: Sat, 08 Jun 2024 11:01:13 +0200 Subject: [PATCH HID v3 01/16] HID: rename struct hid_bpf_ops into hid_ops Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240608-hid_bpf_struct_ops-v3-1-6ac6ade58329@kernel.org> References: <20240608-hid_bpf_struct_ops-v3-0-6ac6ade58329@kernel.org> In-Reply-To: <20240608-hid_bpf_struct_ops-v3-0-6ac6ade58329@kernel.org> To: Shuah Khan , Jiri Kosina , Jonathan Corbet , Alexei Starovoitov Cc: linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, linux-input@vger.kernel.org, linux-doc@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1717837279; l=4952; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=SqWBE4A1R6EX1/tAq/E6TPVDDWLh4zwW64KIjuXOJ/s=; b=Vtd+6fiKrGf5Kv+rkk9gDbM+ZniP5naQNsBcVqEj6wyzmmQzXg/Uxs7c+M8ZTPmalJFP65w/u 9PcdU+lX/A0BXh9lrYXPvmIC/Kj1sONa7hM1UvMDaMMglOylTsDhuNb X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= Those operations are the ones from HID, not HID-BPF, and I'd like to reuse hid_bpf_ops as the user facing struct_ops API. Signed-off-by: Benjamin Tissoires --- no changes in v3 no changes in v2 --- drivers/hid/bpf/hid_bpf_dispatch.c | 22 +++++++++++----------- drivers/hid/hid-core.c | 6 +++--- include/linux/hid_bpf.h | 4 ++-- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_d= ispatch.c index 10289f44d0cc..55c9f82fdef0 100644 --- a/drivers/hid/bpf/hid_bpf_dispatch.c +++ b/drivers/hid/bpf/hid_bpf_dispatch.c @@ -21,8 +21,8 @@ #include "hid_bpf_dispatch.h" #include "entrypoints/entrypoints.lskel.h" =20 -struct hid_bpf_ops *hid_bpf_ops; -EXPORT_SYMBOL(hid_bpf_ops); +struct hid_ops *hid_ops; +EXPORT_SYMBOL(hid_ops); =20 /** * hid_bpf_device_event - Called whenever an event is coming in from the d= evice @@ -284,13 +284,13 @@ hid_bpf_attach_prog(unsigned int hid_id, int prog_fd,= __u32 flags) struct device *dev; int err, fd; =20 - if (!hid_bpf_ops) + if (!hid_ops) return -EINVAL; =20 if ((flags & ~HID_BPF_FLAG_MASK)) return -EINVAL; =20 - dev =3D bus_find_device(hid_bpf_ops->bus_type, NULL, &hid_id, device_matc= h_id); + dev =3D bus_find_device(hid_ops->bus_type, NULL, &hid_id, device_match_id= ); if (!dev) return -EINVAL; =20 @@ -335,10 +335,10 @@ hid_bpf_allocate_context(unsigned int hid_id) struct hid_bpf_ctx_kern *ctx_kern =3D NULL; struct device *dev; =20 - if (!hid_bpf_ops) + if (!hid_ops) return NULL; =20 - dev =3D bus_find_device(hid_bpf_ops->bus_type, NULL, &hid_id, device_matc= h_id); + dev =3D bus_find_device(hid_ops->bus_type, NULL, &hid_id, device_match_id= ); if (!dev) return NULL; =20 @@ -386,7 +386,7 @@ __hid_bpf_hw_check_params(struct hid_bpf_ctx *ctx, __u8= *buf, size_t *buf__sz, u32 report_len; =20 /* check arguments */ - if (!ctx || !hid_bpf_ops || !buf) + if (!ctx || !hid_ops || !buf) return -EINVAL; =20 switch (rtype) { @@ -404,7 +404,7 @@ __hid_bpf_hw_check_params(struct hid_bpf_ctx *ctx, __u8= *buf, size_t *buf__sz, hdev =3D (struct hid_device *)ctx->hid; /* discard const */ =20 report_enum =3D hdev->report_enum + rtype; - report =3D hid_bpf_ops->hid_get_report(report_enum, buf); + report =3D hid_ops->hid_get_report(report_enum, buf); if (!report) return -EINVAL; =20 @@ -459,7 +459,7 @@ hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8 *buf, = size_t buf__sz, if (!dma_data) return -ENOMEM; =20 - ret =3D hid_bpf_ops->hid_hw_raw_request(hdev, + ret =3D hid_ops->hid_hw_raw_request(hdev, dma_data[0], dma_data, size, @@ -501,7 +501,7 @@ hid_bpf_hw_output_report(struct hid_bpf_ctx *ctx, __u8 = *buf, size_t buf__sz) if (!dma_data) return -ENOMEM; =20 - ret =3D hid_bpf_ops->hid_hw_output_report(hdev, + ret =3D hid_ops->hid_hw_output_report(hdev, dma_data, size); =20 @@ -534,7 +534,7 @@ hid_bpf_input_report(struct hid_bpf_ctx *ctx, enum hid_= report_type type, u8 *buf =20 hdev =3D (struct hid_device *)ctx->hid; /* discard const */ =20 - return hid_bpf_ops->hid_input_report(hdev, type, buf, size, 0); + return hid_ops->hid_input_report(hdev, type, buf, size, 0); } __bpf_kfunc_end_defs(); =20 diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index b1fa0378e8f4..14bbac432de5 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -2971,7 +2971,7 @@ int hid_check_keys_pressed(struct hid_device *hid) EXPORT_SYMBOL_GPL(hid_check_keys_pressed); =20 #ifdef CONFIG_HID_BPF -static struct hid_bpf_ops hid_ops =3D { +static struct hid_ops __hid_ops =3D { .hid_get_report =3D hid_get_report, .hid_hw_raw_request =3D hid_hw_raw_request, .hid_hw_output_report =3D hid_hw_output_report, @@ -2992,7 +2992,7 @@ static int __init hid_init(void) } =20 #ifdef CONFIG_HID_BPF - hid_bpf_ops =3D &hid_ops; + hid_ops =3D &__hid_ops; #endif =20 ret =3D hidraw_init(); @@ -3011,7 +3011,7 @@ static int __init hid_init(void) static void __exit hid_exit(void) { #ifdef CONFIG_HID_BPF - hid_bpf_ops =3D NULL; + hid_ops =3D NULL; #endif hid_debug_exit(); hidraw_exit(); diff --git a/include/linux/hid_bpf.h b/include/linux/hid_bpf.h index eec2592dec12..a66103618e6e 100644 --- a/include/linux/hid_bpf.h +++ b/include/linux/hid_bpf.h @@ -97,7 +97,7 @@ enum hid_bpf_prog_type { =20 struct hid_report_enum; =20 -struct hid_bpf_ops { +struct hid_ops { struct hid_report *(*hid_get_report)(struct hid_report_enum *report_enum,= const u8 *data); int (*hid_hw_raw_request)(struct hid_device *hdev, unsigned char reportnum, __u8 *buf, @@ -110,7 +110,7 @@ struct hid_bpf_ops { const struct bus_type *bus_type; }; =20 -extern struct hid_bpf_ops *hid_bpf_ops; +extern struct hid_ops *hid_ops; =20 struct hid_bpf_prog_list { u16 prog_idx[HID_BPF_MAX_PROGS_PER_DEV]; --=20 2.44.0 From nobody Fri Dec 19 21:10:08 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AB7C3178371; Sat, 8 Jun 2024 09:01: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=1717837286; cv=none; b=gvfYFOZpZ7pkIOfB0AjT15xgrxp9bVxKSuSlOwDP/wOBOaVB1AmCC5PK16gBHkgQIO6iIaDxsUtHPOfWp+VhzFXLitqsVmUeLgH5+ogNdu8BgZmUWXGunm1E0pbfFxmXHj9k9I0HrfQkNSwAZsfJ3K2wHsrhAGnhxdYMDNOw/U8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717837286; c=relaxed/simple; bh=NoLrJd5sEhcFvxDx8M3VYx3BFl64wagoJzWAatOgIx8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=en+2f085fsKLNne2OXTzXTgx40m4ftvHfIXHhtaj25TCNLSO3gexUcnPkR5WnaMIgEaTmfZ5RDWiy9EiNeb9uD1HagmzFrYgtJI4Bq5IiB8FXqA9/YN6yrja95TMHJV3O/Mjm5fazZMusL/XKd1lfrKiMOItHvnRGbSXgKlrmWc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=dXnmsuem; 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="dXnmsuem" Received: by smtp.kernel.org (Postfix) with ESMTPSA id AC037C4AF0A; Sat, 8 Jun 2024 09:01:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1717837286; bh=NoLrJd5sEhcFvxDx8M3VYx3BFl64wagoJzWAatOgIx8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=dXnmsuemeQxjAA4XasfeL7d4V576vK9yxYH4lD2T57IacO1Ev49h49Lq328En9EWO 2nbAm1ejPl+9ypiKZLFWZE/RLp7s8FHCHiWzSxqRqHC7YEWmerf0zMST++cYHfwo1k xd09XnJ5pzgiBu0lBbLwUiokW/MKd2kcWsjrzPhp2qqMZVzEqYZevN3n8uZB1xoP80 UU6oqR1fcnz4+bbUpfp5QXe21TtmefMapoQp2/efNSb3Uf5weVgDebhsEmPax2R2VL wil9b48L2O3gNz9vpwhZTeqHSSPhX6zo1Gsq66PElrS5xWVDoYVdzhXRiIa0MCk8Iz kjQlHrMxTfEFQ== From: Benjamin Tissoires Date: Sat, 08 Jun 2024 11:01:14 +0200 Subject: [PATCH HID v3 02/16] HID: bpf: add hid_get/put_device() helpers Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240608-hid_bpf_struct_ops-v3-2-6ac6ade58329@kernel.org> References: <20240608-hid_bpf_struct_ops-v3-0-6ac6ade58329@kernel.org> In-Reply-To: <20240608-hid_bpf_struct_ops-v3-0-6ac6ade58329@kernel.org> To: Shuah Khan , Jiri Kosina , Jonathan Corbet , Alexei Starovoitov Cc: linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, linux-input@vger.kernel.org, linux-doc@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1717837279; l=2742; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=NoLrJd5sEhcFvxDx8M3VYx3BFl64wagoJzWAatOgIx8=; b=wOSu1fuRpEKlVNqrOkUqe6GzMxDRCQHI/7fp9HQi+CGJSRCuXY6YUIaVXEA31aabzlvHb0mc2 h65LP1FKmGpBflAOxnsNtjZWHPQ6U1VGePku2hbfX+/pFxFxsz4iTeR X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= no code change, but this way we reduce code duplication and we can export it later. Signed-off-by: Benjamin Tissoires --- no changes in v3 no changes in v2 --- drivers/hid/bpf/hid_bpf_dispatch.c | 47 ++++++++++++++++++++++------------= ---- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_d= ispatch.c index 55c9f82fdef0..c8bb79ce2354 100644 --- a/drivers/hid/bpf/hid_bpf_dispatch.c +++ b/drivers/hid/bpf/hid_bpf_dispatch.c @@ -150,6 +150,25 @@ static int device_match_id(struct device *dev, const v= oid *id) return hdev->id =3D=3D *(int *)id; } =20 +static struct hid_device *hid_get_device(unsigned int hid_id) +{ + struct device *dev; + + if (!hid_ops) + return ERR_PTR(-EINVAL); + + dev =3D bus_find_device(hid_ops->bus_type, NULL, &hid_id, device_match_id= ); + if (!dev) + return ERR_PTR(-EINVAL); + + return to_hid_device(dev); +} + +static void hid_put_device(struct hid_device *hid) +{ + put_device(&hid->dev); +} + static int __hid_bpf_allocate_data(struct hid_device *hdev, u8 **data, u32= *size) { u8 *alloc_data; @@ -281,20 +300,14 @@ hid_bpf_attach_prog(unsigned int hid_id, int prog_fd,= __u32 flags) { struct hid_device *hdev; struct bpf_prog *prog; - struct device *dev; int err, fd; =20 - if (!hid_ops) - return -EINVAL; - if ((flags & ~HID_BPF_FLAG_MASK)) return -EINVAL; =20 - dev =3D bus_find_device(hid_ops->bus_type, NULL, &hid_id, device_match_id= ); - if (!dev) - return -EINVAL; - - hdev =3D to_hid_device(dev); + hdev =3D hid_get_device(hid_id); + if (IS_ERR(hdev)) + return PTR_ERR(hdev); =20 /* * take a ref on the prog itself, it will be released @@ -317,7 +330,7 @@ hid_bpf_attach_prog(unsigned int hid_id, int prog_fd, _= _u32 flags) out_prog_put: bpf_prog_put(prog); out_dev_put: - put_device(dev); + hid_put_device(hdev); return err; } =20 @@ -333,20 +346,14 @@ hid_bpf_allocate_context(unsigned int hid_id) { struct hid_device *hdev; struct hid_bpf_ctx_kern *ctx_kern =3D NULL; - struct device *dev; - - if (!hid_ops) - return NULL; =20 - dev =3D bus_find_device(hid_ops->bus_type, NULL, &hid_id, device_match_id= ); - if (!dev) + hdev =3D hid_get_device(hid_id); + if (IS_ERR(hdev)) return NULL; =20 - hdev =3D to_hid_device(dev); - ctx_kern =3D kzalloc(sizeof(*ctx_kern), GFP_KERNEL); if (!ctx_kern) { - put_device(dev); + hid_put_device(hdev); return NULL; } =20 @@ -373,7 +380,7 @@ hid_bpf_release_context(struct hid_bpf_ctx *ctx) kfree(ctx_kern); =20 /* get_device() is called by bus_find_device() */ - put_device(&hid->dev); + hid_put_device(hid); } =20 static int --=20 2.44.0 From nobody Fri Dec 19 21:10:08 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6D90B178CE8; Sat, 8 Jun 2024 09:01:29 +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=1717837289; cv=none; b=KW9ZxAePKN0NIO6CvBqYWaNnJeVA9ubd7PMxIHFESyNomWu0GDEaF4LrdgW/5QbGSbcBQso4ojI5TSEWXk5ndlPiIDCj5Go2b94UgFZg3+yjYtMnJKsroeWJ3e00qk2ix7D9zqG3hcuqNdCZrWi9UdLcNDm87Zk3ZAEVw8KCDa8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717837289; c=relaxed/simple; bh=OIEmOnY6LUArDtJP6+RTh1DFzFON+zwGu9h57NUoZ0Y=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=hZtRqtswqLJKFTmupjafiPZ7WuAQA1NaSeDgv/IxxI93qM011UY+hvCiNWSmeb+Ap6292Yut6Th4C89LQEHg4IAqmcOIshnPJcCtJ4sFgQI4EsFvFgWA3OCN9b4TEvYVPy4UsSjp8BDDqNsc7ZkxCnSHGCA5aFVXD8k/4NLFs+s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rtLN17tp; 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="rtLN17tp" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 00D63C4AF0B; Sat, 8 Jun 2024 09:01:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1717837289; bh=OIEmOnY6LUArDtJP6+RTh1DFzFON+zwGu9h57NUoZ0Y=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=rtLN17tpHu7UllX6xPAJV+l+YtENX0ut0/+vW4XQ0U9vIfG8VZJS5df349tVUUF1p MtY6W0C0k/P2KdnisOHt6ciLNyW1vhDQhZHR0/p1rjblxTyo25iBWIw0iD4umlQi/9 0mDYPCw9yKKpTykLTKXdFddEggxjbsQltt+jkpmsVzKToamgx0fryQzLX/5IwJWIe7 JCKAR3b0uC7P4YtlsuO1TxiwEDcs+II6fz2HYRLP917khO/IOwCA9rR+cDi/w83qyb CHXfRK6haTduT3MvqfBjojNNynfT4uy5tVCkRB1GV9muqo5BWLbwZRKoA51iEfWUWn S5vMOqFRCZ2gQ== From: Benjamin Tissoires Date: Sat, 08 Jun 2024 11:01:15 +0200 Subject: [PATCH HID v3 03/16] HID: bpf: implement HID-BPF through bpf_struct_ops Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240608-hid_bpf_struct_ops-v3-3-6ac6ade58329@kernel.org> References: <20240608-hid_bpf_struct_ops-v3-0-6ac6ade58329@kernel.org> In-Reply-To: <20240608-hid_bpf_struct_ops-v3-0-6ac6ade58329@kernel.org> To: Shuah Khan , Jiri Kosina , Jonathan Corbet , Alexei Starovoitov Cc: linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, linux-input@vger.kernel.org, linux-doc@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1717837279; l=17315; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=OIEmOnY6LUArDtJP6+RTh1DFzFON+zwGu9h57NUoZ0Y=; b=zXhVrGzYGWDHlSifx6yxxEWcWpP+pXqUdyHcTXkDV9uSccNpXMIZ5kgb8xAq7hwLP6c7q6lSp EHrgKQ2fg6sC5HQ71jB+R/ngd4tAIkZHtdnFfAlPEl6P33CxxDXrINU X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= We do this implementation in several steps to not have the CI failing: - first (this patch), we add struct_ops while keeping the existing infra available - then we change the selftests, the examples and the existing in-tree HID-BPF programs - then we remove the existing trace points making old HID-BPF obsolete There are a few advantages of struct_ops over tracing: - compatibility with sleepable programs (for hid_hw_raw_request() in a later patch) - a lot simpler in the kernel: it's a simple rcu protected list - we can add more parameters to the function called without much trouble - the "attach" is now generic through BPF-core: the caller just needs to set hid_id and flags before calling __load(). - all the BPF tough part is not handled in BPF-core through generic processing - hid_bpf_ctx is now only writable where it needs be Signed-off-by: Benjamin Tissoires Acked-by: Alexei Starovoitov --- changes in v3: - change private/public misleading comments - remove cache line comments/attribute - change mutex prog_list_lock comment changes in v2: - drop custom enum hid_bpf_attach_flags (use BPF_F_BEFORE instead) - fix member offset in .ops_init_member() --- drivers/hid/bpf/Makefile | 2 +- drivers/hid/bpf/hid_bpf_dispatch.c | 52 +++++++- drivers/hid/bpf/hid_bpf_dispatch.h | 4 + drivers/hid/bpf/hid_bpf_jmp_table.c | 3 + drivers/hid/bpf/hid_bpf_struct_ops.c | 247 +++++++++++++++++++++++++++++++= ++++ include/linux/hid_bpf.h | 61 ++++++++- 6 files changed, 360 insertions(+), 9 deletions(-) diff --git a/drivers/hid/bpf/Makefile b/drivers/hid/bpf/Makefile index cf55120cf7d6..1cb3f31e9335 100644 --- a/drivers/hid/bpf/Makefile +++ b/drivers/hid/bpf/Makefile @@ -8,4 +8,4 @@ LIBBPF_INCLUDE =3D $(srctree)/tools/lib obj-$(CONFIG_HID_BPF) +=3D hid_bpf.o CFLAGS_hid_bpf_dispatch.o +=3D -I$(LIBBPF_INCLUDE) CFLAGS_hid_bpf_jmp_table.o +=3D -I$(LIBBPF_INCLUDE) -hid_bpf-objs +=3D hid_bpf_dispatch.o hid_bpf_jmp_table.o +hid_bpf-objs +=3D hid_bpf_dispatch.o hid_bpf_jmp_table.o hid_bpf_struct_op= s.o diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_d= ispatch.c index c8bb79ce2354..7216c3c7713d 100644 --- a/drivers/hid/bpf/hid_bpf_dispatch.c +++ b/drivers/hid/bpf/hid_bpf_dispatch.c @@ -58,6 +58,7 @@ dispatch_hid_bpf_device_event(struct hid_device *hdev, en= um hid_report_type type }, .data =3D hdev->bpf.device_data, }; + struct hid_bpf_ops *e; int ret; =20 if (type >=3D HID_REPORT_TYPES) @@ -70,9 +71,25 @@ dispatch_hid_bpf_device_event(struct hid_device *hdev, e= num hid_report_type type memset(ctx_kern.data, 0, hdev->bpf.allocated_data); memcpy(ctx_kern.data, data, *size); =20 + rcu_read_lock(); + list_for_each_entry_rcu(e, &hdev->bpf.prog_list, list) { + if (e->hid_device_event) { + ret =3D e->hid_device_event(&ctx_kern.ctx, type); + if (ret < 0) { + rcu_read_unlock(); + return ERR_PTR(ret); + } + + if (ret) + ctx_kern.ctx.retval =3D ret; + } + } + rcu_read_unlock(); + ret =3D hid_bpf_prog_run(hdev, HID_BPF_PROG_TYPE_DEVICE_EVENT, &ctx_kern); if (ret < 0) return ERR_PTR(ret); + ret =3D ctx_kern.ctx.retval; =20 if (ret) { if (ret > ctx_kern.ctx.allocated_size) @@ -122,7 +139,10 @@ u8 *call_hid_bpf_rdesc_fixup(struct hid_device *hdev, = u8 *rdesc, unsigned int *s =20 memcpy(ctx_kern.data, rdesc, min_t(unsigned int, *size, HID_MAX_DESCRIPTO= R_SIZE)); =20 - ret =3D hid_bpf_prog_run(hdev, HID_BPF_PROG_TYPE_RDESC_FIXUP, &ctx_kern); + if (hdev->bpf.rdesc_ops) + ret =3D hdev->bpf.rdesc_ops->hid_rdesc_fixup(&ctx_kern.ctx); + else + ret =3D hid_bpf_prog_run(hdev, HID_BPF_PROG_TYPE_RDESC_FIXUP, &ctx_kern); if (ret < 0) goto ignore_bpf; =20 @@ -150,7 +170,7 @@ static int device_match_id(struct device *dev, const vo= id *id) return hdev->id =3D=3D *(int *)id; } =20 -static struct hid_device *hid_get_device(unsigned int hid_id) +struct hid_device *hid_get_device(unsigned int hid_id) { struct device *dev; =20 @@ -164,7 +184,7 @@ static struct hid_device *hid_get_device(unsigned int h= id_id) return to_hid_device(dev); } =20 -static void hid_put_device(struct hid_device *hid) +void hid_put_device(struct hid_device *hid) { put_device(&hid->dev); } @@ -205,7 +225,7 @@ static int __hid_bpf_allocate_data(struct hid_device *h= dev, u8 **data, u32 *size return 0; } =20 -static int hid_bpf_allocate_event_data(struct hid_device *hdev) +int hid_bpf_allocate_event_data(struct hid_device *hdev) { /* hdev->bpf.device_data is already allocated, abort */ if (hdev->bpf.device_data) @@ -592,14 +612,22 @@ static const struct btf_kfunc_id_set hid_bpf_syscall_= kfunc_set =3D { =20 int hid_bpf_connect_device(struct hid_device *hdev) { - struct hid_bpf_prog_list *prog_list; + bool need_to_allocate =3D false; + struct hid_bpf_ops *e; =20 rcu_read_lock(); - prog_list =3D rcu_dereference(hdev->bpf.progs[HID_BPF_PROG_TYPE_DEVICE_EV= ENT]); + list_for_each_entry_rcu(e, &hdev->bpf.prog_list, list) { + if (e->hid_device_event) { + need_to_allocate =3D true; + break; + } + } + if (rcu_dereference(hdev->bpf.progs[HID_BPF_PROG_TYPE_DEVICE_EVENT])) + need_to_allocate =3D true; rcu_read_unlock(); =20 /* only allocate BPF data if there are programs attached */ - if (!prog_list) + if (!need_to_allocate) return 0; =20 return hid_bpf_allocate_event_data(hdev); @@ -623,12 +651,15 @@ void hid_bpf_destroy_device(struct hid_device *hdev) hdev->bpf.destroyed =3D true; =20 __hid_bpf_destroy_device(hdev); + __hid_bpf_ops_destroy_device(hdev); } EXPORT_SYMBOL_GPL(hid_bpf_destroy_device); =20 void hid_bpf_device_init(struct hid_device *hdev) { spin_lock_init(&hdev->bpf.progs_lock); + INIT_LIST_HEAD(&hdev->bpf.prog_list); + mutex_init(&hdev->bpf.prog_list_lock); } EXPORT_SYMBOL_GPL(hid_bpf_device_init); =20 @@ -662,6 +693,13 @@ static int __init hid_bpf_init(void) return 0; } =20 + /* register struct_ops kfuncs after we are sure we can load our preloaded= bpf program */ + err =3D register_btf_kfunc_id_set(BPF_PROG_TYPE_STRUCT_OPS, &hid_bpf_kfun= c_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 prog= ram */ err =3D register_btf_kfunc_id_set(BPF_PROG_TYPE_SYSCALL, &hid_bpf_syscall= _kfunc_set); if (err) { diff --git a/drivers/hid/bpf/hid_bpf_dispatch.h b/drivers/hid/bpf/hid_bpf_d= ispatch.h index fbe0639d09f2..e52c43d81650 100644 --- a/drivers/hid/bpf/hid_bpf_dispatch.h +++ b/drivers/hid/bpf/hid_bpf_dispatch.h @@ -10,12 +10,16 @@ struct hid_bpf_ctx_kern { u8 *data; }; =20 +struct hid_device *hid_get_device(unsigned int hid_id); +void hid_put_device(struct hid_device *hid); +int hid_bpf_allocate_event_data(struct hid_device *hdev); 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, struct bpf_prog *prog, __u32 flags); void __hid_bpf_destroy_device(struct hid_device *hdev); +void __hid_bpf_ops_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); int hid_bpf_reconnect(struct hid_device *hdev); diff --git a/drivers/hid/bpf/hid_bpf_jmp_table.c b/drivers/hid/bpf/hid_bpf_= jmp_table.c index aa8e1c79cdf5..8a54ba447718 100644 --- a/drivers/hid/bpf/hid_bpf_jmp_table.c +++ b/drivers/hid/bpf/hid_bpf_jmp_table.c @@ -81,6 +81,9 @@ static int hid_bpf_program_count(struct hid_device *hdev, if (type >=3D HID_BPF_PROG_TYPE_MAX) return -EINVAL; =20 + if (type =3D=3D HID_BPF_PROG_TYPE_RDESC_FIXUP && hdev->bpf.rdesc_ops) + n +=3D 1; + FOR_ENTRIES(i, jmp_table.tail, jmp_table.head) { struct hid_bpf_prog_entry *entry =3D &jmp_table.entries[i]; =20 diff --git a/drivers/hid/bpf/hid_bpf_struct_ops.c b/drivers/hid/bpf/hid_bpf= _struct_ops.c new file mode 100644 index 000000000000..9192c66cde20 --- /dev/null +++ b/drivers/hid/bpf/hid_bpf_struct_ops.c @@ -0,0 +1,247 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/* + * HID-BPF support for Linux + * + * Copyright (c) 2024 Benjamin Tissoires + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hid_bpf_dispatch.h" + +static struct btf *hid_bpf_ops_btf; + +static int hid_bpf_ops_init(struct btf *btf) +{ + hid_bpf_ops_btf =3D btf; + return 0; +} + +static bool hid_bpf_ops_is_valid_access(int off, int size, + enum bpf_access_type type, + const struct bpf_prog *prog, + struct bpf_insn_access_aux *info) +{ + return bpf_tracing_btf_ctx_access(off, size, type, prog, info); +} + +static int hid_bpf_ops_check_member(const struct btf_type *t, + const struct btf_member *member, + const struct bpf_prog *prog) +{ + u32 moff =3D __btf_member_bit_offset(t, member) / 8; + + switch (moff) { + case offsetof(struct hid_bpf_ops, hid_rdesc_fixup): + break; + default: + if (prog->sleepable) + return -EINVAL; + } + + return 0; +} + +static int hid_bpf_ops_btf_struct_access(struct bpf_verifier_log *log, + const struct bpf_reg_state *reg, + int off, int size) +{ + const struct btf_type *state; + const struct btf_type *t; + s32 type_id; + + type_id =3D btf_find_by_name_kind(reg->btf, "hid_bpf_ctx", + BTF_KIND_STRUCT); + if (type_id < 0) + return -EINVAL; + + t =3D btf_type_by_id(reg->btf, reg->btf_id); + state =3D btf_type_by_id(reg->btf, type_id); + if (t !=3D state) { + bpf_log(log, "only access to hid_bpf_ctx is supported\n"); + return -EACCES; + } + + /* out-of-bound access in hid_bpf_ctx */ + if (off + size > sizeof(struct hid_bpf_ctx)) { + bpf_log(log, "write access at off %d with size %d\n", off, size); + return -EACCES; + } + + if (off < offsetof(struct hid_bpf_ctx, retval)) { + bpf_log(log, + "write access at off %d with size %d on read-only part of hid_bpf_ctx\n= ", + off, size); + return -EACCES; + } + + return NOT_INIT; +} + +static const struct bpf_verifier_ops hid_bpf_verifier_ops =3D { + .is_valid_access =3D hid_bpf_ops_is_valid_access, + .btf_struct_access =3D hid_bpf_ops_btf_struct_access, +}; + +static int hid_bpf_ops_init_member(const struct btf_type *t, + const struct btf_member *member, + void *kdata, const void *udata) +{ + u32 moff =3D __btf_member_bit_offset(t, member) / 8; + u32 flags; + + switch (moff) { + case offsetof(struct hid_bpf_ops, hid_id): + /* For hid_id and flags fields, this function has to copy it + * and return 1 to indicate that the data has been handled by + * the struct_ops type, or the verifier will reject the map if + * the value of those fields is not zero. + */ + ((struct hid_bpf_ops *)kdata)->hid_id =3D ((struct hid_bpf_ops *)udata)-= >hid_id; + return 1; + case offsetof(struct hid_bpf_ops, flags): + flags =3D ((struct hid_bpf_ops *)udata)->flags; + if (flags & ~BPF_F_BEFORE) + return -EINVAL; + ((struct hid_bpf_ops *)kdata)->flags =3D flags; + return 1; + } + return 0; +} + +static int hid_bpf_reg(void *kdata) +{ + struct hid_bpf_ops *ops =3D kdata; + struct hid_device *hdev; + int count, err =3D 0; + + hdev =3D hid_get_device(ops->hid_id); + if (IS_ERR(hdev)) + return PTR_ERR(hdev); + + ops->hdev =3D hdev; + + mutex_lock(&hdev->bpf.prog_list_lock); + + count =3D list_count_nodes(&hdev->bpf.prog_list); + if (count >=3D HID_BPF_MAX_PROGS_PER_DEV) { + err =3D -E2BIG; + goto out_unlock; + } + + if (ops->hid_rdesc_fixup) { + if (hdev->bpf.rdesc_ops) { + err =3D -EINVAL; + goto out_unlock; + } + + hdev->bpf.rdesc_ops =3D ops; + } + + if (ops->hid_device_event) { + err =3D hid_bpf_allocate_event_data(hdev); + if (err) + goto out_unlock; + } + + if (ops->flags & BPF_F_BEFORE) + list_add_rcu(&ops->list, &hdev->bpf.prog_list); + else + list_add_tail_rcu(&ops->list, &hdev->bpf.prog_list); + +out_unlock: + mutex_unlock(&hdev->bpf.prog_list_lock); + + if (err) { + if (hdev->bpf.rdesc_ops =3D=3D ops) + hdev->bpf.rdesc_ops =3D NULL; + hid_put_device(hdev); + } else if (ops->hid_rdesc_fixup) { + hid_bpf_reconnect(hdev); + } + + return err; +} + +static void hid_bpf_unreg(void *kdata) +{ + struct hid_bpf_ops *ops =3D kdata; + struct hid_device *hdev; + bool reconnect =3D false; + + hdev =3D ops->hdev; + + /* check if __hid_bpf_ops_destroy_device() has been called */ + if (!hdev) + return; + + mutex_lock(&hdev->bpf.prog_list_lock); + + list_del_rcu(&ops->list); + + reconnect =3D hdev->bpf.rdesc_ops =3D=3D ops; + if (reconnect) + hdev->bpf.rdesc_ops =3D NULL; + + mutex_unlock(&hdev->bpf.prog_list_lock); + + if (reconnect) + hid_bpf_reconnect(hdev); + + hid_put_device(hdev); +} + +static int __hid_bpf_device_event(struct hid_bpf_ctx *ctx, enum hid_report= _type type) +{ + return 0; +} + +static int __hid_bpf_rdesc_fixup(struct hid_bpf_ctx *ctx) +{ + return 0; +} + +static struct hid_bpf_ops __bpf_hid_bpf_ops =3D { + .hid_device_event =3D __hid_bpf_device_event, + .hid_rdesc_fixup =3D __hid_bpf_rdesc_fixup, +}; + +static struct bpf_struct_ops bpf_hid_bpf_ops =3D { + .verifier_ops =3D &hid_bpf_verifier_ops, + .init =3D hid_bpf_ops_init, + .check_member =3D hid_bpf_ops_check_member, + .init_member =3D hid_bpf_ops_init_member, + .reg =3D hid_bpf_reg, + .unreg =3D hid_bpf_unreg, + .name =3D "hid_bpf_ops", + .cfi_stubs =3D &__bpf_hid_bpf_ops, + .owner =3D THIS_MODULE, +}; + +void __hid_bpf_ops_destroy_device(struct hid_device *hdev) +{ + struct hid_bpf_ops *e; + + rcu_read_lock(); + list_for_each_entry_rcu(e, &hdev->bpf.prog_list, list) { + hid_put_device(hdev); + e->hdev =3D NULL; + } + rcu_read_unlock(); +} + +static int __init hid_bpf_struct_ops_init(void) +{ + return register_bpf_struct_ops(&bpf_hid_bpf_ops, hid_bpf_ops); +} +late_initcall(hid_bpf_struct_ops_init); diff --git a/include/linux/hid_bpf.h b/include/linux/hid_bpf.h index a66103618e6e..c4f4ce10b7dd 100644 --- a/include/linux/hid_bpf.h +++ b/include/linux/hid_bpf.h @@ -65,11 +65,12 @@ struct hid_bpf_ctx { * @HID_BPF_FLAG_INSERT_HEAD: insert the given program before any other pr= ogram * currently attached to the device. This doesn= 't * guarantee that this program will always be f= irst - * @HID_BPF_FLAG_MAX: sentinel value, not to be used by the callers */ enum hid_bpf_attach_flags { HID_BPF_FLAG_NONE =3D 0, HID_BPF_FLAG_INSERT_HEAD =3D _BITUL(0), + + /* private: internal use only */ HID_BPF_FLAG_MAX, }; =20 @@ -112,6 +113,60 @@ struct hid_ops { =20 extern struct hid_ops *hid_ops; =20 +/** + * struct hid_bpf_ops - A BPF struct_ops of callbacks allowing to attach H= ID-BPF + * programs to a HID device + * @hid_id: the HID uniq ID to attach to. This is writeable before ``load(= )``, and + * cannot be changed after + * @flags: flags used while attaching the struct_ops to the device. Curren= tly only + * available value is %0 or ``BPF_F_BEFORE``. + * Writeable only before ``load()`` + */ +struct hid_bpf_ops { + /* hid_id needs to stay first so we can easily change it + * from userspace. + */ + int hid_id; + u32 flags; + + /* private: do not show up in the docs */ + struct list_head list; + + /* public: rest should show up in the docs */ + + /** + * @hid_device_event: called whenever an event is coming in from the devi= ce + * + * It has the following arguments: + * + * ``ctx``: The HID-BPF context as &struct hid_bpf_ctx + * + * Return: %0 on success and keep processing; a positive + * value to change the incoming size buffer; a negative + * error code to interrupt the processing of this event + * + * Context: Interrupt context. + */ + int (*hid_device_event)(struct hid_bpf_ctx *ctx, enum hid_report_type rep= ort_type); + + /** + * @hid_rdesc_fixup: called when the probe function parses the report des= criptor + * of the HID device + * + * It has the following arguments: + * + * ``ctx``: The HID-BPF context as &struct hid_bpf_ctx + * + * Return: %0 on success and keep processing; a positive + * value to change the incoming size buffer; a negative + * error code to interrupt the processing of this device + */ + int (*hid_rdesc_fixup)(struct hid_bpf_ctx *ctx); + + /* private: do not show up in the docs */ + struct hid_device *hdev; +}; + struct hid_bpf_prog_list { u16 prog_idx[HID_BPF_MAX_PROGS_PER_DEV]; u8 prog_cnt; @@ -129,6 +184,10 @@ struct hid_bpf { bool destroyed; /* prevents the assignment of any progs */ =20 spinlock_t progs_lock; /* protects RCU update of progs */ + + struct hid_bpf_ops *rdesc_ops; + struct list_head prog_list; + struct mutex prog_list_lock; /* protects prog_list update */ }; =20 /* specific HID-BPF link when a program is attached to a device */ --=20 2.44.0 From nobody Fri Dec 19 21:10:08 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7C889179652; Sat, 8 Jun 2024 09:01:31 +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=1717837291; cv=none; b=lUbJC2vmzSPCAucrjFbYNC9IOs/fzhNwffH+PP9/aiNO+9eoquxtxfvNqN54Azphh0tY7vhnwuD0IP2JJq65nW6a1BltZr4Y0kMtkc2Ml6TGRP3jxjGGGk+p3HR/a4IZI2P/xdgzrROedScF1rv92gfPV/+hfkHXiolzSH5k1Bc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717837291; c=relaxed/simple; bh=h5CB26I20SEzuJWzCaBWDsFR6O9I0MvQtx7Y5XppM6c=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Z0eE3Pl1FBurJ/khZcVoX5Mf9C28OQfMjPGM9sz7Vy0Oi1C6J5Q//NxE5J2aUO2jd1s9+iLJpcl0oWtJKHkPow1kuUHR3jSoBxLL1/7vZflhegMD8bJXquL/JJ9R8HOXtX0n0wLcdQ0nuFPOEs+NfTyp/5DQJuPEkO4VxxIZCGo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=PLqrZXOy; 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="PLqrZXOy" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6D71CC4AF07; Sat, 8 Jun 2024 09:01:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1717837291; bh=h5CB26I20SEzuJWzCaBWDsFR6O9I0MvQtx7Y5XppM6c=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=PLqrZXOyRKtqGn6N5VT6i8BZ8S8sYcwNW0c97XgQWgfbEQGM/+7ViF3g+hk+gB9Uq ITN91RFYGr/2m5r5P5RGPdXcuhf2345hixY+9XYuRe5xax4XH6vhJxhGvWUi8dw2se dYHT9aumq2kNfyg+FgHuQY9F0ARwqBNLlEc5egLQtIFHQFRj9EV5oFaoL3WXkqqao2 Nl+Mm2xPL7eq2iehm4YQgpacd2ZVPuKr8LT+QzG1dr8ydqL8VbNcUAAqwQL8ZxQaV1 tVHTsZTZQDHOKNG1QsdRMPG5CVuoTDyXB/ZGxrbtRd2mKVFnayQEyZp7gc2v/GN1NJ l9E8IGRF7rb2Q== From: Benjamin Tissoires Date: Sat, 08 Jun 2024 11:01:16 +0200 Subject: [PATCH HID v3 04/16] selftests/hid: convert the hid_bpf selftests with struct_ops Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240608-hid_bpf_struct_ops-v3-4-6ac6ade58329@kernel.org> References: <20240608-hid_bpf_struct_ops-v3-0-6ac6ade58329@kernel.org> In-Reply-To: <20240608-hid_bpf_struct_ops-v3-0-6ac6ade58329@kernel.org> To: Shuah Khan , Jiri Kosina , Jonathan Corbet , Alexei Starovoitov Cc: linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, linux-input@vger.kernel.org, linux-doc@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1717837279; l=11693; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=h5CB26I20SEzuJWzCaBWDsFR6O9I0MvQtx7Y5XppM6c=; b=XFRZmWKC09Td+NEVlqT07pg8hNm0STgORW5ZFR/2vhHsKELOKL4dznqQd11rYI98vw0J+pgTD Y/MIgeX5VmoBOGstQXtnDDMRrQzfRtzGxeUQdD2CkbL1x4n/MwJmMWf X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= We drop the need for the attach() bpf syscall, but we need to set up the hid_id field before calling __load(). The .bpf.c part is mechanical: we create one struct_ops per HID-BPF program, as all the tests are for one program at a time. Signed-off-by: Benjamin Tissoires --- no changes in v3 changes in v2: - use BPF_F_BEFORE --- tools/testing/selftests/hid/hid_bpf.c | 59 +++++++++-------- tools/testing/selftests/hid/progs/hid.c | 76 +++++++++++++++---= ---- .../testing/selftests/hid/progs/hid_bpf_helpers.h | 19 ++---- 3 files changed, 89 insertions(+), 65 deletions(-) diff --git a/tools/testing/selftests/hid/hid_bpf.c b/tools/testing/selftest= s/hid/hid_bpf.c index f825623e3edc..967dfe6b58cb 100644 --- a/tools/testing/selftests/hid/hid_bpf.c +++ b/tools/testing/selftests/hid/hid_bpf.c @@ -460,7 +460,7 @@ FIXTURE(hid_bpf) { int hid_id; pthread_t tid; struct hid *skel; - int hid_links[3]; /* max number of programs loaded in a single test */ + struct bpf_link *hid_links[3]; /* max number of programs loaded in a sing= le test */ }; static void detach_bpf(FIXTURE_DATA(hid_bpf) * self) { @@ -472,7 +472,7 @@ static void detach_bpf(FIXTURE_DATA(hid_bpf) * self) =20 for (i =3D 0; i < ARRAY_SIZE(self->hid_links); i++) { if (self->hid_links[i]) - close(self->hid_links[i]); + bpf_link__destroy(self->hid_links[i]); } =20 hid__destroy(self->skel); @@ -527,14 +527,7 @@ static void load_programs(const struct test_program pr= ograms[], FIXTURE_DATA(hid_bpf) * self, const FIXTURE_VARIANT(hid_bpf) * variant) { - int attach_fd, err =3D -EINVAL; - struct attach_prog_args args =3D { - .retval =3D -1, - }; - DECLARE_LIBBPF_OPTS(bpf_test_run_opts, tattr, - .ctx_in =3D &args, - .ctx_size_in =3D sizeof(args), - ); + int err =3D -EINVAL; =20 ASSERT_LE(progs_count, ARRAY_SIZE(self->hid_links)) TH_LOG("too many programs are to be loaded"); @@ -545,35 +538,41 @@ static void load_programs(const struct test_program p= rograms[], =20 for (int i =3D 0; i < progs_count; i++) { struct bpf_program *prog; + struct bpf_map *map; + int *ops_hid_id; =20 prog =3D bpf_object__find_program_by_name(*self->skel->skeleton->obj, programs[i].name); ASSERT_OK_PTR(prog) TH_LOG("can not find program by name '%s'", programs= [i].name); =20 bpf_program__set_autoload(prog, true); + + map =3D bpf_object__find_map_by_name(*self->skel->skeleton->obj, + programs[i].name + 4); + ASSERT_OK_PTR(map) TH_LOG("can not find struct_ops by name '%s'", + programs[i].name + 4); + + /* hid_id is the first field of struct hid_bpf_ops */ + ops_hid_id =3D bpf_map__initial_value(map, NULL); + ASSERT_OK_PTR(ops_hid_id) TH_LOG("unable to retrieve struct_ops data"); + + *ops_hid_id =3D self->hid_id; } =20 err =3D hid__load(self->skel); ASSERT_OK(err) TH_LOG("hid_skel_load failed: %d", err); =20 - attach_fd =3D bpf_program__fd(self->skel->progs.attach_prog); - ASSERT_GE(attach_fd, 0) TH_LOG("locate attach_prog: %d", attach_fd); - for (int i =3D 0; i < progs_count; i++) { - struct bpf_program *prog; + struct bpf_map *map; =20 - prog =3D bpf_object__find_program_by_name(*self->skel->skeleton->obj, - programs[i].name); - ASSERT_OK_PTR(prog) TH_LOG("can not find program by name '%s'", programs= [i].name); - - args.prog_fd =3D bpf_program__fd(prog); - args.hid =3D self->hid_id; - args.insert_head =3D programs[i].insert_head; - err =3D bpf_prog_test_run_opts(attach_fd, &tattr); - ASSERT_GE(args.retval, 0) - TH_LOG("attach_hid(%s): %d", programs[i].name, args.retval); + map =3D bpf_object__find_map_by_name(*self->skel->skeleton->obj, + programs[i].name + 4); + ASSERT_OK_PTR(map) TH_LOG("can not find struct_ops by name '%s'", + programs[i].name + 4); =20 - self->hid_links[i] =3D args.retval; + self->hid_links[i] =3D bpf_map__attach_struct_ops(map); + ASSERT_OK_PTR(self->hid_links[i]) TH_LOG("failed to attach struct ops '%= s'", + programs[i].name + 4); } =20 self->hidraw_fd =3D open_hidraw(self->dev_id); @@ -648,13 +647,17 @@ TEST_F(hid_bpf, test_attach_detach) { .name =3D "hid_first_event" }, { .name =3D "hid_second_event" }, }; + struct bpf_link *link; __u8 buf[10] =3D {0}; - int err, link; + int err, link_fd; =20 LOAD_PROGRAMS(progs); =20 link =3D self->hid_links[0]; - ASSERT_GT(link, 0) TH_LOG("HID-BPF link not created"); + ASSERT_OK_PTR(link) TH_LOG("HID-BPF link not created"); + + link_fd =3D bpf_link__fd(link); + ASSERT_GE(link_fd, 0) TH_LOG("HID-BPF link FD not valid"); =20 /* inject one event */ buf[0] =3D 1; @@ -673,7 +676,7 @@ TEST_F(hid_bpf, test_attach_detach) =20 /* pin the first program and immediately unpin it */ #define PIN_PATH "/sys/fs/bpf/hid_first_event" - err =3D bpf_obj_pin(link, PIN_PATH); + err =3D bpf_obj_pin(link_fd, PIN_PATH); ASSERT_OK(err) TH_LOG("error while calling bpf_obj_pin"); remove(PIN_PATH); #undef PIN_PATH diff --git a/tools/testing/selftests/hid/progs/hid.c b/tools/testing/selfte= sts/hid/progs/hid.c index f67d35def142..614f1aa32649 100644 --- a/tools/testing/selftests/hid/progs/hid.c +++ b/tools/testing/selftests/hid/progs/hid.c @@ -14,8 +14,8 @@ struct attach_prog_args { __u64 callback_check =3D 52; __u64 callback2_check =3D 52; =20 -SEC("?fmod_ret/hid_bpf_device_event") -int BPF_PROG(hid_first_event, struct hid_bpf_ctx *hid_ctx) +SEC("?struct_ops/hid_device_event") +int BPF_PROG(hid_first_event, struct hid_bpf_ctx *hid_ctx, enum hid_report= _type type) { __u8 *rw_data =3D hid_bpf_get_data(hid_ctx, 0 /* offset */, 3 /* size */); =20 @@ -29,8 +29,14 @@ int BPF_PROG(hid_first_event, struct hid_bpf_ctx *hid_ct= x) return hid_ctx->size; } =20 -SEC("?fmod_ret/hid_bpf_device_event") -int BPF_PROG(hid_second_event, struct hid_bpf_ctx *hid_ctx) +SEC(".struct_ops.link") +struct hid_bpf_ops first_event =3D { + .hid_device_event =3D (void *)hid_first_event, + .hid_id =3D 2, +}; + +SEC("?struct_ops/hid_device_event") +int BPF_PROG(hid_second_event, struct hid_bpf_ctx *hid_ctx, enum hid_repor= t_type type) { __u8 *rw_data =3D hid_bpf_get_data(hid_ctx, 0 /* offset */, 4 /* size */); =20 @@ -42,8 +48,13 @@ int BPF_PROG(hid_second_event, struct hid_bpf_ctx *hid_c= tx) return hid_ctx->size; } =20 -SEC("?fmod_ret/hid_bpf_device_event") -int BPF_PROG(hid_change_report_id, struct hid_bpf_ctx *hid_ctx) +SEC(".struct_ops.link") +struct hid_bpf_ops second_event =3D { + .hid_device_event =3D (void *)hid_second_event, +}; + +SEC("?struct_ops/hid_device_event") +int BPF_PROG(hid_change_report_id, struct hid_bpf_ctx *hid_ctx, enum hid_r= eport_type type) { __u8 *rw_data =3D hid_bpf_get_data(hid_ctx, 0 /* offset */, 3 /* size */); =20 @@ -55,15 +66,10 @@ int BPF_PROG(hid_change_report_id, struct hid_bpf_ctx *= hid_ctx) return 9; } =20 -SEC("syscall") -int attach_prog(struct attach_prog_args *ctx) -{ - ctx->retval =3D hid_bpf_attach_prog(ctx->hid, - ctx->prog_fd, - ctx->insert_head ? HID_BPF_FLAG_INSERT_HEAD : - HID_BPF_FLAG_NONE); - return 0; -} +SEC(".struct_ops.link") +struct hid_bpf_ops change_report_id =3D { + .hid_device_event =3D (void *)hid_change_report_id, +}; =20 struct hid_hw_request_syscall_args { /* data needs to come at offset 0 so we can use it in calls */ @@ -181,7 +187,12 @@ static const __u8 rdesc[] =3D { 0xc0, /* END_COLLECTION */ }; =20 -SEC("?fmod_ret/hid_bpf_rdesc_fixup") +/* + * the following program is marked as sleepable (struct_ops.s). + * This is not strictly mandatory but is a nice test for + * sleepable struct_ops + */ +SEC("?struct_ops.s/hid_rdesc_fixup") int BPF_PROG(hid_rdesc_fixup, struct hid_bpf_ctx *hid_ctx) { __u8 *data =3D hid_bpf_get_data(hid_ctx, 0 /* offset */, 4096 /* size */); @@ -200,8 +211,13 @@ int BPF_PROG(hid_rdesc_fixup, struct hid_bpf_ctx *hid_= ctx) return sizeof(rdesc) + 73; } =20 -SEC("?fmod_ret/hid_bpf_device_event") -int BPF_PROG(hid_test_insert1, struct hid_bpf_ctx *hid_ctx) +SEC(".struct_ops.link") +struct hid_bpf_ops rdesc_fixup =3D { + .hid_rdesc_fixup =3D (void *)hid_rdesc_fixup, +}; + +SEC("?struct_ops/hid_device_event") +int BPF_PROG(hid_test_insert1, struct hid_bpf_ctx *hid_ctx, enum hid_repor= t_type type) { __u8 *data =3D hid_bpf_get_data(hid_ctx, 0 /* offset */, 4 /* size */); =20 @@ -217,8 +233,14 @@ int BPF_PROG(hid_test_insert1, struct hid_bpf_ctx *hid= _ctx) return 0; } =20 -SEC("?fmod_ret/hid_bpf_device_event") -int BPF_PROG(hid_test_insert2, struct hid_bpf_ctx *hid_ctx) +SEC(".struct_ops.link") +struct hid_bpf_ops test_insert1 =3D { + .hid_device_event =3D (void *)hid_test_insert1, + .flags =3D BPF_F_BEFORE, +}; + +SEC("?struct_ops/hid_device_event") +int BPF_PROG(hid_test_insert2, struct hid_bpf_ctx *hid_ctx, enum hid_repor= t_type type) { __u8 *data =3D hid_bpf_get_data(hid_ctx, 0 /* offset */, 4 /* size */); =20 @@ -234,8 +256,13 @@ int BPF_PROG(hid_test_insert2, struct hid_bpf_ctx *hid= _ctx) return 0; } =20 -SEC("?fmod_ret/hid_bpf_device_event") -int BPF_PROG(hid_test_insert3, struct hid_bpf_ctx *hid_ctx) +SEC(".struct_ops.link") +struct hid_bpf_ops test_insert2 =3D { + .hid_device_event =3D (void *)hid_test_insert2, +}; + +SEC("?struct_ops/hid_device_event") +int BPF_PROG(hid_test_insert3, struct hid_bpf_ctx *hid_ctx, enum hid_repor= t_type type) { __u8 *data =3D hid_bpf_get_data(hid_ctx, 0 /* offset */, 4 /* size */); =20 @@ -250,3 +277,8 @@ int BPF_PROG(hid_test_insert3, struct hid_bpf_ctx *hid_= ctx) =20 return 0; } + +SEC(".struct_ops.link") +struct hid_bpf_ops test_insert3 =3D { + .hid_device_event =3D (void *)hid_test_insert3, +}; diff --git a/tools/testing/selftests/hid/progs/hid_bpf_helpers.h b/tools/te= sting/selftests/hid/progs/hid_bpf_helpers.h index 9cd56821d0f1..e02e24e3eab3 100644 --- a/tools/testing/selftests/hid/progs/hid_bpf_helpers.h +++ b/tools/testing/selftests/hid/progs/hid_bpf_helpers.h @@ -20,9 +20,6 @@ #define HID_REQ_SET_REPORT HID_REQ_SET_REPORT___not_used #define HID_REQ_SET_IDLE HID_REQ_SET_IDLE___not_used #define HID_REQ_SET_PROTOCOL HID_REQ_SET_PROTOCOL___not_used -#define HID_BPF_FLAG_NONE HID_BPF_FLAG_NONE___not_used -#define HID_BPF_FLAG_INSERT_HEAD HID_BPF_FLAG_INSERT_HEAD___not_used -#define HID_BPF_FLAG_MAX HID_BPF_FLAG_MAX___not_used =20 #include "vmlinux.h" =20 @@ -40,9 +37,6 @@ #undef HID_REQ_SET_REPORT #undef HID_REQ_SET_IDLE #undef HID_REQ_SET_PROTOCOL -#undef HID_BPF_FLAG_NONE -#undef HID_BPF_FLAG_INSERT_HEAD -#undef HID_BPF_FLAG_MAX =20 #include #include @@ -57,10 +51,8 @@ enum hid_report_type { }; =20 struct hid_bpf_ctx { - __u32 index; - const struct hid_device *hid; + struct hid_device *hid; __u32 allocated_size; - enum hid_report_type report_type; union { __s32 retval; __s32 size; @@ -76,17 +68,14 @@ enum hid_class_request { HID_REQ_SET_PROTOCOL =3D 0x0B, }; =20 -enum hid_bpf_attach_flags { - HID_BPF_FLAG_NONE =3D 0, - HID_BPF_FLAG_INSERT_HEAD =3D _BITUL(0), - HID_BPF_FLAG_MAX, -}; +#ifndef BPF_F_BEFORE +#define BPF_F_BEFORE (1U << 3) +#endif =20 /* 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 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, --=20 2.44.0 From nobody Fri Dec 19 21:10:08 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AF71217A902; Sat, 8 Jun 2024 09:01:33 +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=1717837293; cv=none; b=ft6wmTZg7zRwJa2vF5gokTs3L6/2iH4AumieXL9Xp8SA8tEOZTtqt962h/Rd8UUSC3Vc5RmwHIS6Af4CfqcKqO8yg5tIdHbMYcCEQHi84Ir2rinJqGcnkNCQmE4mKGy2jP/NG0PQ12xGp6Iq0bgg5LT5nSmcE7RVLeqPw7JY4SA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717837293; c=relaxed/simple; bh=rsY5swL5ZI3DFuKCDu6J27a7EBDj2FlsZbpIR8sel3c=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=MJrEmP/eaVWaSHXJNQ2EEwv7oDGF9sHiJSL4UvMF0jQ3TCQq5OkAzufPprW/GWrj4hzvA+NPNXT2ou2okvlsfhL1jUqKKd4CMbW2cCZXlsxVDGg45CqN08cqiwJC3N9UPqmipevDRfLlAY2sk7Uk7JD8VAhMaSXG1yIQL3aknfs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Mh9vEHf1; 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="Mh9vEHf1" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B04F1C4AF0C; Sat, 8 Jun 2024 09:01:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1717837293; bh=rsY5swL5ZI3DFuKCDu6J27a7EBDj2FlsZbpIR8sel3c=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Mh9vEHf13aGomaCDOUV9v8x/vfjekZxwi+z03Ulcb6YB65peCzf+d2kmzzZxIXUZG aRlotscRVi/r4dCceEGichw80/zAtpZen3WX1C5OWjm7D3vxXabrW9z2lssxGoEZXc T5lIsmhNVshYRw8ZiQ933IlTz5ZU9o0TP7GKqa7a6CgekmGBttlv+CWUskqUBUQP6B pily5FTDd28u2GO4SZk61mkyvZ8y5dpB7eKEKIPnw0WxXMFcQq4yOmmxi8ZyXFfroN eg4eDu+39D8qfsIXJrm/50pyXkBHhzFvfY92WKjZH5Kc8E9LVC6WjVt06mhZ458sTu LoS9tE0DWsqTw== From: Benjamin Tissoires Date: Sat, 08 Jun 2024 11:01:17 +0200 Subject: [PATCH HID v3 05/16] HID: samples: convert the 2 HID-BPF samples into struct_ops Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240608-hid_bpf_struct_ops-v3-5-6ac6ade58329@kernel.org> References: <20240608-hid_bpf_struct_ops-v3-0-6ac6ade58329@kernel.org> In-Reply-To: <20240608-hid_bpf_struct_ops-v3-0-6ac6ade58329@kernel.org> To: Shuah Khan , Jiri Kosina , Jonathan Corbet , Alexei Starovoitov Cc: linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, linux-input@vger.kernel.org, linux-doc@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1717837279; l=10438; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=rsY5swL5ZI3DFuKCDu6J27a7EBDj2FlsZbpIR8sel3c=; b=5c0eSJb32M91HEWN+mAUmYRmF8+DSPoytm+2FpWPyiURx//cosyuE8uVlvsRw4Hlea0d7TcCX rxg/yAMJE3/BhqB+avqyuFbJK9OZyBSTSs1s1Fim6X0CDB3EY01O5WR X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= This is mostly mechanical: attach_prog is dropped, and the SEC are converted into struct_ops. Signed-off-by: Benjamin Tissoires --- no changes in v3 no changes in v2 but the commit message. --- samples/hid/Makefile | 5 ++-- samples/hid/hid_bpf_attach.bpf.c | 18 ------------- samples/hid/hid_bpf_attach.h | 14 ---------- samples/hid/hid_mouse.bpf.c | 26 +++++++++++++++---- samples/hid/hid_mouse.c | 39 ++++++++-------------------- samples/hid/hid_surface_dial.bpf.c | 10 +++++-- samples/hid/hid_surface_dial.c | 53 +++++++++++-----------------------= ---- 7 files changed, 57 insertions(+), 108 deletions(-) diff --git a/samples/hid/Makefile b/samples/hid/Makefile index c128ccd49974..8ea59e9631a3 100644 --- a/samples/hid/Makefile +++ b/samples/hid/Makefile @@ -16,7 +16,6 @@ LIBBPF_DESTDIR =3D $(LIBBPF_OUTPUT) LIBBPF_INCLUDE =3D $(LIBBPF_DESTDIR)/include LIBBPF =3D $(LIBBPF_OUTPUT)/libbpf.a =20 -EXTRA_HEADERS :=3D hid_bpf_attach.h EXTRA_BPF_HEADERS :=3D hid_bpf_helpers.h =20 hid_mouse-objs :=3D hid_mouse.o @@ -207,8 +206,8 @@ $(obj)/%.bpf.o: $(src)/%.bpf.c $(EXTRA_BPF_HEADERS_SRC)= $(obj)/vmlinux.h LINKED_SKELS :=3D hid_mouse.skel.h hid_surface_dial.skel.h clean-files +=3D $(LINKED_SKELS) =20 -hid_mouse.skel.h-deps :=3D hid_mouse.bpf.o hid_bpf_attach.bpf.o -hid_surface_dial.skel.h-deps :=3D hid_surface_dial.bpf.o hid_bpf_attach.bp= f.o +hid_mouse.skel.h-deps :=3D hid_mouse.bpf.o +hid_surface_dial.skel.h-deps :=3D hid_surface_dial.bpf.o =20 LINKED_BPF_SRCS :=3D $(patsubst %.bpf.o,%.bpf.c,$(foreach skel,$(LINKED_SK= ELS),$($(skel)-deps))) =20 diff --git a/samples/hid/hid_bpf_attach.bpf.c b/samples/hid/hid_bpf_attach.= bpf.c deleted file mode 100644 index d4dce4ea7c6e..000000000000 --- a/samples/hid/hid_bpf_attach.bpf.c +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2022 Benjamin Tissoires - */ - -#include "vmlinux.h" -#include -#include -#include "hid_bpf_attach.h" -#include "hid_bpf_helpers.h" - -SEC("syscall") -int attach_prog(struct attach_prog_args *ctx) -{ - ctx->retval =3D hid_bpf_attach_prog(ctx->hid, - ctx->prog_fd, - 0); - return 0; -} diff --git a/samples/hid/hid_bpf_attach.h b/samples/hid/hid_bpf_attach.h deleted file mode 100644 index 35bb28b49264..000000000000 --- a/samples/hid/hid_bpf_attach.h +++ /dev/null @@ -1,14 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2022 Benjamin Tissoires - */ - -#ifndef __HID_BPF_ATTACH_H -#define __HID_BPF_ATTACH_H - -struct attach_prog_args { - int prog_fd; - unsigned int hid; - int retval; -}; - -#endif /* __HID_BPF_ATTACH_H */ diff --git a/samples/hid/hid_mouse.bpf.c b/samples/hid/hid_mouse.bpf.c index 7c8b453ccb16..bd901fa855c9 100644 --- a/samples/hid/hid_mouse.bpf.c +++ b/samples/hid/hid_mouse.bpf.c @@ -5,8 +5,7 @@ #include #include "hid_bpf_helpers.h" =20 -SEC("fmod_ret/hid_bpf_device_event") -int BPF_PROG(hid_y_event, struct hid_bpf_ctx *hctx) +static int hid_y_event(struct hid_bpf_ctx *hctx) { s16 y; __u8 *data =3D hid_bpf_get_data(hctx, 0 /* offset */, 9 /* size */); @@ -51,8 +50,7 @@ int BPF_PROG(hid_y_event, struct hid_bpf_ctx *hctx) return 0; } =20 -SEC("fmod_ret/hid_bpf_device_event") -int BPF_PROG(hid_x_event, struct hid_bpf_ctx *hctx) +static int hid_x_event(struct hid_bpf_ctx *hctx) { s16 x; __u8 *data =3D hid_bpf_get_data(hctx, 0 /* offset */, 9 /* size */); @@ -69,7 +67,19 @@ int BPF_PROG(hid_x_event, struct hid_bpf_ctx *hctx) return 0; } =20 -SEC("fmod_ret/hid_bpf_rdesc_fixup") +SEC("struct_ops/device_event") +int BPF_PROG(hid_event, struct hid_bpf_ctx *hctx, enum hid_report_type typ= e) +{ + int ret =3D hid_y_event(hctx); + + if (ret) + return ret; + + return hid_x_event(hctx); +} + + +SEC("struct_ops/rdesc_fixup") int BPF_PROG(hid_rdesc_fixup, struct hid_bpf_ctx *hctx) { __u8 *data =3D hid_bpf_get_data(hctx, 0 /* offset */, 4096 /* size */); @@ -109,4 +119,10 @@ int BPF_PROG(hid_rdesc_fixup, struct hid_bpf_ctx *hctx) return 0; } =20 +SEC(".struct_ops.link") +struct hid_bpf_ops mouse_invert =3D { + .rdesc_fixup =3D (void *)hid_rdesc_fixup, + .device_event =3D (void *)hid_event, +}; + char _license[] SEC("license") =3D "GPL"; diff --git a/samples/hid/hid_mouse.c b/samples/hid/hid_mouse.c index 018f1185f203..4b80d4e4c154 100644 --- a/samples/hid/hid_mouse.c +++ b/samples/hid/hid_mouse.c @@ -29,7 +29,6 @@ #include =20 #include "hid_mouse.skel.h" -#include "hid_bpf_attach.h" =20 static bool running =3D true; =20 @@ -76,18 +75,11 @@ static int get_hid_id(const char *path) int main(int argc, char **argv) { struct hid_mouse *skel; - struct bpf_program *prog; + struct bpf_link *link; int err; const char *optstr =3D ""; const char *sysfs_path; - int opt, hid_id, attach_fd; - struct attach_prog_args args =3D { - .retval =3D -1, - }; - DECLARE_LIBBPF_OPTS(bpf_test_run_opts, tattr, - .ctx_in =3D &args, - .ctx_size_in =3D sizeof(args), - ); + int opt, hid_id; =20 while ((opt =3D getopt(argc, argv, optstr)) !=3D -1) { switch (opt) { @@ -108,7 +100,7 @@ int main(int argc, char **argv) return 1; } =20 - skel =3D hid_mouse__open_and_load(); + skel =3D hid_mouse__open(); if (!skel) { fprintf(stderr, "%s %s:%d", __func__, __FILE__, __LINE__); return -1; @@ -120,27 +112,18 @@ int main(int argc, char **argv) fprintf(stderr, "can not open HID device: %m\n"); return 1; } - args.hid =3D hid_id; + skel->struct_ops.mouse_invert->hid_id =3D hid_id; =20 - attach_fd =3D bpf_program__fd(skel->progs.attach_prog); - if (attach_fd < 0) { - fprintf(stderr, "can't locate attach prog: %m\n"); + err =3D hid_mouse__load(skel); + if (err < 0) { + fprintf(stderr, "can not load HID-BPF program: %m\n"); return 1; } =20 - bpf_object__for_each_program(prog, *skel->skeleton->obj) { - /* ignore syscalls */ - if (bpf_program__get_type(prog) !=3D BPF_PROG_TYPE_TRACING) - continue; - - args.retval =3D -1; - args.prog_fd =3D bpf_program__fd(prog); - err =3D bpf_prog_test_run_opts(attach_fd, &tattr); - if (err) { - fprintf(stderr, "can't attach prog to hid device %d: %m (err: %d)\n", - hid_id, err); - return 1; - } + link =3D bpf_map__attach_struct_ops(skel->maps.mouse_invert); + if (!link) { + fprintf(stderr, "can not attach HID-BPF program: %m\n"); + return 1; } =20 signal(SIGINT, int_exit); diff --git a/samples/hid/hid_surface_dial.bpf.c b/samples/hid/hid_surface_d= ial.bpf.c index 1f80478c0918..d8d0fb07391f 100644 --- a/samples/hid/hid_surface_dial.bpf.c +++ b/samples/hid/hid_surface_dial.bpf.c @@ -10,7 +10,7 @@ #define HID_UP_BUTTON 0x0009 #define HID_GD_WHEEL 0x0038 =20 -SEC("fmod_ret/hid_bpf_device_event") +SEC("struct_ops/device_event") int BPF_PROG(hid_event, struct hid_bpf_ctx *hctx) { __u8 *data =3D hid_bpf_get_data(hctx, 0 /* offset */, 9 /* size */); @@ -101,7 +101,7 @@ int set_haptic(struct haptic_syscall_args *args) } =20 /* Convert REL_DIAL into REL_WHEEL */ -SEC("fmod_ret/hid_bpf_rdesc_fixup") +SEC("struct_ops/rdesc_fixup") int BPF_PROG(hid_rdesc_fixup, struct hid_bpf_ctx *hctx) { __u8 *data =3D hid_bpf_get_data(hctx, 0 /* offset */, 4096 /* size */); @@ -130,5 +130,11 @@ int BPF_PROG(hid_rdesc_fixup, struct hid_bpf_ctx *hctx) return 0; } =20 +SEC(".struct_ops.link") +struct hid_bpf_ops surface_dial =3D { + .rdesc_fixup =3D (void *)hid_rdesc_fixup, + .device_event =3D (void *)hid_event, +}; + char _license[] SEC("license") =3D "GPL"; u32 _version SEC("version") =3D 1; diff --git a/samples/hid/hid_surface_dial.c b/samples/hid/hid_surface_dial.c index 4bc97373a708..9dd363845a85 100644 --- a/samples/hid/hid_surface_dial.c +++ b/samples/hid/hid_surface_dial.c @@ -31,7 +31,6 @@ #include =20 #include "hid_surface_dial.skel.h" -#include "hid_bpf_attach.h" =20 static bool running =3D true; =20 @@ -86,34 +85,6 @@ static int get_hid_id(const char *path) return (int)strtol(str_id, NULL, 16); } =20 -static int attach_prog(struct hid_surface_dial *skel, struct bpf_program *= prog, int hid_id) -{ - struct attach_prog_args args =3D { - .hid =3D hid_id, - .retval =3D -1, - }; - int attach_fd, err; - DECLARE_LIBBPF_OPTS(bpf_test_run_opts, tattr, - .ctx_in =3D &args, - .ctx_size_in =3D sizeof(args), - ); - - attach_fd =3D bpf_program__fd(skel->progs.attach_prog); - if (attach_fd < 0) { - fprintf(stderr, "can't locate attach prog: %m\n"); - return 1; - } - - args.prog_fd =3D bpf_program__fd(prog); - err =3D bpf_prog_test_run_opts(attach_fd, &tattr); - if (err) { - fprintf(stderr, "can't attach prog to hid device %d: %m (err: %d)\n", - hid_id, err); - return 1; - } - return 0; -} - static int set_haptic(struct hid_surface_dial *skel, int hid_id) { struct haptic_syscall_args args =3D { @@ -144,10 +115,10 @@ static int set_haptic(struct hid_surface_dial *skel, = int hid_id) int main(int argc, char **argv) { struct hid_surface_dial *skel; - struct bpf_program *prog; const char *optstr =3D "r:"; + struct bpf_link *link; const char *sysfs_path; - int opt, hid_id, resolution =3D 72; + int err, opt, hid_id, resolution =3D 72; =20 while ((opt =3D getopt(argc, argv, optstr)) !=3D -1) { switch (opt) { @@ -189,7 +160,7 @@ int main(int argc, char **argv) return 1; } =20 - skel =3D hid_surface_dial__open_and_load(); + skel =3D hid_surface_dial__open(); if (!skel) { fprintf(stderr, "%s %s:%d", __func__, __FILE__, __LINE__); return -1; @@ -201,15 +172,21 @@ int main(int argc, char **argv) return 1; } =20 + skel->struct_ops.surface_dial->hid_id =3D hid_id; + + err =3D hid_surface_dial__load(skel); + if (err < 0) { + fprintf(stderr, "can not load HID-BPF program: %m\n"); + return 1; + } + skel->data->resolution =3D resolution; skel->data->physical =3D (int)(resolution / 72); =20 - bpf_object__for_each_program(prog, *skel->skeleton->obj) { - /* ignore syscalls */ - if (bpf_program__get_type(prog) !=3D BPF_PROG_TYPE_TRACING) - continue; - - attach_prog(skel, prog, hid_id); + link =3D bpf_map__attach_struct_ops(skel->maps.surface_dial); + if (!link) { + fprintf(stderr, "can not attach HID-BPF program: %m\n"); + return 1; } =20 signal(SIGINT, int_exit); --=20 2.44.0 From nobody Fri Dec 19 21:10:08 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6BF7A176FB8; Sat, 8 Jun 2024 09:01:35 +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=1717837296; cv=none; b=aJunGQ2+hpa6jKPxH8DIaxhO9f1zt5JOTZyKFzCVnb0FFltlPoG1CJvSH/dx3PbhFNrfMde5AP8N8GeFHAYyD6AVJTSBEXamcJpkAWkfKjhiJYi5ZINDP56ROIzGTEjYyLCgmyeKrSPozsL0OvdUf6l7HHzfk4tY92q7hOKM+a4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717837296; c=relaxed/simple; bh=yG1pGkZtC9Anfz5EEv/yx6g2z75uDkKpVPn27LPVJiI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=QyFdGXmnH48G+5rStIe0MMPny0ZxdNDfeMmT1/4MoOkRqi6do3kEjBcQSnImNeJC83M13rK4b1HSs7xSbgtBeAxuuQxLfcBDP/c6DEoEcC8hAHt04kSAwr/yDsCKCyFZTHCSa35iFevhjfgcSmE+GLWR8IE75V5O6c0MDeAKu0Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=oTUodsGo; 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="oTUodsGo" Received: by smtp.kernel.org (Postfix) with ESMTPSA id F2949C2BD11; Sat, 8 Jun 2024 09:01:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1717837295; bh=yG1pGkZtC9Anfz5EEv/yx6g2z75uDkKpVPn27LPVJiI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=oTUodsGoZi8+kJ0TMURTzyRYjsRat4+kM7rE5qTYIwE8nVZHpPXWVGXphnpmS7EVm 31ZvFTTn3kTkY1m8T86q3g/1UgRTmcQAlSd3/7nnULBIhVO9NR8SbmUggwdW9lzYPV mPffj5k90lLTzrKGhgbdznEvtZCgNfjbsPZIvB4OFrEColaVztXh91eAVaoZypbDNN p/rO8Gq52iph38riISvvz7bHsWySFH7nb1qsxsEQbIh+la3fbgbe3DSzeFuyBpYWEW FKODyO3mUKGULVjreW6zfNNO0iBtiDi+HX5iayN8eixd8rXogRvqwVrkrTlhbNExu2 n+VuyCWkGq3MA== From: Benjamin Tissoires Date: Sat, 08 Jun 2024 11:01:18 +0200 Subject: [PATCH HID v3 06/16] HID: bpf: add defines for HID-BPF SEC in in-tree bpf fixes Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240608-hid_bpf_struct_ops-v3-6-6ac6ade58329@kernel.org> References: <20240608-hid_bpf_struct_ops-v3-0-6ac6ade58329@kernel.org> In-Reply-To: <20240608-hid_bpf_struct_ops-v3-0-6ac6ade58329@kernel.org> To: Shuah Khan , Jiri Kosina , Jonathan Corbet , Alexei Starovoitov Cc: linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, linux-input@vger.kernel.org, linux-doc@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1717837279; l=8093; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=yG1pGkZtC9Anfz5EEv/yx6g2z75uDkKpVPn27LPVJiI=; b=y2ruVxmIfdZaADC4Dt0SFM02Fo3Ln8e4T1SbHzyVfn34BbP2CkJnPBFZD4iP/bnpQuNGVm41/ UdIoRi3f5MeAQa4IUZWj7BVcSyCPdkxnHTrtXqkbAhiC9L2HBy5YyTF X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= We are going to switch over struct_ops, so instead of having to manually replace all fields one by one, let's have a common place to change it. Signed-off-by: Benjamin Tissoires --- no changes in v3 no changes in v2 --- drivers/hid/bpf/progs/FR-TEC__Raptor-Mach-2.bpf.c | 4 ++-- drivers/hid/bpf/progs/HP__Elite-Presenter.bpf.c | 2 +- drivers/hid/bpf/progs/Huion__Kamvas-Pro-19.bpf.c | 4 ++-- drivers/hid/bpf/progs/IOGEAR__Kaliber-MMOmentum.bpf.c | 2 +- drivers/hid/bpf/progs/Microsoft__XBox-Elite-2.bpf.c | 2 +- drivers/hid/bpf/progs/Wacom__ArtPen.bpf.c | 2 +- drivers/hid/bpf/progs/XPPen__Artist24.bpf.c | 4 ++-- drivers/hid/bpf/progs/XPPen__ArtistPro16Gen2.bpf.c | 6 +++--- drivers/hid/bpf/progs/hid_bpf.h | 3 +++ 9 files changed, 16 insertions(+), 13 deletions(-) diff --git a/drivers/hid/bpf/progs/FR-TEC__Raptor-Mach-2.bpf.c b/drivers/hi= d/bpf/progs/FR-TEC__Raptor-Mach-2.bpf.c index dc26a7677d36..2c2c1637ade8 100644 --- a/drivers/hid/bpf/progs/FR-TEC__Raptor-Mach-2.bpf.c +++ b/drivers/hid/bpf/progs/FR-TEC__Raptor-Mach-2.bpf.c @@ -133,7 +133,7 @@ HID_BPF_CONFIG( * integer. We thus divide it by 30 to match what other joysticks are * doing */ -SEC("fmod_ret/hid_bpf_rdesc_fixup") +SEC(HID_BPF_RDESC_FIXUP) int BPF_PROG(hid_fix_rdesc_raptor_mach_2, struct hid_bpf_ctx *hctx) { __u8 *data =3D hid_bpf_get_data(hctx, 0 /* offset */, HID_MAX_DESCRIPTOR_= SIZE /* size */); @@ -152,7 +152,7 @@ int BPF_PROG(hid_fix_rdesc_raptor_mach_2, struct hid_bp= f_ctx *hctx) * divide it by 30. * Byte 34 is always null, so it is ignored. */ -SEC("fmod_ret/hid_bpf_device_event") +SEC(HID_BPF_DEVICE_EVENT) int BPF_PROG(raptor_mach_2_fix_hat_switch, struct hid_bpf_ctx *hctx) { __u8 *data =3D hid_bpf_get_data(hctx, 0 /* offset */, 64 /* size */); diff --git a/drivers/hid/bpf/progs/HP__Elite-Presenter.bpf.c b/drivers/hid/= bpf/progs/HP__Elite-Presenter.bpf.c index 3d14bbb6f276..17fc55f6f02c 100644 --- a/drivers/hid/bpf/progs/HP__Elite-Presenter.bpf.c +++ b/drivers/hid/bpf/progs/HP__Elite-Presenter.bpf.c @@ -30,7 +30,7 @@ HID_BPF_CONFIG( * pointer. */ =20 -SEC("fmod_ret/hid_bpf_rdesc_fixup") +SEC(HID_BPF_RDESC_FIXUP) int BPF_PROG(hid_fix_rdesc, struct hid_bpf_ctx *hctx) { __u8 *data =3D hid_bpf_get_data(hctx, 0 /* offset */, 4096 /* size */); diff --git a/drivers/hid/bpf/progs/Huion__Kamvas-Pro-19.bpf.c b/drivers/hid= /bpf/progs/Huion__Kamvas-Pro-19.bpf.c index ff759f2276f9..24b8a5aa05f3 100644 --- a/drivers/hid/bpf/progs/Huion__Kamvas-Pro-19.bpf.c +++ b/drivers/hid/bpf/progs/Huion__Kamvas-Pro-19.bpf.c @@ -191,7 +191,7 @@ static const __u8 fixed_rdesc[] =3D { 0xc0, // End Collection 327 }; =20 -SEC("fmod_ret/hid_bpf_rdesc_fixup") +SEC(HID_BPF_RDESC_FIXUP) int BPF_PROG(hid_fix_rdesc_huion_kamvas_pro_19, struct hid_bpf_ctx *hctx) { __u8 *data =3D hid_bpf_get_data(hctx, 0 /* offset */, HID_MAX_DESCRIPTOR_= SIZE /* size */); @@ -215,7 +215,7 @@ int BPF_PROG(hid_fix_rdesc_huion_kamvas_pro_19, struct = hid_bpf_ctx *hctx) * - if there was this out-of-proximity event, we are entering * eraser mode, and we will until the next out-of-proximity. */ -SEC("fmod_ret/hid_bpf_device_event") +SEC(HID_BPF_DEVICE_EVENT) int BPF_PROG(kamvas_pro_19_fix_3rd_button, struct hid_bpf_ctx *hctx) { __u8 *data =3D hid_bpf_get_data(hctx, 0 /* offset */, 10 /* size */); diff --git a/drivers/hid/bpf/progs/IOGEAR__Kaliber-MMOmentum.bpf.c b/driver= s/hid/bpf/progs/IOGEAR__Kaliber-MMOmentum.bpf.c index 225cbefdbf0e..bee37872ee8c 100644 --- a/drivers/hid/bpf/progs/IOGEAR__Kaliber-MMOmentum.bpf.c +++ b/drivers/hid/bpf/progs/IOGEAR__Kaliber-MMOmentum.bpf.c @@ -21,7 +21,7 @@ HID_BPF_CONFIG( * We just fix the report descriptor to enable those missing 7 buttons. */ =20 -SEC("fmod_ret/hid_bpf_rdesc_fixup") +SEC(HID_BPF_RDESC_FIXUP) int BPF_PROG(hid_fix_rdesc, struct hid_bpf_ctx *hctx) { const u8 offsets[] =3D {84, 112, 140}; diff --git a/drivers/hid/bpf/progs/Microsoft__XBox-Elite-2.bpf.c b/drivers/= hid/bpf/progs/Microsoft__XBox-Elite-2.bpf.c index c04abecab8ee..f9ad33f4a373 100644 --- a/drivers/hid/bpf/progs/Microsoft__XBox-Elite-2.bpf.c +++ b/drivers/hid/bpf/progs/Microsoft__XBox-Elite-2.bpf.c @@ -93,7 +93,7 @@ _Static_assert(sizeof(rdesc_assign_selection) =3D=3D size= of(fixed_rdesc_assign_selec _Static_assert(sizeof(rdesc_assign_selection) + OFFSET_ASSIGN_SELECTION < = ORIGINAL_RDESC_SIZE, "Rdesc at given offset is too big"); =20 -SEC("fmod_ret/hid_bpf_rdesc_fixup") +SEC(HID_BPF_RDESC_FIXUP) int BPF_PROG(hid_fix_rdesc, struct hid_bpf_ctx *hctx) { __u8 *data =3D hid_bpf_get_data(hctx, 0 /* offset */, 4096 /* size */); diff --git a/drivers/hid/bpf/progs/Wacom__ArtPen.bpf.c b/drivers/hid/bpf/pr= ogs/Wacom__ArtPen.bpf.c index dc05aa48faa7..39d77c5e9172 100644 --- a/drivers/hid/bpf/progs/Wacom__ArtPen.bpf.c +++ b/drivers/hid/bpf/progs/Wacom__ArtPen.bpf.c @@ -101,7 +101,7 @@ static inline __u8 *get_u8(__u8 *data, unsigned int off= set) return (__u8 *)get_bits(data, offset); } =20 -SEC("fmod_ret/hid_bpf_device_event") +SEC(HID_BPF_DEVICE_EVENT) int BPF_PROG(artpen_pressure_interpolate, struct hid_bpf_ctx *hctx) { __u8 *data =3D hid_bpf_get_data(hctx, 0 /* offset */, PEN_REPORT_LEN /* s= ize */); diff --git a/drivers/hid/bpf/progs/XPPen__Artist24.bpf.c b/drivers/hid/bpf/= progs/XPPen__Artist24.bpf.c index e1be6a12bb75..c938808bd589 100644 --- a/drivers/hid/bpf/progs/XPPen__Artist24.bpf.c +++ b/drivers/hid/bpf/progs/XPPen__Artist24.bpf.c @@ -91,7 +91,7 @@ static const __u8 fixed_rdesc[] =3D { =20 #define U16(index) (data[index] | (data[index + 1] << 8)) =20 -SEC("fmod_ret/hid_bpf_rdesc_fixup") +SEC(HID_BPF_RDESC_FIXUP) int BPF_PROG(hid_fix_rdesc_xppen_artist24, struct hid_bpf_ctx *hctx) { __u8 *data =3D hid_bpf_get_data(hctx, 0 /* offset */, 4096 /* size */); @@ -152,7 +152,7 @@ static __u8 prev_state =3D 0; * E: TipSwitch InRange * */ -SEC("fmod_ret/hid_bpf_device_event") +SEC(HID_BPF_DEVICE_EVENT) int BPF_PROG(xppen_24_fix_eraser, struct hid_bpf_ctx *hctx) { __u8 *data =3D hid_bpf_get_data(hctx, 0 /* offset */, 10 /* size */); diff --git a/drivers/hid/bpf/progs/XPPen__ArtistPro16Gen2.bpf.c b/drivers/h= id/bpf/progs/XPPen__ArtistPro16Gen2.bpf.c index 65ef10036126..77ef8b95d52e 100644 --- a/drivers/hid/bpf/progs/XPPen__ArtistPro16Gen2.bpf.c +++ b/drivers/hid/bpf/progs/XPPen__ArtistPro16Gen2.bpf.c @@ -82,7 +82,7 @@ static const __u8 fixed_rdesc[] =3D { 0xc0, // End Collection 112 }; =20 -SEC("fmod_ret/hid_bpf_rdesc_fixup") +SEC(HID_BPF_RDESC_FIXUP) int BPF_PROG(hid_fix_rdesc_xppen_artistpro16gen2, struct hid_bpf_ctx *hctx) { __u8 *data =3D hid_bpf_get_data(hctx, 0 /* offset */, 4096 /* size */); @@ -105,7 +105,7 @@ int BPF_PROG(hid_fix_rdesc_xppen_artistpro16gen2, struc= t hid_bpf_ctx *hctx) return sizeof(fixed_rdesc); } =20 -SEC("fmod_ret/hid_bpf_device_event") +SEC(HID_BPF_DEVICE_EVENT) int BPF_PROG(xppen_16_fix_eraser, struct hid_bpf_ctx *hctx) { __u8 *data =3D hid_bpf_get_data(hctx, 0 /* offset */, 10 /* size */); @@ -207,7 +207,7 @@ static void compensate_coordinates_by_tilt(__u8 *data, = const __u8 idx, data[idx+1] =3D coords >> 8; } =20 -SEC("fmod_ret/hid_bpf_device_event") +SEC(HID_BPF_DEVICE_EVENT) int BPF_PROG(xppen_16_fix_angle_offset, struct hid_bpf_ctx *hctx) { __u8 *data =3D hid_bpf_get_data(hctx, 0 /* offset */, 10 /* size */); diff --git a/drivers/hid/bpf/progs/hid_bpf.h b/drivers/hid/bpf/progs/hid_bp= f.h index 7ee371cac2e1..1970faf84310 100644 --- a/drivers/hid/bpf/progs/hid_bpf.h +++ b/drivers/hid/bpf/progs/hid_bpf.h @@ -5,6 +5,9 @@ #ifndef ____HID_BPF__H #define ____HID_BPF__H =20 +#define HID_BPF_DEVICE_EVENT "fmod_ret/hid_bpf_device_event" +#define HID_BPF_RDESC_FIXUP "fmod_ret/hid_bpf_rdesc_fixup" + struct hid_bpf_probe_args { unsigned int hid; unsigned int rdesc_size; --=20 2.44.0 From nobody Fri Dec 19 21:10:08 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 86E2117B43C; Sat, 8 Jun 2024 09:01:38 +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=1717837298; cv=none; b=YLn/JZF4kW/nBFOP4+0Jo+B7FSodYzbnml2St2QWvxHknXu1EeSx0O/ee71cCvky3Pe1aicIpgWkhMO2ykGu9vjjS5Pqb44iFeL+rs8UyhiA0qJ1zSHNRkVInXLKNx6IwpcD8xUlkcLT52CznoaLYAWP5IJjvm89A/5u5lTBLIo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717837298; c=relaxed/simple; bh=kP6WWoVTUSGh7I12vcXXq3MMA4Yy0zcq/ss058SAxFY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=D4gcGgdxFBkFPZvljl4uFOlnxeo9VLVsOZ1suyoWv26Ac71xF54nUhAaj0hA2oQaJTOHPmq5srzXfjivk4ax9rTE++QKJsxJIeBW8cofsU1bWOZgAQta9dNgmbYBFwUgJIk/gJeXh+ud4P5586mZ/sd7xGKU1ZXTM1oFddgUEvg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=lcKkq94d; 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="lcKkq94d" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 40C3AC4AF07; Sat, 8 Jun 2024 09:01:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1717837298; bh=kP6WWoVTUSGh7I12vcXXq3MMA4Yy0zcq/ss058SAxFY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=lcKkq94dHCcxlxzuKCI+jRfxQ8F5VWlEa05gbxeLvXbXpMgE85kE3W6cguAlj1y8d silovsEO6f6JVr5BZHEHH1qo0nu7/9aCdPbNzqCsyJMS7yi8NcOuzap0KbZf0ZQljD YHDdo61dB7tQ2ZdlPYOakVTL7qdJ35O8qwMonSWN7FNw1VSIo/rEZReAByOBqHq3m0 akFAAjxbT/usr5pX9WzZ1UgrSGelYItqParYWeInAwoX89/meQXrWQLpKOWw8T38Bv PpI4yw+j5rBGKBtkxjwWgL+P4X1p4msSKvvZD/CiNGBFC4gHYlURg+Y0KRfmp2apk3 kwaYTjlS0cdBg== From: Benjamin Tissoires Date: Sat, 08 Jun 2024 11:01:19 +0200 Subject: [PATCH HID v3 07/16] HID: bpf: convert in-tree fixes into struct_ops Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240608-hid_bpf_struct_ops-v3-7-6ac6ade58329@kernel.org> References: <20240608-hid_bpf_struct_ops-v3-0-6ac6ade58329@kernel.org> In-Reply-To: <20240608-hid_bpf_struct_ops-v3-0-6ac6ade58329@kernel.org> To: Shuah Khan , Jiri Kosina , Jonathan Corbet , Alexei Starovoitov Cc: linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, linux-input@vger.kernel.org, linux-doc@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1717837279; l=7104; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=kP6WWoVTUSGh7I12vcXXq3MMA4Yy0zcq/ss058SAxFY=; b=CLiirSSfksv1tnOdj5fMsysLLhk3ORObbzg9oxbrIR2k5sdghRvX/9Ellm84eu4RbUAQgj9pe rCOS2+hPT2hCgrqkYa+4Q27oolukh3J5Cn5Te42LyjDzs8L1pdWLqeB X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= Very mechanical: - Change HID_BPF_DEVICE_EVENT and HID_BPF_RDESC_FIXUP #defines - add a matching SEC(".struct_ops.link") - in ArtistPro16Gen2 make the 2 functions static and have a new one calling them Signed-off-by: Benjamin Tissoires --- no changes in v3 no changes in v2 --- drivers/hid/bpf/progs/FR-TEC__Raptor-Mach-2.bpf.c | 5 +++++ drivers/hid/bpf/progs/HP__Elite-Presenter.bpf.c | 4 ++++ drivers/hid/bpf/progs/Huion__Kamvas-Pro-19.bpf.c | 5 +++++ .../hid/bpf/progs/IOGEAR__Kaliber-MMOmentum.bpf.c | 4 ++++ .../hid/bpf/progs/Microsoft__XBox-Elite-2.bpf.c | 4 ++++ drivers/hid/bpf/progs/Wacom__ArtPen.bpf.c | 4 ++++ drivers/hid/bpf/progs/XPPen__Artist24.bpf.c | 5 +++++ drivers/hid/bpf/progs/XPPen__ArtistPro16Gen2.bpf.c | 22 ++++++++++++++++++= ---- drivers/hid/bpf/progs/hid_bpf.h | 6 ++++-- 9 files changed, 53 insertions(+), 6 deletions(-) diff --git a/drivers/hid/bpf/progs/FR-TEC__Raptor-Mach-2.bpf.c b/drivers/hi= d/bpf/progs/FR-TEC__Raptor-Mach-2.bpf.c index 2c2c1637ade8..caec91391d32 100644 --- a/drivers/hid/bpf/progs/FR-TEC__Raptor-Mach-2.bpf.c +++ b/drivers/hid/bpf/progs/FR-TEC__Raptor-Mach-2.bpf.c @@ -168,6 +168,11 @@ int BPF_PROG(raptor_mach_2_fix_hat_switch, struct hid_= bpf_ctx *hctx) return 0; } =20 +HID_BPF_OPS(raptor_mach_2) =3D { + .hid_rdesc_fixup =3D (void *)hid_fix_rdesc_raptor_mach_2, + .hid_device_event =3D (void *)raptor_mach_2_fix_hat_switch, +}; + SEC("syscall") int probe(struct hid_bpf_probe_args *ctx) { diff --git a/drivers/hid/bpf/progs/HP__Elite-Presenter.bpf.c b/drivers/hid/= bpf/progs/HP__Elite-Presenter.bpf.c index 17fc55f6f02c..c2413fa80543 100644 --- a/drivers/hid/bpf/progs/HP__Elite-Presenter.bpf.c +++ b/drivers/hid/bpf/progs/HP__Elite-Presenter.bpf.c @@ -45,6 +45,10 @@ int BPF_PROG(hid_fix_rdesc, struct hid_bpf_ctx *hctx) return 0; } =20 +HID_BPF_OPS(hp_elite_presenter) =3D { + .hid_rdesc_fixup =3D (void *)hid_fix_rdesc, +}; + SEC("syscall") int probe(struct hid_bpf_probe_args *ctx) { diff --git a/drivers/hid/bpf/progs/Huion__Kamvas-Pro-19.bpf.c b/drivers/hid= /bpf/progs/Huion__Kamvas-Pro-19.bpf.c index 24b8a5aa05f3..a4a4f324aedd 100644 --- a/drivers/hid/bpf/progs/Huion__Kamvas-Pro-19.bpf.c +++ b/drivers/hid/bpf/progs/Huion__Kamvas-Pro-19.bpf.c @@ -255,6 +255,11 @@ int BPF_PROG(kamvas_pro_19_fix_3rd_button, struct hid_= bpf_ctx *hctx) return 0; } =20 +HID_BPF_OPS(huion_Kamvas_pro_19) =3D { + .hid_rdesc_fixup =3D (void *)hid_fix_rdesc_huion_kamvas_pro_19, + .hid_device_event =3D (void *)kamvas_pro_19_fix_3rd_button, +}; + SEC("syscall") int probe(struct hid_bpf_probe_args *ctx) { diff --git a/drivers/hid/bpf/progs/IOGEAR__Kaliber-MMOmentum.bpf.c b/driver= s/hid/bpf/progs/IOGEAR__Kaliber-MMOmentum.bpf.c index bee37872ee8c..82f1950445dd 100644 --- a/drivers/hid/bpf/progs/IOGEAR__Kaliber-MMOmentum.bpf.c +++ b/drivers/hid/bpf/progs/IOGEAR__Kaliber-MMOmentum.bpf.c @@ -45,6 +45,10 @@ int BPF_PROG(hid_fix_rdesc, struct hid_bpf_ctx *hctx) return 0; } =20 +HID_BPF_OPS(iogear_kaliber_momentum) =3D { + .hid_rdesc_fixup =3D (void *)hid_fix_rdesc, +}; + SEC("syscall") int probe(struct hid_bpf_probe_args *ctx) { diff --git a/drivers/hid/bpf/progs/Microsoft__XBox-Elite-2.bpf.c b/drivers/= hid/bpf/progs/Microsoft__XBox-Elite-2.bpf.c index f9ad33f4a373..70b16edfb59a 100644 --- a/drivers/hid/bpf/progs/Microsoft__XBox-Elite-2.bpf.c +++ b/drivers/hid/bpf/progs/Microsoft__XBox-Elite-2.bpf.c @@ -114,6 +114,10 @@ int BPF_PROG(hid_fix_rdesc, struct hid_bpf_ctx *hctx) return 0; } =20 +HID_BPF_OPS(xbox_elite_2) =3D { + .hid_rdesc_fixup =3D (void *)hid_fix_rdesc, +}; + SEC("syscall") int probe(struct hid_bpf_probe_args *ctx) { diff --git a/drivers/hid/bpf/progs/Wacom__ArtPen.bpf.c b/drivers/hid/bpf/pr= ogs/Wacom__ArtPen.bpf.c index 39d77c5e9172..2da680bc4e11 100644 --- a/drivers/hid/bpf/progs/Wacom__ArtPen.bpf.c +++ b/drivers/hid/bpf/progs/Wacom__ArtPen.bpf.c @@ -139,6 +139,10 @@ int BPF_PROG(artpen_pressure_interpolate, struct hid_b= pf_ctx *hctx) return 0; } =20 +HID_BPF_OPS(wacom_artpen) =3D { + .hid_device_event =3D (void *)artpen_pressure_interpolate, +}; + SEC("syscall") int probe(struct hid_bpf_probe_args *ctx) { diff --git a/drivers/hid/bpf/progs/XPPen__Artist24.bpf.c b/drivers/hid/bpf/= progs/XPPen__Artist24.bpf.c index c938808bd589..bc0b85c38445 100644 --- a/drivers/hid/bpf/progs/XPPen__Artist24.bpf.c +++ b/drivers/hid/bpf/progs/XPPen__Artist24.bpf.c @@ -209,6 +209,11 @@ int BPF_PROG(xppen_24_fix_eraser, struct hid_bpf_ctx *= hctx) return 0; } =20 +HID_BPF_OPS(xppen_artist_24) =3D { + .hid_rdesc_fixup =3D (void *)hid_fix_rdesc_xppen_artist24, + .hid_device_event =3D (void *)xppen_24_fix_eraser, +}; + SEC("syscall") int probe(struct hid_bpf_probe_args *ctx) { diff --git a/drivers/hid/bpf/progs/XPPen__ArtistPro16Gen2.bpf.c b/drivers/h= id/bpf/progs/XPPen__ArtistPro16Gen2.bpf.c index 77ef8b95d52e..a669525691aa 100644 --- a/drivers/hid/bpf/progs/XPPen__ArtistPro16Gen2.bpf.c +++ b/drivers/hid/bpf/progs/XPPen__ArtistPro16Gen2.bpf.c @@ -105,8 +105,7 @@ int BPF_PROG(hid_fix_rdesc_xppen_artistpro16gen2, struc= t hid_bpf_ctx *hctx) return sizeof(fixed_rdesc); } =20 -SEC(HID_BPF_DEVICE_EVENT) -int BPF_PROG(xppen_16_fix_eraser, struct hid_bpf_ctx *hctx) +static int xppen_16_fix_eraser(struct hid_bpf_ctx *hctx) { __u8 *data =3D hid_bpf_get_data(hctx, 0 /* offset */, 10 /* size */); =20 @@ -207,8 +206,7 @@ static void compensate_coordinates_by_tilt(__u8 *data, = const __u8 idx, data[idx+1] =3D coords >> 8; } =20 -SEC(HID_BPF_DEVICE_EVENT) -int BPF_PROG(xppen_16_fix_angle_offset, struct hid_bpf_ctx *hctx) +static int xppen_16_fix_angle_offset(struct hid_bpf_ctx *hctx) { __u8 *data =3D hid_bpf_get_data(hctx, 0 /* offset */, 10 /* size */); =20 @@ -254,6 +252,22 @@ int BPF_PROG(xppen_16_fix_angle_offset, struct hid_bpf= _ctx *hctx) return 0; } =20 +SEC(HID_BPF_DEVICE_EVENT) +int BPF_PROG(xppen_artist_pro_16_device_event, struct hid_bpf_ctx *hctx) +{ + int ret =3D xppen_16_fix_angle_offset(hctx); + + if (ret) + return ret; + + return xppen_16_fix_eraser(hctx); +} + +HID_BPF_OPS(xppen_artist_pro_16) =3D { + .hid_rdesc_fixup =3D (void *)hid_fix_rdesc_xppen_artistpro16gen2, + .hid_device_event =3D (void *)xppen_artist_pro_16_device_event, +}; + SEC("syscall") int probe(struct hid_bpf_probe_args *ctx) { diff --git a/drivers/hid/bpf/progs/hid_bpf.h b/drivers/hid/bpf/progs/hid_bp= f.h index 1970faf84310..8c1cd9e25bc3 100644 --- a/drivers/hid/bpf/progs/hid_bpf.h +++ b/drivers/hid/bpf/progs/hid_bpf.h @@ -5,8 +5,10 @@ #ifndef ____HID_BPF__H #define ____HID_BPF__H =20 -#define HID_BPF_DEVICE_EVENT "fmod_ret/hid_bpf_device_event" -#define HID_BPF_RDESC_FIXUP "fmod_ret/hid_bpf_rdesc_fixup" +#define HID_BPF_DEVICE_EVENT "struct_ops/hid_device_event" +#define HID_BPF_RDESC_FIXUP "struct_ops/hid_rdesc_fixup" +#define HID_BPF_OPS(name) SEC(".struct_ops.link") \ + struct hid_bpf_ops name =20 struct hid_bpf_probe_args { unsigned int hid; --=20 2.44.0 From nobody Fri Dec 19 21:10:08 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A7C2117B509; Sat, 8 Jun 2024 09:01:40 +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=1717837300; cv=none; b=cEZ6kg9/6dWXcn/4SNtwyAgQ6kiVWU6cRCDgzXgn6w+8Sus6fD5Q5J65qBay+uLAvYEXpSmO5AvotC4qKjb7YApZIWExwadD/S5L0xGnD9Z8mZaHsMTmuhB7OyiUxGqcA43zHI5ILWhrGFJDae977U+Gz66IT4Q5spmxsniqjOk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717837300; c=relaxed/simple; bh=ZNd17jjvGjK/HSzWJlLePvcKrIMcqrY8szK9rl118M0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=o2XUTORI/v6AGNb/oR8Z5agXYoKA8kHi846/eCc1h+QdwaATfDryo41Hhq+Pvrm498EW8eNX50Rmb71KKJTwBEYcNvRblTyaGXmpOY7gZdLHRI1IP4CIJcOx1Qup1sJJ3VFxAcE4f6+qyN23e6k2EIhJ9lmQCY+i4+pasM2eckw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Ij/oYz5P; 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="Ij/oYz5P" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 83DEBC4AF08; Sat, 8 Jun 2024 09:01:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1717837300; bh=ZNd17jjvGjK/HSzWJlLePvcKrIMcqrY8szK9rl118M0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Ij/oYz5PiNFJzhuFGB2OX6sNNG8HHU0PxMAPeycIsLqx9zSUPQzTnSpJWT6UkwRhD ztcZ7yRfuBp78s91QgDdAr/T9fNw/MACZTcPb7RXseifp0rJJWUW+5C7ve1xnfDERx KiDDo/mFCQ4LVXJ04xpnHFqEUqYjeYmARUpkMwiF+bNfteLDy7FsNywsmLZ3D4lnpq Fg9SCAznlhlU1nL1diYXT0flA3k2HjR3ftKk1t1dP9q67FdNn+QUkDnlTSti/uVT8T ARd06BlcaSHrh0+UMeVGdvP7xpFqUcYNTUeGH3IxxmtIJHQownXFEPsKmBRuWlBClE Ar/v7eCiLHnyA== From: Benjamin Tissoires Date: Sat, 08 Jun 2024 11:01:20 +0200 Subject: [PATCH HID v3 08/16] HID: bpf: remove tracing HID-BPF capability Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240608-hid_bpf_struct_ops-v3-8-6ac6ade58329@kernel.org> References: <20240608-hid_bpf_struct_ops-v3-0-6ac6ade58329@kernel.org> In-Reply-To: <20240608-hid_bpf_struct_ops-v3-0-6ac6ade58329@kernel.org> To: Shuah Khan , Jiri Kosina , Jonathan Corbet , Alexei Starovoitov Cc: linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, linux-input@vger.kernel.org, linux-doc@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1717837279; l=48702; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=ZNd17jjvGjK/HSzWJlLePvcKrIMcqrY8szK9rl118M0=; b=k282cP0xoFabLaF6vWeLs/5MiEENCoxm+g2ZYMysOK3hStMpDMPa3fdpcm5XaYJD6uOAxnoSm bzkdOfLwhUIAKiSX4RTvF/YnpvMgB3P84NiYzHq0m/vvjJSYg6aaxBH X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= We can now rely on struct_ops as we cleared the users in-tree. Signed-off-by: Benjamin Tissoires --- no changes in v3 changes in v2: - remove now unused enum hid_bpf_attach_flags --- drivers/hid/bpf/Makefile | 2 +- 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 | 193 +------- drivers/hid/bpf/hid_bpf_dispatch.h | 8 - drivers/hid/bpf/hid_bpf_jmp_table.c | 568 --------------------= ---- include/linux/hid_bpf.h | 54 +-- 9 files changed, 8 insertions(+), 1187 deletions(-) diff --git a/drivers/hid/bpf/Makefile b/drivers/hid/bpf/Makefile index 1cb3f31e9335..d1f2b81788ca 100644 --- a/drivers/hid/bpf/Makefile +++ b/drivers/hid/bpf/Makefile @@ -8,4 +8,4 @@ LIBBPF_INCLUDE =3D $(srctree)/tools/lib obj-$(CONFIG_HID_BPF) +=3D hid_bpf.o CFLAGS_hid_bpf_dispatch.o +=3D -I$(LIBBPF_INCLUDE) CFLAGS_hid_bpf_jmp_table.o +=3D -I$(LIBBPF_INCLUDE) -hid_bpf-objs +=3D hid_bpf_dispatch.o hid_bpf_jmp_table.o hid_bpf_struct_op= s.o +hid_bpf-objs +=3D hid_bpf_dispatch.o hid_bpf_struct_ops.o diff --git a/drivers/hid/bpf/entrypoints/Makefile b/drivers/hid/bpf/entrypo= ints/Makefile deleted file mode 100644 index 43b99b5575cf..000000000000 --- a/drivers/hid/bpf/entrypoints/Makefile +++ /dev/null @@ -1,93 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -OUTPUT :=3D .output -abs_out :=3D $(abspath $(OUTPUT)) - -CLANG ?=3D clang -LLC ?=3D llc -LLVM_STRIP ?=3D llvm-strip - -TOOLS_PATH :=3D $(abspath ../../../../tools) -BPFTOOL_SRC :=3D $(TOOLS_PATH)/bpf/bpftool -BPFTOOL_OUTPUT :=3D $(abs_out)/bpftool -DEFAULT_BPFTOOL :=3D $(BPFTOOL_OUTPUT)/bootstrap/bpftool -BPFTOOL ?=3D $(DEFAULT_BPFTOOL) - -LIBBPF_SRC :=3D $(TOOLS_PATH)/lib/bpf -LIBBPF_OUTPUT :=3D $(abs_out)/libbpf -LIBBPF_DESTDIR :=3D $(LIBBPF_OUTPUT) -LIBBPF_INCLUDE :=3D $(LIBBPF_DESTDIR)/include -BPFOBJ :=3D $(LIBBPF_OUTPUT)/libbpf.a - -INCLUDES :=3D -I$(OUTPUT) -I$(LIBBPF_INCLUDE) -I$(TOOLS_PATH)/include/uapi -CFLAGS :=3D -g -Wall - -VMLINUX_BTF_PATHS ?=3D $(if $(O),$(O)/vmlinux) \ - $(if $(KBUILD_OUTPUT),$(KBUILD_OUTPUT)/vmlinux) \ - ../../../../vmlinux \ - /sys/kernel/btf/vmlinux \ - /boot/vmlinux-$(shell uname -r) -VMLINUX_BTF ?=3D $(abspath $(firstword $(wildcard $(VMLINUX_BTF_PATHS)))) -ifeq ($(VMLINUX_BTF),) -$(error Cannot find a vmlinux for VMLINUX_BTF at any of "$(VMLINUX_BTF_PAT= HS)") -endif - -ifeq ($(V),1) -Q =3D -msg =3D -else -Q =3D @ -msg =3D @printf ' %-8s %s%s\n' "$(1)" "$(notdir $(2))" "$(if $(3), $(3))"; -MAKEFLAGS +=3D --no-print-directory -submake_extras :=3D feature_display=3D0 -endif - -.DELETE_ON_ERROR: - -.PHONY: all clean - -all: entrypoints.lskel.h - -clean: - $(call msg,CLEAN) - $(Q)rm -rf $(OUTPUT) entrypoints - -entrypoints.lskel.h: $(OUTPUT)/entrypoints.bpf.o | $(BPFTOOL) - $(call msg,GEN-SKEL,$@) - $(Q)$(BPFTOOL) gen skeleton -L $< > $@ - - -$(OUTPUT)/entrypoints.bpf.o: entrypoints.bpf.c $(OUTPUT)/vmlinux.h $(BPFOB= J) | $(OUTPUT) - $(call msg,BPF,$@) - $(Q)$(CLANG) -g -O2 --target=3Dbpf $(INCLUDES) \ - -c $(filter %.c,$^) -o $@ && \ - $(LLVM_STRIP) -g $@ - -$(OUTPUT)/vmlinux.h: $(VMLINUX_BTF) $(BPFTOOL) | $(INCLUDE_DIR) -ifeq ($(VMLINUX_H),) - $(call msg,GEN,,$@) - $(Q)$(BPFTOOL) btf dump file $(VMLINUX_BTF) format c > $@ -else - $(call msg,CP,,$@) - $(Q)cp "$(VMLINUX_H)" $@ -endif - -$(OUTPUT) $(LIBBPF_OUTPUT) $(BPFTOOL_OUTPUT): - $(call msg,MKDIR,$@) - $(Q)mkdir -p $@ - -$(BPFOBJ): $(wildcard $(LIBBPF_SRC)/*.[ch] $(LIBBPF_SRC)/Makefile) | $(LIB= BPF_OUTPUT) - $(Q)$(MAKE) $(submake_extras) -C $(LIBBPF_SRC) \ - OUTPUT=3D$(abspath $(dir $@))/ prefix=3D \ - DESTDIR=3D$(LIBBPF_DESTDIR) $(abspath $@) install_headers - -ifeq ($(CROSS_COMPILE),) -$(DEFAULT_BPFTOOL): $(BPFOBJ) | $(BPFTOOL_OUTPUT) - $(Q)$(MAKE) $(submake_extras) -C $(BPFTOOL_SRC) \ - OUTPUT=3D$(BPFTOOL_OUTPUT)/ \ - LIBBPF_BOOTSTRAP_OUTPUT=3D$(LIBBPF_OUTPUT)/ \ - LIBBPF_BOOTSTRAP_DESTDIR=3D$(LIBBPF_DESTDIR)/ bootstrap -else -$(DEFAULT_BPFTOOL): | $(BPFTOOL_OUTPUT) - $(Q)$(MAKE) $(submake_extras) -C $(BPFTOOL_SRC) \ - OUTPUT=3D$(BPFTOOL_OUTPUT)/ bootstrap -endif diff --git a/drivers/hid/bpf/entrypoints/README b/drivers/hid/bpf/entrypoin= ts/README deleted file mode 100644 index 147e0d41509f..000000000000 --- a/drivers/hid/bpf/entrypoints/README +++ /dev/null @@ -1,4 +0,0 @@ -WARNING: -If you change "entrypoints.bpf.c" do "make -j" in this directory to rebuil= d "entrypoints.skel.h". -Make sure to have clang 10 installed. -See Documentation/bpf/bpf_devel_QA.rst diff --git a/drivers/hid/bpf/entrypoints/entrypoints.bpf.c b/drivers/hid/bp= f/entrypoints/entrypoints.bpf.c deleted file mode 100644 index c22921125a1a..000000000000 --- a/drivers/hid/bpf/entrypoints/entrypoints.bpf.c +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright (c) 2022 Benjamin Tissoires */ - -#include ".output/vmlinux.h" -#include -#include - -#define HID_BPF_MAX_PROGS 1024 - -struct { - __uint(type, BPF_MAP_TYPE_PROG_ARRAY); - __uint(max_entries, HID_BPF_MAX_PROGS); - __uint(key_size, sizeof(__u32)); - __uint(value_size, sizeof(__u32)); -} hid_jmp_table SEC(".maps"); - -SEC("fmod_ret/__hid_bpf_tail_call") -int BPF_PROG(hid_tail_call, struct hid_bpf_ctx *hctx) -{ - bpf_tail_call(ctx, &hid_jmp_table, hctx->index); - - return 0; -} - -char LICENSE[] SEC("license") =3D "GPL"; diff --git a/drivers/hid/bpf/entrypoints/entrypoints.lskel.h b/drivers/hid/= bpf/entrypoints/entrypoints.lskel.h deleted file mode 100644 index 35618051598c..000000000000 --- a/drivers/hid/bpf/entrypoints/entrypoints.lskel.h +++ /dev/null @@ -1,248 +0,0 @@ -/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ -/* THIS FILE IS AUTOGENERATED BY BPFTOOL! */ -#ifndef __ENTRYPOINTS_BPF_SKEL_H__ -#define __ENTRYPOINTS_BPF_SKEL_H__ - -#include - -struct entrypoints_bpf { - struct bpf_loader_ctx ctx; - struct { - struct bpf_map_desc hid_jmp_table; - } maps; - struct { - struct bpf_prog_desc hid_tail_call; - } progs; - struct { - int hid_tail_call_fd; - } links; -}; - -static inline int -entrypoints_bpf__hid_tail_call__attach(struct entrypoints_bpf *skel) -{ - int prog_fd =3D skel->progs.hid_tail_call.prog_fd; - int fd =3D skel_raw_tracepoint_open(NULL, prog_fd); - - if (fd > 0) - skel->links.hid_tail_call_fd =3D fd; - return fd; -} - -static inline int -entrypoints_bpf__attach(struct entrypoints_bpf *skel) -{ - int ret =3D 0; - - ret =3D ret < 0 ? ret : entrypoints_bpf__hid_tail_call__attach(skel); - return ret < 0 ? ret : 0; -} - -static inline void -entrypoints_bpf__detach(struct entrypoints_bpf *skel) -{ - skel_closenz(skel->links.hid_tail_call_fd); -} -static void -entrypoints_bpf__destroy(struct entrypoints_bpf *skel) -{ - if (!skel) - return; - entrypoints_bpf__detach(skel); - skel_closenz(skel->progs.hid_tail_call.prog_fd); - skel_closenz(skel->maps.hid_jmp_table.map_fd); - skel_free(skel); -} -static inline struct entrypoints_bpf * -entrypoints_bpf__open(void) -{ - struct entrypoints_bpf *skel; - - skel =3D skel_alloc(sizeof(*skel)); - if (!skel) - goto cleanup; - skel->ctx.sz =3D (void *)&skel->links - (void *)skel; - return skel; -cleanup: - entrypoints_bpf__destroy(skel); - return NULL; -} - -static inline int -entrypoints_bpf__load(struct entrypoints_bpf *skel) -{ - struct bpf_load_and_run_opts opts =3D {}; - int err; - - opts.ctx =3D (struct bpf_loader_ctx *)skel; - opts.data_sz =3D 2856; - opts.data =3D (void *)"\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x9f\xeb\x= 01\0\ -\x18\0\0\0\0\0\0\0\x60\x02\0\0\x60\x02\0\0\x12\x02\0\0\0\0\0\0\0\0\0\x02\x= 03\0\ -\0\0\x01\0\0\0\0\0\0\x01\x04\0\0\0\x20\0\0\x01\0\0\0\0\0\0\0\x03\0\0\0\0\x= 02\0\ -\0\0\x04\0\0\0\x03\0\0\0\x05\0\0\0\0\0\0\x01\x04\0\0\0\x20\0\0\0\0\0\0\0\0= \0\0\ -\x02\x06\0\0\0\0\0\0\0\0\0\0\x03\0\0\0\0\x02\0\0\0\x04\0\0\0\0\x04\0\0\0\0= \0\0\ -\0\0\0\x02\x08\0\0\0\0\0\0\0\0\0\0\x03\0\0\0\0\x02\0\0\0\x04\0\0\0\x04\0\0= \0\0\ -\0\0\0\x04\0\0\x04\x20\0\0\0\x19\0\0\0\x01\0\0\0\0\0\0\0\x1e\0\0\0\x05\0\0= \0\ -\x40\0\0\0\x2a\0\0\0\x07\0\0\0\x80\0\0\0\x33\0\0\0\x07\0\0\0\xc0\0\0\0\x3e= \0\0\ -\0\0\0\0\x0e\x09\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\x02\x0c\0\0\0\x4c\0\0\0\0\0= \0\ -\x01\x08\0\0\0\x40\0\0\0\0\0\0\0\x01\0\0\x0d\x02\0\0\0\x5f\0\0\0\x0b\0\0\0= \x63\ -\0\0\0\x01\0\0\x0c\x0d\0\0\0\x09\x01\0\0\x05\0\0\x04\x20\0\0\0\x15\x01\0\0= \x10\ -\0\0\0\0\0\0\0\x1b\x01\0\0\x12\0\0\0\x40\0\0\0\x1f\x01\0\0\x10\0\0\0\x80\0= \0\0\ -\x2e\x01\0\0\x14\0\0\0\xa0\0\0\0\0\0\0\0\x15\0\0\0\xc0\0\0\0\x3a\x01\0\0\0= \0\0\ -\x08\x11\0\0\0\x40\x01\0\0\0\0\0\x01\x04\0\0\0\x20\0\0\0\0\0\0\0\0\0\0\x02= \x13\ -\0\0\0\0\0\0\0\0\0\0\x0a\x1c\0\0\0\x4d\x01\0\0\x04\0\0\x06\x04\0\0\0\x5d\x= 01\0\ -\0\0\0\0\0\x6e\x01\0\0\x01\0\0\0\x80\x01\0\0\x02\0\0\0\x93\x01\0\0\x03\0\0= \0\0\ -\0\0\0\x02\0\0\x05\x04\0\0\0\xa4\x01\0\0\x16\0\0\0\0\0\0\0\xab\x01\0\0\x16= \0\0\ -\0\0\0\0\0\xb0\x01\0\0\0\0\0\x08\x02\0\0\0\xec\x01\0\0\0\0\0\x01\x01\0\0\0= \x08\ -\0\0\x01\0\0\0\0\0\0\0\x03\0\0\0\0\x17\0\0\0\x04\0\0\0\x04\0\0\0\xf1\x01\0= \0\0\ -\0\0\x0e\x18\0\0\0\x01\0\0\0\xf9\x01\0\0\x01\0\0\x0f\x20\0\0\0\x0a\0\0\0\0= \0\0\ -\0\x20\0\0\0\xff\x01\0\0\x01\0\0\x0f\x04\0\0\0\x19\0\0\0\0\0\0\0\x04\0\0\0= \x07\ -\x02\0\0\0\0\0\x07\0\0\0\0\0\x69\x6e\x74\0\x5f\x5f\x41\x52\x52\x41\x59\x5f= \x53\ -\x49\x5a\x45\x5f\x54\x59\x50\x45\x5f\x5f\0\x74\x79\x70\x65\0\x6d\x61\x78\x= 5f\ -\x65\x6e\x74\x72\x69\x65\x73\0\x6b\x65\x79\x5f\x73\x69\x7a\x65\0\x76\x61\x= 6c\ -\x75\x65\x5f\x73\x69\x7a\x65\0\x68\x69\x64\x5f\x6a\x6d\x70\x5f\x74\x61\x62= \x6c\ -\x65\0\x75\x6e\x73\x69\x67\x6e\x65\x64\x20\x6c\x6f\x6e\x67\x20\x6c\x6f\x6e= \x67\ -\0\x63\x74\x78\0\x68\x69\x64\x5f\x74\x61\x69\x6c\x5f\x63\x61\x6c\x6c\0\x66= \x6d\ -\x6f\x64\x5f\x72\x65\x74\x2f\x5f\x5f\x68\x69\x64\x5f\x62\x70\x66\x5f\x74\x= 61\ -\x69\x6c\x5f\x63\x61\x6c\x6c\0\x2f\x68\x6f\x6d\x65\x2f\x62\x74\x69\x73\x73= \x6f\ -\x69\x72\x2f\x53\x72\x63\x2f\x68\x69\x64\x2f\x64\x72\x69\x76\x65\x72\x73\x= 2f\ -\x68\x69\x64\x2f\x62\x70\x66\x2f\x65\x6e\x74\x72\x79\x70\x6f\x69\x6e\x74\x= 73\ -\x2f\x65\x6e\x74\x72\x79\x70\x6f\x69\x6e\x74\x73\x2e\x62\x70\x66\x2e\x63\0= \x69\ -\x6e\x74\x20\x42\x50\x46\x5f\x50\x52\x4f\x47\x28\x68\x69\x64\x5f\x74\x61\x= 69\ -\x6c\x5f\x63\x61\x6c\x6c\x2c\x20\x73\x74\x72\x75\x63\x74\x20\x68\x69\x64\x= 5f\ -\x62\x70\x66\x5f\x63\x74\x78\x20\x2a\x68\x63\x74\x78\x29\0\x68\x69\x64\x5f= \x62\ -\x70\x66\x5f\x63\x74\x78\0\x69\x6e\x64\x65\x78\0\x68\x69\x64\0\x61\x6c\x6c= \x6f\ -\x63\x61\x74\x65\x64\x5f\x73\x69\x7a\x65\0\x72\x65\x70\x6f\x72\x74\x5f\x74= \x79\ -\x70\x65\0\x5f\x5f\x75\x33\x32\0\x75\x6e\x73\x69\x67\x6e\x65\x64\x20\x69\x= 6e\ -\x74\0\x68\x69\x64\x5f\x72\x65\x70\x6f\x72\x74\x5f\x74\x79\x70\x65\0\x48\x= 49\ -\x44\x5f\x49\x4e\x50\x55\x54\x5f\x52\x45\x50\x4f\x52\x54\0\x48\x49\x44\x5f= \x4f\ -\x55\x54\x50\x55\x54\x5f\x52\x45\x50\x4f\x52\x54\0\x48\x49\x44\x5f\x46\x45= \x41\ -\x54\x55\x52\x45\x5f\x52\x45\x50\x4f\x52\x54\0\x48\x49\x44\x5f\x52\x45\x50= \x4f\ -\x52\x54\x5f\x54\x59\x50\x45\x53\0\x72\x65\x74\x76\x61\x6c\0\x73\x69\x7a\x= 65\0\ -\x5f\x5f\x73\x33\x32\0\x30\x3a\x30\0\x09\x62\x70\x66\x5f\x74\x61\x69\x6c\x= 5f\ -\x63\x61\x6c\x6c\x28\x63\x74\x78\x2c\x20\x26\x68\x69\x64\x5f\x6a\x6d\x70\x= 5f\ -\x74\x61\x62\x6c\x65\x2c\x20\x68\x63\x74\x78\x2d\x3e\x69\x6e\x64\x65\x78\x= 29\ -\x3b\0\x63\x68\x61\x72\0\x4c\x49\x43\x45\x4e\x53\x45\0\x2e\x6d\x61\x70\x73= \0\ -\x6c\x69\x63\x65\x6e\x73\x65\0\x68\x69\x64\x5f\x64\x65\x76\x69\x63\x65\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x8a\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \x03\ -\0\0\0\x04\0\0\0\x04\0\0\0\0\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x68\x69\x64\x= 5f\ -\x6a\x6d\x70\x5f\x74\x61\x62\x6c\x65\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\x47\x50\x4c\0\0\0\0\0\x79\x12\0\0\0\0\0\0\x61\x23\0\0= \0\0\ -\0\0\x18\x52\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x85\0\0\0\x0c\0\0\0\xb7\0\0\0\0\0= \0\0\ -\x95\0\0\0\0\0\0\0\0\0\0\0\x0e\0\0\0\0\0\0\0\x8e\0\0\0\xd3\0\0\0\x05\x48\0= \0\ -\x01\0\0\0\x8e\0\0\0\xba\x01\0\0\x02\x50\0\0\x05\0\0\0\x8e\0\0\0\xd3\0\0\0= \x05\ -\x48\0\0\x08\0\0\0\x0f\0\0\0\xb6\x01\0\0\0\0\0\0\x1a\0\0\0\x07\0\0\0\0\0\0= \0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x68= \x69\ -\x64\x5f\x74\x61\x69\x6c\x5f\x63\x61\x6c\x6c\0\0\0\0\0\0\0\x1a\0\0\0\0\0\0= \0\ -\x08\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\x10\0\0\0\0\0\0\0\0\0\0\0\x03\0\0\0\x= 01\0\ -\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\0\0\0\0\0\0\0\x= 5f\ -\x5f\x68\x69\x64\x5f\x62\x70\x66\x5f\x74\x61\x69\x6c\x5f\x63\x61\x6c\x6c\0= \0\0\ -\0\0"; - opts.insns_sz =3D 1192; - opts.insns =3D (void *)"\ -\xbf\x16\0\0\0\0\0\0\xbf\xa1\0\0\0\0\0\0\x07\x01\0\0\x78\xff\xff\xff\xb7\x= 02\0\ -\0\x88\0\0\0\xb7\x03\0\0\0\0\0\0\x85\0\0\0\x71\0\0\0\x05\0\x11\0\0\0\0\0\x= 61\ -\xa1\x78\xff\0\0\0\0\xd5\x01\x01\0\0\0\0\0\x85\0\0\0\xa8\0\0\0\x61\xa1\x7c= \xff\ -\0\0\0\0\xd5\x01\x01\0\0\0\0\0\x85\0\0\0\xa8\0\0\0\x61\xa1\x80\xff\0\0\0\0= \xd5\ -\x01\x01\0\0\0\0\0\x85\0\0\0\xa8\0\0\0\x18\x60\0\0\0\0\0\0\0\0\0\0\0\0\0\0= \x61\ -\x01\0\0\0\0\0\0\xd5\x01\x02\0\0\0\0\0\xbf\x19\0\0\0\0\0\0\x85\0\0\0\xa8\0= \0\0\ -\xbf\x70\0\0\0\0\0\0\x95\0\0\0\0\0\0\0\x61\x60\x08\0\0\0\0\0\x18\x61\0\0\0= \0\0\ -\0\0\0\0\0\xa8\x09\0\0\x63\x01\0\0\0\0\0\0\x61\x60\x0c\0\0\0\0\0\x18\x61\0= \0\0\ -\0\0\0\0\0\0\0\xa4\x09\0\0\x63\x01\0\0\0\0\0\0\x79\x60\x10\0\0\0\0\0\x18\x= 61\0\ -\0\0\0\0\0\0\0\0\0\x98\x09\0\0\x7b\x01\0\0\0\0\0\0\x18\x60\0\0\0\0\0\0\0\0= \0\0\ -\0\x05\0\0\x18\x61\0\0\0\0\0\0\0\0\0\0\x90\x09\0\0\x7b\x01\0\0\0\0\0\0\xb7= \x01\ -\0\0\x12\0\0\0\x18\x62\0\0\0\0\0\0\0\0\0\0\x90\x09\0\0\xb7\x03\0\0\x1c\0\0= \0\ -\x85\0\0\0\xa6\0\0\0\xbf\x07\0\0\0\0\0\0\xc5\x07\xd7\xff\0\0\0\0\x63\x7a\x= 78\ -\xff\0\0\0\0\x61\x60\x1c\0\0\0\0\0\x15\0\x03\0\0\0\0\0\x18\x61\0\0\0\0\0\0= \0\0\ -\0\0\xbc\x09\0\0\x63\x01\0\0\0\0\0\0\xb7\x01\0\0\0\0\0\0\x18\x62\0\0\0\0\0= \0\0\ -\0\0\0\xb0\x09\0\0\xb7\x03\0\0\x48\0\0\0\x85\0\0\0\xa6\0\0\0\xbf\x07\0\0\0= \0\0\ -\0\xc5\x07\xca\xff\0\0\0\0\x18\x61\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x63\x71\0\0= \0\0\ -\0\0\x18\x60\0\0\0\0\0\0\0\0\0\0\xf8\x09\0\0\x18\x61\0\0\0\0\0\0\0\0\0\0\x= 90\ -\x0a\0\0\x7b\x01\0\0\0\0\0\0\x18\x60\0\0\0\0\0\0\0\0\0\0\0\x0a\0\0\x18\x61= \0\0\ -\0\0\0\0\0\0\0\0\x88\x0a\0\0\x7b\x01\0\0\0\0\0\0\x18\x60\0\0\0\0\0\0\0\0\0= \0\ -\x38\x0a\0\0\x18\x61\0\0\0\0\0\0\0\0\0\0\xd0\x0a\0\0\x7b\x01\0\0\0\0\0\0\x= 18\ -\x60\0\0\0\0\0\0\0\0\0\0\x40\x0a\0\0\x18\x61\0\0\0\0\0\0\0\0\0\0\xe0\x0a\0= \0\ -\x7b\x01\0\0\0\0\0\0\x18\x60\0\0\0\0\0\0\0\0\0\0\x70\x0a\0\0\x18\x61\0\0\0= \0\0\ -\0\0\0\0\0\0\x0b\0\0\x7b\x01\0\0\0\0\0\0\x18\x60\0\0\0\0\0\0\0\0\0\0\0\0\0= \0\ -\x18\x61\0\0\0\0\0\0\0\0\0\0\xf8\x0a\0\0\x7b\x01\0\0\0\0\0\0\x61\x60\x08\0= \0\0\ -\0\0\x18\x61\0\0\0\0\0\0\0\0\0\0\x98\x0a\0\0\x63\x01\0\0\0\0\0\0\x61\x60\x= 0c\0\ -\0\0\0\0\x18\x61\0\0\0\0\0\0\0\0\0\0\x9c\x0a\0\0\x63\x01\0\0\0\0\0\0\x79\x= 60\ -\x10\0\0\0\0\0\x18\x61\0\0\0\0\0\0\0\0\0\0\xa0\x0a\0\0\x7b\x01\0\0\0\0\0\0= \x61\ -\xa0\x78\xff\0\0\0\0\x18\x61\0\0\0\0\0\0\0\0\0\0\xc8\x0a\0\0\x63\x01\0\0\0= \0\0\ -\0\x18\x61\0\0\0\0\0\0\0\0\0\0\x10\x0b\0\0\xb7\x02\0\0\x14\0\0\0\xb7\x03\0= \0\ -\x0c\0\0\0\xb7\x04\0\0\0\0\0\0\x85\0\0\0\xa7\0\0\0\xbf\x07\0\0\0\0\0\0\xc5= \x07\ -\x91\xff\0\0\0\0\x18\x60\0\0\0\0\0\0\0\0\0\0\x80\x0a\0\0\x63\x70\x6c\0\0\0= \0\0\ -\x77\x07\0\0\x20\0\0\0\x63\x70\x70\0\0\0\0\0\xb7\x01\0\0\x05\0\0\0\x18\x62= \0\0\ -\0\0\0\0\0\0\0\0\x80\x0a\0\0\xb7\x03\0\0\x8c\0\0\0\x85\0\0\0\xa6\0\0\0\xbf= \x07\ -\0\0\0\0\0\0\x18\x60\0\0\0\0\0\0\0\0\0\0\xf0\x0a\0\0\x61\x01\0\0\0\0\0\0\x= d5\ -\x01\x02\0\0\0\0\0\xbf\x19\0\0\0\0\0\0\x85\0\0\0\xa8\0\0\0\xc5\x07\x7f\xff= \0\0\ -\0\0\x63\x7a\x80\xff\0\0\0\0\x61\xa1\x78\xff\0\0\0\0\xd5\x01\x02\0\0\0\0\0= \xbf\ -\x19\0\0\0\0\0\0\x85\0\0\0\xa8\0\0\0\x61\xa0\x80\xff\0\0\0\0\x63\x06\x28\0= \0\0\ -\0\0\x18\x61\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x61\x10\0\0\0\0\0\0\x63\x06\x18\0= \0\0\ -\0\0\xb7\0\0\0\0\0\0\0\x95\0\0\0\0\0\0\0"; - err =3D bpf_load_and_run(&opts); - if (err < 0) - return err; - return 0; -} - -static inline struct entrypoints_bpf * -entrypoints_bpf__open_and_load(void) -{ - struct entrypoints_bpf *skel; - - skel =3D entrypoints_bpf__open(); - if (!skel) - return NULL; - if (entrypoints_bpf__load(skel)) { - entrypoints_bpf__destroy(skel); - return NULL; - } - return skel; -} - -__attribute__((unused)) static void -entrypoints_bpf__assert(struct entrypoints_bpf *s __attribute__((unused))) -{ -#ifdef __cplusplus -#define _Static_assert static_assert -#endif -#ifdef __cplusplus -#undef _Static_assert -#endif -} - -#endif /* __ENTRYPOINTS_BPF_SKEL_H__ */ diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_d= ispatch.c index 7216c3c7713d..06cc628e7bb4 100644 --- a/drivers/hid/bpf/hid_bpf_dispatch.c +++ b/drivers/hid/bpf/hid_bpf_dispatch.c @@ -3,7 +3,7 @@ /* * HID-BPF support for Linux * - * Copyright (c) 2022 Benjamin Tissoires + * Copyright (c) 2022-2024 Benjamin Tissoires */ =20 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -17,34 +17,11 @@ #include #include #include -#include #include "hid_bpf_dispatch.h" -#include "entrypoints/entrypoints.lskel.h" =20 struct hid_ops *hid_ops; EXPORT_SYMBOL(hid_ops); =20 -/** - * hid_bpf_device_event - Called whenever an event is coming in from the d= evice - * - * @ctx: The HID-BPF context - * - * @return %0 on success and keep processing; a positive value to change t= he - * incoming size buffer; a negative error code to interrupt the processing - * of this event - * - * Declare an %fmod_ret tracing bpf program to this function and attach th= is - * program through hid_bpf_attach_prog() to have this helper called for - * any incoming event from the device itself. - * - * The function is called while on IRQ context, so we can not sleep. - */ -/* never used by the kernel but declared so we can load and attach a trace= point */ -__weak noinline int hid_bpf_device_event(struct hid_bpf_ctx *ctx) -{ - return 0; -} - u8 * dispatch_hid_bpf_device_event(struct hid_device *hdev, enum hid_report_typ= e type, u8 *data, u32 *size, int interrupt) @@ -52,7 +29,6 @@ dispatch_hid_bpf_device_event(struct hid_device *hdev, en= um hid_report_type type struct hid_bpf_ctx_kern ctx_kern =3D { .ctx =3D { .hid =3D hdev, - .report_type =3D type, .allocated_size =3D hdev->bpf.allocated_data, .size =3D *size, }, @@ -86,11 +62,6 @@ dispatch_hid_bpf_device_event(struct hid_device *hdev, e= num hid_report_type type } rcu_read_unlock(); =20 - ret =3D hid_bpf_prog_run(hdev, HID_BPF_PROG_TYPE_DEVICE_EVENT, &ctx_kern); - if (ret < 0) - return ERR_PTR(ret); - ret =3D ctx_kern.ctx.retval; - if (ret) { if (ret > ctx_kern.ctx.allocated_size) return ERR_PTR(-EINVAL); @@ -102,26 +73,6 @@ dispatch_hid_bpf_device_event(struct hid_device *hdev, = enum hid_report_type type } EXPORT_SYMBOL_GPL(dispatch_hid_bpf_device_event); =20 -/** - * hid_bpf_rdesc_fixup - Called when the probe function parses the report - * descriptor of the HID device - * - * @ctx: The HID-BPF context - * - * @return 0 on success and keep processing; a positive value to change the - * incoming size buffer; a negative error code to interrupt the processing - * of this event - * - * Declare an %fmod_ret tracing bpf program to this function and attach th= is - * program through hid_bpf_attach_prog() to have this helper called before= any - * parsing of the report descriptor by HID. - */ -/* never used by the kernel but declared so we can load and attach a trace= point */ -__weak noinline int hid_bpf_rdesc_fixup(struct hid_bpf_ctx *ctx) -{ - return 0; -} - u8 *call_hid_bpf_rdesc_fixup(struct hid_device *hdev, u8 *rdesc, unsigned = int *size) { int ret; @@ -133,16 +84,16 @@ u8 *call_hid_bpf_rdesc_fixup(struct hid_device *hdev, = u8 *rdesc, unsigned int *s }, }; =20 + if (!hdev->bpf.rdesc_ops) + goto ignore_bpf; + ctx_kern.data =3D kzalloc(ctx_kern.ctx.allocated_size, GFP_KERNEL); if (!ctx_kern.data) goto ignore_bpf; =20 memcpy(ctx_kern.data, rdesc, min_t(unsigned int, *size, HID_MAX_DESCRIPTO= R_SIZE)); =20 - if (hdev->bpf.rdesc_ops) - ret =3D hdev->bpf.rdesc_ops->hid_rdesc_fixup(&ctx_kern.ctx); - else - ret =3D hid_bpf_prog_run(hdev, HID_BPF_PROG_TYPE_RDESC_FIXUP, &ctx_kern); + ret =3D hdev->bpf.rdesc_ops->hid_rdesc_fixup(&ctx_kern.ctx); if (ret < 0) goto ignore_bpf; =20 @@ -242,39 +193,6 @@ int hid_bpf_reconnect(struct hid_device *hdev) return 0; } =20 -static int do_hid_bpf_attach_prog(struct hid_device *hdev, int prog_fd, st= ruct bpf_prog *prog, - __u32 flags) -{ - int fd, err, prog_type; - - prog_type =3D hid_bpf_get_prog_attach_type(prog); - if (prog_type < 0) - return prog_type; - - if (prog_type >=3D HID_BPF_PROG_TYPE_MAX) - return -EINVAL; - - if (prog_type =3D=3D HID_BPF_PROG_TYPE_DEVICE_EVENT) { - err =3D hid_bpf_allocate_event_data(hdev); - if (err) - return err; - } - - fd =3D __hid_bpf_attach_prog(hdev, prog_type, prog_fd, prog, flags); - if (fd < 0) - return fd; - - if (prog_type =3D=3D HID_BPF_PROG_TYPE_RDESC_FIXUP) { - err =3D hid_bpf_reconnect(hdev); - if (err) { - close_fd(fd); - return err; - } - } - - return fd; -} - /* Disables missing prototype warnings */ __bpf_kfunc_start_defs(); =20 @@ -303,57 +221,6 @@ hid_bpf_get_data(struct hid_bpf_ctx *ctx, unsigned int= offset, const size_t rdwr return ctx_kern->data + offset; } =20 -/** - * hid_bpf_attach_prog - Attach the given @prog_fd to the given HID device - * - * @hid_id: the system unique identifier of the HID device - * @prog_fd: an fd in the user process representing the program to attach - * @flags: any logical OR combination of &enum hid_bpf_attach_flags - * - * @returns an fd of a bpf_link object on success (> %0), an error code ot= herwise. - * Closing this fd will detach the program from the HID device (unless the= bpf_link - * is pinned to the BPF file system). - */ -/* called from syscall */ -__bpf_kfunc int -hid_bpf_attach_prog(unsigned int hid_id, int prog_fd, __u32 flags) -{ - struct hid_device *hdev; - struct bpf_prog *prog; - int err, fd; - - if ((flags & ~HID_BPF_FLAG_MASK)) - return -EINVAL; - - hdev =3D hid_get_device(hid_id); - if (IS_ERR(hdev)) - return PTR_ERR(hdev); - - /* - * take a ref on the prog itself, it will be released - * on errors or when it'll be detached - */ - prog =3D bpf_prog_get(prog_fd); - if (IS_ERR(prog)) { - err =3D PTR_ERR(prog); - goto out_dev_put; - } - - fd =3D do_hid_bpf_attach_prog(hdev, prog_fd, prog, flags); - if (fd < 0) { - err =3D fd; - goto out_prog_put; - } - - return fd; - - out_prog_put: - bpf_prog_put(prog); - out_dev_put: - hid_put_device(hdev); - return err; -} - /** * hid_bpf_allocate_context - Allocate a context to the given HID device * @@ -583,21 +450,8 @@ static const struct btf_kfunc_id_set hid_bpf_kfunc_set= =3D { .set =3D &hid_bpf_kfunc_ids, }; =20 -/* our HID-BPF entrypoints */ -BTF_SET8_START(hid_bpf_fmodret_ids) -BTF_ID_FLAGS(func, hid_bpf_device_event) -BTF_ID_FLAGS(func, hid_bpf_rdesc_fixup) -BTF_ID_FLAGS(func, __hid_bpf_tail_call) -BTF_SET8_END(hid_bpf_fmodret_ids) - -static const struct btf_kfunc_id_set hid_bpf_fmodret_set =3D { - .owner =3D THIS_MODULE, - .set =3D &hid_bpf_fmodret_ids, -}; - /* for syscall HID-BPF */ BTF_KFUNCS_START(hid_bpf_syscall_kfunc_ids) -BTF_ID_FLAGS(func, hid_bpf_attach_prog) BTF_ID_FLAGS(func, hid_bpf_allocate_context, KF_ACQUIRE | KF_RET_NULL) BTF_ID_FLAGS(func, hid_bpf_release_context, KF_RELEASE) BTF_ID_FLAGS(func, hid_bpf_hw_request) @@ -622,8 +476,6 @@ int hid_bpf_connect_device(struct hid_device *hdev) break; } } - if (rcu_dereference(hdev->bpf.progs[HID_BPF_PROG_TYPE_DEVICE_EVENT])) - need_to_allocate =3D true; rcu_read_unlock(); =20 /* only allocate BPF data if there are programs attached */ @@ -650,14 +502,12 @@ void hid_bpf_destroy_device(struct hid_device *hdev) /* mark the device as destroyed in bpf so we don't reattach it */ hdev->bpf.destroyed =3D true; =20 - __hid_bpf_destroy_device(hdev); __hid_bpf_ops_destroy_device(hdev); } EXPORT_SYMBOL_GPL(hid_bpf_destroy_device); =20 void hid_bpf_device_init(struct hid_device *hdev) { - spin_lock_init(&hdev->bpf.progs_lock); INIT_LIST_HEAD(&hdev->bpf.prog_list); mutex_init(&hdev->bpf.prog_list_lock); } @@ -670,37 +520,15 @@ static int __init hid_bpf_init(void) /* Note: if we exit with an error any time here, we would entirely break = HID, which * is probably not something we want. So we log an error and return succe= ss. * - * This is not a big deal: the syscall allowing to attach a BPF program t= o a HID device - * will not be available, so nobody will be able to use the functionality. + * This is not a big deal: nobody will be able to use the functionality. */ =20 - err =3D register_btf_fmodret_id_set(&hid_bpf_fmodret_set); - if (err) { - pr_warn("error while registering fmodret entrypoints: %d", err); - return 0; - } - - err =3D hid_bpf_preload_skel(); - if (err) { - pr_warn("error while preloading HID BPF dispatcher: %d", err); - return 0; - } - - /* register tracing kfuncs after we are sure we can load our preloaded bp= f program */ - err =3D register_btf_kfunc_id_set(BPF_PROG_TYPE_TRACING, &hid_bpf_kfunc_s= et); - if (err) { - pr_warn("error while setting HID BPF tracing kfuncs: %d", err); - return 0; - } - - /* register struct_ops kfuncs after we are sure we can load our preloaded= bpf program */ err =3D register_btf_kfunc_id_set(BPF_PROG_TYPE_STRUCT_OPS, &hid_bpf_kfun= c_set); if (err) { pr_warn("error while setting HID BPF tracing kfuncs: %d", err); return 0; } =20 - /* register syscalls after we are sure we can load our preloaded bpf prog= ram */ err =3D register_btf_kfunc_id_set(BPF_PROG_TYPE_SYSCALL, &hid_bpf_syscall= _kfunc_set); if (err) { pr_warn("error while setting HID BPF syscall kfuncs: %d", err); @@ -710,15 +538,6 @@ static int __init hid_bpf_init(void) return 0; } =20 -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); -module_exit(hid_bpf_exit); MODULE_AUTHOR("Benjamin Tissoires"); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/bpf/hid_bpf_dispatch.h b/drivers/hid/bpf/hid_bpf_d= ispatch.h index e52c43d81650..835e6f69f479 100644 --- a/drivers/hid/bpf/hid_bpf_dispatch.h +++ b/drivers/hid/bpf/hid_bpf_dispatch.h @@ -13,15 +13,7 @@ struct hid_bpf_ctx_kern { struct hid_device *hid_get_device(unsigned int hid_id); void hid_put_device(struct hid_device *hid); int hid_bpf_allocate_event_data(struct hid_device *hdev); -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, - struct bpf_prog *prog, __u32 flags); -void __hid_bpf_destroy_device(struct hid_device *hdev); void __hid_bpf_ops_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); int hid_bpf_reconnect(struct hid_device *hdev); =20 struct bpf_prog; diff --git a/drivers/hid/bpf/hid_bpf_jmp_table.c b/drivers/hid/bpf/hid_bpf_= jmp_table.c deleted file mode 100644 index 8a54ba447718..000000000000 --- a/drivers/hid/bpf/hid_bpf_jmp_table.c +++ /dev/null @@ -1,568 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only - -/* - * HID-BPF support for Linux - * - * Copyright (c) 2022 Benjamin Tissoires - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#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 - * a circular buffer - */ - -#define NEXT(idx) (((idx) + 1) & (HID_BPF_MAX_PROGS - 1)) -#define PREV(idx) (((idx) - 1) & (HID_BPF_MAX_PROGS - 1)) - -/* - * represents one attached program stored in the hid jump table - */ -struct hid_bpf_prog_entry { - struct bpf_prog *prog; - struct hid_device *hdev; - enum hid_bpf_prog_type type; - u16 idx; -}; - -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 */ - unsigned long enabled[BITS_TO_LONGS(HID_BPF_MAX_PROGS)]; -}; - -#define FOR_ENTRIES(__i, __start, __end) \ - for (__i =3D __start; CIRC_CNT(__end, __i, HID_BPF_MAX_PROGS); __i =3D NE= XT(__i)) - -static struct hid_bpf_jmp_table jmp_table; - -static DEFINE_MUTEX(hid_bpf_attach_lock); /* held when attaching/detachin= g programs */ - -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) { - case HID_BPF_PROG_TYPE_DEVICE_EVENT: - return HID_BPF_MAX_PROGS_PER_DEV; - case HID_BPF_PROG_TYPE_RDESC_FIXUP: - return 1; - default: - return -EINVAL; - } -} - -static int hid_bpf_program_count(struct hid_device *hdev, - struct bpf_prog *prog, - enum hid_bpf_prog_type type) -{ - int i, n =3D 0; - - if (type >=3D HID_BPF_PROG_TYPE_MAX) - return -EINVAL; - - if (type =3D=3D HID_BPF_PROG_TYPE_RDESC_FIXUP && hdev->bpf.rdesc_ops) - n +=3D 1; - - FOR_ENTRIES(i, jmp_table.tail, jmp_table.head) { - struct hid_bpf_prog_entry *entry =3D &jmp_table.entries[i]; - - if (type !=3D HID_BPF_PROG_TYPE_UNDEF && entry->type !=3D type) - continue; - - if (hdev && entry->hdev !=3D hdev) - continue; - - if (prog && entry->prog !=3D prog) - continue; - - n++; - } - - 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; - int i, idx, err =3D 0; - - rcu_read_lock(); - prog_list =3D rcu_dereference(hdev->bpf.progs[type]); - - if (!prog_list) - goto out_unlock; - - for (i =3D 0; i < prog_list->prog_cnt; i++) { - idx =3D prog_list->prog_idx[i]; - - if (!test_bit(idx, jmp_table.enabled)) - continue; - - ctx_kern->ctx.index =3D idx; - err =3D __hid_bpf_tail_call(&ctx_kern->ctx); - if (err < 0) - break; - if (err) - ctx_kern->ctx.retval =3D err; - } - - out_unlock: - rcu_read_unlock(); - - return err; -} - -/* - * assign the list of programs attached to a given hid device. - */ -static void __hid_bpf_set_hdev_progs(struct hid_device *hdev, struct hid_b= pf_prog_list *new_list, - enum hid_bpf_prog_type type) -{ - struct hid_bpf_prog_list *old_list; - - spin_lock(&hdev->bpf.progs_lock); - old_list =3D rcu_dereference_protected(hdev->bpf.progs[type], - lockdep_is_held(&hdev->bpf.progs_lock)); - rcu_assign_pointer(hdev->bpf.progs[type], new_list); - spin_unlock(&hdev->bpf.progs_lock); - synchronize_rcu(); - - kfree(old_list); -} - -/* - * allocate and populate the list of programs attached to a given hid devi= ce. - * - * Must be called under lock. - */ -static int hid_bpf_populate_hdev(struct hid_device *hdev, enum hid_bpf_pro= g_type type) -{ - struct hid_bpf_prog_list *new_list; - int i; - - if (type >=3D HID_BPF_PROG_TYPE_MAX || !hdev) - return -EINVAL; - - if (hdev->bpf.destroyed) - return 0; - - new_list =3D kzalloc(sizeof(*new_list), GFP_KERNEL); - if (!new_list) - return -ENOMEM; - - FOR_ENTRIES(i, jmp_table.tail, jmp_table.head) { - struct hid_bpf_prog_entry *entry =3D &jmp_table.entries[i]; - - if (entry->type =3D=3D type && entry->hdev =3D=3D hdev && - test_bit(entry->idx, jmp_table.enabled)) - new_list->prog_idx[new_list->prog_cnt++] =3D entry->idx; - } - - __hid_bpf_set_hdev_progs(hdev, new_list, type); - - return 0; -} - -static void __hid_bpf_do_release_prog(int map_fd, unsigned int idx) -{ - skel_map_delete_elem(map_fd, &idx); - jmp_table.progs[idx] =3D NULL; -} - -static void hid_bpf_release_progs(struct work_struct *work) -{ - int i, j, n, map_fd =3D -1; - bool hdev_destroyed; - - if (!jmp_table.map) - return; - - /* retrieve a fd of our prog_array map in BPF */ - map_fd =3D skel_map_get_fd_by_id(jmp_table.map->id); - if (map_fd < 0) - return; - - mutex_lock(&hid_bpf_attach_lock); /* protects against attaching new progr= ams */ - - /* detach unused progs from HID devices */ - FOR_ENTRIES(i, jmp_table.tail, jmp_table.head) { - struct hid_bpf_prog_entry *entry =3D &jmp_table.entries[i]; - enum hid_bpf_prog_type type; - struct hid_device *hdev; - - if (test_bit(entry->idx, jmp_table.enabled)) - continue; - - /* we have an attached prog */ - if (entry->hdev) { - hdev =3D entry->hdev; - type =3D entry->type; - /* - * hdev is still valid, even if we are called after hid_destroy_device(= ): - * when hid_bpf_attach() gets called, it takes a ref on the dev through - * bus_find_device() - */ - hdev_destroyed =3D hdev->bpf.destroyed; - - hid_bpf_populate_hdev(hdev, type); - - /* mark all other disabled progs from hdev of the given type as detache= d */ - FOR_ENTRIES(j, i, jmp_table.head) { - struct hid_bpf_prog_entry *next; - - next =3D &jmp_table.entries[j]; - - if (test_bit(next->idx, jmp_table.enabled)) - continue; - - if (next->hdev =3D=3D hdev && next->type =3D=3D type) { - /* - * clear the hdev reference and decrement the device ref - * that was taken during bus_find_device() while calling - * hid_bpf_attach() - */ - next->hdev =3D NULL; - put_device(&hdev->dev); - } - } - - /* if type was rdesc fixup and the device is not gone, reconnect device= */ - if (type =3D=3D HID_BPF_PROG_TYPE_RDESC_FIXUP && !hdev_destroyed) - hid_bpf_reconnect(hdev); - } - } - - /* remove all unused progs from the jump table */ - FOR_ENTRIES(i, jmp_table.tail, jmp_table.head) { - struct hid_bpf_prog_entry *entry =3D &jmp_table.entries[i]; - - if (test_bit(entry->idx, jmp_table.enabled)) - continue; - - if (entry->prog) - __hid_bpf_do_release_prog(map_fd, entry->idx); - } - - /* compact the entry list */ - n =3D jmp_table.tail; - FOR_ENTRIES(i, jmp_table.tail, jmp_table.head) { - struct hid_bpf_prog_entry *entry =3D &jmp_table.entries[i]; - - if (!test_bit(entry->idx, jmp_table.enabled)) - continue; - - jmp_table.entries[n] =3D jmp_table.entries[i]; - n =3D NEXT(n); - } - - jmp_table.head =3D n; - - mutex_unlock(&hid_bpf_attach_lock); - - if (map_fd >=3D 0) - close_fd(map_fd); -} - -static void hid_bpf_release_prog_at(int idx) -{ - int map_fd =3D -1; - - /* retrieve a fd of our prog_array map in BPF */ - map_fd =3D skel_map_get_fd_by_id(jmp_table.map->id); - if (map_fd < 0) - return; - - __hid_bpf_do_release_prog(map_fd, idx); - - close(map_fd); -} - -/* - * Insert the given BPF program represented by its fd 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) -{ - int i, index =3D -1, map_fd =3D -1, err =3D -EINVAL; - - /* retrieve a fd of our prog_array map in BPF */ - map_fd =3D skel_map_get_fd_by_id(jmp_table.map->id); - - if (map_fd < 0) { - err =3D -EINVAL; - goto out; - } - - /* find the first available index in the jmp_table */ - for (i =3D 0; i < HID_BPF_MAX_PROGS; i++) { - if (!jmp_table.progs[i] && index < 0) { - /* mark the index as used */ - jmp_table.progs[i] =3D prog; - index =3D i; - __set_bit(i, jmp_table.enabled); - } - } - if (index < 0) { - err =3D -ENOMEM; - goto out; - } - - /* insert the program in the jump table */ - err =3D skel_map_update_elem(map_fd, &index, &prog_fd, 0); - if (err) - goto out; - - /* return the index */ - err =3D index; - - out: - if (err < 0) - __hid_bpf_do_release_prog(map_fd, index); - if (map_fd >=3D 0) - close_fd(map_fd); - return err; -} - -int hid_bpf_get_prog_attach_type(struct bpf_prog *prog) -{ - int prog_type =3D HID_BPF_PROG_TYPE_UNDEF; - int i; - - for (i =3D 0; i < HID_BPF_PROG_TYPE_MAX; i++) { - if (hid_bpf_btf_ids[i] =3D=3D prog->aux->attach_btf_id) { - prog_type =3D i; - break; - } - } - - return prog_type; -} - -static void hid_bpf_link_release(struct bpf_link *link) -{ - struct hid_bpf_link *hid_link =3D - container_of(link, struct hid_bpf_link, link); - - __clear_bit(hid_link->hid_table_index, jmp_table.enabled); - schedule_work(&release_work); -} - -static void hid_bpf_link_dealloc(struct bpf_link *link) -{ - struct hid_bpf_link *hid_link =3D - container_of(link, struct hid_bpf_link, link); - - kfree(hid_link); -} - -static void hid_bpf_link_show_fdinfo(const struct bpf_link *link, - struct seq_file *seq) -{ - seq_printf(seq, - "attach_type:\tHID-BPF\n"); -} - -static const struct bpf_link_ops hid_bpf_link_lops =3D { - .release =3D hid_bpf_link_release, - .dealloc =3D hid_bpf_link_dealloc, - .show_fdinfo =3D hid_bpf_link_show_fdinfo, -}; - -/* 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) -{ - struct bpf_link_primer link_primer; - struct hid_bpf_link *link; - struct hid_bpf_prog_entry *prog_entry; - int cnt, err =3D -EINVAL, prog_table_idx =3D -1; - - mutex_lock(&hid_bpf_attach_lock); - - link =3D kzalloc(sizeof(*link), GFP_USER); - if (!link) { - err =3D -ENOMEM; - goto err_unlock; - } - - bpf_link_init(&link->link, BPF_LINK_TYPE_UNSPEC, - &hid_bpf_link_lops, prog); - - /* do not attach too many programs to a given HID device */ - cnt =3D hid_bpf_program_count(hdev, NULL, prog_type); - if (cnt < 0) { - err =3D cnt; - goto err_unlock; - } - - if (cnt >=3D hid_bpf_max_programs(prog_type)) { - err =3D -E2BIG; - goto err_unlock; - } - - prog_table_idx =3D hid_bpf_insert_prog(prog_fd, prog); - /* if the jmp table is full, abort */ - if (prog_table_idx < 0) { - err =3D prog_table_idx; - goto err_unlock; - } - - if (flags & HID_BPF_FLAG_INSERT_HEAD) { - /* take the previous prog_entry slot */ - jmp_table.tail =3D PREV(jmp_table.tail); - prog_entry =3D &jmp_table.entries[jmp_table.tail]; - } else { - /* take the next prog_entry slot */ - prog_entry =3D &jmp_table.entries[jmp_table.head]; - jmp_table.head =3D NEXT(jmp_table.head); - } - - /* we steal the ref here */ - prog_entry->prog =3D prog; - prog_entry->idx =3D prog_table_idx; - prog_entry->hdev =3D hdev; - prog_entry->type =3D prog_type; - - /* finally store the index in the device list */ - err =3D hid_bpf_populate_hdev(hdev, prog_type); - if (err) { - hid_bpf_release_prog_at(prog_table_idx); - goto err_unlock; - } - - link->hid_table_index =3D prog_table_idx; - - err =3D bpf_link_prime(&link->link, &link_primer); - if (err) - goto err_unlock; - - mutex_unlock(&hid_bpf_attach_lock); - - return bpf_link_settle(&link_primer); - - err_unlock: - mutex_unlock(&hid_bpf_attach_lock); - - kfree(link); - - return err; -} - -void __hid_bpf_destroy_device(struct hid_device *hdev) -{ - int type, i; - struct hid_bpf_prog_list *prog_list; - - rcu_read_lock(); - - for (type =3D 0; type < HID_BPF_PROG_TYPE_MAX; type++) { - prog_list =3D rcu_dereference(hdev->bpf.progs[type]); - - if (!prog_list) - continue; - - for (i =3D 0; i < prog_list->prog_cnt; i++) - __clear_bit(prog_list->prog_idx[i], jmp_table.enabled); - } - - rcu_read_unlock(); - - for (type =3D 0; type < HID_BPF_PROG_TYPE_MAX; type++) - __hid_bpf_set_hdev_progs(hdev, NULL, type); - - /* schedule release of all detached progs */ - schedule_work(&release_work); -} - -#define HID_BPF_PROGS_COUNT 1 - -static struct bpf_link *links[HID_BPF_PROGS_COUNT]; -static struct entrypoints_bpf *skel; - -void hid_bpf_free_links_and_skel(void) -{ - int i; - - /* the following is enough to release all programs attached to hid */ - if (jmp_table.map) - bpf_map_put_with_uref(jmp_table.map); - - for (i =3D 0; i < ARRAY_SIZE(links); i++) { - if (!IS_ERR_OR_NULL(links[i])) - bpf_link_put(links[i]); - } - entrypoints_bpf__destroy(skel); -} - -#define ATTACH_AND_STORE_LINK(__name) do { \ - err =3D entrypoints_bpf__##__name##__attach(skel); \ - if (err) \ - goto out; \ - \ - links[idx] =3D bpf_link_get_from_fd(skel->links.__name##_fd); \ - if (IS_ERR(links[idx])) { \ - err =3D PTR_ERR(links[idx]); \ - goto out; \ - } \ - \ - /* Avoid taking over stdin/stdout/stderr of init process. Zeroing out \ - * makes skel_closenz() a no-op later in iterators_bpf__destroy(). \ - */ \ - close_fd(skel->links.__name##_fd); \ - skel->links.__name##_fd =3D 0; \ - idx++; \ -} while (0) - -int hid_bpf_preload_skel(void) -{ - int err, idx =3D 0; - - skel =3D entrypoints_bpf__open(); - if (!skel) - return -ENOMEM; - - err =3D entrypoints_bpf__load(skel); - if (err) - goto out; - - jmp_table.map =3D bpf_map_get_with_uref(skel->maps.hid_jmp_table.map_fd); - if (IS_ERR(jmp_table.map)) { - err =3D PTR_ERR(jmp_table.map); - goto out; - } - - ATTACH_AND_STORE_LINK(hid_tail_call); - - return 0; -out: - hid_bpf_free_links_and_skel(); - return err; -} diff --git a/include/linux/hid_bpf.h b/include/linux/hid_bpf.h index c4f4ce10b7dd..447b94aa99ab 100644 --- a/include/linux/hid_bpf.h +++ b/include/linux/hid_bpf.h @@ -4,7 +4,7 @@ #define __HID_BPF_H =20 #include -#include +#include #include =20 struct hid_device; @@ -24,11 +24,7 @@ struct hid_device; * * All of these fields are currently read-only. * - * @index: program index in the jump table. No special meaning (a smaller = index - * doesn't mean the program will be executed before another progra= m with - * a bigger index). * @hid: the ``struct hid_device`` representing the device itself - * @report_type: used for ``hid_bpf_device_event()`` * @allocated_size: Allocated size of data. * * This is how much memory is available and can be reques= ted @@ -47,54 +43,21 @@ struct hid_device; * @retval: Return value of the previous program. */ 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; }; }; =20 -/** - * enum hid_bpf_attach_flags - flags used when attaching a HIF-BPF program - * - * @HID_BPF_FLAG_NONE: no specific flag is used, the kernel choses where to - * insert the program - * @HID_BPF_FLAG_INSERT_HEAD: insert the given program before any other pr= ogram - * currently attached to the device. This doesn= 't - * guarantee that this program will always be f= irst - */ -enum hid_bpf_attach_flags { - HID_BPF_FLAG_NONE =3D 0, - HID_BPF_FLAG_INSERT_HEAD =3D _BITUL(0), - - /* private: internal use only */ - HID_BPF_FLAG_MAX, -}; - -/* 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); - /* * Below is HID internal */ =20 -/* internal function to call eBPF programs, not to be used by anybody */ -int __hid_bpf_tail_call(struct hid_bpf_ctx *ctx); - #define HID_BPF_MAX_PROGS_PER_DEV 64 #define HID_BPF_FLAG_MASK (((HID_BPF_FLAG_MAX - 1) << 1) - 1) =20 -/* types of HID programs to attach to */ -enum hid_bpf_prog_type { - HID_BPF_PROG_TYPE_UNDEF =3D -1, - HID_BPF_PROG_TYPE_DEVICE_EVENT, /* an event is emitted from the device = */ - HID_BPF_PROG_TYPE_RDESC_FIXUP, - HID_BPF_PROG_TYPE_MAX, -}; =20 struct hid_report_enum; =20 @@ -167,11 +130,6 @@ struct hid_bpf_ops { struct hid_device *hdev; }; =20 -struct hid_bpf_prog_list { - u16 prog_idx[HID_BPF_MAX_PROGS_PER_DEV]; - u8 prog_cnt; -}; - /* stored in each device */ struct hid_bpf { u8 *device_data; /* allocated when a bpf program of type @@ -179,23 +137,13 @@ struct hid_bpf { * to this HID device */ u32 allocated_data; - - struct hid_bpf_prog_list __rcu *progs[HID_BPF_PROG_TYPE_MAX]; /* attached= BPF progs */ bool destroyed; /* prevents the assignment of any progs */ =20 - spinlock_t progs_lock; /* protects RCU update of progs */ - struct hid_bpf_ops *rdesc_ops; struct list_head prog_list; struct mutex prog_list_lock; /* protects prog_list update */ }; =20 -/* specific HID-BPF link when a program is attached to a device */ -struct hid_bpf_link { - struct bpf_link link; - int hid_table_index; -}; - #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); --=20 2.44.0 From nobody Fri Dec 19 21:10:08 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4FAC217BB05; Sat, 8 Jun 2024 09:01:42 +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=1717837303; cv=none; b=ZY05vts3tQOu8c4+/VrNmH6O/5ibTB5cjgGtKrapFhqpwxm+vQGhS/9wZYcJiJh9sPYaTAoqAnou9+D9/FJl1HHZPCATtpFvFGAbNRP1eU22VcRTmuhQUIHOu9hWxp9aYFSBrwjmEMO/sAP7RMO38S5oNzih+bLeiEw6u8uVbmw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717837303; c=relaxed/simple; bh=XOXbeH+nudNU+hzpnIdjEwnDufgfsVsre+2aXUI0WiI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=J3uejYcjZQTQxbzx/8S2kr01jtUul4cIoO2Jo74kfcqcNkxfiF03K+oZ7Z8/4hf2PBXZ6d+YjwxFIkyNDVPsn6lu9E9S5hbvcirsmC7pEKE9wz+PoVPufbExlJoPWkLlBv4rRMSGZKesCzz3NF1AxIh/QIuHeuc45xD3apmfFgY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=M8s2XKvl; 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="M8s2XKvl" Received: by smtp.kernel.org (Postfix) with ESMTPSA id F015FC4AF07; Sat, 8 Jun 2024 09:01:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1717837302; bh=XOXbeH+nudNU+hzpnIdjEwnDufgfsVsre+2aXUI0WiI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=M8s2XKvl1n2PjYS1RK31aB7WdFa+45SkLKeStgEp3AEMjWiFlt1LdIGjDXDc0cYcs yFa6mnvLh9wMQ4KH2I3i5aohg46rZFzNxrxPXH3f2NnP4IJquCX0IsU1cHBZveRrJF DDUVS4ER2g9itpSuInNVQwtl8guc6bwXXvAXYOflTodqOe27UoEdyVpXDEpFLlnxlN LvNpY22Y+o1S1DhMWoIq59i5yApEe6eD2rdNxc76rnM4zE3crLzZ8Ww70uP7ynvDMs 7OWrkd20ZwJfsaHidbVHVIPZRw2fGRaUWA9C3wljkudwqHZM1NgczeOoxIc6C15RRn w0YWn3WaDbdew== From: Benjamin Tissoires Date: Sat, 08 Jun 2024 11:01:21 +0200 Subject: [PATCH HID v3 09/16] selftests/hid: add subprog call test Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240608-hid_bpf_struct_ops-v3-9-6ac6ade58329@kernel.org> References: <20240608-hid_bpf_struct_ops-v3-0-6ac6ade58329@kernel.org> In-Reply-To: <20240608-hid_bpf_struct_ops-v3-0-6ac6ade58329@kernel.org> To: Shuah Khan , Jiri Kosina , Jonathan Corbet , Alexei Starovoitov Cc: linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, linux-input@vger.kernel.org, linux-doc@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1717837279; l=2921; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=XOXbeH+nudNU+hzpnIdjEwnDufgfsVsre+2aXUI0WiI=; b=V31y0/GjRpPqF7HgJGM9p1Cw2elgDz5SrQlv1dbiy75zzpTo1Q+9z08Uoaky6BVAPJlWmwXYl 35QpCTtQSGrCBwbN/2lVB1n/lexh0RunBG/WEwAd65OraaEodIMM+89 X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= I got a weird verifier error with a subprog once, so let's have a test for it. Signed-off-by: Benjamin Tissoires --- no changes in v3 no changes in v2 --- tools/testing/selftests/hid/hid_bpf.c | 41 +++++++++++++++++++++++++++++= ++++ tools/testing/selftests/hid/progs/hid.c | 24 +++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/tools/testing/selftests/hid/hid_bpf.c b/tools/testing/selftest= s/hid/hid_bpf.c index 967dfe6b58cb..45e173db35bd 100644 --- a/tools/testing/selftests/hid/hid_bpf.c +++ b/tools/testing/selftests/hid/hid_bpf.c @@ -638,6 +638,47 @@ TEST_F(hid_bpf, raw_event) ASSERT_EQ(buf[2], 52); } =20 +/* + * Attach hid_first_event to the given uhid device, + * retrieve and open the matching hidraw node, + * inject one event in the uhid device, + * check that the program sees it and can change the data + */ +TEST_F(hid_bpf, subprog_raw_event) +{ + const struct test_program progs[] =3D { + { .name =3D "hid_subprog_first_event" }, + }; + __u8 buf[10] =3D {0}; + int err; + + LOAD_PROGRAMS(progs); + + /* inject one event */ + buf[0] =3D 1; + buf[1] =3D 42; + uhid_send_event(_metadata, self->uhid_fd, buf, 6); + + /* read the data from hidraw */ + memset(buf, 0, sizeof(buf)); + err =3D read(self->hidraw_fd, buf, sizeof(buf)); + ASSERT_EQ(err, 6) TH_LOG("read_hidraw"); + ASSERT_EQ(buf[0], 1); + ASSERT_EQ(buf[2], 47); + + /* inject another event */ + memset(buf, 0, sizeof(buf)); + buf[0] =3D 1; + buf[1] =3D 47; + uhid_send_event(_metadata, self->uhid_fd, buf, 6); + + /* read the data from hidraw */ + memset(buf, 0, sizeof(buf)); + err =3D read(self->hidraw_fd, buf, sizeof(buf)); + ASSERT_EQ(err, 6) TH_LOG("read_hidraw"); + ASSERT_EQ(buf[2], 52); +} + /* * Ensures that we can attach/detach programs */ diff --git a/tools/testing/selftests/hid/progs/hid.c b/tools/testing/selfte= sts/hid/progs/hid.c index 614f1aa32649..2e7e5a736dc6 100644 --- a/tools/testing/selftests/hid/progs/hid.c +++ b/tools/testing/selftests/hid/progs/hid.c @@ -35,6 +35,30 @@ struct hid_bpf_ops first_event =3D { .hid_id =3D 2, }; =20 +int __hid_subprog_first_event(struct hid_bpf_ctx *hid_ctx, enum hid_report= _type type) +{ + __u8 *rw_data =3D hid_bpf_get_data(hid_ctx, 0 /* offset */, 3 /* size */); + + if (!rw_data) + return 0; /* EPERM check */ + + rw_data[2] =3D rw_data[1] + 5; + + return hid_ctx->size; +} + +SEC("?struct_ops/hid_device_event") +int BPF_PROG(hid_subprog_first_event, struct hid_bpf_ctx *hid_ctx, enum hi= d_report_type type) +{ + return __hid_subprog_first_event(hid_ctx, type); +} + +SEC(".struct_ops.link") +struct hid_bpf_ops subprog_first_event =3D { + .hid_device_event =3D (void *)hid_subprog_first_event, + .hid_id =3D 2, +}; + SEC("?struct_ops/hid_device_event") int BPF_PROG(hid_second_event, struct hid_bpf_ctx *hid_ctx, enum hid_repor= t_type type) { --=20 2.44.0 From nobody Fri Dec 19 21:10:08 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4463317BB34; Sat, 8 Jun 2024 09:01:45 +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=1717837305; cv=none; b=KbTOiexJO2EPkwrm8vf40lgJI0T3pOnZPd0B299bbS80I3ZCopQwVI7g+fioiZRt736YNKaMaR8M9KzYFUeQvRF5jnHSaZxhFF6EAhIuyGZkoyhF5JTrcJQjmkEoq4VwrOtD6CuNIhAxi9bMIsu/fLvtY2rFqoUj0pcEhQ/Fq44= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717837305; c=relaxed/simple; bh=eZ1eFdEJgFaYwtLAK7/bdxQ0IOGe6mOo0E9HoKOIq/k=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=B9COtF4ZcQi+9NAGuPTdw/0ankI7SCbtF7wNy7HXsdTfrTkmsKa4YlCKsqmFzmrRmMt+FSbGTYqcrDgEfYhNgfKwaudynFIXCUAzVwWtQdyZp32HSeITuc6mquOFrmT8EARONcthjaz7w2MfZmxl/8sah0MHp04h8iiX4KsJ1jg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=VgBJxvZ+; 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="VgBJxvZ+" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3E70EC2BD11; Sat, 8 Jun 2024 09:01:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1717837305; bh=eZ1eFdEJgFaYwtLAK7/bdxQ0IOGe6mOo0E9HoKOIq/k=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=VgBJxvZ+zdTxlX12oIGMV/42ei564B7SuaVEysWXj7C6u5Mw3AacGxle/K+/ytbAu E2Dx5H1j0s15/tF/4Btu0IUg+rb4/Pfp565j3w2fcqIj6UH4VIfYN07vLUsy8F2UGS b/iIJRkE1ZHKgS0eJUs8xR6peQYCmaCJBzTZ93D/Di5qJLahxS6uIliGzWTTmbYYhw Wpi1imphefJliUMLmoO490twC6oeMzwb3tcDwKordRtJvGvdvNOeAnIR+eOq9oABY1 EBzh5xBSeXclRdqWDQYm12r3J8RB+q9HNLSlHjvAGWznE/NaissnE1lLBL76I5SCcZ 8MebHNAalDxAQ== From: Benjamin Tissoires Date: Sat, 08 Jun 2024 11:01:22 +0200 Subject: [PATCH HID v3 10/16] Documentation: HID: amend HID-BPF for struct_ops Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240608-hid_bpf_struct_ops-v3-10-6ac6ade58329@kernel.org> References: <20240608-hid_bpf_struct_ops-v3-0-6ac6ade58329@kernel.org> In-Reply-To: <20240608-hid_bpf_struct_ops-v3-0-6ac6ade58329@kernel.org> To: Shuah Khan , Jiri Kosina , Jonathan Corbet , Alexei Starovoitov Cc: linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, linux-input@vger.kernel.org, linux-doc@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1717837279; l=14094; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=eZ1eFdEJgFaYwtLAK7/bdxQ0IOGe6mOo0E9HoKOIq/k=; b=x/NDJdE91lVksRleB4Sxn58ApoJSdUi609M6Ha+3PSNUv4wlyGflyrx4z7r9H0zljn9mrRkUA h16qiLGA4WwA2Vz6StrqULfqxCDFYk4JTFMpDkfoKGYDAlnUAW9T6KE X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= Now that we are using struct_ops, the docs need to be changed. Signed-off-by: Benjamin Tissoires --- no changes in v3 changes in v2 - use BPF_F_BEFORE --- Documentation/hid/hid-bpf.rst | 156 +++++++++++++++++++-------------------= ---- include/linux/hid_bpf.h | 8 +-- 2 files changed, 76 insertions(+), 88 deletions(-) diff --git a/Documentation/hid/hid-bpf.rst b/Documentation/hid/hid-bpf.rst index 0765b3298ecf..456e15097d87 100644 --- a/Documentation/hid/hid-bpf.rst +++ b/Documentation/hid/hid-bpf.rst @@ -132,16 +132,17 @@ input events. Available types of programs =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D =20 -HID-BPF is built "on top" of BPF, meaning that we use tracing method to +HID-BPF is built "on top" of BPF, meaning that we use bpf struct_ops metho= d to declare our programs. =20 HID-BPF has the following attachment types available: =20 -1. event processing/filtering with ``SEC("fmod_ret/hid_bpf_device_event")`= ` in libbpf +1. event processing/filtering with ``SEC("struct_ops/hid_device_event")`` = in libbpf 2. actions coming from userspace with ``SEC("syscall")`` in libbpf -3. change of the report descriptor with ``SEC("fmod_ret/hid_bpf_rdesc_fixu= p")`` in libbpf +3. change of the report descriptor with ``SEC("struct_ops/hid_rdesc_fixup"= )`` or + ``SEC("struct_ops.s/hid_rdesc_fixup")`` in libbpf =20 -A ``hid_bpf_device_event`` is calling a BPF program when an event is recei= ved from +A ``hid_device_event`` is calling a BPF program when an event is received = from the device. Thus we are in IRQ context and can act on the data or notify u= serspace. And given that we are in IRQ context, we can not talk back to the device. =20 @@ -149,37 +150,42 @@ A ``syscall`` means that userspace called the syscall= ``BPF_PROG_RUN`` facility. This time, we can do any operations allowed by HID-BPF, and talking to the= device is allowed. =20 -Last, ``hid_bpf_rdesc_fixup`` is different from the others as there can be= only one +Last, ``hid_rdesc_fixup`` is different from the others as there can be onl= y one BPF program of this type. This is called on ``probe`` from the driver and = allows to -change the report descriptor from the BPF program. Once a ``hid_bpf_rdesc_= fixup`` +change the report descriptor from the BPF program. Once a ``hid_rdesc_fixu= p`` program has been loaded, it is not possible to overwrite it unless the pro= gram which inserted it allows us by pinning the program and closing all of its fds po= inting to it. =20 +Note that ``hid_rdesc_fixup`` can be declared as sleepable (``SEC("struct_= ops.s/hid_rdesc_fixup")``). + + Developer API: =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 -User API data structures available in programs: ------------------------------------------------ +Available ``struct_ops`` for HID-BPF: +------------------------------------- =20 .. kernel-doc:: include/linux/hid_bpf.h + :identifiers: hid_bpf_ops =20 -Available tracing functions to attach a HID-BPF program: --------------------------------------------------------- =20 -.. kernel-doc:: drivers/hid/bpf/hid_bpf_dispatch.c - :functions: hid_bpf_device_event hid_bpf_rdesc_fixup +User API data structures available in programs: +----------------------------------------------- + +.. kernel-doc:: include/linux/hid_bpf.h + :identifiers: hid_bpf_ctx =20 -Available API that can be used in all HID-BPF programs: -------------------------------------------------------- +Available API that can be used in all HID-BPF struct_ops programs: +------------------------------------------------------------------ =20 .. kernel-doc:: drivers/hid/bpf/hid_bpf_dispatch.c - :functions: hid_bpf_get_data + :identifiers: hid_bpf_get_data =20 -Available API that can be used in syscall HID-BPF programs: ------------------------------------------------------------ +Available API that can be used in syscall HID-BPF programs or in sleepable= HID-BPF struct_ops programs: +--------------------------------------------------------------------------= ----------------------------- =20 .. kernel-doc:: drivers/hid/bpf/hid_bpf_dispatch.c - :functions: hid_bpf_attach_prog hid_bpf_hw_request hid_bpf_hw_output_re= port hid_bpf_input_report hid_bpf_allocate_context hid_bpf_release_context + :identifiers: hid_bpf_hw_request hid_bpf_hw_output_report hid_bpf_input= _report hid_bpf_allocate_context hid_bpf_release_context =20 General overview of a HID-BPF program =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D @@ -222,20 +228,21 @@ This allows the following: Effect of a HID-BPF program --------------------------- =20 -For all HID-BPF attachment types except for :c:func:`hid_bpf_rdesc_fixup`,= several eBPF -programs can be attached to the same device. +For all HID-BPF attachment types except for :c:func:`hid_rdesc_fixup`, sev= eral eBPF +programs can be attached to the same device. If a HID-BPF struct_ops has a +:c:func:`hid_rdesc_fixup` while another is already attached to the device,= the +kernel will return `-EINVAL` when attaching the struct_ops. =20 -Unless ``HID_BPF_FLAG_INSERT_HEAD`` is added to the flags while attaching = the -program, the new program is appended at the end of the list. -``HID_BPF_FLAG_INSERT_HEAD`` will insert the new program at the beginning = of the -list which is useful for e.g. tracing where we need to get the unprocessed= events -from the device. +Unless ``BPF_F_BEFORE`` is added to the flags while attaching the program,= the new +program is appended at the end of the list. +``BPF_F_BEFORE`` will insert the new program at the beginning of the list = which is +useful for e.g. tracing where we need to get the unprocessed events from t= he device. =20 -Note that if there are multiple programs using the ``HID_BPF_FLAG_INSERT_H= EAD`` flag, +Note that if there are multiple programs using the ``BPF_F_BEFORE`` flag, only the most recently loaded one is actually the first in the list. =20 -``SEC("fmod_ret/hid_bpf_device_event")`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``SEC("struct_ops/hid_device_event")`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ =20 Whenever a matching event is raised, the eBPF programs are called one afte= r the other and are working on the same data buffer. @@ -258,17 +265,17 @@ with, userspace needs to refer to the device by its u= nique system id (the last 4 in the sysfs path: ``/sys/bus/hid/devices/xxxx:yyyy:zzzz:0000``). =20 To retrieve a context associated with the device, the program must call -:c:func:`hid_bpf_allocate_context` and must release it with :c:func:`hid_b= pf_release_context` +hid_bpf_allocate_context() and must release it with hid_bpf_release_contex= t() before returning. Once the context is retrieved, one can also request a pointer to kernel me= mory with -:c:func:`hid_bpf_get_data`. This memory is big enough to support all input= /output/feature +hid_bpf_get_data(). This memory is big enough to support all input/output/= feature reports of the given device. =20 -``SEC("fmod_ret/hid_bpf_rdesc_fixup")`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``SEC("struct_ops/hid_rdesc_fixup")`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ =20 -The ``hid_bpf_rdesc_fixup`` program works in a similar manner to -``.report_fixup`` of ``struct hid_driver``. +The ``hid_rdesc_fixup`` program works in a similar manner to ``.report_fix= up`` +of ``struct hid_driver``. =20 When the device is probed, the kernel sets the data buffer of the context = with the content of the report descriptor. The memory associated with that buffer is @@ -277,33 +284,31 @@ content of the report descriptor. The memory associat= ed with that buffer is The eBPF program can modify the data buffer at-will and the kernel uses the modified content and size as the report descriptor. =20 -Whenever a ``SEC("fmod_ret/hid_bpf_rdesc_fixup")`` program is attached (if= no -program was attached before), the kernel immediately disconnects the HID d= evice -and does a reprobe. +Whenever a struct_ops containing a ``SEC("struct_ops/hid_rdesc_fixup")`` p= rogram +is attached (if no program was attached before), the kernel immediately di= sconnects +the HID device and does a reprobe. =20 -In the same way, when the ``SEC("fmod_ret/hid_bpf_rdesc_fixup")`` program = is -detached, the kernel issues a disconnect on the device. +In the same way, when this struct_ops is detached, the kernel issues a dis= connect +on the device. =20 There is no ``detach`` facility in HID-BPF. Detaching a program happens wh= en -all the user space file descriptors pointing at a program are closed. +all the user space file descriptors pointing at a HID-BPF struct_ops link = are closed. Thus, if we need to replace a report descriptor fixup, some cooperation is required from the owner of the original report descriptor fixup. -The previous owner will likely pin the program in the bpffs, and we can th= en +The previous owner will likely pin the struct_ops link in the bpffs, and w= e can then replace it through normal bpf operations. =20 Attaching a bpf program to a device =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 -``libbpf`` does not export any helper to attach a HID-BPF program. -Users need to use a dedicated ``syscall`` program which will call -``hid_bpf_attach_prog(hid_id, program_fd, flags)``. +We now use standard struct_ops attachment through ``bpf_map__attach_struct= _ops()``. +But given that we need to attach a struct_ops to a dedicated HID device, t= he caller +must set ``hid_id`` in the struct_ops map before loading the program in th= e kernel. =20 ``hid_id`` is the unique system ID of the HID device (the last 4 numbers i= n the sysfs path: ``/sys/bus/hid/devices/xxxx:yyyy:zzzz:0000``) =20 -``progam_fd`` is the opened file descriptor of the program to attach. - -``flags`` is of type ``enum hid_bpf_attach_flags``. +One can also set ``flags``, which is of type ``enum hid_bpf_attach_flags``. =20 We can not rely on hidraw to bind a BPF program to a HID device. hidraw is= an artefact of the processing of the HID device, and is not stable. Some driv= ers @@ -358,32 +363,15 @@ For that, we can create a basic skeleton for our BPF = program:: 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 fla= gs) __ksym; =20 struct { __uint(type, BPF_MAP_TYPE_RINGBUF); __uint(max_entries, 4096 * 64); } ringbuf SEC(".maps"); =20 - struct attach_prog_args { - int prog_fd; - unsigned int hid; - unsigned int flags; - int retval; - }; - - SEC("syscall") - int attach_prog(struct attach_prog_args *ctx) - { - ctx->retval =3D hid_bpf_attach_prog(ctx->hid, - ctx->prog_fd, - ctx->flags); - return 0; - } - __u8 current_value =3D 0; =20 - SEC("?fmod_ret/hid_bpf_device_event") + SEC("struct_ops/hid_device_event") int BPF_PROG(filter_switch, struct hid_bpf_ctx *hid_ctx) { __u8 *data =3D hid_bpf_get_data(hid_ctx, 0 /* offset */, 192 /* size */); @@ -407,37 +395,37 @@ For that, we can create a basic skeleton for our BPF = program:: return 0; } =20 -To attach ``filter_switch``, userspace needs to call the ``attach_prog`` s= yscall -program first:: + SEC(".struct_ops.link") + struct hid_bpf_ops haptic_tablet =3D { + .hid_device_event =3D (void *)filter_switch, + }; + + +To attach ``haptic_tablet``, userspace needs to set ``hid_id`` first:: =20 static int attach_filter(struct hid *hid_skel, int hid_id) { - int err, prog_fd; - int ret =3D -1; - struct attach_prog_args args =3D { - .hid =3D hid_id, - }; - DECLARE_LIBBPF_OPTS(bpf_test_run_opts, tattrs, - .ctx_in =3D &args, - .ctx_size_in =3D sizeof(args), - ); + int err, link_fd; =20 - args.prog_fd =3D bpf_program__fd(hid_skel->progs.filter_switch); + hid_skel->struct_ops.haptic_tablet->hid_id =3D hid_id; + err =3D hid__load(skel); + if (err) + return err; =20 - prog_fd =3D bpf_program__fd(hid_skel->progs.attach_prog); - - err =3D bpf_prog_test_run_opts(prog_fd, &tattrs); - if (err) - return err; + link_fd =3D bpf_map__attach_struct_ops(hid_skel->maps.haptic_tablet); + if (!link_fd) { + fprintf(stderr, "can not attach HID-BPF program: %m\n"); + return -1; + } =20 - return args.retval; /* the fd of the created bpf_link */ + return link_fd; /* the fd of the created bpf_link */ } =20 Our userspace program can now listen to notifications on the ring buffer, = and is awaken only when the value changes. =20 When the userspace program doesn't need to listen to events anymore, it ca= n just -close the returned fd from :c:func:`attach_filter`, which will tell the ke= rnel to +close the returned bpf link from :c:func:`attach_filter`, which will tell = the kernel to detach the program from the HID device. =20 Of course, in other use cases, the userspace program can also pin the fd t= o the diff --git a/include/linux/hid_bpf.h b/include/linux/hid_bpf.h index 447b94aa99ab..1b4cc1b2c31d 100644 --- a/include/linux/hid_bpf.h +++ b/include/linux/hid_bpf.h @@ -20,11 +20,9 @@ struct hid_device; * struct hid_bpf_ctx - User accessible data for all HID programs * * ``data`` is not directly accessible from the context. We need to issue - * a call to ``hid_bpf_get_data()`` in order to get a pointer to that fiel= d. + * a call to hid_bpf_get_data() in order to get a pointer to that field. * - * All of these fields are currently read-only. - * - * @hid: the ``struct hid_device`` representing the device itself + * @hid: the &struct hid_device representing the device itself * @allocated_size: Allocated size of data. * * This is how much memory is available and can be reques= ted @@ -41,6 +39,8 @@ struct hid_device; * ``size`` must always be less or equal than ``allocated_size`` (i= t is enforced * once all BPF programs have been run). * @retval: Return value of the previous program. + * + * ``hid`` and ``allocated_size`` are read-only, ``size`` and ``retval`` a= re read-write. */ struct hid_bpf_ctx { const struct hid_device *hid; --=20 2.44.0 From nobody Fri Dec 19 21:10:08 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8420817C21A; Sat, 8 Jun 2024 09:01:47 +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=1717837307; cv=none; b=ov3KX/n54SWcleMV9vVAXv5U11AJz6eP2e/XWH5d+276I2OmeUzunwwTQ69z9sjp8uF5dv7nWJFUAltwn/Eijhihr6TXGIxQvOvnjKYtcVvCvHLst+BmxwXITbSb0c9ZxIRKuRovx+GI+65HMl+4kpQFQTw6ylinnen/d8WJcFU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717837307; c=relaxed/simple; bh=Q+Ac2u6IrcunkGq5of0uabcj090YkndfqLEDRr9KTMo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=j8LJ+g8g+RwYd0X5zxvhNW2s1/cV+sV/87xxESifBerbD1Roc5hdPJocrTcggvmCz4qpMhKG2VDaLWY6OaLmaeXWRTrBNExzZBybhs1UGAPbHp/y18DwJeIJFWQgfBYjPgaaj+fomz6034msvVKtJLO6YZNoPcj2sy+7lxX7Fsw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=jI76BG4i; 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="jI76BG4i" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8BE19C3277B; Sat, 8 Jun 2024 09:01:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1717837307; bh=Q+Ac2u6IrcunkGq5of0uabcj090YkndfqLEDRr9KTMo=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=jI76BG4i9uihwm6M7RArAtpS01nQRRfReaJpgG3qp9dXEEFrn3XSuogpEJI2kSe9Q H0bV/0uTW54gDQN7XMQSJ4sTch+kQWww4nBkTHu12HQsP2zwvCE7R7Q2ahaXXFZDTp HNdWZkoGvps+GyZIcGesn3f8ZkjP6fQYM/e1LAta2x8AcxkhmQ6Ld/jBlZF9j00y1s oxoDTxtsVrQHkClynPy/sOtdbKwGqNSWf0FzXKkikWbtX+2V5tm5mTBElwYC3oRr/l MmeV5Pn6iuqFIdpBoPA2xJAN21kqJTYMdh+CcZKNCq9QLM5T8+ZpOAZCsoOsH+cpsL EXr5CsmCrZGdg== From: Benjamin Tissoires Date: Sat, 08 Jun 2024 11:01:23 +0200 Subject: [PATCH HID v3 11/16] Documentation: HID: add a small blurb on udev-hid-bpf Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240608-hid_bpf_struct_ops-v3-11-6ac6ade58329@kernel.org> References: <20240608-hid_bpf_struct_ops-v3-0-6ac6ade58329@kernel.org> In-Reply-To: <20240608-hid_bpf_struct_ops-v3-0-6ac6ade58329@kernel.org> To: Shuah Khan , Jiri Kosina , Jonathan Corbet , Alexei Starovoitov Cc: linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, linux-input@vger.kernel.org, linux-doc@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1717837279; l=1825; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=Q+Ac2u6IrcunkGq5of0uabcj090YkndfqLEDRr9KTMo=; b=+evcf//zew7WoveGul3DJER+y/2Z2upCyb/BJMaE8c2k4StDCEQUWjbiRyNCtXzV4nlXSxKf1 pm78qDv3d+yCzXPaYgMggUpyNO/p4bb851f/QsZ/qh+GGdonS3XzPip X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= This is the current decision we took: we don't provide automatic loading of HID-BPF by the kernel directly, but rely on an external tool for it. This tool is currently udev-hid-bpf, so let's make people aware of it. Signed-off-by: Benjamin Tissoires --- no changes in v3 no changes in v2 --- Documentation/hid/hid-bpf.rst | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Documentation/hid/hid-bpf.rst b/Documentation/hid/hid-bpf.rst index 456e15097d87..8ae8f49801cb 100644 --- a/Documentation/hid/hid-bpf.rst +++ b/Documentation/hid/hid-bpf.rst @@ -129,6 +129,23 @@ When a BPF program needs to emit input events, it need= s to talk with the HID protocol, and rely on the HID kernel processing to translate the HID data = into input events. =20 +In-tree HID-BPF programs and ``udev-hid-bpf`` +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +Official device fixes are shipped in the kernel tree as source in the +``drivers/hid/bpf/progs`` directory. This allows to add selftests to them = in +``tools/testing/selftests/hid``. + +However, the compilation of these objects is not part of a regular kernel = compilation +given that they need an external tool to be loaded. This tool is currently +`udev-hid-bpf `_. + +For convenience, that external repository duplicates the files from here in +``drivers/hid/bpf/progs`` into its own ``src/bpf/stable`` directory. This = allows +distributions to not have to pull the entire kernel source tree to ship an= d package +those HID-BPF fixes. ``udev-hid-bpf`` also has capabilities of handling mu= ltiple +objects files depending on the kernel the user is running. + Available types of programs =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D =20 --=20 2.44.0 From nobody Fri Dec 19 21:10:08 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4078B17C7AE; Sat, 8 Jun 2024 09:01:49 +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=1717837310; cv=none; b=tMpzryp15xPA4i0QSMYJXJeWQ9UMX1NH6kPRcxd9LJI9nfV14RPl1xK73RA0Axq6bB2T40v4MxVKFkAVCzEyg+3rB1rbrn9FTcKpgiMOtyMUbNdUX/5B/AEHDolWfkqRtXeKIvs7mPcUH5wgu07kq4jbmHOBQEDDYGZEAbce2PI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717837310; c=relaxed/simple; bh=L4CYU4n+T+6E8bgHr6bJqE2mTuITTQLAF8wrCeVIKd4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Z7DMcjB3CNaLdF7YJGkGvs/U92TNuG0bH6o9WpZJu/2JLhdw1NMon+dxh5LSJP3nTz/xu4M9AVorAPSl+8b8iJkHdoTiJCn5kzkiE6FZf22DYFWLvGt+FNLVccKzYzGlFalLzp0v5GSKh56GDNwU7aUB1Q8zPqqDO4RTw6kMnrQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hURxL6Y2; 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="hURxL6Y2" Received: by smtp.kernel.org (Postfix) with ESMTPSA id CDF3BC4AF09; Sat, 8 Jun 2024 09:01:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1717837309; bh=L4CYU4n+T+6E8bgHr6bJqE2mTuITTQLAF8wrCeVIKd4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=hURxL6Y2YzJLFkBryk39+BRq0xjbHHfoNsqDV+8gIcNMJEeQBp3h+HxdmF5sRIWWs BjPkEPX1yxcQr3puxh2p2QJQEX+F2TH/9M8MMVuYBOPxcvRiygdZyBt6YpjjqNqOxc duBmQ93OwBSKpWTl4OqSD8RvURj2GRtldNeRVeSrWqN9KqyqIa2S/13WaYY84KpGfG kfxtU6blcHFvZzYVM3tRm5JhSUGtIub6uSSRhKxKE+qkMuI7jCEKp6XYKIDqqv8V/Z 4YkC/7ZNoOHhB8HaqUn+JMTAFRI5GYke64U2VXb/gVXxGkKuueWXnCQegzX7jdyhCF LZxK5Ft2FACMw== From: Benjamin Tissoires Date: Sat, 08 Jun 2024 11:01:24 +0200 Subject: [PATCH HID v3 12/16] HID: bpf: Artist24: remove unused variable Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240608-hid_bpf_struct_ops-v3-12-6ac6ade58329@kernel.org> References: <20240608-hid_bpf_struct_ops-v3-0-6ac6ade58329@kernel.org> In-Reply-To: <20240608-hid_bpf_struct_ops-v3-0-6ac6ade58329@kernel.org> To: Shuah Khan , Jiri Kosina , Jonathan Corbet , Alexei Starovoitov Cc: linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, linux-input@vger.kernel.org, linux-doc@vger.kernel.org, Benjamin Tissoires , Peter Hutterer X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1717837279; l=845; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=L4CYU4n+T+6E8bgHr6bJqE2mTuITTQLAF8wrCeVIKd4=; b=fckHWugzyfy+gR4/x05n4t1rKyJFCApWnbtapRom03hX/4BB38MXmaqMkKdt3Akb6q0D8KpCn 3X6yLewsqT1DrDKbQtqKAiQuLErMkYyuO8LqmEEVUz0okULythft8+n X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= warning: unused variable =E2=80=98tilt=E2=80=99 [-Wunused-variable] Signed-off-by: Peter Hutterer Signed-off-by: Benjamin Tissoires --- no changes in v3 no changes in v2 --- drivers/hid/bpf/progs/XPPen__Artist24.bpf.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/hid/bpf/progs/XPPen__Artist24.bpf.c b/drivers/hid/bpf/= progs/XPPen__Artist24.bpf.c index bc0b85c38445..d4d062c3a653 100644 --- a/drivers/hid/bpf/progs/XPPen__Artist24.bpf.c +++ b/drivers/hid/bpf/progs/XPPen__Artist24.bpf.c @@ -158,7 +158,6 @@ int BPF_PROG(xppen_24_fix_eraser, struct hid_bpf_ctx *h= ctx) __u8 *data =3D hid_bpf_get_data(hctx, 0 /* offset */, 10 /* size */); __u8 current_state, changed_state; bool prev_tip; - __u16 tilt; =20 if (!data) return 0; /* EPERM check */ --=20 2.44.0 From nobody Fri Dec 19 21:10:08 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4686D17C9E7; Sat, 8 Jun 2024 09:01:52 +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=1717837312; cv=none; b=PhHNnmjdj1dxuVeodJtO7gxK26eWoJPlmvqf6wmBNkMb6v6MGYLJev7JkgjM8vf3ln/66uxLA2TZXxMd+tigvMl1eqM9bbCvPhUqXsIrzmxeqU49ouvAcfCLOTsM+U4874Qt2mVvjCdJfQE9R8uCVjPbFjjEvO0VrYYYkbnmZYc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717837312; c=relaxed/simple; bh=vy4mezYjZtrXyMz65bPN043/fx8Jb4rfGeuYveZNR50=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=d+H4gqR8EU4KyGeDv71xsGxnp/pwCZTfJ7WRhImjsfvdUfyLXBN8bEDiyUenGLaND5QtkQCMpWuoCuNKuFD+0ZEz9O/YpASM7FIhm+27UPov/R/Z/FFsL0+Ra8ndC0tao6Xf5G8MzW3CJuvC9PoRiQm++FLKzlVGpZNurJMtUa4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=shD3lBca; 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="shD3lBca" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 45F1CC4AF08; Sat, 8 Jun 2024 09:01:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1717837312; bh=vy4mezYjZtrXyMz65bPN043/fx8Jb4rfGeuYveZNR50=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=shD3lBcaP5UhqoE5qXZlKCoGjv5f5sg2Mk9aSUx7NocZGD6xG+sKDANnxFAU0IvvA fJAUonGfBakyAtIe51DEdavCWka2UQZn1KPFUSg+/coZiXW4NGCfEgw/Av3QjqiKF5 VLsJw8v7mkmqhcreySIducfjBsySf6bSzPET1E2O3l+6wf9EZyGK72sNsL1urJGx6L WfnU+qxisv49f0+rYMfuMT3eRG92hS8j5Fb5Rzq16CPUDf3I6TmOyZmuLzYv8Qdvld Mo8lRnMZyZMrhP0OlAeXSIcaCdpHlmbBRjV/houRP4qK/uHExaXZ2eK1sBz8Qq+dyy 2ZUIOxmH3SKvQ== From: Benjamin Tissoires Date: Sat, 08 Jun 2024 11:01:25 +0200 Subject: [PATCH HID v3 13/16] HID: bpf: error on warnings when compiling bpf objects Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240608-hid_bpf_struct_ops-v3-13-6ac6ade58329@kernel.org> References: <20240608-hid_bpf_struct_ops-v3-0-6ac6ade58329@kernel.org> In-Reply-To: <20240608-hid_bpf_struct_ops-v3-0-6ac6ade58329@kernel.org> To: Shuah Khan , Jiri Kosina , Jonathan Corbet , Alexei Starovoitov Cc: linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, linux-input@vger.kernel.org, linux-doc@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1717837279; l=785; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=vy4mezYjZtrXyMz65bPN043/fx8Jb4rfGeuYveZNR50=; b=Cm0xeT6L2mEWnBbNTcNf6Eg2hL1BMyLChleBIQdszevtTvtVQR/Z/dSkx4uT1I2L8TQXEur1Q mL2VetAFIfCATyvns1fvYG0G2x56sNVJfbnCXSHaPUUziQLxcaI1D91 X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= There is no real reasons to paper over warnings for such small programs. Signed-off-by: Benjamin Tissoires --- no changes in v3 no changes in v2 --- drivers/hid/bpf/progs/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/bpf/progs/Makefile b/drivers/hid/bpf/progs/Makefile index 63ed7e02adf1..ec1fc642fd63 100644 --- a/drivers/hid/bpf/progs/Makefile +++ b/drivers/hid/bpf/progs/Makefile @@ -56,7 +56,7 @@ clean: =20 %.bpf.o: %.bpf.c vmlinux.h $(BPFOBJ) | $(OUTPUT) $(call msg,BPF,$@) - $(Q)$(CLANG) -g -O2 --target=3Dbpf $(INCLUDES) \ + $(Q)$(CLANG) -g -O2 --target=3Dbpf -Wall -Werror $(INCLUDES) \ -c $(filter %.c,$^) -o $@ && \ $(LLVM_STRIP) -g $@ =20 --=20 2.44.0 From nobody Fri Dec 19 21:10:08 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AB13F17D353; Sat, 8 Jun 2024 09:01:54 +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=1717837314; cv=none; b=Jo2DGSNi1cxdmM7+IRLtSrFzG9hocHX8orIV2DyEyGzO4UYJSFPUgluHO5LV7FQH1OyuLl+Q1PKAAp14vuI5JBltQvzX5Zf2I8KpzFJ2XkNoXfRQKdvfE47Ism1xeJ4IC8miGqCXg7qkhY4lpHjp1G3EyQwjX9a890bh434OFfs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717837314; c=relaxed/simple; bh=764BpJJ+0RLPa1xYfm3CFomwnOdKd7B+O2p4oCLJSr4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=PNjrK7rPlL+LXSj35k3496AdKgKvw0xXm1oHalgeGScGL13EkphGFXFX9DfdPvNrCuwQM7PttkhMIooSUq+d8LdX+G5Xaq/paUGfjlY4GPsbq4nqQn5H5IPvzZqN9rRbj2UQwitJXR1Yw1ECKiSWKrsjhzqtd5M+kVzmT49ONvA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hmGw4jqy; 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="hmGw4jqy" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 889A2C2BD11; Sat, 8 Jun 2024 09:01:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1717837314; bh=764BpJJ+0RLPa1xYfm3CFomwnOdKd7B+O2p4oCLJSr4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=hmGw4jqyeZX9gecOAZcpA9hmMobqBFmqa8gADRChp1F6lyxiomcPQgildieiDIeHi 79C4RbLHmTT6Jt2pfFwn2lo4hi8tzqYrnTswAd2sdpksuEurkiwRMev9axRvgUf9+W Q+uxgTSag9NQP1LmwMCnwhkOtdGY24J0xRu4Lou5OiwwfDmHML2lVRskAGYNNbeQ70 AmgjKvebEiwn89xyCAwF8Sp425/z0u4dNo1I/N07aOnhbpLpmiQlJtvTEk7VpOwN5G 5F7XXT+fUNsa/GuEveL0L6axBaDojTBhQImTCeZTczCtGNfneYLzMWc4SBG10PPo+j AWlJSoElkXMSA== From: Benjamin Tissoires Date: Sat, 08 Jun 2024 11:01:26 +0200 Subject: [PATCH HID v3 14/16] bpf: allow bpf helpers to be used into HID-BPF struct_ops Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240608-hid_bpf_struct_ops-v3-14-6ac6ade58329@kernel.org> References: <20240608-hid_bpf_struct_ops-v3-0-6ac6ade58329@kernel.org> In-Reply-To: <20240608-hid_bpf_struct_ops-v3-0-6ac6ade58329@kernel.org> To: Shuah Khan , Jiri Kosina , Jonathan Corbet , Alexei Starovoitov Cc: linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, linux-input@vger.kernel.org, linux-doc@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1717837279; l=865; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=764BpJJ+0RLPa1xYfm3CFomwnOdKd7B+O2p4oCLJSr4=; b=V0vyUFFgCONMp6lGmOJ7JyItCEU/faMXE1HkrIoGTlhdEetexQxlAgu8tl/Kg7y59HfFCltvk uvu3DakWhr+B6kteKAMVA0Q2w3qVEKoQ22jQJhXz/gsdmyhGPlybtYH X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= Without this helpers like bpf_printk() or bpf_map_update() are not available, making anything but change of bytes impossible to do. Signed-off-by: Benjamin Tissoires --- no changes in v3 new in v2 --- drivers/hid/bpf/hid_bpf_struct_ops.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hid/bpf/hid_bpf_struct_ops.c b/drivers/hid/bpf/hid_bpf= _struct_ops.c index 9192c66cde20..056d05d96962 100644 --- a/drivers/hid/bpf/hid_bpf_struct_ops.c +++ b/drivers/hid/bpf/hid_bpf_struct_ops.c @@ -89,6 +89,7 @@ static int hid_bpf_ops_btf_struct_access(struct bpf_verif= ier_log *log, } =20 static const struct bpf_verifier_ops hid_bpf_verifier_ops =3D { + .get_func_proto =3D bpf_base_func_proto, .is_valid_access =3D hid_bpf_ops_is_valid_access, .btf_struct_access =3D hid_bpf_ops_btf_struct_access, }; --=20 2.44.0 From nobody Fri Dec 19 21:10:08 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C431E14286; Sat, 8 Jun 2024 09:01:56 +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=1717837316; cv=none; b=I7F+4BVUZSqOUNkELOW8CA8c66QEIQG1SwZUEmB9AWgC+URvTsX+26tnpPctO2sQcG4frbcRBeb2tBemTdCXjdR1C7hVcMSJ4e4j9w+BurFOEEEcHZvZeTz7Euvhnu0591kDyDJeOhu8OH+yRxkrOaI1XqUBR6TVJC9j0Zld/Ww= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717837316; c=relaxed/simple; bh=HIrrmyaYgI3pACH+lmgDvM1+uBik3+a//vxGZcnQimg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=KwD7ZuhRXLqKB8qjNFGxEBUrVEGjZ6R1FV8LjSwT96zccJie7sEy7ixPebi4kjoDAGa11qlZUukZh6njxaOa2Yl4DHaS4kguWqyi6+KbXifaoY0eHcxli/3uNf9jC+RN+siHkOHRd1hVswHal3l+TqPflBEx5lsFsxg7PiLf4AQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=SxaO+UXD; 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="SxaO+UXD" Received: by smtp.kernel.org (Postfix) with ESMTPSA id CAB21C4AF07; Sat, 8 Jun 2024 09:01:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1717837316; bh=HIrrmyaYgI3pACH+lmgDvM1+uBik3+a//vxGZcnQimg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=SxaO+UXDrTYRXcNH1lKaNZcThkDz/kaDxJZlwGVL/OGtNnTfgWxmkw41XdYdf0Ebb jsuRYuQfHXY/7SALbzLZhklF0rKo5fANbNUccxh07bX2n7l8Gb1VMHRNAnlMYmQ+B6 6hJHoGepPHc5tniZuodQi7lRriIIBp7d49T0+5OS1JHcO9HEnvVZOwyTLIxEPhchFo yZhjzR4Bryqky5W4ccCH9embWD+VVjwsfiSBxQxUAb8VVjiJdcUZ1z1EGLpox7weGY AU5LM5DzhkgE8uRcp/ppmupjBEnFFe/TSkDOq9pmORc/Vh17PVkfYnPzjPK91jPdly tsHv8j2HcieeA== From: Benjamin Tissoires Date: Sat, 08 Jun 2024 11:01:27 +0200 Subject: [PATCH HID v3 15/16] HID: bpf: rework hid_bpf_ops_btf_struct_access Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240608-hid_bpf_struct_ops-v3-15-6ac6ade58329@kernel.org> References: <20240608-hid_bpf_struct_ops-v3-0-6ac6ade58329@kernel.org> In-Reply-To: <20240608-hid_bpf_struct_ops-v3-0-6ac6ade58329@kernel.org> To: Shuah Khan , Jiri Kosina , Jonathan Corbet , Alexei Starovoitov Cc: linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, linux-input@vger.kernel.org, linux-doc@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1717837279; l=4130; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=HIrrmyaYgI3pACH+lmgDvM1+uBik3+a//vxGZcnQimg=; b=NMPE52ezcZipQcLjtnuDHX9D3HBCIFlM25VOGZTCC3fbQOZriKVwUTwVgtsbFvNMZYiLKLY/U cfBz6WfyaFIBxTLOrnghBmcCiq35Y4Ftrwyln8R0yVPHiTAT9UGA1ar X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= The idea is to provide a list of stucts and their editable fields. Currently no functional changes are introduced here, we will add some more writeable fields in the next patch. Signed-off-by: Benjamin Tissoires Acked-by: Alexei Starovoitov --- changes in v3: - rewrote WRITE_RANGE macro to not deal with offset from the caller side new in v2 --- drivers/hid/bpf/hid_bpf_struct_ops.c | 91 +++++++++++++++++++++++++++-----= ---- 1 file changed, 69 insertions(+), 22 deletions(-) diff --git a/drivers/hid/bpf/hid_bpf_struct_ops.c b/drivers/hid/bpf/hid_bpf= _struct_ops.c index 056d05d96962..b14eccb121e0 100644 --- a/drivers/hid/bpf/hid_bpf_struct_ops.c +++ b/drivers/hid/bpf/hid_bpf_struct_ops.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "hid_bpf_dispatch.h" =20 @@ -52,40 +53,86 @@ static int hid_bpf_ops_check_member(const struct btf_ty= pe *t, return 0; } =20 +struct hid_bpf_offset_write_range { + const char *struct_name; + u32 struct_length; + u32 start; + u32 end; +}; + static int hid_bpf_ops_btf_struct_access(struct bpf_verifier_log *log, const struct bpf_reg_state *reg, int off, int size) { - const struct btf_type *state; - const struct btf_type *t; - s32 type_id; +#define WRITE_RANGE(_name, _field, _is_string) \ + { \ + .struct_name =3D #_name, \ + .struct_length =3D sizeof(struct _name), \ + .start =3D offsetof(struct _name, _field), \ + .end =3D offsetofend(struct _name, _field) - !!(_is_string), \ + } =20 - type_id =3D btf_find_by_name_kind(reg->btf, "hid_bpf_ctx", - BTF_KIND_STRUCT); - if (type_id < 0) - return -EINVAL; + const struct hid_bpf_offset_write_range write_ranges[] =3D { + WRITE_RANGE(hid_bpf_ctx, retval, false), + }; +#undef WRITE_RANGE + const struct btf_type *state =3D NULL; + const struct btf_type *t; + const char *cur =3D NULL; + int i; =20 t =3D btf_type_by_id(reg->btf, reg->btf_id); - state =3D btf_type_by_id(reg->btf, type_id); - if (t !=3D state) { - bpf_log(log, "only access to hid_bpf_ctx is supported\n"); - return -EACCES; - } =20 - /* out-of-bound access in hid_bpf_ctx */ - if (off + size > sizeof(struct hid_bpf_ctx)) { - bpf_log(log, "write access at off %d with size %d\n", off, size); - return -EACCES; + for (i =3D 0; i < ARRAY_SIZE(write_ranges); i++) { + const struct hid_bpf_offset_write_range *write_range =3D &write_ranges[i= ]; + s32 type_id; + + /* we already found a writeable struct, but there is a + * new one, let's break the loop. + */ + if (t =3D=3D state && write_range->struct_name !=3D cur) + break; + + /* new struct to look for */ + if (write_range->struct_name !=3D cur) { + type_id =3D btf_find_by_name_kind(reg->btf, write_range->struct_name, + BTF_KIND_STRUCT); + if (type_id < 0) + return -EINVAL; + + state =3D btf_type_by_id(reg->btf, type_id); + } + + /* this is not the struct we are looking for */ + if (t !=3D state) { + cur =3D write_range->struct_name; + continue; + } + + /* first time we see this struct, check for out of bounds */ + if (cur !=3D write_range->struct_name && + off + size > write_range->struct_length) { + bpf_log(log, "write access for struct %s at off %d with size %d\n", + write_range->struct_name, off, size); + return -EACCES; + } + + /* now check if we are in our boundaries */ + if (off >=3D write_range->start && off + size <=3D write_range->end) + return NOT_INIT; + + cur =3D write_range->struct_name; } =20 - if (off < offsetof(struct hid_bpf_ctx, retval)) { + + if (t !=3D state) + bpf_log(log, "write access to this struct is not supported\n"); + else bpf_log(log, - "write access at off %d with size %d on read-only part of hid_bpf_ctx\n= ", - off, size); - return -EACCES; - } + "write access at off %d with size %d on read-only part of %s\n", + off, size, cur); =20 - return NOT_INIT; + return -EACCES; } =20 static const struct bpf_verifier_ops hid_bpf_verifier_ops =3D { --=20 2.44.0 From nobody Fri Dec 19 21:10:08 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5D65917D8AB; Sat, 8 Jun 2024 09:01:59 +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=1717837319; cv=none; b=e1nSkO9nYdaWHDb58/xIrfcV0hmuPOLgrsJaIzeUlcRaZmIhnU0dVTAzJvFsB9yuTaATIf2amj+nc/FFGk5O2wG3QVoSJkEkrUt9ZCc9hmrmOM2xE5/Nm03xtq9c9Agl4uqRN+0chOkWL74uHMcNQ7OPtqhEZm7+CBhX5IgYBBY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717837319; c=relaxed/simple; bh=YHolCvF3jA/DQGyy5jN6lFObu+rIHNuOu9Dmy3Vod3s=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=vAWuIfFrgPMtDd82JCM4NYweVN+JMXxDNs7ImURdwFWxd/YrHTbnxEDC9VLrA+ttRytoELiXp+n0x2+KTa4WU6kF/4I5q0XSHUlMAMZQl++YeBOKiil/s1Gm18ohF4PjoZXeDuvdeJJ94p/F2t8kDTmio0gJfFe7HK7oQWVxb/s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=LnGemssx; 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="LnGemssx" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 194D5C2BD11; Sat, 8 Jun 2024 09:01:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1717837318; bh=YHolCvF3jA/DQGyy5jN6lFObu+rIHNuOu9Dmy3Vod3s=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=LnGemssx+z+2K25Xw92Vk4C+ubNIsAfaEmFEbd0Tik3oN5d5gYJMkWvjaNImlQatE R2bP64tn3V8FknJxybCEobkZbtFtgb8mOQX3v7Lkxd2iIJFemsXckHrbCq/5OtB7Yv mFBKw3tB+ImpWCwAoZVyymfKyTUIZVCz8V1HVG9CZlgYGIbXRu03A1iHlq7DzXpwRy mlohtUSJsomVheW16NDYB+NbUJl7jrRjjMljtGsYR+8D/I3k6ricVI9XwzSHUCu0TF e1MBSPZBeJcCchnXe279kZ8wGRsZHEzMWFedMEbmpQlh6vUjfGexyePkHSxRp42lGB ok7vhLH3VXtLA== From: Benjamin Tissoires Date: Sat, 08 Jun 2024 11:01:28 +0200 Subject: [PATCH HID v3 16/16] HID: bpf: make part of struct hid_device writable Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240608-hid_bpf_struct_ops-v3-16-6ac6ade58329@kernel.org> References: <20240608-hid_bpf_struct_ops-v3-0-6ac6ade58329@kernel.org> In-Reply-To: <20240608-hid_bpf_struct_ops-v3-0-6ac6ade58329@kernel.org> To: Shuah Khan , Jiri Kosina , Jonathan Corbet , Alexei Starovoitov Cc: linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, linux-input@vger.kernel.org, linux-doc@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1717837279; l=1694; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=YHolCvF3jA/DQGyy5jN6lFObu+rIHNuOu9Dmy3Vod3s=; b=CdyFQFSOvnA/Vvz1fzchBiZjuEjZvhWbXkEF/tt9wXTyR9zjNA+HozZMMQG0RO/2vF20g01sT n5qq7W2nfvgAHvK0GUkqigT7+e1KxJDjF0kSVu9OT9JFxIZKpXZ7bCL X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= It is useful to change the name, the phys and/or the uniq of a struct hid_device during .rdesc_fixup(). For example, hid-uclogic.ko changes the uniq to store the firmware version to differentiate between 2 devices sharing the same PID. In the same way, changing the device name is useful when the device export 3 nodes, all with the same name. Signed-off-by: Benjamin Tissoires --- changes in v3: - amend for new WRITE_RANGE API new in v2 --- drivers/hid/bpf/hid_bpf_struct_ops.c | 3 +++ include/linux/hid_bpf.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/hid/bpf/hid_bpf_struct_ops.c b/drivers/hid/bpf/hid_bpf= _struct_ops.c index b14eccb121e0..e28cca78e1f5 100644 --- a/drivers/hid/bpf/hid_bpf_struct_ops.c +++ b/drivers/hid/bpf/hid_bpf_struct_ops.c @@ -74,6 +74,9 @@ static int hid_bpf_ops_btf_struct_access(struct bpf_verif= ier_log *log, =20 const struct hid_bpf_offset_write_range write_ranges[] =3D { WRITE_RANGE(hid_bpf_ctx, retval, false), + WRITE_RANGE(hid_device, name, true), + WRITE_RANGE(hid_device, uniq, true), + WRITE_RANGE(hid_device, phys, true), }; #undef WRITE_RANGE const struct btf_type *state =3D NULL; diff --git a/include/linux/hid_bpf.h b/include/linux/hid_bpf.h index 1b4cc1b2c31d..65d7e0acc8c2 100644 --- a/include/linux/hid_bpf.h +++ b/include/linux/hid_bpf.h @@ -43,7 +43,7 @@ struct hid_device; * ``hid`` and ``allocated_size`` are read-only, ``size`` and ``retval`` a= re read-write. */ struct hid_bpf_ctx { - const struct hid_device *hid; + struct hid_device *hid; __u32 allocated_size; union { __s32 retval; --=20 2.44.0