From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751717AbdJFOXX (ORCPT ); Fri, 6 Oct 2017 10:23:23 -0400 Received: from mail-wm0-f67.google.com ([74.125.82.67]:33638 "EHLO mail-wm0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750950AbdJFOXV (ORCPT ); Fri, 6 Oct 2017 10:23:21 -0400 X-Google-Smtp-Source: AOwi7QBcgbOrpMlBNEHgSWK16Y5dCxRw4hVrYdQdaR5bBEpSbZm3dia9PxfvjEkJp5Q6MtOjGsIu8g== Date: Fri, 6 Oct 2017 16:23:17 +0200 From: Daniel Vetter To: Tvrtko Ursulin Cc: Daniel Vetter , Intel Graphics Development , Peter Zijlstra , LKML , Tejun Heo , Daniel Vetter , Thomas Gleixner , Sasha Levin Subject: Re: [Intel-gfx] [PATCH 1/2] drm/i915: Preallocate our mmu notifier workequeu to unbreak cpu hotplug deadlock Message-ID: <20171006142317.gwecjkftrj5djies@phenom.ffwll.local> Mail-Followup-To: Tvrtko Ursulin , Intel Graphics Development , Peter Zijlstra , LKML , Tejun Heo , Daniel Vetter , Thomas Gleixner , Sasha Levin References: <20171006090637.25545-1-daniel.vetter@ffwll.ch> <9f61d57c-12c4-eb01-a008-e674727810d6@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <9f61d57c-12c4-eb01-a008-e674727810d6@linux.intel.com> X-Operating-System: Linux phenom 4.12.0-1-amd64 User-Agent: NeoMutt/20170609 (1.8.3) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, Oct 06, 2017 at 12:34:02PM +0100, Tvrtko Ursulin wrote: > > On 06/10/2017 10:06, Daniel Vetter wrote: > > 4.14-rc1 gained the fancy new cross-release support in lockdep, which > > seems to have uncovered a few more rules about what is allowed and > > isn't. > > > > This one here seems to indicate that allocating a work-queue while > > holding mmap_sem is a no-go, so let's try to preallocate it. > > > > Of course another way to break this chain would be somewhere in the > > cpu hotplug code, since this isn't the only trace we're finding now > > which goes through msr_create_device. > > > > Full lockdep splat: > > > > ====================================================== > > WARNING: possible circular locking dependency detected > > 4.14.0-rc1-CI-CI_DRM_3118+ #1 Tainted: G U > > ------------------------------------------------------ > > prime_mmap/1551 is trying to acquire lock: > > (cpu_hotplug_lock.rw_sem){++++}, at: [] apply_workqueue_attrs+0x17/0x50 > > > > but task is already holding lock: > > (&dev_priv->mm_lock){+.+.}, at: [] i915_gem_userptr_init__mmu_notifier+0x14a/0x270 [i915] > > > > which lock already depends on the new lock. > > > > the existing dependency chain (in reverse order) is: > > > > -> #6 (&dev_priv->mm_lock){+.+.}: > > __lock_acquire+0x1420/0x15e0 > > lock_acquire+0xb0/0x200 > > __mutex_lock+0x86/0x9b0 > > mutex_lock_nested+0x1b/0x20 > > i915_gem_userptr_init__mmu_notifier+0x14a/0x270 [i915] > > i915_gem_userptr_ioctl+0x222/0x2c0 [i915] > > drm_ioctl_kernel+0x69/0xb0 > > drm_ioctl+0x2f9/0x3d0 > > do_vfs_ioctl+0x94/0x670 > > SyS_ioctl+0x41/0x70 > > entry_SYSCALL_64_fastpath+0x1c/0xb1 > > > > -> #5 (&mm->mmap_sem){++++}: > > __lock_acquire+0x1420/0x15e0 > > lock_acquire+0xb0/0x200 > > __might_fault+0x68/0x90 > > _copy_to_user+0x23/0x70 > > filldir+0xa5/0x120 > > dcache_readdir+0xf9/0x170 > > iterate_dir+0x69/0x1a0 > > SyS_getdents+0xa5/0x140 > > entry_SYSCALL_64_fastpath+0x1c/0xb1 > > > > -> #4 (&sb->s_type->i_mutex_key#5){++++}: > > down_write+0x3b/0x70 > > handle_create+0xcb/0x1e0 > > devtmpfsd+0x139/0x180 > > kthread+0x152/0x190 > > ret_from_fork+0x27/0x40 > > > > -> #3 ((complete)&req.done){+.+.}: > > __lock_acquire+0x1420/0x15e0 > > lock_acquire+0xb0/0x200 > > wait_for_common+0x58/0x210 > > wait_for_completion+0x1d/0x20 > > devtmpfs_create_node+0x13d/0x160 > > device_add+0x5eb/0x620 > > device_create_groups_vargs+0xe0/0xf0 > > device_create+0x3a/0x40 > > msr_device_create+0x2b/0x40 > > cpuhp_invoke_callback+0xa3/0x840 > > cpuhp_thread_fun+0x7a/0x150 > > smpboot_thread_fn+0x18a/0x280 > > kthread+0x152/0x190 > > ret_from_fork+0x27/0x40 > > > > -> #2 (cpuhp_state){+.+.}: > > __lock_acquire+0x1420/0x15e0 > > lock_acquire+0xb0/0x200 > > cpuhp_issue_call+0x10b/0x170 > > __cpuhp_setup_state_cpuslocked+0x134/0x2a0 > > __cpuhp_setup_state+0x46/0x60 > > page_writeback_init+0x43/0x67 > > pagecache_init+0x3d/0x42 > > start_kernel+0x3a8/0x3fc > > x86_64_start_reservations+0x2a/0x2c > > x86_64_start_kernel+0x6d/0x70 > > verify_cpu+0x0/0xfb > > > > -> #1 (cpuhp_state_mutex){+.+.}: > > __lock_acquire+0x1420/0x15e0 > > lock_acquire+0xb0/0x200 > > __mutex_lock+0x86/0x9b0 > > mutex_lock_nested+0x1b/0x20 > > __cpuhp_setup_state_cpuslocked+0x52/0x2a0 > > __cpuhp_setup_state+0x46/0x60 > > page_alloc_init+0x28/0x30 > > start_kernel+0x145/0x3fc > > x86_64_start_reservations+0x2a/0x2c > > x86_64_start_kernel+0x6d/0x70 > > verify_cpu+0x0/0xfb > > > > -> #0 (cpu_hotplug_lock.rw_sem){++++}: > > check_prev_add+0x430/0x840 > > __lock_acquire+0x1420/0x15e0 > > lock_acquire+0xb0/0x200 > > cpus_read_lock+0x3d/0xb0 > > apply_workqueue_attrs+0x17/0x50 > > __alloc_workqueue_key+0x1d8/0x4d9 > > i915_gem_userptr_init__mmu_notifier+0x1fb/0x270 [i915] > > i915_gem_userptr_ioctl+0x222/0x2c0 [i915] > > drm_ioctl_kernel+0x69/0xb0 > > drm_ioctl+0x2f9/0x3d0 > > do_vfs_ioctl+0x94/0x670 > > SyS_ioctl+0x41/0x70 > > entry_SYSCALL_64_fastpath+0x1c/0xb1 > > > > other info that might help us debug this: > > > > Chain exists of: > > cpu_hotplug_lock.rw_sem --> &mm->mmap_sem --> &dev_priv->mm_lock > > > > Possible unsafe locking scenario: > > > > CPU0 CPU1 > > ---- ---- > > lock(&dev_priv->mm_lock); > > lock(&mm->mmap_sem); > > lock(&dev_priv->mm_lock); > > lock(cpu_hotplug_lock.rw_sem); > > > > *** DEADLOCK *** > > > > 2 locks held by prime_mmap/1551: > > #0: (&mm->mmap_sem){++++}, at: [] i915_gem_userptr_init__mmu_notifier+0x138/0x270 [i915] > > #1: (&dev_priv->mm_lock){+.+.}, at: [] i915_gem_userptr_init__mmu_notifier+0x14a/0x270 [i915] > > > > stack backtrace: > > CPU: 4 PID: 1551 Comm: prime_mmap Tainted: G U 4.14.0-rc1-CI-CI_DRM_3118+ #1 > > Hardware name: Dell Inc. XPS 8300 /0Y2MRG, BIOS A06 10/17/2011 > > Call Trace: > > dump_stack+0x68/0x9f > > print_circular_bug+0x235/0x3c0 > > ? lockdep_init_map_crosslock+0x20/0x20 > > check_prev_add+0x430/0x840 > > __lock_acquire+0x1420/0x15e0 > > ? __lock_acquire+0x1420/0x15e0 > > ? lockdep_init_map_crosslock+0x20/0x20 > > lock_acquire+0xb0/0x200 > > ? apply_workqueue_attrs+0x17/0x50 > > cpus_read_lock+0x3d/0xb0 > > ? apply_workqueue_attrs+0x17/0x50 > > apply_workqueue_attrs+0x17/0x50 > > __alloc_workqueue_key+0x1d8/0x4d9 > > ? __lockdep_init_map+0x57/0x1c0 > > i915_gem_userptr_init__mmu_notifier+0x1fb/0x270 [i915] > > i915_gem_userptr_ioctl+0x222/0x2c0 [i915] > > ? i915_gem_userptr_release+0x140/0x140 [i915] > > drm_ioctl_kernel+0x69/0xb0 > > drm_ioctl+0x2f9/0x3d0 > > ? i915_gem_userptr_release+0x140/0x140 [i915] > > ? __do_page_fault+0x2a4/0x570 > > do_vfs_ioctl+0x94/0x670 > > ? entry_SYSCALL_64_fastpath+0x5/0xb1 > > ? __this_cpu_preempt_check+0x13/0x20 > > ? trace_hardirqs_on_caller+0xe3/0x1b0 > > SyS_ioctl+0x41/0x70 > > entry_SYSCALL_64_fastpath+0x1c/0xb1 > > RIP: 0033:0x7fbb83c39587 > > RSP: 002b:00007fff188dc228 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 > > RAX: ffffffffffffffda RBX: ffffffff81492963 RCX: 00007fbb83c39587 > > RDX: 00007fff188dc260 RSI: 00000000c0186473 RDI: 0000000000000003 > > RBP: ffffc90001487f88 R08: 0000000000000000 R09: 00007fff188dc2ac > > R10: 00007fbb83efcb58 R11: 0000000000000246 R12: 0000000000000000 > > R13: 0000000000000003 R14: 00000000c0186473 R15: 00007fff188dc2ac > > ? __this_cpu_preempt_check+0x13/0x20 > > > > v2: Set ret correctly when we raced with another thread. > > > > v3: Use Chris' diff. Attach the right lockdep splat. > > > > Cc: Chris Wilson > > Cc: Tvrtko Ursulin > > Cc: Joonas Lahtinen > > Cc: Peter Zijlstra > > Cc: Thomas Gleixner > > Cc: Sasha Levin > > Cc: Marta Lofstedt > > Cc: Tejun Heo > > References: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_3180/shard-hsw3/igt@prime_mmap@test_userptr.html > > Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=102939 > > Signed-off-by: Daniel Vetter > > --- > > drivers/gpu/drm/i915/i915_gem_userptr.c | 35 +++++++++++++++++++-------------- > > 1 file changed, 20 insertions(+), 15 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c > > index 2d4996de7331..f9b3406401af 100644 > > --- a/drivers/gpu/drm/i915/i915_gem_userptr.c > > +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c > > @@ -164,7 +164,6 @@ static struct i915_mmu_notifier * > > i915_mmu_notifier_create(struct mm_struct *mm) > > { > > struct i915_mmu_notifier *mn; > > - int ret; > > mn = kmalloc(sizeof(*mn), GFP_KERNEL); > > if (mn == NULL) > > @@ -179,14 +178,6 @@ i915_mmu_notifier_create(struct mm_struct *mm) > > return ERR_PTR(-ENOMEM); > > } > > - /* Protected by mmap_sem (write-lock) */ > > - ret = __mmu_notifier_register(&mn->mn, mm); > > - if (ret) { > > - destroy_workqueue(mn->wq); > > - kfree(mn); > > - return ERR_PTR(ret); > > - } > > - > > return mn; > > } > > @@ -210,23 +201,37 @@ i915_gem_userptr_release__mmu_notifier(struct drm_i915_gem_object *obj) > > static struct i915_mmu_notifier * > > i915_mmu_notifier_find(struct i915_mm_struct *mm) > > { > > - struct i915_mmu_notifier *mn = mm->mn; > > + struct i915_mmu_notifier *mn; > > + int err; > > mn = mm->mn; > > if (mn) > > return mn; > > + mn = i915_mmu_notifier_create(mm->mm); > > + if (IS_ERR(mn)) > > + return mn; > > Strictly speaking we don't want to fail just yet, only it we actually needed > a new notifier and we failed to create it. The check 2 lines above not good enough? It's somewhat racy, but I'm not sure what value we provide by being perfectly correct against low memory. This thread racing against a 2nd one, where the minimal allocation of the 2nd one pushed us perfectly over the oom threshold seems a very unlikely scenario. Also, small allocations actually never fail :-) > > > + > > + err = 0; > > down_write(&mm->mm->mmap_sem); > > mutex_lock(&mm->i915->mm_lock); > > - if ((mn = mm->mn) == NULL) { > > - mn = i915_mmu_notifier_create(mm->mm); > > - if (!IS_ERR(mn)) > > - mm->mn = mn; > > + if (mm->mn == NULL) { > > + /* Protected by mmap_sem (write-lock) */ > > + err = __mmu_notifier_register(&mn->mn, mm->mm); > > + if (!err) { > > + /* Protected by mm_lock */ > > + mm->mn = fetch_and_zero(&mn); > > + } > > } > > mutex_unlock(&mm->i915->mm_lock); > > up_write(&mm->mm->mmap_sem); > > - return mn; > > + if (mn) { > > + destroy_workqueue(mn->wq); > > + kfree(mn); > > + } > > + > > + return err ? ERR_PTR(err) : mm->mn; > > } > > static int > > > > Otherwise looks good to me. > > I would also put a note in the commit on how working around the locking > issue is also beneficial to performance with moving the allocation step > outside the mmap_sem. Yeah Chris brought that up too, I don't really buy it given how heavy-weight __mmu_notifier_register is. But I can add something like: "This also has the minor benefit of slightly reducing the critical section where we hold mmap_sem." r-b with that added to the commit message? -Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch From mboxrd@z Thu Jan 1 00:00:00 1970 From: Daniel Vetter Subject: Re: [PATCH 1/2] drm/i915: Preallocate our mmu notifier workequeu to unbreak cpu hotplug deadlock Date: Fri, 6 Oct 2017 16:23:17 +0200 Message-ID: <20171006142317.gwecjkftrj5djies@phenom.ffwll.local> References: <20171006090637.25545-1-daniel.vetter@ffwll.ch> <9f61d57c-12c4-eb01-a008-e674727810d6@linux.intel.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from mail-wm0-x241.google.com (mail-wm0-x241.google.com [IPv6:2a00:1450:400c:c09::241]) by gabe.freedesktop.org (Postfix) with ESMTPS id C7B106E971 for ; Fri, 6 Oct 2017 14:23:21 +0000 (UTC) Received: by mail-wm0-x241.google.com with SMTP id k66so6918500wmd.4 for ; Fri, 06 Oct 2017 07:23:21 -0700 (PDT) Content-Disposition: inline In-Reply-To: <9f61d57c-12c4-eb01-a008-e674727810d6@linux.intel.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" To: Tvrtko Ursulin Cc: Peter Zijlstra , Daniel Vetter , Intel Graphics Development , LKML , Sasha Levin , Tejun Heo , Daniel Vetter , Thomas Gleixner List-Id: intel-gfx@lists.freedesktop.org T24gRnJpLCBPY3QgMDYsIDIwMTcgYXQgMTI6MzQ6MDJQTSArMDEwMCwgVHZydGtvIFVyc3VsaW4g d3JvdGU6Cj4gCj4gT24gMDYvMTAvMjAxNyAxMDowNiwgRGFuaWVsIFZldHRlciB3cm90ZToKPiA+ IDQuMTQtcmMxIGdhaW5lZCB0aGUgZmFuY3kgbmV3IGNyb3NzLXJlbGVhc2Ugc3VwcG9ydCBpbiBs b2NrZGVwLCB3aGljaAo+ID4gc2VlbXMgdG8gaGF2ZSB1bmNvdmVyZWQgYSBmZXcgbW9yZSBydWxl cyBhYm91dCB3aGF0IGlzIGFsbG93ZWQgYW5kCj4gPiBpc24ndC4KPiA+IAo+ID4gVGhpcyBvbmUg aGVyZSBzZWVtcyB0byBpbmRpY2F0ZSB0aGF0IGFsbG9jYXRpbmcgYSB3b3JrLXF1ZXVlIHdoaWxl Cj4gPiBob2xkaW5nIG1tYXBfc2VtIGlzIGEgbm8tZ28sIHNvIGxldCdzIHRyeSB0byBwcmVhbGxv Y2F0ZSBpdC4KPiA+IAo+ID4gT2YgY291cnNlIGFub3RoZXIgd2F5IHRvIGJyZWFrIHRoaXMgY2hh aW4gd291bGQgYmUgc29tZXdoZXJlIGluIHRoZQo+ID4gY3B1IGhvdHBsdWcgY29kZSwgc2luY2Ug dGhpcyBpc24ndCB0aGUgb25seSB0cmFjZSB3ZSdyZSBmaW5kaW5nIG5vdwo+ID4gd2hpY2ggZ29l cyB0aHJvdWdoIG1zcl9jcmVhdGVfZGV2aWNlLgo+ID4gCj4gPiBGdWxsIGxvY2tkZXAgc3BsYXQ6 Cj4gPiAKPiA+ID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09 PT09PT09PQo+ID4gV0FSTklORzogcG9zc2libGUgY2lyY3VsYXIgbG9ja2luZyBkZXBlbmRlbmN5 IGRldGVjdGVkCj4gPiA0LjE0LjAtcmMxLUNJLUNJX0RSTV8zMTE4KyAjMSBUYWludGVkOiBHICAg ICBVCj4gPiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0KPiA+IHByaW1lX21tYXAvMTU1MSBpcyB0cnlpbmcgdG8gYWNxdWlyZSBsb2NrOgo+ID4g ICAoY3B1X2hvdHBsdWdfbG9jay5yd19zZW0peysrKyt9LCBhdDogWzxmZmZmZmZmZjgxMDlkYmI3 Pl0gYXBwbHlfd29ya3F1ZXVlX2F0dHJzKzB4MTcvMHg1MAo+ID4gCj4gPiBidXQgdGFzayBpcyBh bHJlYWR5IGhvbGRpbmcgbG9jazoKPiA+ICAgKCZkZXZfcHJpdi0+bW1fbG9jayl7Ky4rLn0sIGF0 OiBbPGZmZmZmZmZmYTAxYTdiMmE+XSBpOTE1X2dlbV91c2VycHRyX2luaXRfX21tdV9ub3RpZmll cisweDE0YS8weDI3MCBbaTkxNV0KPiA+IAo+ID4gd2hpY2ggbG9jayBhbHJlYWR5IGRlcGVuZHMg b24gdGhlIG5ldyBsb2NrLgo+ID4gCj4gPiB0aGUgZXhpc3RpbmcgZGVwZW5kZW5jeSBjaGFpbiAo aW4gcmV2ZXJzZSBvcmRlcikgaXM6Cj4gPiAKPiA+IC0+ICM2ICgmZGV2X3ByaXYtPm1tX2xvY2sp eysuKy59Ogo+ID4gICAgICAgICBfX2xvY2tfYWNxdWlyZSsweDE0MjAvMHgxNWUwCj4gPiAgICAg ICAgIGxvY2tfYWNxdWlyZSsweGIwLzB4MjAwCj4gPiAgICAgICAgIF9fbXV0ZXhfbG9jaysweDg2 LzB4OWIwCj4gPiAgICAgICAgIG11dGV4X2xvY2tfbmVzdGVkKzB4MWIvMHgyMAo+ID4gICAgICAg ICBpOTE1X2dlbV91c2VycHRyX2luaXRfX21tdV9ub3RpZmllcisweDE0YS8weDI3MCBbaTkxNV0K PiA+ICAgICAgICAgaTkxNV9nZW1fdXNlcnB0cl9pb2N0bCsweDIyMi8weDJjMCBbaTkxNV0KPiA+ ICAgICAgICAgZHJtX2lvY3RsX2tlcm5lbCsweDY5LzB4YjAKPiA+ICAgICAgICAgZHJtX2lvY3Rs KzB4MmY5LzB4M2QwCj4gPiAgICAgICAgIGRvX3Zmc19pb2N0bCsweDk0LzB4NjcwCj4gPiAgICAg ICAgIFN5U19pb2N0bCsweDQxLzB4NzAKPiA+ICAgICAgICAgZW50cnlfU1lTQ0FMTF82NF9mYXN0 cGF0aCsweDFjLzB4YjEKPiA+IAo+ID4gLT4gIzUgKCZtbS0+bW1hcF9zZW0peysrKyt9Ogo+ID4g ICAgICAgICBfX2xvY2tfYWNxdWlyZSsweDE0MjAvMHgxNWUwCj4gPiAgICAgICAgIGxvY2tfYWNx dWlyZSsweGIwLzB4MjAwCj4gPiAgICAgICAgIF9fbWlnaHRfZmF1bHQrMHg2OC8weDkwCj4gPiAg ICAgICAgIF9jb3B5X3RvX3VzZXIrMHgyMy8weDcwCj4gPiAgICAgICAgIGZpbGxkaXIrMHhhNS8w eDEyMAo+ID4gICAgICAgICBkY2FjaGVfcmVhZGRpcisweGY5LzB4MTcwCj4gPiAgICAgICAgIGl0 ZXJhdGVfZGlyKzB4NjkvMHgxYTAKPiA+ICAgICAgICAgU3lTX2dldGRlbnRzKzB4YTUvMHgxNDAK PiA+ICAgICAgICAgZW50cnlfU1lTQ0FMTF82NF9mYXN0cGF0aCsweDFjLzB4YjEKPiA+IAo+ID4g LT4gIzQgKCZzYi0+c190eXBlLT5pX211dGV4X2tleSM1KXsrKysrfToKPiA+ICAgICAgICAgZG93 bl93cml0ZSsweDNiLzB4NzAKPiA+ICAgICAgICAgaGFuZGxlX2NyZWF0ZSsweGNiLzB4MWUwCj4g PiAgICAgICAgIGRldnRtcGZzZCsweDEzOS8weDE4MAo+ID4gICAgICAgICBrdGhyZWFkKzB4MTUy LzB4MTkwCj4gPiAgICAgICAgIHJldF9mcm9tX2ZvcmsrMHgyNy8weDQwCj4gPiAKPiA+IC0+ICMz ICgoY29tcGxldGUpJnJlcS5kb25lKXsrLisufToKPiA+ICAgICAgICAgX19sb2NrX2FjcXVpcmUr MHgxNDIwLzB4MTVlMAo+ID4gICAgICAgICBsb2NrX2FjcXVpcmUrMHhiMC8weDIwMAo+ID4gICAg ICAgICB3YWl0X2Zvcl9jb21tb24rMHg1OC8weDIxMAo+ID4gICAgICAgICB3YWl0X2Zvcl9jb21w bGV0aW9uKzB4MWQvMHgyMAo+ID4gICAgICAgICBkZXZ0bXBmc19jcmVhdGVfbm9kZSsweDEzZC8w eDE2MAo+ID4gICAgICAgICBkZXZpY2VfYWRkKzB4NWViLzB4NjIwCj4gPiAgICAgICAgIGRldmlj ZV9jcmVhdGVfZ3JvdXBzX3ZhcmdzKzB4ZTAvMHhmMAo+ID4gICAgICAgICBkZXZpY2VfY3JlYXRl KzB4M2EvMHg0MAo+ID4gICAgICAgICBtc3JfZGV2aWNlX2NyZWF0ZSsweDJiLzB4NDAKPiA+ICAg ICAgICAgY3B1aHBfaW52b2tlX2NhbGxiYWNrKzB4YTMvMHg4NDAKPiA+ICAgICAgICAgY3B1aHBf dGhyZWFkX2Z1bisweDdhLzB4MTUwCj4gPiAgICAgICAgIHNtcGJvb3RfdGhyZWFkX2ZuKzB4MThh LzB4MjgwCj4gPiAgICAgICAgIGt0aHJlYWQrMHgxNTIvMHgxOTAKPiA+ICAgICAgICAgcmV0X2Zy b21fZm9yaysweDI3LzB4NDAKPiA+IAo+ID4gLT4gIzIgKGNwdWhwX3N0YXRlKXsrLisufToKPiA+ ICAgICAgICAgX19sb2NrX2FjcXVpcmUrMHgxNDIwLzB4MTVlMAo+ID4gICAgICAgICBsb2NrX2Fj cXVpcmUrMHhiMC8weDIwMAo+ID4gICAgICAgICBjcHVocF9pc3N1ZV9jYWxsKzB4MTBiLzB4MTcw Cj4gPiAgICAgICAgIF9fY3B1aHBfc2V0dXBfc3RhdGVfY3B1c2xvY2tlZCsweDEzNC8weDJhMAo+ ID4gICAgICAgICBfX2NwdWhwX3NldHVwX3N0YXRlKzB4NDYvMHg2MAo+ID4gICAgICAgICBwYWdl X3dyaXRlYmFja19pbml0KzB4NDMvMHg2Nwo+ID4gICAgICAgICBwYWdlY2FjaGVfaW5pdCsweDNk LzB4NDIKPiA+ICAgICAgICAgc3RhcnRfa2VybmVsKzB4M2E4LzB4M2ZjCj4gPiAgICAgICAgIHg4 Nl82NF9zdGFydF9yZXNlcnZhdGlvbnMrMHgyYS8weDJjCj4gPiAgICAgICAgIHg4Nl82NF9zdGFy dF9rZXJuZWwrMHg2ZC8weDcwCj4gPiAgICAgICAgIHZlcmlmeV9jcHUrMHgwLzB4ZmIKPiA+IAo+ ID4gLT4gIzEgKGNwdWhwX3N0YXRlX211dGV4KXsrLisufToKPiA+ICAgICAgICAgX19sb2NrX2Fj cXVpcmUrMHgxNDIwLzB4MTVlMAo+ID4gICAgICAgICBsb2NrX2FjcXVpcmUrMHhiMC8weDIwMAo+ ID4gICAgICAgICBfX211dGV4X2xvY2srMHg4Ni8weDliMAo+ID4gICAgICAgICBtdXRleF9sb2Nr X25lc3RlZCsweDFiLzB4MjAKPiA+ICAgICAgICAgX19jcHVocF9zZXR1cF9zdGF0ZV9jcHVzbG9j a2VkKzB4NTIvMHgyYTAKPiA+ICAgICAgICAgX19jcHVocF9zZXR1cF9zdGF0ZSsweDQ2LzB4NjAK PiA+ICAgICAgICAgcGFnZV9hbGxvY19pbml0KzB4MjgvMHgzMAo+ID4gICAgICAgICBzdGFydF9r ZXJuZWwrMHgxNDUvMHgzZmMKPiA+ICAgICAgICAgeDg2XzY0X3N0YXJ0X3Jlc2VydmF0aW9ucysw eDJhLzB4MmMKPiA+ICAgICAgICAgeDg2XzY0X3N0YXJ0X2tlcm5lbCsweDZkLzB4NzAKPiA+ICAg ICAgICAgdmVyaWZ5X2NwdSsweDAvMHhmYgo+ID4gCj4gPiAtPiAjMCAoY3B1X2hvdHBsdWdfbG9j ay5yd19zZW0peysrKyt9Ogo+ID4gICAgICAgICBjaGVja19wcmV2X2FkZCsweDQzMC8weDg0MAo+ ID4gICAgICAgICBfX2xvY2tfYWNxdWlyZSsweDE0MjAvMHgxNWUwCj4gPiAgICAgICAgIGxvY2tf YWNxdWlyZSsweGIwLzB4MjAwCj4gPiAgICAgICAgIGNwdXNfcmVhZF9sb2NrKzB4M2QvMHhiMAo+ ID4gICAgICAgICBhcHBseV93b3JrcXVldWVfYXR0cnMrMHgxNy8weDUwCj4gPiAgICAgICAgIF9f YWxsb2Nfd29ya3F1ZXVlX2tleSsweDFkOC8weDRkOQo+ID4gICAgICAgICBpOTE1X2dlbV91c2Vy cHRyX2luaXRfX21tdV9ub3RpZmllcisweDFmYi8weDI3MCBbaTkxNV0KPiA+ICAgICAgICAgaTkx NV9nZW1fdXNlcnB0cl9pb2N0bCsweDIyMi8weDJjMCBbaTkxNV0KPiA+ICAgICAgICAgZHJtX2lv Y3RsX2tlcm5lbCsweDY5LzB4YjAKPiA+ICAgICAgICAgZHJtX2lvY3RsKzB4MmY5LzB4M2QwCj4g PiAgICAgICAgIGRvX3Zmc19pb2N0bCsweDk0LzB4NjcwCj4gPiAgICAgICAgIFN5U19pb2N0bCsw eDQxLzB4NzAKPiA+ICAgICAgICAgZW50cnlfU1lTQ0FMTF82NF9mYXN0cGF0aCsweDFjLzB4YjEK PiA+IAo+ID4gb3RoZXIgaW5mbyB0aGF0IG1pZ2h0IGhlbHAgdXMgZGVidWcgdGhpczoKPiA+IAo+ ID4gQ2hhaW4gZXhpc3RzIG9mOgo+ID4gICAgY3B1X2hvdHBsdWdfbG9jay5yd19zZW0gLS0+ICZt bS0+bW1hcF9zZW0gLS0+ICZkZXZfcHJpdi0+bW1fbG9jawo+ID4gCj4gPiAgIFBvc3NpYmxlIHVu c2FmZSBsb2NraW5nIHNjZW5hcmlvOgo+ID4gCj4gPiAgICAgICAgIENQVTAgICAgICAgICAgICAg ICAgICAgIENQVTEKPiA+ICAgICAgICAgLS0tLSAgICAgICAgICAgICAgICAgICAgLS0tLQo+ID4g ICAgbG9jaygmZGV2X3ByaXYtPm1tX2xvY2spOwo+ID4gICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICBsb2NrKCZtbS0+bW1hcF9zZW0pOwo+ID4gICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICBsb2NrKCZkZXZfcHJpdi0+bW1fbG9jayk7Cj4gPiAgICBsb2NrKGNwdV9ob3RwbHVn X2xvY2sucndfc2VtKTsKPiA+IAo+ID4gICAqKiogREVBRExPQ0sgKioqCj4gPiAKPiA+IDIgbG9j a3MgaGVsZCBieSBwcmltZV9tbWFwLzE1NTE6Cj4gPiAgICMwOiAgKCZtbS0+bW1hcF9zZW0peysr Kyt9LCBhdDogWzxmZmZmZmZmZmEwMWE3YjE4Pl0gaTkxNV9nZW1fdXNlcnB0cl9pbml0X19tbXVf bm90aWZpZXIrMHgxMzgvMHgyNzAgW2k5MTVdCj4gPiAgICMxOiAgKCZkZXZfcHJpdi0+bW1fbG9j ayl7Ky4rLn0sIGF0OiBbPGZmZmZmZmZmYTAxYTdiMmE+XSBpOTE1X2dlbV91c2VycHRyX2luaXRf X21tdV9ub3RpZmllcisweDE0YS8weDI3MCBbaTkxNV0KPiA+IAo+ID4gc3RhY2sgYmFja3RyYWNl Ogo+ID4gQ1BVOiA0IFBJRDogMTU1MSBDb21tOiBwcmltZV9tbWFwIFRhaW50ZWQ6IEcgICAgIFUg ICAgICAgICAgNC4xNC4wLXJjMS1DSS1DSV9EUk1fMzExOCsgIzEKPiA+IEhhcmR3YXJlIG5hbWU6 IERlbGwgSW5jLiBYUFMgODMwMCAgLzBZMk1SRywgQklPUyBBMDYgMTAvMTcvMjAxMQo+ID4gQ2Fs bCBUcmFjZToKPiA+ICAgZHVtcF9zdGFjaysweDY4LzB4OWYKPiA+ICAgcHJpbnRfY2lyY3VsYXJf YnVnKzB4MjM1LzB4M2MwCj4gPiAgID8gbG9ja2RlcF9pbml0X21hcF9jcm9zc2xvY2srMHgyMC8w eDIwCj4gPiAgIGNoZWNrX3ByZXZfYWRkKzB4NDMwLzB4ODQwCj4gPiAgIF9fbG9ja19hY3F1aXJl KzB4MTQyMC8weDE1ZTAKPiA+ICAgPyBfX2xvY2tfYWNxdWlyZSsweDE0MjAvMHgxNWUwCj4gPiAg ID8gbG9ja2RlcF9pbml0X21hcF9jcm9zc2xvY2srMHgyMC8weDIwCj4gPiAgIGxvY2tfYWNxdWly ZSsweGIwLzB4MjAwCj4gPiAgID8gYXBwbHlfd29ya3F1ZXVlX2F0dHJzKzB4MTcvMHg1MAo+ID4g ICBjcHVzX3JlYWRfbG9jaysweDNkLzB4YjAKPiA+ICAgPyBhcHBseV93b3JrcXVldWVfYXR0cnMr MHgxNy8weDUwCj4gPiAgIGFwcGx5X3dvcmtxdWV1ZV9hdHRycysweDE3LzB4NTAKPiA+ICAgX19h bGxvY193b3JrcXVldWVfa2V5KzB4MWQ4LzB4NGQ5Cj4gPiAgID8gX19sb2NrZGVwX2luaXRfbWFw KzB4NTcvMHgxYzAKPiA+ICAgaTkxNV9nZW1fdXNlcnB0cl9pbml0X19tbXVfbm90aWZpZXIrMHgx ZmIvMHgyNzAgW2k5MTVdCj4gPiAgIGk5MTVfZ2VtX3VzZXJwdHJfaW9jdGwrMHgyMjIvMHgyYzAg W2k5MTVdCj4gPiAgID8gaTkxNV9nZW1fdXNlcnB0cl9yZWxlYXNlKzB4MTQwLzB4MTQwIFtpOTE1 XQo+ID4gICBkcm1faW9jdGxfa2VybmVsKzB4NjkvMHhiMAo+ID4gICBkcm1faW9jdGwrMHgyZjkv MHgzZDAKPiA+ICAgPyBpOTE1X2dlbV91c2VycHRyX3JlbGVhc2UrMHgxNDAvMHgxNDAgW2k5MTVd Cj4gPiAgID8gX19kb19wYWdlX2ZhdWx0KzB4MmE0LzB4NTcwCj4gPiAgIGRvX3Zmc19pb2N0bCsw eDk0LzB4NjcwCj4gPiAgID8gZW50cnlfU1lTQ0FMTF82NF9mYXN0cGF0aCsweDUvMHhiMQo+ID4g ICA/IF9fdGhpc19jcHVfcHJlZW1wdF9jaGVjaysweDEzLzB4MjAKPiA+ICAgPyB0cmFjZV9oYXJk aXJxc19vbl9jYWxsZXIrMHhlMy8weDFiMAo+ID4gICBTeVNfaW9jdGwrMHg0MS8weDcwCj4gPiAg IGVudHJ5X1NZU0NBTExfNjRfZmFzdHBhdGgrMHgxYy8weGIxCj4gPiBSSVA6IDAwMzM6MHg3ZmJi ODNjMzk1ODcKPiA+IFJTUDogMDAyYjowMDAwN2ZmZjE4OGRjMjI4IEVGTEFHUzogMDAwMDAyNDYg T1JJR19SQVg6IDAwMDAwMDAwMDAwMDAwMTAKPiA+IFJBWDogZmZmZmZmZmZmZmZmZmZkYSBSQlg6 IGZmZmZmZmZmODE0OTI5NjMgUkNYOiAwMDAwN2ZiYjgzYzM5NTg3Cj4gPiBSRFg6IDAwMDA3ZmZm MTg4ZGMyNjAgUlNJOiAwMDAwMDAwMGMwMTg2NDczIFJESTogMDAwMDAwMDAwMDAwMDAwMwo+ID4g UkJQOiBmZmZmYzkwMDAxNDg3Zjg4IFIwODogMDAwMDAwMDAwMDAwMDAwMCBSMDk6IDAwMDA3ZmZm MTg4ZGMyYWMKPiA+IFIxMDogMDAwMDdmYmI4M2VmY2I1OCBSMTE6IDAwMDAwMDAwMDAwMDAyNDYg UjEyOiAwMDAwMDAwMDAwMDAwMDAwCj4gPiBSMTM6IDAwMDAwMDAwMDAwMDAwMDMgUjE0OiAwMDAw MDAwMGMwMTg2NDczIFIxNTogMDAwMDdmZmYxODhkYzJhYwo+ID4gICA/IF9fdGhpc19jcHVfcHJl ZW1wdF9jaGVjaysweDEzLzB4MjAKPiA+IAo+ID4gdjI6IFNldCByZXQgY29ycmVjdGx5IHdoZW4g d2UgcmFjZWQgd2l0aCBhbm90aGVyIHRocmVhZC4KPiA+IAo+ID4gdjM6IFVzZSBDaHJpcycgZGlm Zi4gQXR0YWNoIHRoZSByaWdodCBsb2NrZGVwIHNwbGF0Lgo+ID4gCj4gPiBDYzogQ2hyaXMgV2ls c29uIDxjaHJpc0BjaHJpcy13aWxzb24uY28udWs+Cj4gPiBDYzogVHZydGtvIFVyc3VsaW4gPHR2 cnRrby51cnN1bGluQGludGVsLmNvbT4KPiA+IENjOiBKb29uYXMgTGFodGluZW4gPGpvb25hcy5s YWh0aW5lbkBsaW51eC5pbnRlbC5jb20+Cj4gPiBDYzogUGV0ZXIgWmlqbHN0cmEgPHBldGVyekBp bmZyYWRlYWQub3JnPgo+ID4gQ2M6IFRob21hcyBHbGVpeG5lciA8dGdseEBsaW51dHJvbml4LmRl Pgo+ID4gQ2M6IFNhc2hhIExldmluIDxhbGV4YW5kZXIubGV2aW5AdmVyaXpvbi5jb20+Cj4gPiBD YzogTWFydGEgTG9mc3RlZHQgPG1hcnRhLmxvZnN0ZWR0QGludGVsLmNvbT4KPiA+IENjOiBUZWp1 biBIZW8gPHRqQGtlcm5lbC5vcmc+Cj4gPiBSZWZlcmVuY2VzOiBodHRwczovL2ludGVsLWdmeC1j aS4wMS5vcmcvdHJlZS9kcm0tdGlwL0NJX0RSTV8zMTgwL3NoYXJkLWhzdzMvaWd0QHByaW1lX21t YXBAdGVzdF91c2VycHRyLmh0bWwKPiA+IEJ1Z3ppbGxhOiBodHRwczovL2J1Z3MuZnJlZWRlc2t0 b3Aub3JnL3Nob3dfYnVnLmNnaT9pZD0xMDI5MzkKPiA+IFNpZ25lZC1vZmYtYnk6IERhbmllbCBW ZXR0ZXIgPGRhbmllbC52ZXR0ZXJAaW50ZWwuY29tPgo+ID4gLS0tCj4gPiAgIGRyaXZlcnMvZ3B1 L2RybS9pOTE1L2k5MTVfZ2VtX3VzZXJwdHIuYyB8IDM1ICsrKysrKysrKysrKysrKysrKystLS0t LS0tLS0tLS0tLQo+ID4gICAxIGZpbGUgY2hhbmdlZCwgMjAgaW5zZXJ0aW9ucygrKSwgMTUgZGVs ZXRpb25zKC0pCj4gPiAKPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vaTkxNS9pOTE1 X2dlbV91c2VycHRyLmMgYi9kcml2ZXJzL2dwdS9kcm0vaTkxNS9pOTE1X2dlbV91c2VycHRyLmMK PiA+IGluZGV4IDJkNDk5NmRlNzMzMS4uZjliMzQwNjQwMWFmIDEwMDY0NAo+ID4gLS0tIGEvZHJp dmVycy9ncHUvZHJtL2k5MTUvaTkxNV9nZW1fdXNlcnB0ci5jCj4gPiArKysgYi9kcml2ZXJzL2dw dS9kcm0vaTkxNS9pOTE1X2dlbV91c2VycHRyLmMKPiA+IEBAIC0xNjQsNyArMTY0LDYgQEAgc3Rh dGljIHN0cnVjdCBpOTE1X21tdV9ub3RpZmllciAqCj4gPiAgIGk5MTVfbW11X25vdGlmaWVyX2Ny ZWF0ZShzdHJ1Y3QgbW1fc3RydWN0ICptbSkKPiA+ICAgewo+ID4gICAJc3RydWN0IGk5MTVfbW11 X25vdGlmaWVyICptbjsKPiA+IC0JaW50IHJldDsKPiA+ICAgCW1uID0ga21hbGxvYyhzaXplb2Yo Km1uKSwgR0ZQX0tFUk5FTCk7Cj4gPiAgIAlpZiAobW4gPT0gTlVMTCkKPiA+IEBAIC0xNzksMTQg KzE3OCw2IEBAIGk5MTVfbW11X25vdGlmaWVyX2NyZWF0ZShzdHJ1Y3QgbW1fc3RydWN0ICptbSkK PiA+ICAgCQlyZXR1cm4gRVJSX1BUUigtRU5PTUVNKTsKPiA+ICAgCX0KPiA+IC0JIC8qIFByb3Rl Y3RlZCBieSBtbWFwX3NlbSAod3JpdGUtbG9jaykgKi8KPiA+IC0JcmV0ID0gX19tbXVfbm90aWZp ZXJfcmVnaXN0ZXIoJm1uLT5tbiwgbW0pOwo+ID4gLQlpZiAocmV0KSB7Cj4gPiAtCQlkZXN0cm95 X3dvcmtxdWV1ZShtbi0+d3EpOwo+ID4gLQkJa2ZyZWUobW4pOwo+ID4gLQkJcmV0dXJuIEVSUl9Q VFIocmV0KTsKPiA+IC0JfQo+ID4gLQo+ID4gICAJcmV0dXJuIG1uOwo+ID4gICB9Cj4gPiBAQCAt MjEwLDIzICsyMDEsMzcgQEAgaTkxNV9nZW1fdXNlcnB0cl9yZWxlYXNlX19tbXVfbm90aWZpZXIo c3RydWN0IGRybV9pOTE1X2dlbV9vYmplY3QgKm9iaikKPiA+ICAgc3RhdGljIHN0cnVjdCBpOTE1 X21tdV9ub3RpZmllciAqCj4gPiAgIGk5MTVfbW11X25vdGlmaWVyX2ZpbmQoc3RydWN0IGk5MTVf bW1fc3RydWN0ICptbSkKPiA+ICAgewo+ID4gLQlzdHJ1Y3QgaTkxNV9tbXVfbm90aWZpZXIgKm1u ID0gbW0tPm1uOwo+ID4gKwlzdHJ1Y3QgaTkxNV9tbXVfbm90aWZpZXIgKm1uOwo+ID4gKwlpbnQg ZXJyOwo+ID4gICAJbW4gPSBtbS0+bW47Cj4gPiAgIAlpZiAobW4pCj4gPiAgIAkJcmV0dXJuIG1u Owo+ID4gKwltbiA9IGk5MTVfbW11X25vdGlmaWVyX2NyZWF0ZShtbS0+bW0pOwo+ID4gKwlpZiAo SVNfRVJSKG1uKSkKPiA+ICsJCXJldHVybiBtbjsKPiAKPiBTdHJpY3RseSBzcGVha2luZyB3ZSBk b24ndCB3YW50IHRvIGZhaWwganVzdCB5ZXQsIG9ubHkgaXQgd2UgYWN0dWFsbHkgbmVlZGVkCj4g YSBuZXcgbm90aWZpZXIgYW5kIHdlIGZhaWxlZCB0byBjcmVhdGUgaXQuCgpUaGUgY2hlY2sgMiBs aW5lcyBhYm92ZSBub3QgZ29vZCBlbm91Z2g/IEl0J3Mgc29tZXdoYXQgcmFjeSwgYnV0IEknbSBu b3QKc3VyZSB3aGF0IHZhbHVlIHdlIHByb3ZpZGUgYnkgYmVpbmcgcGVyZmVjdGx5IGNvcnJlY3Qg YWdhaW5zdCBsb3cgbWVtb3J5LgpUaGlzIHRocmVhZCByYWNpbmcgYWdhaW5zdCBhIDJuZCBvbmUs IHdoZXJlIHRoZSBtaW5pbWFsIGFsbG9jYXRpb24gb2YgdGhlCjJuZCBvbmUgcHVzaGVkIHVzIHBl cmZlY3RseSBvdmVyIHRoZSBvb20gdGhyZXNob2xkIHNlZW1zIGEgdmVyeSB1bmxpa2VseQpzY2Vu YXJpby4KCkFsc28sIHNtYWxsIGFsbG9jYXRpb25zIGFjdHVhbGx5IG5ldmVyIGZhaWwgOi0pCgo+ IAo+ID4gKwo+ID4gKwllcnIgPSAwOwo+ID4gICAJZG93bl93cml0ZSgmbW0tPm1tLT5tbWFwX3Nl bSk7Cj4gPiAgIAltdXRleF9sb2NrKCZtbS0+aTkxNS0+bW1fbG9jayk7Cj4gPiAtCWlmICgobW4g PSBtbS0+bW4pID09IE5VTEwpIHsKPiA+IC0JCW1uID0gaTkxNV9tbXVfbm90aWZpZXJfY3JlYXRl KG1tLT5tbSk7Cj4gPiAtCQlpZiAoIUlTX0VSUihtbikpCj4gPiAtCQkJbW0tPm1uID0gbW47Cj4g PiArCWlmIChtbS0+bW4gPT0gTlVMTCkgewo+ID4gKwkJLyogUHJvdGVjdGVkIGJ5IG1tYXBfc2Vt ICh3cml0ZS1sb2NrKSAqLwo+ID4gKwkJZXJyID0gX19tbXVfbm90aWZpZXJfcmVnaXN0ZXIoJm1u LT5tbiwgbW0tPm1tKTsKPiA+ICsJCWlmICghZXJyKSB7Cj4gPiArCQkJLyogUHJvdGVjdGVkIGJ5 IG1tX2xvY2sgKi8KPiA+ICsJCQltbS0+bW4gPSBmZXRjaF9hbmRfemVybygmbW4pOwo+ID4gKwkJ fQo+ID4gICAJfQo+ID4gICAJbXV0ZXhfdW5sb2NrKCZtbS0+aTkxNS0+bW1fbG9jayk7Cj4gPiAg IAl1cF93cml0ZSgmbW0tPm1tLT5tbWFwX3NlbSk7Cj4gPiAtCXJldHVybiBtbjsKPiA+ICsJaWYg KG1uKSB7Cj4gPiArCQlkZXN0cm95X3dvcmtxdWV1ZShtbi0+d3EpOwo+ID4gKwkJa2ZyZWUobW4p Owo+ID4gKwl9Cj4gPiArCj4gPiArCXJldHVybiBlcnIgPyBFUlJfUFRSKGVycikgOiBtbS0+bW47 Cj4gPiAgIH0KPiA+ICAgc3RhdGljIGludAo+ID4gCj4gCj4gT3RoZXJ3aXNlIGxvb2tzIGdvb2Qg dG8gbWUuCj4gCj4gSSB3b3VsZCBhbHNvIHB1dCBhIG5vdGUgaW4gdGhlIGNvbW1pdCBvbiBob3cg d29ya2luZyBhcm91bmQgdGhlIGxvY2tpbmcKPiBpc3N1ZSBpcyBhbHNvIGJlbmVmaWNpYWwgdG8g cGVyZm9ybWFuY2Ugd2l0aCBtb3ZpbmcgdGhlIGFsbG9jYXRpb24gc3RlcAo+IG91dHNpZGUgdGhl IG1tYXBfc2VtLgoKWWVhaCBDaHJpcyBicm91Z2h0IHRoYXQgdXAgdG9vLCBJIGRvbid0IHJlYWxs eSBidXkgaXQgZ2l2ZW4gaG93CmhlYXZ5LXdlaWdodCBfX21tdV9ub3RpZmllcl9yZWdpc3RlciBp cy4gQnV0IEkgY2FuIGFkZCBzb21ldGhpbmcgbGlrZToKCiJUaGlzIGFsc28gaGFzIHRoZSBtaW5v ciBiZW5lZml0IG9mIHNsaWdodGx5IHJlZHVjaW5nIHRoZSBjcml0aWNhbApzZWN0aW9uIHdoZXJl IHdlIGhvbGQgbW1hcF9zZW0uIgoKci1iIHdpdGggdGhhdCBhZGRlZCB0byB0aGUgY29tbWl0IG1l c3NhZ2U/Ci1EYW5pZWwKLS0gCkRhbmllbCBWZXR0ZXIKU29mdHdhcmUgRW5naW5lZXIsIEludGVs IENvcnBvcmF0aW9uCmh0dHA6Ly9ibG9nLmZmd2xsLmNoCl9fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fCkludGVsLWdmeCBtYWlsaW5nIGxpc3QKSW50ZWwtZ2Z4 QGxpc3RzLmZyZWVkZXNrdG9wLm9yZwpodHRwczovL2xpc3RzLmZyZWVkZXNrdG9wLm9yZy9tYWls bWFuL2xpc3RpbmZvL2ludGVsLWdmeAo=