[PATCH 3/8] HID: bpf: add helper macros for LE/BE conversion

Benjamin Tissoires posted 8 patches 3 days, 20 hours ago
[PATCH 3/8] HID: bpf: add helper macros for LE/BE conversion
Posted by Benjamin Tissoires 3 days, 20 hours ago
From: Peter Hutterer <peter.hutterer@who-t.net>

BPF has bpf_htons and friends but those only work with data in Big
Endian format. HID is little endian so we need our own macros.

Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/221
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
 drivers/hid/bpf/progs/hid_bpf_helpers.h | 67 +++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/drivers/hid/bpf/progs/hid_bpf_helpers.h b/drivers/hid/bpf/progs/hid_bpf_helpers.h
index 5e3ffca1ed7b..f9071444c938 100644
--- a/drivers/hid/bpf/progs/hid_bpf_helpers.h
+++ b/drivers/hid/bpf/progs/hid_bpf_helpers.h
@@ -7,6 +7,7 @@
 
 #include "vmlinux.h"
 #include <bpf/bpf_helpers.h>
+#include <bpf/bpf_endian.h>
 #include <linux/errno.h>
 
 extern __u8 *hid_bpf_get_data(struct hid_bpf_ctx *ctx,
@@ -263,4 +264,70 @@ DEFINE_GUARD(bpf_spin, struct bpf_spin_lock, bpf_spin_lock, bpf_spin_unlock);
 	_EXPAND(_ARG, __VA_ARGS__) \
 } _device_ids SEC(".hid_bpf_config")
 
+
+/* Equivalency macros for bpf_htons and friends which are
+ * Big Endian only - HID needs little endian so these are the
+ * corresponding macros for that. See bpf/bpf_endian.h
+ */
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+# define __hid_bpf_le16_to_cpu(x)		(x)
+# define __hid_bpf_le32_to_cpu(x)		(x)
+# define __hid_bpf_le64_to_cpu(x)		(x)
+# define __hid_bpf_cpu_to_le16(x)		(x)
+# define __hid_bpf_cpu_to_le32(x)		(x)
+# define __hid_bpf_cpu_to_le64(x)		(x)
+# define __hid_bpf_constant_le16_to_cpu(x)	(x)
+# define __hid_bpf_constant_le32_to_cpu(x)	(x)
+# define __hid_bpf_constant_le64_to_cpu(x)	(x)
+# define __hid_bpf_constant_cpu_to_le16(x)	(x)
+# define __hid_bpf_constant_cpu_to_le32(x)	(x)
+# define __hid_bpf_constant_cpu_to_le64(x)	(x)
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+# define __hid_bpf_le16_to_cpu(x)		__builtin_bswap16(x)
+# define __hid_bpf_le32_to_cpu(x)		__builtin_bswap32(x)
+# define __hid_bpf_le64_to_cpu(x)		__builtin_bswap64(x)
+# define __hid_bpf_cpu_to_le16(x)		__builtin_bswap16(x)
+# define __hid_bpf_cpu_to_le32(x)		__builtin_bswap32(x)
+# define __hid_bpf_cpu_to_le64(x)		__builtin_bswap64(x)
+# define __hid_bpf_constant_le16_to_cpu(x)	__bpf_swab16(x)
+# define __hid_bpf_constant_le32_to_cpu(x)	__bpf_swab32(x)
+# define __hid_bpf_constant_le64_to_cpu(x)	__bpf_swab64(x)
+# define __hid_bpf_constant_cpu_to_le16(x)	__bpf_swab16(x)
+# define __hid_bpf_constant_cpu_to_le32(x)	__bpf_swab32(x)
+# define __hid_bpf_constant_cpu_to_le64(x)	__bpf_swab64(x)
+#else
+# error "Invalid __BYTE_ORDER__"
+#endif
+
+#define hid_bpf_le16_to_cpu(x)				\
+	(__builtin_constant_p(x) ?			\
+	 __hid_bpf_constant_le16_to_cpu(x) : __hid_bpf_le16_to_cpu(x))
+
+#define hid_bpf_le32_to_cpu(x)				\
+	(__builtin_constant_p(x) ?			\
+	 __hid_bpf_constant_le32_to_cpu(x) : __hid_bpf_le32_to_cpu(x))
+
+#define hid_bpf_le64_to_cpu(x)				\
+	(__builtin_constant_p(x) ?			\
+	 __hid_bpf_constant_le64_to_cpu(x) : __hid_bpf_le64_to_cpu(x))
+
+#define hid_bpf_cpu_to_le16(x)				\
+	(__builtin_constant_p(x) ?			\
+	 __hid_bpf_constant_cpu_to_le16(x) : __hid_bpf_cpu_to_le16(x))
+
+#define hid_bpf_cpu_to_le32(x)				\
+	(__builtin_constant_p(x) ?			\
+	 __hid_bpf_constant_cpu_to_le32(x) : __hid_bpf_cpu_to_le32(x))
+
+#define hid_bpf_cpu_to_le64(x)				\
+	(__builtin_constant_p(x) ?			\
+	 __hid_bpf_constant_cpu_to_le64(x) : __hid_bpf_cpu_to_le64(x))
+
+#define hid_bpf_be16_to_cpu(x)	bpf_ntohs(x)
+#define hid_bpf_be32_to_cpu(x)	bpf_ntohl(x)
+#define hid_bpf_be64_to_cpu(x)	bpf_be64_to_cpu(x)
+#define hid_bpf_cpu_to_be16(x)	bpf_htons(x)
+#define hid_bpf_cpu_to_be32(x)	bpf_htonl(x)
+#define hid_bpf_cpu_to_be64(x)	bpf_cpu_to_be64(x)
+
 #endif /* __HID_BPF_HELPERS_H */

-- 
2.53.0