From nobody Fri Dec 19 21:10:09 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 A657A16F26D; Tue, 28 May 2024 13:15:18 +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=1716902118; cv=none; b=RenYQa4+hsoBP2yNSD8yF1rJbG3e1op744DuiHeezQO/IYkn0F+IH2EFaDQCFooaQdhIoy0+7jq1RBFwWfM1EiSZx50uRpJf397pSdvDM34PUbWsySaoZ0thnBgAB2AdXiLYQnhLu9ngwb6hh1aH3wFsNn8ntOwuo0D+af7qIQ0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716902118; c=relaxed/simple; bh=qjh548Ed99ribfGzmhee9KtCOpFpgKgwNHDsKsVMZ2E=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=oBeoZzDaA5wwdnXGAQSE475q8MGd1zwurC5ZIzurh450IP873O7tPgr0a6azVsXEOJvTu32JR3RAGXW3c2fCRt9Y2E88H+CEqTyciz7zV0gn3dLwciRHPgbjnJGOkmdsqtr2ugSfAoEB5E/7YMNehKSL5AXbNBQtI4J8xJOq6O4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=pQpQptQv; 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="pQpQptQv" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9DE53C32782; Tue, 28 May 2024 13:15:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1716902118; bh=qjh548Ed99ribfGzmhee9KtCOpFpgKgwNHDsKsVMZ2E=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=pQpQptQv9MrWTl3Z8WwqNILsEgxJXmuPYP7wvRCN0nx8QKRJ+nbkZfrkOFjM3fsuL WkAlzU/pHAKBNCUNLzr7XBqVPckrpg/+gd4mEyhTfRxgrto1ArhxRCBJSMbad1wRSH TaTE0fR5dI82DDvJzhBkCtWaSxLfhbmjeWucEBG0uQmNROBCbqeP29bgOI8YyjOBZn hpTlZ21X91/l9N/GXHNpfxbqBqB8R69bkEVrzMQBskMB3Q0ztg84vnaol33Fl7BWnA 7FWTD5/XuRGX8Fln/SJoR1eA9N7sOV++yMR+QIsS7gh24y9Li6GparAGlyCJOHNtB4 lyispOTTlhSyg== From: Benjamin Tissoires Date: Tue, 28 May 2024 15:14:39 +0200 Subject: [PATCH HID 01/13] 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: <20240528-hid_bpf_struct_ops-v1-1-8c6663df27d8@kernel.org> References: <20240528-hid_bpf_struct_ops-v1-0-8c6663df27d8@kernel.org> In-Reply-To: <20240528-hid_bpf_struct_ops-v1-0-8c6663df27d8@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=1716902113; l=4905; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=qjh548Ed99ribfGzmhee9KtCOpFpgKgwNHDsKsVMZ2E=; b=Oo/12hPcmAyPOG2YIYuV5Ne6Mk1J/N4KezsSZ9g/H1gkEepx7MOydLSfCa4Q1RWBuj7FZuluM VcaoejiYtzjAqiwDT1RPPYaou5X5eQP4UApnDYpnjNdP0DClXkUH5jI 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 --- 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:09 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 4239016F29D; Tue, 28 May 2024 13:15:20 +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=1716902121; cv=none; b=ZmXFTPJDiv0mkO7ds7L0fSBqTLohtQ8Mpl7woZVkgdCc1FlaomWxkBsx8xUjTLPvGGC+j5cDFGbW5o7oHwBr8/qmZzYT4vIB/zkR3JrMxff4OH3+5L8Nub/ClY0pwMIMnrE73KWTIrrcw7eqmI1n/21Lc8Gcr1kFBmznn6eZEJI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716902121; c=relaxed/simple; bh=k80jRINwHvZ+mA1/CvTlz56wthVn4z/bRY+1lsX1KzU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=uyKsAVNilRuIERNs99VmguRpPIqyRd71jYkVHnY4JO3Bi8x61ngK+5ZooxABymYy5lvbobUnrpExIldEeZ0n0BXDHln51NUjDkik146qzHzz/OWaesUQRog8DuCGAOzYiMp9MWfIUlX9cecoL82Q5jh+o8LjwmqCLJp/TbUA9dw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=V8NUf+Zs; 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="V8NUf+Zs" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E88C3C3277B; Tue, 28 May 2024 13:15:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1716902120; bh=k80jRINwHvZ+mA1/CvTlz56wthVn4z/bRY+1lsX1KzU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=V8NUf+Zsi674sw6wYZL9QuUQf+E7UyMjXl3DcAS6jna6nOfMGU+soB5ZERHM7EecA wAidV2q5Ukf/2aNATUIxA3+yaDZFSbEdHupnyHl6lxjmmP78roVvO/wiijCaXpJjpj BDW5RejcYZY/QDN2cCLorjUZ34d/bVaJN52hp9WCadzEj4srAaIB6/WVEUmqWmQXfH QHGayUj/+osSIKt6J33AklHCBuSaNDqPnVMiqQhmQor1peFTg3HfWO90JhYPCohu4a wXVLTR+eT3rwY1C29S9Ey9NPUn46KMU2T/XY5IyV6dzePOomNcECTmEnzrJi7I2cAn bR2XoifIsWYng== From: Benjamin Tissoires Date: Tue, 28 May 2024 15:14:40 +0200 Subject: [PATCH HID 02/13] 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: <20240528-hid_bpf_struct_ops-v1-2-8c6663df27d8@kernel.org> References: <20240528-hid_bpf_struct_ops-v1-0-8c6663df27d8@kernel.org> In-Reply-To: <20240528-hid_bpf_struct_ops-v1-0-8c6663df27d8@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=1716902113; l=2695; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=k80jRINwHvZ+mA1/CvTlz56wthVn4z/bRY+1lsX1KzU=; b=90be5r6MEoEoF60gANLPDX5MDwZJfIpGWtFtxLfi59aAdNfzmOc4bFQOLMtHkYiD2wnXw7gxc W8sLognaXowCD0DvLaF9yCjCE6RzMSEF7WVmWCD8NShhwYa8YEJ4lsA 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 --- 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:09 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 C58A616F846; Tue, 28 May 2024 13:15:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716902123; cv=none; b=R+zyQcabc6wGb6ZXvwaGorJ2rXIKZUK5FSFRlUpzVGQs7mv1xu/UueYQf/Khj2CvUNyzKTGdC/vzBVRGGIEMpj1Ax/U9RWA8m0oO0LT+veRYrtfS/P6dmBHw0o2T9IcjXLC94Hzq55wrhxqq2oCvt/tMzL4hu12vStpq0CbkFVQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716902123; c=relaxed/simple; bh=9WdrhkQ/w3fjmh2OCYNw2/sdwfYWu3wu/kbo44PGz9g=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=HNnEutw5FtoPwGDd+Hgg8JpNtGsaLlmtg1cu1/itlhZNuK0nUEjbniEvu4eRW6z3hLt+CN/SDnDSBbvwqJX5DJwdB2ag4LWkCMqeDgAkVl9V7o8iomBb6g6zvx7RP+0GtHFHFRJiAwqu8cCoVRr4UwA4ZUXJFzYlH+r9BIFEQfY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=HEIROk2x; 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="HEIROk2x" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3FC36C4AF0B; Tue, 28 May 2024 13:15:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1716902123; bh=9WdrhkQ/w3fjmh2OCYNw2/sdwfYWu3wu/kbo44PGz9g=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=HEIROk2x0ybH8MKibJDr3gc3KX3tBNuxCc2jIy2Sgdci7ukJCE58iuyAEBx245mQe udL7mw9oZjItVPC3PGPuyrHM9VlIWNjYMoU1j3fanscAC/JT0ajWTVCNdroR2LBtuN n6rCErvQJE+TySQN/ep6vu3bHKpdNtVxquacAR4JmCLAFDwZr52yHNamNGVxuoghlK B2YLe8SYv5qfeBoBgl2TfSBAbNPqKetP5oKU8wBfrwbQikAWdg/2yffj4WbqXkKj2p sGG5sTuSHyzoSa56xyc6dEFNZhqgV9iOooMbJ70jhQhTiwIj7wcmOXdhJjU9+nji1p J7M+UxCnNebeA== From: Benjamin Tissoires Date: Tue, 28 May 2024 15:14:41 +0200 Subject: [PATCH HID 03/13] 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: <20240528-hid_bpf_struct_ops-v1-3-8c6663df27d8@kernel.org> References: <20240528-hid_bpf_struct_ops-v1-0-8c6663df27d8@kernel.org> In-Reply-To: <20240528-hid_bpf_struct_ops-v1-0-8c6663df27d8@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=1716902113; l=17062; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=9WdrhkQ/w3fjmh2OCYNw2/sdwfYWu3wu/kbo44PGz9g=; b=K2dE2hE7YkYkC2Yl7vUUciAtCrcsT8MaxGoi2o8dtPCAoQy1/5G5BK2GgfK/onggEMMQE1d/N ssbkMjPF+z7CHnPoi08RPlKefWueC5fAxWsKEeISszoVCvnSZkJh9S3 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 --- 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 | 246 +++++++++++++++++++++++++++++++= ++++ include/linux/hid_bpf.h | 64 ++++++++- 6 files changed, 362 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..be514a98e55b --- /dev/null +++ b/drivers/hid/bpf/hid_bpf_struct_ops.c @@ -0,0 +1,246 @@ +// 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 flags; + + switch (member->offset) { + case offsetof(struct hid_bpf_ops, hid_id) * 8: + /* 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) * 8: + flags =3D ((struct hid_bpf_ops *)udata)->flags; + if (flags & ~HID_BPF_FLAG_MASK) + 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 & HID_BPF_FLAG_INSERT_HEAD) + 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..96495e977204 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,63 @@ 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: &enum hid_bpf_attach_flags to assign flags before ``load()``. + * 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: internal use only */ + struct list_head list; + + /* public: rest is public */ + +/* fast path fields are put first to fill one cache line */ + + /** + * @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); + +/* control/slow paths put last */ + + /** + * @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: internal use only */ + struct hid_device *hdev; +} ____cacheline_aligned_in_smp; + struct hid_bpf_prog_list { u16 prog_idx[HID_BPF_MAX_PROGS_PER_DEV]; u8 prog_cnt; @@ -129,6 +187,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 RCU update of prog_list */ }; =20 /* specific HID-BPF link when a program is attached to a device */ --=20 2.44.0 From nobody Fri Dec 19 21:10:09 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 0E74F16E894; Tue, 28 May 2024 13:15:25 +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=1716902126; cv=none; b=hkmw1gu4VKWdWSCEN7JEdH7MRSsCFmlGwBi+mLqPeJdMyhU1WfCyGMFHeX7SM6lyX79Thk+ijSdSyYMBwHzuxDBqnJweIVppTPcY7esAeV+VjiqWupsjt3N/qzL28ZtTlZJQniTZgH2s+t1+UPovJMwLLRwwQOy44IbNcA0MxTw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716902126; c=relaxed/simple; bh=Peyz1EG9lVg4zl3CGQlZmk0mwWsyuGKOxsnzIdcTtuY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=AASGGBI1ozCmpAzOqHOyVaRNCVfeE8V4E+hGdNc2T82KwHRExi2EQqNleMuAGzw9sXfZFop2M/Uas9O3xHxMRndewu3BkotQGae4ArARvluAB0zsOHtZiAQOCflLUr4cj3Id7etm1OJ1Err6tYHRyGTckiG2fsHMQSPzBzSerfY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=C+apPNVs; 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="C+apPNVs" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B78F2C4AF0C; Tue, 28 May 2024 13:15:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1716902125; bh=Peyz1EG9lVg4zl3CGQlZmk0mwWsyuGKOxsnzIdcTtuY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=C+apPNVs0RCyudd981WD6a9nnmAoyQWlWiql8xqo2qMtls4mb4cAGeeBFp+ZnbcKA q9FoWAq6bbVO3VL8ZhMLtl5loDL8c/cw8Ziu6orB6IcMYl7HXV01BFdYq6yA8QEOza XGPjh/BGJOTYGBp/LLJUZuZ8AJeBjfaicSVPO2shpG57zbpLkJB4q0Q0IVU0/nWjNl iYSqJh+DX39jNJcghSuhfy4rD5DE2CGEYWxLL7rL/yccaNMUHmGyQ+qTDBzb/iyhkA /U/sCv9Q1DX+t3DI1Sb0N/W7qzbodGsO5V1wDq6dKHeMF7GbB2l+3XFMF26zzrjX+h vU8+O4293knUg== From: Benjamin Tissoires Date: Tue, 28 May 2024 15:14:42 +0200 Subject: [PATCH HID 04/13] 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: <20240528-hid_bpf_struct_ops-v1-4-8c6663df27d8@kernel.org> References: <20240528-hid_bpf_struct_ops-v1-0-8c6663df27d8@kernel.org> In-Reply-To: <20240528-hid_bpf_struct_ops-v1-0-8c6663df27d8@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=1716902113; l=9581; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=Peyz1EG9lVg4zl3CGQlZmk0mwWsyuGKOxsnzIdcTtuY=; b=FCWBycVRHs1e++pucRrlOttuIZCSuvThzaJdZ2cuiPwjl7mVLYs0Nbe8X3yjiNXWK1tgLcrKo Sdb9D65niFvDE2J9U1bNpDfTgqFnhNZyvF1hiShmRYNPJ+AerllI1Qi 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 --- tools/testing/selftests/hid/hid_bpf.c | 59 +++++++++++++------------ tools/testing/selftests/hid/progs/hid.c | 76 +++++++++++++++++++++++------= ---- 2 files changed, 85 insertions(+), 50 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..9adace26e8aa 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 HID_BPF_FLAG_INSERT_HEAD, +}; + +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, +}; --=20 2.44.0 From nobody Fri Dec 19 21:10:09 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 462C916F0E6; Tue, 28 May 2024 13:15:28 +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=1716902128; cv=none; b=ukOeSaWxFaeZu7Meha2/WsBQejr56MP7GzGYKgYm8hHlZgaVS9a1aFXF7Z2cXYz1gG9iOa5Tz/+rbokFZoE2w41vSJnkWxgTN5Q3iWEoKPJfA46rojZjuhcoYlFgUlUOVKXQMWdiiUqxk6CyWE5j4fbozKYHsaLAOM9JGtZhnYY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716902128; c=relaxed/simple; bh=O1/nk3956cFuty7ad2Pf/GY4bqEhv56MhENqud0riqw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=hv5UP9V7+Ky5b8Qh6T05700vbgpv3HJWwQiY55j1epAHe/RAZJvSCw7n8jXszAJcHD9NxF6/aqHmqvuLa54KVyuY0X/kDyLJoYg3qIaV6hVH48uF1UI+xFH6zGgjcdVzbqQYQ0/BcEzJR5eQfNyUuJWLxQc/pEb14JiXuYADFD4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=BwjUaQ8c; 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="BwjUaQ8c" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0E2EAC32786; Tue, 28 May 2024 13:15:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1716902127; bh=O1/nk3956cFuty7ad2Pf/GY4bqEhv56MhENqud0riqw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=BwjUaQ8cZtFQPyJtLaS7+RhKW0fgVXziZFIePGLf3THUFNRU6HZJD0BnLg1EN+V4f WQ2TS07SR7viIWxvi4D1EeV1KlKC+pb/whfttKMqhTULItGczLFwObdCNkwdFkvb6x 3kqGX2FD0F1IOq8HdR+8RM09TZpQjSC0SUKFDizOYZ+O5QeskjSjjwHxrLge1xQ67U A4bce3SW6NEy6c8mJDHw/DhLwyCt0mOhXJQRexUhsPH3r/Nsb6K+CVlxUXDEhc9TVW Y7ShGwsX2PE9HSt99NBkKmpd8pE82ppOjIFAcn0ah7CjiFPajHpod/ahmv5ixLysFZ BmzUQaJb/gLxA== From: Benjamin Tissoires Date: Tue, 28 May 2024 15:14:43 +0200 Subject: [PATCH HID 05/13] 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: <20240528-hid_bpf_struct_ops-v1-5-8c6663df27d8@kernel.org> References: <20240528-hid_bpf_struct_ops-v1-0-8c6663df27d8@kernel.org> In-Reply-To: <20240528-hid_bpf_struct_ops-v1-0-8c6663df27d8@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=1716902113; l=10364; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=O1/nk3956cFuty7ad2Pf/GY4bqEhv56MhENqud0riqw=; b=Nmp+BEGU31tlbsYYrAbv4H/LXLFTanrVFttTbFov9GVFUUYK5Jgn4sHFQLMsWhzCmEB3ImOQU nufI226/q9fDsBmL3A3gd+Qb14poaah9gPVFr+rTxWqele9qa01JL+/ X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= hid_mouse is currently failing with bpf_printk() not available in struct_ops program type. Signed-off-by: Benjamin Tissoires --- 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:09 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 5811F16FF3D; Tue, 28 May 2024 13:15:30 +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=1716902130; cv=none; b=Ygd4BTBln7fsYTsB8P0EjYVLpzyVeH90Wb4ucb0JN4Zt0w56TR/VJTqONQAYzn0OEjWtyBZf/T8JFfL3RfKVmQjWZzTNU6QfyD6fihJgmDFzYT2ijksHpU/HtBPDzRUL5SVpAQzb1ME1YV8WvOA0eHrjpAnGBVvMH4629/sTCts= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716902130; c=relaxed/simple; bh=ASYT7C4PzdLCyYUiHYyqygWpOHzADQG5pEoKYjPNpLw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DdeH+PdTxRnAJTePcNy5+X8zv2zFLOvsPzlYdEDb68tlY/AnndYNYaLg2oCxB+CZX6hWUgaMhCfyaEtzvYAD/sOhJJRSy7sE4GYcR7MQhyfuvYbo4w/ts9W8aQYUKHolEsY2b9lff04hMRTs3Qw2P+BUf/Ho9lDtsqKJCyXFcQs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=bwkX8cqi; 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="bwkX8cqi" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 58FE1C4AF0E; Tue, 28 May 2024 13:15:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1716902130; bh=ASYT7C4PzdLCyYUiHYyqygWpOHzADQG5pEoKYjPNpLw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=bwkX8cqijGiQ/QYWGGcZDZ/scvEanb4LC1M1wvbOzItZ/DBxSNMkAL8VmjUBMr/Qb jk61eakf0gpJNvEXaVVicwfbhyNfuIa1yUATV2UbaWFjIDYVvHsvwHod0uKBl8HhU7 Ltjv/nqJiQsDdX9EVNWk1mPDKRNhuYEaV9gt/o1nIrc+XOYsz1ejr6ZgN7ZKpJB5/b rzhX69BW+HxsHwlGLAXV6jdsrUqzh15l1kqgjKJ9rjcODb4+xiqe3y2tJ3so12nQZv grLDLE8AbTkmhIXc11Y0EZkUMBvqWlGxTB0IK2ua0vlO1PGGRSZOc/1wImYjwyoX9g ovTMUBIU07vDA== From: Benjamin Tissoires Date: Tue, 28 May 2024 15:14:44 +0200 Subject: [PATCH HID 06/13] 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: <20240528-hid_bpf_struct_ops-v1-6-8c6663df27d8@kernel.org> References: <20240528-hid_bpf_struct_ops-v1-0-8c6663df27d8@kernel.org> In-Reply-To: <20240528-hid_bpf_struct_ops-v1-0-8c6663df27d8@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=1716902113; l=8046; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=ASYT7C4PzdLCyYUiHYyqygWpOHzADQG5pEoKYjPNpLw=; b=n25Uu3EJwKcRP7Hcut64lnYNaZZh3KCE0KPUUCQS6VwdqQ+aOA9q/cx7D+6Iromo5BwuCEJVz F6QGNfzhS05AQx7i32p/JuXvBpiOaaXzWU16RgTYMJWvQcd0lXk1PaH 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 --- 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:09 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 0BC1017083E; Tue, 28 May 2024 13:15:32 +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=1716902133; cv=none; b=qh4LrI8xCYi1yo9stghcwmmhUZIF3n8UnHXxkiK97ERaJBvOXdlX3ti17I74s6LogzRPOhZzDVJ7MWWUr4j95TV1UKaOKmVvnCzv7+1irLPVQRtow7c7oNM6bIgKH0LlUdLq0pz+/J+e2PX0AhnVN4ACDQ3Hms+6n3lB55t8Yts= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716902133; c=relaxed/simple; bh=tqO/DG0FgvAOibuQ2xEp6PL6ZRfxR/tzTfW3jaARF5E=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=QZsJzRfLGvwusnMuj07ehuW3eGEXGsIn6WPDljCkCp8DR1/YfCJ6R9Rds/e24wCSprNzfxC9FYJjsMOPyF3QxkGh+m/kNTVPIU1FEtdn42hUst79gh2qChqqmdYjLpswtyjnjoSD89LCp8fK41R5s+Px4q+BXcZU0XXnzqNhSjM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Lm2ld1Dp; 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="Lm2ld1Dp" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A5549C4AF0E; Tue, 28 May 2024 13:15:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1716902132; bh=tqO/DG0FgvAOibuQ2xEp6PL6ZRfxR/tzTfW3jaARF5E=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Lm2ld1Dp1d3nNPOqg4+igSXG7SXytZ+BMVFZvF3yuFNBvFkj84ZalUzsAadDDnZty Fx+j7u9oDEFEKD/r3H/ddqJCxw2X1xobOeyuTpghVwGHNPPPjti8tIZvshVbBICZsM ziuQMaYep7EFeYH1Y2e/GREOsISJxhkD1Q0vPkZmhGx9paFZ0u0JENgfJtHzEsQRg8 10RJZdfcJnLNI2+Mc2zlw3JGfUfIPScXSj+GDt3dt1SHIJr/n6W81gXx+dNYlugKHr JteKyEo3pr1GnnrpGbgoAP7mAeVobe41WmsfKVF0eThaFrpV0GqJVYicG7qptWtad9 3q05WzFNED/5A== From: Benjamin Tissoires Date: Tue, 28 May 2024 15:14:45 +0200 Subject: [PATCH HID 07/13] 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: <20240528-hid_bpf_struct_ops-v1-7-8c6663df27d8@kernel.org> References: <20240528-hid_bpf_struct_ops-v1-0-8c6663df27d8@kernel.org> In-Reply-To: <20240528-hid_bpf_struct_ops-v1-0-8c6663df27d8@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=1716902113; l=7057; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=tqO/DG0FgvAOibuQ2xEp6PL6ZRfxR/tzTfW3jaARF5E=; b=JKmQNp3Z0oIQZmbdR4fgXuPPMXA0Mvaof+w+0mIQ1G0jGZQx3+EHmXKN7BFG5D37z+iQ+kV9C eiHCj7v/O+ED4xEJ3zGSQN4l2X8xx+jvxC4EEFVPNeG30sdsozVKq7C 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 --- 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:09 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 8B5B917109F; Tue, 28 May 2024 13:15: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=1716902135; cv=none; b=Xjiscujx1Dhgfc+ZtYYZxITxt6uXbeTTOzc9OhT4wYCt7cFM1xsAgDvDnBMbKK6GnJElWZEOI6FIXuSbuiMsnimOaDUkQ7zKvUGFwOgntLNW6ch4R6EGVg+P28Ct41t3EIXfqw1DrzqKqJAdanvRQ+QNZSx3ypTcrc0TcqqkhgI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716902135; c=relaxed/simple; bh=8TtmKzskCffvmEzfSvuVmB1Ck3elvFNnCVCPNiogbA0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=MJkoLjkQGw3fvBgWvmCEIm1mkeiUGU7y9TfTqvBOcgXeQUZyh1epMcvnGusI7X12f+5HMpb/dq8Ivaj5pICtceSutLz05mDE0uPgJoWC9ndgRZo+zDm/KQTM+kC9u3bbWRrrky+q/d6RvzDQT+BrapNq7wyP224SXiUEzFsSqIc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=WR7CJYkf; 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="WR7CJYkf" Received: by smtp.kernel.org (Postfix) with ESMTPSA id F373DC32789; Tue, 28 May 2024 13:15:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1716902135; bh=8TtmKzskCffvmEzfSvuVmB1Ck3elvFNnCVCPNiogbA0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=WR7CJYkfgTLAVkkHABUuOO3sPjxqKwpSypEQ9dn+TTz8xDAPOxkPe+ZPDGuJYI1v9 g8OwzrpwH7M9ZG9K9e3WCH4CDhvr8TZAKGkLBU8BSbjS6LXapSgWp5o0dAHz/tVR3W BdAr4Bxn/bTmG8pBQuVv77Zo7Bmck78jW93QlDE+rncp1A0eauB93LgIokkFKpl9bB eMvb7wRKOo5RkB9zQH5cbqCJ0B3pfI3MtfzPSjZO1Qr+qFYR65bWx9AFU6MBe6nHQM 0yp6Kl86QZCS6kPENdN504KzVi8ZYaUsTy+bRwJ+V8o3UseK57KfX+Aq8Fv7YAdQRZ K+d3qqxRW6kiQ== From: Benjamin Tissoires Date: Tue, 28 May 2024 15:14:46 +0200 Subject: [PATCH HID 08/13] 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: <20240528-hid_bpf_struct_ops-v1-8-8c6663df27d8@kernel.org> References: <20240528-hid_bpf_struct_ops-v1-0-8c6663df27d8@kernel.org> In-Reply-To: <20240528-hid_bpf_struct_ops-v1-0-8c6663df27d8@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=1716902113; l=48085; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=8TtmKzskCffvmEzfSvuVmB1Ck3elvFNnCVCPNiogbA0=; b=oScMCchMR5Q3HLt0mkFyZ6mS/5Zq80ArDrJR1LF1WBEYIqNvSSnvxSgZeywDVCsiYp/3tuGqh Lj/qwECWDd+BegICDJiVG7Ifey+8frvRlJl8QtULzYlYDNdg+OqvrJh 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 --- 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 | 37 +- 9 files changed, 8 insertions(+), 1170 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 96495e977204..c0682db73aeb 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,10 +43,8 @@ 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; @@ -74,27 +68,13 @@ enum hid_bpf_attach_flags { HID_BPF_FLAG_MAX, }; =20 -/* 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 @@ -170,11 +150,6 @@ struct hid_bpf_ops { struct hid_device *hdev; } ____cacheline_aligned_in_smp; =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 @@ -182,23 +157,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 RCU update of prog_list */ }; =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:09 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 72B5E171679; Tue, 28 May 2024 13:15:37 +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=1716902137; cv=none; b=eTx6B2MUjS+1osp8SFMCLwk895QC+pAy6AeYMfE4/6A6ZnE10uig/yhfswZBpTNnYTdOoKkDIaq0L/N5qJCA6WcvJSUylW8oc5HW4zpkqnJx5/RlwkxSmxiFZ3uxNLTZhD8XA+Y3n+jdR0GdK/kJSRJ3nY+noBLQjWwB+KcaQRw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716902137; c=relaxed/simple; bh=r5PRmmxJaUk08rAPSCBzO9oSNG9qSKMUcqLqCcrKXiQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=NTl8pU3S6m8Mb3m8G6TeRi9guMXkdnD0WO8cX9M1x9N0QoRejp3d9KPLpBpNe13JE36ZTGBiLt0C8JHTX2pq3EonHIWFA08NcyX+cdzzLtvrpn3oYJqdnyDWEoM+7Kg8+4PdmfPYpxZcopn7ySbWljtIhk5kuCjIzwvKiBctABw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=a4R+nlNL; 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="a4R+nlNL" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 74A32C3277B; Tue, 28 May 2024 13:15:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1716902137; bh=r5PRmmxJaUk08rAPSCBzO9oSNG9qSKMUcqLqCcrKXiQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=a4R+nlNLumi2QM5Rv8uuN48nmEzt4Pj1X60btY+MADHG3O4nmsdzG1UjPRdEskAUl Ql0R47Bd6wyKxm/tPeHOonVj6DTzPGdZAnIb/lZxylw3c64xx7/aITCLFc/MCYFepW 8gsQtDBedaEpJbFGKGJOOOCyDnQgy096qcRGnZewCQCDYPgKPE2p/PGPcLyNikQ0mz /RwhOOEvyrdqQmujoBPkpZ7pI1etcYXcGbqZwI/JQs6RjZQv4X0dRXtn0ikW5LdhIc qFbSWxFyP7gnix/fKuxSMACmsZoT5YyAElCoduX5sBzY1GVrqLfDFNPmAq8lan19jt CY59CIpm7FFUA== From: Benjamin Tissoires Date: Tue, 28 May 2024 15:14:47 +0200 Subject: [PATCH HID 09/13] 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: <20240528-hid_bpf_struct_ops-v1-9-8c6663df27d8@kernel.org> References: <20240528-hid_bpf_struct_ops-v1-0-8c6663df27d8@kernel.org> In-Reply-To: <20240528-hid_bpf_struct_ops-v1-0-8c6663df27d8@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=1716902113; l=2874; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=r5PRmmxJaUk08rAPSCBzO9oSNG9qSKMUcqLqCcrKXiQ=; b=Bb/kgLvMa2H3hEIhee/vec2iqeL/yB3axdtRrtdDBokZLYyrCJOgC7ir2UEXwkV6TTffDYk5r EdVtWZdCRUKB+HLe/6fAzN1E9G7QqrJmHMO38lFOEg/HkoJhS0gQ8UR 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 --- 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 9adace26e8aa..efa3c7d292bc 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:09 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 10938171E7F; Tue, 28 May 2024 13:15:39 +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=1716902140; cv=none; b=sgwSLJuY4hcodMpguXGGXi35FTT6xzHa+z/3No9UeOtzLaNNqbazonfig+AlfrBWhKeElAlG8HlOOqMNKhg2Iw54zsvC6hbncMCRixQxMVli/S+lhGfIB9WNC0BiTrEKyszZS0piLi08Gkm1cRxVFtO3Rw7XvC01yAF6EQjSEZQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716902140; c=relaxed/simple; bh=ldhQPriIAfKnPCHmQLp+2mLlIct3nzCp8E50ETSxOSQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=J10LAq1C/LPZy3SMOzHRE6f51Fl3w4EAHT02czQcDJu+w1P98Ug6PBJJGcTk2zUmMgaEehJC+H2R+9aAq4qIt22j2iVfHTBw3UhqFyR1cCKARxv4DLAdT7sCJXmeO6ad9EKR9t2eIS7mSEtrcZnOKKeqF6709Ze8sxG9DzCKHrw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=QBs9arnx; 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="QBs9arnx" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C003BC3277B; Tue, 28 May 2024 13:15:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1716902139; bh=ldhQPriIAfKnPCHmQLp+2mLlIct3nzCp8E50ETSxOSQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=QBs9arnxt/CGjPIxIJv/ClYF3DoG38jP5iUaI83N/XjApfc1jpB3Y/0ryp34+qNKV cd3Ee6rqNtncDWRHeVfNbeU5IfNhf+QiUTZRKVUIc+BopLvVRD35ZKmcD61QWhYIQb 16HfKmD5rb9vOclh3mWL0X6lXOlSL+HTK9fl4S08eK1n2INDiFGG+b8pbV/SbEBFEe GNce/8Ua6S+nf3OCEQdOwPEuUqnezzoZCb2LsTzf8q6L0suVdzj2v1+dSaxEwJZMlq AncZblvk4O0f7wcae40DrxoGBAlFg3nugV2uX1jccwjkvUb7ziVuGFQavvIviqO83a 8t+9m3z8q3vZw== From: Benjamin Tissoires Date: Tue, 28 May 2024 15:14:48 +0200 Subject: [PATCH HID 10/13] 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: <20240528-hid_bpf_struct_ops-v1-10-8c6663df27d8@kernel.org> References: <20240528-hid_bpf_struct_ops-v1-0-8c6663df27d8@kernel.org> In-Reply-To: <20240528-hid_bpf_struct_ops-v1-0-8c6663df27d8@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=1716902113; l=13520; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=ldhQPriIAfKnPCHmQLp+2mLlIct3nzCp8E50ETSxOSQ=; b=buV9K084lC5PoSsbfHoY+NUTXt18xtaWdU9a8Fe002il5Wgv94T2E8NgjM+PwcX367pTZriE0 hJSltRF7C6EBmQtwZSTe5RwafHCkwWIN/sxwrFYmEixRY/tsLrxAsBC 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 --- Documentation/hid/hid-bpf.rst | 145 +++++++++++++++++++-------------------= ---- include/linux/hid_bpf.h | 8 +-- 2 files changed, 71 insertions(+), 82 deletions(-) diff --git a/Documentation/hid/hid-bpf.rst b/Documentation/hid/hid-bpf.rst index 0765b3298ecf..bb8457bf15dd 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 hid_bpf_attach_flags =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,8 +228,10 @@ 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. @@ -234,8 +242,8 @@ from the device. Note that if there are multiple programs using the ``HID_BPF_FLAG_INSERT_H= EAD`` 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 +266,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 +285,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 +364,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 +396,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 c0682db73aeb..36cfaf092d0f 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:09 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 71AE3172BD4; Tue, 28 May 2024 13:15: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=1716902142; cv=none; b=bWAVWJ3y9drUVT/UzIXuvu+R/n4cj1lcfqN1WwuhrbnGg7l/V/Rl8Z7aV1pjRYYu/Hdc+uM1P4GYIZ2tqpWGtBUi3ApEbKZaUoEt8LomphIiODngJCdrPAdMnupl960rY9EaguTGXVhCOqEac5GdSoRrH0y4rIOwkw3cEynEM3Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716902142; c=relaxed/simple; bh=LLJuXzECrzZ19dHpKyqnDZSibpJxTRfPg9I8vzVwFcU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=AYdbI/Gpa45vrQMNyGMATlK1L/nNNvYTtMYm5JUc3ico6ricTYYzZ6ay/ePc7EJEuROyJcoLZVDhIV5Ud24oJZdlA41cKUynBYVWUXw33Tqk3/5KMTrB6cPGgjS4YXyCk85VzUy6OZjT+8m5sBkRi2G+aFgG1/GL5YxqctVGU4Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=VJCJQAcQ; 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="VJCJQAcQ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1753AC32786; Tue, 28 May 2024 13:15:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1716902142; bh=LLJuXzECrzZ19dHpKyqnDZSibpJxTRfPg9I8vzVwFcU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=VJCJQAcQBgk6xkDpzbLMmqte9kI2Ctyr2cwKZxsLcBzkKdZNT1fxhYZl1FUgZ952L IRd+mb/60E+MWw8KkvIU7yXgtTmLcB+UGaghXMWmOf49JmIIIfhUwDTbVGJF16DDCo x/5jjoNyiuaUCINAU54qbNRB7sxYA/h60WPLZh+jOcPEgOqXt760Qea64MAbSJfhVk ZrCl41egkFz/tSZ8EddPufzp7Tt6cG+/Ha/8S0uympivDs+bmjHWaTjxmXXxvUHabu HRmplyMCGfQzojoSYlH061xSuhu4QtqbLHYFcGPHkej1c6nqVGuvGqV5S05wkTSt5n SXgornPnFFd9A== From: Benjamin Tissoires Date: Tue, 28 May 2024 15:14:49 +0200 Subject: [PATCH HID 11/13] 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: <20240528-hid_bpf_struct_ops-v1-11-8c6663df27d8@kernel.org> References: <20240528-hid_bpf_struct_ops-v1-0-8c6663df27d8@kernel.org> In-Reply-To: <20240528-hid_bpf_struct_ops-v1-0-8c6663df27d8@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=1716902113; l=1778; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=LLJuXzECrzZ19dHpKyqnDZSibpJxTRfPg9I8vzVwFcU=; b=ellvHsaUddXd2866gyZVKvMLF/FI6KsxQvQH1L7/peDA9c6YBxzrBFBTDUJ/LjVT/pa+t3WoG yhiT9pPClYSBUEU3mrQ4MXbMUK55xpp/gkCPLWOWUFBAY8xfpZ2pBBw 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 --- 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 bb8457bf15dd..7b151a2aef63 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:09 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 8B3F5174EC2; Tue, 28 May 2024 13:15:44 +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=1716902144; cv=none; b=JewKQ8116Qv6yP1cfqGyZXSWJvEe0KAqYtSfirogQpyzVOMGaJV2C46ETlN/lMHUOgGWI1BlC094J1G2TLgdcl+iAHFiqEDwsN160+Qu/gOcFOzoJpk0yYcokXjRXOxn8BcB/TGfDxSOTDUWtBCSJdnxAY5sS94VxE75Z1VNxsg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716902144; c=relaxed/simple; bh=eowKlObErurap8texC0IeDebTUGtflcKm/yE3YPRDsM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=QICpFCewiEEozN7na2fg3APDX63VNPYrftR+E3zNL4bfUa7LYN8n+uotq25YDYvLLKHj8DbIqMkJY2PjpQKUVnEoLe+to54xW5oV7QWi7+VNWb7juZuNcRKya9p1ncoDnW0ZsmOXGQmK3kMXaRx8MpznH85vKmT/sFDjWosn2ts= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=l4pVrrGM; 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="l4pVrrGM" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6292AC32782; Tue, 28 May 2024 13:15:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1716902144; bh=eowKlObErurap8texC0IeDebTUGtflcKm/yE3YPRDsM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=l4pVrrGMR+eaVZ650RASvdPqk5Qs6N42cWpsfR2nnawaAJiiMFgdrRT93DRUf/NI+ upH8s1Xi09lDAbY/rtQ+L0dmSHGf5JBpNUFHq7OABcSPyZRN4kGawzac80CFzsE8Iq jKN45764pVJGkTLy99ycPSxigRdDxBjVUP/baIb00fJdRvnRop2NRkvJzr2i0tM0Nb QnKPYfEeZq4ywEt5XxswykkrHOwWjAbHNOtbbWk9u96TIDsMn3721Q3VqzqdwManl7 HZ5ig7wE6G6R4GumGn45oePa4hcNanuz7W7D9UsPVTYJ3/N3ki7DKqNrMBiSf3saxs gi82dpAA0N8CA== From: Benjamin Tissoires Date: Tue, 28 May 2024 15:14:50 +0200 Subject: [PATCH HID 12/13] 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: <20240528-hid_bpf_struct_ops-v1-12-8c6663df27d8@kernel.org> References: <20240528-hid_bpf_struct_ops-v1-0-8c6663df27d8@kernel.org> In-Reply-To: <20240528-hid_bpf_struct_ops-v1-0-8c6663df27d8@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=1716902113; l=798; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=eowKlObErurap8texC0IeDebTUGtflcKm/yE3YPRDsM=; b=Ls5lwnz+jdJM1LWEGdDwN8HduhTcE/XsVVk3I0en9UjFVNudj1VbmZx8GyvMr768n45DRHogi pge7gg0uxd3DYz6If4EJeIPwRU1A0itz7C8bO30e4WJuYE1ZBLerFdz 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 --- 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:09 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 358EE16F292; Tue, 28 May 2024 13:15:46 +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=1716902147; cv=none; b=SyrjlGbd+8ozr92O48C+Evim2dQP2HUbjKMFS8MebmyxBpn1J3csTNfLwG+OZF1P/LOnhGYIk69g2KamCs6OXqJq1rxtnbXSkLASn15muYxGpS38NIM0Lm3O/1D92VlGGBFRjojtdCzT/NA3c6ycsjwwLONWgScHBxShA6fbisw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716902147; c=relaxed/simple; bh=Tr1yyl5glZHjQNVjRPObhpi0VbS6TeTAGCRSkl0ml0o=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=bG7c8HvsDFOtfYsoP/9b1GDZCChwkWLDz2KcX2J7H5M7FXRo8XztBdDzeBBPsLapXnVX3MLZ2370rw5S9H1cg3OP56uvdVr2nEA5D2VTN4DpCStjJ+F0AMEffVTpxxtq3QYpKRoJ0tueLGDA18mKKqSDsBOSAhFc+RNePbTqzyk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=TwMtJSDW; 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="TwMtJSDW" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D7CA4C3277B; Tue, 28 May 2024 13:15:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1716902146; bh=Tr1yyl5glZHjQNVjRPObhpi0VbS6TeTAGCRSkl0ml0o=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=TwMtJSDWPlzw5fDvIRqsukaJzOvsTmwKO7Un/0JdBdOdTfgD1/ceFpckunTXnRS1B 3DfhAj6WRP/p8mXGE26jZqwAgBiFk1w2rSAHhjyIK4ea9qMc2FKgrMiLLUUtTd5E1Q TxHmmzKvTV9A41HSxhhcOu76csJkauFYMaPWemJWE5Lhj7JZLDyXkBrehzv478E0Nl Cfux73/Tsh3G8xowzc7fqV3wFF07nbNaEU0IdGVjJ3nr1P55NR7+s/JqyZAmnEbfZ7 k1p9UsKpaG7e12fZmJUOawIt9b8JtUITIRCRfMlLMtnxouFFxFin6ZMfCCJMwPjVZl N2fWBYOMnjEkw== From: Benjamin Tissoires Date: Tue, 28 May 2024 15:14:51 +0200 Subject: [PATCH HID 13/13] 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: <20240528-hid_bpf_struct_ops-v1-13-8c6663df27d8@kernel.org> References: <20240528-hid_bpf_struct_ops-v1-0-8c6663df27d8@kernel.org> In-Reply-To: <20240528-hid_bpf_struct_ops-v1-0-8c6663df27d8@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=1716902113; l=738; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=Tr1yyl5glZHjQNVjRPObhpi0VbS6TeTAGCRSkl0ml0o=; b=qxiMEpLA+Im0ChWCITPIRK6TeeA/TJVdvPQGZsHorM0DpzVPYNhMnXntGCTYXbSlMKw16m8on rlOPAfnnqQDB6Wir5YKJ+ohEXsRXC4xGagLLtLa8oWalMqZiQMk6HEi 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 --- 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