1 | /* SPDX-License-Identifier: GPL-2.0+ */ |
2 | |
3 | #ifndef __HID_BPF_H |
4 | #define __HID_BPF_H |
5 | |
6 | #include <linux/bpf.h> |
7 | #include <linux/spinlock.h> |
8 | #include <uapi/linux/hid.h> |
9 | |
10 | struct hid_device; |
11 | |
12 | /* |
13 | * The following is the user facing HID BPF API. |
14 | * |
15 | * Extra care should be taken when editing this part, as |
16 | * it might break existing out of the tree bpf programs. |
17 | */ |
18 | |
19 | /** |
20 | * struct hid_bpf_ctx - User accessible data for all HID programs |
21 | * |
22 | * ``data`` is not directly accessible from the context. We need to issue |
23 | * a call to ``hid_bpf_get_data()`` in order to get a pointer to that field. |
24 | * |
25 | * All of these fields are currently read-only. |
26 | * |
27 | * @index: program index in the jump table. No special meaning (a smaller index |
28 | * doesn't mean the program will be executed before another program with |
29 | * a bigger index). |
30 | * @hid: the ``struct hid_device`` representing the device itself |
31 | * @report_type: used for ``hid_bpf_device_event()`` |
32 | * @allocated_size: Allocated size of data. |
33 | * |
34 | * This is how much memory is available and can be requested |
35 | * by the HID program. |
36 | * Note that for ``HID_BPF_RDESC_FIXUP``, that memory is set to |
37 | * ``4096`` (4 KB) |
38 | * @size: Valid data in the data field. |
39 | * |
40 | * Programs can get the available valid size in data by fetching this field. |
41 | * Programs can also change this value by returning a positive number in the |
42 | * program. |
43 | * To discard the event, return a negative error code. |
44 | * |
45 | * ``size`` must always be less or equal than ``allocated_size`` (it is enforced |
46 | * once all BPF programs have been run). |
47 | * @retval: Return value of the previous program. |
48 | */ |
49 | struct hid_bpf_ctx { |
50 | __u32 index; |
51 | const struct hid_device *hid; |
52 | __u32 allocated_size; |
53 | enum hid_report_type report_type; |
54 | union { |
55 | __s32 retval; |
56 | __s32 size; |
57 | }; |
58 | }; |
59 | |
60 | /** |
61 | * enum hid_bpf_attach_flags - flags used when attaching a HIF-BPF program |
62 | * |
63 | * @HID_BPF_FLAG_NONE: no specific flag is used, the kernel choses where to |
64 | * insert the program |
65 | * @HID_BPF_FLAG_INSERT_HEAD: insert the given program before any other program |
66 | * currently attached to the device. This doesn't |
67 | * guarantee that this program will always be first |
68 | * @HID_BPF_FLAG_MAX: sentinel value, not to be used by the callers |
69 | */ |
70 | enum hid_bpf_attach_flags { |
71 | HID_BPF_FLAG_NONE = 0, |
72 | HID_BPF_FLAG_INSERT_HEAD = _BITUL(0), |
73 | HID_BPF_FLAG_MAX, |
74 | }; |
75 | |
76 | /* Following functions are tracepoints that BPF programs can attach to */ |
77 | int hid_bpf_device_event(struct hid_bpf_ctx *ctx); |
78 | int hid_bpf_rdesc_fixup(struct hid_bpf_ctx *ctx); |
79 | |
80 | /* |
81 | * Below is HID internal |
82 | */ |
83 | |
84 | /* internal function to call eBPF programs, not to be used by anybody */ |
85 | int __hid_bpf_tail_call(struct hid_bpf_ctx *ctx); |
86 | |
87 | #define HID_BPF_MAX_PROGS_PER_DEV 64 |
88 | #define HID_BPF_FLAG_MASK (((HID_BPF_FLAG_MAX - 1) << 1) - 1) |
89 | |
90 | /* types of HID programs to attach to */ |
91 | enum hid_bpf_prog_type { |
92 | HID_BPF_PROG_TYPE_UNDEF = -1, |
93 | HID_BPF_PROG_TYPE_DEVICE_EVENT, /* an event is emitted from the device */ |
94 | HID_BPF_PROG_TYPE_RDESC_FIXUP, |
95 | HID_BPF_PROG_TYPE_MAX, |
96 | }; |
97 | |
98 | struct hid_report_enum; |
99 | |
100 | struct hid_bpf_ops { |
101 | struct hid_report *(*hid_get_report)(struct hid_report_enum *report_enum, const u8 *data); |
102 | int (*hid_hw_raw_request)(struct hid_device *hdev, |
103 | unsigned char reportnum, __u8 *buf, |
104 | size_t len, enum hid_report_type rtype, |
105 | enum hid_class_request reqtype); |
106 | struct module *owner; |
107 | const struct bus_type *bus_type; |
108 | }; |
109 | |
110 | extern struct hid_bpf_ops *hid_bpf_ops; |
111 | |
112 | struct hid_bpf_prog_list { |
113 | u16 prog_idx[HID_BPF_MAX_PROGS_PER_DEV]; |
114 | u8 prog_cnt; |
115 | }; |
116 | |
117 | /* stored in each device */ |
118 | struct hid_bpf { |
119 | u8 *device_data; /* allocated when a bpf program of type |
120 | * SEC(f.../hid_bpf_device_event) has been attached |
121 | * to this HID device |
122 | */ |
123 | u32 allocated_data; |
124 | |
125 | struct hid_bpf_prog_list __rcu *progs[HID_BPF_PROG_TYPE_MAX]; /* attached BPF progs */ |
126 | bool destroyed; /* prevents the assignment of any progs */ |
127 | |
128 | spinlock_t progs_lock; /* protects RCU update of progs */ |
129 | }; |
130 | |
131 | /* specific HID-BPF link when a program is attached to a device */ |
132 | struct hid_bpf_link { |
133 | struct bpf_link link; |
134 | int hid_table_index; |
135 | }; |
136 | |
137 | #ifdef CONFIG_HID_BPF |
138 | u8 *dispatch_hid_bpf_device_event(struct hid_device *hid, enum hid_report_type type, u8 *data, |
139 | u32 *size, int interrupt); |
140 | int hid_bpf_connect_device(struct hid_device *hdev); |
141 | void hid_bpf_disconnect_device(struct hid_device *hdev); |
142 | void hid_bpf_destroy_device(struct hid_device *hid); |
143 | void hid_bpf_device_init(struct hid_device *hid); |
144 | u8 *call_hid_bpf_rdesc_fixup(struct hid_device *hdev, u8 *rdesc, unsigned int *size); |
145 | #else /* CONFIG_HID_BPF */ |
146 | static inline u8 *dispatch_hid_bpf_device_event(struct hid_device *hid, enum hid_report_type type, |
147 | u8 *data, u32 *size, int interrupt) { return data; } |
148 | static inline int hid_bpf_connect_device(struct hid_device *hdev) { return 0; } |
149 | static inline void hid_bpf_disconnect_device(struct hid_device *hdev) {} |
150 | static inline void hid_bpf_destroy_device(struct hid_device *hid) {} |
151 | static inline void hid_bpf_device_init(struct hid_device *hid) {} |
152 | static inline u8 *call_hid_bpf_rdesc_fixup(struct hid_device *hdev, u8 *rdesc, unsigned int *size) |
153 | { |
154 | return kmemdup(rdesc, *size, GFP_KERNEL); |
155 | } |
156 | |
157 | #endif /* CONFIG_HID_BPF */ |
158 | |
159 | #endif /* __HID_BPF_H */ |
160 | |