xref: /linux/drivers/hid/bpf/progs/hid_bpf_helpers.h (revision fbf5df34a4dbcd09d433dd4f0916bf9b2ddb16de)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /* Copyright (c) 2022 Benjamin Tissoires
3  */
4 
5 #ifndef __HID_BPF_HELPERS_H
6 #define __HID_BPF_HELPERS_H
7 
8 #include "vmlinux.h"
9 #include <bpf/bpf_helpers.h>
10 #include <bpf/bpf_endian.h>
11 #include <linux/errno.h>
12 #include "hid_report_descriptor_helpers.h"
13 
14 /* Compiler attributes */
15 #ifndef __packed
16 #define __packed __attribute__((packed))
17 #endif
18 
19 #ifndef __maybe_unused
20 #define __maybe_unused __attribute__((__unused__))
21 #endif
22 
23 extern __u8 *hid_bpf_get_data(struct hid_bpf_ctx *ctx,
24 			      unsigned int offset,
25 			      const size_t __sz) __ksym;
26 extern struct hid_bpf_ctx *hid_bpf_allocate_context(unsigned int hid_id) __ksym;
27 extern void hid_bpf_release_context(struct hid_bpf_ctx *ctx) __ksym;
28 extern int hid_bpf_hw_request(struct hid_bpf_ctx *ctx,
29 			      __u8 *data,
30 			      size_t buf__sz,
31 			      enum hid_report_type type,
32 			      enum hid_class_request reqtype) __ksym;
33 extern int hid_bpf_hw_output_report(struct hid_bpf_ctx *ctx,
34 				    __u8 *buf, size_t buf__sz) __weak __ksym;
35 extern int hid_bpf_input_report(struct hid_bpf_ctx *ctx,
36 				enum hid_report_type type,
37 				__u8 *data,
38 				size_t buf__sz) __weak __ksym;
39 extern int hid_bpf_try_input_report(struct hid_bpf_ctx *ctx,
40 				    enum hid_report_type type,
41 				    __u8 *data,
42 				    size_t buf__sz) __weak __ksym;
43 
44 /* bpf_wq implementation */
45 extern int bpf_wq_init(struct bpf_wq *wq, void *p__map, unsigned int flags) __weak __ksym;
46 extern int bpf_wq_start(struct bpf_wq *wq, unsigned int flags) __weak __ksym;
47 extern int bpf_wq_set_callback(struct bpf_wq *wq,
48 		int (*callback_fn)(void *, int *, void *),
49 		unsigned int flags) __weak __ksym;
50 
51 #define HID_MAX_DESCRIPTOR_SIZE	4096
52 #define HID_IGNORE_EVENT	-1
53 
54 /**
55  * Use: _cleanup_(somefunction) struct foo *bar;
56  */
57 #define _cleanup_(_x) __attribute__((cleanup(_x)))
58 
59 /**
60  * Use: _release_(foo) *bar;
61  *
62  * This requires foo_releasep() to be present, use DEFINE_RELEASE_CLEANUP_FUNC.
63  */
64 #define _release_(_type) struct _type __attribute__((cleanup(_type##_releasep)))
65 
66 /**
67  * Define a cleanup function for the struct type foo with a matching
68  * foo_release(). Use:
69  * DEFINE_RELEASE_CLEANUP_FUNC(foo)
70  * _unref_(foo) struct foo *bar;
71  */
72 #define DEFINE_RELEASE_CLEANUP_FUNC(_type)				\
73 	static inline void _type##_releasep(struct _type **_p) {	\
74 		if (*_p)						\
75 			_type##_release(*_p);				\
76 	}								\
77 	struct __useless_struct_to_allow_trailing_semicolon__
78 
79 /* for being able to have a cleanup function */
80 #define hid_bpf_ctx_release hid_bpf_release_context
81 DEFINE_RELEASE_CLEANUP_FUNC(hid_bpf_ctx);
82 
83 /*
84  * Kernel-style guard macros adapted for BPF
85  * Based on include/linux/cleanup.h from the Linux kernel
86  *
87  * These provide automatic lock/unlock using __attribute__((cleanup))
88  * similar to how _release_() works for contexts.
89  */
90 
91 /**
92  * DEFINE_GUARD(name, type, lock, unlock):
93  *	Define a guard for automatic lock/unlock using the same pattern as _release_()
94  *	@name: identifier for the guard (e.g., bpf_spin)
95  *	@type: lock variable type (e.g., struct bpf_spin_lock)
96  *	@lock: lock function name (e.g., bpf_spin_lock)
97  *	@unlock: unlock function name (e.g., bpf_spin_unlock)
98  *
99  * guard(name):
100  *	Declare and lock in one statement - lock held until end of scope
101  *
102  * Example:
103  *	DEFINE_GUARD(bpf_spin, struct bpf_spin_lock, bpf_spin_lock, bpf_spin_unlock)
104  *
105  *	void foo(struct bpf_spin_lock *lock) {
106  *		guard(bpf_spin)(lock);
107  *		// lock held until end of scope
108  *	}
109  */
110 
111 /* Guard helper struct - stores lock pointer for cleanup */
112 #define DEFINE_GUARD(_name, _type, _lock, _unlock)			\
113 struct _name##_guard {							\
114 	_type *lock;							\
115 };									\
116 static inline void _name##_guard_cleanup(struct _name##_guard *g) {	\
117 	if (g && g->lock) 						\
118 		_unlock(g->lock);					\
119 }									\
120 static inline struct _name##_guard _name##_guard_init(_type *l) {	\
121 	if (l)								\
122 		_lock(l);						\
123 	return (struct _name##_guard){.lock = l};			\
124 }									\
125 struct __useless_struct_to_allow_trailing_semicolon__
126 
127 #define guard(_name) \
128 	struct _name##_guard COMBINE(guard, __LINE__) __attribute__((cleanup(_name##_guard_cleanup))) = \
129 		_name##_guard_init
130 
131 /* Define BPF spinlock guard */
132 DEFINE_GUARD(bpf_spin, struct bpf_spin_lock, bpf_spin_lock, bpf_spin_unlock);
133 
134 /* extracted from <linux/input.h> */
135 #define BUS_ANY			0x00
136 #define BUS_PCI			0x01
137 #define BUS_ISAPNP		0x02
138 #define BUS_USB			0x03
139 #define BUS_HIL			0x04
140 #define BUS_BLUETOOTH		0x05
141 #define BUS_VIRTUAL		0x06
142 #define BUS_ISA			0x10
143 #define BUS_I8042		0x11
144 #define BUS_XTKBD		0x12
145 #define BUS_RS232		0x13
146 #define BUS_GAMEPORT		0x14
147 #define BUS_PARPORT		0x15
148 #define BUS_AMIGA		0x16
149 #define BUS_ADB			0x17
150 #define BUS_I2C			0x18
151 #define BUS_HOST		0x19
152 #define BUS_GSC			0x1A
153 #define BUS_ATARI		0x1B
154 #define BUS_SPI			0x1C
155 #define BUS_RMI			0x1D
156 #define BUS_CEC			0x1E
157 #define BUS_INTEL_ISHTP		0x1F
158 #define BUS_AMD_SFH		0x20
159 
160 /* extracted from <linux/hid.h> */
161 #define HID_GROUP_ANY				0x0000
162 #define HID_GROUP_GENERIC			0x0001
163 #define HID_GROUP_MULTITOUCH			0x0002
164 #define HID_GROUP_SENSOR_HUB			0x0003
165 #define HID_GROUP_MULTITOUCH_WIN_8		0x0004
166 #define HID_GROUP_RMI				0x0100
167 #define HID_GROUP_WACOM				0x0101
168 #define HID_GROUP_LOGITECH_DJ_DEVICE		0x0102
169 #define HID_GROUP_STEAM				0x0103
170 #define HID_GROUP_LOGITECH_27MHZ_DEVICE		0x0104
171 #define HID_GROUP_VIVALDI			0x0105
172 
173 /* include/linux/mod_devicetable.h defines as (~0), but that gives us negative size arrays */
174 #define HID_VID_ANY				0x0000
175 #define HID_PID_ANY				0x0000
176 
177 #define BIT(n) (1UL << (n))
178 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
179 
180 /* Helper macro to convert (foo, __LINE__)  into foo134 so we can use __LINE__ for
181  * field/variable names
182  */
183 #define COMBINE1(X, Y) X ## Y
184 #define COMBINE(X, Y) COMBINE1(X, Y)
185 
186 /* Macro magic:
187  * __uint(foo, 123) creates a int (*foo)[1234]
188  *
189  * We use that macro to declare an anonymous struct with several
190  * fields, each is the declaration of an pointer to an array of size
191  * bus/group/vid/pid. (Because it's a pointer to such an array, actual storage
192  * would be sizeof(pointer) rather than sizeof(array). Not that we ever
193  * instantiate it anyway).
194  *
195  * This is only used for BTF introspection, we can later check "what size
196  * is the bus array" in the introspection data and thus extract the bus ID
197  * again.
198  *
199  * And we use the __LINE__ to give each of our structs a unique name so the
200  * BPF program writer doesn't have to.
201  *
202  * $ bpftool btf dump file target/bpf/HP_Elite_Presenter.bpf.o
203  * shows the inspection data, start by searching for .hid_bpf_config
204  * and working backwards from that (each entry references the type_id of the
205  * content).
206  */
207 
208 #define HID_DEVICE(b, g, ven, prod)	\
209 	struct {			\
210 		__uint(name, 0);	\
211 		__uint(bus, (b));	\
212 		__uint(group, (g));	\
213 		__uint(vid, (ven));	\
214 		__uint(pid, (prod));	\
215 	} COMBINE(_entry, __LINE__)
216 
217 /* Macro magic below is to make HID_BPF_CONFIG() look like a function call that
218  * we can pass multiple HID_DEVICE() invocations in.
219  *
220  * For up to 16 arguments, HID_BPF_CONFIG(one, two) resolves to
221  *
222  * union {
223  *    HID_DEVICE(...);
224  *    HID_DEVICE(...);
225  * } _device_ids SEC(".hid_bpf_config")
226  *
227  */
228 
229 /* Returns the number of macro arguments, this expands
230  * NARGS(a, b, c) to NTH_ARG(a, b, c, 15, 14, 13, .... 4, 3, 2, 1).
231  * NTH_ARG always returns the 16th argument which in our case is 3.
232  *
233  * If we want more than 16 values _COUNTDOWN and _NTH_ARG both need to be
234  * updated.
235  */
236 #define _NARGS(...)  _NARGS1(__VA_ARGS__, _COUNTDOWN)
237 #define _NARGS1(...) _NTH_ARG(__VA_ARGS__)
238 
239 /* Add to this if we need more than 16 args */
240 #define _COUNTDOWN \
241 	15, 14, 13, 12, 11, 10, 9, 8,  \
242 	 7,  6,  5,  4,  3,  2, 1, 0
243 
244 /* Return the 16 argument passed in. See _NARGS above for usage. Note this is
245  * 1-indexed.
246  */
247 #define _NTH_ARG( \
248 	_1,  _2,  _3,  _4,  _5,  _6,  _7, _8, \
249 	_9, _10, _11, _12, _13, _14, _15,\
250 	 N, ...) N
251 
252 /* Turns EXPAND(_ARG, a, b, c) into _ARG3(a, b, c) */
253 #define _EXPAND(func, ...) COMBINE(func, _NARGS(__VA_ARGS__)) (__VA_ARGS__)
254 
255 /* And now define all the ARG macros for each number of args we want to accept */
256 #define _ARG1(_1)                                                         _1;
257 #define _ARG2(_1, _2)                                                     _1; _2;
258 #define _ARG3(_1, _2, _3)                                                 _1; _2; _3;
259 #define _ARG4(_1, _2, _3, _4)                                             _1; _2; _3; _4;
260 #define _ARG5(_1, _2, _3, _4, _5)                                         _1; _2; _3; _4; _5;
261 #define _ARG6(_1, _2, _3, _4, _5, _6)                                     _1; _2; _3; _4; _5; _6;
262 #define _ARG7(_1, _2, _3, _4, _5, _6, _7)                                 _1; _2; _3; _4; _5; _6; _7;
263 #define _ARG8(_1, _2, _3, _4, _5, _6, _7, _8)                             _1; _2; _3; _4; _5; _6; _7; _8;
264 #define _ARG9(_1, _2, _3, _4, _5, _6, _7, _8, _9)                         _1; _2; _3; _4; _5; _6; _7; _8; _9;
265 #define _ARG10(_1, _2, _3, _4, _5, _6, _7, _8, _9, _a)                     _1; _2; _3; _4; _5; _6; _7; _8; _9; _a;
266 #define _ARG11(_1, _2, _3, _4, _5, _6, _7, _8, _9, _a, _b)                 _1; _2; _3; _4; _5; _6; _7; _8; _9; _a; _b;
267 #define _ARG12(_1, _2, _3, _4, _5, _6, _7, _8, _9, _a, _b, _c)             _1; _2; _3; _4; _5; _6; _7; _8; _9; _a; _b; _c;
268 #define _ARG13(_1, _2, _3, _4, _5, _6, _7, _8, _9, _a, _b, _c, _d)         _1; _2; _3; _4; _5; _6; _7; _8; _9; _a; _b; _c; _d;
269 #define _ARG14(_1, _2, _3, _4, _5, _6, _7, _8, _9, _a, _b, _c, _d, _e)     _1; _2; _3; _4; _5; _6; _7; _8; _9; _a; _b; _c; _d; _e;
270 #define _ARG15(_1, _2, _3, _4, _5, _6, _7, _8, _9, _a, _b, _c, _d, _e, _f) _1; _2; _3; _4; _5; _6; _7; _8; _9; _a; _b; _c; _d; _e; _f;
271 
272 
273 #define HID_BPF_CONFIG(...)  union { \
274 	_EXPAND(_ARG, __VA_ARGS__) \
275 } _device_ids SEC(".hid_bpf_config")
276 
277 
278 /* Equivalency macros for bpf_htons and friends which are
279  * Big Endian only - HID needs little endian so these are the
280  * corresponding macros for that. See bpf/bpf_endian.h
281  */
282 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
283 # define __hid_bpf_le16_to_cpu(x)		(x)
284 # define __hid_bpf_le32_to_cpu(x)		(x)
285 # define __hid_bpf_le64_to_cpu(x)		(x)
286 # define __hid_bpf_cpu_to_le16(x)		(x)
287 # define __hid_bpf_cpu_to_le32(x)		(x)
288 # define __hid_bpf_cpu_to_le64(x)		(x)
289 # define __hid_bpf_constant_le16_to_cpu(x)	(x)
290 # define __hid_bpf_constant_le32_to_cpu(x)	(x)
291 # define __hid_bpf_constant_le64_to_cpu(x)	(x)
292 # define __hid_bpf_constant_cpu_to_le16(x)	(x)
293 # define __hid_bpf_constant_cpu_to_le32(x)	(x)
294 # define __hid_bpf_constant_cpu_to_le64(x)	(x)
295 #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
296 # define __hid_bpf_le16_to_cpu(x)		__builtin_bswap16(x)
297 # define __hid_bpf_le32_to_cpu(x)		__builtin_bswap32(x)
298 # define __hid_bpf_le64_to_cpu(x)		__builtin_bswap64(x)
299 # define __hid_bpf_cpu_to_le16(x)		__builtin_bswap16(x)
300 # define __hid_bpf_cpu_to_le32(x)		__builtin_bswap32(x)
301 # define __hid_bpf_cpu_to_le64(x)		__builtin_bswap64(x)
302 # define __hid_bpf_constant_le16_to_cpu(x)	__bpf_swab16(x)
303 # define __hid_bpf_constant_le32_to_cpu(x)	__bpf_swab32(x)
304 # define __hid_bpf_constant_le64_to_cpu(x)	__bpf_swab64(x)
305 # define __hid_bpf_constant_cpu_to_le16(x)	__bpf_swab16(x)
306 # define __hid_bpf_constant_cpu_to_le32(x)	__bpf_swab32(x)
307 # define __hid_bpf_constant_cpu_to_le64(x)	__bpf_swab64(x)
308 #else
309 # error "Invalid __BYTE_ORDER__"
310 #endif
311 
312 #define hid_bpf_le16_to_cpu(x)				\
313 	(__builtin_constant_p(x) ?			\
314 	 __hid_bpf_constant_le16_to_cpu(x) : __hid_bpf_le16_to_cpu(x))
315 
316 #define hid_bpf_le32_to_cpu(x)				\
317 	(__builtin_constant_p(x) ?			\
318 	 __hid_bpf_constant_le32_to_cpu(x) : __hid_bpf_le32_to_cpu(x))
319 
320 #define hid_bpf_le64_to_cpu(x)				\
321 	(__builtin_constant_p(x) ?			\
322 	 __hid_bpf_constant_le64_to_cpu(x) : __hid_bpf_le64_to_cpu(x))
323 
324 #define hid_bpf_cpu_to_le16(x)				\
325 	(__builtin_constant_p(x) ?			\
326 	 __hid_bpf_constant_cpu_to_le16(x) : __hid_bpf_cpu_to_le16(x))
327 
328 #define hid_bpf_cpu_to_le32(x)				\
329 	(__builtin_constant_p(x) ?			\
330 	 __hid_bpf_constant_cpu_to_le32(x) : __hid_bpf_cpu_to_le32(x))
331 
332 #define hid_bpf_cpu_to_le64(x)				\
333 	(__builtin_constant_p(x) ?			\
334 	 __hid_bpf_constant_cpu_to_le64(x) : __hid_bpf_cpu_to_le64(x))
335 
336 #define hid_bpf_be16_to_cpu(x)	bpf_ntohs(x)
337 #define hid_bpf_be32_to_cpu(x)	bpf_ntohl(x)
338 #define hid_bpf_be64_to_cpu(x)	bpf_be64_to_cpu(x)
339 #define hid_bpf_cpu_to_be16(x)	bpf_htons(x)
340 #define hid_bpf_cpu_to_be32(x)	bpf_htonl(x)
341 #define hid_bpf_cpu_to_be64(x)	bpf_cpu_to_be64(x)
342 
343 /*
344  * The following macros are helpers for exporting udev properties:
345  *
346  * EXPORT_UDEV_PROP(name, len) generates:
347  *  - a map with a single element UDEV_PROP_##name, of size len
348  *  - a const global declaration of that len: SIZEOF_##name
349  *
350  * udev_prop_ptr(name) retrieves the data pointer behind the map.
351  *
352  * UDEV_PROP_SPRINTF(name, fmt, ...) writes data into the udev property.
353  *
354  *  Can be used as such:
355  *  EXPORT_UDEV_PROP(HID_FOO, 32);
356  *
357  *  SEC("syscall")
358  *  int probe(struct hid_bpf_probe_args *ctx)
359  *  {
360  *    const char *foo = "foo";
361  *    UDEV_PROP_SPRINTF(HID_FOO, "%s", foo);
362  *
363  *    return 0;
364  *  }
365  */
366 #define EXPORT_UDEV_PROP(name, len) \
367 	const __u32 SIZEOF_##name = len; \
368 	struct COMBINE(udev_prop, __LINE__) { \
369 		__uint(type, BPF_MAP_TYPE_ARRAY); \
370 		__uint(max_entries, 1); \
371 		__type(key, __u32); \
372 		__type(value, __u8[len]); \
373 	} UDEV_PROP_##name SEC(".maps");
374 
375 #define udev_prop_ptr(name) \
376 	bpf_map_lookup_elem(&UDEV_PROP_##name, &(__u32){0})
377 
378 #define UDEV_PROP_SPRINTF(name, fmt, ...) \
379 	BPF_SNPRINTF(udev_prop_ptr(name), SIZEOF_##name, fmt, ##__VA_ARGS__)
380 
381 static inline __maybe_unused __u16 field_start_byte(struct hid_rdesc_field *field)
382 {
383 	return field->bits_start / 8;
384 }
385 
386 static inline __maybe_unused __u16 field_end_byte(struct hid_rdesc_field *field)
387 {
388 	if (!field->bits_end)
389 		return 0;
390 
391 	return (__u16)(field->bits_end - 1) / 8;
392 }
393 
394 static __maybe_unused __u32 extract_bits(__u8 *buffer, const size_t size, struct hid_rdesc_field *field)
395 {
396 	__s32 nbits = field->bits_end - field->bits_start;
397 	__u32 start = field_start_byte(field);
398 	__u32 end = field_end_byte(field);
399 	__u8 base_shift = field->bits_start % 8;
400 
401 	if (nbits <= 0 || nbits > 32 || start >= size || end >= size)
402 		return 0;
403 
404 	/* Fast path for byte-aligned standard-sized reads */
405 	if (base_shift == 0) {
406 		/* 8-bit aligned read */
407 		if (nbits == 8 && start < size)
408 			return buffer[start];
409 
410 		/* 16-bit aligned read - use separate variables for verifier */
411 		if (nbits == 16) {
412 			__u32 off0 = start;
413 			__u32 off1 = start + 1;
414 
415 			if (off0 < size && off1 < size) {
416 				return buffer[off0] |
417 				       ((__u32)buffer[off1] << 8);
418 			}
419 		}
420 
421 		/* 32-bit aligned read - use separate variables for verifier */
422 		if (nbits == 32) {
423 			__u32 off0 = start;
424 			__u32 off1 = start + 1;
425 			__u32 off2 = start + 2;
426 			__u32 off3 = start + 3;
427 
428 			if (off0 < size && off1 < size &&
429 			    off2 < size && off3 < size) {
430 				return buffer[off0] |
431 				       ((__u32)buffer[off1] << 8) |
432 				       ((__u32)buffer[off2] << 16) |
433 				       ((__u32)buffer[off3] << 24);
434 			}
435 		}
436 	}
437 
438 	/* General case: bit manipulation for unaligned or non-standard sizes */
439 	int mask = 0xffffffff >> (32 - nbits);
440 	__u64 value = 0;
441 	__u32 i;
442 
443 	bpf_for (i, start, end + 1) {
444 		value |= (__u64)buffer[i] << ((i - start) * 8);
445 	}
446 
447 	return (value >> base_shift) & mask;
448 }
449 
450 #define EXTRACT_BITS(buffer, field) extract_bits(buffer, sizeof(buffer), field)
451 
452 /* Base macro for iterating over HID arrays with bounds checking.
453  * Follows the bpf_for pattern from libbpf.
454  */
455 #define __hid_bpf_for_each_array(array, num_elements, max_elements, var)              \
456 	for (                                                                          \
457 		/* initialize and define destructor */                                 \
458 		struct bpf_iter_num ___it __attribute__((aligned(8),                   \
459 							 cleanup(bpf_iter_num_destroy))),      \
460 		/* ___p pointer is necessary to call bpf_iter_num_new() *once* */      \
461 				    *___p __attribute__((unused)) = (                  \
462 			/* always initialize iterator; if bounds fail, iterate 0 times */ \
463 			bpf_iter_num_new(&___it, 0,                                    \
464 					 (num_elements) > (max_elements) ?             \
465 						0 : (num_elements)),                   \
466 			/* workaround for Clang bug */                                 \
467 			(void)bpf_iter_num_destroy, (void *)0);                        \
468 		({                                                                     \
469 			/* iteration step */                                           \
470 			int *___t = bpf_iter_num_next(&___it);                         \
471 			int ___i;                                                      \
472 			/* termination and bounds check, assign var */                 \
473 			(___t && (___i = *___t, ___i >= 0 && ___i < (num_elements)) && \
474 			 ((num_elements) <= (max_elements)) &&                         \
475 			 (var = &(array)[___i], 1));                                   \
476 		});                                                                    \
477 	)
478 
479 /* Iterate over input reports in a descriptor */
480 #define hid_bpf_for_each_input_report(descriptor, report_var) \
481 	__hid_bpf_for_each_array((descriptor)->input_reports, \
482 				 (descriptor)->num_input_reports, \
483 				 HID_MAX_REPORTS, report_var)
484 
485 /* Iterate over feature reports in a descriptor */
486 #define hid_bpf_for_each_feature_report(descriptor, report_var) \
487 	__hid_bpf_for_each_array((descriptor)->feature_reports, \
488 				 (descriptor)->num_feature_reports, \
489 				 HID_MAX_REPORTS, report_var)
490 
491 /* Iterate over output reports in a descriptor */
492 #define hid_bpf_for_each_output_report(descriptor, report_var) \
493 	__hid_bpf_for_each_array((descriptor)->output_reports, \
494 				 (descriptor)->num_output_reports, \
495 				 HID_MAX_REPORTS, report_var)
496 
497 /* Iterate over fields in a report */
498 #define hid_bpf_for_each_field(report, field_var) \
499 	__hid_bpf_for_each_array((report)->fields, (report)->num_fields, \
500 				 HID_MAX_FIELDS, field_var)
501 
502 /* Iterate over collections in a field */
503 #define hid_bpf_for_each_collection(field, collection_var) \
504 	__hid_bpf_for_each_array((field)->collections, (field)->num_collections, \
505 				 HID_MAX_COLLECTIONS, collection_var)
506 
507 #endif /* __HID_BPF_HELPERS_H */
508