From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.2 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_SANE_1 autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3A9EFC433E0 for ; Wed, 10 Jun 2020 04:25:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0B5AF206F4 for ; Wed, 10 Jun 2020 04:25:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725988AbgFJEZm (ORCPT ); Wed, 10 Jun 2020 00:25:42 -0400 Received: from mga03.intel.com ([134.134.136.65]:41165 "EHLO mga03.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725908AbgFJEZl (ORCPT ); Wed, 10 Jun 2020 00:25:41 -0400 IronPort-SDR: KPbRKZckX/ZD9SdYpSXrbg26q/Uxz4fmtQVvkg2zYhh7bUAFv+UHBS73/2ktczMIQ+CjwPMdpg Nl+mGYbGkiQg== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Jun 2020 21:25:40 -0700 IronPort-SDR: UUyBuO4FlUnlM+NT3WcPbtStCXuA3fZXSoSp6YR2oiKGU9foTV7Ky7V1Shcaa8DQxdReJy+C4a 52qHRQhtx3kQ== X-IronPort-AV: E=Sophos;i="5.73,494,1583222400"; d="scan'208";a="473291983" Received: from ychan10-mobl2.amr.corp.intel.com (HELO [10.212.8.218]) ([10.212.8.218]) by fmsmga005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Jun 2020 21:25:39 -0700 Subject: Re: [Intel-gfx] [PATCH] drm/i915/gt: Incrementally check for rewinding To: Chris Wilson , intel-gfx@lists.freedesktop.org Cc: stable@vger.kernel.org References: <20200609122856.10207-1-chris@chris-wilson.co.uk> <20200609151723.12971-1-chris@chris-wilson.co.uk> From: "Chang, Bruce" Message-ID: Date: Tue, 9 Jun 2020 21:25:39 -0700 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:68.0) Gecko/20100101 Thunderbird/68.9.0 MIME-Version: 1.0 In-Reply-To: <20200609151723.12971-1-chris@chris-wilson.co.uk> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Content-Language: en-US Sender: stable-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org On 6/9/2020 8:17 AM, Chris Wilson wrote: > In commit 5ba32c7be81e ("drm/i915/execlists: Always force a context > reload when rewinding RING_TAIL"), we placed the check for rewinding a > context on actually submitting the next request in that context. This > was so that we only had to check once, and could do so with precision > avoiding as many forced restores as possible. For example, to ensure > that we can resubmit the same request a couple of times, we include a > small wa_tail such that on the next submission, the ring->tail will > appear to move forwards when resubmitting the same request. This is very > common as it will happen for every lite-restore to fill the second port > after a context switch. > > However, intel_ring_direction() is limited in precision to movements of > upto half the ring size. The consequence being that if we tried to > unwind many requests, we could exceed half the ring and flip the sense > of the direction, so missing a force restore. As no request can be > greater than half the ring (i.e. 2048 bytes in the smallest case), we > can check for rollback incrementally. As we check against the tail that > would be submitted, we do not lose any sensitivity and allow lite > restores for the simple case. We still need to double check upon > submitting the context, to allow for multiple preemptions and > resubmissions. > > Fixes: 5ba32c7be81e ("drm/i915/execlists: Always force a context reload when rewinding RING_TAIL") > Signed-off-by: Chris Wilson > Cc: Mika Kuoppala > Cc: # v5.4+ Verified this has fixed the issue regarding the GPU hang with incomplete error state. reviewed by: Bruce Chang > --- > drivers/gpu/drm/i915/gt/intel_engine_cs.c | 4 +- > drivers/gpu/drm/i915/gt/intel_lrc.c | 21 +++- > drivers/gpu/drm/i915/gt/intel_ring.c | 4 + > drivers/gpu/drm/i915/gt/selftest_mocs.c | 18 ++- > drivers/gpu/drm/i915/gt/selftest_ring.c | 110 ++++++++++++++++++ > .../drm/i915/selftests/i915_mock_selftests.h | 1 + > 6 files changed, 154 insertions(+), 4 deletions(-) > create mode 100644 drivers/gpu/drm/i915/gt/selftest_ring.c > > diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c > index e5141a897786..0a05301e00fb 100644 > --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c > +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c > @@ -646,7 +646,7 @@ static int engine_setup_common(struct intel_engine_cs *engine) > struct measure_breadcrumb { > struct i915_request rq; > struct intel_ring ring; > - u32 cs[1024]; > + u32 cs[2048]; > }; > > static int measure_breadcrumb_dw(struct intel_context *ce) > @@ -667,6 +667,8 @@ static int measure_breadcrumb_dw(struct intel_context *ce) > > frame->ring.vaddr = frame->cs; > frame->ring.size = sizeof(frame->cs); > + frame->ring.wrap = > + BITS_PER_TYPE(frame->ring.size) - ilog2(frame->ring.size); Not sure if this  frame->ring.wrap being used anywhere > frame->ring.effective_size = frame->ring.size; > intel_ring_update_space(&frame->ring); > frame->rq.ring = &frame->ring; > diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c > index a057f7a2a521..5f33342c15e2 100644 > --- a/drivers/gpu/drm/i915/gt/intel_lrc.c > +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c > @@ -1137,6 +1137,13 @@ __unwind_incomplete_requests(struct intel_engine_cs *engine) > list_move(&rq->sched.link, pl); > set_bit(I915_FENCE_FLAG_PQUEUE, &rq->fence.flags); > > + /* Check in case rollback so far, we wrap [size/2] */ > + if (intel_ring_direction(rq->ring, > + intel_ring_wrap(rq->ring, > + rq->tail), > + rq->ring->tail) > 0) > + rq->context->lrc.desc |= CTX_DESC_FORCE_RESTORE; > + minor: maybe just me, "so far" -> "too far"? > active = rq; > } else { > struct intel_engine_cs *owner = rq->context->engine; > @@ -1505,8 +1512,9 @@ static u64 execlists_update_context(struct i915_request *rq) > * HW has a tendency to ignore us rewinding the TAIL to the end of > * an earlier request. > */ > + GEM_BUG_ON(ce->lrc_reg_state[CTX_RING_TAIL] != rq->ring->tail); > + prev = rq->ring->tail; > tail = intel_ring_set_tail(rq->ring, rq->tail); > - prev = ce->lrc_reg_state[CTX_RING_TAIL]; > if (unlikely(intel_ring_direction(rq->ring, tail, prev) <= 0)) > desc |= CTX_DESC_FORCE_RESTORE; > ce->lrc_reg_state[CTX_RING_TAIL] = tail; > @@ -4758,6 +4766,14 @@ static int gen12_emit_flush(struct i915_request *request, u32 mode) > return 0; > } > > +static void assert_request_valid(struct i915_request *rq) > +{ > + struct intel_ring *ring __maybe_unused = rq->ring; > + > + /* Can we unwind this request without appearing to go forwards? */ > + GEM_BUG_ON(intel_ring_direction(ring, rq->wa_tail, rq->head) <= 0); > +} > + > /* > * Reserve space for 2 NOOPs at the end of each request to be > * used as a workaround for not being allowed to do lite > @@ -4770,6 +4786,9 @@ static u32 *gen8_emit_wa_tail(struct i915_request *request, u32 *cs) > *cs++ = MI_NOOP; > request->wa_tail = intel_ring_offset(request, cs); > > + /* Check that entire request is less than half the ring */ > + assert_request_valid(request); > + > return cs; > } > > diff --git a/drivers/gpu/drm/i915/gt/intel_ring.c b/drivers/gpu/drm/i915/gt/intel_ring.c > index 8cda1b7e17ba..bdb324167ef3 100644 > --- a/drivers/gpu/drm/i915/gt/intel_ring.c > +++ b/drivers/gpu/drm/i915/gt/intel_ring.c > @@ -315,3 +315,7 @@ int intel_ring_cacheline_align(struct i915_request *rq) > GEM_BUG_ON(rq->ring->emit & (CACHELINE_BYTES - 1)); > return 0; > } > + > +#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) > +#include "selftest_ring.c" > +#endif > diff --git a/drivers/gpu/drm/i915/gt/selftest_mocs.c b/drivers/gpu/drm/i915/gt/selftest_mocs.c > index 7bae64018ad9..b25eba50c88e 100644 > --- a/drivers/gpu/drm/i915/gt/selftest_mocs.c > +++ b/drivers/gpu/drm/i915/gt/selftest_mocs.c > @@ -18,6 +18,20 @@ struct live_mocs { > void *vaddr; > }; > > +static struct intel_context *mocs_context_create(struct intel_engine_cs *engine) > +{ > + struct intel_context *ce; > + > + ce = intel_context_create(engine); > + if (IS_ERR(ce)) > + return ce; > + > + /* We build large requests to read the registers from the ring */ > + ce->ring = __intel_context_ring_size(SZ_16K); > + > + return ce; > +} > + > static int request_add_sync(struct i915_request *rq, int err) > { > i915_request_get(rq); > @@ -301,7 +315,7 @@ static int live_mocs_clean(void *arg) > for_each_engine(engine, gt, id) { > struct intel_context *ce; > > - ce = intel_context_create(engine); > + ce = mocs_context_create(engine); > if (IS_ERR(ce)) { > err = PTR_ERR(ce); > break; > @@ -395,7 +409,7 @@ static int live_mocs_reset(void *arg) > for_each_engine(engine, gt, id) { > struct intel_context *ce; > > - ce = intel_context_create(engine); > + ce = mocs_context_create(engine); > if (IS_ERR(ce)) { > err = PTR_ERR(ce); > break; > diff --git a/drivers/gpu/drm/i915/gt/selftest_ring.c b/drivers/gpu/drm/i915/gt/selftest_ring.c > new file mode 100644 > index 000000000000..2a8c534dc125 > --- /dev/null > +++ b/drivers/gpu/drm/i915/gt/selftest_ring.c > @@ -0,0 +1,110 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright © 2020 Intel Corporation > + */ > + > +static struct intel_ring *mock_ring(unsigned long sz) > +{ > + struct intel_ring *ring; > + > + ring = kzalloc(sizeof(*ring) + sz, GFP_KERNEL); > + if (!ring) > + return NULL; > + > + kref_init(&ring->ref); > + ring->size = sz; > + ring->wrap = BITS_PER_TYPE(ring->size) - ilog2(sz); > + ring->effective_size = sz; > + ring->vaddr = (void *)(ring + 1); > + atomic_set(&ring->pin_count, 1); > + > + intel_ring_update_space(ring); > + > + return ring; > +} > + > +static void mock_ring_free(struct intel_ring *ring) > +{ > + kfree(ring); > +} > + > +static int check_ring_direction(struct intel_ring *ring, > + u32 next, u32 prev, > + int expected) > +{ > + int result; > + > + result = intel_ring_direction(ring, next, prev); > + if (result < 0) > + result = -1; > + else if (result > 0) > + result = 1; > + > + if (result != expected) { > + pr_err("intel_ring_direction(%u, %u):%d != %d\n", > + next, prev, result, expected); > + return -EINVAL; > + } > + > + return 0; > +} > + > +static int check_ring_step(struct intel_ring *ring, u32 x, u32 step) > +{ > + u32 prev = x, next = intel_ring_wrap(ring, x + step); > + int err = 0; > + > + err |= check_ring_direction(ring, next, next, 0); > + err |= check_ring_direction(ring, prev, prev, 0); > + err |= check_ring_direction(ring, next, prev, 1); > + err |= check_ring_direction(ring, prev, next, -1); > + > + return err; > +} > + > +static int check_ring_offset(struct intel_ring *ring, u32 x, u32 step) > +{ > + int err = 0; > + > + err |= check_ring_step(ring, x, step); > + err |= check_ring_step(ring, intel_ring_wrap(ring, x + 1), step); > + err |= check_ring_step(ring, intel_ring_wrap(ring, x - 1), step); > + > + return err; > +} > + > +static int igt_ring_direction(void *dummy) > +{ > + struct intel_ring *ring; > + unsigned int half = 2048; > + int step, err = 0; > + > + ring = mock_ring(2 * half); > + if (!ring) > + return -ENOMEM; > + > + GEM_BUG_ON(ring->size != 2 * half); > + > + /* Precision of wrap detection is limited to ring->size / 2 */ > + for (step = 1; step < half; step <<= 1) { > + err |= check_ring_offset(ring, 0, step); > + err |= check_ring_offset(ring, half, step); > + } > + err |= check_ring_step(ring, 0, half - 64); > + > + /* And check unwrapped handling for good measure */ > + err |= check_ring_offset(ring, 0, 2 * half + 64); > + err |= check_ring_offset(ring, 3 * half, 1); > + > + mock_ring_free(ring); > + return err; > +} > + > +int intel_ring_mock_selftests(void) > +{ > + static const struct i915_subtest tests[] = { > + SUBTEST(igt_ring_direction), > + }; > + > + return i915_subtests(tests, NULL); > +} > diff --git a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h > index 1929feba4e8e..3db34d3eea58 100644 > --- a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h > +++ b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h > @@ -21,6 +21,7 @@ selftest(fence, i915_sw_fence_mock_selftests) > selftest(scatterlist, scatterlist_mock_selftests) > selftest(syncmap, i915_syncmap_mock_selftests) > selftest(uncore, intel_uncore_mock_selftests) > +selftest(ring, intel_ring_mock_selftests) > selftest(engine, intel_engine_cs_mock_selftests) > selftest(timelines, intel_timeline_mock_selftests) > selftest(requests, i915_request_mock_selftests) From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.2 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_SANE_1 autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 033DBC433DF for ; Wed, 10 Jun 2020 04:25:44 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id CCDA8206F4 for ; Wed, 10 Jun 2020 04:25:43 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org CCDA8206F4 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=intel-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8BB2C6E362; Wed, 10 Jun 2020 04:25:42 +0000 (UTC) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by gabe.freedesktop.org (Postfix) with ESMTPS id EC6656E362 for ; Wed, 10 Jun 2020 04:25:40 +0000 (UTC) IronPort-SDR: RboHiCAEt2WkqRp+WQE6vb9PbTCmYsp2Mrq9aNIB9eFEgdHfYr0dAB8V4lAy4UiQIy04ZMrI6W BXe7695D6n8g== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Jun 2020 21:25:40 -0700 IronPort-SDR: UUyBuO4FlUnlM+NT3WcPbtStCXuA3fZXSoSp6YR2oiKGU9foTV7Ky7V1Shcaa8DQxdReJy+C4a 52qHRQhtx3kQ== X-IronPort-AV: E=Sophos;i="5.73,494,1583222400"; d="scan'208";a="473291983" Received: from ychan10-mobl2.amr.corp.intel.com (HELO [10.212.8.218]) ([10.212.8.218]) by fmsmga005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Jun 2020 21:25:39 -0700 To: Chris Wilson , intel-gfx@lists.freedesktop.org References: <20200609122856.10207-1-chris@chris-wilson.co.uk> <20200609151723.12971-1-chris@chris-wilson.co.uk> From: "Chang, Bruce" Message-ID: Date: Tue, 9 Jun 2020 21:25:39 -0700 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:68.0) Gecko/20100101 Thunderbird/68.9.0 MIME-Version: 1.0 In-Reply-To: <20200609151723.12971-1-chris@chris-wilson.co.uk> Content-Language: en-US Subject: Re: [Intel-gfx] [PATCH] drm/i915/gt: Incrementally check for rewinding X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: stable@vger.kernel.org Content-Transfer-Encoding: base64 Content-Type: text/plain; charset="utf-8"; Format="flowed" Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" T24gNi85LzIwMjAgODoxNyBBTSwgQ2hyaXMgV2lsc29uIHdyb3RlOgo+IEluIGNvbW1pdCA1YmEz MmM3YmU4MWUgKCJkcm0vaTkxNS9leGVjbGlzdHM6IEFsd2F5cyBmb3JjZSBhIGNvbnRleHQKPiBy ZWxvYWQgd2hlbiByZXdpbmRpbmcgUklOR19UQUlMIiksIHdlIHBsYWNlZCB0aGUgY2hlY2sgZm9y IHJld2luZGluZyBhCj4gY29udGV4dCBvbiBhY3R1YWxseSBzdWJtaXR0aW5nIHRoZSBuZXh0IHJl cXVlc3QgaW4gdGhhdCBjb250ZXh0LiBUaGlzCj4gd2FzIHNvIHRoYXQgd2Ugb25seSBoYWQgdG8g Y2hlY2sgb25jZSwgYW5kIGNvdWxkIGRvIHNvIHdpdGggcHJlY2lzaW9uCj4gYXZvaWRpbmcgYXMg bWFueSBmb3JjZWQgcmVzdG9yZXMgYXMgcG9zc2libGUuIEZvciBleGFtcGxlLCB0byBlbnN1cmUK PiB0aGF0IHdlIGNhbiByZXN1Ym1pdCB0aGUgc2FtZSByZXF1ZXN0IGEgY291cGxlIG9mIHRpbWVz LCB3ZSBpbmNsdWRlIGEKPiBzbWFsbCB3YV90YWlsIHN1Y2ggdGhhdCBvbiB0aGUgbmV4dCBzdWJt aXNzaW9uLCB0aGUgcmluZy0+dGFpbCB3aWxsCj4gYXBwZWFyIHRvIG1vdmUgZm9yd2FyZHMgd2hl biByZXN1Ym1pdHRpbmcgdGhlIHNhbWUgcmVxdWVzdC4gVGhpcyBpcyB2ZXJ5Cj4gY29tbW9uIGFz IGl0IHdpbGwgaGFwcGVuIGZvciBldmVyeSBsaXRlLXJlc3RvcmUgdG8gZmlsbCB0aGUgc2Vjb25k IHBvcnQKPiBhZnRlciBhIGNvbnRleHQgc3dpdGNoLgo+Cj4gSG93ZXZlciwgaW50ZWxfcmluZ19k aXJlY3Rpb24oKSBpcyBsaW1pdGVkIGluIHByZWNpc2lvbiB0byBtb3ZlbWVudHMgb2YKPiB1cHRv IGhhbGYgdGhlIHJpbmcgc2l6ZS4gVGhlIGNvbnNlcXVlbmNlIGJlaW5nIHRoYXQgaWYgd2UgdHJp ZWQgdG8KPiB1bndpbmQgbWFueSByZXF1ZXN0cywgd2UgY291bGQgZXhjZWVkIGhhbGYgdGhlIHJp bmcgYW5kIGZsaXAgdGhlIHNlbnNlCj4gb2YgdGhlIGRpcmVjdGlvbiwgc28gbWlzc2luZyBhIGZv cmNlIHJlc3RvcmUuIEFzIG5vIHJlcXVlc3QgY2FuIGJlCj4gZ3JlYXRlciB0aGFuIGhhbGYgdGhl IHJpbmcgKGkuZS4gMjA0OCBieXRlcyBpbiB0aGUgc21hbGxlc3QgY2FzZSksIHdlCj4gY2FuIGNo ZWNrIGZvciByb2xsYmFjayBpbmNyZW1lbnRhbGx5LiBBcyB3ZSBjaGVjayBhZ2FpbnN0IHRoZSB0 YWlsIHRoYXQKPiB3b3VsZCBiZSBzdWJtaXR0ZWQsIHdlIGRvIG5vdCBsb3NlIGFueSBzZW5zaXRp dml0eSBhbmQgYWxsb3cgbGl0ZQo+IHJlc3RvcmVzIGZvciB0aGUgc2ltcGxlIGNhc2UuIFdlIHN0 aWxsIG5lZWQgdG8gZG91YmxlIGNoZWNrIHVwb24KPiBzdWJtaXR0aW5nIHRoZSBjb250ZXh0LCB0 byBhbGxvdyBmb3IgbXVsdGlwbGUgcHJlZW1wdGlvbnMgYW5kCj4gcmVzdWJtaXNzaW9ucy4KPgo+ IEZpeGVzOiA1YmEzMmM3YmU4MWUgKCJkcm0vaTkxNS9leGVjbGlzdHM6IEFsd2F5cyBmb3JjZSBh IGNvbnRleHQgcmVsb2FkIHdoZW4gcmV3aW5kaW5nIFJJTkdfVEFJTCIpCj4gU2lnbmVkLW9mZi1i eTogQ2hyaXMgV2lsc29uIDxjaHJpc0BjaHJpcy13aWxzb24uY28udWs+Cj4gQ2M6IE1pa2EgS3Vv cHBhbGEgPG1pa2Eua3VvcHBhbGFAbGludXguaW50ZWwuY29tPgo+IENjOiA8c3RhYmxlQHZnZXIu a2VybmVsLm9yZz4gIyB2NS40KwoKVmVyaWZpZWQgdGhpcyBoYXMgZml4ZWQgdGhlIGlzc3VlIHJl Z2FyZGluZyB0aGUgR1BVIGhhbmcgd2l0aCBpbmNvbXBsZXRlIAplcnJvciBzdGF0ZS4KCnJldmll d2VkIGJ5OiBCcnVjZSBDaGFuZyA8eXUuYnJ1Y2UuY2hhbmdAaW50ZWwuY29tPgoKPiAtLS0KPiAg IGRyaXZlcnMvZ3B1L2RybS9pOTE1L2d0L2ludGVsX2VuZ2luZV9jcy5jICAgICB8ICAgNCArLQo+ ICAgZHJpdmVycy9ncHUvZHJtL2k5MTUvZ3QvaW50ZWxfbHJjLmMgICAgICAgICAgIHwgIDIxICsr Ky0KPiAgIGRyaXZlcnMvZ3B1L2RybS9pOTE1L2d0L2ludGVsX3JpbmcuYyAgICAgICAgICB8ICAg NCArCj4gICBkcml2ZXJzL2dwdS9kcm0vaTkxNS9ndC9zZWxmdGVzdF9tb2NzLmMgICAgICAgfCAg MTggKystCj4gICBkcml2ZXJzL2dwdS9kcm0vaTkxNS9ndC9zZWxmdGVzdF9yaW5nLmMgICAgICAg fCAxMTAgKysrKysrKysrKysrKysrKysrCj4gICAuLi4vZHJtL2k5MTUvc2VsZnRlc3RzL2k5MTVf bW9ja19zZWxmdGVzdHMuaCAgfCAgIDEgKwo+ICAgNiBmaWxlcyBjaGFuZ2VkLCAxNTQgaW5zZXJ0 aW9ucygrKSwgNCBkZWxldGlvbnMoLSkKPiAgIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL2dw dS9kcm0vaTkxNS9ndC9zZWxmdGVzdF9yaW5nLmMKPgo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2dw dS9kcm0vaTkxNS9ndC9pbnRlbF9lbmdpbmVfY3MuYyBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2d0 L2ludGVsX2VuZ2luZV9jcy5jCj4gaW5kZXggZTUxNDFhODk3Nzg2Li4wYTA1MzAxZTAwZmIgMTAw NjQ0Cj4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL2k5MTUvZ3QvaW50ZWxfZW5naW5lX2NzLmMKPiAr KysgYi9kcml2ZXJzL2dwdS9kcm0vaTkxNS9ndC9pbnRlbF9lbmdpbmVfY3MuYwo+IEBAIC02NDYs NyArNjQ2LDcgQEAgc3RhdGljIGludCBlbmdpbmVfc2V0dXBfY29tbW9uKHN0cnVjdCBpbnRlbF9l bmdpbmVfY3MgKmVuZ2luZSkKPiAgIHN0cnVjdCBtZWFzdXJlX2JyZWFkY3J1bWIgewo+ICAgCXN0 cnVjdCBpOTE1X3JlcXVlc3QgcnE7Cj4gICAJc3RydWN0IGludGVsX3JpbmcgcmluZzsKPiAtCXUz MiBjc1sxMDI0XTsKPiArCXUzMiBjc1syMDQ4XTsKPiAgIH07Cj4gICAKPiAgIHN0YXRpYyBpbnQg bWVhc3VyZV9icmVhZGNydW1iX2R3KHN0cnVjdCBpbnRlbF9jb250ZXh0ICpjZSkKPiBAQCAtNjY3 LDYgKzY2Nyw4IEBAIHN0YXRpYyBpbnQgbWVhc3VyZV9icmVhZGNydW1iX2R3KHN0cnVjdCBpbnRl bF9jb250ZXh0ICpjZSkKPiAgIAo+ICAgCWZyYW1lLT5yaW5nLnZhZGRyID0gZnJhbWUtPmNzOwo+ ICAgCWZyYW1lLT5yaW5nLnNpemUgPSBzaXplb2YoZnJhbWUtPmNzKTsKPiArCWZyYW1lLT5yaW5n LndyYXAgPQo+ICsJCUJJVFNfUEVSX1RZUEUoZnJhbWUtPnJpbmcuc2l6ZSkgLSBpbG9nMihmcmFt ZS0+cmluZy5zaXplKTsKCgpOb3Qgc3VyZSBpZiB0aGlzwqAgZnJhbWUtPnJpbmcud3JhcCBiZWlu ZyB1c2VkIGFueXdoZXJlCgoKPiAgIAlmcmFtZS0+cmluZy5lZmZlY3RpdmVfc2l6ZSA9IGZyYW1l LT5yaW5nLnNpemU7Cj4gICAJaW50ZWxfcmluZ191cGRhdGVfc3BhY2UoJmZyYW1lLT5yaW5nKTsK PiAgIAlmcmFtZS0+cnEucmluZyA9ICZmcmFtZS0+cmluZzsKPiBkaWZmIC0tZ2l0IGEvZHJpdmVy cy9ncHUvZHJtL2k5MTUvZ3QvaW50ZWxfbHJjLmMgYi9kcml2ZXJzL2dwdS9kcm0vaTkxNS9ndC9p bnRlbF9scmMuYwo+IGluZGV4IGEwNTdmN2EyYTUyMS4uNWYzMzM0MmMxNWUyIDEwMDY0NAo+IC0t LSBhL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2d0L2ludGVsX2xyYy5jCj4gKysrIGIvZHJpdmVycy9n cHUvZHJtL2k5MTUvZ3QvaW50ZWxfbHJjLmMKPiBAQCAtMTEzNyw2ICsxMTM3LDEzIEBAIF9fdW53 aW5kX2luY29tcGxldGVfcmVxdWVzdHMoc3RydWN0IGludGVsX2VuZ2luZV9jcyAqZW5naW5lKQo+ ICAgCQkJbGlzdF9tb3ZlKCZycS0+c2NoZWQubGluaywgcGwpOwo+ICAgCQkJc2V0X2JpdChJOTE1 X0ZFTkNFX0ZMQUdfUFFVRVVFLCAmcnEtPmZlbmNlLmZsYWdzKTsKPiAgIAo+ICsJCQkvKiBDaGVj ayBpbiBjYXNlIHJvbGxiYWNrIHNvIGZhciwgd2Ugd3JhcCBbc2l6ZS8yXSAqLwo+ICsJCQlpZiAo aW50ZWxfcmluZ19kaXJlY3Rpb24ocnEtPnJpbmcsCj4gKwkJCQkJCSBpbnRlbF9yaW5nX3dyYXAo cnEtPnJpbmcsCj4gKwkJCQkJCQkJIHJxLT50YWlsKSwKPiArCQkJCQkJIHJxLT5yaW5nLT50YWls KSA+IDApCj4gKwkJCQlycS0+Y29udGV4dC0+bHJjLmRlc2MgfD0gQ1RYX0RFU0NfRk9SQ0VfUkVT VE9SRTsKPiArCgoKbWlub3I6IG1heWJlIGp1c3QgbWUsICJzbyBmYXIiIC0+ICJ0b28gZmFyIj8K Cgo+ICAgCQkJYWN0aXZlID0gcnE7Cj4gICAJCX0gZWxzZSB7Cj4gICAJCQlzdHJ1Y3QgaW50ZWxf ZW5naW5lX2NzICpvd25lciA9IHJxLT5jb250ZXh0LT5lbmdpbmU7Cj4gQEAgLTE1MDUsOCArMTUx Miw5IEBAIHN0YXRpYyB1NjQgZXhlY2xpc3RzX3VwZGF0ZV9jb250ZXh0KHN0cnVjdCBpOTE1X3Jl cXVlc3QgKnJxKQo+ICAgCSAqIEhXIGhhcyBhIHRlbmRlbmN5IHRvIGlnbm9yZSB1cyByZXdpbmRp bmcgdGhlIFRBSUwgdG8gdGhlIGVuZCBvZgo+ICAgCSAqIGFuIGVhcmxpZXIgcmVxdWVzdC4KPiAg IAkgKi8KPiArCUdFTV9CVUdfT04oY2UtPmxyY19yZWdfc3RhdGVbQ1RYX1JJTkdfVEFJTF0gIT0g cnEtPnJpbmctPnRhaWwpOwo+ICsJcHJldiA9IHJxLT5yaW5nLT50YWlsOwo+ICAgCXRhaWwgPSBp bnRlbF9yaW5nX3NldF90YWlsKHJxLT5yaW5nLCBycS0+dGFpbCk7Cj4gLQlwcmV2ID0gY2UtPmxy Y19yZWdfc3RhdGVbQ1RYX1JJTkdfVEFJTF07Cj4gICAJaWYgKHVubGlrZWx5KGludGVsX3Jpbmdf ZGlyZWN0aW9uKHJxLT5yaW5nLCB0YWlsLCBwcmV2KSA8PSAwKSkKPiAgIAkJZGVzYyB8PSBDVFhf REVTQ19GT1JDRV9SRVNUT1JFOwo+ICAgCWNlLT5scmNfcmVnX3N0YXRlW0NUWF9SSU5HX1RBSUxd ID0gdGFpbDsKPiBAQCAtNDc1OCw2ICs0NzY2LDE0IEBAIHN0YXRpYyBpbnQgZ2VuMTJfZW1pdF9m bHVzaChzdHJ1Y3QgaTkxNV9yZXF1ZXN0ICpyZXF1ZXN0LCB1MzIgbW9kZSkKPiAgIAlyZXR1cm4g MDsKPiAgIH0KPiAgIAo+ICtzdGF0aWMgdm9pZCBhc3NlcnRfcmVxdWVzdF92YWxpZChzdHJ1Y3Qg aTkxNV9yZXF1ZXN0ICpycSkKPiArewo+ICsJc3RydWN0IGludGVsX3JpbmcgKnJpbmcgX19tYXli ZV91bnVzZWQgPSBycS0+cmluZzsKPiArCj4gKwkvKiBDYW4gd2UgdW53aW5kIHRoaXMgcmVxdWVz dCB3aXRob3V0IGFwcGVhcmluZyB0byBnbyBmb3J3YXJkcz8gKi8KPiArCUdFTV9CVUdfT04oaW50 ZWxfcmluZ19kaXJlY3Rpb24ocmluZywgcnEtPndhX3RhaWwsIHJxLT5oZWFkKSA8PSAwKTsKPiAr fQo+ICsKPiAgIC8qCj4gICAgKiBSZXNlcnZlIHNwYWNlIGZvciAyIE5PT1BzIGF0IHRoZSBlbmQg b2YgZWFjaCByZXF1ZXN0IHRvIGJlCj4gICAgKiB1c2VkIGFzIGEgd29ya2Fyb3VuZCBmb3Igbm90 IGJlaW5nIGFsbG93ZWQgdG8gZG8gbGl0ZQo+IEBAIC00NzcwLDYgKzQ3ODYsOSBAQCBzdGF0aWMg dTMyICpnZW44X2VtaXRfd2FfdGFpbChzdHJ1Y3QgaTkxNV9yZXF1ZXN0ICpyZXF1ZXN0LCB1MzIg KmNzKQo+ICAgCSpjcysrID0gTUlfTk9PUDsKPiAgIAlyZXF1ZXN0LT53YV90YWlsID0gaW50ZWxf cmluZ19vZmZzZXQocmVxdWVzdCwgY3MpOwo+ICAgCj4gKwkvKiBDaGVjayB0aGF0IGVudGlyZSBy ZXF1ZXN0IGlzIGxlc3MgdGhhbiBoYWxmIHRoZSByaW5nICovCj4gKwlhc3NlcnRfcmVxdWVzdF92 YWxpZChyZXF1ZXN0KTsKPiArCj4gICAJcmV0dXJuIGNzOwo+ICAgfQo+ICAgCj4gZGlmZiAtLWdp dCBhL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2d0L2ludGVsX3JpbmcuYyBiL2RyaXZlcnMvZ3B1L2Ry bS9pOTE1L2d0L2ludGVsX3JpbmcuYwo+IGluZGV4IDhjZGExYjdlMTdiYS4uYmRiMzI0MTY3ZWYz IDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2d0L2ludGVsX3JpbmcuYwo+ICsr KyBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2d0L2ludGVsX3JpbmcuYwo+IEBAIC0zMTUsMyArMzE1 LDcgQEAgaW50IGludGVsX3JpbmdfY2FjaGVsaW5lX2FsaWduKHN0cnVjdCBpOTE1X3JlcXVlc3Qg KnJxKQo+ICAgCUdFTV9CVUdfT04ocnEtPnJpbmctPmVtaXQgJiAoQ0FDSEVMSU5FX0JZVEVTIC0g MSkpOwo+ICAgCXJldHVybiAwOwo+ICAgfQo+ICsKPiArI2lmIElTX0VOQUJMRUQoQ09ORklHX0RS TV9JOTE1X1NFTEZURVNUKQo+ICsjaW5jbHVkZSAic2VsZnRlc3RfcmluZy5jIgo+ICsjZW5kaWYK PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL2k5MTUvZ3Qvc2VsZnRlc3RfbW9jcy5jIGIv ZHJpdmVycy9ncHUvZHJtL2k5MTUvZ3Qvc2VsZnRlc3RfbW9jcy5jCj4gaW5kZXggN2JhZTY0MDE4 YWQ5Li5iMjVlYmE1MGM4OGUgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL2k5MTUvZ3Qv c2VsZnRlc3RfbW9jcy5jCj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL2k5MTUvZ3Qvc2VsZnRlc3Rf bW9jcy5jCj4gQEAgLTE4LDYgKzE4LDIwIEBAIHN0cnVjdCBsaXZlX21vY3Mgewo+ICAgCXZvaWQg KnZhZGRyOwo+ICAgfTsKPiAgIAo+ICtzdGF0aWMgc3RydWN0IGludGVsX2NvbnRleHQgKm1vY3Nf Y29udGV4dF9jcmVhdGUoc3RydWN0IGludGVsX2VuZ2luZV9jcyAqZW5naW5lKQo+ICt7Cj4gKwlz dHJ1Y3QgaW50ZWxfY29udGV4dCAqY2U7Cj4gKwo+ICsJY2UgPSBpbnRlbF9jb250ZXh0X2NyZWF0 ZShlbmdpbmUpOwo+ICsJaWYgKElTX0VSUihjZSkpCj4gKwkJcmV0dXJuIGNlOwo+ICsKPiArCS8q IFdlIGJ1aWxkIGxhcmdlIHJlcXVlc3RzIHRvIHJlYWQgdGhlIHJlZ2lzdGVycyBmcm9tIHRoZSBy aW5nICovCj4gKwljZS0+cmluZyA9IF9faW50ZWxfY29udGV4dF9yaW5nX3NpemUoU1pfMTZLKTsK PiArCj4gKwlyZXR1cm4gY2U7Cj4gK30KPiArCj4gICBzdGF0aWMgaW50IHJlcXVlc3RfYWRkX3N5 bmMoc3RydWN0IGk5MTVfcmVxdWVzdCAqcnEsIGludCBlcnIpCj4gICB7Cj4gICAJaTkxNV9yZXF1 ZXN0X2dldChycSk7Cj4gQEAgLTMwMSw3ICszMTUsNyBAQCBzdGF0aWMgaW50IGxpdmVfbW9jc19j bGVhbih2b2lkICphcmcpCj4gICAJZm9yX2VhY2hfZW5naW5lKGVuZ2luZSwgZ3QsIGlkKSB7Cj4g ICAJCXN0cnVjdCBpbnRlbF9jb250ZXh0ICpjZTsKPiAgIAo+IC0JCWNlID0gaW50ZWxfY29udGV4 dF9jcmVhdGUoZW5naW5lKTsKPiArCQljZSA9IG1vY3NfY29udGV4dF9jcmVhdGUoZW5naW5lKTsK PiAgIAkJaWYgKElTX0VSUihjZSkpIHsKPiAgIAkJCWVyciA9IFBUUl9FUlIoY2UpOwo+ICAgCQkJ YnJlYWs7Cj4gQEAgLTM5NSw3ICs0MDksNyBAQCBzdGF0aWMgaW50IGxpdmVfbW9jc19yZXNldCh2 b2lkICphcmcpCj4gICAJZm9yX2VhY2hfZW5naW5lKGVuZ2luZSwgZ3QsIGlkKSB7Cj4gICAJCXN0 cnVjdCBpbnRlbF9jb250ZXh0ICpjZTsKPiAgIAo+IC0JCWNlID0gaW50ZWxfY29udGV4dF9jcmVh dGUoZW5naW5lKTsKPiArCQljZSA9IG1vY3NfY29udGV4dF9jcmVhdGUoZW5naW5lKTsKPiAgIAkJ aWYgKElTX0VSUihjZSkpIHsKPiAgIAkJCWVyciA9IFBUUl9FUlIoY2UpOwo+ICAgCQkJYnJlYWs7 Cj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2d0L3NlbGZ0ZXN0X3JpbmcuYyBi L2RyaXZlcnMvZ3B1L2RybS9pOTE1L2d0L3NlbGZ0ZXN0X3JpbmcuYwo+IG5ldyBmaWxlIG1vZGUg MTAwNjQ0Cj4gaW5kZXggMDAwMDAwMDAwMDAwLi4yYThjNTM0ZGMxMjUKPiAtLS0gL2Rldi9udWxs Cj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL2k5MTUvZ3Qvc2VsZnRlc3RfcmluZy5jCj4gQEAgLTAs MCArMSwxMTAgQEAKPiArLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjAKPiArLyoK PiArICogQ29weXJpZ2h0IMKpIDIwMjAgSW50ZWwgQ29ycG9yYXRpb24KPiArICovCj4gKwo+ICtz dGF0aWMgc3RydWN0IGludGVsX3JpbmcgKm1vY2tfcmluZyh1bnNpZ25lZCBsb25nIHN6KQo+ICt7 Cj4gKwlzdHJ1Y3QgaW50ZWxfcmluZyAqcmluZzsKPiArCj4gKwlyaW5nID0ga3phbGxvYyhzaXpl b2YoKnJpbmcpICsgc3osIEdGUF9LRVJORUwpOwo+ICsJaWYgKCFyaW5nKQo+ICsJCXJldHVybiBO VUxMOwo+ICsKPiArCWtyZWZfaW5pdCgmcmluZy0+cmVmKTsKPiArCXJpbmctPnNpemUgPSBzejsK PiArCXJpbmctPndyYXAgPSBCSVRTX1BFUl9UWVBFKHJpbmctPnNpemUpIC0gaWxvZzIoc3opOwo+ ICsJcmluZy0+ZWZmZWN0aXZlX3NpemUgPSBzejsKPiArCXJpbmctPnZhZGRyID0gKHZvaWQgKiko cmluZyArIDEpOwo+ICsJYXRvbWljX3NldCgmcmluZy0+cGluX2NvdW50LCAxKTsKPiArCj4gKwlp bnRlbF9yaW5nX3VwZGF0ZV9zcGFjZShyaW5nKTsKPiArCj4gKwlyZXR1cm4gcmluZzsKPiArfQo+ ICsKPiArc3RhdGljIHZvaWQgbW9ja19yaW5nX2ZyZWUoc3RydWN0IGludGVsX3JpbmcgKnJpbmcp Cj4gK3sKPiArCWtmcmVlKHJpbmcpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IGNoZWNrX3Jpbmdf ZGlyZWN0aW9uKHN0cnVjdCBpbnRlbF9yaW5nICpyaW5nLAo+ICsJCQkJdTMyIG5leHQsIHUzMiBw cmV2LAo+ICsJCQkJaW50IGV4cGVjdGVkKQo+ICt7Cj4gKwlpbnQgcmVzdWx0Owo+ICsKPiArCXJl c3VsdCA9IGludGVsX3JpbmdfZGlyZWN0aW9uKHJpbmcsIG5leHQsIHByZXYpOwo+ICsJaWYgKHJl c3VsdCA8IDApCj4gKwkJcmVzdWx0ID0gLTE7Cj4gKwllbHNlIGlmIChyZXN1bHQgPiAwKQo+ICsJ CXJlc3VsdCA9IDE7Cj4gKwo+ICsJaWYgKHJlc3VsdCAhPSBleHBlY3RlZCkgewo+ICsJCXByX2Vy cigiaW50ZWxfcmluZ19kaXJlY3Rpb24oJXUsICV1KTolZCAhPSAlZFxuIiwKPiArCQkgICAgICAg bmV4dCwgcHJldiwgcmVzdWx0LCBleHBlY3RlZCk7Cj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4gKwl9 Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgY2hlY2tfcmluZ19zdGVw KHN0cnVjdCBpbnRlbF9yaW5nICpyaW5nLCB1MzIgeCwgdTMyIHN0ZXApCj4gK3sKPiArCXUzMiBw cmV2ID0geCwgbmV4dCA9IGludGVsX3Jpbmdfd3JhcChyaW5nLCB4ICsgc3RlcCk7Cj4gKwlpbnQg ZXJyID0gMDsKPiArCj4gKwllcnIgfD0gY2hlY2tfcmluZ19kaXJlY3Rpb24ocmluZywgbmV4dCwg bmV4dCwgIDApOwo+ICsJZXJyIHw9IGNoZWNrX3JpbmdfZGlyZWN0aW9uKHJpbmcsIHByZXYsIHBy ZXYsICAwKTsKPiArCWVyciB8PSBjaGVja19yaW5nX2RpcmVjdGlvbihyaW5nLCBuZXh0LCBwcmV2 LCAgMSk7Cj4gKwllcnIgfD0gY2hlY2tfcmluZ19kaXJlY3Rpb24ocmluZywgcHJldiwgbmV4dCwg LTEpOwo+ICsKPiArCXJldHVybiBlcnI7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgY2hlY2tfcmlu Z19vZmZzZXQoc3RydWN0IGludGVsX3JpbmcgKnJpbmcsIHUzMiB4LCB1MzIgc3RlcCkKPiArewo+ ICsJaW50IGVyciA9IDA7Cj4gKwo+ICsJZXJyIHw9IGNoZWNrX3Jpbmdfc3RlcChyaW5nLCB4LCBz dGVwKTsKPiArCWVyciB8PSBjaGVja19yaW5nX3N0ZXAocmluZywgaW50ZWxfcmluZ193cmFwKHJp bmcsIHggKyAxKSwgc3RlcCk7Cj4gKwllcnIgfD0gY2hlY2tfcmluZ19zdGVwKHJpbmcsIGludGVs X3Jpbmdfd3JhcChyaW5nLCB4IC0gMSksIHN0ZXApOwo+ICsKPiArCXJldHVybiBlcnI7Cj4gK30K PiArCj4gK3N0YXRpYyBpbnQgaWd0X3JpbmdfZGlyZWN0aW9uKHZvaWQgKmR1bW15KQo+ICt7Cj4g KwlzdHJ1Y3QgaW50ZWxfcmluZyAqcmluZzsKPiArCXVuc2lnbmVkIGludCBoYWxmID0gMjA0ODsK PiArCWludCBzdGVwLCBlcnIgPSAwOwo+ICsKPiArCXJpbmcgPSBtb2NrX3JpbmcoMiAqIGhhbGYp Owo+ICsJaWYgKCFyaW5nKQo+ICsJCXJldHVybiAtRU5PTUVNOwo+ICsKPiArCUdFTV9CVUdfT04o cmluZy0+c2l6ZSAhPSAyICogaGFsZik7Cj4gKwo+ICsJLyogUHJlY2lzaW9uIG9mIHdyYXAgZGV0 ZWN0aW9uIGlzIGxpbWl0ZWQgdG8gcmluZy0+c2l6ZSAvIDIgKi8KPiArCWZvciAoc3RlcCA9IDE7 IHN0ZXAgPCBoYWxmOyBzdGVwIDw8PSAxKSB7Cj4gKwkJZXJyIHw9IGNoZWNrX3Jpbmdfb2Zmc2V0 KHJpbmcsIDAsIHN0ZXApOwo+ICsJCWVyciB8PSBjaGVja19yaW5nX29mZnNldChyaW5nLCBoYWxm LCBzdGVwKTsKPiArCX0KPiArCWVyciB8PSBjaGVja19yaW5nX3N0ZXAocmluZywgMCwgaGFsZiAt IDY0KTsKPiArCj4gKwkvKiBBbmQgY2hlY2sgdW53cmFwcGVkIGhhbmRsaW5nIGZvciBnb29kIG1l YXN1cmUgKi8KPiArCWVyciB8PSBjaGVja19yaW5nX29mZnNldChyaW5nLCAwLCAyICogaGFsZiAr IDY0KTsKPiArCWVyciB8PSBjaGVja19yaW5nX29mZnNldChyaW5nLCAzICogaGFsZiwgMSk7Cj4g Kwo+ICsJbW9ja19yaW5nX2ZyZWUocmluZyk7Cj4gKwlyZXR1cm4gZXJyOwo+ICt9Cj4gKwo+ICtp bnQgaW50ZWxfcmluZ19tb2NrX3NlbGZ0ZXN0cyh2b2lkKQo+ICt7Cj4gKwlzdGF0aWMgY29uc3Qg c3RydWN0IGk5MTVfc3VidGVzdCB0ZXN0c1tdID0gewo+ICsJCVNVQlRFU1QoaWd0X3JpbmdfZGly ZWN0aW9uKSwKPiArCX07Cj4gKwo+ICsJcmV0dXJuIGk5MTVfc3VidGVzdHModGVzdHMsIE5VTEwp Owo+ICt9Cj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9pOTE1L3NlbGZ0ZXN0cy9pOTE1 X21vY2tfc2VsZnRlc3RzLmggYi9kcml2ZXJzL2dwdS9kcm0vaTkxNS9zZWxmdGVzdHMvaTkxNV9t b2NrX3NlbGZ0ZXN0cy5oCj4gaW5kZXggMTkyOWZlYmE0ZThlLi4zZGIzNGQzZWVhNTggMTAwNjQ0 Cj4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL2k5MTUvc2VsZnRlc3RzL2k5MTVfbW9ja19zZWxmdGVz dHMuaAo+ICsrKyBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L3NlbGZ0ZXN0cy9pOTE1X21vY2tfc2Vs ZnRlc3RzLmgKPiBAQCAtMjEsNiArMjEsNyBAQCBzZWxmdGVzdChmZW5jZSwgaTkxNV9zd19mZW5j ZV9tb2NrX3NlbGZ0ZXN0cykKPiAgIHNlbGZ0ZXN0KHNjYXR0ZXJsaXN0LCBzY2F0dGVybGlzdF9t b2NrX3NlbGZ0ZXN0cykKPiAgIHNlbGZ0ZXN0KHN5bmNtYXAsIGk5MTVfc3luY21hcF9tb2NrX3Nl bGZ0ZXN0cykKPiAgIHNlbGZ0ZXN0KHVuY29yZSwgaW50ZWxfdW5jb3JlX21vY2tfc2VsZnRlc3Rz KQo+ICtzZWxmdGVzdChyaW5nLCBpbnRlbF9yaW5nX21vY2tfc2VsZnRlc3RzKQo+ICAgc2VsZnRl c3QoZW5naW5lLCBpbnRlbF9lbmdpbmVfY3NfbW9ja19zZWxmdGVzdHMpCj4gICBzZWxmdGVzdCh0 aW1lbGluZXMsIGludGVsX3RpbWVsaW5lX21vY2tfc2VsZnRlc3RzKQo+ICAgc2VsZnRlc3QocmVx dWVzdHMsIGk5MTVfcmVxdWVzdF9tb2NrX3NlbGZ0ZXN0cykKX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX18KSW50ZWwtZ2Z4IG1haWxpbmcgbGlzdApJbnRlbC1n ZnhAbGlzdHMuZnJlZWRlc2t0b3Aub3JnCmh0dHBzOi8vbGlzdHMuZnJlZWRlc2t0b3Aub3JnL21h aWxtYW4vbGlzdGluZm8vaW50ZWwtZ2Z4Cg==