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