Skip to content

Commit 62f2e1a

Browse files
author
Benjamin Tissoires
committed
selftests/hid: add another test for injecting an event from an event hook
Similar to test_multiply_events_wq: we receive one event and inject a new one. But given that this time we are already in the event hook, we can use hid_bpf_try_input_report() directly as this function will not sleep. Note that the injected event gets processed before the original one this way. Link: https://patch.msgid.link/[email protected] Acked-by: Jiri Kosina <[email protected]> Signed-off-by: Benjamin Tissoires <[email protected]>
1 parent 9acbb7b commit 62f2e1a

File tree

3 files changed

+79
-0
lines changed

3 files changed

+79
-0
lines changed

tools/testing/selftests/hid/hid_bpf.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,6 +1168,42 @@ TEST_F(hid_bpf, test_multiply_events_wq)
11681168
ASSERT_EQ(buf[1], 3);
11691169
}
11701170

1171+
/*
1172+
* Attach hid_multiply_event to the given uhid device,
1173+
* retrieve and open the matching hidraw node,
1174+
* inject one event in the uhid device,
1175+
* check that the program sees it and can add extra data
1176+
*/
1177+
TEST_F(hid_bpf, test_multiply_events)
1178+
{
1179+
const struct test_program progs[] = {
1180+
{ .name = "hid_test_multiply_events" },
1181+
};
1182+
__u8 buf[10] = {0};
1183+
int err;
1184+
1185+
LOAD_PROGRAMS(progs);
1186+
1187+
/* inject one event */
1188+
buf[0] = 1;
1189+
buf[1] = 42;
1190+
uhid_send_event(_metadata, self->uhid_fd, buf, 6);
1191+
1192+
/* read the data from hidraw */
1193+
memset(buf, 0, sizeof(buf));
1194+
err = read(self->hidraw_fd, buf, sizeof(buf));
1195+
ASSERT_EQ(err, 9) TH_LOG("read_hidraw");
1196+
ASSERT_EQ(buf[0], 2);
1197+
ASSERT_EQ(buf[1], 47);
1198+
1199+
/* read the data from hidraw */
1200+
memset(buf, 0, sizeof(buf));
1201+
err = read(self->hidraw_fd, buf, sizeof(buf));
1202+
ASSERT_EQ(err, 9) TH_LOG("read_hidraw");
1203+
ASSERT_EQ(buf[0], 2);
1204+
ASSERT_EQ(buf[1], 52);
1205+
}
1206+
11711207
/*
11721208
* Attach hid_insert{0,1,2} to the given uhid device,
11731209
* retrieve and open the matching hidraw node,

tools/testing/selftests/hid/progs/hid.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,3 +522,42 @@ SEC(".struct_ops.link")
522522
struct hid_bpf_ops test_multiply_events_wq = {
523523
.hid_device_event = (void *)hid_test_multiply_events_wq,
524524
};
525+
526+
SEC("?struct_ops/hid_device_event")
527+
int BPF_PROG(hid_test_multiply_events, struct hid_bpf_ctx *hid_ctx, enum hid_report_type type)
528+
{
529+
__u8 *data = hid_bpf_get_data(hid_ctx, 0 /* offset */, 9 /* size */);
530+
__u8 buf[9];
531+
int ret;
532+
533+
if (!data)
534+
return 0; /* EPERM check */
535+
536+
if (data[0] != 1)
537+
return 0;
538+
539+
/*
540+
* we have to use an intermediate buffer as hid_bpf_input_report
541+
* will memset data to \0
542+
*/
543+
__builtin_memcpy(buf, data, sizeof(buf));
544+
545+
buf[0] = 2;
546+
buf[1] += 5;
547+
ret = hid_bpf_try_input_report(hid_ctx, HID_INPUT_REPORT, buf, sizeof(buf));
548+
if (ret < 0)
549+
return ret;
550+
551+
/*
552+
* In real world we should reset the original buffer as data might be garbage now,
553+
* but it actually now has the content of 'buf'
554+
*/
555+
data[1] += 5;
556+
557+
return 9;
558+
}
559+
560+
SEC(".struct_ops.link")
561+
struct hid_bpf_ops test_multiply_events = {
562+
.hid_device_event = (void *)hid_test_multiply_events,
563+
};

tools/testing/selftests/hid/progs/hid_bpf_helpers.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ extern int hid_bpf_input_report(struct hid_bpf_ctx *ctx,
8989
enum hid_report_type type,
9090
__u8 *data,
9191
size_t buf__sz) __ksym;
92+
extern int hid_bpf_try_input_report(struct hid_bpf_ctx *ctx,
93+
enum hid_report_type type,
94+
__u8 *data,
95+
size_t buf__sz) __ksym;
9296

9397
/* bpf_wq implementation */
9498
extern int bpf_wq_init(struct bpf_wq *wq, void *p__map, unsigned int flags) __weak __ksym;

0 commit comments

Comments
 (0)