0001
0002
0003
0004
0005
0006 #include <linux/bpf.h>
0007 #include <linux/filter.h>
0008 #include <linux/bpf_lirc.h>
0009 #include "rc-core-priv.h"
0010
0011 #define lirc_rcu_dereference(p) \
0012 rcu_dereference_protected(p, lockdep_is_held(&ir_raw_handler_lock))
0013
0014
0015
0016
0017 const struct bpf_prog_ops lirc_mode2_prog_ops = {
0018 };
0019
0020 BPF_CALL_1(bpf_rc_repeat, u32*, sample)
0021 {
0022 struct ir_raw_event_ctrl *ctrl;
0023
0024 ctrl = container_of(sample, struct ir_raw_event_ctrl, bpf_sample);
0025
0026 rc_repeat(ctrl->dev);
0027
0028 return 0;
0029 }
0030
0031 static const struct bpf_func_proto rc_repeat_proto = {
0032 .func = bpf_rc_repeat,
0033 .gpl_only = true,
0034 .ret_type = RET_INTEGER,
0035 .arg1_type = ARG_PTR_TO_CTX,
0036 };
0037
0038 BPF_CALL_4(bpf_rc_keydown, u32*, sample, u32, protocol, u64, scancode,
0039 u32, toggle)
0040 {
0041 struct ir_raw_event_ctrl *ctrl;
0042
0043 ctrl = container_of(sample, struct ir_raw_event_ctrl, bpf_sample);
0044
0045 rc_keydown(ctrl->dev, protocol, scancode, toggle != 0);
0046
0047 return 0;
0048 }
0049
0050 static const struct bpf_func_proto rc_keydown_proto = {
0051 .func = bpf_rc_keydown,
0052 .gpl_only = true,
0053 .ret_type = RET_INTEGER,
0054 .arg1_type = ARG_PTR_TO_CTX,
0055 .arg2_type = ARG_ANYTHING,
0056 .arg3_type = ARG_ANYTHING,
0057 .arg4_type = ARG_ANYTHING,
0058 };
0059
0060 BPF_CALL_3(bpf_rc_pointer_rel, u32*, sample, s32, rel_x, s32, rel_y)
0061 {
0062 struct ir_raw_event_ctrl *ctrl;
0063
0064 ctrl = container_of(sample, struct ir_raw_event_ctrl, bpf_sample);
0065
0066 input_report_rel(ctrl->dev->input_dev, REL_X, rel_x);
0067 input_report_rel(ctrl->dev->input_dev, REL_Y, rel_y);
0068 input_sync(ctrl->dev->input_dev);
0069
0070 return 0;
0071 }
0072
0073 static const struct bpf_func_proto rc_pointer_rel_proto = {
0074 .func = bpf_rc_pointer_rel,
0075 .gpl_only = true,
0076 .ret_type = RET_INTEGER,
0077 .arg1_type = ARG_PTR_TO_CTX,
0078 .arg2_type = ARG_ANYTHING,
0079 .arg3_type = ARG_ANYTHING,
0080 };
0081
0082 static const struct bpf_func_proto *
0083 lirc_mode2_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
0084 {
0085 switch (func_id) {
0086 case BPF_FUNC_rc_repeat:
0087 return &rc_repeat_proto;
0088 case BPF_FUNC_rc_keydown:
0089 return &rc_keydown_proto;
0090 case BPF_FUNC_rc_pointer_rel:
0091 return &rc_pointer_rel_proto;
0092 case BPF_FUNC_map_lookup_elem:
0093 return &bpf_map_lookup_elem_proto;
0094 case BPF_FUNC_map_update_elem:
0095 return &bpf_map_update_elem_proto;
0096 case BPF_FUNC_map_delete_elem:
0097 return &bpf_map_delete_elem_proto;
0098 case BPF_FUNC_map_push_elem:
0099 return &bpf_map_push_elem_proto;
0100 case BPF_FUNC_map_pop_elem:
0101 return &bpf_map_pop_elem_proto;
0102 case BPF_FUNC_map_peek_elem:
0103 return &bpf_map_peek_elem_proto;
0104 case BPF_FUNC_ktime_get_ns:
0105 return &bpf_ktime_get_ns_proto;
0106 case BPF_FUNC_ktime_get_boot_ns:
0107 return &bpf_ktime_get_boot_ns_proto;
0108 case BPF_FUNC_tail_call:
0109 return &bpf_tail_call_proto;
0110 case BPF_FUNC_get_prandom_u32:
0111 return &bpf_get_prandom_u32_proto;
0112 case BPF_FUNC_trace_printk:
0113 if (perfmon_capable())
0114 return bpf_get_trace_printk_proto();
0115 fallthrough;
0116 default:
0117 return NULL;
0118 }
0119 }
0120
0121 static bool lirc_mode2_is_valid_access(int off, int size,
0122 enum bpf_access_type type,
0123 const struct bpf_prog *prog,
0124 struct bpf_insn_access_aux *info)
0125 {
0126
0127 return type == BPF_READ && off == 0 && size == sizeof(u32);
0128 }
0129
0130 const struct bpf_verifier_ops lirc_mode2_verifier_ops = {
0131 .get_func_proto = lirc_mode2_func_proto,
0132 .is_valid_access = lirc_mode2_is_valid_access
0133 };
0134
0135 #define BPF_MAX_PROGS 64
0136
0137 static int lirc_bpf_attach(struct rc_dev *rcdev, struct bpf_prog *prog)
0138 {
0139 struct bpf_prog_array *old_array;
0140 struct bpf_prog_array *new_array;
0141 struct ir_raw_event_ctrl *raw;
0142 int ret;
0143
0144 if (rcdev->driver_type != RC_DRIVER_IR_RAW)
0145 return -EINVAL;
0146
0147 ret = mutex_lock_interruptible(&ir_raw_handler_lock);
0148 if (ret)
0149 return ret;
0150
0151 raw = rcdev->raw;
0152 if (!raw) {
0153 ret = -ENODEV;
0154 goto unlock;
0155 }
0156
0157 old_array = lirc_rcu_dereference(raw->progs);
0158 if (old_array && bpf_prog_array_length(old_array) >= BPF_MAX_PROGS) {
0159 ret = -E2BIG;
0160 goto unlock;
0161 }
0162
0163 ret = bpf_prog_array_copy(old_array, NULL, prog, 0, &new_array);
0164 if (ret < 0)
0165 goto unlock;
0166
0167 rcu_assign_pointer(raw->progs, new_array);
0168 bpf_prog_array_free(old_array);
0169
0170 unlock:
0171 mutex_unlock(&ir_raw_handler_lock);
0172 return ret;
0173 }
0174
0175 static int lirc_bpf_detach(struct rc_dev *rcdev, struct bpf_prog *prog)
0176 {
0177 struct bpf_prog_array *old_array;
0178 struct bpf_prog_array *new_array;
0179 struct ir_raw_event_ctrl *raw;
0180 int ret;
0181
0182 if (rcdev->driver_type != RC_DRIVER_IR_RAW)
0183 return -EINVAL;
0184
0185 ret = mutex_lock_interruptible(&ir_raw_handler_lock);
0186 if (ret)
0187 return ret;
0188
0189 raw = rcdev->raw;
0190 if (!raw) {
0191 ret = -ENODEV;
0192 goto unlock;
0193 }
0194
0195 old_array = lirc_rcu_dereference(raw->progs);
0196 ret = bpf_prog_array_copy(old_array, prog, NULL, 0, &new_array);
0197
0198
0199
0200
0201
0202 if (ret)
0203 goto unlock;
0204
0205 rcu_assign_pointer(raw->progs, new_array);
0206 bpf_prog_array_free(old_array);
0207 bpf_prog_put(prog);
0208 unlock:
0209 mutex_unlock(&ir_raw_handler_lock);
0210 return ret;
0211 }
0212
0213 void lirc_bpf_run(struct rc_dev *rcdev, u32 sample)
0214 {
0215 struct ir_raw_event_ctrl *raw = rcdev->raw;
0216
0217 raw->bpf_sample = sample;
0218
0219 if (raw->progs) {
0220 rcu_read_lock();
0221 bpf_prog_run_array(rcu_dereference(raw->progs),
0222 &raw->bpf_sample, bpf_prog_run);
0223 rcu_read_unlock();
0224 }
0225 }
0226
0227
0228
0229
0230
0231
0232
0233 void lirc_bpf_free(struct rc_dev *rcdev)
0234 {
0235 struct bpf_prog_array_item *item;
0236 struct bpf_prog_array *array;
0237
0238 array = lirc_rcu_dereference(rcdev->raw->progs);
0239 if (!array)
0240 return;
0241
0242 for (item = array->items; item->prog; item++)
0243 bpf_prog_put(item->prog);
0244
0245 bpf_prog_array_free(array);
0246 }
0247
0248 int lirc_prog_attach(const union bpf_attr *attr, struct bpf_prog *prog)
0249 {
0250 struct rc_dev *rcdev;
0251 int ret;
0252
0253 if (attr->attach_flags)
0254 return -EINVAL;
0255
0256 rcdev = rc_dev_get_from_fd(attr->target_fd);
0257 if (IS_ERR(rcdev))
0258 return PTR_ERR(rcdev);
0259
0260 ret = lirc_bpf_attach(rcdev, prog);
0261
0262 put_device(&rcdev->dev);
0263
0264 return ret;
0265 }
0266
0267 int lirc_prog_detach(const union bpf_attr *attr)
0268 {
0269 struct bpf_prog *prog;
0270 struct rc_dev *rcdev;
0271 int ret;
0272
0273 if (attr->attach_flags)
0274 return -EINVAL;
0275
0276 prog = bpf_prog_get_type(attr->attach_bpf_fd,
0277 BPF_PROG_TYPE_LIRC_MODE2);
0278 if (IS_ERR(prog))
0279 return PTR_ERR(prog);
0280
0281 rcdev = rc_dev_get_from_fd(attr->target_fd);
0282 if (IS_ERR(rcdev)) {
0283 bpf_prog_put(prog);
0284 return PTR_ERR(rcdev);
0285 }
0286
0287 ret = lirc_bpf_detach(rcdev, prog);
0288
0289 bpf_prog_put(prog);
0290 put_device(&rcdev->dev);
0291
0292 return ret;
0293 }
0294
0295 int lirc_prog_query(const union bpf_attr *attr, union bpf_attr __user *uattr)
0296 {
0297 __u32 __user *prog_ids = u64_to_user_ptr(attr->query.prog_ids);
0298 struct bpf_prog_array *progs;
0299 struct rc_dev *rcdev;
0300 u32 cnt, flags = 0;
0301 int ret;
0302
0303 if (attr->query.query_flags)
0304 return -EINVAL;
0305
0306 rcdev = rc_dev_get_from_fd(attr->query.target_fd);
0307 if (IS_ERR(rcdev))
0308 return PTR_ERR(rcdev);
0309
0310 if (rcdev->driver_type != RC_DRIVER_IR_RAW) {
0311 ret = -EINVAL;
0312 goto put;
0313 }
0314
0315 ret = mutex_lock_interruptible(&ir_raw_handler_lock);
0316 if (ret)
0317 goto put;
0318
0319 progs = lirc_rcu_dereference(rcdev->raw->progs);
0320 cnt = progs ? bpf_prog_array_length(progs) : 0;
0321
0322 if (copy_to_user(&uattr->query.prog_cnt, &cnt, sizeof(cnt))) {
0323 ret = -EFAULT;
0324 goto unlock;
0325 }
0326
0327 if (copy_to_user(&uattr->query.attach_flags, &flags, sizeof(flags))) {
0328 ret = -EFAULT;
0329 goto unlock;
0330 }
0331
0332 if (attr->query.prog_cnt != 0 && prog_ids && cnt)
0333 ret = bpf_prog_array_copy_to_user(progs, prog_ids,
0334 attr->query.prog_cnt);
0335
0336 unlock:
0337 mutex_unlock(&ir_raw_handler_lock);
0338 put:
0339 put_device(&rcdev->dev);
0340
0341 return ret;
0342 }