From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 49689144609; Fri, 2 Feb 2024 14:56:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706885794; cv=none; b=lyyX3SWnNTZ9U598dq0yLSt4kPCqOYoErMAKkyc2uOgKWEFsrtj7VKINsZ9kgoe1Mc9qExiprCXpOP2YrKyrDkt8gLnB/Ck4kKcrEw8iwGn669CwDy24JrkFLU2DNFbN2OhRx71+VoYsHtPmcnYPTmpDiC3lVePZtUcoJdVgkN0= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706885794; c=relaxed/simple; bh=SJlQhmb5tC5daGZOVHcT81vuW/W+IrMxxcibXDyUhBs=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=QR8XL0ePbEt0kc9ktuETt/be4QtnQtjDU9ZOaz+kNX+JkG0qKLH8pp8EdeknFzQdx+D3/aLNttjhUOnetTeq5A0XQH5UErw/8rG3G//iq7EaarMZSbytyHdCIVxNJSfurkDSVVmFPhNXRHBrpdX0ZkolGJBfnVwNNhQpiyUv4js= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id E78D3DA7; Fri, 2 Feb 2024 06:57:13 -0800 (PST) Received: from raptor (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 6FB8B3F5A1; Fri, 2 Feb 2024 06:56:26 -0800 (PST) Date: Fri, 2 Feb 2024 14:56:15 +0000 From: Alexandru Elisei To: Peter Collingbourne Cc: catalin.marinas@arm.com, will@kernel.org, oliver.upton@linux.dev, maz@kernel.org, james.morse@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com, arnd@arndb.de, akpm@linux-foundation.org, mingo@redhat.com, peterz@infradead.org, juri.lelli@redhat.com, vincent.guittot@linaro.org, dietmar.eggemann@arm.com, rostedt@goodmis.org, bsegall@google.com, mgorman@suse.de, bristot@redhat.com, vschneid@redhat.com, mhiramat@kernel.org, rppt@kernel.org, hughd@google.com, steven.price@arm.com, anshuman.khandual@arm.com, vincenzo.frascino@arm.com, david@redhat.com, eugenis@google.com, kcc@google.com, hyesoo.yu@samsung.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, kvmarm@lists.linux.dev, linux-fsdevel@vger.kernel.org, linux-arch@vger.kernel.org, linux-mm@kvack.org, linux-trace-kernel@vger.kernel.org Subject: Re: [PATCH RFC v3 28/35] arm64: mte: swap: Handle tag restoring when missing tag storage Message-ID: References: <20240125164256.4147-1-alexandru.elisei@arm.com> <20240125164256.4147-29-alexandru.elisei@arm.com> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: Hi Peter, On Thu, Feb 01, 2024 at 08:02:40PM -0800, Peter Collingbourne wrote: > On Thu, Jan 25, 2024 at 8:45 AM Alexandru Elisei > wrote: > > > > Linux restores tags when a page is swapped in and there are tags associated > > with the swap entry which the new page will replace. The saved tags are > > restored even if the page will not be mapped as tagged, to protect against > > cases where the page is shared between different VMAs, and is tagged in > > some, but untagged in others. By using this approach, the process can still > > access the correct tags following an mprotect(PROT_MTE) on the non-MTE > > enabled VMA. > > > > But this poses a challenge for managing tag storage: in the scenario above, > > when a new page is allocated to be swapped in for the process where it will > > be mapped as untagged, the corresponding tag storage block is not reserved. > > mte_restore_page_tags_by_swp_entry(), when it restores the saved tags, will > > overwrite data in the tag storage block associated with the new page, > > leading to data corruption if the block is in use by a process. > > > > Get around this issue by saving the tags in a new xarray, this time indexed > > by the page pfn, and then restoring them when tag storage is reserved for > > the page. > > > > Signed-off-by: Alexandru Elisei > > --- > > > > Changes since rfc v2: > > > > * Restore saved tags **before** setting the PG_tag_storage_reserved bit to > > eliminate a brief window of opportunity where userspace can access uninitialized > > tags (Peter Collingbourne). > > > > arch/arm64/include/asm/mte_tag_storage.h | 8 ++ > > arch/arm64/include/asm/pgtable.h | 11 +++ > > arch/arm64/kernel/mte_tag_storage.c | 12 ++- > > arch/arm64/mm/mteswap.c | 110 +++++++++++++++++++++++ > > 4 files changed, 140 insertions(+), 1 deletion(-) > > > > diff --git a/arch/arm64/include/asm/mte_tag_storage.h b/arch/arm64/include/asm/mte_tag_storage.h > > index 50bdae94cf71..40590a8c3748 100644 > > --- a/arch/arm64/include/asm/mte_tag_storage.h > > +++ b/arch/arm64/include/asm/mte_tag_storage.h > > @@ -36,6 +36,14 @@ bool page_is_tag_storage(struct page *page); > > > > vm_fault_t handle_folio_missing_tag_storage(struct folio *folio, struct vm_fault *vmf, > > bool *map_pte); > > +vm_fault_t mte_try_transfer_swap_tags(swp_entry_t entry, struct page *page); > > + > > +void tags_by_pfn_lock(void); > > +void tags_by_pfn_unlock(void); > > + > > +void *mte_erase_tags_for_pfn(unsigned long pfn); > > +bool mte_save_tags_for_pfn(void *tags, unsigned long pfn); > > +void mte_restore_tags_for_pfn(unsigned long start_pfn, int order); > > #else > > static inline bool tag_storage_enabled(void) > > { > > diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h > > index 0174e292f890..87ae59436162 100644 > > --- a/arch/arm64/include/asm/pgtable.h > > +++ b/arch/arm64/include/asm/pgtable.h > > @@ -1085,6 +1085,17 @@ static inline void arch_swap_invalidate_area(int type) > > mte_invalidate_tags_area_by_swp_entry(type); > > } > > > > +#ifdef CONFIG_ARM64_MTE_TAG_STORAGE > > +#define __HAVE_ARCH_SWAP_PREPARE_TO_RESTORE > > +static inline vm_fault_t arch_swap_prepare_to_restore(swp_entry_t entry, > > + struct folio *folio) > > +{ > > + if (tag_storage_enabled()) > > + return mte_try_transfer_swap_tags(entry, &folio->page); > > + return 0; > > +} > > +#endif > > + > > #define __HAVE_ARCH_SWAP_RESTORE > > static inline void arch_swap_restore(swp_entry_t entry, struct folio *folio) > > { > > diff --git a/arch/arm64/kernel/mte_tag_storage.c b/arch/arm64/kernel/mte_tag_storage.c > > index afe2bb754879..ac7b9c9c585c 100644 > > --- a/arch/arm64/kernel/mte_tag_storage.c > > +++ b/arch/arm64/kernel/mte_tag_storage.c > > @@ -567,6 +567,7 @@ int reserve_tag_storage(struct page *page, int order, gfp_t gfp) > > } > > } > > > > + mte_restore_tags_for_pfn(page_to_pfn(page), order); > > page_set_tag_storage_reserved(page, order); > > out_unlock: > > mutex_unlock(&tag_blocks_lock); > > @@ -595,7 +596,8 @@ void free_tag_storage(struct page *page, int order) > > struct tag_region *region; > > unsigned long page_va; > > unsigned long flags; > > - int ret; > > + void *tags; > > + int i, ret; > > > > ret = tag_storage_find_block(page, &start_block, ®ion); > > if (WARN_ONCE(ret, "Missing tag storage block for pfn 0x%lx", page_to_pfn(page))) > > @@ -605,6 +607,14 @@ void free_tag_storage(struct page *page, int order) > > /* Avoid writeback of dirty tag cache lines corrupting data. */ > > dcache_inval_tags_poc(page_va, page_va + (PAGE_SIZE << order)); > > > > + tags_by_pfn_lock(); > > + for (i = 0; i < (1 << order); i++) { > > + tags = mte_erase_tags_for_pfn(page_to_pfn(page + i)); > > + if (unlikely(tags)) > > + mte_free_tag_buf(tags); > > + } > > + tags_by_pfn_unlock(); > > + > > end_block = start_block + order_to_num_blocks(order, region->block_size_pages); > > > > xa_lock_irqsave(&tag_blocks_reserved, flags); > > diff --git a/arch/arm64/mm/mteswap.c b/arch/arm64/mm/mteswap.c > > index 2a43746b803f..e11495fa3c18 100644 > > --- a/arch/arm64/mm/mteswap.c > > +++ b/arch/arm64/mm/mteswap.c > > @@ -20,6 +20,112 @@ void mte_free_tag_buf(void *buf) > > kfree(buf); > > } > > > > +#ifdef CONFIG_ARM64_MTE_TAG_STORAGE > > +static DEFINE_XARRAY(tags_by_pfn); > > + > > +void tags_by_pfn_lock(void) > > +{ > > + xa_lock(&tags_by_pfn); > > +} > > + > > +void tags_by_pfn_unlock(void) > > +{ > > + xa_unlock(&tags_by_pfn); > > +} > > + > > +void *mte_erase_tags_for_pfn(unsigned long pfn) > > +{ > > + return __xa_erase(&tags_by_pfn, pfn); > > +} > > + > > +bool mte_save_tags_for_pfn(void *tags, unsigned long pfn) > > +{ > > + void *entry; > > + int ret; > > + > > + ret = xa_reserve(&tags_by_pfn, pfn, GFP_KERNEL); > > copy_highpage can be called from an atomic context, so it isn't > currently valid to pass GFP_KERNEL here. > > To give one example of a possible atomic context call, copy_pte_range > will take a PTE spinlock and can call copy_present_pte, which can call > copy_present_page, which will call copy_user_highpage. > > To give another example, __buffer_migrate_folio can call > spin_lock(&mapping->private_lock), then call folio_migrate_copy, which > will call folio_copy. That is very unfortunate from my part. I distinctly remember looking precisely at copy_page_range() to double check that it doesn't call copy_*highpage() from an atomic context, I can only assume that I missed that it's called with the ptl lock held. With your two examples, and the khugepaged case in patch #31 ("khugepaged: arm64: Don't collapse MTE enabled VMAs"), it's crystal clear that the convention for copy_*highpage() is that the function cannot sleep. There are two issues here: allocating the buffer in memory where the tags will be copied, and xarray allocating memory for a new entry. One fix would be to allocate an entire page with __GFP_ATOMIC, and use that as a cache for tag buffers (storing the tags for a page uses 1/32th of a page). From what little I know about xarray, xarray stores would still have to be GFP_ATOMIC. This should fix the sleeping in atomic context bug. But the issue I see with this is that a memory allocation can fail, while copy_*highpage() cannot. Send a fatal signal to the process if memory allocation fails? Another approach would be to preallocate memory in a preemptible context, something like copy_*highpage_prepare(), but that would mean a lot more work: finding all the places where copy_*highpage is used and add copy_*highpage_prepare() outside the critical section, releasing the memory in case of failure (like in the copy_pte_range() case - maybe copy_*highpage_end()?). That's a pretty big maintenance burden for the MM code. Although maybe other architectures can find a use for it? And yet another approach is reserve the needed memory (for the buffer and in the xarray) when the page is allocated, if it doesn't have tag storage reserved, regardless of the page being allocated as tagged or not. Then in set_pte_at() free this memory if it's unused. But this would mean reserving memory for possibly all memory allocations in the system (including for tag storage pages) if userspace doesn't use tags at all, though not all pages in the system will have this memory reserved at the same time. Pretty big downside. Out of the three, I prefer the first, but it's definitely not perfect. I'll try to think of something else, maybe I can come up with something better. What are your thoughts? Thanks, Alex > > Peter > > > + if (ret) > > + return true; > > + > > + tags_by_pfn_lock(); > > + > > + if (page_tag_storage_reserved(pfn_to_page(pfn))) { > > + xa_release(&tags_by_pfn, pfn); > > + tags_by_pfn_unlock(); > > + return false; > > + } > > + > > + entry = __xa_store(&tags_by_pfn, pfn, tags, GFP_ATOMIC); > > + if (xa_is_err(entry)) { > > + xa_release(&tags_by_pfn, pfn); > > + goto out_unlock; > > + } else if (entry) { > > + mte_free_tag_buf(entry); > > + } > > + > > +out_unlock: > > + tags_by_pfn_unlock(); > > + return true; > > +} > > + > > +void mte_restore_tags_for_pfn(unsigned long start_pfn, int order) > > +{ > > + struct page *page = pfn_to_page(start_pfn); > > + unsigned long pfn; > > + void *tags; > > + > > + tags_by_pfn_lock(); > > + > > + for (pfn = start_pfn; pfn < start_pfn + (1 << order); pfn++, page++) { > > + tags = mte_erase_tags_for_pfn(pfn); > > + if (unlikely(tags)) { > > + /* > > + * Mark the page as tagged so mte_sync_tags() doesn't > > + * clear the tags. > > + */ > > + WARN_ON_ONCE(!try_page_mte_tagging(page)); > > + mte_copy_page_tags_from_buf(page_address(page), tags); > > + set_page_mte_tagged(page); > > + mte_free_tag_buf(tags); > > + } > > + } > > + > > + tags_by_pfn_unlock(); > > +} > > + > > +/* > > + * Note on locking: swap in/out is done with the folio locked, which eliminates > > + * races with mte_save/restore_page_tags_by_swp_entry. > > + */ > > +vm_fault_t mte_try_transfer_swap_tags(swp_entry_t entry, struct page *page) > > +{ > > + void *swap_tags, *pfn_tags; > > + bool saved; > > + > > + /* > > + * mte_restore_page_tags_by_swp_entry() will take care of copying the > > + * tags over. > > + */ > > + if (likely(page_mte_tagged(page) || page_tag_storage_reserved(page))) > > + return 0; > > + > > + swap_tags = xa_load(&tags_by_swp_entry, entry.val); > > + if (!swap_tags) > > + return 0; > > + > > + pfn_tags = mte_allocate_tag_buf(); > > + if (!pfn_tags) > > + return VM_FAULT_OOM; > > + > > + memcpy(pfn_tags, swap_tags, MTE_PAGE_TAG_STORAGE_SIZE); > > + saved = mte_save_tags_for_pfn(pfn_tags, page_to_pfn(page)); > > + if (!saved) > > + mte_free_tag_buf(pfn_tags); > > + > > + return 0; > > +} > > +#endif > > + > > int mte_save_page_tags_by_swp_entry(struct page *page) > > { > > void *tags, *ret; > > @@ -54,6 +160,10 @@ void mte_restore_page_tags_by_swp_entry(swp_entry_t entry, struct page *page) > > if (!tags) > > return; > > > > + /* Tags will be restored when tag storage is reserved. */ > > + if (tag_storage_enabled() && unlikely(!page_tag_storage_reserved(page))) > > + return; > > + > > if (try_page_mte_tagging(page)) { > > mte_copy_page_tags_from_buf(page_address(page), tags); > > set_page_mte_tagged(page); > > -- > > 2.43.0 > > 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 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 428CDC47DB3 for ; Fri, 2 Feb 2024 14:56:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:References: Message-ID:Subject:Cc:To:From:Date:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=+qZXX1PkJa9XMB1hYDF6CC4b3a/3nj94GcdniTDxfsQ=; b=a2vZibwlYiCxx8 dsQZFz8JaFklXHtDJAfG0WXJO4/sC42mGIDZRpjW5p6tS7rqu9kGdvOVSjVnVRKGEZZ5j3ksrpHzS QzVIvU1ArGZb2sUoDC5+SSU4xL9QOTgvG69zPClwLedp5EAZ+kr/FuVjEy+7vFge4oSUxcvfAeusr i28r4E7Of2q3sDrol1HjZtpKU9/fk9GVebCQP9H8WnZnhygih4mENdcDZecrFd9nY8xTN3oP5bLKr mJaFMwPshrGp56++K2Uf6WQEn+bJXzC60dvuYuwSZjRvxyA3qCwXGiUYgmL2DrZcrcl5YberwesSZ NOIRe5inMXL3EvKfZ06w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1rVuy8-0000000BreJ-0b1p; Fri, 02 Feb 2024 14:56:40 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1rVuy4-0000000BrbL-2nfN for linux-arm-kernel@lists.infradead.org; Fri, 02 Feb 2024 14:56:38 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id E78D3DA7; Fri, 2 Feb 2024 06:57:13 -0800 (PST) Received: from raptor (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 6FB8B3F5A1; Fri, 2 Feb 2024 06:56:26 -0800 (PST) Date: Fri, 2 Feb 2024 14:56:15 +0000 From: Alexandru Elisei To: Peter Collingbourne Cc: catalin.marinas@arm.com, will@kernel.org, oliver.upton@linux.dev, maz@kernel.org, james.morse@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com, arnd@arndb.de, akpm@linux-foundation.org, mingo@redhat.com, peterz@infradead.org, juri.lelli@redhat.com, vincent.guittot@linaro.org, dietmar.eggemann@arm.com, rostedt@goodmis.org, bsegall@google.com, mgorman@suse.de, bristot@redhat.com, vschneid@redhat.com, mhiramat@kernel.org, rppt@kernel.org, hughd@google.com, steven.price@arm.com, anshuman.khandual@arm.com, vincenzo.frascino@arm.com, david@redhat.com, eugenis@google.com, kcc@google.com, hyesoo.yu@samsung.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, kvmarm@lists.linux.dev, linux-fsdevel@vger.kernel.org, linux-arch@vger.kernel.org, linux-mm@kvack.org, linux-trace-kernel@vger.kernel.org Subject: Re: [PATCH RFC v3 28/35] arm64: mte: swap: Handle tag restoring when missing tag storage Message-ID: References: <20240125164256.4147-1-alexandru.elisei@arm.com> <20240125164256.4147-29-alexandru.elisei@arm.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240202_065636_989436_E8CBDBE3 X-CRM114-Status: GOOD ( 53.84 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org SGkgUGV0ZXIsCgpPbiBUaHUsIEZlYiAwMSwgMjAyNCBhdCAwODowMjo0MFBNIC0wODAwLCBQZXRl ciBDb2xsaW5nYm91cm5lIHdyb3RlOgo+IE9uIFRodSwgSmFuIDI1LCAyMDI0IGF0IDg6NDXigK9B TSBBbGV4YW5kcnUgRWxpc2VpCj4gPGFsZXhhbmRydS5lbGlzZWlAYXJtLmNvbT4gd3JvdGU6Cj4g Pgo+ID4gTGludXggcmVzdG9yZXMgdGFncyB3aGVuIGEgcGFnZSBpcyBzd2FwcGVkIGluIGFuZCB0 aGVyZSBhcmUgdGFncyBhc3NvY2lhdGVkCj4gPiB3aXRoIHRoZSBzd2FwIGVudHJ5IHdoaWNoIHRo ZSBuZXcgcGFnZSB3aWxsIHJlcGxhY2UuIFRoZSBzYXZlZCB0YWdzIGFyZQo+ID4gcmVzdG9yZWQg ZXZlbiBpZiB0aGUgcGFnZSB3aWxsIG5vdCBiZSBtYXBwZWQgYXMgdGFnZ2VkLCB0byBwcm90ZWN0 IGFnYWluc3QKPiA+IGNhc2VzIHdoZXJlIHRoZSBwYWdlIGlzIHNoYXJlZCBiZXR3ZWVuIGRpZmZl cmVudCBWTUFzLCBhbmQgaXMgdGFnZ2VkIGluCj4gPiBzb21lLCBidXQgdW50YWdnZWQgaW4gb3Ro ZXJzLiBCeSB1c2luZyB0aGlzIGFwcHJvYWNoLCB0aGUgcHJvY2VzcyBjYW4gc3RpbGwKPiA+IGFj Y2VzcyB0aGUgY29ycmVjdCB0YWdzIGZvbGxvd2luZyBhbiBtcHJvdGVjdChQUk9UX01URSkgb24g dGhlIG5vbi1NVEUKPiA+IGVuYWJsZWQgVk1BLgo+ID4KPiA+IEJ1dCB0aGlzIHBvc2VzIGEgY2hh bGxlbmdlIGZvciBtYW5hZ2luZyB0YWcgc3RvcmFnZTogaW4gdGhlIHNjZW5hcmlvIGFib3ZlLAo+ ID4gd2hlbiBhIG5ldyBwYWdlIGlzIGFsbG9jYXRlZCB0byBiZSBzd2FwcGVkIGluIGZvciB0aGUg cHJvY2VzcyB3aGVyZSBpdCB3aWxsCj4gPiBiZSBtYXBwZWQgYXMgdW50YWdnZWQsIHRoZSBjb3Jy ZXNwb25kaW5nIHRhZyBzdG9yYWdlIGJsb2NrIGlzIG5vdCByZXNlcnZlZC4KPiA+IG10ZV9yZXN0 b3JlX3BhZ2VfdGFnc19ieV9zd3BfZW50cnkoKSwgd2hlbiBpdCByZXN0b3JlcyB0aGUgc2F2ZWQg dGFncywgd2lsbAo+ID4gb3ZlcndyaXRlIGRhdGEgaW4gdGhlIHRhZyBzdG9yYWdlIGJsb2NrIGFz c29jaWF0ZWQgd2l0aCB0aGUgbmV3IHBhZ2UsCj4gPiBsZWFkaW5nIHRvIGRhdGEgY29ycnVwdGlv biBpZiB0aGUgYmxvY2sgaXMgaW4gdXNlIGJ5IGEgcHJvY2Vzcy4KPiA+Cj4gPiBHZXQgYXJvdW5k IHRoaXMgaXNzdWUgYnkgc2F2aW5nIHRoZSB0YWdzIGluIGEgbmV3IHhhcnJheSwgdGhpcyB0aW1l IGluZGV4ZWQKPiA+IGJ5IHRoZSBwYWdlIHBmbiwgYW5kIHRoZW4gcmVzdG9yaW5nIHRoZW0gd2hl biB0YWcgc3RvcmFnZSBpcyByZXNlcnZlZCBmb3IKPiA+IHRoZSBwYWdlLgo+ID4KPiA+IFNpZ25l ZC1vZmYtYnk6IEFsZXhhbmRydSBFbGlzZWkgPGFsZXhhbmRydS5lbGlzZWlAYXJtLmNvbT4KPiA+ IC0tLQo+ID4KPiA+IENoYW5nZXMgc2luY2UgcmZjIHYyOgo+ID4KPiA+ICogUmVzdG9yZSBzYXZl ZCB0YWdzICoqYmVmb3JlKiogc2V0dGluZyB0aGUgUEdfdGFnX3N0b3JhZ2VfcmVzZXJ2ZWQgYml0 IHRvCj4gPiBlbGltaW5hdGUgYSBicmllZiB3aW5kb3cgb2Ygb3Bwb3J0dW5pdHkgd2hlcmUgdXNl cnNwYWNlIGNhbiBhY2Nlc3MgdW5pbml0aWFsaXplZAo+ID4gdGFncyAoUGV0ZXIgQ29sbGluZ2Jv dXJuZSkuCj4gPgo+ID4gIGFyY2gvYXJtNjQvaW5jbHVkZS9hc20vbXRlX3RhZ19zdG9yYWdlLmgg fCAgIDggKysKPiA+ICBhcmNoL2FybTY0L2luY2x1ZGUvYXNtL3BndGFibGUuaCAgICAgICAgIHwg IDExICsrKwo+ID4gIGFyY2gvYXJtNjQva2VybmVsL210ZV90YWdfc3RvcmFnZS5jICAgICAgfCAg MTIgKystCj4gPiAgYXJjaC9hcm02NC9tbS9tdGVzd2FwLmMgICAgICAgICAgICAgICAgICB8IDEx MCArKysrKysrKysrKysrKysrKysrKysrKwo+ID4gIDQgZmlsZXMgY2hhbmdlZCwgMTQwIGluc2Vy dGlvbnMoKyksIDEgZGVsZXRpb24oLSkKPiA+Cj4gPiBkaWZmIC0tZ2l0IGEvYXJjaC9hcm02NC9p bmNsdWRlL2FzbS9tdGVfdGFnX3N0b3JhZ2UuaCBiL2FyY2gvYXJtNjQvaW5jbHVkZS9hc20vbXRl X3RhZ19zdG9yYWdlLmgKPiA+IGluZGV4IDUwYmRhZTk0Y2Y3MS4uNDA1OTBhOGMzNzQ4IDEwMDY0 NAo+ID4gLS0tIGEvYXJjaC9hcm02NC9pbmNsdWRlL2FzbS9tdGVfdGFnX3N0b3JhZ2UuaAo+ID4g KysrIGIvYXJjaC9hcm02NC9pbmNsdWRlL2FzbS9tdGVfdGFnX3N0b3JhZ2UuaAo+ID4gQEAgLTM2 LDYgKzM2LDE0IEBAIGJvb2wgcGFnZV9pc190YWdfc3RvcmFnZShzdHJ1Y3QgcGFnZSAqcGFnZSk7 Cj4gPgo+ID4gIHZtX2ZhdWx0X3QgaGFuZGxlX2ZvbGlvX21pc3NpbmdfdGFnX3N0b3JhZ2Uoc3Ry dWN0IGZvbGlvICpmb2xpbywgc3RydWN0IHZtX2ZhdWx0ICp2bWYsCj4gPiAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgKm1hcF9wdGUpOwo+ID4gK3ZtX2Zh dWx0X3QgbXRlX3RyeV90cmFuc2Zlcl9zd2FwX3RhZ3Moc3dwX2VudHJ5X3QgZW50cnksIHN0cnVj dCBwYWdlICpwYWdlKTsKPiA+ICsKPiA+ICt2b2lkIHRhZ3NfYnlfcGZuX2xvY2sodm9pZCk7Cj4g PiArdm9pZCB0YWdzX2J5X3Bmbl91bmxvY2sodm9pZCk7Cj4gPiArCj4gPiArdm9pZCAqbXRlX2Vy YXNlX3RhZ3NfZm9yX3Bmbih1bnNpZ25lZCBsb25nIHBmbik7Cj4gPiArYm9vbCBtdGVfc2F2ZV90 YWdzX2Zvcl9wZm4odm9pZCAqdGFncywgdW5zaWduZWQgbG9uZyBwZm4pOwo+ID4gK3ZvaWQgbXRl X3Jlc3RvcmVfdGFnc19mb3JfcGZuKHVuc2lnbmVkIGxvbmcgc3RhcnRfcGZuLCBpbnQgb3JkZXIp Owo+ID4gICNlbHNlCj4gPiAgc3RhdGljIGlubGluZSBib29sIHRhZ19zdG9yYWdlX2VuYWJsZWQo dm9pZCkKPiA+ICB7Cj4gPiBkaWZmIC0tZ2l0IGEvYXJjaC9hcm02NC9pbmNsdWRlL2FzbS9wZ3Rh YmxlLmggYi9hcmNoL2FybTY0L2luY2x1ZGUvYXNtL3BndGFibGUuaAo+ID4gaW5kZXggMDE3NGUy OTJmODkwLi44N2FlNTk0MzYxNjIgMTAwNjQ0Cj4gPiAtLS0gYS9hcmNoL2FybTY0L2luY2x1ZGUv YXNtL3BndGFibGUuaAo+ID4gKysrIGIvYXJjaC9hcm02NC9pbmNsdWRlL2FzbS9wZ3RhYmxlLmgK PiA+IEBAIC0xMDg1LDYgKzEwODUsMTcgQEAgc3RhdGljIGlubGluZSB2b2lkIGFyY2hfc3dhcF9p bnZhbGlkYXRlX2FyZWEoaW50IHR5cGUpCj4gPiAgICAgICAgICAgICAgICAgbXRlX2ludmFsaWRh dGVfdGFnc19hcmVhX2J5X3N3cF9lbnRyeSh0eXBlKTsKPiA+ICB9Cj4gPgo+ID4gKyNpZmRlZiBD T05GSUdfQVJNNjRfTVRFX1RBR19TVE9SQUdFCj4gPiArI2RlZmluZSBfX0hBVkVfQVJDSF9TV0FQ X1BSRVBBUkVfVE9fUkVTVE9SRQo+ID4gK3N0YXRpYyBpbmxpbmUgdm1fZmF1bHRfdCBhcmNoX3N3 YXBfcHJlcGFyZV90b19yZXN0b3JlKHN3cF9lbnRyeV90IGVudHJ5LAo+ID4gKyAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IGZvbGlvICpm b2xpbykKPiA+ICt7Cj4gPiArICAgICAgIGlmICh0YWdfc3RvcmFnZV9lbmFibGVkKCkpCj4gPiAr ICAgICAgICAgICAgICAgcmV0dXJuIG10ZV90cnlfdHJhbnNmZXJfc3dhcF90YWdzKGVudHJ5LCAm Zm9saW8tPnBhZ2UpOwo+ID4gKyAgICAgICByZXR1cm4gMDsKPiA+ICt9Cj4gPiArI2VuZGlmCj4g PiArCj4gPiAgI2RlZmluZSBfX0hBVkVfQVJDSF9TV0FQX1JFU1RPUkUKPiA+ICBzdGF0aWMgaW5s aW5lIHZvaWQgYXJjaF9zd2FwX3Jlc3RvcmUoc3dwX2VudHJ5X3QgZW50cnksIHN0cnVjdCBmb2xp byAqZm9saW8pCj4gPiAgewo+ID4gZGlmZiAtLWdpdCBhL2FyY2gvYXJtNjQva2VybmVsL210ZV90 YWdfc3RvcmFnZS5jIGIvYXJjaC9hcm02NC9rZXJuZWwvbXRlX3RhZ19zdG9yYWdlLmMKPiA+IGlu ZGV4IGFmZTJiYjc1NDg3OS4uYWM3YjljOWM1ODVjIDEwMDY0NAo+ID4gLS0tIGEvYXJjaC9hcm02 NC9rZXJuZWwvbXRlX3RhZ19zdG9yYWdlLmMKPiA+ICsrKyBiL2FyY2gvYXJtNjQva2VybmVsL210 ZV90YWdfc3RvcmFnZS5jCj4gPiBAQCAtNTY3LDYgKzU2Nyw3IEBAIGludCByZXNlcnZlX3RhZ19z dG9yYWdlKHN0cnVjdCBwYWdlICpwYWdlLCBpbnQgb3JkZXIsIGdmcF90IGdmcCkKPiA+ICAgICAg ICAgICAgICAgICB9Cj4gPiAgICAgICAgIH0KPiA+Cj4gPiArICAgICAgIG10ZV9yZXN0b3JlX3Rh Z3NfZm9yX3BmbihwYWdlX3RvX3BmbihwYWdlKSwgb3JkZXIpOwo+ID4gICAgICAgICBwYWdlX3Nl dF90YWdfc3RvcmFnZV9yZXNlcnZlZChwYWdlLCBvcmRlcik7Cj4gPiAgb3V0X3VubG9jazoKPiA+ ICAgICAgICAgbXV0ZXhfdW5sb2NrKCZ0YWdfYmxvY2tzX2xvY2spOwo+ID4gQEAgLTU5NSw3ICs1 OTYsOCBAQCB2b2lkIGZyZWVfdGFnX3N0b3JhZ2Uoc3RydWN0IHBhZ2UgKnBhZ2UsIGludCBvcmRl cikKPiA+ICAgICAgICAgc3RydWN0IHRhZ19yZWdpb24gKnJlZ2lvbjsKPiA+ICAgICAgICAgdW5z aWduZWQgbG9uZyBwYWdlX3ZhOwo+ID4gICAgICAgICB1bnNpZ25lZCBsb25nIGZsYWdzOwo+ID4g LSAgICAgICBpbnQgcmV0Owo+ID4gKyAgICAgICB2b2lkICp0YWdzOwo+ID4gKyAgICAgICBpbnQg aSwgcmV0Owo+ID4KPiA+ICAgICAgICAgcmV0ID0gdGFnX3N0b3JhZ2VfZmluZF9ibG9jayhwYWdl LCAmc3RhcnRfYmxvY2ssICZyZWdpb24pOwo+ID4gICAgICAgICBpZiAoV0FSTl9PTkNFKHJldCwg Ik1pc3NpbmcgdGFnIHN0b3JhZ2UgYmxvY2sgZm9yIHBmbiAweCVseCIsIHBhZ2VfdG9fcGZuKHBh Z2UpKSkKPiA+IEBAIC02MDUsNiArNjA3LDE0IEBAIHZvaWQgZnJlZV90YWdfc3RvcmFnZShzdHJ1 Y3QgcGFnZSAqcGFnZSwgaW50IG9yZGVyKQo+ID4gICAgICAgICAvKiBBdm9pZCB3cml0ZWJhY2sg b2YgZGlydHkgdGFnIGNhY2hlIGxpbmVzIGNvcnJ1cHRpbmcgZGF0YS4gKi8KPiA+ICAgICAgICAg ZGNhY2hlX2ludmFsX3RhZ3NfcG9jKHBhZ2VfdmEsIHBhZ2VfdmEgKyAoUEFHRV9TSVpFIDw8IG9y ZGVyKSk7Cj4gPgo+ID4gKyAgICAgICB0YWdzX2J5X3Bmbl9sb2NrKCk7Cj4gPiArICAgICAgIGZv ciAoaSA9IDA7IGkgPCAoMSA8PCBvcmRlcik7IGkrKykgewo+ID4gKyAgICAgICAgICAgICAgIHRh Z3MgPSBtdGVfZXJhc2VfdGFnc19mb3JfcGZuKHBhZ2VfdG9fcGZuKHBhZ2UgKyBpKSk7Cj4gPiAr ICAgICAgICAgICAgICAgaWYgKHVubGlrZWx5KHRhZ3MpKQo+ID4gKyAgICAgICAgICAgICAgICAg ICAgICAgbXRlX2ZyZWVfdGFnX2J1Zih0YWdzKTsKPiA+ICsgICAgICAgfQo+ID4gKyAgICAgICB0 YWdzX2J5X3Bmbl91bmxvY2soKTsKPiA+ICsKPiA+ICAgICAgICAgZW5kX2Jsb2NrID0gc3RhcnRf YmxvY2sgKyBvcmRlcl90b19udW1fYmxvY2tzKG9yZGVyLCByZWdpb24tPmJsb2NrX3NpemVfcGFn ZXMpOwo+ID4KPiA+ICAgICAgICAgeGFfbG9ja19pcnFzYXZlKCZ0YWdfYmxvY2tzX3Jlc2VydmVk LCBmbGFncyk7Cj4gPiBkaWZmIC0tZ2l0IGEvYXJjaC9hcm02NC9tbS9tdGVzd2FwLmMgYi9hcmNo L2FybTY0L21tL210ZXN3YXAuYwo+ID4gaW5kZXggMmE0Mzc0NmI4MDNmLi5lMTE0OTVmYTNjMTgg MTAwNjQ0Cj4gPiAtLS0gYS9hcmNoL2FybTY0L21tL210ZXN3YXAuYwo+ID4gKysrIGIvYXJjaC9h cm02NC9tbS9tdGVzd2FwLmMKPiA+IEBAIC0yMCw2ICsyMCwxMTIgQEAgdm9pZCBtdGVfZnJlZV90 YWdfYnVmKHZvaWQgKmJ1ZikKPiA+ICAgICAgICAga2ZyZWUoYnVmKTsKPiA+ICB9Cj4gPgo+ID4g KyNpZmRlZiBDT05GSUdfQVJNNjRfTVRFX1RBR19TVE9SQUdFCj4gPiArc3RhdGljIERFRklORV9Y QVJSQVkodGFnc19ieV9wZm4pOwo+ID4gKwo+ID4gK3ZvaWQgdGFnc19ieV9wZm5fbG9jayh2b2lk KQo+ID4gK3sKPiA+ICsgICAgICAgeGFfbG9jaygmdGFnc19ieV9wZm4pOwo+ID4gK30KPiA+ICsK PiA+ICt2b2lkIHRhZ3NfYnlfcGZuX3VubG9jayh2b2lkKQo+ID4gK3sKPiA+ICsgICAgICAgeGFf dW5sb2NrKCZ0YWdzX2J5X3Bmbik7Cj4gPiArfQo+ID4gKwo+ID4gK3ZvaWQgKm10ZV9lcmFzZV90 YWdzX2Zvcl9wZm4odW5zaWduZWQgbG9uZyBwZm4pCj4gPiArewo+ID4gKyAgICAgICByZXR1cm4g X194YV9lcmFzZSgmdGFnc19ieV9wZm4sIHBmbik7Cj4gPiArfQo+ID4gKwo+ID4gK2Jvb2wgbXRl X3NhdmVfdGFnc19mb3JfcGZuKHZvaWQgKnRhZ3MsIHVuc2lnbmVkIGxvbmcgcGZuKQo+ID4gK3sK PiA+ICsgICAgICAgdm9pZCAqZW50cnk7Cj4gPiArICAgICAgIGludCByZXQ7Cj4gPiArCj4gPiAr ICAgICAgIHJldCA9IHhhX3Jlc2VydmUoJnRhZ3NfYnlfcGZuLCBwZm4sIEdGUF9LRVJORUwpOwo+ IAo+IGNvcHlfaGlnaHBhZ2UgY2FuIGJlIGNhbGxlZCBmcm9tIGFuIGF0b21pYyBjb250ZXh0LCBz byBpdCBpc24ndAo+IGN1cnJlbnRseSB2YWxpZCB0byBwYXNzIEdGUF9LRVJORUwgaGVyZS4KPiAK PiBUbyBnaXZlIG9uZSBleGFtcGxlIG9mIGEgcG9zc2libGUgYXRvbWljIGNvbnRleHQgY2FsbCwg Y29weV9wdGVfcmFuZ2UKPiB3aWxsIHRha2UgYSBQVEUgc3BpbmxvY2sgYW5kIGNhbiBjYWxsIGNv cHlfcHJlc2VudF9wdGUsIHdoaWNoIGNhbiBjYWxsCj4gY29weV9wcmVzZW50X3BhZ2UsIHdoaWNo IHdpbGwgY2FsbCBjb3B5X3VzZXJfaGlnaHBhZ2UuCj4gCj4gVG8gZ2l2ZSBhbm90aGVyIGV4YW1w bGUsIF9fYnVmZmVyX21pZ3JhdGVfZm9saW8gY2FuIGNhbGwKPiBzcGluX2xvY2soJm1hcHBpbmct PnByaXZhdGVfbG9jayksIHRoZW4gY2FsbCBmb2xpb19taWdyYXRlX2NvcHksIHdoaWNoCj4gd2ls bCBjYWxsIGZvbGlvX2NvcHkuCgpUaGF0IGlzIHZlcnkgdW5mb3J0dW5hdGUgZnJvbSBteSBwYXJ0 LiBJIGRpc3RpbmN0bHkgcmVtZW1iZXIgbG9va2luZwpwcmVjaXNlbHkgYXQgY29weV9wYWdlX3Jh bmdlKCkgdG8gZG91YmxlIGNoZWNrIHRoYXQgaXQgZG9lc24ndCBjYWxsCmNvcHlfKmhpZ2hwYWdl KCkgZnJvbSBhbiBhdG9taWMgY29udGV4dCwgSSBjYW4gb25seSBhc3N1bWUgdGhhdCBJIG1pc3Nl ZAp0aGF0IGl0J3MgY2FsbGVkIHdpdGggdGhlIHB0bCBsb2NrIGhlbGQuCgpXaXRoIHlvdXIgdHdv IGV4YW1wbGVzLCBhbmQgdGhlIGtodWdlcGFnZWQgY2FzZSBpbiBwYXRjaCAjMzEgKCJraHVnZXBh Z2VkOgphcm02NDogRG9uJ3QgY29sbGFwc2UgTVRFIGVuYWJsZWQgVk1BcyIpLCBpdCdzIGNyeXN0 YWwgY2xlYXIgdGhhdCB0aGUKY29udmVudGlvbiBmb3IgY29weV8qaGlnaHBhZ2UoKSBpcyB0aGF0 IHRoZSBmdW5jdGlvbiBjYW5ub3Qgc2xlZXAuCgpUaGVyZSBhcmUgdHdvIGlzc3VlcyBoZXJlOiBh bGxvY2F0aW5nIHRoZSBidWZmZXIgaW4gbWVtb3J5IHdoZXJlIHRoZSB0YWdzCndpbGwgYmUgY29w aWVkLCBhbmQgeGFycmF5IGFsbG9jYXRpbmcgbWVtb3J5IGZvciBhIG5ldyBlbnRyeS4KCk9uZSBm aXggd291bGQgYmUgdG8gYWxsb2NhdGUgYW4gZW50aXJlIHBhZ2Ugd2l0aCBfX0dGUF9BVE9NSUMs IGFuZCB1c2UgdGhhdAphcyBhIGNhY2hlIGZvciB0YWcgYnVmZmVycyAoc3RvcmluZyB0aGUgdGFn cyBmb3IgYSBwYWdlIHVzZXMgMS8zMnRoIG9mIGEKcGFnZSkuIEZyb20gd2hhdCBsaXR0bGUgSSBr bm93IGFib3V0IHhhcnJheSwgeGFycmF5IHN0b3JlcyB3b3VsZCBzdGlsbCBoYXZlCnRvIGJlIEdG UF9BVE9NSUMuIFRoaXMgc2hvdWxkIGZpeCB0aGUgc2xlZXBpbmcgaW4gYXRvbWljIGNvbnRleHQg YnVnLiBCdXQKdGhlIGlzc3VlIEkgc2VlIHdpdGggdGhpcyBpcyB0aGF0IGEgbWVtb3J5IGFsbG9j YXRpb24gY2FuIGZhaWwsIHdoaWxlCmNvcHlfKmhpZ2hwYWdlKCkgY2Fubm90LiBTZW5kIGEgZmF0 YWwgc2lnbmFsIHRvIHRoZSBwcm9jZXNzIGlmIG1lbW9yeQphbGxvY2F0aW9uIGZhaWxzPwoKQW5v dGhlciBhcHByb2FjaCB3b3VsZCBiZSB0byBwcmVhbGxvY2F0ZSBtZW1vcnkgaW4gYSBwcmVlbXB0 aWJsZSBjb250ZXh0LApzb21ldGhpbmcgbGlrZSBjb3B5XypoaWdocGFnZV9wcmVwYXJlKCksIGJ1 dCB0aGF0IHdvdWxkIG1lYW4gYSBsb3QgbW9yZQp3b3JrOiBmaW5kaW5nIGFsbCB0aGUgcGxhY2Vz IHdoZXJlIGNvcHlfKmhpZ2hwYWdlIGlzIHVzZWQgYW5kIGFkZApjb3B5XypoaWdocGFnZV9wcmVw YXJlKCkgb3V0c2lkZSB0aGUgY3JpdGljYWwgc2VjdGlvbiwgcmVsZWFzaW5nIHRoZSBtZW1vcnkK aW4gY2FzZSBvZiBmYWlsdXJlIChsaWtlIGluIHRoZSBjb3B5X3B0ZV9yYW5nZSgpIGNhc2UgLSBt YXliZQpjb3B5XypoaWdocGFnZV9lbmQoKT8pLiBUaGF0J3MgYSBwcmV0dHkgYmlnIG1haW50ZW5h bmNlIGJ1cmRlbiBmb3IgdGhlIE1NCmNvZGUuIEFsdGhvdWdoIG1heWJlIG90aGVyIGFyY2hpdGVj dHVyZXMgY2FuIGZpbmQgYSB1c2UgZm9yIGl0PwoKQW5kIHlldCBhbm90aGVyIGFwcHJvYWNoIGlz IHJlc2VydmUgdGhlIG5lZWRlZCBtZW1vcnkgKGZvciB0aGUgYnVmZmVyIGFuZAppbiB0aGUgeGFy cmF5KSB3aGVuIHRoZSBwYWdlIGlzIGFsbG9jYXRlZCwgaWYgaXQgZG9lc24ndCBoYXZlIHRhZyBz dG9yYWdlCnJlc2VydmVkLCByZWdhcmRsZXNzIG9mIHRoZSBwYWdlIGJlaW5nIGFsbG9jYXRlZCBh cyB0YWdnZWQgb3Igbm90LiBUaGVuIGluCnNldF9wdGVfYXQoKSBmcmVlIHRoaXMgbWVtb3J5IGlm IGl0J3MgdW51c2VkLiBCdXQgdGhpcyB3b3VsZCBtZWFuIHJlc2VydmluZwptZW1vcnkgZm9yIHBv c3NpYmx5IGFsbCBtZW1vcnkgYWxsb2NhdGlvbnMgaW4gdGhlIHN5c3RlbSAoaW5jbHVkaW5nIGZv ciB0YWcKc3RvcmFnZSBwYWdlcykgaWYgdXNlcnNwYWNlIGRvZXNuJ3QgdXNlIHRhZ3MgYXQgYWxs LCB0aG91Z2ggbm90IGFsbCBwYWdlcwppbiB0aGUgc3lzdGVtIHdpbGwgaGF2ZSB0aGlzIG1lbW9y eSByZXNlcnZlZCBhdCB0aGUgc2FtZSB0aW1lLiBQcmV0dHkgYmlnCmRvd25zaWRlLgoKT3V0IG9m IHRoZSB0aHJlZSwgSSBwcmVmZXIgdGhlIGZpcnN0LCBidXQgaXQncyBkZWZpbml0ZWx5IG5vdCBw ZXJmZWN0LiBJJ2xsCnRyeSB0byB0aGluayBvZiBzb21ldGhpbmcgZWxzZSwgbWF5YmUgSSBjYW4g Y29tZSB1cCB3aXRoIHNvbWV0aGluZyBiZXR0ZXIuCgpXaGF0IGFyZSB5b3VyIHRob3VnaHRzPwoK VGhhbmtzLApBbGV4Cgo+IAo+IFBldGVyCj4gCj4gPiArICAgICAgIGlmIChyZXQpCj4gPiArICAg ICAgICAgICAgICAgcmV0dXJuIHRydWU7Cj4gPiArCj4gPiArICAgICAgIHRhZ3NfYnlfcGZuX2xv Y2soKTsKPiA+ICsKPiA+ICsgICAgICAgaWYgKHBhZ2VfdGFnX3N0b3JhZ2VfcmVzZXJ2ZWQocGZu X3RvX3BhZ2UocGZuKSkpIHsKPiA+ICsgICAgICAgICAgICAgICB4YV9yZWxlYXNlKCZ0YWdzX2J5 X3BmbiwgcGZuKTsKPiA+ICsgICAgICAgICAgICAgICB0YWdzX2J5X3Bmbl91bmxvY2soKTsKPiA+ ICsgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Cj4gPiArICAgICAgIH0KPiA+ICsKPiA+ICsg ICAgICAgZW50cnkgPSBfX3hhX3N0b3JlKCZ0YWdzX2J5X3BmbiwgcGZuLCB0YWdzLCBHRlBfQVRP TUlDKTsKPiA+ICsgICAgICAgaWYgKHhhX2lzX2VycihlbnRyeSkpIHsKPiA+ICsgICAgICAgICAg ICAgICB4YV9yZWxlYXNlKCZ0YWdzX2J5X3BmbiwgcGZuKTsKPiA+ICsgICAgICAgICAgICAgICBn b3RvIG91dF91bmxvY2s7Cj4gPiArICAgICAgIH0gZWxzZSBpZiAoZW50cnkpIHsKPiA+ICsgICAg ICAgICAgICAgICBtdGVfZnJlZV90YWdfYnVmKGVudHJ5KTsKPiA+ICsgICAgICAgfQo+ID4gKwo+ ID4gK291dF91bmxvY2s6Cj4gPiArICAgICAgIHRhZ3NfYnlfcGZuX3VubG9jaygpOwo+ID4gKyAg ICAgICByZXR1cm4gdHJ1ZTsKPiA+ICt9Cj4gPiArCj4gPiArdm9pZCBtdGVfcmVzdG9yZV90YWdz X2Zvcl9wZm4odW5zaWduZWQgbG9uZyBzdGFydF9wZm4sIGludCBvcmRlcikKPiA+ICt7Cj4gPiAr ICAgICAgIHN0cnVjdCBwYWdlICpwYWdlID0gcGZuX3RvX3BhZ2Uoc3RhcnRfcGZuKTsKPiA+ICsg ICAgICAgdW5zaWduZWQgbG9uZyBwZm47Cj4gPiArICAgICAgIHZvaWQgKnRhZ3M7Cj4gPiArCj4g PiArICAgICAgIHRhZ3NfYnlfcGZuX2xvY2soKTsKPiA+ICsKPiA+ICsgICAgICAgZm9yIChwZm4g PSBzdGFydF9wZm47IHBmbiA8IHN0YXJ0X3BmbiArICgxIDw8IG9yZGVyKTsgcGZuKyssIHBhZ2Ur Kykgewo+ID4gKyAgICAgICAgICAgICAgIHRhZ3MgPSBtdGVfZXJhc2VfdGFnc19mb3JfcGZuKHBm bik7Cj4gPiArICAgICAgICAgICAgICAgaWYgKHVubGlrZWx5KHRhZ3MpKSB7Cj4gPiArICAgICAg ICAgICAgICAgICAgICAgICAvKgo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICogTWFyayB0 aGUgcGFnZSBhcyB0YWdnZWQgc28gbXRlX3N5bmNfdGFncygpIGRvZXNuJ3QKPiA+ICsgICAgICAg ICAgICAgICAgICAgICAgICAqIGNsZWFyIHRoZSB0YWdzLgo+ID4gKyAgICAgICAgICAgICAgICAg ICAgICAgICovCj4gPiArICAgICAgICAgICAgICAgICAgICAgICBXQVJOX09OX09OQ0UoIXRyeV9w YWdlX210ZV90YWdnaW5nKHBhZ2UpKTsKPiA+ICsgICAgICAgICAgICAgICAgICAgICAgIG10ZV9j b3B5X3BhZ2VfdGFnc19mcm9tX2J1ZihwYWdlX2FkZHJlc3MocGFnZSksIHRhZ3MpOwo+ID4gKyAg ICAgICAgICAgICAgICAgICAgICAgc2V0X3BhZ2VfbXRlX3RhZ2dlZChwYWdlKTsKPiA+ICsgICAg ICAgICAgICAgICAgICAgICAgIG10ZV9mcmVlX3RhZ19idWYodGFncyk7Cj4gPiArICAgICAgICAg ICAgICAgfQo+ID4gKyAgICAgICB9Cj4gPiArCj4gPiArICAgICAgIHRhZ3NfYnlfcGZuX3VubG9j aygpOwo+ID4gK30KPiA+ICsKPiA+ICsvKgo+ID4gKyAqIE5vdGUgb24gbG9ja2luZzogc3dhcCBp bi9vdXQgaXMgZG9uZSB3aXRoIHRoZSBmb2xpbyBsb2NrZWQsIHdoaWNoIGVsaW1pbmF0ZXMKPiA+ ICsgKiByYWNlcyB3aXRoIG10ZV9zYXZlL3Jlc3RvcmVfcGFnZV90YWdzX2J5X3N3cF9lbnRyeS4K PiA+ICsgKi8KPiA+ICt2bV9mYXVsdF90IG10ZV90cnlfdHJhbnNmZXJfc3dhcF90YWdzKHN3cF9l bnRyeV90IGVudHJ5LCBzdHJ1Y3QgcGFnZSAqcGFnZSkKPiA+ICt7Cj4gPiArICAgICAgIHZvaWQg KnN3YXBfdGFncywgKnBmbl90YWdzOwo+ID4gKyAgICAgICBib29sIHNhdmVkOwo+ID4gKwo+ID4g KyAgICAgICAvKgo+ID4gKyAgICAgICAgKiBtdGVfcmVzdG9yZV9wYWdlX3RhZ3NfYnlfc3dwX2Vu dHJ5KCkgd2lsbCB0YWtlIGNhcmUgb2YgY29weWluZyB0aGUKPiA+ICsgICAgICAgICogdGFncyBv dmVyLgo+ID4gKyAgICAgICAgKi8KPiA+ICsgICAgICAgaWYgKGxpa2VseShwYWdlX210ZV90YWdn ZWQocGFnZSkgfHwgcGFnZV90YWdfc3RvcmFnZV9yZXNlcnZlZChwYWdlKSkpCj4gPiArICAgICAg ICAgICAgICAgcmV0dXJuIDA7Cj4gPiArCj4gPiArICAgICAgIHN3YXBfdGFncyA9IHhhX2xvYWQo JnRhZ3NfYnlfc3dwX2VudHJ5LCBlbnRyeS52YWwpOwo+ID4gKyAgICAgICBpZiAoIXN3YXBfdGFn cykKPiA+ICsgICAgICAgICAgICAgICByZXR1cm4gMDsKPiA+ICsKPiA+ICsgICAgICAgcGZuX3Rh Z3MgPSBtdGVfYWxsb2NhdGVfdGFnX2J1ZigpOwo+ID4gKyAgICAgICBpZiAoIXBmbl90YWdzKQo+ ID4gKyAgICAgICAgICAgICAgIHJldHVybiBWTV9GQVVMVF9PT007Cj4gPiArCj4gPiArICAgICAg IG1lbWNweShwZm5fdGFncywgc3dhcF90YWdzLCBNVEVfUEFHRV9UQUdfU1RPUkFHRV9TSVpFKTsK PiA+ICsgICAgICAgc2F2ZWQgPSBtdGVfc2F2ZV90YWdzX2Zvcl9wZm4ocGZuX3RhZ3MsIHBhZ2Vf dG9fcGZuKHBhZ2UpKTsKPiA+ICsgICAgICAgaWYgKCFzYXZlZCkKPiA+ICsgICAgICAgICAgICAg ICBtdGVfZnJlZV90YWdfYnVmKHBmbl90YWdzKTsKPiA+ICsKPiA+ICsgICAgICAgcmV0dXJuIDA7 Cj4gPiArfQo+ID4gKyNlbmRpZgo+ID4gKwo+ID4gIGludCBtdGVfc2F2ZV9wYWdlX3RhZ3NfYnlf c3dwX2VudHJ5KHN0cnVjdCBwYWdlICpwYWdlKQo+ID4gIHsKPiA+ICAgICAgICAgdm9pZCAqdGFn cywgKnJldDsKPiA+IEBAIC01NCw2ICsxNjAsMTAgQEAgdm9pZCBtdGVfcmVzdG9yZV9wYWdlX3Rh Z3NfYnlfc3dwX2VudHJ5KHN3cF9lbnRyeV90IGVudHJ5LCBzdHJ1Y3QgcGFnZSAqcGFnZSkKPiA+ ICAgICAgICAgaWYgKCF0YWdzKQo+ID4gICAgICAgICAgICAgICAgIHJldHVybjsKPiA+Cj4gPiAr ICAgICAgIC8qIFRhZ3Mgd2lsbCBiZSByZXN0b3JlZCB3aGVuIHRhZyBzdG9yYWdlIGlzIHJlc2Vy dmVkLiAqLwo+ID4gKyAgICAgICBpZiAodGFnX3N0b3JhZ2VfZW5hYmxlZCgpICYmIHVubGlrZWx5 KCFwYWdlX3RhZ19zdG9yYWdlX3Jlc2VydmVkKHBhZ2UpKSkKPiA+ICsgICAgICAgICAgICAgICBy ZXR1cm47Cj4gPiArCj4gPiAgICAgICAgIGlmICh0cnlfcGFnZV9tdGVfdGFnZ2luZyhwYWdlKSkg ewo+ID4gICAgICAgICAgICAgICAgIG10ZV9jb3B5X3BhZ2VfdGFnc19mcm9tX2J1ZihwYWdlX2Fk ZHJlc3MocGFnZSksIHRhZ3MpOwo+ID4gICAgICAgICAgICAgICAgIHNldF9wYWdlX210ZV90YWdn ZWQocGFnZSk7Cj4gPiAtLQo+ID4gMi40My4wCj4gPgoKX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX18KbGludXgtYXJtLWtlcm5lbCBtYWlsaW5nIGxpc3QKbGlu dXgtYXJtLWtlcm5lbEBsaXN0cy5pbmZyYWRlYWQub3JnCmh0dHA6Ly9saXN0cy5pbmZyYWRlYWQu b3JnL21haWxtYW4vbGlzdGluZm8vbGludXgtYXJtLWtlcm5lbAo=