mirror of
https://github.com/torvalds/linux.git
synced 2026-05-21 13:27:57 +02:00
selftests/hid: Add test for hid_bpf_hw_output_report
This time we need to ensure uhid receives it, thus the new mutex and condition. Link: https://lore.kernel.org/r/20240315-b4-hid-bpf-new-funcs-v4-4-079c282469d3@kernel.org Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
This commit is contained in:
parent
c8a1495947
commit
db624e82c5
|
|
@ -16,6 +16,11 @@
|
|||
|
||||
#define SHOW_UHID_DEBUG 0
|
||||
|
||||
#define min(a, b) \
|
||||
({ __typeof__(a) _a = (a); \
|
||||
__typeof__(b) _b = (b); \
|
||||
_a < _b ? _a : _b; })
|
||||
|
||||
static unsigned char rdesc[] = {
|
||||
0x06, 0x00, 0xff, /* Usage Page (Vendor Defined Page 1) */
|
||||
0x09, 0x21, /* Usage (Vendor Usage 0x21) */
|
||||
|
|
@ -111,6 +116,10 @@ struct hid_hw_request_syscall_args {
|
|||
static pthread_mutex_t uhid_started_mtx = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t uhid_started = PTHREAD_COND_INITIALIZER;
|
||||
|
||||
static pthread_mutex_t uhid_output_mtx = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t uhid_output_cond = PTHREAD_COND_INITIALIZER;
|
||||
static unsigned char output_report[10];
|
||||
|
||||
/* no need to protect uhid_stopped, only one thread accesses it */
|
||||
static bool uhid_stopped;
|
||||
|
||||
|
|
@ -205,6 +214,13 @@ static int uhid_event(struct __test_metadata *_metadata, int fd)
|
|||
break;
|
||||
case UHID_OUTPUT:
|
||||
UHID_LOG("UHID_OUTPUT from uhid-dev");
|
||||
|
||||
pthread_mutex_lock(&uhid_output_mtx);
|
||||
memcpy(output_report,
|
||||
ev.u.output.data,
|
||||
min(ev.u.output.size, sizeof(output_report)));
|
||||
pthread_cond_signal(&uhid_output_cond);
|
||||
pthread_mutex_unlock(&uhid_output_mtx);
|
||||
break;
|
||||
case UHID_GET_REPORT:
|
||||
UHID_LOG("UHID_GET_REPORT from uhid-dev");
|
||||
|
|
@ -733,6 +749,53 @@ TEST_F(hid_bpf, test_hid_change_report)
|
|||
ASSERT_EQ(buf[2], 0) TH_LOG("leftovers_from_previous_test");
|
||||
}
|
||||
|
||||
/*
|
||||
* Call hid_bpf_hw_output_report against the given uhid device,
|
||||
* check that the program is called and does the expected.
|
||||
*/
|
||||
TEST_F(hid_bpf, test_hid_user_output_report_call)
|
||||
{
|
||||
struct hid_hw_request_syscall_args args = {
|
||||
.retval = -1,
|
||||
.size = 10,
|
||||
};
|
||||
DECLARE_LIBBPF_OPTS(bpf_test_run_opts, tattrs,
|
||||
.ctx_in = &args,
|
||||
.ctx_size_in = sizeof(args),
|
||||
);
|
||||
int err, cond_err, prog_fd;
|
||||
struct timespec time_to_wait;
|
||||
|
||||
LOAD_BPF;
|
||||
|
||||
args.hid = self->hid_id;
|
||||
args.data[0] = 1; /* report ID */
|
||||
args.data[1] = 2; /* report ID */
|
||||
args.data[2] = 42; /* report ID */
|
||||
|
||||
prog_fd = bpf_program__fd(self->skel->progs.hid_user_output_report);
|
||||
|
||||
pthread_mutex_lock(&uhid_output_mtx);
|
||||
|
||||
memset(output_report, 0, sizeof(output_report));
|
||||
clock_gettime(CLOCK_REALTIME, &time_to_wait);
|
||||
time_to_wait.tv_sec += 2;
|
||||
|
||||
err = bpf_prog_test_run_opts(prog_fd, &tattrs);
|
||||
cond_err = pthread_cond_timedwait(&uhid_output_cond, &uhid_output_mtx, &time_to_wait);
|
||||
|
||||
ASSERT_OK(err) TH_LOG("error while calling bpf_prog_test_run_opts");
|
||||
ASSERT_OK(cond_err) TH_LOG("error while calling waiting for the condition");
|
||||
|
||||
ASSERT_EQ(args.retval, 3);
|
||||
|
||||
ASSERT_EQ(output_report[0], 1);
|
||||
ASSERT_EQ(output_report[1], 2);
|
||||
ASSERT_EQ(output_report[2], 42);
|
||||
|
||||
pthread_mutex_unlock(&uhid_output_mtx);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attach hid_user_raw_request to the given uhid device,
|
||||
* call the bpf program from userspace
|
||||
|
|
|
|||
|
|
@ -101,6 +101,30 @@ int hid_user_raw_request(struct hid_hw_request_syscall_args *args)
|
|||
return 0;
|
||||
}
|
||||
|
||||
SEC("syscall")
|
||||
int hid_user_output_report(struct hid_hw_request_syscall_args *args)
|
||||
{
|
||||
struct hid_bpf_ctx *ctx;
|
||||
const size_t size = args->size;
|
||||
int i, ret = 0;
|
||||
|
||||
if (size > sizeof(args->data))
|
||||
return -7; /* -E2BIG */
|
||||
|
||||
ctx = hid_bpf_allocate_context(args->hid);
|
||||
if (!ctx)
|
||||
return -1; /* EPERM check */
|
||||
|
||||
ret = hid_bpf_hw_output_report(ctx,
|
||||
args->data,
|
||||
size);
|
||||
args->retval = ret;
|
||||
|
||||
hid_bpf_release_context(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const __u8 rdesc[] = {
|
||||
0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
|
||||
0x09, 0x32, /* USAGE (Z) */
|
||||
|
|
|
|||
|
|
@ -94,5 +94,7 @@ extern int hid_bpf_hw_request(struct hid_bpf_ctx *ctx,
|
|||
size_t buf__sz,
|
||||
enum hid_report_type type,
|
||||
enum hid_class_request reqtype) __ksym;
|
||||
extern int hid_bpf_hw_output_report(struct hid_bpf_ctx *ctx,
|
||||
__u8 *buf, size_t buf__sz) __ksym;
|
||||
|
||||
#endif /* __HID_BPF_HELPERS_H */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user