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 	if (!ctx)
299 		return NULL;
300 
301 	ctx_kern = container_of(ctx, struct hid_bpf_ctx_kern, ctx);
302 
303 	if (rdwr_buf_size + offset > ctx->allocated_size)
304 		return NULL;
305 
306 	return ctx_kern->data + offset;
307 }
308 
309 /**
310  * hid_bpf_allocate_context - Allocate a context to the given HID device
311  *
312  * @hid_id: the system unique identifier of the HID device
313  *
314  * @returns A pointer to &struct hid_bpf_ctx on success, %NULL on error.
315  */
316 __bpf_kfunc struct hid_bpf_ctx *
317 hid_bpf_allocate_context(unsigned int hid_id)
318 {
319 	struct hid_device *hdev;
320 	struct hid_bpf_ctx_kern *ctx_kern = NULL;
321 
322 	hdev = hid_get_device(hid_id);
323 	if (IS_ERR(hdev))
324 		return NULL;
325 
326 	ctx_kern = kzalloc(sizeof(*ctx_kern), GFP_KERNEL);
327 	if (!ctx_kern) {
328 		hid_put_device(hdev);
329 		return NULL;
330 	}
331 
332 	ctx_kern->ctx.hid = hdev;
333 
334 	return &ctx_kern->ctx;
335 }
336 
337 /**
338  * hid_bpf_release_context - Release the previously allocated context @ctx
339  *
340  * @ctx: the HID-BPF context to release
341  *
342  */
343 __bpf_kfunc void
344 hid_bpf_release_context(struct hid_bpf_ctx *ctx)
345 {
346 	struct hid_bpf_ctx_kern *ctx_kern;
347 	struct hid_device *hid;
348 
349 	ctx_kern = container_of(ctx, struct hid_bpf_ctx_kern, ctx);
350 	hid = (struct hid_device *)ctx_kern->ctx.hid; /* ignore const */
351 
352 	kfree(ctx_kern);
353 
354 	/* get_device() is called by bus_find_device() */
355 	hid_put_device(hid);
356 }
357 
358 static int
359 __hid_bpf_hw_check_params(struct hid_bpf_ctx *ctx, __u8 *buf, size_t *buf__sz,
360 			  enum hid_report_type rtype)
361 {
362 	struct hid_report_enum *report_enum;
363 	struct hid_report *report;
364 	u32 report_len;
365 
366 	/* check arguments */
367 	if (!ctx || !hid_ops || !buf)
368 		return -EINVAL;
369 
370 	switch (rtype) {
371 	case HID_INPUT_REPORT:
372 	case HID_OUTPUT_REPORT:
373 	case HID_FEATURE_REPORT:
374 		break;
375 	default:
376 		return -EINVAL;
377 	}
378 
379 	if (*buf__sz < 1)
380 		return -EINVAL;
381 
382 	report_enum = ctx->hid->report_enum + rtype;
383 	report = hid_ops->hid_get_report(report_enum, buf);
384 	if (!report)
385 		return -EINVAL;
386 
387 	report_len = hid_report_len(report);
388 
389 	if (*buf__sz > report_len)
390 		*buf__sz = report_len;
391 
392 	return 0;
393 }
394 
395 /**
396  * hid_bpf_hw_request - Communicate with a HID device
397  *
398  * @ctx: the HID-BPF context previously allocated in hid_bpf_allocate_context()
399  * @buf: a %PTR_TO_MEM buffer
400  * @buf__sz: the size of the data to transfer
401  * @rtype: the type of the report (%HID_INPUT_REPORT, %HID_FEATURE_REPORT, %HID_OUTPUT_REPORT)
402  * @reqtype: the type of the request (%HID_REQ_GET_REPORT, %HID_REQ_SET_REPORT, ...)
403  *
404  * @returns %0 on success, a negative error code otherwise.
405  */
406 __bpf_kfunc int
407 hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz,
408 		   enum hid_report_type rtype, enum hid_class_request reqtype)
409 {
410 	struct hid_bpf_ctx_kern *ctx_kern;
411 	size_t size = buf__sz;
412 	u8 *dma_data;
413 	int ret;
414 
415 	ctx_kern = container_of(ctx, struct hid_bpf_ctx_kern, ctx);
416 
417 	if (ctx_kern->from_bpf)
418 		return -EDEADLOCK;
419 
420 	/* check arguments */
421 	ret = __hid_bpf_hw_check_params(ctx, buf, &size, rtype);
422 	if (ret)
423 		return ret;
424 
425 	switch (reqtype) {
426 	case HID_REQ_GET_REPORT:
427 	case HID_REQ_GET_IDLE:
428 	case HID_REQ_GET_PROTOCOL:
429 	case HID_REQ_SET_REPORT:
430 	case HID_REQ_SET_IDLE:
431 	case HID_REQ_SET_PROTOCOL:
432 		break;
433 	default:
434 		return -EINVAL;
435 	}
436 
437 	dma_data = kmemdup(buf, size, GFP_KERNEL);
438 	if (!dma_data)
439 		return -ENOMEM;
440 
441 	ret = hid_ops->hid_hw_raw_request(ctx->hid,
442 					      dma_data[0],
443 					      dma_data,
444 					      size,
445 					      rtype,
446 					      reqtype,
447 					      (u64)(long)ctx,
448 					      true); /* prevent infinite recursions */
449 
450 	if (ret > 0)
451 		memcpy(buf, dma_data, ret);
452 
453 	kfree(dma_data);
454 	return ret;
455 }
456 
457 /**
458  * hid_bpf_hw_output_report - Send an output report to a HID device
459  *
460  * @ctx: the HID-BPF context previously allocated in hid_bpf_allocate_context()
461  * @buf: a %PTR_TO_MEM buffer
462  * @buf__sz: the size of the data to transfer
463  *
464  * Returns the number of bytes transferred on success, a negative error code otherwise.
465  */
466 __bpf_kfunc int
467 hid_bpf_hw_output_report(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz)
468 {
469 	struct hid_bpf_ctx_kern *ctx_kern;
470 	size_t size = buf__sz;
471 	u8 *dma_data;
472 	int ret;
473 
474 	ctx_kern = container_of(ctx, struct hid_bpf_ctx_kern, ctx);
475 	if (ctx_kern->from_bpf)
476 		return -EDEADLOCK;
477 
478 	/* check arguments */
479 	ret = __hid_bpf_hw_check_params(ctx, buf, &size, HID_OUTPUT_REPORT);
480 	if (ret)
481 		return ret;
482 
483 	dma_data = kmemdup(buf, size, GFP_KERNEL);
484 	if (!dma_data)
485 		return -ENOMEM;
486 
487 	ret = hid_ops->hid_hw_output_report(ctx->hid, dma_data, size, (u64)(long)ctx, true);
488 
489 	kfree(dma_data);
490 	return ret;
491 }
492 
493 static int
494 __hid_bpf_input_report(struct hid_bpf_ctx *ctx, enum hid_report_type type, u8 *buf,
495 		       size_t size, bool lock_already_taken)
496 {
497 	struct hid_bpf_ctx_kern *ctx_kern;
498 	int ret;
499 
500 	ctx_kern = container_of(ctx, struct hid_bpf_ctx_kern, ctx);
501 	if (ctx_kern->from_bpf)
502 		return -EDEADLOCK;
503 
504 	/* check arguments */
505 	ret = __hid_bpf_hw_check_params(ctx, buf, &size, type);
506 	if (ret)
507 		return ret;
508 
509 	return hid_ops->hid_input_report(ctx->hid, type, buf, size, 0, (u64)(long)ctx, true,
510 					 lock_already_taken);
511 }
512 
513 /**
514  * hid_bpf_try_input_report - Inject a HID report in the kernel from a HID device
515  *
516  * @ctx: the HID-BPF context previously allocated in hid_bpf_allocate_context()
517  * @type: the type of the report (%HID_INPUT_REPORT, %HID_FEATURE_REPORT, %HID_OUTPUT_REPORT)
518  * @buf: a %PTR_TO_MEM buffer
519  * @buf__sz: the size of the data to transfer
520  *
521  * Returns %0 on success, a negative error code otherwise. This function will immediately
522  * fail if the device is not available, thus can be safely used in IRQ context.
523  */
524 __bpf_kfunc int
525 hid_bpf_try_input_report(struct hid_bpf_ctx *ctx, enum hid_report_type type, u8 *buf,
526 			 const size_t buf__sz)
527 {
528 	struct hid_bpf_ctx_kern *ctx_kern;
529 	bool from_hid_event_hook;
530 
531 	ctx_kern = container_of(ctx, struct hid_bpf_ctx_kern, ctx);
532 	from_hid_event_hook = ctx_kern->data && ctx_kern->data == ctx->hid->bpf.device_data;
533 
534 	return __hid_bpf_input_report(ctx, type, buf, buf__sz, from_hid_event_hook);
535 }
536 
537 /**
538  * hid_bpf_input_report - Inject a HID report in the kernel from a HID device
539  *
540  * @ctx: the HID-BPF context previously allocated in hid_bpf_allocate_context()
541  * @type: the type of the report (%HID_INPUT_REPORT, %HID_FEATURE_REPORT, %HID_OUTPUT_REPORT)
542  * @buf: a %PTR_TO_MEM buffer
543  * @buf__sz: the size of the data to transfer
544  *
545  * Returns %0 on success, a negative error code otherwise. This function will wait for the
546  * device to be available before injecting the event, thus needs to be called in sleepable
547  * context.
548  */
549 __bpf_kfunc int
550 hid_bpf_input_report(struct hid_bpf_ctx *ctx, enum hid_report_type type, u8 *buf,
551 		     const size_t buf__sz)
552 {
553 	int ret;
554 
555 	ret = down_interruptible(&ctx->hid->driver_input_lock);
556 	if (ret)
557 		return ret;
558 
559 	/* check arguments */
560 	ret = __hid_bpf_input_report(ctx, type, buf, buf__sz, true /* lock_already_taken */);
561 
562 	up(&ctx->hid->driver_input_lock);
563 
564 	return ret;
565 }
566 __bpf_kfunc_end_defs();
567 
568 /*
569  * The following set contains all functions we agree BPF programs
570  * can use.
571  */
572 BTF_KFUNCS_START(hid_bpf_kfunc_ids)
573 BTF_ID_FLAGS(func, hid_bpf_get_data, KF_RET_NULL)
574 BTF_ID_FLAGS(func, hid_bpf_allocate_context, KF_ACQUIRE | KF_RET_NULL | KF_SLEEPABLE)
575 BTF_ID_FLAGS(func, hid_bpf_release_context, KF_RELEASE | KF_SLEEPABLE)
576 BTF_ID_FLAGS(func, hid_bpf_hw_request, KF_SLEEPABLE)
577 BTF_ID_FLAGS(func, hid_bpf_hw_output_report, KF_SLEEPABLE)
578 BTF_ID_FLAGS(func, hid_bpf_input_report, KF_SLEEPABLE)
579 BTF_ID_FLAGS(func, hid_bpf_try_input_report)
580 BTF_KFUNCS_END(hid_bpf_kfunc_ids)
581 
582 static const struct btf_kfunc_id_set hid_bpf_kfunc_set = {
583 	.owner = THIS_MODULE,
584 	.set   = &hid_bpf_kfunc_ids,
585 };
586 
587 /* for syscall HID-BPF */
588 BTF_KFUNCS_START(hid_bpf_syscall_kfunc_ids)
589 BTF_ID_FLAGS(func, hid_bpf_allocate_context, KF_ACQUIRE | KF_RET_NULL)
590 BTF_ID_FLAGS(func, hid_bpf_release_context, KF_RELEASE)
591 BTF_ID_FLAGS(func, hid_bpf_hw_request)
592 BTF_ID_FLAGS(func, hid_bpf_hw_output_report)
593 BTF_ID_FLAGS(func, hid_bpf_input_report)
594 BTF_KFUNCS_END(hid_bpf_syscall_kfunc_ids)
595 
596 static const struct btf_kfunc_id_set hid_bpf_syscall_kfunc_set = {
597 	.owner = THIS_MODULE,
598 	.set   = &hid_bpf_syscall_kfunc_ids,
599 };
600 
601 int hid_bpf_connect_device(struct hid_device *hdev)
602 {
603 	bool need_to_allocate = false;
604 	struct hid_bpf_ops *e;
605 
606 	rcu_read_lock();
607 	list_for_each_entry_rcu(e, &hdev->bpf.prog_list, list) {
608 		if (e->hid_device_event) {
609 			need_to_allocate = true;
610 			break;
611 		}
612 	}
613 	rcu_read_unlock();
614 
615 	/* only allocate BPF data if there are programs attached */
616 	if (!need_to_allocate)
617 		return 0;
618 
619 	return hid_bpf_allocate_event_data(hdev);
620 }
621 EXPORT_SYMBOL_GPL(hid_bpf_connect_device);
622 
623 void hid_bpf_disconnect_device(struct hid_device *hdev)
624 {
625 	kfree(hdev->bpf.device_data);
626 	hdev->bpf.device_data = NULL;
627 	hdev->bpf.allocated_data = 0;
628 }
629 EXPORT_SYMBOL_GPL(hid_bpf_disconnect_device);
630 
631 void hid_bpf_destroy_device(struct hid_device *hdev)
632 {
633 	if (!hdev)
634 		return;
635 
636 	/* mark the device as destroyed in bpf so we don't reattach it */
637 	hdev->bpf.destroyed = true;
638 
639 	__hid_bpf_ops_destroy_device(hdev);
640 
641 	synchronize_srcu(&hdev->bpf.srcu);
642 	cleanup_srcu_struct(&hdev->bpf.srcu);
643 }
644 EXPORT_SYMBOL_GPL(hid_bpf_destroy_device);
645 
646 int hid_bpf_device_init(struct hid_device *hdev)
647 {
648 	INIT_LIST_HEAD(&hdev->bpf.prog_list);
649 	mutex_init(&hdev->bpf.prog_list_lock);
650 	return init_srcu_struct(&hdev->bpf.srcu);
651 }
652 EXPORT_SYMBOL_GPL(hid_bpf_device_init);
653 
654 static int __init hid_bpf_init(void)
655 {
656 	int err;
657 
658 	/* Note: if we exit with an error any time here, we would entirely break HID, which
659 	 * is probably not something we want. So we log an error and return success.
660 	 *
661 	 * This is not a big deal: nobody will be able to use the functionality.
662 	 */
663 
664 	err = register_btf_kfunc_id_set(BPF_PROG_TYPE_STRUCT_OPS, &hid_bpf_kfunc_set);
665 	if (err) {
666 		pr_warn("error while setting HID BPF tracing kfuncs: %d", err);
667 		return 0;
668 	}
669 
670 	err = register_btf_kfunc_id_set(BPF_PROG_TYPE_SYSCALL, &hid_bpf_syscall_kfunc_set);
671 	if (err) {
672 		pr_warn("error while setting HID BPF syscall kfuncs: %d", err);
673 		return 0;
674 	}
675 
676 	return 0;
677 }
678 
679 late_initcall(hid_bpf_init);
680 MODULE_AUTHOR("Benjamin Tissoires");
681 MODULE_LICENSE("GPL");
682