From patchwork Mon Sep 2 16:14:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Tissoires X-Patchwork-Id: 13787454 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 849C71AB6DB; Mon, 2 Sep 2024 16:15:02 +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=1725293702; cv=none; b=HejMrDLd/DxBlmtET2OH8x1ukEaRfxAeSnt7fRwpsThKeE/vU3LFY96zhXWFfNZ+nbB+83R4INQ49Tr+QByp535JD8w3oTfL33MTUX8Tb9PNAOYP9Muv4R9BhVxkfFs4YpZ47yPF0D6wN8ROcEI7L1lwCJyNEstB5YXJ3g4o1jY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725293702; c=relaxed/simple; bh=SAepiqf5pj0GW3dbl6s8Y9ralJY+FSiywgHt7/u9Iks=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=k9///bxTwNqqdIpjVIuJZx9y/0L20DU12UXTU7V1OI+lYOu628+9zDCcSO2U99g7FOgD4woBTwdggsVLJW2gnd3bBUzC/QHlpmUXGl3ocDE8rl0xKu7mI0uIxdjMaCv2OoxqYg3IAjNy50NUjjMDakpL5Fs5qv+HrWKrQLzqKXc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=l3R4kCJl; 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="l3R4kCJl" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A0F51C4CECA; Mon, 2 Sep 2024 16:14:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1725293702; bh=SAepiqf5pj0GW3dbl6s8Y9ralJY+FSiywgHt7/u9Iks=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=l3R4kCJl3Os1hbrFcJKs+xg2yer3z63pKGoM6ElBi+WzoD54GvlavYhwIUKVsPFXY jmZR7D3DXabIHBFvwQU0zjIo2wODMXfysQSlhZxxoAyLE3ZUOp71XaHmlWl6Hle6aU rTQKJubL72xI5ONxHFRVHqf5qNUd6tzWDS79QVG2EDZkIVzpvoYaI1FW77LZV4jIaE fcyf/vaTwD4S4Fa+PK66EBzNuMQCkp0/o+woUYVp7WOmGGnAOpLsIfYvXpCOLY6hOy x33yEilRGP/kiDQFGUPpdLsiq0ogz/xT5vEDaD3B25IcNQVIwIyUKKDmYs0uF2cLqt zCTLrEq3r2kxw== From: Benjamin Tissoires Date: Tue, 03 Sep 2024 01:14:31 +0900 Subject: [PATCH HID 1/7] selftests/hid: add dependency on hid_common.h Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240903-hid-bpf-hid-generic-v1-1-9511a565b2da@kernel.org> References: <20240903-hid-bpf-hid-generic-v1-0-9511a565b2da@kernel.org> In-Reply-To: <20240903-hid-bpf-hid-generic-v1-0-9511a565b2da@kernel.org> To: Jiri Kosina , Peter Hutterer , Vicki Pfau , Shuah Khan , Jonathan Corbet Cc: linux-input@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, linux-doc@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1725293696; l=827; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=SAepiqf5pj0GW3dbl6s8Y9ralJY+FSiywgHt7/u9Iks=; b=LgetzPyn8o0P+uKkHDVzEJaYqwFqkaJma4QjIwgWjKuzGybMpZvp8uKwffCRGi/ymKZysNX4y rrlztCVuFDtCGkiO/ER8WCoqxtkm8MFCXMXJ/aBVgEGUhqLSUISxS0I X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= Allows to recompile the C tests when that file changes Signed-off-by: Benjamin Tissoires --- tools/testing/selftests/hid/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/hid/Makefile b/tools/testing/selftests/hid/Makefile index 72be55ac4bdf..9399fa3f2f9d 100644 --- a/tools/testing/selftests/hid/Makefile +++ b/tools/testing/selftests/hid/Makefile @@ -229,7 +229,7 @@ $(BPF_SKELS): %.skel.h: %.bpf.o $(BPFTOOL) | $(OUTPUT) $(Q)$(BPFTOOL) gen object $(<:.o=.linked1.o) $< $(Q)$(BPFTOOL) gen skeleton $(<:.o=.linked1.o) name $(notdir $(<:.bpf.o=)) > $@ -$(OUTPUT)/%.o: %.c $(BPF_SKELS) +$(OUTPUT)/%.o: %.c $(BPF_SKELS) hid_common.h $(call msg,CC,,$@) $(Q)$(CC) $(CFLAGS) -c $(filter %.c,$^) $(LDLIBS) -o $@ From patchwork Mon Sep 2 16:14:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Tissoires X-Patchwork-Id: 13787455 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 6D5D11AB6DF; Mon, 2 Sep 2024 16:15:05 +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=1725293705; cv=none; b=PUmkY/LnabvQ0p2L1j6yPjqT3dBbl0ZkNvtM39c6L5qaUjUlQYtHJ/Lk23UvtDAnvCbfAkIS6DPZo04zHaPqveQosNtM7C0Vpc33ObK3UzO0lKiHOIM+lhIFqJTxzraD4+OoKbsmN+W0eJoBPXRcWYc2WrSAOwXErfw0rnk2ZRY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725293705; c=relaxed/simple; bh=mjRGj3p2s2+oljV+CNMWj1xafj4TZ81lnS8aFwMgVsg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=oypOUXzRppGCjkPNyvSkgN6TKV+PRnMVXXDJcrVdGOLfuMwIefGd1W4i7kA4o+3lqFvfwc+ruRP1kcRm4Hrze85pPEbC6RbBr85ernu9cYGSw+oP88DZ7QlhPZVoHhRzeqhoYhhik5kmsjefcqbPp5WMELawWyoMx9x4VNoG1+c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=nJJ9wgLL; 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="nJJ9wgLL" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 74992C4CEC8; Mon, 2 Sep 2024 16:15:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1725293705; bh=mjRGj3p2s2+oljV+CNMWj1xafj4TZ81lnS8aFwMgVsg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=nJJ9wgLLFlPoc61A46ehkkq0VCBuv6SoOSlDn9OI5HB4vYVkYmTZRrbANCjky55Qv N4O/BCSrq+WQUMwheJATZgn3crId5ti1vdmYuNkQPbWj75Hg48S5vhG16weKDlnbNd FHhJB3Wz0evzSgIzSxB5bJ/syDL6eJ0//QN7oFqGDuRASX6m4fW7mJOYz4Bmyx5Fje e80y38B3kuU9KP9FnRzBWVLhCG+2fdyd/qotesnGTdi7tpguH9j3Q0hyk+pPgMk75j i/avJalMlzJmgnvv1K7ikNaao8WZHLmdJeDmH4uVMGOmksb3wotebj3AJLq+KHML4x 1iFbKVO6QrhAQ== From: Benjamin Tissoires Date: Tue, 03 Sep 2024 01:14:32 +0900 Subject: [PATCH HID 2/7] selftests/hid: cleanup C tests by adding a common struct uhid_device Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240903-hid-bpf-hid-generic-v1-2-9511a565b2da@kernel.org> References: <20240903-hid-bpf-hid-generic-v1-0-9511a565b2da@kernel.org> In-Reply-To: <20240903-hid-bpf-hid-generic-v1-0-9511a565b2da@kernel.org> To: Jiri Kosina , Peter Hutterer , Vicki Pfau , Shuah Khan , Jonathan Corbet Cc: linux-input@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, linux-doc@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1725293696; l=15716; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=mjRGj3p2s2+oljV+CNMWj1xafj4TZ81lnS8aFwMgVsg=; b=+x/yILga/SXAm5rD64HtuOU2momg8/7CwvN3bp9KMjTE1U4QH60FnNUp8LSAwq8SOhQIRXaEI CVgXoG6lGUEBSQDWHzzCm8ffPrly5DckZRx0o8mQZm9faMyWhTkN6Qj X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= Allows to have an abstract class uhid_device which handles all of the uhid part without having to mess up with individual fds. struct attach_prog_args is now never used in hid_bpf.c, so drop it as well Signed-off-by: Benjamin Tissoires --- tools/testing/selftests/hid/hid_bpf.c | 77 +++++++++++--------------------- tools/testing/selftests/hid/hid_common.h | 74 ++++++++++++++++++++---------- tools/testing/selftests/hid/hidraw.c | 36 +++++---------- 3 files changed, 87 insertions(+), 100 deletions(-) diff --git a/tools/testing/selftests/hid/hid_bpf.c b/tools/testing/selftests/hid/hid_bpf.c index d10cf6883683..17ccbf5ff4b5 100644 --- a/tools/testing/selftests/hid/hid_bpf.c +++ b/tools/testing/selftests/hid/hid_bpf.c @@ -4,13 +4,6 @@ #include "hid_common.h" #include -struct attach_prog_args { - int prog_fd; - unsigned int hid; - int retval; - int insert_head; -}; - struct hid_hw_request_syscall_args { __u8 data[10]; unsigned int hid; @@ -21,11 +14,8 @@ struct hid_hw_request_syscall_args { }; FIXTURE(hid_bpf) { - int dev_id; - int uhid_fd; + struct uhid_device hid; int hidraw_fd; - int hid_id; - pthread_t tid; struct hid *skel; struct bpf_link *hid_links[3]; /* max number of programs loaded in a single test */ }; @@ -54,10 +44,10 @@ static void detach_bpf(FIXTURE_DATA(hid_bpf) * self) FIXTURE_TEARDOWN(hid_bpf) { void *uhid_err; - uhid_destroy(_metadata, self->uhid_fd); + uhid_destroy(_metadata, &self->hid); detach_bpf(self); - pthread_join(self->tid, &uhid_err); + pthread_join(self->hid.tid, &uhid_err); } #define TEARDOWN_LOG(fmt, ...) do { \ TH_LOG(fmt, ##__VA_ARGS__); \ @@ -66,23 +56,10 @@ FIXTURE_TEARDOWN(hid_bpf) { FIXTURE_SETUP(hid_bpf) { - time_t t; int err; - /* initialize random number generator */ - srand((unsigned int)time(&t)); - - self->dev_id = rand() % 1024; - - self->uhid_fd = setup_uhid(_metadata, self->dev_id); - - /* locate the uev, self, variant);ent file of the created device */ - self->hid_id = get_hid_id(self->dev_id); - ASSERT_GT(self->hid_id, 0) - TEARDOWN_LOG("Could not locate uhid device id: %d", self->hid_id); - - err = uhid_start_listener(_metadata, &self->tid, self->uhid_fd); - ASSERT_EQ(0, err) TEARDOWN_LOG("could not start udev listener: %d", err); + err = setup_uhid(_metadata, &self->hid); + ASSERT_OK(err); } struct test_program { @@ -129,7 +106,7 @@ static void load_programs(const struct test_program programs[], ops_hid_id = bpf_map__initial_value(map, NULL); ASSERT_OK_PTR(ops_hid_id) TH_LOG("unable to retrieve struct_ops data"); - *ops_hid_id = self->hid_id; + *ops_hid_id = self->hid.hid_id; } /* we disable the auto-attach feature of all maps because we @@ -157,7 +134,7 @@ static void load_programs(const struct test_program programs[], hid__attach(self->skel); - self->hidraw_fd = open_hidraw(self->dev_id); + self->hidraw_fd = open_hidraw(&self->hid); ASSERT_GE(self->hidraw_fd, 0) TH_LOG("open_hidraw"); } @@ -192,7 +169,7 @@ TEST_F(hid_bpf, raw_event) /* inject one event */ buf[0] = 1; buf[1] = 42; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); /* check that hid_first_event() was executed */ ASSERT_EQ(self->skel->data->callback_check, 42) TH_LOG("callback_check1"); @@ -208,7 +185,7 @@ TEST_F(hid_bpf, raw_event) memset(buf, 0, sizeof(buf)); buf[0] = 1; buf[1] = 47; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); /* check that hid_first_event() was executed */ ASSERT_EQ(self->skel->data->callback_check, 47) TH_LOG("callback_check1"); @@ -239,7 +216,7 @@ TEST_F(hid_bpf, subprog_raw_event) /* inject one event */ buf[0] = 1; buf[1] = 42; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); /* read the data from hidraw */ memset(buf, 0, sizeof(buf)); @@ -252,7 +229,7 @@ TEST_F(hid_bpf, subprog_raw_event) memset(buf, 0, sizeof(buf)); buf[0] = 1; buf[1] = 47; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); /* read the data from hidraw */ memset(buf, 0, sizeof(buf)); @@ -303,7 +280,7 @@ TEST_F(hid_bpf, test_attach_detach) /* inject one event */ buf[0] = 1; buf[1] = 42; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); /* read the data from hidraw */ memset(buf, 0, sizeof(buf)); @@ -326,14 +303,14 @@ TEST_F(hid_bpf, test_attach_detach) /* detach the program */ detach_bpf(self); - self->hidraw_fd = open_hidraw(self->dev_id); + self->hidraw_fd = open_hidraw(&self->hid); ASSERT_GE(self->hidraw_fd, 0) TH_LOG("open_hidraw"); /* inject another event */ memset(buf, 0, sizeof(buf)); buf[0] = 1; buf[1] = 47; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); /* read the data from hidraw */ memset(buf, 0, sizeof(buf)); @@ -352,7 +329,7 @@ TEST_F(hid_bpf, test_attach_detach) memset(buf, 0, sizeof(buf)); buf[0] = 1; buf[1] = 42; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); /* read the data from hidraw */ memset(buf, 0, sizeof(buf)); @@ -382,7 +359,7 @@ TEST_F(hid_bpf, test_hid_change_report) /* inject one event */ buf[0] = 1; buf[1] = 42; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); /* read the data from hidraw */ memset(buf, 0, sizeof(buf)); @@ -412,7 +389,7 @@ TEST_F(hid_bpf, test_hid_user_input_report_call) LOAD_BPF; - args.hid = self->hid_id; + args.hid = self->hid.hid_id; args.data[0] = 1; /* report ID */ args.data[1] = 2; /* report ID */ args.data[2] = 42; /* report ID */ @@ -458,7 +435,7 @@ TEST_F(hid_bpf, test_hid_user_output_report_call) LOAD_BPF; - args.hid = self->hid_id; + args.hid = self->hid.hid_id; args.data[0] = 1; /* report ID */ args.data[1] = 2; /* report ID */ args.data[2] = 42; /* report ID */ @@ -506,7 +483,7 @@ TEST_F(hid_bpf, test_hid_user_raw_request_call) LOAD_BPF; - args.hid = self->hid_id; + args.hid = self->hid.hid_id; args.data[0] = 1; /* report ID */ prog_fd = bpf_program__fd(self->skel->progs.hid_user_raw_request); @@ -539,7 +516,7 @@ TEST_F(hid_bpf, test_hid_filter_raw_request_call) /* inject one event */ buf[0] = 1; buf[1] = 42; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); /* read the data from hidraw */ memset(buf, 0, sizeof(buf)); @@ -565,7 +542,7 @@ TEST_F(hid_bpf, test_hid_filter_raw_request_call) /* detach the program */ detach_bpf(self); - self->hidraw_fd = open_hidraw(self->dev_id); + self->hidraw_fd = open_hidraw(&self->hid); ASSERT_GE(self->hidraw_fd, 0) TH_LOG("open_hidraw"); err = ioctl(self->hidraw_fd, HIDIOCGFEATURE(sizeof(buf)), buf); @@ -641,7 +618,7 @@ TEST_F(hid_bpf, test_hid_filter_output_report_call) /* inject one event */ buf[0] = 1; buf[1] = 42; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); /* read the data from hidraw */ memset(buf, 0, sizeof(buf)); @@ -667,7 +644,7 @@ TEST_F(hid_bpf, test_hid_filter_output_report_call) /* detach the program */ detach_bpf(self); - self->hidraw_fd = open_hidraw(self->dev_id); + self->hidraw_fd = open_hidraw(&self->hid); ASSERT_GE(self->hidraw_fd, 0) TH_LOG("open_hidraw"); err = write(self->hidraw_fd, buf, 3); @@ -742,7 +719,7 @@ TEST_F(hid_bpf, test_multiply_events_wq) /* inject one event */ buf[0] = 1; buf[1] = 42; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); /* read the data from hidraw */ memset(buf, 0, sizeof(buf)); @@ -780,7 +757,7 @@ TEST_F(hid_bpf, test_multiply_events) /* inject one event */ buf[0] = 1; buf[1] = 42; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); /* read the data from hidraw */ memset(buf, 0, sizeof(buf)); @@ -816,7 +793,7 @@ TEST_F(hid_bpf, test_hid_infinite_loop_input_report_call) buf[1] = 2; buf[2] = 42; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); /* read the data from hidraw */ memset(buf, 0, sizeof(buf)); @@ -867,7 +844,7 @@ TEST_F(hid_bpf, test_hid_attach_flags) /* inject one event */ buf[0] = 1; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); /* read the data from hidraw */ memset(buf, 0, sizeof(buf)); diff --git a/tools/testing/selftests/hid/hid_common.h b/tools/testing/selftests/hid/hid_common.h index f151f151a1ed..a7d836a35bb1 100644 --- a/tools/testing/selftests/hid/hid_common.h +++ b/tools/testing/selftests/hid/hid_common.h @@ -19,6 +19,13 @@ __typeof__(b) _b = (b); \ _a < _b ? _a : _b; }) +struct uhid_device { + int dev_id; /* uniq (random) number to identify the device */ + int uhid_fd; + int hid_id; /* HID device id in the system */ + pthread_t tid; /* thread for reading uhid events */ +}; + static unsigned char rdesc[] = { 0x06, 0x00, 0xff, /* Usage Page (Vendor Defined Page 1) */ 0x09, 0x21, /* Usage (Vendor Usage 0x21) */ @@ -146,14 +153,14 @@ static int uhid_create(struct __test_metadata *_metadata, int fd, int rand_nb) return uhid_write(_metadata, fd, &ev); } -static void uhid_destroy(struct __test_metadata *_metadata, int fd) +static void uhid_destroy(struct __test_metadata *_metadata, struct uhid_device *hid) { struct uhid_event ev; memset(&ev, 0, sizeof(ev)); ev.type = UHID_DESTROY; - uhid_write(_metadata, fd, &ev); + uhid_write(_metadata, hid->uhid_fd, &ev); } static int uhid_event(struct __test_metadata *_metadata, int fd) @@ -281,7 +288,8 @@ static int uhid_start_listener(struct __test_metadata *_metadata, pthread_t *tid return 0; } -static int uhid_send_event(struct __test_metadata *_metadata, int fd, __u8 *buf, size_t size) +static int uhid_send_event(struct __test_metadata *_metadata, struct uhid_device *hid, + __u8 *buf, size_t size) { struct uhid_event ev; @@ -294,25 +302,7 @@ static int uhid_send_event(struct __test_metadata *_metadata, int fd, __u8 *buf, memcpy(ev.u.input2.data, buf, size); - return uhid_write(_metadata, fd, &ev); -} - -static int setup_uhid(struct __test_metadata *_metadata, int rand_nb) -{ - int fd; - const char *path = "/dev/uhid"; - int ret; - - fd = open(path, O_RDWR | O_CLOEXEC); - ASSERT_GE(fd, 0) TH_LOG("open uhid-cdev failed; %d", fd); - - ret = uhid_create(_metadata, fd, rand_nb); - ASSERT_EQ(0, ret) { - TH_LOG("create uhid device failed: %d", ret); - close(fd); - } - - return fd; + return uhid_write(_metadata, hid->uhid_fd, &ev); } static bool match_sysfs_device(int dev_id, const char *workdir, struct dirent *dir) @@ -421,12 +411,12 @@ static int get_hidraw(int dev_id) return found; } -static int open_hidraw(int dev_id) +static int open_hidraw(struct uhid_device *hid) { int hidraw_number; char hidraw_path[64] = { 0 }; - hidraw_number = get_hidraw(dev_id); + hidraw_number = get_hidraw(hid->dev_id); if (hidraw_number < 0) return hidraw_number; @@ -434,3 +424,39 @@ static int open_hidraw(int dev_id) sprintf(hidraw_path, "/dev/hidraw%d", hidraw_number); return open(hidraw_path, O_RDWR | O_NONBLOCK); } + +static int setup_uhid(struct __test_metadata *_metadata, struct uhid_device *hid) +{ + const char *path = "/dev/uhid"; + time_t t; + int ret; + + /* initialize random number generator */ + srand((unsigned int)time(&t)); + + hid->dev_id = rand() % 1024; + + hid->uhid_fd = open(path, O_RDWR | O_CLOEXEC); + ASSERT_GE(hid->uhid_fd, 0) TH_LOG("open uhid-cdev failed; %d", hid->uhid_fd); + + ret = uhid_create(_metadata, hid->uhid_fd, hid->dev_id); + ASSERT_EQ(0, ret) { + TH_LOG("create uhid device failed: %d", ret); + close(hid->uhid_fd); + return ret; + } + + /* locate the uevent file of the created device */ + hid->hid_id = get_hid_id(hid->dev_id); + ASSERT_GT(hid->hid_id, 0) + TH_LOG("Could not locate uhid device id: %d", hid->hid_id); + + ret = uhid_start_listener(_metadata, &hid->tid, hid->uhid_fd); + ASSERT_EQ(0, ret) { + TH_LOG("could not start udev listener: %d", ret); + close(hid->uhid_fd); + return ret; + } + + return 0; +} diff --git a/tools/testing/selftests/hid/hidraw.c b/tools/testing/selftests/hid/hidraw.c index f8b4f7ff292c..5934818b2036 100644 --- a/tools/testing/selftests/hid/hidraw.c +++ b/tools/testing/selftests/hid/hidraw.c @@ -9,11 +9,8 @@ #endif /* HIDIOCREVOKE */ FIXTURE(hidraw) { - int dev_id; - int uhid_fd; + struct uhid_device hid; int hidraw_fd; - int hid_id; - pthread_t tid; }; static void close_hidraw(FIXTURE_DATA(hidraw) * self) { @@ -25,10 +22,10 @@ static void close_hidraw(FIXTURE_DATA(hidraw) * self) FIXTURE_TEARDOWN(hidraw) { void *uhid_err; - uhid_destroy(_metadata, self->uhid_fd); + uhid_destroy(_metadata, &self->hid); close_hidraw(self); - pthread_join(self->tid, &uhid_err); + pthread_join(self->hid.tid, &uhid_err); } #define TEARDOWN_LOG(fmt, ...) do { \ TH_LOG(fmt, ##__VA_ARGS__); \ @@ -37,25 +34,12 @@ FIXTURE_TEARDOWN(hidraw) { FIXTURE_SETUP(hidraw) { - time_t t; int err; - /* initialize random number generator */ - srand((unsigned int)time(&t)); + err = setup_uhid(_metadata, &self->hid); + ASSERT_OK(err); - self->dev_id = rand() % 1024; - - self->uhid_fd = setup_uhid(_metadata, self->dev_id); - - /* locate the uev, self, variant);ent file of the created device */ - self->hid_id = get_hid_id(self->dev_id); - ASSERT_GT(self->hid_id, 0) - TEARDOWN_LOG("Could not locate uhid device id: %d", self->hid_id); - - err = uhid_start_listener(_metadata, &self->tid, self->uhid_fd); - ASSERT_EQ(0, err) TEARDOWN_LOG("could not start udev listener: %d", err); - - self->hidraw_fd = open_hidraw(self->dev_id); + self->hidraw_fd = open_hidraw(&self->hid); ASSERT_GE(self->hidraw_fd, 0) TH_LOG("open_hidraw"); } @@ -79,7 +63,7 @@ TEST_F(hidraw, raw_event) /* inject one event */ buf[0] = 1; buf[1] = 42; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); /* read the data from hidraw */ memset(buf, 0, sizeof(buf)); @@ -101,7 +85,7 @@ TEST_F(hidraw, raw_event_revoked) /* inject one event */ buf[0] = 1; buf[1] = 42; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); /* read the data from hidraw */ memset(buf, 0, sizeof(buf)); @@ -117,7 +101,7 @@ TEST_F(hidraw, raw_event_revoked) /* inject one other event */ buf[0] = 1; buf[1] = 43; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); /* read the data from hidraw */ memset(buf, 0, sizeof(buf)); @@ -161,7 +145,7 @@ TEST_F(hidraw, poll_revoked) /* inject one event */ buf[0] = 1; buf[1] = 42; - uhid_send_event(_metadata, self->uhid_fd, buf, 6); + uhid_send_event(_metadata, &self->hid, buf, 6); while (true) { ready = poll(pfds, 1, 5000); From patchwork Mon Sep 2 16:14:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Tissoires X-Patchwork-Id: 13787456 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 512F41A3054; Mon, 2 Sep 2024 16:15:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725293708; cv=none; b=IdgQNyU21OOpKMKO0I3MMABeE/lA2vWn8qqYoK60rfuaMr4a8GnvMP4/T8ZSmbZZrqWh+/tBvxFO6EZpTpiwBwVWhhBtmx2CoqmEjtL90KhJTvEDfJeRI8Xvr/5uUm435vJY/b7gFSj/ISrL/ygsA0oO3SO7o9wTBi2EaTWEW3o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725293708; c=relaxed/simple; bh=m3oIMhADAyQVl7YG192CntrtfP5ma8pR8cYemrmggas=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=uUjTYN60k3ka5wLJy2fkmhUjFrPc5oG6KoULJgQ/n9+2WHVXyhplJo54+F2BfOVeSw7QBuY0jvhhh1UywbeX932spv95cdo1k8zQ68JVjdTTjfEPioZSxDwfMs4pCEtgwHx/KZLoEdLAJRKSccTRfkaHMPsaewkvucUCfEM293I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=loB/Gxmw; 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="loB/Gxmw" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 70D35C4AF0C; Mon, 2 Sep 2024 16:15:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1725293707; bh=m3oIMhADAyQVl7YG192CntrtfP5ma8pR8cYemrmggas=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=loB/GxmwOtF5z32lB/3pMgIOOo1Af9xpDtR1joh8m7eYujKSGxcHmksk8T8ZXWAp2 tS+rC+AzjngE2js4MJAD25IiypKo0g+bnuAPjxYwKFhbbo9FMi9xFavoaG/xHLXPU3 u2ZVtfqJwZ5clid3HoRIwT2KSW4mu6ZB2DGjyN16q5RCgHdtj99F0GRQeO9t+rPafl FvQtLNjTEeLDcxgrfH88dgTz+c6pYV2YyZ6us+lbaBN7vNtwQfl6J6HCQm4idhnftv a+ZA3WxlC6nJimanwU5iT1MrnWjut96ZXmQuQFiLKR4rdkxERYlCdTStXSXAVr4vvd SaWXYOhjGkbCg== From: Benjamin Tissoires Date: Tue, 03 Sep 2024 01:14:33 +0900 Subject: [PATCH HID 3/7] selftests/hid: allow to parametrize bus/vid/pid/rdesc on the test device Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240903-hid-bpf-hid-generic-v1-3-9511a565b2da@kernel.org> References: <20240903-hid-bpf-hid-generic-v1-0-9511a565b2da@kernel.org> In-Reply-To: <20240903-hid-bpf-hid-generic-v1-0-9511a565b2da@kernel.org> To: Jiri Kosina , Peter Hutterer , Vicki Pfau , Shuah Khan , Jonathan Corbet Cc: linux-input@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, linux-doc@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1725293696; l=6724; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=m3oIMhADAyQVl7YG192CntrtfP5ma8pR8cYemrmggas=; b=9w7NTjxpXke9Lh2zyhCvbNuWEz7EAHjD6CGznUXqa6d93rfQm+R3qsqaxbOjQJ9UNIMQ5CNxl wyVYKW1ottWAmNMMllv54ds4NA068yLcO3DL0hx+0QOYVRI2RJtno0o X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= This will be useful to introduce variants in tests to test the interactions between HID-BPF and some kernel modules. Signed-off-by: Benjamin Tissoires --- tools/testing/selftests/hid/hid_bpf.c | 2 +- tools/testing/selftests/hid/hid_common.h | 46 ++++++++++++++++++++------------ tools/testing/selftests/hid/hidraw.c | 2 +- 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/tools/testing/selftests/hid/hid_bpf.c b/tools/testing/selftests/hid/hid_bpf.c index 17ccbf5ff4b5..7eb15da62bdc 100644 --- a/tools/testing/selftests/hid/hid_bpf.c +++ b/tools/testing/selftests/hid/hid_bpf.c @@ -58,7 +58,7 @@ FIXTURE_SETUP(hid_bpf) { int err; - err = setup_uhid(_metadata, &self->hid); + err = setup_uhid(_metadata, &self->hid, BUS_USB, 0x0001, 0x0a36, rdesc, sizeof(rdesc)); ASSERT_OK(err); } diff --git a/tools/testing/selftests/hid/hid_common.h b/tools/testing/selftests/hid/hid_common.h index a7d836a35bb1..f77f69c6657d 100644 --- a/tools/testing/selftests/hid/hid_common.h +++ b/tools/testing/selftests/hid/hid_common.h @@ -23,6 +23,9 @@ struct uhid_device { int dev_id; /* uniq (random) number to identify the device */ int uhid_fd; int hid_id; /* HID device id in the system */ + __u16 bus; + __u32 vid; + __u32 pid; pthread_t tid; /* thread for reading uhid events */ }; @@ -129,7 +132,9 @@ static int uhid_write(struct __test_metadata *_metadata, int fd, const struct uh } } -static int uhid_create(struct __test_metadata *_metadata, int fd, int rand_nb) +static int uhid_create(struct __test_metadata *_metadata, int fd, int rand_nb, + __u16 bus, __u32 vid, __u32 pid, __u8 *rdesc, + size_t rdesc_size) { struct uhid_event ev; char buf[25]; @@ -140,10 +145,10 @@ static int uhid_create(struct __test_metadata *_metadata, int fd, int rand_nb) ev.type = UHID_CREATE; strcpy((char *)ev.u.create.name, buf); ev.u.create.rd_data = rdesc; - ev.u.create.rd_size = sizeof(rdesc); - ev.u.create.bus = BUS_USB; - ev.u.create.vendor = 0x0001; - ev.u.create.product = 0x0a37; + ev.u.create.rd_size = rdesc_size; + ev.u.create.bus = bus; + ev.u.create.vendor = vid; + ev.u.create.product = pid; ev.u.create.version = 0; ev.u.create.country = 0; @@ -305,15 +310,17 @@ static int uhid_send_event(struct __test_metadata *_metadata, struct uhid_device return uhid_write(_metadata, hid->uhid_fd, &ev); } -static bool match_sysfs_device(int dev_id, const char *workdir, struct dirent *dir) +static bool match_sysfs_device(struct uhid_device *hid, const char *workdir, struct dirent *dir) { - const char *target = "0003:0001:0A37.*"; + char target[20] = ""; char phys[512]; char uevent[1024]; char temp[512]; int fd, nread; bool found = false; + snprintf(target, sizeof(target), "%04X:%04X:%04X.*", hid->bus, hid->vid, hid->pid); + if (fnmatch(target, dir->d_name, 0)) return false; @@ -324,7 +331,7 @@ static bool match_sysfs_device(int dev_id, const char *workdir, struct dirent *d if (fd < 0) return false; - sprintf(phys, "PHYS=%d", dev_id); + sprintf(phys, "PHYS=%d", hid->dev_id); nread = read(fd, temp, ARRAY_SIZE(temp)); if (nread > 0 && (strstr(temp, phys)) != NULL) @@ -335,7 +342,7 @@ static bool match_sysfs_device(int dev_id, const char *workdir, struct dirent *d return found; } -static int get_hid_id(int dev_id) +static int get_hid_id(struct uhid_device *hid) { const char *workdir = "/sys/devices/virtual/misc/uhid"; const char *str_id; @@ -350,10 +357,10 @@ static int get_hid_id(int dev_id) d = opendir(workdir); if (d) { while ((dir = readdir(d)) != NULL) { - if (!match_sysfs_device(dev_id, workdir, dir)) + if (!match_sysfs_device(hid, workdir, dir)) continue; - str_id = dir->d_name + sizeof("0003:0001:0A37."); + str_id = dir->d_name + sizeof("0000:0000:0000."); found = (int)strtol(str_id, NULL, 16); break; @@ -367,7 +374,7 @@ static int get_hid_id(int dev_id) return found; } -static int get_hidraw(int dev_id) +static int get_hidraw(struct uhid_device *hid) { const char *workdir = "/sys/devices/virtual/misc/uhid"; char sysfs[1024]; @@ -384,7 +391,7 @@ static int get_hidraw(int dev_id) continue; while ((dir = readdir(d)) != NULL) { - if (!match_sysfs_device(dev_id, workdir, dir)) + if (!match_sysfs_device(hid, workdir, dir)) continue; sprintf(sysfs, "%s/%s/hidraw", workdir, dir->d_name); @@ -416,7 +423,7 @@ static int open_hidraw(struct uhid_device *hid) int hidraw_number; char hidraw_path[64] = { 0 }; - hidraw_number = get_hidraw(hid->dev_id); + hidraw_number = get_hidraw(hid); if (hidraw_number < 0) return hidraw_number; @@ -425,7 +432,8 @@ static int open_hidraw(struct uhid_device *hid) return open(hidraw_path, O_RDWR | O_NONBLOCK); } -static int setup_uhid(struct __test_metadata *_metadata, struct uhid_device *hid) +static int setup_uhid(struct __test_metadata *_metadata, struct uhid_device *hid, + __u16 bus, __u32 vid, __u32 pid, const __u8 *rdesc, size_t rdesc_size) { const char *path = "/dev/uhid"; time_t t; @@ -435,11 +443,15 @@ static int setup_uhid(struct __test_metadata *_metadata, struct uhid_device *hid srand((unsigned int)time(&t)); hid->dev_id = rand() % 1024; + hid->bus = bus; + hid->vid = vid; + hid->pid = pid; hid->uhid_fd = open(path, O_RDWR | O_CLOEXEC); ASSERT_GE(hid->uhid_fd, 0) TH_LOG("open uhid-cdev failed; %d", hid->uhid_fd); - ret = uhid_create(_metadata, hid->uhid_fd, hid->dev_id); + ret = uhid_create(_metadata, hid->uhid_fd, hid->dev_id, bus, vid, pid, + (__u8 *)rdesc, rdesc_size); ASSERT_EQ(0, ret) { TH_LOG("create uhid device failed: %d", ret); close(hid->uhid_fd); @@ -447,7 +459,7 @@ static int setup_uhid(struct __test_metadata *_metadata, struct uhid_device *hid } /* locate the uevent file of the created device */ - hid->hid_id = get_hid_id(hid->dev_id); + hid->hid_id = get_hid_id(hid); ASSERT_GT(hid->hid_id, 0) TH_LOG("Could not locate uhid device id: %d", hid->hid_id); diff --git a/tools/testing/selftests/hid/hidraw.c b/tools/testing/selftests/hid/hidraw.c index 5934818b2036..821db37ba4bb 100644 --- a/tools/testing/selftests/hid/hidraw.c +++ b/tools/testing/selftests/hid/hidraw.c @@ -36,7 +36,7 @@ FIXTURE_SETUP(hidraw) { int err; - err = setup_uhid(_metadata, &self->hid); + err = setup_uhid(_metadata, &self->hid, BUS_USB, 0x0001, 0x0a37, rdesc, sizeof(rdesc)); ASSERT_OK(err); self->hidraw_fd = open_hidraw(&self->hid); From patchwork Mon Sep 2 16:14:34 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Tissoires X-Patchwork-Id: 13787457 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 A4FF91A305B; Mon, 2 Sep 2024 16:15:10 +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=1725293710; cv=none; b=HAjqqvkAQEyr0e9R0p/tBEu/5UqzHJLoCrpOEFtNoefb7pvm4PFUfLmyQiNfTTkzreaKDlE7zgihDOOD++rS5RlhNUPyH5z8rgwIoXQmrHncbN/6W3L7zA2Hnne8P9I0dQIcaJYM47sIh4u0j+xevjPM42lRQbqIJM7laOh3lcQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725293710; c=relaxed/simple; bh=4umFokG0L8wm/rAylgpeht+x3XKOrOe/Td1BuJUa1yY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=BaJpkh8sunwudgXmPfeQlOwsLBb+FICf4XVLcDjr8qt66fAOxtvzvMKRRpznJQQImaJaskBa3diOpPeFfTMRUXBrCmeBKkSo6ph2P9gqmZ9Fjz25lHxRaRBloo1KfuLej0V7LxQYqMx8lkVuN6xWPDdyskJBiB1B6GRwxCVw0FQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ItGSGR1w; 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="ItGSGR1w" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3C4D6C4CEC2; Mon, 2 Sep 2024 16:15:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1725293710; bh=4umFokG0L8wm/rAylgpeht+x3XKOrOe/Td1BuJUa1yY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=ItGSGR1woKqkGQkEZHGW7dOn8lkq3E9YhC4L+C02eAmo8gbnCo0S4ecE3DEZZcwAS 8md5i+bOcRHRRMGgb5o5hKm614uGWCV6926MjHaHYblqITu/GWSKR3Cs10GqvsHCZ1 mNlM3UWcsSin2g7L0XxdRkib15iADnbteFhmES19CHHJKlbRsbKF0nedzrpqM8iep9 9P/2bRHS30Nu0cv9usWCCrqAt/hLQW30EeGgqNnLySvIMFPFlb4AJDZ/WjQiAoWd7B 7oyGPwpE5Xeau/ggjJQOJDuh8fioLK9TFVDfGcu/S/dOaKABNFFJCySUYiYg0LzPf3 lFxIVEwiXLlQA== From: Benjamin Tissoires Date: Tue, 03 Sep 2024 01:14:34 +0900 Subject: [PATCH HID 4/7] HID: bpf: allow BPF programs to force using hid-generic Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240903-hid-bpf-hid-generic-v1-4-9511a565b2da@kernel.org> References: <20240903-hid-bpf-hid-generic-v1-0-9511a565b2da@kernel.org> In-Reply-To: <20240903-hid-bpf-hid-generic-v1-0-9511a565b2da@kernel.org> To: Jiri Kosina , Peter Hutterer , Vicki Pfau , Shuah Khan , Jonathan Corbet Cc: linux-input@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, linux-doc@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1725293696; l=8001; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=4umFokG0L8wm/rAylgpeht+x3XKOrOe/Td1BuJUa1yY=; b=YbUkm/vww3jheM9bUiSFlhaPQW3omJLmeGneCGbM5fWwIy45f6GWyVKz1RmG4Ow8LNyNnf6At CFgiWveQixEAUQU9RZ35yZ3KrrOQjmK/6PhH7X5gDLhSz9HQRDbBsdC X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= The use case is when we fix a device through HID-BPF, 99% of the cases we want the device to use hid-generic now instead of a dedicated device. That's because the dedicated device might also want to change the report descriptor, or will be handling the device in a different way the new fixed device is using. In hid-core, after matching for the device (so that we only call this new hook on compatible drivers), we call for `.hid_bpf_driver_probe`. The function can not communicate with the device because it is not yet started, but it can make educated guesses and decide to: - let hid-core decide by itself - force the use of this driver (by comparing the provided name with "hid-generic" for instance) - force hid-core to ignore this driver for this device. For API stability, we don't rely on a bitfield or a return value for chosing hid-core behavior. We simply have a couple of writeable fields in the new struct hid_bpf_driver, and then hid-core can make its educated decision. Signed-off-by: Benjamin Tissoires --- Documentation/hid/hid-bpf.rst | 2 +- drivers/hid/bpf/hid_bpf_dispatch.c | 31 ++++++++++++++++++++++++++++ drivers/hid/bpf/hid_bpf_struct_ops.c | 3 +++ drivers/hid/hid-core.c | 6 ++++++ include/linux/hid_bpf.h | 40 ++++++++++++++++++++++++++++++++++++ 5 files changed, 81 insertions(+), 1 deletion(-) diff --git a/Documentation/hid/hid-bpf.rst b/Documentation/hid/hid-bpf.rst index 5939eeafb361..05a43f11cdab 100644 --- a/Documentation/hid/hid-bpf.rst +++ b/Documentation/hid/hid-bpf.rst @@ -190,7 +190,7 @@ User API data structures available in programs: ----------------------------------------------- .. kernel-doc:: include/linux/hid_bpf.h - :identifiers: hid_bpf_ctx + :identifiers: hid_bpf_ctx hid_bpf_driver Available API that can be used in all HID-BPF struct_ops programs: ------------------------------------------------------------------ diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_dispatch.c index a272a086c950..2df136d64152 100644 --- a/drivers/hid/bpf/hid_bpf_dispatch.c +++ b/drivers/hid/bpf/hid_bpf_dispatch.c @@ -189,6 +189,37 @@ u8 *call_hid_bpf_rdesc_fixup(struct hid_device *hdev, u8 *rdesc, unsigned int *s } EXPORT_SYMBOL_GPL(call_hid_bpf_rdesc_fixup); +int call_hid_bpf_driver_probe(struct hid_device *hdev, struct hid_driver *hdrv, + const struct hid_device_id *id) +{ + struct hid_bpf_driver drv = { 0 }; + struct hid_bpf_ops *e; + int idx; + + if (strscpy(drv.name, hdrv->name, sizeof(drv.name)) < 0) + return 0; + + idx = srcu_read_lock(&hdev->bpf.srcu); + list_for_each_entry_srcu(e, &hdev->bpf.prog_list, list, + srcu_read_lock_held(&hdev->bpf.srcu)) { + if (!e->hid_driver_probe) + continue; + + e->hid_driver_probe(hdev, &drv, id); + } + + srcu_read_unlock(&hdev->bpf.srcu, idx); + + if (drv.force_driver) + return 1; + + if (drv.ignore_driver) + return -1; + + return 0; +} +EXPORT_SYMBOL_GPL(call_hid_bpf_driver_probe); + static int device_match_id(struct device *dev, const void *id) { struct hid_device *hdev = to_hid_device(dev); diff --git a/drivers/hid/bpf/hid_bpf_struct_ops.c b/drivers/hid/bpf/hid_bpf_struct_ops.c index cd696c59ba0f..1e13a22f73a1 100644 --- a/drivers/hid/bpf/hid_bpf_struct_ops.c +++ b/drivers/hid/bpf/hid_bpf_struct_ops.c @@ -46,6 +46,7 @@ static int hid_bpf_ops_check_member(const struct btf_type *t, case offsetof(struct hid_bpf_ops, hid_rdesc_fixup): case offsetof(struct hid_bpf_ops, hid_hw_request): case offsetof(struct hid_bpf_ops, hid_hw_output_report): + case offsetof(struct hid_bpf_ops, hid_driver_probe): break; default: if (prog->sleepable) @@ -79,6 +80,8 @@ static int hid_bpf_ops_btf_struct_access(struct bpf_verifier_log *log, WRITE_RANGE(hid_device, name, true), WRITE_RANGE(hid_device, uniq, true), WRITE_RANGE(hid_device, phys, true), + WRITE_RANGE(hid_bpf_driver, force_driver, false), + WRITE_RANGE(hid_bpf_driver, ignore_driver, false), }; #undef WRITE_RANGE const struct btf_type *state = NULL; diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 988d0acbdf04..7845f0a789ec 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -2639,10 +2639,16 @@ static bool hid_check_device_match(struct hid_device *hdev, struct hid_driver *hdrv, const struct hid_device_id **id) { + int ret; + *id = hid_match_device(hdev, hdrv); if (!*id) return false; + ret = call_hid_bpf_driver_probe(hdev, hdrv, *id); + if (ret) + return ret > 0; + if (hdrv->match) return hdrv->match(hdev, hid_ignore_special_drivers); diff --git a/include/linux/hid_bpf.h b/include/linux/hid_bpf.h index d4d063cf63b5..20693c218857 100644 --- a/include/linux/hid_bpf.h +++ b/include/linux/hid_bpf.h @@ -9,6 +9,7 @@ #include struct hid_device; +struct hid_driver; /* * The following is the user facing HID BPF API. @@ -80,6 +81,22 @@ struct hid_ops { extern struct hid_ops *hid_ops; +/** + * struct hid_bpf_driver - User accessible data for the ``hid_bpf_probe`` + * struct_ops + * + * @name: the name of the driver currently being treated + * @force_driver: set this to ``true`` to force hid-core to use this driver, + * bypassing any further decision made by this driver + * @ignore_driver: set this to ``true`` to force hid-core to ignore this driver, + * bypassing any further decision made by this driver + */ +struct hid_bpf_driver { + __u8 name[64]; + bool force_driver; + bool ignore_driver; +}; + /** * struct hid_bpf_ops - A BPF struct_ops of callbacks allowing to attach HID-BPF * programs to a HID device @@ -178,6 +195,25 @@ struct hid_bpf_ops { */ int (*hid_hw_output_report)(struct hid_bpf_ctx *ctx, u64 source); + /** + * @hid_driver_probe: called before the kernel ``.probe()`` function + * + * It has the following arguments: + * + * ``hdev``: The HID device kernel representation + * + * ``hdrv``: A BPF partially writeable representation of a HID driver + * + * ``id``: The device match structure found in the driver + * + * Note that the device has not been started yet, and thus kfuncs like + * ``hid_hw_output_report`` will likely fail. + * + * This function is useful to force/ignore a given supported HID driver, + * by writing ``true`` in ``hdrv->force_driver`` or ``hdrv->ignore_driver`` + */ + void (*hid_driver_probe)(struct hid_device *hdev, struct hid_bpf_driver *hdrv, + const struct hid_device_id *id); /* private: do not show up in the docs */ struct hid_device *hdev; @@ -213,6 +249,8 @@ void hid_bpf_disconnect_device(struct hid_device *hdev); void hid_bpf_destroy_device(struct hid_device *hid); int hid_bpf_device_init(struct hid_device *hid); u8 *call_hid_bpf_rdesc_fixup(struct hid_device *hdev, u8 *rdesc, unsigned int *size); +int call_hid_bpf_driver_probe(struct hid_device *hdev, struct hid_driver *hdrv, + const struct hid_device_id *id); #else /* CONFIG_HID_BPF */ static inline u8 *dispatch_hid_bpf_device_event(struct hid_device *hid, enum hid_report_type type, u8 *data, u32 *size, int interrupt, @@ -228,6 +266,8 @@ static inline int hid_bpf_connect_device(struct hid_device *hdev) { return 0; } static inline void hid_bpf_disconnect_device(struct hid_device *hdev) {} static inline void hid_bpf_destroy_device(struct hid_device *hid) {} static inline int hid_bpf_device_init(struct hid_device *hid) { return 0; } +static inline int call_hid_bpf_driver_probe(struct hid_device *hdev, struct hid_driver *hdrv, + const struct hid_device_id *id) { return 0; } /* * This specialized allocator has to be a macro for its allocations to be * accounted separately (to have a separate alloc_tag). The typecast is From patchwork Mon Sep 2 16:14:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Tissoires X-Patchwork-Id: 13787458 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 705EC1AB6C0; Mon, 2 Sep 2024 16:15:13 +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=1725293713; cv=none; b=giJ7xijiHZ5pycQr5AJKCm5vjoSOS6VYYs9GluhVnx4mTSWXf6HnRY3YGVXIw7HkZXL2qpe7sXmBsBdLy2Kx8jXZoyrOYzvGl/QwLKonsV7L2cJLAllABRsq+tedghYXQ8WARzTQ58lwN5EV5qnmeptBZeSefSDlLH0qiVFcMVA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725293713; c=relaxed/simple; bh=bCMnwRpHi66cFH/lCsEid/oKr2HghP0ARsPCue09C2M=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Bynj1YEbs6EHDOxTLcfBVooRMQ4ULxj1OI3dsScaNV/xnzt2TNSJa866ngIeS1kQwvZEfJoy3ZtsgVtdRsX1BoZJF4UqxSKTvUIGZ6WOOuJ9LuPiCmSlBc8DbTm+VJ7DER6qk6fEDiLTEbMlZFwVtYaFiewg5MGOMJrbYhDd9Vg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hiogrxRF; 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="hiogrxRF" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 07DD0C4CEC2; Mon, 2 Sep 2024 16:15:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1725293713; bh=bCMnwRpHi66cFH/lCsEid/oKr2HghP0ARsPCue09C2M=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=hiogrxRFyn8vQQfhGNJ/drW4qbwWXwEEu+Dd5WhXG6olMKDiFN8hf7mfXh716j+Nt pZEadSoeHP7P01LgCx6sxgA0v14AgoOSB+CVNLP2gPDxIuASdkeC2n7VH7Lyi77SCJ 77HABY9Yw1XdmFAM3pceLtWlbIueNanAlWwEqoWC6Cg6e+4uWJSir6Y4Sk7pRKTAiP o2Wzl+sPcsH/mkO8HXePqQu6OQUARzsSWNYBLjW2Akkv4BfId6967yJJd8QgdPWL5L p1nPkDDxZuW0ROzghllns9AwjWRsI068jmIAl3H6AY5UaTOcvyINeP2umSOk2ou9TB 2cFwtmVG5CGjw== From: Benjamin Tissoires Date: Tue, 03 Sep 2024 01:14:35 +0900 Subject: [PATCH HID 5/7] selftests/hid: add test for assigning a given device to hid-generic Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240903-hid-bpf-hid-generic-v1-5-9511a565b2da@kernel.org> References: <20240903-hid-bpf-hid-generic-v1-0-9511a565b2da@kernel.org> In-Reply-To: <20240903-hid-bpf-hid-generic-v1-0-9511a565b2da@kernel.org> To: Jiri Kosina , Peter Hutterer , Vicki Pfau , Shuah Khan , Jonathan Corbet Cc: linux-input@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, linux-doc@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1725293696; l=5135; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=bCMnwRpHi66cFH/lCsEid/oKr2HghP0ARsPCue09C2M=; b=Fq51Mhtp6XwSlsUtSdLSeedwjleE6cg3NOpcXRnxuSFQIC9FgLEV+4LSzRgH15TeB4rKXfyLB aKDVQtAT9jOAOS8f2qq1Ec0OJv/wWjgaml16hs+DactyKIIezB33DVF X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= We use a well known VID/PID on a driver that doesn't need to talk to the device, ensures we created the device against the target driver, then load our program and ensure we have unbound to this driver and use hid-generic instead. Signed-off-by: Benjamin Tissoires --- tools/testing/selftests/hid/hid_bpf.c | 80 +++++++++++++++++++++- tools/testing/selftests/hid/progs/hid.c | 29 ++++++++ .../testing/selftests/hid/progs/hid_bpf_helpers.h | 2 + 3 files changed, 110 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/hid/hid_bpf.c b/tools/testing/selftests/hid/hid_bpf.c index 7eb15da62bdc..edc061b38528 100644 --- a/tools/testing/selftests/hid/hid_bpf.c +++ b/tools/testing/selftests/hid/hid_bpf.c @@ -54,11 +54,41 @@ FIXTURE_TEARDOWN(hid_bpf) { hid_bpf_teardown(_metadata, self, variant); \ } while (0) +struct specific_device { + const char test_name[64]; + __u16 bus; + __u32 vid; + __u32 pid; +}; + FIXTURE_SETUP(hid_bpf) { + const struct specific_device *match = NULL; int err; - err = setup_uhid(_metadata, &self->hid, BUS_USB, 0x0001, 0x0a36, rdesc, sizeof(rdesc)); + const struct specific_device devices[] = { + { + .test_name = "test_hid_driver_probe", + .bus = BUS_BLUETOOTH, + .vid = 0x05ac, /* USB_VENDOR_ID_APPLE */ + .pid = 0x022c, /* USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI */ + }, { + .test_name = "*", + .bus = BUS_USB, + .vid = 0x0001, + .pid = 0x0a36, + }}; + + for (int i = 0; i < ARRAY_SIZE(devices); i++) { + match = &devices[i]; + if (!strncmp(_metadata->name, devices[i].test_name, sizeof(devices[i].test_name))) + break; + } + + ASSERT_OK_PTR(match); + + err = setup_uhid(_metadata, &self->hid, match->bus, match->vid, match->pid, + rdesc, sizeof(rdesc)); ASSERT_OK(err); } @@ -855,6 +885,54 @@ TEST_F(hid_bpf, test_hid_attach_flags) ASSERT_EQ(buf[3], 3); } +static bool is_using_driver(struct __test_metadata *_metadata, struct uhid_device *hid, + const char *driver) +{ + char driver_line[512]; + char uevent[1024]; + char temp[512]; + int fd, nread; + bool found = false; + + sprintf(uevent, "/sys/bus/hid/devices/%04X:%04X:%04X.%04X/uevent", + hid->bus, hid->vid, hid->pid, hid->hid_id); + + fd = open(uevent, O_RDONLY | O_NONBLOCK); + if (fd < 0) { + TH_LOG("couldn't open '%s': %d, %d", uevent, fd, errno); + return false; + } + + sprintf(driver_line, "DRIVER=%s", driver); + + nread = read(fd, temp, ARRAY_SIZE(temp)); + if (nread > 0 && (strstr(temp, driver_line)) != NULL) + found = true; + + close(fd); + + return found; +} + +/* + * Attach hid_driver_probe to the given uhid device, + * check that the device is now using hid-generic. + */ +TEST_F(hid_bpf, test_hid_driver_probe) +{ + const struct test_program progs[] = { + { + .name = "hid_test_driver_probe", + }, + }; + + ASSERT_TRUE(is_using_driver(_metadata, &self->hid, "apple")); + + LOAD_PROGRAMS(progs); + + ASSERT_TRUE(is_using_driver(_metadata, &self->hid, "hid-generic")); +} + /* * Attach hid_rdesc_fixup to the given uhid device, * retrieve and open the matching hidraw node, diff --git a/tools/testing/selftests/hid/progs/hid.c b/tools/testing/selftests/hid/progs/hid.c index 5ecc845ef792..883d09498351 100644 --- a/tools/testing/selftests/hid/progs/hid.c +++ b/tools/testing/selftests/hid/progs/hid.c @@ -598,3 +598,32 @@ SEC(".struct_ops.link") struct hid_bpf_ops test_infinite_loop_input_report = { .hid_device_event = (void *)hid_test_infinite_loop_input_report, }; + +SEC("?struct_ops/hid_driver_probe") +void BPF_PROG(hid_test_driver_probe, struct hid_device *hdev, struct hid_bpf_driver *hdrv, + struct hid_device_id *id) +{ + static const char hid_generic[] = "hid-generic"; + + bpf_printk("test_driver_probe, %s", hdrv->name); + if (!__builtin_memcmp(hdrv->name, hid_generic, sizeof(hid_generic))) + hdrv->force_driver = 1; + else + hdrv->ignore_driver = 1; +} + +SEC("?struct_ops.s/hid_rdesc_fixup") +int BPF_PROG(hid_rdesc_fixup_2, struct hid_bpf_ctx *hid_ctx) +{ + /* + * We need an empty report descriptor fixup to force detach/reattach + * the device when we load the BPF program. + */ + return 0; +} + +SEC(".struct_ops.link") +struct hid_bpf_ops test_driver_probe = { + .hid_driver_probe = (void *)hid_test_driver_probe, + .hid_rdesc_fixup = (void *)hid_rdesc_fixup_2, +}; diff --git a/tools/testing/selftests/hid/progs/hid_bpf_helpers.h b/tools/testing/selftests/hid/progs/hid_bpf_helpers.h index e5db897586bb..6b0f870d0727 100644 --- a/tools/testing/selftests/hid/progs/hid_bpf_helpers.h +++ b/tools/testing/selftests/hid/progs/hid_bpf_helpers.h @@ -81,6 +81,8 @@ struct hid_bpf_ops { enum hid_report_type rtype, enum hid_class_request reqtype, u64 source); int (*hid_hw_output_report)(struct hid_bpf_ctx *ctx, u64 source); + void (*hid_driver_probe)(struct hid_device *hdev, struct hid_bpf_driver *hdrv, + struct hid_device_id *id); struct hid_device *hdev; }; From patchwork Mon Sep 2 16:14:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Tissoires X-Patchwork-Id: 13787459 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 AE3CB1AB6CD; Mon, 2 Sep 2024 16:15:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725293716; cv=none; b=t3cVv2Xj3BPsG+3bb0b9yPXfhpKb4lYNF29+bbB9LSTaWf3k1RYrwzYXi9YywHBwxeLSgrqI53C4+h5U4Ju0GsuXF5N+vrlmuE6m2MZ86AB/LdppszyAtnIxI33X8+24H6L2SWS+re1c653xeBRUKVapNNCflLC+K14Fv77JCqY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725293716; c=relaxed/simple; bh=XMF4tyjgQTZmmDwd1PZu42vm+Z1+DNVxea8aQd/u1RQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=rCApBgNrmFtv4Kv4Kva870Wql6ZO01nmvCywab8LbCWrsr2U7RY3dwQlfddnyoA3Of/ObYGDIWYNaJAEeaF7i9J5iUuOrm7Fxu1f05DhdkaGYKgcertxFc1KBWwP468hruo29eW2uirMwwtVo8TqW/sZw2nX9EZTNMqU7OhjJMM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Tc5rwWph; 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="Tc5rwWph" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C7FB8C4CEC4; Mon, 2 Sep 2024 16:15:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1725293716; bh=XMF4tyjgQTZmmDwd1PZu42vm+Z1+DNVxea8aQd/u1RQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Tc5rwWphxCyI28z4DRwWHG+TL1iqLOFJggafMwQOoI6j4rhVEqb+NFDH5YE4RGyz2 xhFq+07M8IcFXyAJpBK76PnElq6bDDy7xLsNyiENdXa5AesbQEPjKi0Y9UMZyVSuXt H+9xoE9plzwMa4cnTbgnt6g/yhx+bic0KQlf2Bey0rZhgchxccYwCwKNsqEJyEYvFP +G3gEzAFY5+1p4+TFkrrcWTARlvqPViWoWdAit6K7mAMuN7Z+S0rOMX1+SuZWef1/3 vOEWDzLFxAM69ciAXkyvf/F76xQhjyYwHNOnpd9P75RMxpoPMq470hJ1fFi56WUN5T ReC8++PGgB99g== From: Benjamin Tissoires Date: Tue, 03 Sep 2024 01:14:36 +0900 Subject: [PATCH HID 6/7] HID: bpf: Allow to control the connect mask of hid-generic from BPF Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240903-hid-bpf-hid-generic-v1-6-9511a565b2da@kernel.org> References: <20240903-hid-bpf-hid-generic-v1-0-9511a565b2da@kernel.org> In-Reply-To: <20240903-hid-bpf-hid-generic-v1-0-9511a565b2da@kernel.org> To: Jiri Kosina , Peter Hutterer , Vicki Pfau , Shuah Khan , Jonathan Corbet Cc: linux-input@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, linux-doc@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1725293696; l=3583; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=XMF4tyjgQTZmmDwd1PZu42vm+Z1+DNVxea8aQd/u1RQ=; b=WDKNwNUxU5NH071omL+ADXlWlicmd4sE9+4iMgORKVSh4qt/QwemvY3k4tvaY2auD2g952VNF B86i6pNs6QEBjqtG7cD+jQMY6aHjyIK0FvynZ7s0ylHXNXSq9q2DnSg X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= We make struct hid_device_id writeable and use the .driver_data field of hid-generic as the connect mask. This way, we can control from a HID-BPF program if a device needs to be exported through hidraw and/or hid-input mainly. This is useful in case we want to have a third party program that directly talks to the hidraw node and we don't want regular input events to be emitted. This third party program can load a BPF program that instructs hid-generic to rebind on the device with hidraw only and then open the hidraw node itself. When the application is closed, the BPF program is unloaded and the normal driver takes back the control of the device. Signed-off-by: Benjamin Tissoires --- drivers/hid/bpf/hid_bpf_struct_ops.c | 1 + drivers/hid/hid-core.c | 14 ++++++++------ drivers/hid/hid-generic.c | 5 +++-- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/hid/bpf/hid_bpf_struct_ops.c b/drivers/hid/bpf/hid_bpf_struct_ops.c index 1e13a22f73a1..bb755edd02f0 100644 --- a/drivers/hid/bpf/hid_bpf_struct_ops.c +++ b/drivers/hid/bpf/hid_bpf_struct_ops.c @@ -80,6 +80,7 @@ static int hid_bpf_ops_btf_struct_access(struct bpf_verifier_log *log, WRITE_RANGE(hid_device, name, true), WRITE_RANGE(hid_device, uniq, true), WRITE_RANGE(hid_device, phys, true), + WRITE_RANGE(hid_device_id, driver_data, false), WRITE_RANGE(hid_bpf_driver, force_driver, false), WRITE_RANGE(hid_bpf_driver, ignore_driver, false), }; diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 7845f0a789ec..2bd279b23aa4 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -2637,15 +2637,17 @@ EXPORT_SYMBOL_GPL(hid_compare_device_paths); static bool hid_check_device_match(struct hid_device *hdev, struct hid_driver *hdrv, - const struct hid_device_id **id) + struct hid_device_id *id) { + const struct hid_device_id *_id = hid_match_device(hdev, hdrv); int ret; - *id = hid_match_device(hdev, hdrv); - if (!*id) + if (!_id) return false; - ret = call_hid_bpf_driver_probe(hdev, hdrv, *id); + memcpy(id, _id, sizeof(*id)); + + ret = call_hid_bpf_driver_probe(hdev, hdrv, id); if (ret) return ret > 0; @@ -2662,7 +2664,7 @@ static bool hid_check_device_match(struct hid_device *hdev, static int __hid_device_probe(struct hid_device *hdev, struct hid_driver *hdrv) { - const struct hid_device_id *id; + struct hid_device_id id; int ret; if (!hid_check_device_match(hdev, hdrv, &id)) @@ -2677,7 +2679,7 @@ static int __hid_device_probe(struct hid_device *hdev, struct hid_driver *hdrv) hdev->driver = hdrv; if (hdrv->probe) { - ret = hdrv->probe(hdev, id); + ret = hdrv->probe(hdev, &id); } else { /* default probe */ ret = hid_open_report(hdev); if (!ret) diff --git a/drivers/hid/hid-generic.c b/drivers/hid/hid-generic.c index f9db991d3c5a..5cd1f3a79a4b 100644 --- a/drivers/hid/hid-generic.c +++ b/drivers/hid/hid-generic.c @@ -64,11 +64,12 @@ static int hid_generic_probe(struct hid_device *hdev, if (ret) return ret; - return hid_hw_start(hdev, HID_CONNECT_DEFAULT); + return hid_hw_start(hdev, id->driver_data); } static const struct hid_device_id hid_table[] = { - { HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, HID_ANY_ID, HID_ANY_ID) }, + { HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, HID_ANY_ID, HID_ANY_ID), + .driver_data = HID_CONNECT_DEFAULT }, { } }; MODULE_DEVICE_TABLE(hid, hid_table); From patchwork Mon Sep 2 16:14:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Tissoires X-Patchwork-Id: 13787460 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 BC79D21C16D; Mon, 2 Sep 2024 16:15:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725293719; cv=none; b=iSX8gJ4ZoIzA1Od9XCSZyQMIqez4vFj4cM0ZYm+thnkCtqb5FvNZNjK78rZHirUpcoujBbI1r2GQ7yZQPcac6Z6pNvGV8Uzn1M4iQCTUX+UzSyuX7ke0cImfAIn+CbSa8PYf6sZu6meWxV1uTG7H89SuT5wcTybgEsAMt/19f1Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725293719; c=relaxed/simple; bh=xtOdecYiKB5InvoL/YSqFAGZREGEyiVcgfttpziwedM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=HoSaIqk94GMV59VwSEGSnlu0tZNFkjx72hREJVeUw7cH3mlKcc+8GmH0jeUIIJ6282OTukElz79sRfKytz4NJqCzBxMWZJn8HQ+gHORly5wfuFStPaqujza1xHUd802xQZyIRbqtigkf5cXMhCWIQnDNbD0bEZXuoRBzow0LaOQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=X9J9lYBA; 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="X9J9lYBA" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9320FC4CECB; Mon, 2 Sep 2024 16:15:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1725293718; bh=xtOdecYiKB5InvoL/YSqFAGZREGEyiVcgfttpziwedM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=X9J9lYBA64rSQShxUiGuKSRL22BP/KcyYHeJ5LlD2d+U3JbXJX4HphKInc20le8Ct D5ZMVkcnyKVO+XiEz092j1U/7VIxyKQIduc8SwwcNJWueU3YY4lwvllhMbwd3eAKPf 98Ap58Z5HS05CBvnARK1iGnssmA7ixbC/6zKKDxGt8K1rt64G5YjFegiY1zPNKxmmd 81mHjaRVGHegi9VIOMXOT4VqFQ4z1BvaTpwdyxN5SUdtGlpNKR+b7563Z5tYDnaMOE l5/W8755n6N1X0sskiFjSlO9ek5mN551rKf+YHlrKRiBMTC2BbUix6PfxksYeigTDb 8luG5fGEGdxHQ== From: Benjamin Tissoires Date: Tue, 03 Sep 2024 01:14:37 +0900 Subject: [PATCH HID 7/7] selftests/hid: add test to disable hid-input Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240903-hid-bpf-hid-generic-v1-7-9511a565b2da@kernel.org> References: <20240903-hid-bpf-hid-generic-v1-0-9511a565b2da@kernel.org> In-Reply-To: <20240903-hid-bpf-hid-generic-v1-0-9511a565b2da@kernel.org> To: Jiri Kosina , Peter Hutterer , Vicki Pfau , Shuah Khan , Jonathan Corbet Cc: linux-input@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, linux-doc@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.14.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1725293696; l=5770; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=xtOdecYiKB5InvoL/YSqFAGZREGEyiVcgfttpziwedM=; b=GE/tgxdBkatX9tmF7AXHOU/jlAbMce5qGP3SxP2mtW5A9+4VoYudbDiOQAuLD+ESHP/ByppSx eeIohiS/C/ADzvR+NR2IhXu7ICiStGPD39RAaNnmcWow5MdY5GSG6eQ X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= Add a test for the newly enabled feature to control the connect_mask of hid-generic. Signed-off-by: Benjamin Tissoires --- tools/testing/selftests/hid/hid_bpf.c | 60 +++++++++++++++++++++- tools/testing/selftests/hid/progs/hid.c | 6 ++- .../testing/selftests/hid/progs/hid_bpf_helpers.h | 2 + 3 files changed, 65 insertions(+), 3 deletions(-) diff --git a/tools/testing/selftests/hid/hid_bpf.c b/tools/testing/selftests/hid/hid_bpf.c index edc061b38528..41cacc30ef8b 100644 --- a/tools/testing/selftests/hid/hid_bpf.c +++ b/tools/testing/selftests/hid/hid_bpf.c @@ -4,6 +4,38 @@ #include "hid_common.h" #include +static const __u8 mouse_rdesc[] = { + 0x05, 0x01, /* .Usage Page (Generic Desktop) 0 */ + 0x09, 0x02, /* .Usage (Mouse) 2 */ + 0xa1, 0x01, /* .Collection (Application) 4 */ + 0x09, 0x02, /* ..Usage (Mouse) 6 */ + 0xa1, 0x02, /* ..Collection (Logical) 8 */ + 0x09, 0x01, /* ...Usage (Pointer) 10 */ + 0xa1, 0x00, /* ...Collection (Physical) 12 */ + 0x05, 0x09, /* ....Usage Page (Button) 14 */ + 0x19, 0x01, /* ....Usage Minimum (1) 16 */ + 0x29, 0x03, /* ....Usage Maximum (3) 18 */ + 0x15, 0x00, /* ....Logical Minimum (0) 20 */ + 0x25, 0x01, /* ....Logical Maximum (1) 22 */ + 0x75, 0x01, /* ....Report Size (1) 24 */ + 0x95, 0x03, /* ....Report Count (3) 26 */ + 0x81, 0x02, /* ....Input (Data,Var,Abs) 28 */ + 0x75, 0x05, /* ....Report Size (5) 30 */ + 0x95, 0x01, /* ....Report Count (1) 32 */ + 0x81, 0x03, /* ....Input (Cnst,Var,Abs) 34 */ + 0x05, 0x01, /* ....Usage Page (Generic Desktop) 36 */ + 0x09, 0x30, /* ....Usage (X) 38 */ + 0x09, 0x31, /* ....Usage (Y) 40 */ + 0x15, 0x81, /* ....Logical Minimum (-127) 42 */ + 0x25, 0x7f, /* ....Logical Maximum (127) 44 */ + 0x75, 0x08, /* ....Report Size (8) 46 */ + 0x95, 0x02, /* ....Report Count (2) 48 */ + 0x81, 0x06, /* ....Input (Data,Var,Rel) 50 */ + 0xc0, /* ...End Collection 52 */ + 0xc0, /* ..End Collection 53 */ + 0xc0, /* .End Collection 54 */ +}; + struct hid_hw_request_syscall_args { __u8 data[10]; unsigned int hid; @@ -59,6 +91,8 @@ struct specific_device { __u16 bus; __u32 vid; __u32 pid; + const __u8 *rdesc; + const size_t rdesc_size; }; FIXTURE_SETUP(hid_bpf) @@ -72,11 +106,15 @@ FIXTURE_SETUP(hid_bpf) .bus = BUS_BLUETOOTH, .vid = 0x05ac, /* USB_VENDOR_ID_APPLE */ .pid = 0x022c, /* USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI */ + .rdesc = mouse_rdesc, + .rdesc_size = sizeof(mouse_rdesc), }, { .test_name = "*", .bus = BUS_USB, .vid = 0x0001, .pid = 0x0a36, + .rdesc = rdesc, + .rdesc_size = sizeof(rdesc), }}; for (int i = 0; i < ARRAY_SIZE(devices); i++) { @@ -88,7 +126,7 @@ FIXTURE_SETUP(hid_bpf) ASSERT_OK_PTR(match); err = setup_uhid(_metadata, &self->hid, match->bus, match->vid, match->pid, - rdesc, sizeof(rdesc)); + match->rdesc, match->rdesc_size); ASSERT_OK(err); } @@ -914,6 +952,24 @@ static bool is_using_driver(struct __test_metadata *_metadata, struct uhid_devic return found; } +static bool has_hid_input(struct uhid_device *hid) +{ + char input[1024]; + DIR *d; + + sprintf(input, "/sys/bus/hid/devices/%04X:%04X:%04X.%04X/input", + hid->bus, hid->vid, hid->pid, hid->hid_id); + + d = opendir(input); + if (d) { + closedir(d); + + return true; + } + + return false; +} + /* * Attach hid_driver_probe to the given uhid device, * check that the device is now using hid-generic. @@ -927,10 +983,12 @@ TEST_F(hid_bpf, test_hid_driver_probe) }; ASSERT_TRUE(is_using_driver(_metadata, &self->hid, "apple")); + ASSERT_TRUE(has_hid_input(&self->hid)) TH_LOG("input node not found"); LOAD_PROGRAMS(progs); ASSERT_TRUE(is_using_driver(_metadata, &self->hid, "hid-generic")); + ASSERT_FALSE(has_hid_input(&self->hid)) TH_LOG("input node unexpectly found"); } /* diff --git a/tools/testing/selftests/hid/progs/hid.c b/tools/testing/selftests/hid/progs/hid.c index 883d09498351..c81d5eb18211 100644 --- a/tools/testing/selftests/hid/progs/hid.c +++ b/tools/testing/selftests/hid/progs/hid.c @@ -606,10 +606,12 @@ void BPF_PROG(hid_test_driver_probe, struct hid_device *hdev, struct hid_bpf_dri static const char hid_generic[] = "hid-generic"; bpf_printk("test_driver_probe, %s", hdrv->name); - if (!__builtin_memcmp(hdrv->name, hid_generic, sizeof(hid_generic))) + if (!__builtin_memcmp(hdrv->name, hid_generic, sizeof(hid_generic))) { hdrv->force_driver = 1; - else + id->driver_data &= ~HID_CONNECT_INPUT; + } else { hdrv->ignore_driver = 1; + } } SEC("?struct_ops.s/hid_rdesc_fixup") diff --git a/tools/testing/selftests/hid/progs/hid_bpf_helpers.h b/tools/testing/selftests/hid/progs/hid_bpf_helpers.h index 6b0f870d0727..9447233d7a3d 100644 --- a/tools/testing/selftests/hid/progs/hid_bpf_helpers.h +++ b/tools/testing/selftests/hid/progs/hid_bpf_helpers.h @@ -90,6 +90,8 @@ struct hid_bpf_ops { #define BPF_F_BEFORE (1U << 3) #endif +#define HID_CONNECT_INPUT (1U << 0) + /* following are kfuncs exported by HID for HID-BPF */ extern __u8 *hid_bpf_get_data(struct hid_bpf_ctx *ctx, unsigned int offset,