Received: by 2002:a6b:500f:0:0:0:0:0 with SMTP id e15csp3598580iob; Tue, 17 May 2022 03:36:21 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwFS0RhXDvNRcM8rMXJ3TGGVecuPyHat48c6j3/2mOm+nyC8Ol/AhhrN9cVpeu3oiOI9Tc9 X-Received: by 2002:a17:907:60cf:b0:6f4:4240:849 with SMTP id hv15-20020a17090760cf00b006f442400849mr19776760ejc.566.1652783780704; Tue, 17 May 2022 03:36:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1652783780; cv=none; d=google.com; s=arc-20160816; b=I0E2q9JNd8b1HbKM7JhABbbhYwuKfJ1rkMR+PciEXgAW1XuqHowQPxfqI5bT0E0I3O jpSUo8kBg7sMK83HQLwgnQyCI7L2R+LaqslwaPAabKO14RawSMdjN03M9Jlbk7gXYAnr SE1Ca8v9IVoELylpy+KiVlb1ldf5V+A6YDYdSGtU+hNRi4xqDqqc2gIgFSSK6KmoS2zk jjeBQTw2FYCLHSn7i2qenLvBGMqVbYVGDnM+4r9wTjypjsbJdNPCSgIsxlyaX5j+J9WY 2RI8Ghp5dnAv+4g+ug9U+vx7dsyV1v3fnWtHqWBd9DwugZrlQaQxDWiJIm1JT9zIAScG ehcA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=+2MCDPWgT8AD1zUOUEgwDbZ/724dUAUyb7qZCZGMeUw=; b=x78rtV+dIHlyTkgDRoyJD8OTBiKm2UhXKKqW3T2HDCtwUqZ76YBhNkmBPbcsDP3dVe bkqDiXrbL42K+rH830Dl9aI/YevhztqACm3wlDtngfVFaI1RZZIsJTkinrCH8+x7Zfb9 oQE+xXgu5Vd6Zrs+NWUHOuaoP3XFHNvJuMauL2hzu5kLaeiCpXRDREqnvO85G9RGokGV iRVYzjpwOUjEP/pmtpZ8g2ZxXGMOFjCpm4TbojUV7h+YwRgb0EPF82DIDUtlNCNNKhNq 2Rerop8SvK6v4KeEafhMya0BoxWRtjmnHpMGOIJsOqcxaHhl52bYBoV3QqpO0A837lRL znMw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=PGetkuOM; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id b9-20020a056402278900b004282c814a93si15019829ede.68.2022.05.17.03.35.53; Tue, 17 May 2022 03:36:20 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=PGetkuOM; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236832AbiEPUcp (ORCPT + 99 others); Mon, 16 May 2022 16:32:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57588 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1351036AbiEPUB4 (ORCPT ); Mon, 16 May 2022 16:01:56 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8B99547572; Mon, 16 May 2022 12:57:07 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 4CD5BB81611; Mon, 16 May 2022 19:57:06 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id A082CC34100; Mon, 16 May 2022 19:57:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1652731025; bh=urjgqU4I+i/LzVlT3Ydpig5pMFXzKnWRvoTFWv0ka5M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PGetkuOMkLe/LZbp7NBkzuQOYfxfGSbk3ru9SUk9LmWJf8lhWhxrc6GTh5BYuZKmc Jevwmb5q5jmse5DcYEHdy1IbdwBnXlV+13klfh7w/Z+66/DHSGlSF8Gbn4tHnT2UcO hqNAZEJ/pdCh7RO1/0fwdX+7USGXK6IZnpkY9S/A= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Dan Vacura Subject: [PATCH 5.17 079/114] usb: gadget: uvc: allow for application to cleanly shutdown Date: Mon, 16 May 2022 21:36:53 +0200 Message-Id: <20220516193627.754292531@linuxfoundation.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220516193625.489108457@linuxfoundation.org> References: <20220516193625.489108457@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-7.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 --- 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 @@ -890,13 +890,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); @@ -915,6 +939,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 @@ -129,6 +130,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 @@ -253,10 +253,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