xref: /linux/drivers/hid/bpf/hid_bpf_dispatch.c (revision fe2ec83746e501645709761605c2464a44fd2929)
1 // SPDX-License-Identifier: GPL-2.0-only
2 
3 /*
4  *  HID-BPF support for Linux
5  *
6  *  Copyright (c) 2022-2024 Benjamin Tissoires
7  */
8 
9 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
10 #include <linux/bitops.h>
11 #include <linux/btf.h>
12 #include <linux/btf_ids.h>
13 #include <linux/filter.h>
14 #include <linux/hid.h>
15 #include <linux/hid_bpf.h>
16 #include <linux/init.h>
17 #include <linux/kfifo.h>
18 #include <linux/minmax.h>
19 #include <linux/module.h>
20 #include <linux/overflow.h>
21 #include "hid_bpf_dispatch.h"
22 
23 const struct hid_ops *hid_ops;
24 EXPORT_SYMBOL(hid_ops);
25 
26 u8 *
27 dispatch_hid_bpf_device_event(struct hid_device *hdev, enum hid_report_type type, u8 *data,
28 			      size_t *buf_size, u32 *size, int interrupt, u64 source,
29 			      bool from_bpf)
30 {
31 	struct hid_bpf_ctx_kern ctx_kern = {
32 		.ctx = {
33 			.hid = hdev,
34 			.allocated_size = hdev->bpf.allocated_data,
35 			.size = *size,
36 		},
37 		.data = hdev->bpf.device_data,
38 		.from_bpf = from_bpf,
39 	};
40 	struct hid_bpf_ops *e;
41 	int ret;
42 
43 	if (unlikely(hdev->bpf.destroyed))
44 		return ERR_PTR(-ENODEV);
45 
46 	if (type >= HID_REPORT_TYPES)
47 		return ERR_PTR(-EINVAL);
48 
49 	/* no program has been attached yet */
50 	if (!hdev->bpf.device_data)
51 		return data;
52 
53 	memset(ctx_kern.data, 0, hdev->bpf.allocated_data);
54 	memcpy(ctx_kern.data, data, *size);
55 
56 	rcu_read_lock();
57 	list_for_each_entry_rcu(e, &hdev->bpf.prog_list, list) {
58 		if (e->hid_device_event) {
59 			ret = e->hid_device_event(&ctx_kern.ctx, type, source);
60 			if (ret < 0) {
61 				rcu_read_unlock();
62 				return ERR_PTR(ret);
63 			}
64 
65 			if (ret)
66 				ctx_kern.ctx.size = ret;
67 		}
68 	}
69 	rcu_read_unlock();
70 
71 	ret = ctx_kern.ctx.size;
72 	if (ret) {
73 		if (ret > ctx_kern.ctx.allocated_size)
74 			return ERR_PTR(-EINVAL);
75 
76 		*size = ret;
77 	}
78 
79 	*buf_size = ctx_kern.ctx.allocated_size;
80 	return ctx_kern.data;
81 }
82 EXPORT_SYMBOL_GPL(dispatch_hid_bpf_device_event);
83 
84 int dispatch_hid_bpf_raw_requests(struct hid_device *hdev,
85 				  unsigned char reportnum, u8 *buf,
86 				  u32 size, enum hid_report_type rtype,
87 				  enum hid_class_request reqtype,
88 				  u64 source, bool from_bpf)
89 {
90 	struct hid_bpf_ctx_kern ctx_kern = {
91 		.ctx = {
92 			.hid = hdev,
93 			.allocated_size = size,
94 			.size = size,
95 		},
96 		.data = buf,
97 		.from_bpf = from_bpf,
98 	};
99 	struct hid_bpf_ops *e;
100 	int ret, idx;
101 
102 	if (unlikely(hdev->bpf.destroyed))
103 		return -ENODEV;
104 
105 	if (rtype >= HID_REPORT_TYPES)
106 		return -EINVAL;
107 
108 	idx = srcu_read_lock(&hdev->bpf.srcu);
109 	list_for_each_entry_srcu(e, &hdev->bpf.prog_list, list,
110 				 srcu_read_lock_held(&hdev->bpf.srcu)) {
111 		if (!e->hid_hw_request)
112 			continue;
113 
114 		ret = e->hid_hw_request(&ctx_kern.ctx, reportnum, rtype, reqtype, source);
115 		if (ret)
116 			goto out;
117 	}
118 	ret = 0;
119 
120 out:
121 	srcu_read_unlock(&hdev->bpf.srcu, idx);
122 	return ret;
123 }
124 EXPORT_SYMBOL_GPL(dispatch_hid_bpf_raw_requests);
125 
126 int dispatch_hid_bpf_output_report(struct hid_device *hdev,
127 				   __u8 *buf, u32 size, u64 source,
128 				   bool from_bpf)
129 {
130 	struct hid_bpf_ctx_kern ctx_kern = {
131 		.ctx = {
132 			.hid = hdev,
133 			.allocated_size = size,
134 			.size = size,
135 		},
136 		.data = buf,
137 		.from_bpf = from_bpf,
138 	};
139 	struct hid_bpf_ops *e;
140 	int ret, idx;
141 
142 	if (unlikely(hdev->bpf.destroyed))
143 		return -ENODEV;
144 
145 	idx = srcu_read_lock(&hdev->bpf.srcu);
146 	list_for_each_entry_srcu(e, &hdev->bpf.prog_list, list,
147 				 srcu_read_lock_held(&hdev->bpf.srcu)) {
148 		if (!e->hid_hw_output_report)
149 			continue;
150 
151 		ret = e->hid_hw_output_report(&ctx_kern.ctx, source);
152 		if (ret)
153 			goto out;
154 	}
155 	ret = 0;
156 
157 out:
158 	srcu_read_unlock(&hdev->bpf.srcu, idx);
159 	return ret;
160 }
161 EXPORT_SYMBOL_GPL(dispatch_hid_bpf_output_report);
162 
163 const u8 *call_hid_bpf_rdesc_fixup(struct hid_device *hdev, const u8 *rdesc, unsigned int *size)
164 {
165 	int ret;
166 	struct hid_bpf_ctx_kern ctx_kern = {
167 		.ctx = {
168 			.hid = hdev,
169 			.size = *size,
170 			.allocated_size = HID_MAX_DESCRIPTOR_SIZE,
171 		},
172 	};
173 
174 	if (!hdev->bpf.rdesc_ops)
175 		goto ignore_bpf;
176 
177 	ctx_kern.data = kzalloc(ctx_kern.ctx.allocated_size, GFP_KERNEL);
178 	if (!ctx_kern.data)
179 		goto ignore_bpf;
180 
181 	memcpy(ctx_kern.data, rdesc, min_t(unsigned int, *size, HID_MAX_DESCRIPTOR_SIZE));
182 
183 	ret = hdev->bpf.rdesc_ops->hid_rdesc_fixup(&ctx_kern.ctx);
184 	if (ret < 0)
185 		goto ignore_bpf;
186 
187 	if (ret) {
188 		if (ret > ctx_kern.ctx.allocated_size)
189 			goto ignore_bpf;
190 
191 		*size = ret;
192 	}
193 
194 	return krealloc(ctx_kern.data, *size, GFP_KERNEL);
195 
196  ignore_bpf:
197 	kfree(ctx_kern.data);
198 	return rdesc;
199 }
200 EXPORT_SYMBOL_GPL(call_hid_bpf_rdesc_fixup);
201 
202 static int device_match_id(struct device *dev, const void *id)
203 {
204 	struct hid_device *hdev = to_hid_device(dev);
205 
206 	return hdev->id == *(int *)id;
207 }
208 
209 struct hid_device *hid_get_device(unsigned int hid_id)
210 {
211 	struct device *dev;
212 
213 	if (!hid_ops)
214 		return ERR_PTR(-EINVAL);
215 
216 	dev = bus_find_device(hid_ops->bus_type, NULL, &hid_id, device_match_id);
217 	if (!dev)
218 		return ERR_PTR(-EINVAL);
219 
220 	return to_hid_device(dev);
221 }
222 
223 void hid_put_device(struct hid_device *hid)
224 {
225 	put_device(&hid->dev);
226 }
227 
228 static int __hid_bpf_allocate_data(struct hid_device *hdev, u8 **data, u32 *size)
229 {
230 	u8 *alloc_data;
231 	unsigned int i, j, max_report_len = 0;
232 	size_t alloc_size = 0;
233 
234 	/* compute the maximum report length for this device */
235 	for (i = 0; i < HID_REPORT_TYPES; i++) {
236 		struct hid_report_enum *report_enum = hdev->report_enum + i;
237 
238 		for (j = 0; j < HID_MAX_IDS; j++) {
239 			struct hid_report *report = report_enum->report_id_hash[j];
240 
241 			if (report)
242 				max_report_len = max(max_report_len, hid_report_len(report));
243 		}
244 	}
245 
246 	/*
247 	 * Give us a little bit of extra space and some predictability in the
248 	 * buffer length we create. This way, we can tell users that they can
249 	 * work on chunks of 64 bytes of memory without having the bpf verifier
250 	 * scream at them.
251 	 */
252 	alloc_size = DIV_ROUND_UP(max_report_len, 64) * 64;
253 
254 	alloc_data = kzalloc(alloc_size, GFP_KERNEL);
255 	if (!alloc_data)
256 		return -ENOMEM;
257 
258 	*data = alloc_data;
259 	*size = alloc_size;
260 
261 	return 0;
262 }
263 
264 int hid_bpf_allocate_event_data(struct hid_device *hdev)
265 {
266 	/* hdev->bpf.device_data is already allocated, abort */
267 	if (hdev->bpf.device_data)
268 		return 0;
269 
270 	return __hid_bpf_allocate_data(hdev, &hdev->bpf.device_data, &hdev->bpf.allocated_data);
271 }
272 
273 int hid_bpf_reconnect(struct hid_device *hdev)
274 {
275 	if (!test_and_set_bit(ffs(HID_STAT_REPROBED), &hdev->status)) {
276 		/* trigger call to call_hid_bpf_rdesc_fixup() during the next probe */
277 		hdev->bpf_rsize = 0;
278 		return device_reprobe(&hdev->dev);
279 	}
280 
281 	return 0;
282 }
283 
284 /* Disables missing prototype warnings */
285 __bpf_kfunc_start_defs();
286 
287 /**
288  * hid_bpf_get_data - Get the kernel memory pointer associated with the context @ctx
289  *
290  * @ctx: The HID-BPF context
291  * @offset: The offset within the memory
292  * @rdwr_buf_size: the const size of the buffer
293  *
294  * @returns %NULL on error, an %__u8 memory pointer on success
295  */
296 __bpf_kfunc __u8 *
297 hid_bpf_get_data(struct hid_bpf_ctx *ctx, unsigned int offset, const size_t rdwr_buf_size)
298 {
299 	struct hid_bpf_ctx_kern *ctx_kern;
300 	size_t end;
301 
302 	ctx_kern = container_of(ctx, struct hid_bpf_ctx_kern, ctx);
303 
304 	if (check_add_overflow(rdwr_buf_size, offset, &end) ||
305 	    end > ctx->allocated_size)
306 		return NULL;
307 
308 	return ctx_kern->data + offset;
309 }
310 
311 /**
312  * hid_bpf_allocate_context - Allocate a context to the given HID device
313  *
314  * @hid_id: the system unique identifier of the HID device
315  *
316  * @returns A pointer to &struct hid_bpf_ctx on success, %NULL on error.
317  */
318 __bpf_kfunc struct hid_bpf_ctx *
319 hid_bpf_allocate_context(unsigned int hid_id)
320 {
321 	struct hid_device *hdev;
322 	struct hid_bpf_ctx_kern *ctx_kern = NULL;
323 
324 	hdev = hid_get_device(hid_id);
325 	if (IS_ERR(hdev))
326 		return NULL;
327 
328 	ctx_kern = kzalloc_obj(*ctx_kern);
329 	if (!ctx_kern) {
330 		hid_put_device(hdev);
331 		return NULL;
332 	}
333 
334 	ctx_kern->ctx.hid = hdev;
335 
336 	return &ctx_kern->ctx;
337 }
338 
339 /**
340  * hid_bpf_release_context - Release the previously allocated context @ctx
341  *
342  * @ctx: the HID-BPF context to release
343  *
344  */
345 __bpf_kfunc void
346 hid_bpf_release_context(struct hid_bpf_ctx *ctx)
347 {
348 	struct hid_bpf_ctx_kern *ctx_kern;
349 	struct hid_device *hid;
350 
351 	ctx_kern = container_of(ctx, struct hid_bpf_ctx_kern, ctx);
352 	hid = (struct hid_device *)ctx_kern->ctx.hid; /* ignore const */
353 
354 	kfree(ctx_kern);
355 
356 	/* get_device() is called by bus_find_device() */
357 	hid_put_device(hid);
358 }
359 
360 static int
361 __hid_bpf_hw_check_params(struct hid_bpf_ctx *ctx, __u8 *buf, size_t *buf__sz,
362 			  enum hid_report_type rtype, bool hw_request)
363 {
364 	struct hid_report_enum *report_enum;
365 	struct hid_report *report;
366 	u32 report_len;
367 
368 	/* check arguments */
369 	if (!hid_ops)
370 		return -EINVAL;
371 
372 	switch (rtype) {
373 	case HID_INPUT_REPORT:
374 	case HID_OUTPUT_REPORT:
375 	case HID_FEATURE_REPORT:
376 		break;
377 	default:
378 		return -EINVAL;
379 	}
380 
381 	if (*buf__sz < 1)
382 		return -EINVAL;
383 
384 	report_enum = ctx->hid->report_enum + rtype;
385 	report = hid_ops->hid_get_report(report_enum, buf);
386 	if (!report)
387 		return -EINVAL;
388 
389 	report_len = hid_report_len(report);
390 
391 	/* unnumbered reports need to have a report ID reserved in the first byte */
392 	if (hw_request && report_enum->numbered == 0)
393 		report_len += 1;
394 
395 	if (*buf__sz > report_len)
396 		*buf__sz = report_len;
397 
398 	return 0;
399 }
400 
401 /**
402  * hid_bpf_hw_request - Communicate with a HID device
403  *
404  * @ctx: the HID-BPF context previously allocated in hid_bpf_allocate_context()
405  * @buf: a %PTR_TO_MEM buffer
406  * @buf__sz: the size of the data to transfer
407  * @rtype: the type of the report (%HID_INPUT_REPORT, %HID_FEATURE_REPORT, %HID_OUTPUT_REPORT)
408  * @reqtype: the type of the request (%HID_REQ_GET_REPORT, %HID_REQ_SET_REPORT, ...)
409  *
410  * @returns %0 on success, a negative error code otherwise.
411  */
412 __bpf_kfunc int
413 hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz,
414 		   enum hid_report_type rtype, enum hid_class_request reqtype)
415 {
416 	struct hid_bpf_ctx_kern *ctx_kern;
417 	size_t size = buf__sz;
418 	u8 *dma_data;
419 	int ret;
420 
421 	ctx_kern = container_of(ctx, struct hid_bpf_ctx_kern, ctx);
422 
423 	if (ctx_kern->from_bpf)
424 		return -EDEADLOCK;
425 
426 	/* check arguments */
427 	ret = __hid_bpf_hw_check_params(ctx, buf, &size, rtype, true);
428 	if (ret)
429 		return ret;
430 
431 	switch (reqtype) {
432 	case HID_REQ_GET_REPORT:
433 	case HID_REQ_GET_IDLE:
434 	case HID_REQ_GET_PROTOCOL:
435 	case HID_REQ_SET_REPORT:
436 	case HID_REQ_SET_IDLE:
437 	case HID_REQ_SET_PROTOCOL:
438 		break;
439 	default:
440 		return -EINVAL;
441 	}
442 
443 	dma_data = kmemdup(buf, size, GFP_KERNEL);
444 	if (!dma_data)
445 		return -ENOMEM;
446 
447 	ret = hid_ops->hid_hw_raw_request(ctx->hid,
448 					      dma_data[0],
449 					      dma_data,
450 					      size,
451 					      rtype,
452 					      reqtype,
453 					      (u64)(long)ctx,
454 					      true); /* prevent infinite recursions */
455 
456 	if (ret > size)
457 		ret = size;
458 	if (ret > 0)
459 		memcpy(buf, dma_data, ret);
460 
461 	kfree(dma_data);
462 	return ret;
463 }
464 
465 /**
466  * hid_bpf_hw_output_report - Send an output report to a HID device
467  *
468  * @ctx: the HID-BPF context previously allocated in hid_bpf_allocate_context()
469  * @buf: a %PTR_TO_MEM buffer
470  * @buf__sz: the size of the data to transfer
471  *
472  * Returns the number of bytes transferred on success, a negative error code otherwise.
473  */
474 __bpf_kfunc int
475 hid_bpf_hw_output_report(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz)
476 {
477 	struct hid_bpf_ctx_kern *ctx_kern;
478 	size_t size = buf__sz;
479 	u8 *dma_data;
480 	int ret;
481 
482 	ctx_kern = container_of(ctx, struct hid_bpf_ctx_kern, ctx);
483 	if (ctx_kern->from_bpf)
484 		return -EDEADLOCK;
485 
486 	/* check arguments */
487 	ret = __hid_bpf_hw_check_params(ctx, buf, &size, HID_OUTPUT_REPORT, true);
488 	if (ret)
489 		return ret;
490 
491 	dma_data = kmemdup(buf, size, GFP_KERNEL);
492 	if (!dma_data)
493 		return -ENOMEM;
494 
495 	ret = hid_ops->hid_hw_output_report(ctx->hid, dma_data, size, (u64)(long)ctx, true);
496 
497 	kfree(dma_data);
498 	return ret;
499 }
500 
501 static int
502 __hid_bpf_input_report(struct hid_bpf_ctx *ctx, enum hid_report_type type, u8 *buf,
503 		       size_t size, bool lock_already_taken)
504 {
505 	struct hid_bpf_ctx_kern *ctx_kern;
506 	int ret;
507 
508 	ctx_kern = container_of(ctx, struct hid_bpf_ctx_kern, ctx);
509 	if (ctx_kern->from_bpf)
510 		return -EDEADLOCK;
511 
512 	/* check arguments */
513 	ret = __hid_bpf_hw_check_params(ctx, buf, &size, type, false);
514 	if (ret)
515 		return ret;
516 
517 	return hid_ops->hid_input_report(ctx->hid, type, buf, size, size, 0, (u64)(long)ctx, true,
518 					 lock_already_taken);
519 }
520 
521 /**
522  * hid_bpf_try_input_report - Inject a HID report in the kernel from a HID device
523  *
524  * @ctx: the HID-BPF context previously allocated in hid_bpf_allocate_context()
525  * @type: the type of the report (%HID_INPUT_REPORT, %HID_FEATURE_REPORT, %HID_OUTPUT_REPORT)
526  * @buf: a %PTR_TO_MEM buffer
527  * @buf__sz: the size of the data to transfer
528  *
529  * Returns %0 on success, a negative error code otherwise. This function will immediately
530  * fail if the device is not available, thus can be safely used in IRQ context.
531  */
532 __bpf_kfunc int
533 hid_bpf_try_input_report(struct hid_bpf_ctx *ctx, enum hid_report_type type, u8 *buf,
534 			 const size_t buf__sz)
535 {
536 	struct hid_bpf_ctx_kern *ctx_kern;
537 	bool from_hid_event_hook;
538 
539 	ctx_kern = container_of(ctx, struct hid_bpf_ctx_kern, ctx);
540 	from_hid_event_hook = ctx_kern->data && ctx_kern->data == ctx->hid->bpf.device_data;
541 
542 	return __hid_bpf_input_report(ctx, type, buf, buf__sz, from_hid_event_hook);
543 }
544 
545 /**
546  * hid_bpf_input_report - Inject a HID report in the kernel from a HID device
547  *
548  * @ctx: the HID-BPF context previously allocated in hid_bpf_allocate_context()
549  * @type: the type of the report (%HID_INPUT_REPORT, %HID_FEATURE_REPORT, %HID_OUTPUT_REPORT)
550  * @buf: a %PTR_TO_MEM buffer
551  * @buf__sz: the size of the data to transfer
552  *
553  * Returns %0 on success, a negative error code otherwise. This function will wait for the
554  * device to be available before injecting the event, thus needs to be called in sleepable
555  * context.
556  */
557 __bpf_kfunc int
558 hid_bpf_input_report(struct hid_bpf_ctx *ctx, enum hid_report_type type, u8 *buf,
559 		     const size_t buf__sz)
560 {
561 	int ret;
562 
563 	ret = down_interruptible(&ctx->hid->driver_input_lock);
564 	if (ret)
565 		return ret;
566 
567 	/* check arguments */
568 	ret = __hid_bpf_input_report(ctx, type, buf, buf__sz, true /* lock_already_taken */);
569 
570 	up(&ctx->hid->driver_input_lock);
571 
572 	return ret;
573 }
574 __bpf_kfunc_end_defs();
575 
576 /*
577  * The following set contains all functions we agree BPF programs
578  * can use.
579  */
580 BTF_KFUNCS_START(hid_bpf_kfunc_ids)
581 BTF_ID_FLAGS(func, hid_bpf_get_data, KF_RET_NULL)
582 BTF_ID_FLAGS(func, hid_bpf_allocate_context, KF_ACQUIRE | KF_RET_NULL | KF_SLEEPABLE)
583 BTF_ID_FLAGS(func, hid_bpf_release_context, KF_RELEASE | KF_SLEEPABLE)
584 BTF_ID_FLAGS(func, hid_bpf_hw_request, KF_SLEEPABLE)
585 BTF_ID_FLAGS(func, hid_bpf_hw_output_report, KF_SLEEPABLE)
586 BTF_ID_FLAGS(func, hid_bpf_input_report, KF_SLEEPABLE)
587 BTF_ID_FLAGS(func, hid_bpf_try_input_report)
588 BTF_KFUNCS_END(hid_bpf_kfunc_ids)
589 
590 static const struct btf_kfunc_id_set hid_bpf_kfunc_set = {
591 	.owner = THIS_MODULE,
592 	.set   = &hid_bpf_kfunc_ids,
593 };
594 
595 /* for syscall HID-BPF */
596 BTF_KFUNCS_START(hid_bpf_syscall_kfunc_ids)
597 BTF_ID_FLAGS(func, hid_bpf_allocate_context, KF_ACQUIRE | KF_RET_NULL | KF_SLEEPABLE)
598 BTF_ID_FLAGS(func, hid_bpf_release_context, KF_RELEASE | KF_SLEEPABLE)
599 BTF_ID_FLAGS(func, hid_bpf_hw_request, KF_SLEEPABLE)
600 BTF_ID_FLAGS(func, hid_bpf_hw_output_report, KF_SLEEPABLE)
601 BTF_ID_FLAGS(func, hid_bpf_input_report, KF_SLEEPABLE)
602 BTF_KFUNCS_END(hid_bpf_syscall_kfunc_ids)
603 
604 static const struct btf_kfunc_id_set hid_bpf_syscall_kfunc_set = {
605 	.owner = THIS_MODULE,
606 	.set   = &hid_bpf_syscall_kfunc_ids,
607 };
608 
609 int hid_bpf_connect_device(struct hid_device *hdev)
610 {
611 	bool need_to_allocate = false;
612 	struct hid_bpf_ops *e;
613 
614 	rcu_read_lock();
615 	list_for_each_entry_rcu(e, &hdev->bpf.prog_list, list) {
616 		if (e->hid_device_event) {
617 			need_to_allocate = true;
618 			break;
619 		}
620 	}
621 	rcu_read_unlock();
622 
623 	/* only allocate BPF data if there are programs attached */
624 	if (!need_to_allocate)
625 		return 0;
626 
627 	return hid_bpf_allocate_event_data(hdev);
628 }
629 EXPORT_SYMBOL_GPL(hid_bpf_connect_device);
630 
631 void hid_bpf_disconnect_device(struct hid_device *hdev)
632 {
633 	kfree(hdev->bpf.device_data);
634 	hdev->bpf.device_data = NULL;
635 	hdev->bpf.allocated_data = 0;
636 }
637 EXPORT_SYMBOL_GPL(hid_bpf_disconnect_device);
638 
639 void hid_bpf_destroy_device(struct hid_device *hdev)
640 {
641 	if (!hdev)
642 		return;
643 
644 	/* mark the device as destroyed in bpf so we don't reattach it */
645 	hdev->bpf.destroyed = true;
646 
647 	__hid_bpf_ops_destroy_device(hdev);
648 
649 	synchronize_srcu(&hdev->bpf.srcu);
650 	cleanup_srcu_struct(&hdev->bpf.srcu);
651 }
652 EXPORT_SYMBOL_GPL(hid_bpf_destroy_device);
653 
654 int hid_bpf_device_init(struct hid_device *hdev)
655 {
656 	INIT_LIST_HEAD(&hdev->bpf.prog_list);
657 	mutex_init(&hdev->bpf.prog_list_lock);
658 	return init_srcu_struct(&hdev->bpf.srcu);
659 }
660 EXPORT_SYMBOL_GPL(hid_bpf_device_init);
661 
662 static int __init hid_bpf_init(void)
663 {
664 	int err;
665 
666 	/* Note: if we exit with an error any time here, we would entirely break HID, which
667 	 * is probably not something we want. So we log an error and return success.
668 	 *
669 	 * This is not a big deal: nobody will be able to use the functionality.
670 	 */
671 
672 	err = register_btf_kfunc_id_set(BPF_PROG_TYPE_STRUCT_OPS, &hid_bpf_kfunc_set);
673 	if (err) {
674 		pr_warn("error while setting HID BPF tracing kfuncs: %d", err);
675 		return 0;
676 	}
677 
678 	err = register_btf_kfunc_id_set(BPF_PROG_TYPE_SYSCALL, &hid_bpf_syscall_kfunc_set);
679 	if (err) {
680 		pr_warn("error while setting HID BPF syscall kfuncs: %d", err);
681 		return 0;
682 	}
683 
684 	return 0;
685 }
686 
687 late_initcall(hid_bpf_init);
688 MODULE_AUTHOR("Benjamin Tissoires");
689 MODULE_LICENSE("GPL");
690