@@ -143,48 +143,6 @@ u8 *call_hid_bpf_rdesc_fixup(struct hid_device *hdev, u8 *rdesc, unsigned int *s
143143}
144144EXPORT_SYMBOL_GPL (call_hid_bpf_rdesc_fixup );
145145
146- /* Disables missing prototype warnings */
147- __bpf_kfunc_start_defs ();
148-
149- /**
150- * hid_bpf_get_data - Get the kernel memory pointer associated with the context @ctx
151- *
152- * @ctx: The HID-BPF context
153- * @offset: The offset within the memory
154- * @rdwr_buf_size: the const size of the buffer
155- *
156- * @returns %NULL on error, an %__u8 memory pointer on success
157- */
158- __bpf_kfunc __u8 *
159- hid_bpf_get_data (struct hid_bpf_ctx * ctx , unsigned int offset , const size_t rdwr_buf_size )
160- {
161- struct hid_bpf_ctx_kern * ctx_kern ;
162-
163- if (!ctx )
164- return NULL ;
165-
166- ctx_kern = container_of (ctx , struct hid_bpf_ctx_kern , ctx );
167-
168- if (rdwr_buf_size + offset > ctx -> allocated_size )
169- return NULL ;
170-
171- return ctx_kern -> data + offset ;
172- }
173- __bpf_kfunc_end_defs ();
174-
175- /*
176- * The following set contains all functions we agree BPF programs
177- * can use.
178- */
179- BTF_KFUNCS_START (hid_bpf_kfunc_ids )
180- BTF_ID_FLAGS (func , hid_bpf_get_data , KF_RET_NULL )
181- BTF_KFUNCS_END (hid_bpf_kfunc_ids )
182-
183- static const struct btf_kfunc_id_set hid_bpf_kfunc_set = {
184- .owner = THIS_MODULE ,
185- .set = & hid_bpf_kfunc_ids ,
186- };
187-
188146static int device_match_id (struct device * dev , const void * id )
189147{
190148 struct hid_device * hdev = to_hid_device (dev );
@@ -281,6 +239,31 @@ static int do_hid_bpf_attach_prog(struct hid_device *hdev, int prog_fd, struct b
281239/* Disables missing prototype warnings */
282240__bpf_kfunc_start_defs ();
283241
242+ /**
243+ * hid_bpf_get_data - Get the kernel memory pointer associated with the context @ctx
244+ *
245+ * @ctx: The HID-BPF context
246+ * @offset: The offset within the memory
247+ * @rdwr_buf_size: the const size of the buffer
248+ *
249+ * @returns %NULL on error, an %__u8 memory pointer on success
250+ */
251+ __bpf_kfunc __u8 *
252+ hid_bpf_get_data (struct hid_bpf_ctx * ctx , unsigned int offset , const size_t rdwr_buf_size )
253+ {
254+ struct hid_bpf_ctx_kern * ctx_kern ;
255+
256+ if (!ctx )
257+ return NULL ;
258+
259+ ctx_kern = container_of (ctx , struct hid_bpf_ctx_kern , ctx );
260+
261+ if (rdwr_buf_size + offset > ctx -> allocated_size )
262+ return NULL ;
263+
264+ return ctx_kern -> data + offset ;
265+ }
266+
284267/**
285268 * hid_bpf_attach_prog - Attach the given @prog_fd to the given HID device
286269 *
@@ -393,6 +376,46 @@ hid_bpf_release_context(struct hid_bpf_ctx *ctx)
393376 put_device (& hid -> dev );
394377}
395378
379+ static int
380+ __hid_bpf_hw_check_params (struct hid_bpf_ctx * ctx , __u8 * buf , size_t * buf__sz ,
381+ enum hid_report_type rtype )
382+ {
383+ struct hid_report_enum * report_enum ;
384+ struct hid_report * report ;
385+ struct hid_device * hdev ;
386+ u32 report_len ;
387+
388+ /* check arguments */
389+ if (!ctx || !hid_bpf_ops || !buf )
390+ return - EINVAL ;
391+
392+ switch (rtype ) {
393+ case HID_INPUT_REPORT :
394+ case HID_OUTPUT_REPORT :
395+ case HID_FEATURE_REPORT :
396+ break ;
397+ default :
398+ return - EINVAL ;
399+ }
400+
401+ if (* buf__sz < 1 )
402+ return - EINVAL ;
403+
404+ hdev = (struct hid_device * )ctx -> hid ; /* discard const */
405+
406+ report_enum = hdev -> report_enum + rtype ;
407+ report = hid_bpf_ops -> hid_get_report (report_enum , buf );
408+ if (!report )
409+ return - EINVAL ;
410+
411+ report_len = hid_report_len (report );
412+
413+ if (* buf__sz > report_len )
414+ * buf__sz = report_len ;
415+
416+ return 0 ;
417+ }
418+
396419/**
397420 * hid_bpf_hw_request - Communicate with a HID device
398421 *
@@ -409,24 +432,14 @@ hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz,
409432 enum hid_report_type rtype , enum hid_class_request reqtype )
410433{
411434 struct hid_device * hdev ;
412- struct hid_report * report ;
413- struct hid_report_enum * report_enum ;
435+ size_t size = buf__sz ;
414436 u8 * dma_data ;
415- u32 report_len ;
416437 int ret ;
417438
418439 /* check arguments */
419- if (!ctx || !hid_bpf_ops || !buf )
420- return - EINVAL ;
421-
422- switch (rtype ) {
423- case HID_INPUT_REPORT :
424- case HID_OUTPUT_REPORT :
425- case HID_FEATURE_REPORT :
426- break ;
427- default :
428- return - EINVAL ;
429- }
440+ ret = __hid_bpf_hw_check_params (ctx , buf , & size , rtype );
441+ if (ret )
442+ return ret ;
430443
431444 switch (reqtype ) {
432445 case HID_REQ_GET_REPORT :
@@ -440,29 +453,16 @@ hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz,
440453 return - EINVAL ;
441454 }
442455
443- if (buf__sz < 1 )
444- return - EINVAL ;
445-
446456 hdev = (struct hid_device * )ctx -> hid ; /* discard const */
447457
448- report_enum = hdev -> report_enum + rtype ;
449- report = hid_bpf_ops -> hid_get_report (report_enum , buf );
450- if (!report )
451- return - EINVAL ;
452-
453- report_len = hid_report_len (report );
454-
455- if (buf__sz > report_len )
456- buf__sz = report_len ;
457-
458- dma_data = kmemdup (buf , buf__sz , GFP_KERNEL );
458+ dma_data = kmemdup (buf , size , GFP_KERNEL );
459459 if (!dma_data )
460460 return - ENOMEM ;
461461
462462 ret = hid_bpf_ops -> hid_hw_raw_request (hdev ,
463463 dma_data [0 ],
464464 dma_data ,
465- buf__sz ,
465+ size ,
466466 rtype ,
467467 reqtype );
468468
@@ -472,8 +472,90 @@ hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz,
472472 kfree (dma_data );
473473 return ret ;
474474}
475+
476+ /**
477+ * hid_bpf_hw_output_report - Send an output report to a HID device
478+ *
479+ * @ctx: the HID-BPF context previously allocated in hid_bpf_allocate_context()
480+ * @buf: a %PTR_TO_MEM buffer
481+ * @buf__sz: the size of the data to transfer
482+ *
483+ * Returns the number of bytes transferred on success, a negative error code otherwise.
484+ */
485+ __bpf_kfunc int
486+ hid_bpf_hw_output_report (struct hid_bpf_ctx * ctx , __u8 * buf , size_t buf__sz )
487+ {
488+ struct hid_device * hdev ;
489+ size_t size = buf__sz ;
490+ u8 * dma_data ;
491+ int ret ;
492+
493+ /* check arguments */
494+ ret = __hid_bpf_hw_check_params (ctx , buf , & size , HID_OUTPUT_REPORT );
495+ if (ret )
496+ return ret ;
497+
498+ hdev = (struct hid_device * )ctx -> hid ; /* discard const */
499+
500+ dma_data = kmemdup (buf , size , GFP_KERNEL );
501+ if (!dma_data )
502+ return - ENOMEM ;
503+
504+ ret = hid_bpf_ops -> hid_hw_output_report (hdev ,
505+ dma_data ,
506+ size );
507+
508+ kfree (dma_data );
509+ return ret ;
510+ }
511+
512+ /**
513+ * hid_bpf_input_report - Inject a HID report in the kernel from a HID device
514+ *
515+ * @ctx: the HID-BPF context previously allocated in hid_bpf_allocate_context()
516+ * @type: the type of the report (%HID_INPUT_REPORT, %HID_FEATURE_REPORT, %HID_OUTPUT_REPORT)
517+ * @buf: a %PTR_TO_MEM buffer
518+ * @buf__sz: the size of the data to transfer
519+ *
520+ * Returns %0 on success, a negative error code otherwise.
521+ */
522+ __bpf_kfunc int
523+ hid_bpf_input_report (struct hid_bpf_ctx * ctx , enum hid_report_type type , u8 * buf ,
524+ const size_t buf__sz )
525+ {
526+ struct hid_device * hdev ;
527+ size_t size = buf__sz ;
528+ int ret ;
529+
530+ /* check arguments */
531+ ret = __hid_bpf_hw_check_params (ctx , buf , & size , type );
532+ if (ret )
533+ return ret ;
534+
535+ hdev = (struct hid_device * )ctx -> hid ; /* discard const */
536+
537+ return hid_bpf_ops -> hid_input_report (hdev , type , buf , size , 0 );
538+ }
475539__bpf_kfunc_end_defs ();
476540
541+ /*
542+ * The following set contains all functions we agree BPF programs
543+ * can use.
544+ */
545+ BTF_KFUNCS_START (hid_bpf_kfunc_ids )
546+ BTF_ID_FLAGS (func , hid_bpf_get_data , KF_RET_NULL )
547+ BTF_ID_FLAGS (func , hid_bpf_allocate_context , KF_ACQUIRE | KF_RET_NULL | KF_SLEEPABLE )
548+ BTF_ID_FLAGS (func , hid_bpf_release_context , KF_RELEASE | KF_SLEEPABLE )
549+ BTF_ID_FLAGS (func , hid_bpf_hw_request , KF_SLEEPABLE )
550+ BTF_ID_FLAGS (func , hid_bpf_hw_output_report , KF_SLEEPABLE )
551+ BTF_ID_FLAGS (func , hid_bpf_input_report , KF_SLEEPABLE )
552+ BTF_KFUNCS_END (hid_bpf_kfunc_ids )
553+
554+ static const struct btf_kfunc_id_set hid_bpf_kfunc_set = {
555+ .owner = THIS_MODULE ,
556+ .set = & hid_bpf_kfunc_ids ,
557+ };
558+
477559/* our HID-BPF entrypoints */
478560BTF_SET8_START (hid_bpf_fmodret_ids )
479561BTF_ID_FLAGS (func , hid_bpf_device_event )
@@ -492,6 +574,8 @@ BTF_ID_FLAGS(func, hid_bpf_attach_prog)
492574BTF_ID_FLAGS (func , hid_bpf_allocate_context , KF_ACQUIRE | KF_RET_NULL )
493575BTF_ID_FLAGS (func , hid_bpf_release_context , KF_RELEASE )
494576BTF_ID_FLAGS (func , hid_bpf_hw_request )
577+ BTF_ID_FLAGS (func , hid_bpf_hw_output_report )
578+ BTF_ID_FLAGS (func , hid_bpf_input_report )
495579BTF_KFUNCS_END (hid_bpf_syscall_kfunc_ids )
496580
497581static const struct btf_kfunc_id_set hid_bpf_syscall_kfunc_set = {
0 commit comments