From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752129AbeEQArr (ORCPT ); Wed, 16 May 2018 20:47:47 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:33344 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751375AbeEQArp (ORCPT ); Wed, 16 May 2018 20:47:45 -0400 Subject: Re: [PATCH 2/2] support kdump when AMD secure memory encryption is active To: Tom Lendacky , linux-kernel@vger.kernel.org Cc: kexec@lists.infradead.org, dyoung@redhat.com References: <20180515015133.4363-1-lijiang@redhat.com> <20180515015133.4363-3-lijiang@redhat.com> <96b6d169-de5c-7ca8-df87-3d316526733a@amd.com> From: lijiang Message-ID: <0eed2a27-262c-bd33-f389-415b5765b2eb@redhat.com> Date: Thu, 17 May 2018 08:47:39 +0800 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.4.0 MIME-Version: 1.0 In-Reply-To: <96b6d169-de5c-7ca8-df87-3d316526733a@amd.com> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 在 2018年05月16日 04:18, Tom Lendacky 写道: > On 5/14/2018 8:51 PM, Lianbo Jiang wrote: >> When sme enabled on AMD server, we also need to support kdump. Because >> the memory is encrypted in the first kernel, we will remap the old memory >> encrypted to the second kernel(crash kernel), and sme is also enabled in >> the second kernel, otherwise the old memory encrypted can not be decrypted. >> Because simply changing the value of a C-bit on a page will not >> automatically encrypt the existing contents of a page, and any data in the >> page prior to the C-bit modification will become unintelligible. A page of >> memory that is marked encrypted will be automatically decrypted when read >> from DRAM and will be automatically encrypted when written to DRAM. >> >> For the kdump, it is necessary to distinguish whether the memory is >> encrypted. Furthermore, we should also know which part of the memory is >> encrypted or decrypted. We will appropriately remap the memory according >> to the specific situation in order to tell cpu how to deal with the data( >> encrypted or unencrypted). For example, when sme enabled, if the old memory >> is encrypted, we will remap the old memory in encrypted way, which will >> automatically decrypt the old memory encrypted when we read those data from >> the remapping address. >> >> ---------------------------------------------- >> | first-kernel | second-kernel | kdump support | >> | (mem_encrypt=on|off) | (yes|no) | >> |--------------+---------------+---------------| >> | on | on | yes | >> | off | off | yes | >> | on | off | no | >> | off | on | no | >> |______________|_______________|_______________| >> >> Signed-off-by: Lianbo Jiang >> --- >> arch/x86/include/asm/dmi.h | 14 +++++++++++++- >> arch/x86/kernel/acpi/boot.c | 8 ++++++++ >> arch/x86/kernel/crash_dump_64.c | 27 +++++++++++++++++++++++++++ >> drivers/acpi/tables.c | 14 +++++++++++++- >> drivers/iommu/amd_iommu_init.c | 9 ++++++++- >> fs/proc/vmcore.c | 36 +++++++++++++++++++++++++++++++----- >> include/linux/crash_dump.h | 4 ++++ >> kernel/kexec_core.c | 12 ++++++++++++ >> 8 files changed, 116 insertions(+), 8 deletions(-) >> >> diff --git a/arch/x86/include/asm/dmi.h b/arch/x86/include/asm/dmi.h >> index 0ab2ab2..a5663b4 100644 >> --- a/arch/x86/include/asm/dmi.h >> +++ b/arch/x86/include/asm/dmi.h >> @@ -7,6 +7,10 @@ >> >> #include >> #include >> +#ifdef CONFIG_AMD_MEM_ENCRYPT > > I don't think you need all of the #ifdef stuff throughout this > patch. Everything should work just fine without it. > >> +#include >> +#include >> +#endif >> >> static __always_inline __init void *dmi_alloc(unsigned len) >> { >> @@ -14,7 +18,15 @@ static __always_inline __init void *dmi_alloc(unsigned len) >> } >> >> /* Use early IO mappings for DMI because it's initialized early */ >> -#define dmi_early_remap early_memremap >> +static __always_inline __init void *dmi_early_remap(resource_size_t >> + phys_addr, unsigned long size) >> +{ >> +#ifdef CONFIG_AMD_MEM_ENCRYPT > > Again, no need for the #ifdef here. You should probably audit the > code for all of these and truly determine if they are really needed. > >> + if (sme_active() && is_kdump_kernel()) > > Use of sme_active() here is good since under SEV, this area will be > encrypted. > >> + return early_memremap_decrypted(phys_addr, size); >> +#endif >> + return early_memremap(phys_addr, size); > > Instead of doing this, maybe it makes more sense to put this logic > somewhere in the early_memremap() path. Possibly smarten up the > early_memremap_pgprot_adjust() function with some kdump kernel > related logic. Not sure it's possible, but would be nice since you > have this logic in a couple of places. > >> +} >> #define dmi_early_unmap early_memunmap >> #define dmi_remap(_x, _l) memremap(_x, _l, MEMREMAP_WB) >> #define dmi_unmap(_x) memunmap(_x) >> diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c >> index 3b20607..354ad66 100644 >> --- a/arch/x86/kernel/acpi/boot.c >> +++ b/arch/x86/kernel/acpi/boot.c >> @@ -48,6 +48,10 @@ >> #include >> #include >> #include >> +#ifdef CONFIG_AMD_MEM_ENCRYPT >> +#include >> +#include >> +#endif >> >> #include "sleep.h" /* To include x86_acpi_suspend_lowlevel */ >> static int __initdata acpi_force = 0; >> @@ -124,6 +128,10 @@ void __init __iomem *__acpi_map_table(unsigned long phys, unsigned long size) >> if (!phys || !size) >> return NULL; >> >> +#ifdef CONFIG_AMD_MEM_ENCRYPT >> + if (sme_active() && is_kdump_kernel()) >> + return early_memremap_decrypted(phys, size); >> +#endif > > Same as previous comment(s). > >> return early_memremap(phys, size); >> } >> >> diff --git a/arch/x86/kernel/crash_dump_64.c b/arch/x86/kernel/crash_dump_64.c >> index 4f2e077..2ef67fc 100644 >> --- a/arch/x86/kernel/crash_dump_64.c >> +++ b/arch/x86/kernel/crash_dump_64.c >> @@ -48,3 +48,30 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, >> iounmap(vaddr); >> return csize; >> } >> + >> +#ifdef CONFIG_AMD_MEM_ENCRYPT >> +ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf, >> + size_t csize, unsigned long offset, int userbuf) >> +{ >> + void *vaddr; >> + >> + if (!csize) >> + return 0; >> + >> + vaddr = ioremap_encrypted(pfn << PAGE_SHIFT, PAGE_SIZE); >> + if (!vaddr) >> + return -ENOMEM; >> + >> + if (userbuf) { >> + if (copy_to_user(buf, vaddr + offset, csize)) { >> + iounmap(vaddr); >> + return -EFAULT; >> + } >> + } else >> + memcpy(buf, vaddr + offset, csize); >> + >> + set_iounmap_nonlazy(); >> + iounmap(vaddr); >> + return csize; >> +} >> +#endif > > This seems exactly the same as copy_oldmem_page() with the difference > being the type of ioremap done. Might be better to make the code > after the ioremap's a common piece of code that each of the copy_oldmem > functions would call. > >> diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c >> index 849c4fb..6da9b0c 100644 >> --- a/drivers/acpi/tables.c >> +++ b/drivers/acpi/tables.c >> @@ -36,6 +36,10 @@ >> #include >> #include >> #include "internal.h" >> +#ifdef CONFIG_AMD_MEM_ENCRYPT >> +#include >> +#include >> +#endif >> >> #ifdef CONFIG_ACPI_CUSTOM_DSDT >> #include CONFIG_ACPI_CUSTOM_DSDT_FILE >> @@ -566,7 +570,15 @@ void __init acpi_table_upgrade(void) >> clen = size; >> if (clen > MAP_CHUNK_SIZE - slop) >> clen = MAP_CHUNK_SIZE - slop; >> - dest_p = early_memremap(dest_addr & PAGE_MASK, >> +#ifdef CONFIG_AMD_MEM_ENCRYPT >> + if (sme_active() && is_kdump_kernel()) >> + dest_p = early_memremap_decrypted( >> + dest_addr & PAGE_MASK, >> + clen + slop); >> + else >> +#endif >> + dest_p = early_memremap( >> + dest_addr & PAGE_MASK, > > So if the dest_addr (based off of acpi_tables_addr) was added to the e820 > map as an ACPI area (which it will be), then it would be mapped properly > (in both SME and SEV) without needing the if/then/else. > >> clen + slop); >> memcpy(dest_p + slop, src_p, clen); >> early_memunmap(dest_p, clen + slop); >> diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c >> index 904c575..8ecbddb 100644 >> --- a/drivers/iommu/amd_iommu_init.c >> +++ b/drivers/iommu/amd_iommu_init.c >> @@ -889,11 +889,18 @@ static bool copy_device_table(void) >> } >> >> old_devtb_phys = entry & PAGE_MASK; >> + if (sme_active() && is_kdump_kernel()) > > Use mem_encrypt_active() here to cover both SME and SEV. > >> + old_devtb_phys = __sme_clr(old_devtb_phys); >> if (old_devtb_phys >= 0x100000000ULL) { >> pr_err("The address of old device table is above 4G, not trustworthy!\n"); >> return false; >> } >> - old_devtb = memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB); >> + if (sme_active() && is_kdump_kernel()) >> + old_devtb = ioremap_encrypted(old_devtb_phys, >> + dev_table_size); >> + else >> + old_devtb = memremap(old_devtb_phys, >> + dev_table_size, MEMREMAP_WB); > > What happens to the memremap here, does it fall back to the ioremap and > end up getting mapped decrypted? It would be nice to do the right thing > under the covers of memremap. Not sure what that would take, but it would > keep the code nice and clean. > Thank you, Tom. For this issue, it will copy the old content of device table entries, that is to say, it will copy the device table from the first kernel to the second kernel in kdump mode and the content of device table is encrypted, the address includes the sme_me_mask. For the old memory encrypted, it is suitable to use ioremap_encrypted, the kdump kernel can not directly access the first kernel's memory. Lianbo >> if (!old_devtb) >> return false; >> >> diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c >> index a45f0af..316e2b0 100644 >> --- a/fs/proc/vmcore.c >> +++ b/fs/proc/vmcore.c >> @@ -25,6 +25,10 @@ >> #include >> #include >> #include "internal.h" >> +#ifdef CONFIG_AMD_MEM_ENCRYPT >> +#include >> +#include >> +#endif >> >> /* List representing chunks of contiguous memory areas and their offsets in >> * vmcore file. >> @@ -86,7 +90,8 @@ static int pfn_is_ram(unsigned long pfn) >> >> /* Reads a page from the oldmem device from given offset. */ >> static ssize_t read_from_oldmem(char *buf, size_t count, >> - u64 *ppos, int userbuf) >> + u64 *ppos, int userbuf, >> + bool encrypted) >> { >> unsigned long pfn, offset; >> size_t nr_bytes; >> @@ -108,8 +113,15 @@ static ssize_t read_from_oldmem(char *buf, size_t count, >> if (pfn_is_ram(pfn) == 0) >> memset(buf, 0, nr_bytes); >> else { >> - tmp = copy_oldmem_page(pfn, buf, nr_bytes, >> +#ifdef CONFIG_AMD_MEM_ENCRYPT >> + if (encrypted) >> + tmp = copy_oldmem_page_encrypted(pfn, buf, >> + nr_bytes, offset, userbuf); >> + else >> +#endif >> + tmp = copy_oldmem_page(pfn, buf, nr_bytes, >> offset, userbuf);> + >> if (tmp < 0) >> return tmp; >> } >> @@ -143,7 +155,7 @@ void __weak elfcorehdr_free(unsigned long long addr) >> */ >> ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos) >> { >> - return read_from_oldmem(buf, count, ppos, 0); >> + return read_from_oldmem(buf, count, ppos, 0, false); > > For SEV, this will likely be encrypted, so you can probably replace the > "false" with sev_active() so that under SME it is un-encrypted but under > SEV it is encrypted. Where is the elfcorehdr stored? I wonder if it > could be created as encrypted under SME and then you could actually remove > the encrypted parameter from read_from_oldmem() and always map encrypted. > If SME or SEV are active it will be mapped encrypted and if they aren't > then it is mapped normally. > >> } >> >> /* >> @@ -151,7 +163,11 @@ ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos) >> */ >> ssize_t __weak elfcorehdr_read_notes(char *buf, size_t count, u64 *ppos) >> { >> - return read_from_oldmem(buf, count, ppos, 0); >> + bool flag = false; >> +#ifdef CONFIG_AMD_MEM_ENCRYPT >> + flag = sme_active(); >> +#endif >> + return read_from_oldmem(buf, count, ppos, 0, flag); >> } >> >> /* >> @@ -161,6 +177,10 @@ int __weak remap_oldmem_pfn_range(struct vm_area_struct *vma, >> unsigned long from, unsigned long pfn, >> unsigned long size, pgprot_t prot) >> { >> +#ifdef CONFIG_AMD_MEM_ENCRYPT >> + if (sme_active()) > > No need for the sme_active() check here, the encryption will be applied, > for both SME and SEV, if memory encryption is active, otherwise it won't. > >> + prot = __pgprot(pgprot_val(prot) | _PAGE_ENC); > > prot = pgprot_encrypted(prot); > >> +#endif> return remap_pfn_range(vma, from, pfn, size, prot); >> } >> >> @@ -188,6 +208,11 @@ static ssize_t __read_vmcore(char *buffer, size_t buflen, loff_t *fpos, >> size_t tsz; >> u64 start; >> struct vmcore *m = NULL; >> + bool sme_flag = false; >> + >> +#ifdef CONFIG_AMD_MEM_ENCRYPT >> + sme_flag = sme_active();> +#endif > > Probably just want mem_encrypt_active() here to get both SME and SEV > cases mapped as encrypted. > > Thanks, > Tom > >> >> if (buflen == 0 || *fpos >= vmcore_size) >> return 0; >> @@ -235,7 +260,8 @@ static ssize_t __read_vmcore(char *buffer, size_t buflen, loff_t *fpos, >> m->offset + m->size - *fpos, >> buflen); >> start = m->paddr + *fpos - m->offset; >> - tmp = read_from_oldmem(buffer, tsz, &start, userbuf); >> + tmp = read_from_oldmem(buffer, tsz, &start, >> + userbuf, sme_flag); >> if (tmp < 0) >> return tmp; >> buflen -= tsz; >> diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h >> index f7ac2aa..024ae9e 100644 >> --- a/include/linux/crash_dump.h >> +++ b/include/linux/crash_dump.h >> @@ -25,6 +25,10 @@ extern int remap_oldmem_pfn_range(struct vm_area_struct *vma, >> >> extern ssize_t copy_oldmem_page(unsigned long, char *, size_t, >> unsigned long, int); >> +#ifdef CONFIG_AMD_MEM_ENCRYPT >> +extern ssize_t copy_oldmem_page_encrypted(unsigned long, char *, size_t, >> + unsigned long, int); >> +#endif >> void vmcore_cleanup(void); >> >> /* Architecture code defines this if there are other possible ELF >> diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c >> index 20fef1a..3c22a9b 100644 >> --- a/kernel/kexec_core.c >> +++ b/kernel/kexec_core.c >> @@ -471,6 +471,16 @@ static struct page *kimage_alloc_crash_control_pages(struct kimage *image, >> } >> } >> >> + if (pages) { >> + unsigned int count, i; >> + >> + pages->mapping = NULL; >> + set_page_private(pages, order); >> + count = 1 << order; >> + for (i = 0; i < count; i++) >> + SetPageReserved(pages + i); >> + arch_kexec_post_alloc_pages(page_address(pages), 1 << order, 0); >> + } >> return pages; >> } >> >> @@ -865,6 +875,7 @@ static int kimage_load_crash_segment(struct kimage *image, >> result = -ENOMEM; >> goto out; >> } >> + arch_kexec_post_alloc_pages(page_address(page), 1, 0); >> ptr = kmap(page); >> ptr += maddr & ~PAGE_MASK; >> mchunk = min_t(size_t, mbytes, >> @@ -882,6 +893,7 @@ static int kimage_load_crash_segment(struct kimage *image, >> result = copy_from_user(ptr, buf, uchunk); >> kexec_flush_icache_page(page); >> kunmap(page); >> + arch_kexec_pre_free_pages(page_address(page), 1); >> if (result) { >> result = -EFAULT; >> goto out; >> From mboxrd@z Thu Jan 1 00:00:00 1970 Return-path: Received: from mx3-rdu2.redhat.com ([66.187.233.73] helo=mx1.redhat.com) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1fJ75J-0006Jt-Ue for kexec@lists.infradead.org; Thu, 17 May 2018 00:48:13 +0000 Subject: Re: [PATCH 2/2] support kdump when AMD secure memory encryption is active References: <20180515015133.4363-1-lijiang@redhat.com> <20180515015133.4363-3-lijiang@redhat.com> <96b6d169-de5c-7ca8-df87-3d316526733a@amd.com> From: lijiang Message-ID: <0eed2a27-262c-bd33-f389-415b5765b2eb@redhat.com> Date: Thu, 17 May 2018 08:47:39 +0800 MIME-Version: 1.0 In-Reply-To: <96b6d169-de5c-7ca8-df87-3d316526733a@amd.com> Content-Language: en-US List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "kexec" Errors-To: kexec-bounces+dwmw2=infradead.org@lists.infradead.org To: Tom Lendacky , linux-kernel@vger.kernel.org Cc: dyoung@redhat.com, kexec@lists.infradead.org 5ZyoIDIwMTjlubQwNeaciDE25pelIDA0OjE4LCBUb20gTGVuZGFja3kg5YaZ6YGTOgo+IE9uIDUv MTQvMjAxOCA4OjUxIFBNLCBMaWFuYm8gSmlhbmcgd3JvdGU6Cj4+IFdoZW4gc21lIGVuYWJsZWQg b24gQU1EIHNlcnZlciwgd2UgYWxzbyBuZWVkIHRvIHN1cHBvcnQga2R1bXAuIEJlY2F1c2UKPj4g dGhlIG1lbW9yeSBpcyBlbmNyeXB0ZWQgaW4gdGhlIGZpcnN0IGtlcm5lbCwgd2Ugd2lsbCByZW1h cCB0aGUgb2xkIG1lbW9yeQo+PiBlbmNyeXB0ZWQgdG8gdGhlIHNlY29uZCBrZXJuZWwoY3Jhc2gg a2VybmVsKSwgYW5kIHNtZSBpcyBhbHNvIGVuYWJsZWQgaW4KPj4gdGhlIHNlY29uZCBrZXJuZWws IG90aGVyd2lzZSB0aGUgb2xkIG1lbW9yeSBlbmNyeXB0ZWQgY2FuIG5vdCBiZSBkZWNyeXB0ZWQu Cj4+IEJlY2F1c2Ugc2ltcGx5IGNoYW5naW5nIHRoZSB2YWx1ZSBvZiBhIEMtYml0IG9uIGEgcGFn ZSB3aWxsIG5vdAo+PiBhdXRvbWF0aWNhbGx5IGVuY3J5cHQgdGhlIGV4aXN0aW5nIGNvbnRlbnRz IG9mIGEgcGFnZSwgYW5kIGFueSBkYXRhIGluIHRoZQo+PiBwYWdlIHByaW9yIHRvIHRoZSBDLWJp dCBtb2RpZmljYXRpb24gd2lsbCBiZWNvbWUgdW5pbnRlbGxpZ2libGUuIEEgcGFnZSBvZgo+PiBt ZW1vcnkgdGhhdCBpcyBtYXJrZWQgZW5jcnlwdGVkIHdpbGwgYmUgYXV0b21hdGljYWxseSBkZWNy eXB0ZWQgd2hlbiByZWFkCj4+IGZyb20gRFJBTSBhbmQgd2lsbCBiZSBhdXRvbWF0aWNhbGx5IGVu Y3J5cHRlZCB3aGVuIHdyaXR0ZW4gdG8gRFJBTS4KPj4KPj4gRm9yIHRoZSBrZHVtcCwgaXQgaXMg bmVjZXNzYXJ5IHRvIGRpc3Rpbmd1aXNoIHdoZXRoZXIgdGhlIG1lbW9yeSBpcwo+PiBlbmNyeXB0 ZWQuIEZ1cnRoZXJtb3JlLCB3ZSBzaG91bGQgYWxzbyBrbm93IHdoaWNoIHBhcnQgb2YgdGhlIG1l bW9yeSBpcwo+PiBlbmNyeXB0ZWQgb3IgZGVjcnlwdGVkLiBXZSB3aWxsIGFwcHJvcHJpYXRlbHkg cmVtYXAgdGhlIG1lbW9yeSBhY2NvcmRpbmcKPj4gdG8gdGhlIHNwZWNpZmljIHNpdHVhdGlvbiBp biBvcmRlciB0byB0ZWxsIGNwdSBob3cgdG8gZGVhbCB3aXRoIHRoZSBkYXRhKAo+PiBlbmNyeXB0 ZWQgb3IgdW5lbmNyeXB0ZWQpLiBGb3IgZXhhbXBsZSwgd2hlbiBzbWUgZW5hYmxlZCwgaWYgdGhl IG9sZCBtZW1vcnkKPj4gaXMgZW5jcnlwdGVkLCB3ZSB3aWxsIHJlbWFwIHRoZSBvbGQgbWVtb3J5 IGluIGVuY3J5cHRlZCB3YXksIHdoaWNoIHdpbGwKPj4gYXV0b21hdGljYWxseSBkZWNyeXB0IHRo ZSBvbGQgbWVtb3J5IGVuY3J5cHRlZCB3aGVuIHdlIHJlYWQgdGhvc2UgZGF0YSBmcm9tCj4+IHRo ZSByZW1hcHBpbmcgYWRkcmVzcy4KPj4KPj4gIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0KPj4gfCBmaXJzdC1rZXJuZWwgfCBzZWNvbmQta2VybmVsIHwga2R1 bXAgc3VwcG9ydCB8Cj4+IHwgICAgICAobWVtX2VuY3J5cHQ9b258b2ZmKSAgICB8ICAgKHllc3xu bykgICAgfAo+PiB8LS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0t LXwKPj4gfCAgICAgb24gICAgICAgfCAgICAgb24gICAgICAgIHwgICAgIHllcyAgICAgICB8Cj4+ IHwgICAgIG9mZiAgICAgIHwgICAgIG9mZiAgICAgICB8ICAgICB5ZXMgICAgICAgfAo+PiB8ICAg ICBvbiAgICAgICB8ICAgICBvZmYgICAgICAgfCAgICAgbm8gICAgICAgIHwKPj4gfCAgICAgb2Zm ICAgICAgfCAgICAgb24gICAgICAgIHwgICAgIG5vICAgICAgICB8Cj4+IHxfX19fX19fX19fX19f X3xfX19fX19fX19fX19fX198X19fX19fX19fX19fX19ffAo+Pgo+PiBTaWduZWQtb2ZmLWJ5OiBM aWFuYm8gSmlhbmcgPGxpamlhbmdAcmVkaGF0LmNvbT4KPj4gLS0tCj4+ICBhcmNoL3g4Ni9pbmNs dWRlL2FzbS9kbWkuaCAgICAgIHwgMTQgKysrKysrKysrKysrKy0KPj4gIGFyY2gveDg2L2tlcm5l bC9hY3BpL2Jvb3QuYyAgICAgfCAgOCArKysrKysrKwo+PiAgYXJjaC94ODYva2VybmVsL2NyYXNo X2R1bXBfNjQuYyB8IDI3ICsrKysrKysrKysrKysrKysrKysrKysrKysrKwo+PiAgZHJpdmVycy9h Y3BpL3RhYmxlcy5jICAgICAgICAgICB8IDE0ICsrKysrKysrKysrKystCj4+ICBkcml2ZXJzL2lv bW11L2FtZF9pb21tdV9pbml0LmMgIHwgIDkgKysrKysrKystCj4+ICBmcy9wcm9jL3ZtY29yZS5j ICAgICAgICAgICAgICAgIHwgMzYgKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKy0tLS0t Cj4+ICBpbmNsdWRlL2xpbnV4L2NyYXNoX2R1bXAuaCAgICAgIHwgIDQgKysrKwo+PiAga2VybmVs L2tleGVjX2NvcmUuYyAgICAgICAgICAgICB8IDEyICsrKysrKysrKysrKwo+PiAgOCBmaWxlcyBj aGFuZ2VkLCAxMTYgaW5zZXJ0aW9ucygrKSwgOCBkZWxldGlvbnMoLSkKPj4KPj4gZGlmZiAtLWdp dCBhL2FyY2gveDg2L2luY2x1ZGUvYXNtL2RtaS5oIGIvYXJjaC94ODYvaW5jbHVkZS9hc20vZG1p LmgKPj4gaW5kZXggMGFiMmFiMi4uYTU2NjNiNCAxMDA2NDQKPj4gLS0tIGEvYXJjaC94ODYvaW5j bHVkZS9hc20vZG1pLmgKPj4gKysrIGIvYXJjaC94ODYvaW5jbHVkZS9hc20vZG1pLmgKPj4gQEAg LTcsNiArNywxMCBAQAo+PiAgCj4+ICAjaW5jbHVkZSA8YXNtL2lvLmg+Cj4+ICAjaW5jbHVkZSA8 YXNtL3NldHVwLmg+Cj4+ICsjaWZkZWYgQ09ORklHX0FNRF9NRU1fRU5DUllQVAo+IAo+IEkgZG9u J3QgdGhpbmsgeW91IG5lZWQgYWxsIG9mIHRoZSAjaWZkZWYgc3R1ZmYgdGhyb3VnaG91dCB0aGlz Cj4gcGF0Y2guICBFdmVyeXRoaW5nIHNob3VsZCB3b3JrIGp1c3QgZmluZSB3aXRob3V0IGl0Lgo+ IAo+PiArI2luY2x1ZGUgPGxpbnV4L2NyYXNoX2R1bXAuaD4KPj4gKyNpbmNsdWRlIDxsaW51eC9t ZW1fZW5jcnlwdC5oPgo+PiArI2VuZGlmCj4+ICAKPj4gIHN0YXRpYyBfX2Fsd2F5c19pbmxpbmUg X19pbml0IHZvaWQgKmRtaV9hbGxvYyh1bnNpZ25lZCBsZW4pCj4+ICB7Cj4+IEBAIC0xNCw3ICsx OCwxNSBAQCBzdGF0aWMgX19hbHdheXNfaW5saW5lIF9faW5pdCB2b2lkICpkbWlfYWxsb2ModW5z aWduZWQgbGVuKQo+PiAgfQo+PiAgCj4+ICAvKiBVc2UgZWFybHkgSU8gbWFwcGluZ3MgZm9yIERN SSBiZWNhdXNlIGl0J3MgaW5pdGlhbGl6ZWQgZWFybHkgKi8KPj4gLSNkZWZpbmUgZG1pX2Vhcmx5 X3JlbWFwCQllYXJseV9tZW1yZW1hcAo+PiArc3RhdGljIF9fYWx3YXlzX2lubGluZSBfX2luaXQg dm9pZCAqZG1pX2Vhcmx5X3JlbWFwKHJlc291cmNlX3NpemVfdAo+PiArCQkJCQlwaHlzX2FkZHIs IHVuc2lnbmVkIGxvbmcgc2l6ZSkKPj4gK3sKPj4gKyNpZmRlZiBDT05GSUdfQU1EX01FTV9FTkNS WVBUCj4gCj4gQWdhaW4sIG5vIG5lZWQgZm9yIHRoZSAjaWZkZWYgaGVyZS4gIFlvdSBzaG91bGQg cHJvYmFibHkgYXVkaXQgdGhlCj4gY29kZSBmb3IgYWxsIG9mIHRoZXNlIGFuZCB0cnVseSBkZXRl cm1pbmUgaWYgdGhleSBhcmUgcmVhbGx5IG5lZWRlZC4KPiAKPj4gKwlpZiAoc21lX2FjdGl2ZSgp ICYmIGlzX2tkdW1wX2tlcm5lbCgpKQo+IAo+IFVzZSBvZiBzbWVfYWN0aXZlKCkgaGVyZSBpcyBn b29kIHNpbmNlIHVuZGVyIFNFViwgdGhpcyBhcmVhIHdpbGwgYmUKPiBlbmNyeXB0ZWQuCj4gCj4+ ICsJCXJldHVybiBlYXJseV9tZW1yZW1hcF9kZWNyeXB0ZWQocGh5c19hZGRyLCBzaXplKTsKPj4g KyNlbmRpZgo+PiArCXJldHVybiBlYXJseV9tZW1yZW1hcChwaHlzX2FkZHIsIHNpemUpOwo+IAo+ IEluc3RlYWQgb2YgZG9pbmcgdGhpcywgbWF5YmUgaXQgbWFrZXMgbW9yZSBzZW5zZSB0byBwdXQg dGhpcyBsb2dpYwo+IHNvbWV3aGVyZSBpbiB0aGUgZWFybHlfbWVtcmVtYXAoKSBwYXRoLiAgUG9z c2libHkgc21hcnRlbiB1cCB0aGUKPiBlYXJseV9tZW1yZW1hcF9wZ3Byb3RfYWRqdXN0KCkgZnVu Y3Rpb24gd2l0aCBzb21lIGtkdW1wIGtlcm5lbAo+IHJlbGF0ZWQgbG9naWMuICBOb3Qgc3VyZSBp dCdzIHBvc3NpYmxlLCBidXQgd291bGQgYmUgbmljZSBzaW5jZSB5b3UKPiBoYXZlIHRoaXMgbG9n aWMgaW4gYSBjb3VwbGUgb2YgcGxhY2VzLgo+IAo+PiArfQo+PiAgI2RlZmluZSBkbWlfZWFybHlf dW5tYXAJCWVhcmx5X21lbXVubWFwCj4+ICAjZGVmaW5lIGRtaV9yZW1hcChfeCwgX2wpCW1lbXJl bWFwKF94LCBfbCwgTUVNUkVNQVBfV0IpCj4+ICAjZGVmaW5lIGRtaV91bm1hcChfeCkJCW1lbXVu bWFwKF94KQo+PiBkaWZmIC0tZ2l0IGEvYXJjaC94ODYva2VybmVsL2FjcGkvYm9vdC5jIGIvYXJj aC94ODYva2VybmVsL2FjcGkvYm9vdC5jCj4+IGluZGV4IDNiMjA2MDcuLjM1NGFkNjYgMTAwNjQ0 Cj4+IC0tLSBhL2FyY2gveDg2L2tlcm5lbC9hY3BpL2Jvb3QuYwo+PiArKysgYi9hcmNoL3g4Ni9r ZXJuZWwvYWNwaS9ib290LmMKPj4gQEAgLTQ4LDYgKzQ4LDEwIEBACj4+ICAjaW5jbHVkZSA8YXNt L21wc3BlYy5oPgo+PiAgI2luY2x1ZGUgPGFzbS9zbXAuaD4KPj4gICNpbmNsdWRlIDxhc20vaTgy NTkuaD4KPj4gKyNpZmRlZiBDT05GSUdfQU1EX01FTV9FTkNSWVBUCj4+ICsjaW5jbHVkZSA8bGlu dXgvY3Jhc2hfZHVtcC5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L21lbV9lbmNyeXB0Lmg+Cj4+ICsj ZW5kaWYKPj4gIAo+PiAgI2luY2x1ZGUgInNsZWVwLmgiIC8qIFRvIGluY2x1ZGUgeDg2X2FjcGlf c3VzcGVuZF9sb3dsZXZlbCAqLwo+PiAgc3RhdGljIGludCBfX2luaXRkYXRhIGFjcGlfZm9yY2Ug PSAwOwo+PiBAQCAtMTI0LDYgKzEyOCwxMCBAQCB2b2lkIF9faW5pdCBfX2lvbWVtICpfX2FjcGlf bWFwX3RhYmxlKHVuc2lnbmVkIGxvbmcgcGh5cywgdW5zaWduZWQgbG9uZyBzaXplKQo+PiAgCWlm ICghcGh5cyB8fCAhc2l6ZSkKPj4gIAkJcmV0dXJuIE5VTEw7Cj4+ICAKPj4gKyNpZmRlZiBDT05G SUdfQU1EX01FTV9FTkNSWVBUCj4+ICsJaWYgKHNtZV9hY3RpdmUoKSAmJiBpc19rZHVtcF9rZXJu ZWwoKSkKPj4gKwkJcmV0dXJuIGVhcmx5X21lbXJlbWFwX2RlY3J5cHRlZChwaHlzLCBzaXplKTsK Pj4gKyNlbmRpZgo+IAo+IFNhbWUgYXMgcHJldmlvdXMgY29tbWVudChzKS4KPiAKPj4gIAlyZXR1 cm4gZWFybHlfbWVtcmVtYXAocGh5cywgc2l6ZSk7Cj4+ICB9Cj4+ICAKPj4gZGlmZiAtLWdpdCBh L2FyY2gveDg2L2tlcm5lbC9jcmFzaF9kdW1wXzY0LmMgYi9hcmNoL3g4Ni9rZXJuZWwvY3Jhc2hf ZHVtcF82NC5jCj4+IGluZGV4IDRmMmUwNzcuLjJlZjY3ZmMgMTAwNjQ0Cj4+IC0tLSBhL2FyY2gv eDg2L2tlcm5lbC9jcmFzaF9kdW1wXzY0LmMKPj4gKysrIGIvYXJjaC94ODYva2VybmVsL2NyYXNo X2R1bXBfNjQuYwo+PiBAQCAtNDgsMyArNDgsMzAgQEAgc3NpemVfdCBjb3B5X29sZG1lbV9wYWdl KHVuc2lnbmVkIGxvbmcgcGZuLCBjaGFyICpidWYsCj4+ICAJaW91bm1hcCh2YWRkcik7Cj4+ICAJ cmV0dXJuIGNzaXplOwo+PiAgfQo+PiArCj4+ICsjaWZkZWYgQ09ORklHX0FNRF9NRU1fRU5DUllQ VAo+PiArc3NpemVfdCBjb3B5X29sZG1lbV9wYWdlX2VuY3J5cHRlZCh1bnNpZ25lZCBsb25nIHBm biwgY2hhciAqYnVmLAo+PiArCQlzaXplX3QgY3NpemUsIHVuc2lnbmVkIGxvbmcgb2Zmc2V0LCBp bnQgdXNlcmJ1ZikKPj4gK3sKPj4gKwl2b2lkICAqdmFkZHI7Cj4+ICsKPj4gKwlpZiAoIWNzaXpl KQo+PiArCQlyZXR1cm4gMDsKPj4gKwo+PiArCXZhZGRyID0gaW9yZW1hcF9lbmNyeXB0ZWQocGZu IDw8IFBBR0VfU0hJRlQsIFBBR0VfU0laRSk7Cj4+ICsJaWYgKCF2YWRkcikKPj4gKwkJcmV0dXJu IC1FTk9NRU07Cj4+ICsKPj4gKwlpZiAodXNlcmJ1Zikgewo+PiArCQlpZiAoY29weV90b191c2Vy KGJ1ZiwgdmFkZHIgKyBvZmZzZXQsIGNzaXplKSkgewo+PiArCQkJaW91bm1hcCh2YWRkcik7Cj4+ ICsJCQlyZXR1cm4gLUVGQVVMVDsKPj4gKwkJfQo+PiArCX0gZWxzZQo+PiArCQltZW1jcHkoYnVm LCB2YWRkciArIG9mZnNldCwgY3NpemUpOwo+PiArCj4+ICsJc2V0X2lvdW5tYXBfbm9ubGF6eSgp Owo+PiArCWlvdW5tYXAodmFkZHIpOwo+PiArCXJldHVybiBjc2l6ZTsKPj4gK30KPj4gKyNlbmRp Zgo+IAo+IFRoaXMgc2VlbXMgZXhhY3RseSB0aGUgc2FtZSBhcyBjb3B5X29sZG1lbV9wYWdlKCkg d2l0aCB0aGUgZGlmZmVyZW5jZQo+IGJlaW5nIHRoZSB0eXBlIG9mIGlvcmVtYXAgZG9uZS4gIE1p Z2h0IGJlIGJldHRlciB0byBtYWtlIHRoZSBjb2RlCj4gYWZ0ZXIgdGhlIGlvcmVtYXAncyBhIGNv bW1vbiBwaWVjZSBvZiBjb2RlIHRoYXQgZWFjaCBvZiB0aGUgY29weV9vbGRtZW0KPiBmdW5jdGlv bnMgd291bGQgY2FsbC4KPiAKPj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvYWNwaS90YWJsZXMuYyBi L2RyaXZlcnMvYWNwaS90YWJsZXMuYwo+PiBpbmRleCA4NDljNGZiLi42ZGE5YjBjIDEwMDY0NAo+ PiAtLS0gYS9kcml2ZXJzL2FjcGkvdGFibGVzLmMKPj4gKysrIGIvZHJpdmVycy9hY3BpL3RhYmxl cy5jCj4+IEBAIC0zNiw2ICszNiwxMCBAQAo+PiAgI2luY2x1ZGUgPGxpbnV4L21lbWJsb2NrLmg+ Cj4+ICAjaW5jbHVkZSA8bGludXgvaW5pdHJkLmg+Cj4+ICAjaW5jbHVkZSAiaW50ZXJuYWwuaCIK Pj4gKyNpZmRlZiBDT05GSUdfQU1EX01FTV9FTkNSWVBUCj4+ICsjaW5jbHVkZSA8bGludXgvY3Jh c2hfZHVtcC5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L21lbV9lbmNyeXB0Lmg+Cj4+ICsjZW5kaWYK Pj4gIAo+PiAgI2lmZGVmIENPTkZJR19BQ1BJX0NVU1RPTV9EU0RUCj4+ICAjaW5jbHVkZSBDT05G SUdfQUNQSV9DVVNUT01fRFNEVF9GSUxFCj4+IEBAIC01NjYsNyArNTcwLDE1IEBAIHZvaWQgX19p bml0IGFjcGlfdGFibGVfdXBncmFkZSh2b2lkKQo+PiAgCQkJY2xlbiA9IHNpemU7Cj4+ICAJCQlp ZiAoY2xlbiA+IE1BUF9DSFVOS19TSVpFIC0gc2xvcCkKPj4gIAkJCQljbGVuID0gTUFQX0NIVU5L X1NJWkUgLSBzbG9wOwo+PiAtCQkJZGVzdF9wID0gZWFybHlfbWVtcmVtYXAoZGVzdF9hZGRyICYg UEFHRV9NQVNLLAo+PiArI2lmZGVmIENPTkZJR19BTURfTUVNX0VOQ1JZUFQKPj4gKwkJCWlmIChz bWVfYWN0aXZlKCkgJiYgaXNfa2R1bXBfa2VybmVsKCkpCj4+ICsJCQkJZGVzdF9wID0gZWFybHlf bWVtcmVtYXBfZGVjcnlwdGVkKAo+PiArCQkJCQkJZGVzdF9hZGRyICYgUEFHRV9NQVNLLAo+PiAr CQkJCQkJY2xlbiArIHNsb3ApOwo+PiArCQkJZWxzZQo+PiArI2VuZGlmCj4+ICsJCQkJZGVzdF9w ID0gZWFybHlfbWVtcmVtYXAoCj4+ICsJCQkJCQlkZXN0X2FkZHIgJiBQQUdFX01BU0ssCj4gCj4g U28gaWYgdGhlIGRlc3RfYWRkciAoYmFzZWQgb2ZmIG9mIGFjcGlfdGFibGVzX2FkZHIpIHdhcyBh ZGRlZCB0byB0aGUgZTgyMAo+IG1hcCBhcyBhbiBBQ1BJIGFyZWEgKHdoaWNoIGl0IHdpbGwgYmUp LCB0aGVuIGl0IHdvdWxkIGJlIG1hcHBlZCBwcm9wZXJseQo+IChpbiBib3RoIFNNRSBhbmQgU0VW KSB3aXRob3V0IG5lZWRpbmcgdGhlIGlmL3RoZW4vZWxzZS4KPiAKPj4gIAkJCQkJCWNsZW4gKyBz bG9wKTsKPj4gIAkJCW1lbWNweShkZXN0X3AgKyBzbG9wLCBzcmNfcCwgY2xlbik7Cj4+ICAJCQll YXJseV9tZW11bm1hcChkZXN0X3AsIGNsZW4gKyBzbG9wKTsKPj4gZGlmZiAtLWdpdCBhL2RyaXZl cnMvaW9tbXUvYW1kX2lvbW11X2luaXQuYyBiL2RyaXZlcnMvaW9tbXUvYW1kX2lvbW11X2luaXQu Ywo+PiBpbmRleCA5MDRjNTc1Li44ZWNiZGRiIDEwMDY0NAo+PiAtLS0gYS9kcml2ZXJzL2lvbW11 L2FtZF9pb21tdV9pbml0LmMKPj4gKysrIGIvZHJpdmVycy9pb21tdS9hbWRfaW9tbXVfaW5pdC5j Cj4+IEBAIC04ODksMTEgKzg4OSwxOCBAQCBzdGF0aWMgYm9vbCBjb3B5X2RldmljZV90YWJsZSh2 b2lkKQo+PiAgCX0KPj4gIAo+PiAgCW9sZF9kZXZ0Yl9waHlzID0gZW50cnkgJiBQQUdFX01BU0s7 Cj4+ICsJaWYgKHNtZV9hY3RpdmUoKSAmJiBpc19rZHVtcF9rZXJuZWwoKSkKPiAKPiBVc2UgbWVt X2VuY3J5cHRfYWN0aXZlKCkgaGVyZSB0byBjb3ZlciBib3RoIFNNRSBhbmQgU0VWLgo+IAo+PiAr CQlvbGRfZGV2dGJfcGh5cyA9IF9fc21lX2NscihvbGRfZGV2dGJfcGh5cyk7Cj4+ICAJaWYgKG9s ZF9kZXZ0Yl9waHlzID49IDB4MTAwMDAwMDAwVUxMKSB7Cj4+ICAJCXByX2VycigiVGhlIGFkZHJl c3Mgb2Ygb2xkIGRldmljZSB0YWJsZSBpcyBhYm92ZSA0Rywgbm90IHRydXN0d29ydGh5IVxuIik7 Cj4+ICAJCXJldHVybiBmYWxzZTsKPj4gIAl9Cj4+IC0Jb2xkX2RldnRiID0gbWVtcmVtYXAob2xk X2RldnRiX3BoeXMsIGRldl90YWJsZV9zaXplLCBNRU1SRU1BUF9XQik7Cj4+ICsJaWYgKHNtZV9h Y3RpdmUoKSAmJiBpc19rZHVtcF9rZXJuZWwoKSkKPj4gKwkJb2xkX2RldnRiID0gaW9yZW1hcF9l bmNyeXB0ZWQob2xkX2RldnRiX3BoeXMsCj4+ICsJCQkJCWRldl90YWJsZV9zaXplKTsKPj4gKwll bHNlCj4+ICsJCW9sZF9kZXZ0YiA9IG1lbXJlbWFwKG9sZF9kZXZ0Yl9waHlzLAo+PiArCQkJCQlk ZXZfdGFibGVfc2l6ZSwgTUVNUkVNQVBfV0IpOwo+IAo+IFdoYXQgaGFwcGVucyB0byB0aGUgbWVt cmVtYXAgaGVyZSwgZG9lcyBpdCBmYWxsIGJhY2sgdG8gdGhlIGlvcmVtYXAgYW5kCj4gZW5kIHVw IGdldHRpbmcgbWFwcGVkIGRlY3J5cHRlZD8gIEl0IHdvdWxkIGJlIG5pY2UgdG8gZG8gdGhlIHJp Z2h0IHRoaW5nCj4gdW5kZXIgdGhlIGNvdmVycyBvZiBtZW1yZW1hcC4gIE5vdCBzdXJlIHdoYXQg dGhhdCB3b3VsZCB0YWtlLCBidXQgaXQgd291bGQKPiBrZWVwIHRoZSBjb2RlIG5pY2UgYW5kIGNs ZWFuLgo+IApUaGFuayB5b3UsIFRvbS4KRm9yIHRoaXMgaXNzdWUsIGl0IHdpbGwgY29weSB0aGUg b2xkIGNvbnRlbnQgb2YgZGV2aWNlIHRhYmxlIGVudHJpZXMsIHRoYXQgaXMgdG8Kc2F5LCBpdCB3 aWxsIGNvcHkgdGhlIGRldmljZSB0YWJsZSBmcm9tIHRoZSBmaXJzdCBrZXJuZWwgdG8gdGhlIHNl Y29uZCBrZXJuZWwgaW4Ka2R1bXAgbW9kZSBhbmQgdGhlIGNvbnRlbnQgb2YgZGV2aWNlIHRhYmxl IGlzIGVuY3J5cHRlZCwgdGhlIGFkZHJlc3MgaW5jbHVkZXMgdGhlCnNtZV9tZV9tYXNrLiBGb3Ig dGhlIG9sZCBtZW1vcnkgZW5jcnlwdGVkLCBpdCBpcyBzdWl0YWJsZSB0byB1c2UgaW9yZW1hcF9l bmNyeXB0ZWQsCnRoZSBrZHVtcCBrZXJuZWwgY2FuIG5vdCBkaXJlY3RseSBhY2Nlc3MgdGhlIGZp cnN0IGtlcm5lbCdzIG1lbW9yeS4KCkxpYW5ibwo+PiAgCWlmICghb2xkX2RldnRiKQo+PiAgCQly ZXR1cm4gZmFsc2U7Cj4+ICAKPj4gZGlmZiAtLWdpdCBhL2ZzL3Byb2Mvdm1jb3JlLmMgYi9mcy9w cm9jL3ZtY29yZS5jCj4+IGluZGV4IGE0NWYwYWYuLjMxNmUyYjAgMTAwNjQ0Cj4+IC0tLSBhL2Zz L3Byb2Mvdm1jb3JlLmMKPj4gKysrIGIvZnMvcHJvYy92bWNvcmUuYwo+PiBAQCAtMjUsNiArMjUs MTAgQEAKPj4gICNpbmNsdWRlIDxsaW51eC91YWNjZXNzLmg+Cj4+ICAjaW5jbHVkZSA8YXNtL2lv Lmg+Cj4+ICAjaW5jbHVkZSAiaW50ZXJuYWwuaCIKPj4gKyNpZmRlZiBDT05GSUdfQU1EX01FTV9F TkNSWVBUCj4+ICsjaW5jbHVkZSA8bGludXgvbWVtX2VuY3J5cHQuaD4KPj4gKyNpbmNsdWRlIDxh c20vcGd0YWJsZS5oPgo+PiArI2VuZGlmCj4+ICAKPj4gIC8qIExpc3QgcmVwcmVzZW50aW5nIGNo dW5rcyBvZiBjb250aWd1b3VzIG1lbW9yeSBhcmVhcyBhbmQgdGhlaXIgb2Zmc2V0cyBpbgo+PiAg ICogdm1jb3JlIGZpbGUuCj4+IEBAIC04Niw3ICs5MCw4IEBAIHN0YXRpYyBpbnQgcGZuX2lzX3Jh bSh1bnNpZ25lZCBsb25nIHBmbikKPj4gIAo+PiAgLyogUmVhZHMgYSBwYWdlIGZyb20gdGhlIG9s ZG1lbSBkZXZpY2UgZnJvbSBnaXZlbiBvZmZzZXQuICovCj4+ICBzdGF0aWMgc3NpemVfdCByZWFk X2Zyb21fb2xkbWVtKGNoYXIgKmJ1Ziwgc2l6ZV90IGNvdW50LAo+PiAtCQkJCXU2NCAqcHBvcywg aW50IHVzZXJidWYpCj4+ICsJCQkJdTY0ICpwcG9zLCBpbnQgdXNlcmJ1ZiwKPj4gKwkJCQlib29s IGVuY3J5cHRlZCkKPj4gIHsKPj4gIAl1bnNpZ25lZCBsb25nIHBmbiwgb2Zmc2V0Owo+PiAgCXNp emVfdCBucl9ieXRlczsKPj4gQEAgLTEwOCw4ICsxMTMsMTUgQEAgc3RhdGljIHNzaXplX3QgcmVh ZF9mcm9tX29sZG1lbShjaGFyICpidWYsIHNpemVfdCBjb3VudCwKPj4gIAkJaWYgKHBmbl9pc19y YW0ocGZuKSA9PSAwKQo+PiAgCQkJbWVtc2V0KGJ1ZiwgMCwgbnJfYnl0ZXMpOwo+PiAgCQllbHNl IHsKPj4gLQkJCXRtcCA9IGNvcHlfb2xkbWVtX3BhZ2UocGZuLCBidWYsIG5yX2J5dGVzLAo+PiAr I2lmZGVmIENPTkZJR19BTURfTUVNX0VOQ1JZUFQKPj4gKwkJCWlmIChlbmNyeXB0ZWQpCj4+ICsJ CQkJdG1wID0gY29weV9vbGRtZW1fcGFnZV9lbmNyeXB0ZWQocGZuLCBidWYsCj4+ICsJCQkJCSAg ICAgICBucl9ieXRlcywgb2Zmc2V0LCB1c2VyYnVmKTsKPj4gKwkJCWVsc2UKPj4gKyNlbmRpZgo+ PiArCQkJCXRtcCA9IGNvcHlfb2xkbWVtX3BhZ2UocGZuLCBidWYsIG5yX2J5dGVzLAo+PiAgCQkJ CQkJb2Zmc2V0LCB1c2VyYnVmKTs+ICsKPj4gIAkJCWlmICh0bXAgPCAwKQo+PiAgCQkJCXJldHVy biB0bXA7Cj4+ICAJCX0KPj4gQEAgLTE0Myw3ICsxNTUsNyBAQCB2b2lkIF9fd2VhayBlbGZjb3Jl aGRyX2ZyZWUodW5zaWduZWQgbG9uZyBsb25nIGFkZHIpCj4+ICAgKi8KPj4gIHNzaXplX3QgX193 ZWFrIGVsZmNvcmVoZHJfcmVhZChjaGFyICpidWYsIHNpemVfdCBjb3VudCwgdTY0ICpwcG9zKQo+ PiAgewo+PiAtCXJldHVybiByZWFkX2Zyb21fb2xkbWVtKGJ1ZiwgY291bnQsIHBwb3MsIDApOwo+ PiArCXJldHVybiByZWFkX2Zyb21fb2xkbWVtKGJ1ZiwgY291bnQsIHBwb3MsIDAsIGZhbHNlKTsK PiAKPiBGb3IgU0VWLCB0aGlzIHdpbGwgbGlrZWx5IGJlIGVuY3J5cHRlZCwgc28geW91IGNhbiBw cm9iYWJseSByZXBsYWNlIHRoZQo+ICJmYWxzZSIgd2l0aCBzZXZfYWN0aXZlKCkgc28gdGhhdCB1 bmRlciBTTUUgaXQgaXMgdW4tZW5jcnlwdGVkIGJ1dCB1bmRlcgo+IFNFViBpdCBpcyBlbmNyeXB0 ZWQuICBXaGVyZSBpcyB0aGUgZWxmY29yZWhkciBzdG9yZWQ/ICBJIHdvbmRlciBpZiBpdAo+IGNv dWxkIGJlIGNyZWF0ZWQgYXMgZW5jcnlwdGVkIHVuZGVyIFNNRSBhbmQgdGhlbiB5b3UgY291bGQg YWN0dWFsbHkgcmVtb3ZlCj4gdGhlIGVuY3J5cHRlZCBwYXJhbWV0ZXIgZnJvbSByZWFkX2Zyb21f b2xkbWVtKCkgYW5kIGFsd2F5cyBtYXAgZW5jcnlwdGVkLgo+IElmIFNNRSBvciBTRVYgYXJlIGFj dGl2ZSBpdCB3aWxsIGJlIG1hcHBlZCBlbmNyeXB0ZWQgYW5kIGlmIHRoZXkgYXJlbid0Cj4gdGhl biBpdCBpcyBtYXBwZWQgbm9ybWFsbHkuCj4gCj4+ICB9Cj4+ICAKPj4gIC8qCj4+IEBAIC0xNTEs NyArMTYzLDExIEBAIHNzaXplX3QgX193ZWFrIGVsZmNvcmVoZHJfcmVhZChjaGFyICpidWYsIHNp emVfdCBjb3VudCwgdTY0ICpwcG9zKQo+PiAgICovCj4+ICBzc2l6ZV90IF9fd2VhayBlbGZjb3Jl aGRyX3JlYWRfbm90ZXMoY2hhciAqYnVmLCBzaXplX3QgY291bnQsIHU2NCAqcHBvcykKPj4gIHsK Pj4gLQlyZXR1cm4gcmVhZF9mcm9tX29sZG1lbShidWYsIGNvdW50LCBwcG9zLCAwKTsKPj4gKwli b29sIGZsYWcgPSBmYWxzZTsKPj4gKyNpZmRlZiBDT05GSUdfQU1EX01FTV9FTkNSWVBUCj4+ICsJ ZmxhZyA9IHNtZV9hY3RpdmUoKTsKPj4gKyNlbmRpZgo+PiArCXJldHVybiByZWFkX2Zyb21fb2xk bWVtKGJ1ZiwgY291bnQsIHBwb3MsIDAsIGZsYWcpOwo+PiAgfQo+PiAgCj4+ICAvKgo+PiBAQCAt MTYxLDYgKzE3NywxMCBAQCBpbnQgX193ZWFrIHJlbWFwX29sZG1lbV9wZm5fcmFuZ2Uoc3RydWN0 IHZtX2FyZWFfc3RydWN0ICp2bWEsCj4+ICAJCQkJICB1bnNpZ25lZCBsb25nIGZyb20sIHVuc2ln bmVkIGxvbmcgcGZuLAo+PiAgCQkJCSAgdW5zaWduZWQgbG9uZyBzaXplLCBwZ3Byb3RfdCBwcm90 KQo+PiAgewo+PiArI2lmZGVmIENPTkZJR19BTURfTUVNX0VOQ1JZUFQKPj4gKwlpZiAoc21lX2Fj dGl2ZSgpKQo+IAo+IE5vIG5lZWQgZm9yIHRoZSBzbWVfYWN0aXZlKCkgY2hlY2sgaGVyZSwgdGhl IGVuY3J5cHRpb24gd2lsbCBiZSBhcHBsaWVkLAo+IGZvciBib3RoIFNNRSBhbmQgU0VWLCBpZiBt ZW1vcnkgZW5jcnlwdGlvbiBpcyBhY3RpdmUsIG90aGVyd2lzZSBpdCB3b24ndC4KPiAKPj4gKwkJ cHJvdCA9IF9fcGdwcm90KHBncHJvdF92YWwocHJvdCkgfCBfUEFHRV9FTkMpOwo+IAo+ICAgcHJv dCA9IHBncHJvdF9lbmNyeXB0ZWQocHJvdCk7Cj4gCj4+ICsjZW5kaWY+ICAJcmV0dXJuIHJlbWFw X3Bmbl9yYW5nZSh2bWEsIGZyb20sIHBmbiwgc2l6ZSwgcHJvdCk7Cj4+ICB9Cj4+ICAKPj4gQEAg LTE4OCw2ICsyMDgsMTEgQEAgc3RhdGljIHNzaXplX3QgX19yZWFkX3ZtY29yZShjaGFyICpidWZm ZXIsIHNpemVfdCBidWZsZW4sIGxvZmZfdCAqZnBvcywKPj4gIAlzaXplX3QgdHN6Owo+PiAgCXU2 NCBzdGFydDsKPj4gIAlzdHJ1Y3Qgdm1jb3JlICptID0gTlVMTDsKPj4gKwlib29sIHNtZV9mbGFn ID0gZmFsc2U7Cj4+ICsKPj4gKyNpZmRlZiBDT05GSUdfQU1EX01FTV9FTkNSWVBUCj4+ICsJc21l X2ZsYWcgPSBzbWVfYWN0aXZlKCk7PiArI2VuZGlmCj4gCj4gUHJvYmFibHkganVzdCB3YW50IG1l bV9lbmNyeXB0X2FjdGl2ZSgpIGhlcmUgdG8gZ2V0IGJvdGggU01FIGFuZCBTRVYKPiBjYXNlcyBt YXBwZWQgYXMgZW5jcnlwdGVkLgo+IAo+IFRoYW5rcywKPiBUb20KPiAKPj4gIAo+PiAgCWlmIChi dWZsZW4gPT0gMCB8fCAqZnBvcyA+PSB2bWNvcmVfc2l6ZSkKPj4gIAkJcmV0dXJuIDA7Cj4+IEBA IC0yMzUsNyArMjYwLDggQEAgc3RhdGljIHNzaXplX3QgX19yZWFkX3ZtY29yZShjaGFyICpidWZm ZXIsIHNpemVfdCBidWZsZW4sIGxvZmZfdCAqZnBvcywKPj4gIAkJCQkJICAgIG0tPm9mZnNldCAr IG0tPnNpemUgLSAqZnBvcywKPj4gIAkJCQkJICAgIGJ1Zmxlbik7Cj4+ICAJCQlzdGFydCA9IG0t PnBhZGRyICsgKmZwb3MgLSBtLT5vZmZzZXQ7Cj4+IC0JCQl0bXAgPSByZWFkX2Zyb21fb2xkbWVt KGJ1ZmZlciwgdHN6LCAmc3RhcnQsIHVzZXJidWYpOwo+PiArCQkJdG1wID0gcmVhZF9mcm9tX29s ZG1lbShidWZmZXIsIHRzeiwgJnN0YXJ0LAo+PiArCQkJCQkJdXNlcmJ1Ziwgc21lX2ZsYWcpOwo+ PiAgCQkJaWYgKHRtcCA8IDApCj4+ICAJCQkJcmV0dXJuIHRtcDsKPj4gIAkJCWJ1ZmxlbiAtPSB0 c3o7Cj4+IGRpZmYgLS1naXQgYS9pbmNsdWRlL2xpbnV4L2NyYXNoX2R1bXAuaCBiL2luY2x1ZGUv bGludXgvY3Jhc2hfZHVtcC5oCj4+IGluZGV4IGY3YWMyYWEuLjAyNGFlOWUgMTAwNjQ0Cj4+IC0t LSBhL2luY2x1ZGUvbGludXgvY3Jhc2hfZHVtcC5oCj4+ICsrKyBiL2luY2x1ZGUvbGludXgvY3Jh c2hfZHVtcC5oCj4+IEBAIC0yNSw2ICsyNSwxMCBAQCBleHRlcm4gaW50IHJlbWFwX29sZG1lbV9w Zm5fcmFuZ2Uoc3RydWN0IHZtX2FyZWFfc3RydWN0ICp2bWEsCj4+ICAKPj4gIGV4dGVybiBzc2l6 ZV90IGNvcHlfb2xkbWVtX3BhZ2UodW5zaWduZWQgbG9uZywgY2hhciAqLCBzaXplX3QsCj4+ICAJ CQkJCQl1bnNpZ25lZCBsb25nLCBpbnQpOwo+PiArI2lmZGVmIENPTkZJR19BTURfTUVNX0VOQ1JZ UFQKPj4gK2V4dGVybiBzc2l6ZV90IGNvcHlfb2xkbWVtX3BhZ2VfZW5jcnlwdGVkKHVuc2lnbmVk IGxvbmcsIGNoYXIgKiwgc2l6ZV90LAo+PiArCQkJCQkJdW5zaWduZWQgbG9uZywgaW50KTsKPj4g KyNlbmRpZgo+PiAgdm9pZCB2bWNvcmVfY2xlYW51cCh2b2lkKTsKPj4gIAo+PiAgLyogQXJjaGl0 ZWN0dXJlIGNvZGUgZGVmaW5lcyB0aGlzIGlmIHRoZXJlIGFyZSBvdGhlciBwb3NzaWJsZSBFTEYK Pj4gZGlmZiAtLWdpdCBhL2tlcm5lbC9rZXhlY19jb3JlLmMgYi9rZXJuZWwva2V4ZWNfY29yZS5j Cj4+IGluZGV4IDIwZmVmMWEuLjNjMjJhOWIgMTAwNjQ0Cj4+IC0tLSBhL2tlcm5lbC9rZXhlY19j b3JlLmMKPj4gKysrIGIva2VybmVsL2tleGVjX2NvcmUuYwo+PiBAQCAtNDcxLDYgKzQ3MSwxNiBA QCBzdGF0aWMgc3RydWN0IHBhZ2UgKmtpbWFnZV9hbGxvY19jcmFzaF9jb250cm9sX3BhZ2VzKHN0 cnVjdCBraW1hZ2UgKmltYWdlLAo+PiAgCQl9Cj4+ICAJfQo+PiAgCj4+ICsJaWYgKHBhZ2VzKSB7 Cj4+ICsJCXVuc2lnbmVkIGludCBjb3VudCwgaTsKPj4gKwo+PiArCQlwYWdlcy0+bWFwcGluZyA9 IE5VTEw7Cj4+ICsJCXNldF9wYWdlX3ByaXZhdGUocGFnZXMsIG9yZGVyKTsKPj4gKwkJY291bnQg PSAxIDw8IG9yZGVyOwo+PiArCQlmb3IgKGkgPSAwOyBpIDwgY291bnQ7IGkrKykKPj4gKwkJCVNl dFBhZ2VSZXNlcnZlZChwYWdlcyArIGkpOwo+PiArCQlhcmNoX2tleGVjX3Bvc3RfYWxsb2NfcGFn ZXMocGFnZV9hZGRyZXNzKHBhZ2VzKSwgMSA8PCBvcmRlciwgMCk7Cj4+ICsJfQo+PiAgCXJldHVy biBwYWdlczsKPj4gIH0KPj4gIAo+PiBAQCAtODY1LDYgKzg3NSw3IEBAIHN0YXRpYyBpbnQga2lt YWdlX2xvYWRfY3Jhc2hfc2VnbWVudChzdHJ1Y3Qga2ltYWdlICppbWFnZSwKPj4gIAkJCXJlc3Vs dCAgPSAtRU5PTUVNOwo+PiAgCQkJZ290byBvdXQ7Cj4+ICAJCX0KPj4gKwkJYXJjaF9rZXhlY19w b3N0X2FsbG9jX3BhZ2VzKHBhZ2VfYWRkcmVzcyhwYWdlKSwgMSwgMCk7Cj4+ICAJCXB0ciA9IGtt YXAocGFnZSk7Cj4+ICAJCXB0ciArPSBtYWRkciAmIH5QQUdFX01BU0s7Cj4+ICAJCW1jaHVuayA9 IG1pbl90KHNpemVfdCwgbWJ5dGVzLAo+PiBAQCAtODgyLDYgKzg5Myw3IEBAIHN0YXRpYyBpbnQg a2ltYWdlX2xvYWRfY3Jhc2hfc2VnbWVudChzdHJ1Y3Qga2ltYWdlICppbWFnZSwKPj4gIAkJCXJl c3VsdCA9IGNvcHlfZnJvbV91c2VyKHB0ciwgYnVmLCB1Y2h1bmspOwo+PiAgCQlrZXhlY19mbHVz aF9pY2FjaGVfcGFnZShwYWdlKTsKPj4gIAkJa3VubWFwKHBhZ2UpOwo+PiArCQlhcmNoX2tleGVj X3ByZV9mcmVlX3BhZ2VzKHBhZ2VfYWRkcmVzcyhwYWdlKSwgMSk7Cj4+ICAJCWlmIChyZXN1bHQp IHsKPj4gIAkJCXJlc3VsdCA9IC1FRkFVTFQ7Cj4+ICAJCQlnb3RvIG91dDsKPj4KCl9fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCmtleGVjIG1haWxpbmcgbGlz dAprZXhlY0BsaXN0cy5pbmZyYWRlYWQub3JnCmh0dHA6Ly9saXN0cy5pbmZyYWRlYWQub3JnL21h aWxtYW4vbGlzdGluZm8va2V4ZWMK