Received: by 2002:a05:7412:3b8b:b0:fc:a2b0:25d7 with SMTP id nd11csp923235rdb; Fri, 9 Feb 2024 05:28:03 -0800 (PST) X-Google-Smtp-Source: AGHT+IEUzq9Mft421ToI+LW4/uy1BFPyXBn8Xfwg4gVmtLN0absvTzHl4zL25Z35C1JbFFuJLRpS X-Received: by 2002:a17:90a:8a91:b0:296:69a:34c4 with SMTP id x17-20020a17090a8a9100b00296069a34c4mr1593471pjn.21.1707485283312; Fri, 09 Feb 2024 05:28:03 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707485283; cv=pass; d=google.com; s=arc-20160816; b=kJYEmznt5sxIdLdEVSiH8aH7Iqq/gDmsmoRx+AIZKebVW+tS8lxqR5WXqVaFx1niA5 7YqmedHsZ0STbUUZRadE9VnWG/WP+pM0qctCihLPiG6LnSKLK69MNrSsd9bfqZY67bnu mZLOEnohMkovrko4wfUX84/I+a/N/HbXbrokmsuCisfZ3gCEJi1qJirNg4lWJ+oT5wZY ygUcl/WkTHXqMIG1rIMhzknbUd6rJaG4j7KgVgJcR8nd1Q35vKH8YzJMC6/dO5t7Nm4f 8RDVil/7tOk82CapOCkX5NWkTHxBWpOpVfPCIaVoK7zUt+9Ah/Y7PxRK7Nl4ISCCrasQ ak7g== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:list-unsubscribe:list-subscribe:list-id:precedence :subject:date:from:dkim-signature; bh=IDGtnwPX5f7YNWoGu2H7Gfwi79EY6JFOIwzaJKRv69s=; fh=M/ksAceslNIvBrR4wzO6M3yGnv9EsSk00GHRzuIn30c=; b=JAGbhojwF4KoxDCXJ60As5c1Wv/MeEcB2Iu03tQkEGOylOzaBeEyoy9f3q4X2jt1cL apjejW9pLR9zC/njG2G/a6OBpe05AbIB5IDTPR2xKEH/4zRL5NWwP2gy8kP5MfF55JfV mUdWH2u2mPYh/7Chj9I8+uiRy5yXh1DYjcitlKbs6DeVK2UhvVlfp8Uwjw/3Y4vRRsv1 3YL+oBAFTFgji2qDDj1GNc0kb7zFEhPNlzm58zc0MmQFYJIGXHyff3SNJnOhCdPbpGLs SqWZpBX8aj+LEWLaIC+NvEHdn6imq+l/+4Ee6DccVCXIclMKYK8y7KVL5StUgMcfnXer S4zQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=e5gRcFXs; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-59363-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-59363-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCUTxz2nJz9f9KTztcRK6GiB3m2OGXUxPwxOD19YzfzIoAvx0MkHsJ94B9DpmOrpdwbLjA9Pl/JYv4ooFCn6qugq0MeGS9s0BolXIJDscQ== Return-Path: Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id t12-20020a17090aba8c00b00297084c4077si1423822pjr.158.2024.02.09.05.28.03 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 09 Feb 2024 05:28:03 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-59363-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) client-ip=139.178.88.99; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=e5gRcFXs; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-59363-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-59363-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sv.mirrors.kernel.org (Postfix) with ESMTPS id EDF47281BA4 for ; Fri, 9 Feb 2024 13:28:02 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 367DF3F9CA; Fri, 9 Feb 2024 13:27:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="e5gRcFXs" 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 2290F3F9D2; Fri, 9 Feb 2024 13:27:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707485233; cv=none; b=sbsjM4d+BfgrMVJs9nVx8p0oWunew0iGcEgllSwgKXjvC+0TIteWSCSluWL2VIf8kgyHciSY3Nfph/wqDJQJ0urj11msNOaCgSjU1/AtCLVATVbo5OZBFCTA6oqy161jldEX32P0P5MZ95ML8K/ZMIeVbTvCwGAbiMQLcSW/xEw= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707485233; c=relaxed/simple; bh=J9kda3CjXgzb0fJVv5XLIW662cD++kQrM/YYub+TSuI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=rgcmiGFePoYSgEni57GVmWP146RH9wGYIocwUQI4enZeEyrOVXXsUWmiBns0U2rbYPVjenPNtLz9OIdGqvYLzYvkt86GxKOgYFc8IwpGVkXics/hy93qzzPL4gAhNWAE29n/PRNQ8Hvn7RgOD6rHAefcJtbqWE2bL+YFmCkKTro= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=e5gRcFXs; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id AB4AAC433C7; Fri, 9 Feb 2024 13:27:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707485232; bh=J9kda3CjXgzb0fJVv5XLIW662cD++kQrM/YYub+TSuI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=e5gRcFXskMAvkyYlpKYowv0TONgF8EJFhbpkNEqJKOruvwY8Yos6qd+UvqvJjLfvx aKwrBEgX5jew/YvlUh/wwbH2pycXtBK46OBXH+QHbCRNp2jQvf9XQ32ue00nhSpLZB zIoR/sZN8tNo5UMYmOtgU4LyC8JmO/IKBAsRCc8oxbuZgceeHJauyrAZOpORvOYArI 5/whBhPJgatVkAgnwYyOpIbFS4zEao853BtdK8z9fMHz+8h6l/F4hdc/uFkgRdm8NB RcYbi62tnEaB4DXmSpX1pYxZumGanJcIlIjmtxq1WpQATMtwpwmNa9qD8Vki6flmTD Dd734ZcvlPY4Q== From: Benjamin Tissoires Date: Fri, 09 Feb 2024 14:26:39 +0100 Subject: [PATCH RFC bpf-next 3/9] HID: bpf: export hid_hw_output_report as a BPF kfunc 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: 7bit Message-Id: <20240209-hid-bpf-sleepable-v1-3-4cc895b5adbd@kernel.org> References: <20240209-hid-bpf-sleepable-v1-0-4cc895b5adbd@kernel.org> In-Reply-To: <20240209-hid-bpf-sleepable-v1-0-4cc895b5adbd@kernel.org> To: Alexei Starovoitov , Daniel Borkmann , John Fastabend , Andrii Nakryiko , Martin KaFai Lau , Eduard Zingerman , Song Liu , Yonghong Song , KP Singh , Stanislav Fomichev , Hao Luo , Jiri Olsa , Jiri Kosina , Benjamin Tissoires , Jonathan Corbet , Shuah Khan Cc: bpf@vger.kernel.org, linux-kernel@vger.kernel.org, linux-input@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=ed25519-sha256; t=1707485215; l=6480; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=J9kda3CjXgzb0fJVv5XLIW662cD++kQrM/YYub+TSuI=; b=8VgZSyLWe8IgZe4egzZt5sQfdC4WzF6KltvDEoYp0W0KXaMlG3OFMWgUdNJixCYTKt1RCNfJN 4jAt7DTngNODJuC4NDqBaXm2FCE8OWm0amhpUnSmFKTyOMTkexDtC2O X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= We currently only export hid_hw_raw_request() as a BPF kfunc. However, some devices require an explicit write on the Output Report instead of the use of the control channel. So also export hid_hw_output_report to BPF Signed-off-by: Benjamin Tissoires --- Documentation/hid/hid-bpf.rst | 2 +- drivers/hid/bpf/hid_bpf_dispatch.c | 112 +++++++++++++++++++++++++++---------- drivers/hid/hid-core.c | 1 + include/linux/hid_bpf.h | 1 + 4 files changed, 86 insertions(+), 30 deletions(-) diff --git a/Documentation/hid/hid-bpf.rst b/Documentation/hid/hid-bpf.rst index 4fad83a6ebc3..a575004d9025 100644 --- a/Documentation/hid/hid-bpf.rst +++ b/Documentation/hid/hid-bpf.rst @@ -179,7 +179,7 @@ Available API that can be used in syscall HID-BPF programs: ----------------------------------------------------------- .. kernel-doc:: drivers/hid/bpf/hid_bpf_dispatch.c - :functions: hid_bpf_attach_prog hid_bpf_hw_request hid_bpf_allocate_context hid_bpf_release_context + :functions: hid_bpf_attach_prog hid_bpf_hw_request hid_bpf_hw_output_report hid_bpf_allocate_context hid_bpf_release_context General overview of a HID-BPF program ===================================== diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_dispatch.c index 52abb27426f4..a5b88b491b80 100644 --- a/drivers/hid/bpf/hid_bpf_dispatch.c +++ b/drivers/hid/bpf/hid_bpf_dispatch.c @@ -376,6 +376,46 @@ hid_bpf_release_context(struct hid_bpf_ctx *ctx) put_device(&hid->dev); } +static int +__hid_bpf_hw_check_params(struct hid_bpf_ctx *ctx, __u8 *buf, size_t *buf__sz, + enum hid_report_type rtype) +{ + struct hid_report_enum *report_enum; + struct hid_report *report; + struct hid_device *hdev; + u32 report_len; + + /* check arguments */ + if (!ctx || !hid_bpf_ops || !buf) + return -EINVAL; + + switch (rtype) { + case HID_INPUT_REPORT: + case HID_OUTPUT_REPORT: + case HID_FEATURE_REPORT: + break; + default: + return -EINVAL; + } + + if (*buf__sz < 1) + return -EINVAL; + + hdev = (struct hid_device *)ctx->hid; /* discard const */ + + report_enum = hdev->report_enum + rtype; + report = hid_bpf_ops->hid_get_report(report_enum, buf); + if (!report) + return -EINVAL; + + report_len = hid_report_len(report); + + if (*buf__sz > report_len) + *buf__sz = report_len; + + return 0; +} + /** * hid_bpf_hw_request - Communicate with a HID device * @@ -392,24 +432,14 @@ hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz, enum hid_report_type rtype, enum hid_class_request reqtype) { struct hid_device *hdev; - struct hid_report *report; - struct hid_report_enum *report_enum; + size_t size = buf__sz; u8 *dma_data; - u32 report_len; int ret; /* check arguments */ - if (!ctx || !hid_bpf_ops || !buf) - return -EINVAL; - - switch (rtype) { - case HID_INPUT_REPORT: - case HID_OUTPUT_REPORT: - case HID_FEATURE_REPORT: - break; - default: - return -EINVAL; - } + ret = __hid_bpf_hw_check_params(ctx, buf, &size, rtype); + if (ret) + return ret; switch (reqtype) { case HID_REQ_GET_REPORT: @@ -423,29 +453,16 @@ hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz, return -EINVAL; } - if (buf__sz < 1) - return -EINVAL; - hdev = (struct hid_device *)ctx->hid; /* discard const */ - report_enum = hdev->report_enum + rtype; - report = hid_bpf_ops->hid_get_report(report_enum, buf); - if (!report) - return -EINVAL; - - report_len = hid_report_len(report); - - if (buf__sz > report_len) - buf__sz = report_len; - - dma_data = kmemdup(buf, buf__sz, GFP_KERNEL); + dma_data = kmemdup(buf, size, GFP_KERNEL); if (!dma_data) return -ENOMEM; ret = hid_bpf_ops->hid_hw_raw_request(hdev, dma_data[0], dma_data, - buf__sz, + size, rtype, reqtype); @@ -455,6 +472,42 @@ hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz, kfree(dma_data); return ret; } + +/** + * hid_bpf_hw_output_report - Send an output report to a HID device + * + * @ctx: the HID-BPF context previously allocated in hid_bpf_allocate_context() + * @buf: a %PTR_TO_MEM buffer + * @buf__sz: the size of the data to transfer + * + * @returns the number of bytes transferred on success, a negative error code otherwise. + */ +__bpf_kfunc int +hid_bpf_hw_output_report(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz) +{ + struct hid_device *hdev; + size_t size = buf__sz; + u8 *dma_data; + int ret; + + /* check arguments */ + ret = __hid_bpf_hw_check_params(ctx, buf, &size, HID_OUTPUT_REPORT); + if (ret) + return ret; + + hdev = (struct hid_device *)ctx->hid; /* discard const */ + + dma_data = kmemdup(buf, size, GFP_KERNEL); + if (!dma_data) + return -ENOMEM; + + ret = hid_bpf_ops->hid_hw_output_report(hdev, + dma_data, + size); + + kfree(dma_data); + return ret; +} __bpf_kfunc_end_defs(); /* @@ -488,6 +541,7 @@ BTF_ID_FLAGS(func, hid_bpf_attach_prog) BTF_ID_FLAGS(func, hid_bpf_allocate_context, KF_ACQUIRE | KF_RET_NULL) BTF_ID_FLAGS(func, hid_bpf_release_context, KF_RELEASE) BTF_ID_FLAGS(func, hid_bpf_hw_request) +BTF_ID_FLAGS(func, hid_bpf_hw_output_report) BTF_KFUNCS_END(hid_bpf_syscall_kfunc_ids) static const struct btf_kfunc_id_set hid_bpf_syscall_kfunc_set = { diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index de7a477d6665..1243595890ba 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -2974,6 +2974,7 @@ EXPORT_SYMBOL_GPL(hid_check_keys_pressed); static struct hid_bpf_ops hid_ops = { .hid_get_report = hid_get_report, .hid_hw_raw_request = hid_hw_raw_request, + .hid_hw_output_report = hid_hw_output_report, .owner = THIS_MODULE, .bus_type = &hid_bus_type, }; diff --git a/include/linux/hid_bpf.h b/include/linux/hid_bpf.h index 7118ac28d468..5c7ff93dc73e 100644 --- a/include/linux/hid_bpf.h +++ b/include/linux/hid_bpf.h @@ -103,6 +103,7 @@ struct hid_bpf_ops { unsigned char reportnum, __u8 *buf, size_t len, enum hid_report_type rtype, enum hid_class_request reqtype); + int (*hid_hw_output_report)(struct hid_device *hdev, __u8 *buf, size_t len); struct module *owner; const struct bus_type *bus_type; }; -- 2.43.0