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=-10.5 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED 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 CEBDDC4743D for ; Tue, 8 Jun 2021 16:18:45 +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 8F73761278 for ; Tue, 8 Jun 2021 16:18:45 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8F73761278 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 3BF156EC20; Tue, 8 Jun 2021 16:18:44 +0000 (UTC) Received: from mail-qk1-x72a.google.com (mail-qk1-x72a.google.com [IPv6:2607:f8b0:4864:20::72a]) by gabe.freedesktop.org (Postfix) with ESMTPS id 3D9506E202; Tue, 8 Jun 2021 16:18:43 +0000 (UTC) Received: by mail-qk1-x72a.google.com with SMTP id i68so17134709qke.3; Tue, 08 Jun 2021 09:18:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=kptf4JT+dH3ZidDSzD7yamHi41j4w9BAdxBUDKYmeEg=; b=YTsk9Wojacfjx6kCZ5+X+0IWCqY1bnOWVZ/Ja2aszIKFMfvi+Nye8kvuEwdMskruSx HIbO/iWmBf1rO1o05PzDs32EvmpymBJWPGBwUv9Rj2Jg9wsqshSys0JyZcfpLcr1h1uP sLoijWZxm6swHl1p8rVn+BWh6uAoP6VojjjevcTnArfiBSRpCOeRZ/sCbbV7O5JVD+IK nQZt8m7uYxeBTIdgH27PkGyNzaRB5hC5d2zNyHxElf6oS3DmuG3CDUUEJhFOqcCxelWs MYmhfcXlqsk3xZplp1QRgTAmUK+T0VkMsDsCnrzZKj6ZqgJC/J/TuGR/AMnrpgfdWZWu +BTA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=kptf4JT+dH3ZidDSzD7yamHi41j4w9BAdxBUDKYmeEg=; b=limGJT4uCZVVuIZgl9fXLdKWZdmAebSMXR381X96w/7U7UjnNG/E8MN/ryhABtJ7DS jtvY12aSWBesLPeHZm5rZrBU9uJ4i590S9slfll2FivBloiaRnpqwCyGIo2CgO1EbaPv IuTyBEqs5TVL1z3VQEMOLdb2EbouH2RZycfw25DJDjAhUdVSYwYer05zl7gSypkDI1wV GyQ08RKemV16bUvvPurufwLRnJQm0nXlEaHlF/q4R6rvq8YuDi7hynRjT5PEjorbCKS9 6Mb2O9r1PWKI7ayjIVkLgQLQ6oLkULxnxjJpZbp8cM51Yo+1XYvCzaxWHtduwKnM/Fjw CJ4A== X-Gm-Message-State: AOAM531HxGbXzxSoW+X2JiEjSIChNJnvexCnBLgoIeCOhb1iPD3MoetA syoW+4desVTtFNs6Zf66GCE6Po7vINg3Z5ZJsFY= X-Google-Smtp-Source: ABdhPJyPr3khze4DneFxjTte/jE7yWd4XHLpzR2V6fNkyXkmXMDrGvrxLJnMQtSfLJLLFo+TB1R6vnjv1XUiH712Nv8= X-Received: by 2002:a37:a704:: with SMTP id q4mr19477262qke.460.1623169122161; Tue, 08 Jun 2021 09:18:42 -0700 (PDT) MIME-Version: 1.0 References: <20210608092846.64198-1-thomas.hellstrom@linux.intel.com> <20210608092846.64198-8-thomas.hellstrom@linux.intel.com> In-Reply-To: <20210608092846.64198-8-thomas.hellstrom@linux.intel.com> From: Matthew Auld Date: Tue, 8 Jun 2021 17:18:15 +0100 Message-ID: Subject: Re: [Intel-gfx] [PATCH 7/9] drm/i915/gt: Pipelined page migration To: =?UTF-8?Q?Thomas_Hellstr=C3=B6m?= Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Intel Graphics Development , Matthew Auld , ML dri-devel , Chris Wilson Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" On Tue, 8 Jun 2021 at 10:29, Thomas Hellstr=C3=B6m wrote: > > From: Chris Wilson > > If we pipeline the PTE updates and then do the copy of those pages > within a single unpreemptible command packet, we can submit the copies > and leave them to be scheduled without having to synchronously wait > under a global lock. In order to manage migration, we need to > preallocate the page tables (and keep them pinned and available for use > at any time), causing a bottleneck for migrations as all clients must > contend on the limited resources. By inlining the ppGTT updates and > performing the blit atomically, each client only owns the PTE while in > use, and so we can reschedule individual operations however we see fit. > And most importantly, we do not need to take a global lock on the shared > vm, and wait until the operation is complete before releasing the lock > for others to claim the PTE for themselves. > > Signed-off-by: Chris Wilson > Co-developed-by: Thomas Hellstr=C3=B6m > Signed-off-by: Thomas Hellstr=C3=B6m > --- > drivers/gpu/drm/i915/Makefile | 1 + > drivers/gpu/drm/i915/gt/intel_engine.h | 1 + > drivers/gpu/drm/i915/gt/intel_gpu_commands.h | 2 + > drivers/gpu/drm/i915/gt/intel_migrate.c | 543 ++++++++++++++++++ > drivers/gpu/drm/i915/gt/intel_migrate.h | 45 ++ > drivers/gpu/drm/i915/gt/intel_migrate_types.h | 15 + > drivers/gpu/drm/i915/gt/intel_ring.h | 1 + > drivers/gpu/drm/i915/gt/selftest_migrate.c | 291 ++++++++++ > .../drm/i915/selftests/i915_live_selftests.h | 1 + > 9 files changed, 900 insertions(+) > create mode 100644 drivers/gpu/drm/i915/gt/intel_migrate.c > create mode 100644 drivers/gpu/drm/i915/gt/intel_migrate.h > create mode 100644 drivers/gpu/drm/i915/gt/intel_migrate_types.h > create mode 100644 drivers/gpu/drm/i915/gt/selftest_migrate.c > > diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefil= e > index ea8ee4b3e018..9f18902be626 100644 > --- a/drivers/gpu/drm/i915/Makefile > +++ b/drivers/gpu/drm/i915/Makefile > @@ -109,6 +109,7 @@ gt-y +=3D \ > gt/intel_gtt.o \ > gt/intel_llc.o \ > gt/intel_lrc.o \ > + gt/intel_migrate.o \ > gt/intel_mocs.o \ > gt/intel_ppgtt.o \ > gt/intel_rc6.o \ > diff --git a/drivers/gpu/drm/i915/gt/intel_engine.h b/drivers/gpu/drm/i91= 5/gt/intel_engine.h > index 0862c42b4cac..949965680c37 100644 > --- a/drivers/gpu/drm/i915/gt/intel_engine.h > +++ b/drivers/gpu/drm/i915/gt/intel_engine.h > @@ -188,6 +188,7 @@ intel_write_status_page(struct intel_engine_cs *engin= e, int reg, u32 value) > #define I915_GEM_HWS_PREEMPT_ADDR (I915_GEM_HWS_PREEMPT * sizeof(u3= 2)) > #define I915_GEM_HWS_SEQNO 0x40 > #define I915_GEM_HWS_SEQNO_ADDR (I915_GEM_HWS_SEQNO * siz= eof(u32)) > +#define I915_GEM_HWS_MIGRATE (0x42 * sizeof(u32)) > #define I915_GEM_HWS_SCRATCH 0x80 > > #define I915_HWS_CSB_BUF0_INDEX 0x10 > diff --git a/drivers/gpu/drm/i915/gt/intel_gpu_commands.h b/drivers/gpu/d= rm/i915/gt/intel_gpu_commands.h > index 2694dbb9967e..1c3af0fc0456 100644 > --- a/drivers/gpu/drm/i915/gt/intel_gpu_commands.h > +++ b/drivers/gpu/drm/i915/gt/intel_gpu_commands.h > @@ -123,8 +123,10 @@ > #define MI_SEMAPHORE_SAD_NEQ_SDD (5 << 12) > #define MI_SEMAPHORE_TOKEN_MASK REG_GENMASK(9, 5) > #define MI_SEMAPHORE_TOKEN_SHIFT 5 > +#define MI_STORE_DATA_IMM MI_INSTR(0x20, 0) > #define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1) > #define MI_STORE_DWORD_IMM_GEN4 MI_INSTR(0x20, 2) > +#define MI_STORE_QWORD_IMM_GEN8 (MI_INSTR(0x20, 3) | REG_BIT(21)) > #define MI_MEM_VIRTUAL (1 << 22) /* 945,g33,965 */ > #define MI_USE_GGTT (1 << 22) /* g4x+ */ > #define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1) > diff --git a/drivers/gpu/drm/i915/gt/intel_migrate.c b/drivers/gpu/drm/i9= 15/gt/intel_migrate.c > new file mode 100644 > index 000000000000..1f60f8ee36f8 > --- /dev/null > +++ b/drivers/gpu/drm/i915/gt/intel_migrate.c > @@ -0,0 +1,543 @@ > +// SPDX-License-Identifier: MIT > +/* > + * Copyright =C2=A9 2020 Intel Corporation > + */ > + > +#include "i915_drv.h" > +#include "intel_context.h" > +#include "intel_gpu_commands.h" > +#include "intel_gt.h" > +#include "intel_gtt.h" > +#include "intel_migrate.h" > +#include "intel_ring.h" > + > +struct insert_pte_data { > + u64 offset; > + bool is_lmem; > +}; > + > +#define CHUNK_SZ SZ_8M /* ~1ms at 8GiB/s preemption delay */ > + > +static bool engine_supports_migration(struct intel_engine_cs *engine) > +{ > + if (!engine) > + return false; > + > + /* > + * We need the ability to prevent aribtration (MI_ARB_ON_OFF), > + * the ability to write PTE using inline data (MI_STORE_DATA) > + * and of course the ability to do the block transfer (blits). > + */ > + GEM_BUG_ON(engine->class !=3D COPY_ENGINE_CLASS); > + > + return true; > +} > + > +static void insert_pte(struct i915_address_space *vm, > + struct i915_page_table *pt, > + void *data) > +{ > + struct insert_pte_data *d =3D data; > + > + vm->insert_page(vm, px_dma(pt), d->offset, I915_CACHE_NONE, > + d->is_lmem ? PTE_LM : 0); > + d->offset +=3D PAGE_SIZE; > +} > + > +static struct i915_address_space *migrate_vm(struct intel_gt *gt) > +{ > + struct i915_vm_pt_stash stash =3D {}; > + struct i915_ppgtt *vm; > + int err; > + int i; > + > + /* > + * We construct a very special VM for use by all migration contex= ts, > + * it is kept pinned so that it can be used at any time. As we ne= ed > + * to pre-allocate the page directories for the migration VM, thi= s > + * limits us to only using a small number of prepared vma. > + * > + * To be able to pipeline and reschedule migration operations whi= le > + * avoiding unnecessary contention on the vm itself, the PTE upda= tes > + * are inline with the blits. All the blits use the same fixed > + * addresses, with the backing store redirection being updated on= the > + * fly. Only 2 implicit vma are used for all migration operations= . > + * > + * We lay the ppGTT out as: > + * > + * [0, CHUNK_SZ) -> first object > + * [CHUNK_SZ, 2 * CHUNK_SZ) -> second object > + * [2 * CHUNK_SZ, 2 * CHUNK_SZ + 2 * CHUNK_SZ >> 9] -> PTE > + * > + * By exposing the dma addresses of the page directories themselv= es > + * within the ppGTT, we are then able to rewrite the PTE prior to= use. > + * But the PTE update and subsequent migration operation must be = atomic, > + * i.e. within the same non-preemptible window so that we do not = switch > + * to another migration context that overwrites the PTE. > + */ > + > + vm =3D i915_ppgtt_create(gt); > + if (IS_ERR(vm)) > + return ERR_CAST(vm); > + > + if (!vm->vm.allocate_va_range || !vm->vm.foreach) { > + err =3D -ENODEV; > + goto err_vm; > + } > + > + /* > + * Each engine instance is assigned its own chunk in the VM, so > + * that we can run multiple instances concurrently > + */ > + for (i =3D 0; i < ARRAY_SIZE(gt->engine_class[COPY_ENGINE_CLASS])= ; i++) { > + struct intel_engine_cs *engine; > + u64 base =3D (u64)i << 32; > + struct insert_pte_data d =3D {}; > + struct i915_gem_ww_ctx ww; > + u64 sz; > + > + engine =3D gt->engine_class[COPY_ENGINE_CLASS][i]; > + if (!engine_supports_migration(engine)) > + continue; > + > + /* > + * We copy in 8MiB chunks. Each PDE covers 2MiB, so we ne= ed > + * 4x2 page directories for source/destination. > + */ > + sz =3D 2 * CHUNK_SZ; > + d.offset =3D base + sz; > + > + /* > + * We need another page directory setup so that we can wr= ite > + * the 8x512 PTE in each chunk. > + */ > + sz +=3D (sz >> 12) * sizeof(u64); > + > + err =3D i915_vm_alloc_pt_stash(&vm->vm, &stash, sz); > + if (err) > + goto err_vm; > + > + for_i915_gem_ww(&ww, err, true) { > + err =3D i915_vm_lock_objects(&vm->vm, &ww); > + if (err) > + continue; > + err =3D i915_vm_map_pt_stash(&vm->vm, &stash); > + if (err) > + continue; > + > + vm->vm.allocate_va_range(&vm->vm, &stash, base, b= ase + sz); > + } > + i915_vm_free_pt_stash(&vm->vm, &stash); > + if (err) > + goto err_vm; > + > + /* Now allow the GPU to rewrite the PTE via its own ppGTT= */ > + d.is_lmem =3D i915_gem_object_is_lmem(vm->vm.scratch[0]); > + vm->vm.foreach(&vm->vm, base, base + sz, insert_pte, &d); Will this play nice with Xe HP where we have min page size restrictions for the GTT + lmem? The page-table allocations sidestep such restrictions since they were previously never inserted into the GTT. Maybe we need the flat-ppGTT at some point? Perhaps add a TODO or something? 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=-10.5 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED 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 7B3E0C47082 for ; Tue, 8 Jun 2021 16:18: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 3DD1261249 for ; Tue, 8 Jun 2021 16:18:44 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3DD1261249 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.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 E8F686E202; Tue, 8 Jun 2021 16:18:43 +0000 (UTC) Received: from mail-qk1-x72a.google.com (mail-qk1-x72a.google.com [IPv6:2607:f8b0:4864:20::72a]) by gabe.freedesktop.org (Postfix) with ESMTPS id 3D9506E202; Tue, 8 Jun 2021 16:18:43 +0000 (UTC) Received: by mail-qk1-x72a.google.com with SMTP id i68so17134709qke.3; Tue, 08 Jun 2021 09:18:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=kptf4JT+dH3ZidDSzD7yamHi41j4w9BAdxBUDKYmeEg=; b=YTsk9Wojacfjx6kCZ5+X+0IWCqY1bnOWVZ/Ja2aszIKFMfvi+Nye8kvuEwdMskruSx HIbO/iWmBf1rO1o05PzDs32EvmpymBJWPGBwUv9Rj2Jg9wsqshSys0JyZcfpLcr1h1uP sLoijWZxm6swHl1p8rVn+BWh6uAoP6VojjjevcTnArfiBSRpCOeRZ/sCbbV7O5JVD+IK nQZt8m7uYxeBTIdgH27PkGyNzaRB5hC5d2zNyHxElf6oS3DmuG3CDUUEJhFOqcCxelWs MYmhfcXlqsk3xZplp1QRgTAmUK+T0VkMsDsCnrzZKj6ZqgJC/J/TuGR/AMnrpgfdWZWu +BTA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=kptf4JT+dH3ZidDSzD7yamHi41j4w9BAdxBUDKYmeEg=; b=limGJT4uCZVVuIZgl9fXLdKWZdmAebSMXR381X96w/7U7UjnNG/E8MN/ryhABtJ7DS jtvY12aSWBesLPeHZm5rZrBU9uJ4i590S9slfll2FivBloiaRnpqwCyGIo2CgO1EbaPv IuTyBEqs5TVL1z3VQEMOLdb2EbouH2RZycfw25DJDjAhUdVSYwYer05zl7gSypkDI1wV GyQ08RKemV16bUvvPurufwLRnJQm0nXlEaHlF/q4R6rvq8YuDi7hynRjT5PEjorbCKS9 6Mb2O9r1PWKI7ayjIVkLgQLQ6oLkULxnxjJpZbp8cM51Yo+1XYvCzaxWHtduwKnM/Fjw CJ4A== X-Gm-Message-State: AOAM531HxGbXzxSoW+X2JiEjSIChNJnvexCnBLgoIeCOhb1iPD3MoetA syoW+4desVTtFNs6Zf66GCE6Po7vINg3Z5ZJsFY= X-Google-Smtp-Source: ABdhPJyPr3khze4DneFxjTte/jE7yWd4XHLpzR2V6fNkyXkmXMDrGvrxLJnMQtSfLJLLFo+TB1R6vnjv1XUiH712Nv8= X-Received: by 2002:a37:a704:: with SMTP id q4mr19477262qke.460.1623169122161; Tue, 08 Jun 2021 09:18:42 -0700 (PDT) MIME-Version: 1.0 References: <20210608092846.64198-1-thomas.hellstrom@linux.intel.com> <20210608092846.64198-8-thomas.hellstrom@linux.intel.com> In-Reply-To: <20210608092846.64198-8-thomas.hellstrom@linux.intel.com> From: Matthew Auld Date: Tue, 8 Jun 2021 17:18:15 +0100 Message-ID: To: =?UTF-8?Q?Thomas_Hellstr=C3=B6m?= Subject: Re: [Intel-gfx] [PATCH 7/9] drm/i915/gt: Pipelined page migration 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: Intel Graphics Development , Matthew Auld , ML dri-devel , Chris Wilson Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" T24gVHVlLCA4IEp1biAyMDIxIGF0IDEwOjI5LCBUaG9tYXMgSGVsbHN0csO2bQo8dGhvbWFzLmhl bGxzdHJvbUBsaW51eC5pbnRlbC5jb20+IHdyb3RlOgo+Cj4gRnJvbTogQ2hyaXMgV2lsc29uIDxj aHJpc0BjaHJpcy13aWxzb24uY28udWs+Cj4KPiBJZiB3ZSBwaXBlbGluZSB0aGUgUFRFIHVwZGF0 ZXMgYW5kIHRoZW4gZG8gdGhlIGNvcHkgb2YgdGhvc2UgcGFnZXMKPiB3aXRoaW4gYSBzaW5nbGUg dW5wcmVlbXB0aWJsZSBjb21tYW5kIHBhY2tldCwgd2UgY2FuIHN1Ym1pdCB0aGUgY29waWVzCj4g YW5kIGxlYXZlIHRoZW0gdG8gYmUgc2NoZWR1bGVkIHdpdGhvdXQgaGF2aW5nIHRvIHN5bmNocm9u b3VzbHkgd2FpdAo+IHVuZGVyIGEgZ2xvYmFsIGxvY2suIEluIG9yZGVyIHRvIG1hbmFnZSBtaWdy YXRpb24sIHdlIG5lZWQgdG8KPiBwcmVhbGxvY2F0ZSB0aGUgcGFnZSB0YWJsZXMgKGFuZCBrZWVw IHRoZW0gcGlubmVkIGFuZCBhdmFpbGFibGUgZm9yIHVzZQo+IGF0IGFueSB0aW1lKSwgY2F1c2lu ZyBhIGJvdHRsZW5lY2sgZm9yIG1pZ3JhdGlvbnMgYXMgYWxsIGNsaWVudHMgbXVzdAo+IGNvbnRl bmQgb24gdGhlIGxpbWl0ZWQgcmVzb3VyY2VzLiBCeSBpbmxpbmluZyB0aGUgcHBHVFQgdXBkYXRl cyBhbmQKPiBwZXJmb3JtaW5nIHRoZSBibGl0IGF0b21pY2FsbHksIGVhY2ggY2xpZW50IG9ubHkg b3ducyB0aGUgUFRFIHdoaWxlIGluCj4gdXNlLCBhbmQgc28gd2UgY2FuIHJlc2NoZWR1bGUgaW5k aXZpZHVhbCBvcGVyYXRpb25zIGhvd2V2ZXIgd2Ugc2VlIGZpdC4KPiBBbmQgbW9zdCBpbXBvcnRh bnRseSwgd2UgZG8gbm90IG5lZWQgdG8gdGFrZSBhIGdsb2JhbCBsb2NrIG9uIHRoZSBzaGFyZWQK PiB2bSwgYW5kIHdhaXQgdW50aWwgdGhlIG9wZXJhdGlvbiBpcyBjb21wbGV0ZSBiZWZvcmUgcmVs ZWFzaW5nIHRoZSBsb2NrCj4gZm9yIG90aGVycyB0byBjbGFpbSB0aGUgUFRFIGZvciB0aGVtc2Vs dmVzLgo+Cj4gU2lnbmVkLW9mZi1ieTogQ2hyaXMgV2lsc29uIDxjaHJpc0BjaHJpcy13aWxzb24u Y28udWs+Cj4gQ28tZGV2ZWxvcGVkLWJ5OiBUaG9tYXMgSGVsbHN0csO2bSA8dGhvbWFzLmhlbGxz dHJvbUBsaW51eC5pbnRlbC5jb20+Cj4gU2lnbmVkLW9mZi1ieTogVGhvbWFzIEhlbGxzdHLDtm0g PHRob21hcy5oZWxsc3Ryb21AbGludXguaW50ZWwuY29tPgo+IC0tLQo+ICBkcml2ZXJzL2dwdS9k cm0vaTkxNS9NYWtlZmlsZSAgICAgICAgICAgICAgICAgfCAgIDEgKwo+ICBkcml2ZXJzL2dwdS9k cm0vaTkxNS9ndC9pbnRlbF9lbmdpbmUuaCAgICAgICAgfCAgIDEgKwo+ICBkcml2ZXJzL2dwdS9k cm0vaTkxNS9ndC9pbnRlbF9ncHVfY29tbWFuZHMuaCAgfCAgIDIgKwo+ICBkcml2ZXJzL2dwdS9k cm0vaTkxNS9ndC9pbnRlbF9taWdyYXRlLmMgICAgICAgfCA1NDMgKysrKysrKysrKysrKysrKysr Cj4gIGRyaXZlcnMvZ3B1L2RybS9pOTE1L2d0L2ludGVsX21pZ3JhdGUuaCAgICAgICB8ICA0NSAr Kwo+ICBkcml2ZXJzL2dwdS9kcm0vaTkxNS9ndC9pbnRlbF9taWdyYXRlX3R5cGVzLmggfCAgMTUg Kwo+ICBkcml2ZXJzL2dwdS9kcm0vaTkxNS9ndC9pbnRlbF9yaW5nLmggICAgICAgICAgfCAgIDEg Kwo+ICBkcml2ZXJzL2dwdS9kcm0vaTkxNS9ndC9zZWxmdGVzdF9taWdyYXRlLmMgICAgfCAyOTEg KysrKysrKysrKwo+ICAuLi4vZHJtL2k5MTUvc2VsZnRlc3RzL2k5MTVfbGl2ZV9zZWxmdGVzdHMu aCAgfCAgIDEgKwo+ICA5IGZpbGVzIGNoYW5nZWQsIDkwMCBpbnNlcnRpb25zKCspCj4gIGNyZWF0 ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL2dwdS9kcm0vaTkxNS9ndC9pbnRlbF9taWdyYXRlLmMKPiAg Y3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvZ3B1L2RybS9pOTE1L2d0L2ludGVsX21pZ3JhdGUu aAo+ICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9ncHUvZHJtL2k5MTUvZ3QvaW50ZWxfbWln cmF0ZV90eXBlcy5oCj4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL2dwdS9kcm0vaTkxNS9n dC9zZWxmdGVzdF9taWdyYXRlLmMKPgo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vaTkx NS9NYWtlZmlsZSBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L01ha2VmaWxlCj4gaW5kZXggZWE4ZWU0 YjNlMDE4Li45ZjE4OTAyYmU2MjYgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL2k5MTUv TWFrZWZpbGUKPiArKysgYi9kcml2ZXJzL2dwdS9kcm0vaTkxNS9NYWtlZmlsZQo+IEBAIC0xMDks NiArMTA5LDcgQEAgZ3QteSArPSBcCj4gICAgICAgICBndC9pbnRlbF9ndHQubyBcCj4gICAgICAg ICBndC9pbnRlbF9sbGMubyBcCj4gICAgICAgICBndC9pbnRlbF9scmMubyBcCj4gKyAgICAgICBn dC9pbnRlbF9taWdyYXRlLm8gXAo+ICAgICAgICAgZ3QvaW50ZWxfbW9jcy5vIFwKPiAgICAgICAg IGd0L2ludGVsX3BwZ3R0Lm8gXAo+ICAgICAgICAgZ3QvaW50ZWxfcmM2Lm8gXAo+IGRpZmYgLS1n aXQgYS9kcml2ZXJzL2dwdS9kcm0vaTkxNS9ndC9pbnRlbF9lbmdpbmUuaCBiL2RyaXZlcnMvZ3B1 L2RybS9pOTE1L2d0L2ludGVsX2VuZ2luZS5oCj4gaW5kZXggMDg2MmM0MmI0Y2FjLi45NDk5NjU2 ODBjMzcgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL2k5MTUvZ3QvaW50ZWxfZW5naW5l LmgKPiArKysgYi9kcml2ZXJzL2dwdS9kcm0vaTkxNS9ndC9pbnRlbF9lbmdpbmUuaAo+IEBAIC0x ODgsNiArMTg4LDcgQEAgaW50ZWxfd3JpdGVfc3RhdHVzX3BhZ2Uoc3RydWN0IGludGVsX2VuZ2lu ZV9jcyAqZW5naW5lLCBpbnQgcmVnLCB1MzIgdmFsdWUpCj4gICNkZWZpbmUgSTkxNV9HRU1fSFdT X1BSRUVNUFRfQUREUiAgICAgIChJOTE1X0dFTV9IV1NfUFJFRU1QVCAqIHNpemVvZih1MzIpKQo+ ICAjZGVmaW5lIEk5MTVfR0VNX0hXU19TRVFOTyAgICAgICAgICAgICAweDQwCj4gICNkZWZpbmUg STkxNV9HRU1fSFdTX1NFUU5PX0FERFIgICAgICAgICAgICAgICAgKEk5MTVfR0VNX0hXU19TRVFO TyAqIHNpemVvZih1MzIpKQo+ICsjZGVmaW5lIEk5MTVfR0VNX0hXU19NSUdSQVRFICAgICAgICAg ICAoMHg0MiAqIHNpemVvZih1MzIpKQo+ICAjZGVmaW5lIEk5MTVfR0VNX0hXU19TQ1JBVENIICAg ICAgICAgICAweDgwCj4KPiAgI2RlZmluZSBJOTE1X0hXU19DU0JfQlVGMF9JTkRFWCAgICAgICAg ICAgICAgICAweDEwCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2d0L2ludGVs X2dwdV9jb21tYW5kcy5oIGIvZHJpdmVycy9ncHUvZHJtL2k5MTUvZ3QvaW50ZWxfZ3B1X2NvbW1h bmRzLmgKPiBpbmRleCAyNjk0ZGJiOTk2N2UuLjFjM2FmMGZjMDQ1NiAxMDA2NDQKPiAtLS0gYS9k cml2ZXJzL2dwdS9kcm0vaTkxNS9ndC9pbnRlbF9ncHVfY29tbWFuZHMuaAo+ICsrKyBiL2RyaXZl cnMvZ3B1L2RybS9pOTE1L2d0L2ludGVsX2dwdV9jb21tYW5kcy5oCj4gQEAgLTEyMyw4ICsxMjMs MTAgQEAKPiAgI2RlZmluZSAgIE1JX1NFTUFQSE9SRV9TQURfTkVRX1NERCAgICAgKDUgPDwgMTIp Cj4gICNkZWZpbmUgICBNSV9TRU1BUEhPUkVfVE9LRU5fTUFTSyAgICAgIFJFR19HRU5NQVNLKDks IDUpCj4gICNkZWZpbmUgICBNSV9TRU1BUEhPUkVfVE9LRU5fU0hJRlQgICAgIDUKPiArI2RlZmlu ZSBNSV9TVE9SRV9EQVRBX0lNTSAgICAgIE1JX0lOU1RSKDB4MjAsIDApCj4gICNkZWZpbmUgTUlf U1RPUkVfRFdPUkRfSU1NICAgICBNSV9JTlNUUigweDIwLCAxKQo+ICAjZGVmaW5lIE1JX1NUT1JF X0RXT1JEX0lNTV9HRU40ICAgICAgICBNSV9JTlNUUigweDIwLCAyKQo+ICsjZGVmaW5lIE1JX1NU T1JFX1FXT1JEX0lNTV9HRU44IChNSV9JTlNUUigweDIwLCAzKSB8IFJFR19CSVQoMjEpKQo+ICAj ZGVmaW5lICAgTUlfTUVNX1ZJUlRVQUwgICAgICAgKDEgPDwgMjIpIC8qIDk0NSxnMzMsOTY1ICov Cj4gICNkZWZpbmUgICBNSV9VU0VfR0dUVCAgICAgICAgICAoMSA8PCAyMikgLyogZzR4KyAqLwo+ ICAjZGVmaW5lIE1JX1NUT1JFX0RXT1JEX0lOREVYICAgTUlfSU5TVFIoMHgyMSwgMSkKPiBkaWZm IC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL2k5MTUvZ3QvaW50ZWxfbWlncmF0ZS5jIGIvZHJpdmVy cy9ncHUvZHJtL2k5MTUvZ3QvaW50ZWxfbWlncmF0ZS5jCj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQK PiBpbmRleCAwMDAwMDAwMDAwMDAuLjFmNjBmOGVlMzZmOAo+IC0tLSAvZGV2L251bGwKPiArKysg Yi9kcml2ZXJzL2dwdS9kcm0vaTkxNS9ndC9pbnRlbF9taWdyYXRlLmMKPiBAQCAtMCwwICsxLDU0 MyBAQAo+ICsvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlUCj4gKy8qCj4gKyAqIENvcHly aWdodCDCqSAyMDIwIEludGVsIENvcnBvcmF0aW9uCj4gKyAqLwo+ICsKPiArI2luY2x1ZGUgImk5 MTVfZHJ2LmgiCj4gKyNpbmNsdWRlICJpbnRlbF9jb250ZXh0LmgiCj4gKyNpbmNsdWRlICJpbnRl bF9ncHVfY29tbWFuZHMuaCIKPiArI2luY2x1ZGUgImludGVsX2d0LmgiCj4gKyNpbmNsdWRlICJp bnRlbF9ndHQuaCIKPiArI2luY2x1ZGUgImludGVsX21pZ3JhdGUuaCIKPiArI2luY2x1ZGUgImlu dGVsX3JpbmcuaCIKPiArCj4gK3N0cnVjdCBpbnNlcnRfcHRlX2RhdGEgewo+ICsgICAgICAgdTY0 IG9mZnNldDsKPiArICAgICAgIGJvb2wgaXNfbG1lbTsKPiArfTsKPiArCj4gKyNkZWZpbmUgQ0hV TktfU1ogU1pfOE0gLyogfjFtcyBhdCA4R2lCL3MgcHJlZW1wdGlvbiBkZWxheSAqLwo+ICsKPiAr c3RhdGljIGJvb2wgZW5naW5lX3N1cHBvcnRzX21pZ3JhdGlvbihzdHJ1Y3QgaW50ZWxfZW5naW5l X2NzICplbmdpbmUpCj4gK3sKPiArICAgICAgIGlmICghZW5naW5lKQo+ICsgICAgICAgICAgICAg ICByZXR1cm4gZmFsc2U7Cj4gKwo+ICsgICAgICAgLyoKPiArICAgICAgICAqIFdlIG5lZWQgdGhl IGFiaWxpdHkgdG8gcHJldmVudCBhcmlidHJhdGlvbiAoTUlfQVJCX09OX09GRiksCj4gKyAgICAg ICAgKiB0aGUgYWJpbGl0eSB0byB3cml0ZSBQVEUgdXNpbmcgaW5saW5lIGRhdGEgKE1JX1NUT1JF X0RBVEEpCj4gKyAgICAgICAgKiBhbmQgb2YgY291cnNlIHRoZSBhYmlsaXR5IHRvIGRvIHRoZSBi bG9jayB0cmFuc2ZlciAoYmxpdHMpLgo+ICsgICAgICAgICovCj4gKyAgICAgICBHRU1fQlVHX09O KGVuZ2luZS0+Y2xhc3MgIT0gQ09QWV9FTkdJTkVfQ0xBU1MpOwo+ICsKPiArICAgICAgIHJldHVy biB0cnVlOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBpbnNlcnRfcHRlKHN0cnVjdCBpOTE1X2Fk ZHJlc3Nfc3BhY2UgKnZtLAo+ICsgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IGk5MTVfcGFn ZV90YWJsZSAqcHQsCj4gKyAgICAgICAgICAgICAgICAgICAgICB2b2lkICpkYXRhKQo+ICt7Cj4g KyAgICAgICBzdHJ1Y3QgaW5zZXJ0X3B0ZV9kYXRhICpkID0gZGF0YTsKPiArCj4gKyAgICAgICB2 bS0+aW5zZXJ0X3BhZ2Uodm0sIHB4X2RtYShwdCksIGQtPm9mZnNldCwgSTkxNV9DQUNIRV9OT05F LAo+ICsgICAgICAgICAgICAgICAgICAgICAgIGQtPmlzX2xtZW0gPyBQVEVfTE0gOiAwKTsKPiAr ICAgICAgIGQtPm9mZnNldCArPSBQQUdFX1NJWkU7Cj4gK30KPiArCj4gK3N0YXRpYyBzdHJ1Y3Qg aTkxNV9hZGRyZXNzX3NwYWNlICptaWdyYXRlX3ZtKHN0cnVjdCBpbnRlbF9ndCAqZ3QpCj4gK3sK PiArICAgICAgIHN0cnVjdCBpOTE1X3ZtX3B0X3N0YXNoIHN0YXNoID0ge307Cj4gKyAgICAgICBz dHJ1Y3QgaTkxNV9wcGd0dCAqdm07Cj4gKyAgICAgICBpbnQgZXJyOwo+ICsgICAgICAgaW50IGk7 Cj4gKwo+ICsgICAgICAgLyoKPiArICAgICAgICAqIFdlIGNvbnN0cnVjdCBhIHZlcnkgc3BlY2lh bCBWTSBmb3IgdXNlIGJ5IGFsbCBtaWdyYXRpb24gY29udGV4dHMsCj4gKyAgICAgICAgKiBpdCBp cyBrZXB0IHBpbm5lZCBzbyB0aGF0IGl0IGNhbiBiZSB1c2VkIGF0IGFueSB0aW1lLiBBcyB3ZSBu ZWVkCj4gKyAgICAgICAgKiB0byBwcmUtYWxsb2NhdGUgdGhlIHBhZ2UgZGlyZWN0b3JpZXMgZm9y IHRoZSBtaWdyYXRpb24gVk0sIHRoaXMKPiArICAgICAgICAqIGxpbWl0cyB1cyB0byBvbmx5IHVz aW5nIGEgc21hbGwgbnVtYmVyIG9mIHByZXBhcmVkIHZtYS4KPiArICAgICAgICAqCj4gKyAgICAg ICAgKiBUbyBiZSBhYmxlIHRvIHBpcGVsaW5lIGFuZCByZXNjaGVkdWxlIG1pZ3JhdGlvbiBvcGVy YXRpb25zIHdoaWxlCj4gKyAgICAgICAgKiBhdm9pZGluZyB1bm5lY2Vzc2FyeSBjb250ZW50aW9u IG9uIHRoZSB2bSBpdHNlbGYsIHRoZSBQVEUgdXBkYXRlcwo+ICsgICAgICAgICogYXJlIGlubGlu ZSB3aXRoIHRoZSBibGl0cy4gQWxsIHRoZSBibGl0cyB1c2UgdGhlIHNhbWUgZml4ZWQKPiArICAg ICAgICAqIGFkZHJlc3Nlcywgd2l0aCB0aGUgYmFja2luZyBzdG9yZSByZWRpcmVjdGlvbiBiZWlu ZyB1cGRhdGVkIG9uIHRoZQo+ICsgICAgICAgICogZmx5LiBPbmx5IDIgaW1wbGljaXQgdm1hIGFy ZSB1c2VkIGZvciBhbGwgbWlncmF0aW9uIG9wZXJhdGlvbnMuCj4gKyAgICAgICAgKgo+ICsgICAg ICAgICogV2UgbGF5IHRoZSBwcEdUVCBvdXQgYXM6Cj4gKyAgICAgICAgKgo+ICsgICAgICAgICog ICAgICBbMCwgQ0hVTktfU1opIC0+IGZpcnN0IG9iamVjdAo+ICsgICAgICAgICogICAgICBbQ0hV TktfU1osIDIgKiBDSFVOS19TWikgLT4gc2Vjb25kIG9iamVjdAo+ICsgICAgICAgICogICAgICBb MiAqIENIVU5LX1NaLCAyICogQ0hVTktfU1ogKyAyICogQ0hVTktfU1ogPj4gOV0gLT4gUFRFCj4g KyAgICAgICAgKgo+ICsgICAgICAgICogQnkgZXhwb3NpbmcgdGhlIGRtYSBhZGRyZXNzZXMgb2Yg dGhlIHBhZ2UgZGlyZWN0b3JpZXMgdGhlbXNlbHZlcwo+ICsgICAgICAgICogd2l0aGluIHRoZSBw cEdUVCwgd2UgYXJlIHRoZW4gYWJsZSB0byByZXdyaXRlIHRoZSBQVEUgcHJpb3IgdG8gdXNlLgo+ ICsgICAgICAgICogQnV0IHRoZSBQVEUgdXBkYXRlIGFuZCBzdWJzZXF1ZW50IG1pZ3JhdGlvbiBv cGVyYXRpb24gbXVzdCBiZSBhdG9taWMsCj4gKyAgICAgICAgKiBpLmUuIHdpdGhpbiB0aGUgc2Ft ZSBub24tcHJlZW1wdGlibGUgd2luZG93IHNvIHRoYXQgd2UgZG8gbm90IHN3aXRjaAo+ICsgICAg ICAgICogdG8gYW5vdGhlciBtaWdyYXRpb24gY29udGV4dCB0aGF0IG92ZXJ3cml0ZXMgdGhlIFBU RS4KPiArICAgICAgICAqLwo+ICsKPiArICAgICAgIHZtID0gaTkxNV9wcGd0dF9jcmVhdGUoZ3Qp Owo+ICsgICAgICAgaWYgKElTX0VSUih2bSkpCj4gKyAgICAgICAgICAgICAgIHJldHVybiBFUlJf Q0FTVCh2bSk7Cj4gKwo+ICsgICAgICAgaWYgKCF2bS0+dm0uYWxsb2NhdGVfdmFfcmFuZ2UgfHwg IXZtLT52bS5mb3JlYWNoKSB7Cj4gKyAgICAgICAgICAgICAgIGVyciA9IC1FTk9ERVY7Cj4gKyAg ICAgICAgICAgICAgIGdvdG8gZXJyX3ZtOwo+ICsgICAgICAgfQo+ICsKPiArICAgICAgIC8qCj4g KyAgICAgICAgKiBFYWNoIGVuZ2luZSBpbnN0YW5jZSBpcyBhc3NpZ25lZCBpdHMgb3duIGNodW5r IGluIHRoZSBWTSwgc28KPiArICAgICAgICAqIHRoYXQgd2UgY2FuIHJ1biBtdWx0aXBsZSBpbnN0 YW5jZXMgY29uY3VycmVudGx5Cj4gKyAgICAgICAgKi8KPiArICAgICAgIGZvciAoaSA9IDA7IGkg PCBBUlJBWV9TSVpFKGd0LT5lbmdpbmVfY2xhc3NbQ09QWV9FTkdJTkVfQ0xBU1NdKTsgaSsrKSB7 Cj4gKyAgICAgICAgICAgICAgIHN0cnVjdCBpbnRlbF9lbmdpbmVfY3MgKmVuZ2luZTsKPiArICAg ICAgICAgICAgICAgdTY0IGJhc2UgPSAodTY0KWkgPDwgMzI7Cj4gKyAgICAgICAgICAgICAgIHN0 cnVjdCBpbnNlcnRfcHRlX2RhdGEgZCA9IHt9Owo+ICsgICAgICAgICAgICAgICBzdHJ1Y3QgaTkx NV9nZW1fd3dfY3R4IHd3Owo+ICsgICAgICAgICAgICAgICB1NjQgc3o7Cj4gKwo+ICsgICAgICAg ICAgICAgICBlbmdpbmUgPSBndC0+ZW5naW5lX2NsYXNzW0NPUFlfRU5HSU5FX0NMQVNTXVtpXTsK PiArICAgICAgICAgICAgICAgaWYgKCFlbmdpbmVfc3VwcG9ydHNfbWlncmF0aW9uKGVuZ2luZSkp Cj4gKyAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7Cj4gKwo+ICsgICAgICAgICAgICAg ICAvKgo+ICsgICAgICAgICAgICAgICAgKiBXZSBjb3B5IGluIDhNaUIgY2h1bmtzLiBFYWNoIFBE RSBjb3ZlcnMgMk1pQiwgc28gd2UgbmVlZAo+ICsgICAgICAgICAgICAgICAgKiA0eDIgcGFnZSBk aXJlY3RvcmllcyBmb3Igc291cmNlL2Rlc3RpbmF0aW9uLgo+ICsgICAgICAgICAgICAgICAgKi8K PiArICAgICAgICAgICAgICAgc3ogPSAyICogQ0hVTktfU1o7Cj4gKyAgICAgICAgICAgICAgIGQu b2Zmc2V0ID0gYmFzZSArIHN6Owo+ICsKPiArICAgICAgICAgICAgICAgLyoKPiArICAgICAgICAg ICAgICAgICogV2UgbmVlZCBhbm90aGVyIHBhZ2UgZGlyZWN0b3J5IHNldHVwIHNvIHRoYXQgd2Ug Y2FuIHdyaXRlCj4gKyAgICAgICAgICAgICAgICAqIHRoZSA4eDUxMiBQVEUgaW4gZWFjaCBjaHVu ay4KPiArICAgICAgICAgICAgICAgICovCj4gKyAgICAgICAgICAgICAgIHN6ICs9IChzeiA+PiAx MikgKiBzaXplb2YodTY0KTsKPiArCj4gKyAgICAgICAgICAgICAgIGVyciA9IGk5MTVfdm1fYWxs b2NfcHRfc3Rhc2goJnZtLT52bSwgJnN0YXNoLCBzeik7Cj4gKyAgICAgICAgICAgICAgIGlmIChl cnIpCj4gKyAgICAgICAgICAgICAgICAgICAgICAgZ290byBlcnJfdm07Cj4gKwo+ICsgICAgICAg ICAgICAgICBmb3JfaTkxNV9nZW1fd3coJnd3LCBlcnIsIHRydWUpIHsKPiArICAgICAgICAgICAg ICAgICAgICAgICBlcnIgPSBpOTE1X3ZtX2xvY2tfb2JqZWN0cygmdm0tPnZtLCAmd3cpOwo+ICsg ICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnIpCj4gKyAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICBjb250aW51ZTsKPiArICAgICAgICAgICAgICAgICAgICAgICBlcnIgPSBpOTE1X3Zt X21hcF9wdF9zdGFzaCgmdm0tPnZtLCAmc3Rhc2gpOwo+ICsgICAgICAgICAgICAgICAgICAgICAg IGlmIChlcnIpCj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKPiAr Cj4gKyAgICAgICAgICAgICAgICAgICAgICAgdm0tPnZtLmFsbG9jYXRlX3ZhX3JhbmdlKCZ2bS0+ dm0sICZzdGFzaCwgYmFzZSwgYmFzZSArIHN6KTsKPiArICAgICAgICAgICAgICAgfQo+ICsgICAg ICAgICAgICAgICBpOTE1X3ZtX2ZyZWVfcHRfc3Rhc2goJnZtLT52bSwgJnN0YXNoKTsKPiArICAg ICAgICAgICAgICAgaWYgKGVycikKPiArICAgICAgICAgICAgICAgICAgICAgICBnb3RvIGVycl92 bTsKPiArCj4gKyAgICAgICAgICAgICAgIC8qIE5vdyBhbGxvdyB0aGUgR1BVIHRvIHJld3JpdGUg dGhlIFBURSB2aWEgaXRzIG93biBwcEdUVCAqLwo+ICsgICAgICAgICAgICAgICBkLmlzX2xtZW0g PSBpOTE1X2dlbV9vYmplY3RfaXNfbG1lbSh2bS0+dm0uc2NyYXRjaFswXSk7Cj4gKyAgICAgICAg ICAgICAgIHZtLT52bS5mb3JlYWNoKCZ2bS0+dm0sIGJhc2UsIGJhc2UgKyBzeiwgaW5zZXJ0X3B0 ZSwgJmQpOwoKV2lsbCB0aGlzIHBsYXkgbmljZSB3aXRoIFhlIEhQIHdoZXJlIHdlIGhhdmUgbWlu IHBhZ2Ugc2l6ZQpyZXN0cmljdGlvbnMgZm9yIHRoZSBHVFQgKyBsbWVtPyBUaGUgcGFnZS10YWJs ZSBhbGxvY2F0aW9ucyBzaWRlc3RlcApzdWNoIHJlc3RyaWN0aW9ucyBzaW5jZSB0aGV5IHdlcmUg cHJldmlvdXNseSBuZXZlciBpbnNlcnRlZCBpbnRvIHRoZQpHVFQuIE1heWJlIHdlIG5lZWQgdGhl IGZsYXQtcHBHVFQgYXQgc29tZSBwb2ludD8gUGVyaGFwcyBhZGQgYSBUT0RPIG9yCnNvbWV0aGlu Zz8KX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KSW50ZWwt Z2Z4IG1haWxpbmcgbGlzdApJbnRlbC1nZnhAbGlzdHMuZnJlZWRlc2t0b3Aub3JnCmh0dHBzOi8v bGlzdHMuZnJlZWRlc2t0b3Aub3JnL21haWxtYW4vbGlzdGluZm8vaW50ZWwtZ2Z4Cg==