From mboxrd@z Thu Jan 1 00:00:00 1970 From: Bartlomiej Zolnierkiewicz Date: Wed, 04 Jul 2018 15:07:27 +0000 Subject: Re: [PATCH] fb: fix lost console when the user unplugs a USB adapter Message-Id: <6008699.T6Yd1fn3Dk@amdc3058> List-Id: References: <5091035.TYlAUG7jeO@amdc3058> In-Reply-To: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: Mikulas Patocka Cc: Dave Airlie , linux-fbdev@vger.kernel.org, Ladislav Michl , Bernie Thompson , dri-devel@lists.freedesktop.org On Tuesday, July 03, 2018 01:18:57 PM Mikulas Patocka wrote: > > On Tue, 3 Jul 2018, Bartlomiej Zolnierkiewicz wrote: > > > > > Hi, > > > > On Sunday, June 03, 2018 11:46:29 AM Mikulas Patocka wrote: > > > I have a USB display adapter using the udlfb driver and I use it on an ARM > > > board that doesn't have any graphics card. When I plug the adapter in, the > > > console is properly displayed, however when I unplug and re-plug the > > > adapter, the console is not displayed and I can't access it until I reboot > > > the board. > > > > > > The reason is this: > > > When the adapter is unplugged, dlfb_usb_disconnect calls > > > unlink_framebuffer, then it waits until the reference count drops to zero > > > and then it deallocates the framebuffer. However, the console that is > > > attached to the framebuffer device keeps the reference count non-zero, so > > > the framebuffer device is never destroyed. When the USB adapter is plugged > > > again, it creates a new device /dev/fb1 and the console is not attached to > > > it. > > > > > > This patch fixes the bug by unbinding the console from unlink_framebuffer. > > > The code to unbind the console is moved from do_unregister_framebuffer to > > > a function unbind_console. When the console is unbound, the reference > > > count drops to zero and the udlfb driver frees the framebuffer. When the > > > adapter is plugged back, a new framebuffer is created and the console is > > > attached to it. > > > > > > Signed-off-by: Mikulas Patocka > > > Cc: stable@vger.kernel.org > > > > After this change unbind_console() will be called twice in the standard > > framebuffer unregister path: > > > > - first time, directly by do_unregister_framebuffer() > > > > - second time, indirectly by do_unregister_framebuffer()->unlink_framebuffer() > > > > This doesn't look correctly. > > unbind_console calls the FB_EVENT_FB_UNBIND notifier, FB_EVENT_FB_UNBIND > goes to the function fbcon_fb_unbind and fbcon_fb_unbind checks if the > console is bound to the framebuffer for which unbind is requested. So a > double call won't cause any trouble. Even if it works okay currently it is not a best design to send duplicate events - especially since this can be easily avoided (for non-udlfb users) by: - renaming "vanilla" unlink_framebuffer() to __unlink_framebuffer() - converting do_unregister_framebuffer() to use __unlink_framebuffer() - adding "new" unlink_framebuffer() that will also call unbind_console() > > Also why can't udlfb just use unregister_framebuffer() like all other > > drivers (it uses unlink_framebuffer() and it is the only user of this > > helper)? > > It uses unregister_framebuffer() - but - unregister_framebuffer() may only > be called when the open count of the framebuffer is zero. So, the udlfb > driver waits until the open count drops to zero and then calls > unregister_framebuffer(). > > But the console subsystem keeps the framebuffer open - which means that if > user use unplugs the USB adapter, the open count won't drop to zero > (because the console is bound to it) - which means that > unregister_framebuffer() will not be called. Is it a really the console subsystem and not the user-space keeping /dev/fb0 (with console binded to fb0) opened after the USB device vanishes? After re-plugging the USB device /dev/fb0 stays and /dev/fb1 appears, right? I also mean that unregister_framebuffer() should be called instead unlink_framebuffer(), not additionally some time later as it is done currently. Moreover the dlfb <-> fb_info locking scheme seems to be reversed (+racy) as it is dlfb that should control lifetime of fb_info, then in dlfb_free() we should just call framebuffer_release() etc. BTW comment in dlfb_ops_release(): /* We can't free fb_info here - fbmem will touch it when we return */ seems to be wrong as fbmem keeps an extra reference on fb_info during ->fb_release(). > You must unbind the console before calling unregister_framebuffer(). The Hmm? The first thing that [do_]unregister_framebuffer) does seems to be unbinding the console. > PCI framebuffer drivers don't have this problem because the user is not > expected to just unplug the PCI card while it is being used by the > console. PCI framebuffer drivers currently don't use .suppress_bind_attrs driver flag so the PCI devices can be unbinded at any time by using sysfs "unbind" functionality (I guess we should be using .suppress_bind_attrs flag if it doesn't work currently). > Mikulas > > > > --- > > > drivers/video/fbdev/core/fbmem.c | 21 +++++++++++++++++---- > > > 1 file changed, 17 insertions(+), 4 deletions(-) > > > > > > Index: linux-4.16.12/drivers/video/fbdev/core/fbmem.c > > > =================================> > > --- linux-4.16.12.orig/drivers/video/fbdev/core/fbmem.c 2018-05-26 06:13:20.000000000 +0200 > > > +++ linux-4.16.12/drivers/video/fbdev/core/fbmem.c 2018-05-26 06:13:20.000000000 +0200 > > > @@ -1805,12 +1805,12 @@ static int do_register_framebuffer(struc > > > return 0; > > > } > > > > > > -static int do_unregister_framebuffer(struct fb_info *fb_info) > > > +static int unbind_console(struct fb_info *fb_info) > > > { > > > struct fb_event event; > > > - int i, ret = 0; > > > + int ret; > > > + int i = fb_info->node; > > > > > > - i = fb_info->node; > > > if (i < 0 || i >= FB_MAX || registered_fb[i] != fb_info) > > > return -EINVAL; > > > > > > @@ -1825,6 +1825,16 @@ static int do_unregister_framebuffer(str > > > unlock_fb_info(fb_info); > > > console_unlock(); > > > > > > + return ret; > > > +} > > > + > > > +static int do_unregister_framebuffer(struct fb_info *fb_info) > > > +{ > > > + struct fb_event event; > > > + int ret; > > > + > > > + ret = unbind_console(fb_info); > > > + > > > if (ret) > > > return -EINVAL; > > > > > > @@ -1835,7 +1845,7 @@ static int do_unregister_framebuffer(str > > > (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT)) > > > kfree(fb_info->pixmap.addr); > > > fb_destroy_modelist(&fb_info->modelist); > > > - registered_fb[i] = NULL; > > > + registered_fb[fb_info->node] = NULL; > > > num_registered_fb--; > > > fb_cleanup_device(fb_info); > > > event.info = fb_info; > > > @@ -1860,6 +1870,9 @@ int unlink_framebuffer(struct fb_info *f > > > device_destroy(fb_class, MKDEV(FB_MAJOR, i)); > > > fb_info->dev = NULL; > > > } > > > + > > > + unbind_console(fb_info); > > > + > > > return 0; > > > } > > > EXPORT_SYMBOL(unlink_framebuffer); Best regards, -- Bartlomiej Zolnierkiewicz Samsung R&D Institute Poland Samsung Electronics From mboxrd@z Thu Jan 1 00:00:00 1970 From: Bartlomiej Zolnierkiewicz Subject: Re: [PATCH] fb: fix lost console when the user unplugs a USB adapter Date: Wed, 04 Jul 2018 17:07:27 +0200 Message-ID: <6008699.T6Yd1fn3Dk@amdc3058> References: <5091035.TYlAUG7jeO@amdc3058> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from mailout1.w1.samsung.com (mailout1.w1.samsung.com [210.118.77.11]) by gabe.freedesktop.org (Postfix) with ESMTPS id 7D0836EB8C for ; Wed, 4 Jul 2018 15:07:33 +0000 (UTC) In-reply-to: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Mikulas Patocka Cc: Dave Airlie , linux-fbdev@vger.kernel.org, Ladislav Michl , Bernie Thompson , dri-devel@lists.freedesktop.org List-Id: dri-devel@lists.freedesktop.org T24gVHVlc2RheSwgSnVseSAwMywgMjAxOCAwMToxODo1NyBQTSBNaWt1bGFzIFBhdG9ja2Egd3Jv dGU6Cj4gCj4gT24gVHVlLCAzIEp1bCAyMDE4LCBCYXJ0bG9taWVqIFpvbG5pZXJraWV3aWN6IHdy b3RlOgo+IAo+ID4gCj4gPiBIaSwKPiA+IAo+ID4gT24gU3VuZGF5LCBKdW5lIDAzLCAyMDE4IDEx OjQ2OjI5IEFNIE1pa3VsYXMgUGF0b2NrYSB3cm90ZToKPiA+ID4gSSBoYXZlIGEgVVNCIGRpc3Bs YXkgYWRhcHRlciB1c2luZyB0aGUgdWRsZmIgZHJpdmVyIGFuZCBJIHVzZSBpdCBvbiBhbiBBUk0K PiA+ID4gYm9hcmQgdGhhdCBkb2Vzbid0IGhhdmUgYW55IGdyYXBoaWNzIGNhcmQuIFdoZW4gSSBw bHVnIHRoZSBhZGFwdGVyIGluLCB0aGUKPiA+ID4gY29uc29sZSBpcyBwcm9wZXJseSBkaXNwbGF5 ZWQsIGhvd2V2ZXIgd2hlbiBJIHVucGx1ZyBhbmQgcmUtcGx1ZyB0aGUKPiA+ID4gYWRhcHRlciwg dGhlIGNvbnNvbGUgaXMgbm90IGRpc3BsYXllZCBhbmQgSSBjYW4ndCBhY2Nlc3MgaXQgdW50aWwg SSByZWJvb3QKPiA+ID4gdGhlIGJvYXJkLgo+ID4gPiAKPiA+ID4gVGhlIHJlYXNvbiBpcyB0aGlz Ogo+ID4gPiBXaGVuIHRoZSBhZGFwdGVyIGlzIHVucGx1Z2dlZCwgZGxmYl91c2JfZGlzY29ubmVj dCBjYWxscwo+ID4gPiB1bmxpbmtfZnJhbWVidWZmZXIsIHRoZW4gaXQgd2FpdHMgdW50aWwgdGhl IHJlZmVyZW5jZSBjb3VudCBkcm9wcyB0byB6ZXJvCj4gPiA+IGFuZCB0aGVuIGl0IGRlYWxsb2Nh dGVzIHRoZSBmcmFtZWJ1ZmZlci4gSG93ZXZlciwgdGhlIGNvbnNvbGUgdGhhdCBpcwo+ID4gPiBh dHRhY2hlZCB0byB0aGUgZnJhbWVidWZmZXIgZGV2aWNlIGtlZXBzIHRoZSByZWZlcmVuY2UgY291 bnQgbm9uLXplcm8sIHNvCj4gPiA+IHRoZSBmcmFtZWJ1ZmZlciBkZXZpY2UgaXMgbmV2ZXIgZGVz dHJveWVkLiBXaGVuIHRoZSBVU0IgYWRhcHRlciBpcyBwbHVnZ2VkCj4gPiA+IGFnYWluLCBpdCBj cmVhdGVzIGEgbmV3IGRldmljZSAvZGV2L2ZiMSBhbmQgdGhlIGNvbnNvbGUgaXMgbm90IGF0dGFj aGVkIHRvCj4gPiA+IGl0Lgo+ID4gPiAKPiA+ID4gVGhpcyBwYXRjaCBmaXhlcyB0aGUgYnVnIGJ5 IHVuYmluZGluZyB0aGUgY29uc29sZSBmcm9tIHVubGlua19mcmFtZWJ1ZmZlci4KPiA+ID4gVGhl IGNvZGUgdG8gdW5iaW5kIHRoZSBjb25zb2xlIGlzIG1vdmVkIGZyb20gZG9fdW5yZWdpc3Rlcl9m cmFtZWJ1ZmZlciB0bwo+ID4gPiBhIGZ1bmN0aW9uIHVuYmluZF9jb25zb2xlLiBXaGVuIHRoZSBj b25zb2xlIGlzIHVuYm91bmQsIHRoZSByZWZlcmVuY2UKPiA+ID4gY291bnQgZHJvcHMgdG8gemVy byBhbmQgdGhlIHVkbGZiIGRyaXZlciBmcmVlcyB0aGUgZnJhbWVidWZmZXIuIFdoZW4gdGhlCj4g PiA+IGFkYXB0ZXIgaXMgcGx1Z2dlZCBiYWNrLCBhIG5ldyBmcmFtZWJ1ZmZlciBpcyBjcmVhdGVk IGFuZCB0aGUgY29uc29sZSBpcwo+ID4gPiBhdHRhY2hlZCB0byBpdC4KPiA+ID4gCj4gPiA+IFNp Z25lZC1vZmYtYnk6IE1pa3VsYXMgUGF0b2NrYSA8bXBhdG9ja2FAcmVkaGF0LmNvbT4KPiA+ID4g Q2M6IHN0YWJsZUB2Z2VyLmtlcm5lbC5vcmcKPiA+IAo+ID4gQWZ0ZXIgdGhpcyBjaGFuZ2UgdW5i aW5kX2NvbnNvbGUoKSB3aWxsIGJlIGNhbGxlZCB0d2ljZSBpbiB0aGUgc3RhbmRhcmQKPiA+IGZy YW1lYnVmZmVyIHVucmVnaXN0ZXIgcGF0aDoKPiA+IAo+ID4gLSBmaXJzdCB0aW1lLCBkaXJlY3Rs eSBieSBkb191bnJlZ2lzdGVyX2ZyYW1lYnVmZmVyKCkKPiA+IAo+ID4gLSBzZWNvbmQgdGltZSwg aW5kaXJlY3RseSBieSBkb191bnJlZ2lzdGVyX2ZyYW1lYnVmZmVyKCktPnVubGlua19mcmFtZWJ1 ZmZlcigpCj4gPiAKPiA+IFRoaXMgZG9lc24ndCBsb29rIGNvcnJlY3RseS4KPiAKPiB1bmJpbmRf Y29uc29sZSBjYWxscyB0aGUgRkJfRVZFTlRfRkJfVU5CSU5EIG5vdGlmaWVyLCBGQl9FVkVOVF9G Ql9VTkJJTkQgCj4gZ29lcyB0byB0aGUgZnVuY3Rpb24gZmJjb25fZmJfdW5iaW5kIGFuZCBmYmNv bl9mYl91bmJpbmQgY2hlY2tzIGlmIHRoZSAKPiBjb25zb2xlIGlzIGJvdW5kIHRvIHRoZSBmcmFt ZWJ1ZmZlciBmb3Igd2hpY2ggdW5iaW5kIGlzIHJlcXVlc3RlZC4gU28gYSAKPiBkb3VibGUgY2Fs bCB3b24ndCBjYXVzZSBhbnkgdHJvdWJsZS4KCkV2ZW4gaWYgaXQgd29ya3Mgb2theSBjdXJyZW50 bHkgaXQgaXMgbm90IGEgYmVzdCBkZXNpZ24gdG8gc2VuZCBkdXBsaWNhdGUKZXZlbnRzIC0gZXNw ZWNpYWxseSBzaW5jZSB0aGlzIGNhbiBiZSBlYXNpbHkgYXZvaWRlZCAoZm9yIG5vbi11ZGxmYiB1 c2VycykKYnk6CgotIHJlbmFtaW5nICJ2YW5pbGxhIiB1bmxpbmtfZnJhbWVidWZmZXIoKSB0byBf X3VubGlua19mcmFtZWJ1ZmZlcigpCgotIGNvbnZlcnRpbmcgZG9fdW5yZWdpc3Rlcl9mcmFtZWJ1 ZmZlcigpIHRvIHVzZSBfX3VubGlua19mcmFtZWJ1ZmZlcigpCgotIGFkZGluZyAibmV3IiB1bmxp bmtfZnJhbWVidWZmZXIoKSB0aGF0IHdpbGwgYWxzbyBjYWxsIHVuYmluZF9jb25zb2xlKCkKCj4g PiBBbHNvIHdoeSBjYW4ndCB1ZGxmYiBqdXN0IHVzZSB1bnJlZ2lzdGVyX2ZyYW1lYnVmZmVyKCkg bGlrZSBhbGwgb3RoZXIKPiA+IGRyaXZlcnMgKGl0IHVzZXMgdW5saW5rX2ZyYW1lYnVmZmVyKCkg YW5kIGl0IGlzIHRoZSBvbmx5IHVzZXIgb2YgdGhpcwo+ID4gaGVscGVyKT8KPiAKPiBJdCB1c2Vz IHVucmVnaXN0ZXJfZnJhbWVidWZmZXIoKSAtIGJ1dCAtIHVucmVnaXN0ZXJfZnJhbWVidWZmZXIo KSBtYXkgb25seSAKPiBiZSBjYWxsZWQgd2hlbiB0aGUgb3BlbiBjb3VudCBvZiB0aGUgZnJhbWVi dWZmZXIgaXMgemVyby4gU28sIHRoZSB1ZGxmYiAKPiBkcml2ZXIgd2FpdHMgdW50aWwgdGhlIG9w ZW4gY291bnQgZHJvcHMgdG8gemVybyBhbmQgdGhlbiBjYWxscyAKPiB1bnJlZ2lzdGVyX2ZyYW1l YnVmZmVyKCkuCj4gCj4gQnV0IHRoZSBjb25zb2xlIHN1YnN5c3RlbSBrZWVwcyB0aGUgZnJhbWVi dWZmZXIgb3BlbiAtIHdoaWNoIG1lYW5zIHRoYXQgaWYgCj4gdXNlciB1c2UgdW5wbHVncyB0aGUg VVNCIGFkYXB0ZXIsIHRoZSBvcGVuIGNvdW50IHdvbid0IGRyb3AgdG8gemVybyAKPiAoYmVjYXVz ZSB0aGUgY29uc29sZSBpcyBib3VuZCB0byBpdCkgLSB3aGljaCBtZWFucyB0aGF0IAo+IHVucmVn aXN0ZXJfZnJhbWVidWZmZXIoKSB3aWxsIG5vdCBiZSBjYWxsZWQuCgpJcyBpdCBhIHJlYWxseSB0 aGUgY29uc29sZSBzdWJzeXN0ZW0gYW5kIG5vdCB0aGUgdXNlci1zcGFjZSBrZWVwaW5nCi9kZXYv ZmIwICh3aXRoIGNvbnNvbGUgYmluZGVkIHRvIGZiMCkgb3BlbmVkIGFmdGVyIHRoZSBVU0IgZGV2 aWNlCnZhbmlzaGVzPyBBZnRlciByZS1wbHVnZ2luZyB0aGUgVVNCIGRldmljZSAvZGV2L2ZiMCBz dGF5cyBhbmQgL2Rldi9mYjEKYXBwZWFycywgcmlnaHQ/CgpJIGFsc28gbWVhbiB0aGF0IHVucmVn aXN0ZXJfZnJhbWVidWZmZXIoKSBzaG91bGQgYmUgY2FsbGVkIGluc3RlYWQKdW5saW5rX2ZyYW1l YnVmZmVyKCksIG5vdCBhZGRpdGlvbmFsbHkgc29tZSB0aW1lIGxhdGVyIGFzIGl0IGlzIGRvbmUK Y3VycmVudGx5LgoKTW9yZW92ZXIgdGhlIGRsZmIgPC0+IGZiX2luZm8gbG9ja2luZyBzY2hlbWUg c2VlbXMgdG8gYmUgcmV2ZXJzZWQKKCtyYWN5KSBhcyBpdCBpcyBkbGZiIHRoYXQgc2hvdWxkIGNv bnRyb2wgbGlmZXRpbWUgb2YgZmJfaW5mbywgdGhlbgppbiBkbGZiX2ZyZWUoKSB3ZSBzaG91bGQg anVzdCBjYWxsIGZyYW1lYnVmZmVyX3JlbGVhc2UoKSBldGMuCgpCVFcgY29tbWVudCBpbiBkbGZi X29wc19yZWxlYXNlKCk6CgovKiBXZSBjYW4ndCBmcmVlIGZiX2luZm8gaGVyZSAtIGZibWVtIHdp bGwgdG91Y2ggaXQgd2hlbiB3ZSByZXR1cm4gKi8KCnNlZW1zIHRvIGJlIHdyb25nIGFzIGZibWVt IGtlZXBzIGFuIGV4dHJhIHJlZmVyZW5jZSBvbiBmYl9pbmZvCmR1cmluZyAtPmZiX3JlbGVhc2Uo KS4KCj4gWW91IG11c3QgdW5iaW5kIHRoZSBjb25zb2xlIGJlZm9yZSBjYWxsaW5nIHVucmVnaXN0 ZXJfZnJhbWVidWZmZXIoKS4gVGhlIAoKSG1tPyBUaGUgZmlyc3QgdGhpbmcgdGhhdCBbZG9fXXVu cmVnaXN0ZXJfZnJhbWVidWZmZXIpIGRvZXMgc2VlbXMgdG8gYmUKdW5iaW5kaW5nIHRoZSBjb25z b2xlLgoKPiBQQ0kgZnJhbWVidWZmZXIgZHJpdmVycyBkb24ndCBoYXZlIHRoaXMgcHJvYmxlbSBi ZWNhdXNlIHRoZSB1c2VyIGlzIG5vdCAKPiBleHBlY3RlZCB0byBqdXN0IHVucGx1ZyB0aGUgUENJ IGNhcmQgd2hpbGUgaXQgaXMgYmVpbmcgdXNlZCBieSB0aGUgCj4gY29uc29sZS4KClBDSSBmcmFt ZWJ1ZmZlciBkcml2ZXJzIGN1cnJlbnRseSBkb24ndCB1c2UgLnN1cHByZXNzX2JpbmRfYXR0cnMg ZHJpdmVyCmZsYWcgc28gdGhlIFBDSSBkZXZpY2VzIGNhbiBiZSB1bmJpbmRlZCBhdCBhbnkgdGlt ZSBieSB1c2luZyBzeXNmcyAidW5iaW5kIgpmdW5jdGlvbmFsaXR5IChJIGd1ZXNzIHdlIHNob3Vs ZCBiZSB1c2luZyAuc3VwcHJlc3NfYmluZF9hdHRycyBmbGFnIGlmIGl0CmRvZXNuJ3Qgd29yayBj dXJyZW50bHkpLgoKPiBNaWt1bGFzCj4gCj4gPiA+IC0tLQo+ID4gPiAgZHJpdmVycy92aWRlby9m YmRldi9jb3JlL2ZibWVtLmMgfCAgIDIxICsrKysrKysrKysrKysrKysrLS0tLQo+ID4gPiAgMSBm aWxlIGNoYW5nZWQsIDE3IGluc2VydGlvbnMoKyksIDQgZGVsZXRpb25zKC0pCj4gPiA+IAo+ID4g PiBJbmRleDogbGludXgtNC4xNi4xMi9kcml2ZXJzL3ZpZGVvL2ZiZGV2L2NvcmUvZmJtZW0uYwo+ ID4gPiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09Cj4gPiA+IC0tLSBsaW51eC00LjE2LjEyLm9yaWcvZHJpdmVycy92aWRl by9mYmRldi9jb3JlL2ZibWVtLmMJMjAxOC0wNS0yNiAwNjoxMzoyMC4wMDAwMDAwMDAgKzAyMDAK PiA+ID4gKysrIGxpbnV4LTQuMTYuMTIvZHJpdmVycy92aWRlby9mYmRldi9jb3JlL2ZibWVtLmMJ MjAxOC0wNS0yNiAwNjoxMzoyMC4wMDAwMDAwMDAgKzAyMDAKPiA+ID4gQEAgLTE4MDUsMTIgKzE4 MDUsMTIgQEAgc3RhdGljIGludCBkb19yZWdpc3Rlcl9mcmFtZWJ1ZmZlcihzdHJ1Ywo+ID4gPiAg CXJldHVybiAwOwo+ID4gPiAgfQo+ID4gPiAgCj4gPiA+IC1zdGF0aWMgaW50IGRvX3VucmVnaXN0 ZXJfZnJhbWVidWZmZXIoc3RydWN0IGZiX2luZm8gKmZiX2luZm8pCj4gPiA+ICtzdGF0aWMgaW50 IHVuYmluZF9jb25zb2xlKHN0cnVjdCBmYl9pbmZvICpmYl9pbmZvKQo+ID4gPiAgewo+ID4gPiAg CXN0cnVjdCBmYl9ldmVudCBldmVudDsKPiA+ID4gLQlpbnQgaSwgcmV0ID0gMDsKPiA+ID4gKwlp bnQgcmV0Owo+ID4gPiArCWludCBpID0gZmJfaW5mby0+bm9kZTsKPiA+ID4gIAo+ID4gPiAtCWkg PSBmYl9pbmZvLT5ub2RlOwo+ID4gPiAgCWlmIChpIDwgMCB8fCBpID49IEZCX01BWCB8fCByZWdp c3RlcmVkX2ZiW2ldICE9IGZiX2luZm8pCj4gPiA+ICAJCXJldHVybiAtRUlOVkFMOwo+ID4gPiAg Cj4gPiA+IEBAIC0xODI1LDYgKzE4MjUsMTYgQEAgc3RhdGljIGludCBkb191bnJlZ2lzdGVyX2Zy YW1lYnVmZmVyKHN0cgo+ID4gPiAgCXVubG9ja19mYl9pbmZvKGZiX2luZm8pOwo+ID4gPiAgCWNv bnNvbGVfdW5sb2NrKCk7Cj4gPiA+ICAKPiA+ID4gKwlyZXR1cm4gcmV0Owo+ID4gPiArfQo+ID4g PiArCj4gPiA+ICtzdGF0aWMgaW50IGRvX3VucmVnaXN0ZXJfZnJhbWVidWZmZXIoc3RydWN0IGZi X2luZm8gKmZiX2luZm8pCj4gPiA+ICt7Cj4gPiA+ICsJc3RydWN0IGZiX2V2ZW50IGV2ZW50Owo+ ID4gPiArCWludCByZXQ7Cj4gPiA+ICsKPiA+ID4gKwlyZXQgPSB1bmJpbmRfY29uc29sZShmYl9p bmZvKTsKPiA+ID4gKwo+ID4gPiAgCWlmIChyZXQpCj4gPiA+ICAJCXJldHVybiAtRUlOVkFMOwo+ ID4gPiAgCj4gPiA+IEBAIC0xODM1LDcgKzE4NDUsNyBAQCBzdGF0aWMgaW50IGRvX3VucmVnaXN0 ZXJfZnJhbWVidWZmZXIoc3RyCj4gPiA+ICAJICAgIChmYl9pbmZvLT5waXhtYXAuZmxhZ3MgJiBG Ql9QSVhNQVBfREVGQVVMVCkpCj4gPiA+ICAJCWtmcmVlKGZiX2luZm8tPnBpeG1hcC5hZGRyKTsK PiA+ID4gIAlmYl9kZXN0cm95X21vZGVsaXN0KCZmYl9pbmZvLT5tb2RlbGlzdCk7Cj4gPiA+IC0J cmVnaXN0ZXJlZF9mYltpXSA9IE5VTEw7Cj4gPiA+ICsJcmVnaXN0ZXJlZF9mYltmYl9pbmZvLT5u b2RlXSA9IE5VTEw7Cj4gPiA+ICAJbnVtX3JlZ2lzdGVyZWRfZmItLTsKPiA+ID4gIAlmYl9jbGVh bnVwX2RldmljZShmYl9pbmZvKTsKPiA+ID4gIAlldmVudC5pbmZvID0gZmJfaW5mbzsKPiA+ID4g QEAgLTE4NjAsNiArMTg3MCw5IEBAIGludCB1bmxpbmtfZnJhbWVidWZmZXIoc3RydWN0IGZiX2lu Zm8gKmYKPiA+ID4gIAkJZGV2aWNlX2Rlc3Ryb3koZmJfY2xhc3MsIE1LREVWKEZCX01BSk9SLCBp KSk7Cj4gPiA+ICAJCWZiX2luZm8tPmRldiA9IE5VTEw7Cj4gPiA+ICAJfQo+ID4gPiArCj4gPiA+ ICsJdW5iaW5kX2NvbnNvbGUoZmJfaW5mbyk7Cj4gPiA+ICsKPiA+ID4gIAlyZXR1cm4gMDsKPiA+ ID4gIH0KPiA+ID4gIEVYUE9SVF9TWU1CT0wodW5saW5rX2ZyYW1lYnVmZmVyKTsKCkJlc3QgcmVn YXJkcywKLS0KQmFydGxvbWllaiBab2xuaWVya2lld2ljegpTYW1zdW5nIFImRCBJbnN0aXR1dGUg UG9sYW5kClNhbXN1bmcgRWxlY3Ryb25pY3MKCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fCmRyaS1kZXZlbCBtYWlsaW5nIGxpc3QKZHJpLWRldmVsQGxpc3Rz LmZyZWVkZXNrdG9wLm9yZwpodHRwczovL2xpc3RzLmZyZWVkZXNrdG9wLm9yZy9tYWlsbWFuL2xp c3RpbmZvL2RyaS1kZXZlbAo=