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