staticconststruct bpf_func_proto *
lirc_mode2_func_proto(enum bpf_func_id func_id, conststruct bpf_prog *prog)
{ switch (func_id) { case BPF_FUNC_rc_repeat: return &rc_repeat_proto; case BPF_FUNC_rc_keydown: return &rc_keydown_proto; case BPF_FUNC_rc_pointer_rel: return &rc_pointer_rel_proto; case BPF_FUNC_map_lookup_elem: return &bpf_map_lookup_elem_proto; case BPF_FUNC_map_update_elem: return &bpf_map_update_elem_proto; case BPF_FUNC_map_delete_elem: return &bpf_map_delete_elem_proto; case BPF_FUNC_map_push_elem: return &bpf_map_push_elem_proto; case BPF_FUNC_map_pop_elem: return &bpf_map_pop_elem_proto; case BPF_FUNC_map_peek_elem: return &bpf_map_peek_elem_proto; case BPF_FUNC_ktime_get_ns: return &bpf_ktime_get_ns_proto; case BPF_FUNC_ktime_get_boot_ns: return &bpf_ktime_get_boot_ns_proto; case BPF_FUNC_tail_call: return &bpf_tail_call_proto; case BPF_FUNC_get_prandom_u32: return &bpf_get_prandom_u32_proto; case BPF_FUNC_trace_printk: if (bpf_token_capable(prog->aux->token, CAP_PERFMON)) return bpf_get_trace_printk_proto();
fallthrough; default: return NULL;
}
}
staticbool lirc_mode2_is_valid_access(int off, int size, enum bpf_access_type type, conststruct bpf_prog *prog, struct bpf_insn_access_aux *info)
{ /* We have one field of u32 */ return type == BPF_READ && off == 0 && size == sizeof(u32);
}
if (rcdev->driver_type != RC_DRIVER_IR_RAW) return -EINVAL;
ret = mutex_lock_interruptible(&ir_raw_handler_lock); if (ret) return ret;
raw = rcdev->raw; if (!raw) {
ret = -ENODEV; goto unlock;
}
old_array = lirc_rcu_dereference(raw->progs);
ret = bpf_prog_array_copy(old_array, prog, NULL, 0, &new_array); /* * Do not use bpf_prog_array_delete_safe() as we would end up * with a dummy entry in the array, and the we would free the * dummy in lirc_bpf_free()
*/ if (ret) goto unlock;
if (raw->progs) {
rcu_read_lock();
bpf_prog_run_array(rcu_dereference(raw->progs),
&raw->bpf_sample, bpf_prog_run);
rcu_read_unlock();
}
}
/* * This should be called once the rc thread has been stopped, so there can be * no concurrent bpf execution. * * Should be called with the ir_raw_handler_lock held.
*/ void lirc_bpf_free(struct rc_dev *rcdev)
{ struct bpf_prog_array_item *item; struct bpf_prog_array *array;
array = lirc_rcu_dereference(rcdev->raw->progs); if (!array) return;
for (item = array->items; item->prog; item++)
bpf_prog_put(item->prog);
bpf_prog_array_free(array);
}
int lirc_prog_attach(constunion bpf_attr *attr, struct bpf_prog *prog)
{ struct rc_dev *rcdev; int ret;
if (attr->attach_flags) return -EINVAL;
rcdev = rc_dev_get_from_fd(attr->target_fd, true); if (IS_ERR(rcdev)) return PTR_ERR(rcdev);
ret = lirc_bpf_attach(rcdev, prog);
put_device(&rcdev->dev);
return ret;
}
int lirc_prog_detach(constunion bpf_attr *attr)
{ struct bpf_prog *prog; struct rc_dev *rcdev; int ret;
if (attr->attach_flags) return -EINVAL;
prog = bpf_prog_get_type(attr->attach_bpf_fd,
BPF_PROG_TYPE_LIRC_MODE2); if (IS_ERR(prog)) return PTR_ERR(prog);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.