From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Cyrus-Session-Id: sloti22d1t05-1000858-1521940919-5-14087213942044559617 X-Sieve: CMU Sieve 3.0 X-Spam-known-sender: no ("Email failed DMARC policy for domain") X-Spam-score: 0.0 X-Spam-hits: BAYES_00 -1.9, FREEMAIL_FORGED_FROMDOMAIN 0.249, FREEMAIL_FROM 0.001, HEADER_FROM_DIFFERENT_DOMAINS 0.25, RCVD_IN_DNSWL_HI -5, T_RP_MATCHES_RCVD -0.01, LANGUAGES en, BAYES_USED global, SA_VERSION 3.4.0 X-Spam-source: IP='209.132.180.67', Host='vger.kernel.org', Country='CN', FromHeader='com', MailFrom='org' X-Spam-charsets: plain='UTF-8' X-IgnoreVacation: yes ("Email failed DMARC policy for domain") X-Resolved-to: greg@kroah.com X-Delivered-to: greg@kroah.com X-Mail-from: linux-usb-owner@vger.kernel.org ARC-Seal: i=1; a=rsa-sha256; cv=none; d=messagingengine.com; s=arctest; t=1521940918; b=hRd5jRWX753bSiZBIogr2SpB5K+GN2ww5QxKhM7y/LQNiC/ NqliXzH1uWru6RFsjKH0EUl9AEOIBB5je2naPf9f8Hsu8aozUXxkQNt81nAY4AYq aSUOKumeFUX8S9qKtIm+hsq0IsaLM2hSnP0g5az/IzVnsjMNtlVADxowcWFLlmUG S0nRbWCiZVhBrbhzo8wFkv1/xVhydygOTZo3IEK/NQ53Iaf9//gy510ziHHNF4xW GTAd9t3+odZN4JhV7N33lWKSlBqUjsV4Y9Lo9Az9YW1Qy+THBRhWFrjN2Dl1Cx9A MZ+xMXZMeYh2pIMwyY/dsSy5/C4cPuF1npO1FhQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=mime-version:in-reply-to:references:from :date:message-id:subject:to:cc:content-type:sender:list-id; s= arctest; t=1521940918; bh=eV3Nl7JPqgfXAcpnXutPb/ti3XobtxzZlDbGpF IGHto=; b=GxNcjiCOO4Hy5xo3tlrLUauoAEXbpyiX4PQE0pdf/PZ8ec7covUokL 5GHzEHnZahfhQjuGmMa4rxqlwFvtrJXDCUw/oWDPDOEAGkJxQ/BE+bMl+kKiabzo cz1/2voKISC3rCyOVNJchIbDxJG7R/JMeKK76aZBVi7n9CN7lqlQFJwJbQ6LArD/ 6P5YiugnmsUgapakI42dDstgA4yISMwJVI12z81LiciPyPMporigAaL9nGA3QdJe ndaQIZhRT8epeGAH9b9IaQ8yFNOypZuu8+/2064OrMADnO2wTSPjeYn4OhFTzXSm ZobgXHTDtZFrenaKR4Uvxv9J77rwVFGw== ARC-Authentication-Results: i=1; mx3.messagingengine.com; arc=none (no signatures found); dkim=fail (body has been altered, 2048-bit rsa key sha256) header.d=gmail.com header.i=@gmail.com header.b=RVw9vO4N x-bits=2048 x-keytype=rsa x-algorithm=sha256 x-selector=20161025; dmarc=fail (p=none,has-list-id=yes,d=none) header.from=gmail.com; iprev=pass policy.iprev=209.132.180.67 (vger.kernel.org); spf=none smtp.mailfrom=linux-usb-owner@vger.kernel.org smtp.helo=vger.kernel.org; x-aligned-from=fail; x-google-dkim=fail (body has been altered, 2048-bit rsa key) header.d=1e100.net header.i=@1e100.net header.b=oJiUO9i1; x-ptr=pass x-ptr-helo=vger.kernel.org x-ptr-lookup=vger.kernel.org; x-return-mx=pass smtp.domain=vger.kernel.org smtp.result=pass smtp_org.domain=kernel.org smtp_org.result=pass smtp_is_org_domain=no header.domain=gmail.com header.result=pass header_is_org_domain=yes; x-vs=clean score=-100 state=0 Authentication-Results: mx3.messagingengine.com; arc=none (no signatures found); dkim=fail (body has been altered, 2048-bit rsa key sha256) header.d=gmail.com header.i=@gmail.com header.b=RVw9vO4N x-bits=2048 x-keytype=rsa x-algorithm=sha256 x-selector=20161025; dmarc=fail (p=none,has-list-id=yes,d=none) header.from=gmail.com; iprev=pass policy.iprev=209.132.180.67 (vger.kernel.org); spf=none smtp.mailfrom=linux-usb-owner@vger.kernel.org smtp.helo=vger.kernel.org; x-aligned-from=fail; x-google-dkim=fail (body has been altered, 2048-bit rsa key) header.d=1e100.net header.i=@1e100.net header.b=oJiUO9i1; x-ptr=pass x-ptr-helo=vger.kernel.org x-ptr-lookup=vger.kernel.org; x-return-mx=pass smtp.domain=vger.kernel.org smtp.result=pass smtp_org.domain=kernel.org smtp_org.result=pass smtp_is_org_domain=no header.domain=gmail.com header.result=pass header_is_org_domain=yes; x-vs=clean score=-100 state=0 X-ME-VSCategory: clean Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752862AbeCYBVw (ORCPT ); Sat, 24 Mar 2018 21:21:52 -0400 Received: from mail-lf0-f66.google.com ([209.85.215.66]:36531 "EHLO mail-lf0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752216AbeCYBVv (ORCPT ); Sat, 24 Mar 2018 21:21:51 -0400 X-Google-Smtp-Source: AG47ELsVoTuHZ9H9U1iRjf+Wx9LZ5Aluvc6y5DcwXZaI7cXtKGxY/ag3e3zQMsN1wDn2DRJZ0fmMi7KyODuGp72Jw5o= MIME-Version: 1.0 In-Reply-To: <20180208035501.10711-1-jeffy.chen@rock-chips.com> References: <20180208035501.10711-1-jeffy.chen@rock-chips.com> From: Jonathan Liu Date: Sun, 25 Mar 2018 12:21:48 +1100 Message-ID: Subject: Re: [v6] usb: ohci: Proper handling of ed_rm_list to handle race condition between usb_kill_urb() and finish_unlinks() To: Jeffy Chen Cc: linux-kernel , briannorris@chromium.org, stern@rowland.harvard.edu, mka@chromium.org, dianders@chromium.org, AMAN DEEP , stable@vger.kernel.org, Greg Kroah-Hartman , linux-usb@vger.kernel.org Content-Type: text/plain; charset="UTF-8" Sender: linux-usb-owner@vger.kernel.org X-Mailing-List: linux-usb@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-Mailing-List: linux-kernel@vger.kernel.org List-ID: Hi, On 8 February 2018 at 14:55, Jeffy Chen wrote: > From: AMAN DEEP > > There is a race condition between finish_unlinks->finish_urb() function > and usb_kill_urb() in ohci controller case. The finish_urb calls > spin_unlock(&ohci->lock) before usb_hcd_giveback_urb() function call, > then if during this time, usb_kill_urb is called for another endpoint, > then new ed will be added to ed_rm_list at beginning for unlink, and > ed_rm_list will point to newly added. > > When finish_urb() is completed in finish_unlinks() and ed->td_list > becomes empty as in below code (in finish_unlinks() function): > > if (list_empty(&ed->td_list)) { > *last = ed->ed_next; > ed->ed_next = NULL; > } else if (ohci->rh_state == OHCI_RH_RUNNING) { > *last = ed->ed_next; > ed->ed_next = NULL; > ed_schedule(ohci, ed); > } > > The *last = ed->ed_next will make ed_rm_list to point to ed->ed_next > and previously added ed by usb_kill_urb will be left unreferenced by > ed_rm_list. This causes usb_kill_urb() hang forever waiting for > finish_unlink to remove added ed from ed_rm_list. > > The main reason for hang in this race condtion is addition and removal > of ed from ed_rm_list in the beginning during usb_kill_urb and later > last* is modified in finish_unlinks(). > > As suggested by Alan Stern, the solution for proper handling of > ohci->ed_rm_list is to remove ed from the ed_rm_list before finishing > any URBs. Then at the end, we can add ed back to the list if necessary. > > This properly handle the updated ohci->ed_rm_list in usb_kill_urb(). > > Fixes:977dcfdc6031("USB:OHCI:don't lose track of EDs when a controller dies") > Acked-by: Alan Stern > CC: > Signed-off-by: Aman Deep > Signed-off-by: Jeffy Chen > --- > > Changes in v6: > This is a resend of Aman Deep's v5 patch [0], which solved the hang we > hit [1]. (Thanks Aman :) > > The v5 has some format issues, so i slightly adjust the commit message. > > [0] https://www.spinics.net/lists/linux-usb/msg129010.html > [1] https://bugs.chromium.org/p/chromium/issues/detail?id=803749 > > drivers/usb/host/ohci-q.c | 17 ++++++++++------- > 1 file changed, 10 insertions(+), 7 deletions(-) > > diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c > index b2ec8c399363..4ccb85a67bb3 100644 > --- a/drivers/usb/host/ohci-q.c > +++ b/drivers/usb/host/ohci-q.c > @@ -1019,6 +1019,8 @@ static void finish_unlinks(struct ohci_hcd *ohci) > * have modified this list. normally it's just prepending > * entries (which we'd ignore), but paranoia won't hurt. > */ > + *last = ed->ed_next; > + ed->ed_next = NULL; > modified = 0; > > /* unlink urbs as requested, but rescan the list after > @@ -1077,21 +1079,22 @@ static void finish_unlinks(struct ohci_hcd *ohci) > goto rescan_this; > > /* > - * If no TDs are queued, take ED off the ed_rm_list. > + * If no TDs are queued, ED is now idle. > * Otherwise, if the HC is running, reschedule. > - * If not, leave it on the list for further dequeues. > + * If the HC isn't running, add ED back to the > + * start of the list for later processing. > */ > if (list_empty(&ed->td_list)) { > - *last = ed->ed_next; > - ed->ed_next = NULL; > ed->state = ED_IDLE; > list_del(&ed->in_use_list); > } else if (ohci->rh_state == OHCI_RH_RUNNING) { > - *last = ed->ed_next; > - ed->ed_next = NULL; > ed_schedule(ohci, ed); > } else { > - last = &ed->ed_next; > + ed->ed_next = ohci->ed_rm_list; > + ohci->ed_rm_list = ed; > + /* Don't loop on the same ED */ > + if (last == &ohci->ed_rm_list) > + last = &ed->ed_next; > } > > if (modified) I am experiencing a USB function call hang from userspace with OCHI (full speed USB device) after updating from Linux 4.14.15 to 4.14.24 and noticed this commit. Here is the Linux 4.14.24 kernel stack trace (extracted from SysRq+w and amended with addr2line): [] (__schedule) from [] (schedule+0x50/0xb4) kernel/sched/core.c:2792 [] (schedule) from [] (usb_kill_urb.part.3+0x78/0xa8) include/asm-generic/preempt.h:59 [] (usb_kill_urb.part.3) from [] (usbdev_ioctl+0x1288/0x1cf0) drivers/usb/core/urb.c:690 [] (usbdev_ioctl) from [] (do_vfs_ioctl+0x9c/0x8ec) drivers/usb/core/devio.c:1835 [] (do_vfs_ioctl) from [] (SyS_ioctl+0x34/0x5c) fs/ioctl.c:47 [] (SyS_ioctl) from [] (ret_fast_syscall+0x0/0x54) include/linux/file.h:39 Afterwards the kernel is unresponsive to disconnect/connect of the full speed USB device but I can connect/disconnect a high speed USB device to the same port and communicate to it without problem since it uses EHCI (OHCI is companion controller). If I try to connect the full speed USB device again it is still unresponsive. The userspace application is still hanging after all this. Could this commit be causing the issue? Thanks. Regards, Jonathan From mboxrd@z Thu Jan 1 00:00:00 1970 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Subject: [v6] usb: ohci: Proper handling of ed_rm_list to handle race condition between usb_kill_urb() and finish_unlinks() From: Jonathan Liu Message-Id: Date: Sun, 25 Mar 2018 12:21:48 +1100 To: Jeffy Chen Cc: linux-kernel , briannorris@chromium.org, stern@rowland.harvard.edu, mka@chromium.org, dianders@chromium.org, AMAN DEEP , stable@vger.kernel.org, Greg Kroah-Hartman , linux-usb@vger.kernel.org List-ID: SGksCgpPbiA4IEZlYnJ1YXJ5IDIwMTggYXQgMTQ6NTUsIEplZmZ5IENoZW4gPGplZmZ5LmNoZW5A cm9jay1jaGlwcy5jb20+IHdyb3RlOgo+IEZyb206IEFNQU4gREVFUCA8YW1hbi5kZWVwQHNhbXN1 bmcuY29tPgo+Cj4gVGhlcmUgaXMgYSByYWNlIGNvbmRpdGlvbiBiZXR3ZWVuIGZpbmlzaF91bmxp bmtzLT5maW5pc2hfdXJiKCkgZnVuY3Rpb24KPiBhbmQgdXNiX2tpbGxfdXJiKCkgaW4gb2hjaSBj b250cm9sbGVyIGNhc2UuIFRoZSBmaW5pc2hfdXJiIGNhbGxzCj4gc3Bpbl91bmxvY2soJm9oY2kt PmxvY2spIGJlZm9yZSB1c2JfaGNkX2dpdmViYWNrX3VyYigpIGZ1bmN0aW9uIGNhbGwsCj4gdGhl biBpZiBkdXJpbmcgdGhpcyB0aW1lLCB1c2Jfa2lsbF91cmIgaXMgY2FsbGVkIGZvciBhbm90aGVy IGVuZHBvaW50LAo+IHRoZW4gbmV3IGVkIHdpbGwgYmUgYWRkZWQgdG8gZWRfcm1fbGlzdCBhdCBi ZWdpbm5pbmcgZm9yIHVubGluaywgYW5kCj4gZWRfcm1fbGlzdCB3aWxsIHBvaW50IHRvIG5ld2x5 IGFkZGVkLgo+Cj4gV2hlbiBmaW5pc2hfdXJiKCkgaXMgY29tcGxldGVkIGluIGZpbmlzaF91bmxp bmtzKCkgYW5kIGVkLT50ZF9saXN0Cj4gYmVjb21lcyBlbXB0eSBhcyBpbiBiZWxvdyBjb2RlIChp biBmaW5pc2hfdW5saW5rcygpIGZ1bmN0aW9uKToKPgo+ICAgICAgICAgaWYgKGxpc3RfZW1wdHko JmVkLT50ZF9saXN0KSkgewo+ICAgICAgICAgICAgICAgICAqbGFzdCA9IGVkLT5lZF9uZXh0Owo+ ICAgICAgICAgICAgICAgICBlZC0+ZWRfbmV4dCA9IE5VTEw7Cj4gICAgICAgICB9IGVsc2UgaWYg KG9oY2ktPnJoX3N0YXRlID09IE9IQ0lfUkhfUlVOTklORykgewo+ICAgICAgICAgICAgICAgICAq bGFzdCA9IGVkLT5lZF9uZXh0Owo+ICAgICAgICAgICAgICAgICBlZC0+ZWRfbmV4dCA9IE5VTEw7 Cj4gICAgICAgICAgICAgICAgIGVkX3NjaGVkdWxlKG9oY2ksIGVkKTsKPiAgICAgICAgIH0KPgo+ IFRoZSAqbGFzdCA9IGVkLT5lZF9uZXh0IHdpbGwgbWFrZSBlZF9ybV9saXN0IHRvIHBvaW50IHRv IGVkLT5lZF9uZXh0Cj4gYW5kIHByZXZpb3VzbHkgYWRkZWQgZWQgYnkgdXNiX2tpbGxfdXJiIHdp bGwgYmUgbGVmdCB1bnJlZmVyZW5jZWQgYnkKPiBlZF9ybV9saXN0LiBUaGlzIGNhdXNlcyB1c2Jf a2lsbF91cmIoKSBoYW5nIGZvcmV2ZXIgd2FpdGluZyBmb3IKPiBmaW5pc2hfdW5saW5rIHRvIHJl bW92ZSBhZGRlZCBlZCBmcm9tIGVkX3JtX2xpc3QuCj4KPiBUaGUgbWFpbiByZWFzb24gZm9yIGhh bmcgaW4gdGhpcyByYWNlIGNvbmR0aW9uIGlzIGFkZGl0aW9uIGFuZCByZW1vdmFsCj4gb2YgZWQg ZnJvbSBlZF9ybV9saXN0IGluIHRoZSBiZWdpbm5pbmcgZHVyaW5nIHVzYl9raWxsX3VyYiBhbmQg bGF0ZXIKPiBsYXN0KiBpcyBtb2RpZmllZCBpbiBmaW5pc2hfdW5saW5rcygpLgo+Cj4gQXMgc3Vn Z2VzdGVkIGJ5IEFsYW4gU3Rlcm4sIHRoZSBzb2x1dGlvbiBmb3IgcHJvcGVyIGhhbmRsaW5nIG9m Cj4gb2hjaS0+ZWRfcm1fbGlzdCBpcyB0byByZW1vdmUgZWQgZnJvbSB0aGUgZWRfcm1fbGlzdCBi ZWZvcmUgZmluaXNoaW5nCj4gYW55IFVSQnMuIFRoZW4gYXQgdGhlIGVuZCwgd2UgY2FuIGFkZCBl ZCBiYWNrIHRvIHRoZSBsaXN0IGlmIG5lY2Vzc2FyeS4KPgo+IFRoaXMgcHJvcGVybHkgaGFuZGxl IHRoZSB1cGRhdGVkIG9oY2ktPmVkX3JtX2xpc3QgaW4gdXNiX2tpbGxfdXJiKCkuCj4KPiBGaXhl czo5NzdkY2ZkYzYwMzEoIlVTQjpPSENJOmRvbid0IGxvc2UgdHJhY2sgb2YgRURzIHdoZW4gYSBj b250cm9sbGVyIGRpZXMiKQo+IEFja2VkLWJ5OiBBbGFuIFN0ZXJuIDxzdGVybkByb3dsYW5kLmhh cnZhcmQuZWR1Pgo+IENDOiA8c3RhYmxlQHZnZXIua2VybmVsLm9yZz4KPiBTaWduZWQtb2ZmLWJ5 OiBBbWFuIERlZXAgPGFtYW4uZGVlcEBzYW1zdW5nLmNvbT4KPiBTaWduZWQtb2ZmLWJ5OiBKZWZm eSBDaGVuIDxqZWZmeS5jaGVuQHJvY2stY2hpcHMuY29tPgo+IC0tLQo+Cj4gQ2hhbmdlcyBpbiB2 NjoKPiBUaGlzIGlzIGEgcmVzZW5kIG9mIEFtYW4gRGVlcCdzIHY1IHBhdGNoIFswXSwgd2hpY2gg c29sdmVkIHRoZSBoYW5nIHdlCj4gaGl0IFsxXS4gKFRoYW5rcyBBbWFuIDopCj4KPiBUaGUgdjUg aGFzIHNvbWUgZm9ybWF0IGlzc3Vlcywgc28gaSBzbGlnaHRseSBhZGp1c3QgdGhlIGNvbW1pdCBt ZXNzYWdlLgo+Cj4gWzBdIGh0dHBzOi8vd3d3LnNwaW5pY3MubmV0L2xpc3RzL2xpbnV4LXVzYi9t c2cxMjkwMTAuaHRtbAo+IFsxXSBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvY2hyb21pdW0v aXNzdWVzL2RldGFpbD9pZD04MDM3NDkKPgo+ICBkcml2ZXJzL3VzYi9ob3N0L29oY2ktcS5jIHwg MTcgKysrKysrKysrKy0tLS0tLS0KPiAgMSBmaWxlIGNoYW5nZWQsIDEwIGluc2VydGlvbnMoKyks IDcgZGVsZXRpb25zKC0pCj4KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy91c2IvaG9zdC9vaGNpLXEu YyBiL2RyaXZlcnMvdXNiL2hvc3Qvb2hjaS1xLmMKPiBpbmRleCBiMmVjOGMzOTkzNjMuLjRjY2I4 NWE2N2JiMyAxMDA2NDQKPiAtLS0gYS9kcml2ZXJzL3VzYi9ob3N0L29oY2ktcS5jCj4gKysrIGIv ZHJpdmVycy91c2IvaG9zdC9vaGNpLXEuYwo+IEBAIC0xMDE5LDYgKzEwMTksOCBAQCBzdGF0aWMg dm9pZCBmaW5pc2hfdW5saW5rcyhzdHJ1Y3Qgb2hjaV9oY2QgKm9oY2kpCj4gICAgICAgICAgICAg ICAgICAqIGhhdmUgbW9kaWZpZWQgdGhpcyBsaXN0LiAgbm9ybWFsbHkgaXQncyBqdXN0IHByZXBl bmRpbmcKPiAgICAgICAgICAgICAgICAgICogZW50cmllcyAod2hpY2ggd2UnZCBpZ25vcmUpLCBi dXQgcGFyYW5vaWEgd29uJ3QgaHVydC4KPiAgICAgICAgICAgICAgICAgICovCj4gKyAgICAgICAg ICAgICAgICpsYXN0ID0gZWQtPmVkX25leHQ7Cj4gKyAgICAgICAgICAgICAgIGVkLT5lZF9uZXh0 ID0gTlVMTDsKPiAgICAgICAgICAgICAgICAgbW9kaWZpZWQgPSAwOwo+Cj4gICAgICAgICAgICAg ICAgIC8qIHVubGluayB1cmJzIGFzIHJlcXVlc3RlZCwgYnV0IHJlc2NhbiB0aGUgbGlzdCBhZnRl cgo+IEBAIC0xMDc3LDIxICsxMDc5LDIyIEBAIHN0YXRpYyB2b2lkIGZpbmlzaF91bmxpbmtzKHN0 cnVjdCBvaGNpX2hjZCAqb2hjaSkKPiAgICAgICAgICAgICAgICAgICAgICAgICBnb3RvIHJlc2Nh bl90aGlzOwo+Cj4gICAgICAgICAgICAgICAgIC8qCj4gLSAgICAgICAgICAgICAgICAqIElmIG5v IFREcyBhcmUgcXVldWVkLCB0YWtlIEVEIG9mZiB0aGUgZWRfcm1fbGlzdC4KPiArICAgICAgICAg ICAgICAgICogSWYgbm8gVERzIGFyZSBxdWV1ZWQsIEVEIGlzIG5vdyBpZGxlLgo+ICAgICAgICAg ICAgICAgICAgKiBPdGhlcndpc2UsIGlmIHRoZSBIQyBpcyBydW5uaW5nLCByZXNjaGVkdWxlLgo+ IC0gICAgICAgICAgICAgICAgKiBJZiBub3QsIGxlYXZlIGl0IG9uIHRoZSBsaXN0IGZvciBmdXJ0 aGVyIGRlcXVldWVzLgo+ICsgICAgICAgICAgICAgICAgKiBJZiB0aGUgSEMgaXNuJ3QgcnVubmlu ZywgYWRkIEVEIGJhY2sgdG8gdGhlCj4gKyAgICAgICAgICAgICAgICAqIHN0YXJ0IG9mIHRoZSBs aXN0IGZvciBsYXRlciBwcm9jZXNzaW5nLgo+ICAgICAgICAgICAgICAgICAgKi8KPiAgICAgICAg ICAgICAgICAgaWYgKGxpc3RfZW1wdHkoJmVkLT50ZF9saXN0KSkgewo+IC0gICAgICAgICAgICAg ICAgICAgICAgICpsYXN0ID0gZWQtPmVkX25leHQ7Cj4gLSAgICAgICAgICAgICAgICAgICAgICAg ZWQtPmVkX25leHQgPSBOVUxMOwo+ICAgICAgICAgICAgICAgICAgICAgICAgIGVkLT5zdGF0ZSA9 IEVEX0lETEU7Cj4gICAgICAgICAgICAgICAgICAgICAgICAgbGlzdF9kZWwoJmVkLT5pbl91c2Vf bGlzdCk7Cj4gICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAob2hjaS0+cmhfc3RhdGUgPT0gT0hD SV9SSF9SVU5OSU5HKSB7Cj4gLSAgICAgICAgICAgICAgICAgICAgICAgKmxhc3QgPSBlZC0+ZWRf bmV4dDsKPiAtICAgICAgICAgICAgICAgICAgICAgICBlZC0+ZWRfbmV4dCA9IE5VTEw7Cj4gICAg ICAgICAgICAgICAgICAgICAgICAgZWRfc2NoZWR1bGUob2hjaSwgZWQpOwo+ICAgICAgICAgICAg ICAgICB9IGVsc2Ugewo+IC0gICAgICAgICAgICAgICAgICAgICAgIGxhc3QgPSAmZWQtPmVkX25l eHQ7Cj4gKyAgICAgICAgICAgICAgICAgICAgICAgZWQtPmVkX25leHQgPSBvaGNpLT5lZF9ybV9s aXN0Owo+ICsgICAgICAgICAgICAgICAgICAgICAgIG9oY2ktPmVkX3JtX2xpc3QgPSBlZDsKPiAr ICAgICAgICAgICAgICAgICAgICAgICAvKiBEb24ndCBsb29wIG9uIHRoZSBzYW1lIEVEICovCj4g KyAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxhc3QgPT0gJm9oY2ktPmVkX3JtX2xpc3QpCj4g KyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXN0ID0gJmVkLT5lZF9uZXh0Owo+ICAg ICAgICAgICAgICAgICB9Cj4KPiAgICAgICAgICAgICAgICAgaWYgKG1vZGlmaWVkKQoKSSBhbSBl eHBlcmllbmNpbmcgYSBVU0IgZnVuY3Rpb24gY2FsbCBoYW5nIGZyb20gdXNlcnNwYWNlIHdpdGgg T0NISQooZnVsbCBzcGVlZCBVU0IgZGV2aWNlKSBhZnRlciB1cGRhdGluZyBmcm9tIExpbnV4IDQu MTQuMTUgdG8gNC4xNC4yNAphbmQgbm90aWNlZCB0aGlzIGNvbW1pdC4KCkhlcmUgaXMgdGhlIExp bnV4IDQuMTQuMjQga2VybmVsIHN0YWNrIHRyYWNlIChleHRyYWN0ZWQgZnJvbSBTeXNScSt3CmFu ZCBhbWVuZGVkIHdpdGggYWRkcjJsaW5lKToKWzxjMDVjYmQ2ND5dIChfX3NjaGVkdWxlKSBmcm9t IFs8YzA1Y2MxNDg+XSAoc2NoZWR1bGUrMHg1MC8weGI0KQprZXJuZWwvc2NoZWQvY29yZS5jOjI3 OTIKWzxjMDVjYzE0OD5dIChzY2hlZHVsZSkgZnJvbSBbPGMwNDI3ODljPl0KKHVzYl9raWxsX3Vy Yi5wYXJ0LjMrMHg3OC8weGE4KSBpbmNsdWRlL2FzbS1nZW5lcmljL3ByZWVtcHQuaDo1OQpbPGMw NDI3ODljPl0gKHVzYl9raWxsX3VyYi5wYXJ0LjMpIGZyb20gWzxjMDQzM2EzYz5dCih1c2JkZXZf aW9jdGwrMHgxMjg4LzB4MWNmMCkgZHJpdmVycy91c2IvY29yZS91cmIuYzo2OTAKWzxjMDQzM2Ez Yz5dICh1c2JkZXZfaW9jdGwpIGZyb20gWzxjMDIxN2RiOD5dCihkb192ZnNfaW9jdGwrMHg5Yy8w eDhlYykgZHJpdmVycy91c2IvY29yZS9kZXZpby5jOjE4MzUKWzxjMDIxN2RiOD5dIChkb192ZnNf aW9jdGwpIGZyb20gWzxjMDIxODYzYz5dIChTeVNfaW9jdGwrMHgzNC8weDVjKQpmcy9pb2N0bC5j OjQ3Cls8YzAyMTg2M2M+XSAoU3lTX2lvY3RsKSBmcm9tIFs8YzAxMDc4MjA+XSAocmV0X2Zhc3Rf c3lzY2FsbCsweDAvMHg1NCkKaW5jbHVkZS9saW51eC9maWxlLmg6MzkKCkFmdGVyd2FyZHMgdGhl IGtlcm5lbCBpcyB1bnJlc3BvbnNpdmUgdG8gZGlzY29ubmVjdC9jb25uZWN0IG9mIHRoZQpmdWxs IHNwZWVkIFVTQiBkZXZpY2UgYnV0IEkgY2FuIGNvbm5lY3QvZGlzY29ubmVjdCBhIGhpZ2ggc3Bl ZWQgVVNCCmRldmljZSB0byB0aGUgc2FtZSBwb3J0IGFuZCBjb21tdW5pY2F0ZSB0byBpdCB3aXRo b3V0IHByb2JsZW0gc2luY2UgaXQKdXNlcyBFSENJIChPSENJIGlzIGNvbXBhbmlvbiBjb250cm9s bGVyKS4gSWYgSSB0cnkgdG8gY29ubmVjdCB0aGUgZnVsbApzcGVlZCBVU0IgZGV2aWNlIGFnYWlu IGl0IGlzIHN0aWxsIHVucmVzcG9uc2l2ZS4gVGhlIHVzZXJzcGFjZQphcHBsaWNhdGlvbiBpcyBz dGlsbCBoYW5naW5nIGFmdGVyIGFsbCB0aGlzLgoKQ291bGQgdGhpcyBjb21taXQgYmUgY2F1c2lu ZyB0aGUgaXNzdWU/CgpUaGFua3MuCgpSZWdhcmRzLApKb25hdGhhbgotLS0KVG8gdW5zdWJzY3Jp YmUgZnJvbSB0aGlzIGxpc3Q6IHNlbmQgdGhlIGxpbmUgInVuc3Vic2NyaWJlIGxpbnV4LXVzYiIg aW4KdGhlIGJvZHkgb2YgYSBtZXNzYWdlIHRvIG1ham9yZG9tb0B2Z2VyLmtlcm5lbC5vcmcKTW9y ZSBtYWpvcmRvbW8gaW5mbyBhdCAgaHR0cDovL3ZnZXIua2VybmVsLm9yZy9tYWpvcmRvbW8taW5m by5odG1sCg==