From e0a4c46dff869f288df99e8fabd2eb1e701dc811 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 16 May 2022 19:34:47 +0200 Subject: [PATCH] 5.15-stable patches added patches: usb-gadget-uvc-allow-for-application-to-cleanly-shutdown.patch usb-gadget-uvc-rename-function-to-be-more-consistent.patch --- queue-5.15/series | 2 + ...-for-application-to-cleanly-shutdown.patch | 144 ++++++++++++++++++ ...ename-function-to-be-more-consistent.patch | 50 ++++++ 3 files changed, 196 insertions(+) create mode 100644 queue-5.15/usb-gadget-uvc-allow-for-application-to-cleanly-shutdown.patch create mode 100644 queue-5.15/usb-gadget-uvc-rename-function-to-be-more-consistent.patch diff --git a/queue-5.15/series b/queue-5.15/series index 22f6258b91a..60daa634542 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -98,3 +98,5 @@ dma-buf-call-dma_buf_stats_setup-after-dmabuf-is-in-valid-list.patch mm-hwpoison-use-pr_err-instead-of-dump_page-in-get_any_page.patch sunrpc-ensure-we-flush-any-closed-sockets-before-xs_xprt_free.patch ping-fix-address-binding-wrt-vrf.patch +usb-gadget-uvc-rename-function-to-be-more-consistent.patch +usb-gadget-uvc-allow-for-application-to-cleanly-shutdown.patch diff --git a/queue-5.15/usb-gadget-uvc-allow-for-application-to-cleanly-shutdown.patch b/queue-5.15/usb-gadget-uvc-allow-for-application-to-cleanly-shutdown.patch new file mode 100644 index 00000000000..88d71344fc5 --- /dev/null +++ b/queue-5.15/usb-gadget-uvc-allow-for-application-to-cleanly-shutdown.patch @@ -0,0 +1,144 @@ +From b81ac4395bbeaf36e078dea1a48c02dd97b76235 Mon Sep 17 00:00:00 2001 +From: Dan Vacura +Date: Tue, 3 May 2022 15:10:38 -0500 +Subject: usb: gadget: uvc: allow for application to cleanly shutdown + +From: Dan Vacura + +commit b81ac4395bbeaf36e078dea1a48c02dd97b76235 upstream. + +Several types of kernel panics can occur due to timing during the uvc +gadget removal. This appears to be a problem with gadget resources being +managed by both the client application's v4l2 open/close and the UDC +gadget bind/unbind. Since the concept of USB_GADGET_DELAYED_STATUS +doesn't exist for unbind, add a wait to allow for the application to +close out. + +Some examples of the panics that can occur are: + +<1>[ 1147.652313] Unable to handle kernel NULL pointer dereference at +virtual address 0000000000000028 +<4>[ 1147.652510] Call trace: +<4>[ 1147.652514] usb_gadget_disconnect+0x74/0x1f0 +<4>[ 1147.652516] usb_gadget_deactivate+0x38/0x168 +<4>[ 1147.652520] usb_function_deactivate+0x54/0x90 +<4>[ 1147.652524] uvc_function_disconnect+0x14/0x38 +<4>[ 1147.652527] uvc_v4l2_release+0x34/0xa0 +<4>[ 1147.652537] __fput+0xdc/0x2c0 +<4>[ 1147.652540] ____fput+0x10/0x1c +<4>[ 1147.652545] task_work_run+0xe4/0x12c +<4>[ 1147.652549] do_notify_resume+0x108/0x168 + +<1>[ 282.950561][ T1472] Unable to handle kernel NULL pointer +dereference at virtual address 00000000000005b8 +<6>[ 282.953111][ T1472] Call trace: +<6>[ 282.953121][ T1472] usb_function_deactivate+0x54/0xd4 +<6>[ 282.953134][ T1472] uvc_v4l2_release+0xac/0x1e4 +<6>[ 282.953145][ T1472] v4l2_release+0x134/0x1f0 +<6>[ 282.953167][ T1472] __fput+0xf4/0x428 +<6>[ 282.953178][ T1472] ____fput+0x14/0x24 +<6>[ 282.953193][ T1472] task_work_run+0xac/0x130 + +<3>[ 213.410077][ T29] configfs-gadget gadget: uvc: Failed to queue +request (-108). +<1>[ 213.410116][ T29] Unable to handle kernel NULL pointer +dereference at virtual address 0000000000000003 +<6>[ 213.413460][ T29] Call trace: +<6>[ 213.413474][ T29] uvcg_video_pump+0x1f0/0x384 +<6>[ 213.413489][ T29] process_one_work+0x2a4/0x544 +<6>[ 213.413502][ T29] worker_thread+0x350/0x784 +<6>[ 213.413515][ T29] kthread+0x2ac/0x320 +<6>[ 213.413528][ T29] ret_from_fork+0x10/0x30 + +Signed-off-by: Dan Vacura +Cc: stable +Link: https://lore.kernel.org/r/20220503201039.71720-1-w36195@motorola.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/f_uvc.c | 25 +++++++++++++++++++++++++ + drivers/usb/gadget/function/uvc.h | 2 ++ + drivers/usb/gadget/function/uvc_v4l2.c | 3 ++- + 3 files changed, 29 insertions(+), 1 deletion(-) + +--- a/drivers/usb/gadget/function/f_uvc.c ++++ b/drivers/usb/gadget/function/f_uvc.c +@@ -889,13 +889,37 @@ static void uvc_function_unbind(struct u + { + struct usb_composite_dev *cdev = c->cdev; + struct uvc_device *uvc = to_uvc(f); ++ long wait_ret = 1; + + uvcg_info(f, "%s()\n", __func__); + ++ /* If we know we're connected via v4l2, then there should be a cleanup ++ * of the device from userspace either via UVC_EVENT_DISCONNECT or ++ * though the video device removal uevent. Allow some time for the ++ * application to close out before things get deleted. ++ */ ++ if (uvc->func_connected) { ++ uvcg_dbg(f, "waiting for clean disconnect\n"); ++ wait_ret = wait_event_interruptible_timeout(uvc->func_connected_queue, ++ uvc->func_connected == false, msecs_to_jiffies(500)); ++ uvcg_dbg(f, "done waiting with ret: %ld\n", wait_ret); ++ } ++ + device_remove_file(&uvc->vdev.dev, &dev_attr_function_name); + video_unregister_device(&uvc->vdev); + v4l2_device_unregister(&uvc->v4l2_dev); + ++ if (uvc->func_connected) { ++ /* Wait for the release to occur to ensure there are no longer any ++ * pending operations that may cause panics when resources are cleaned ++ * up. ++ */ ++ uvcg_warn(f, "%s no clean disconnect, wait for release\n", __func__); ++ wait_ret = wait_event_interruptible_timeout(uvc->func_connected_queue, ++ uvc->func_connected == false, msecs_to_jiffies(1000)); ++ uvcg_dbg(f, "done waiting for release with ret: %ld\n", wait_ret); ++ } ++ + usb_ep_free_request(cdev->gadget->ep0, uvc->control_req); + kfree(uvc->control_buf); + +@@ -914,6 +938,7 @@ static struct usb_function *uvc_alloc(st + + mutex_init(&uvc->video.mutex); + uvc->state = UVC_STATE_DISCONNECTED; ++ init_waitqueue_head(&uvc->func_connected_queue); + opts = fi_to_f_uvc_opts(fi); + + mutex_lock(&opts->lock); +--- a/drivers/usb/gadget/function/uvc.h ++++ b/drivers/usb/gadget/function/uvc.h +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -127,6 +128,7 @@ struct uvc_device { + struct usb_function func; + struct uvc_video video; + bool func_connected; ++ wait_queue_head_t func_connected_queue; + + /* Descriptors */ + struct { +--- a/drivers/usb/gadget/function/uvc_v4l2.c ++++ b/drivers/usb/gadget/function/uvc_v4l2.c +@@ -252,10 +252,11 @@ uvc_v4l2_subscribe_event(struct v4l2_fh + + static void uvc_v4l2_disable(struct uvc_device *uvc) + { +- uvc->func_connected = false; + uvc_function_disconnect(uvc); + uvcg_video_enable(&uvc->video, 0); + uvcg_free_buffers(&uvc->video.queue); ++ uvc->func_connected = false; ++ wake_up_interruptible(&uvc->func_connected_queue); + } + + static int diff --git a/queue-5.15/usb-gadget-uvc-rename-function-to-be-more-consistent.patch b/queue-5.15/usb-gadget-uvc-rename-function-to-be-more-consistent.patch new file mode 100644 index 00000000000..2f794e1fc5d --- /dev/null +++ b/queue-5.15/usb-gadget-uvc-rename-function-to-be-more-consistent.patch @@ -0,0 +1,50 @@ +From e6bab2b66329b40462fb1bed6f98bc3fcf543a1c Mon Sep 17 00:00:00 2001 +From: Michael Tretter +Date: Sun, 17 Oct 2021 23:50:13 +0200 +Subject: usb: gadget: uvc: rename function to be more consistent + +From: Michael Tretter + +commit e6bab2b66329b40462fb1bed6f98bc3fcf543a1c upstream. + +When enabling info debugging for the uvc gadget, the bind and unbind +infos use different formats. Change the unbind to visually match the +bind. + +Reviewed-by: Laurent Pinchart +Reviewed-by: Paul Elder +Signed-off-by: Michael Tretter +Signed-off-by: Michael Grzeschik +Link: https://lore.kernel.org/r/20211017215017.18392-3-m.grzeschik@pengutronix.de +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/f_uvc.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/drivers/usb/gadget/function/f_uvc.c ++++ b/drivers/usb/gadget/function/f_uvc.c +@@ -884,12 +884,13 @@ static void uvc_free(struct usb_function + kfree(uvc); + } + +-static void uvc_unbind(struct usb_configuration *c, struct usb_function *f) ++static void uvc_function_unbind(struct usb_configuration *c, ++ struct usb_function *f) + { + struct usb_composite_dev *cdev = c->cdev; + struct uvc_device *uvc = to_uvc(f); + +- uvcg_info(f, "%s\n", __func__); ++ uvcg_info(f, "%s()\n", __func__); + + device_remove_file(&uvc->vdev.dev, &dev_attr_function_name); + video_unregister_device(&uvc->vdev); +@@ -943,7 +944,7 @@ static struct usb_function *uvc_alloc(st + /* Register the function. */ + uvc->func.name = "uvc"; + uvc->func.bind = uvc_function_bind; +- uvc->func.unbind = uvc_unbind; ++ uvc->func.unbind = uvc_function_unbind; + uvc->func.get_alt = uvc_function_get_alt; + uvc->func.set_alt = uvc_function_set_alt; + uvc->func.disable = uvc_function_disable; -- 2.47.3