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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D3F71C433EF for ; Sun, 10 Jul 2022 14:33:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229534AbiGJOdL (ORCPT ); Sun, 10 Jul 2022 10:33:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46702 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229469AbiGJOdK (ORCPT ); Sun, 10 Jul 2022 10:33:10 -0400 Received: from out30-45.freemail.mail.aliyun.com (out30-45.freemail.mail.aliyun.com [115.124.30.45]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BD80512AEE for ; Sun, 10 Jul 2022 07:33:06 -0700 (PDT) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R391e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=ay29a033018046059;MF=guanghuifeng@linux.alibaba.com;NM=1;PH=DS;RN=21;SR=0;TI=SMTPD_---0VIrYmg6_1657463579; Received: from 30.32.64.246(mailfrom:guanghuifeng@linux.alibaba.com fp:SMTPD_---0VIrYmg6_1657463579) by smtp.aliyun-inc.com; Sun, 10 Jul 2022 22:33:01 +0800 Message-ID: <999cc14c-9fa4-5edb-ef56-160904a5c16e@linux.alibaba.com> Date: Sun, 10 Jul 2022 22:32:59 +0800 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Thunderbird/91.11.0 Subject: Re: [PATCH v5] arm64: mm: fix linear mem mapping access performance degradation From: "guanghui.fgh" To: baolin.wang@linux.alibaba.com, catalin.marinas@arm.com, will@kernel.org, akpm@linux-foundation.org, david@redhat.com, jianyong.wu@arm.com, james.morse@arm.com, quic_qiancai@quicinc.com, christophe.leroy@csgroup.eu, jonathan@marek.ca, mark.rutland@arm.com, thunder.leizhen@huawei.com, anshuman.khandual@arm.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, rppt@kernel.org, geert+renesas@glider.be, ardb@kernel.org, linux-mm@kvack.org, yaohongbo@linux.alibaba.com Cc: alikernel-developer@linux.alibaba.com References: <1657460657-25698-1-git-send-email-guanghuifeng@linux.alibaba.com> In-Reply-To: <1657460657-25698-1-git-send-email-guanghuifeng@linux.alibaba.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi, Mike Rapoport, Catalin Marinas, I have rewrited the patch to handle tlb conflict and Circular dependency. Namely, (1)When doing work for rebuiling crashkernel mem, the pgd is swapper_pg_dir in use. (2)Firstly, I change the swapper_pg_dir pgd to idmap_pg_dir. As idmap_pg_dir use ttbr0_el1 and without any tlb confict in ttbr1_el1. Afterward I flush all the tlb(all the swapper_pg_dir tlb cache flushed). Later, I change idmap_pg_dir pgd to use init_pg_dir and flush tlb again. Therefor, there is no tlb conflict when rebuiding with init_pg_dir(without any tlb cache for swapper_pg_dir). (3)When switch to init_pg_dir, I can saftely modify swapper_pg_dir pagetable withou any [[[Circular dependency]]] and tlb conflict. Namely, When unmapping or modifying any swapper_pg_dir pagetable, I will use fix map to access the mem. I have test it and work well. Could you give me some advice? Thanks. 在 2022/7/10 21:44, Guanghui Feng 写道: > The arm64 can build 2M/1G block/sectiion mapping. When using DMA/DMA32 zone > (enable crashkernel, disable rodata full, disable kfence), the mem_map will > use non block/section mapping(for crashkernel requires to shrink the region > in page granularity). But it will degrade performance when doing larging > continuous mem access in kernel(memcpy/memmove, etc). > > There are many changes and discussions: > commit 031495635b46 ("arm64: Do not defer reserve_crashkernel() for > platforms with no DMA memory zones") > commit 0a30c53573b0 ("arm64: mm: Move reserve_crashkernel() into > mem_init()") > commit 2687275a5843 ("arm64: Force NO_BLOCK_MAPPINGS if crashkernel > reservation is required") > > This patch changes mem_map to use block/section mapping with crashkernel. > Firstly, do block/section mapping(normally 2M or 1G) for all avail mem at > mem_map, reserve crashkernel memory. And then walking pagetable to split > block/section mapping to non block/section mapping(normally 4K) [[[only]]] > for crashkernel mem. So the linear mem mapping use block/section mapping > as more as possible. We will reduce the cpu dTLB miss conspicuously, and > accelerate mem access about 10-20% performance improvement. > > I have tested it with pft(Page Fault Test) and fio, obtained great > performace improvement. > > For fio test: > 1.prepare ramdisk > modprobe -r brd > modprobe brd rd_nr=1 rd_size=67108864 > dmsetup remove_all > wipefs -a --force /dev/ram0 > mkfs -t ext4 -E lazy_itable_init=0,lazy_journal_init=0 -q -F /dev/ram0 > mkdir -p /fs/ram0 > mount -t ext4 /dev/ram0 /fs/ram0 > > 2.prepare fio paremeter in x.fio file: > [global] > bs=4k > ioengine=psync > iodepth=128 > size=32G > direct=1 > invalidate=1 > group_reporting > thread=1 > rw=read > directory=/fs/ram0 > numjobs=1 > > [task_0] > cpus_allowed=16 > stonewall=1 > > 3.run testcase: > perf stat -e dTLB-load-misses fio x.fio > > 4.contrast > ------------------------ > without patch with patch > fio READ aggrb=1493.2MB/s aggrb=1775.3MB/s > dTLB-load-misses 1,818,320,693 438,729,774 > time elapsed(s) 70.500326434 62.877316408 > user(s) 15.926332000 15.684721000 > sys(s) 54.211939000 47.046165000 > > 5.conclusion > Using this patch will reduce dTLB misses and improve performace greatly. > > Signed-off-by: Guanghui Feng > --- > arch/arm64/include/asm/mmu.h | 1 + > arch/arm64/include/asm/mmu_context.h | 28 ++++ > arch/arm64/mm/init.c | 8 +- > arch/arm64/mm/mmu.c | 305 +++++++++++++++++++++++++---------- > arch/arm64/mm/proc.S | 19 +++ > 5 files changed, 267 insertions(+), 94 deletions(-) > > diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h > index 48f8466..1a46b81 100644 > --- a/arch/arm64/include/asm/mmu.h > +++ b/arch/arm64/include/asm/mmu.h > @@ -63,6 +63,7 @@ static inline bool arm64_kernel_unmapped_at_el0(void) > extern void arm64_memblock_init(void); > extern void paging_init(void); > extern void bootmem_init(void); > +extern void map_crashkernel(void); > extern void __iomem *early_io_map(phys_addr_t phys, unsigned long virt); > extern void init_mem_pgprot(void); > extern void create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys, > diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h > index 6770667..10dffd4 100644 > --- a/arch/arm64/include/asm/mmu_context.h > +++ b/arch/arm64/include/asm/mmu_context.h > @@ -139,6 +139,34 @@ static inline void cpu_install_ttbr0(phys_addr_t ttbr0, unsigned long t0sz) > isb(); > } > > +static inline void __nocfi cpu_replace_ttbr1_with_phys(phys_addr_t ttbr1) > +{ > + typedef void (ttbr_replace_func)(phys_addr_t); > + extern ttbr_replace_func idmap_cpu_replace_ttbr1_with_flush_tlb; > + ttbr_replace_func *replace_phys; > + > + /* phys_to_ttbr() zeros lower 2 bits of ttbr with 52-bit PA */ > + ttbr1 = phys_to_ttbr(ttbr1); > + > + if (system_supports_cnp()) { > + /* > + * cpu_replace_ttbr1() is used when there's a boot CPU > + * up (i.e. cpufeature framework is not up yet) and > + * latter only when we enable CNP via cpufeature's > + * enable() callback. > + * Also we rely on the cpu_hwcap bit being set before > + * calling the enable() function. > + */ > + ttbr1 |= TTBR_CNP_BIT; > + } > + > + replace_phys = (void *)__pa_symbol(function_nocfi(idmap_cpu_replace_ttbr1_with_flush_tlb)); > + > + cpu_install_idmap(); > + replace_phys(ttbr1); > + cpu_uninstall_idmap(); cpu_install_idmap will Swtich to use idmap_pg_dir with use [[[ttbr0_el1]]]. swapper_gp_dir use the [[[ttbr1_el0]]], so there is no tlb conflit to idmap_pg_dir(the different address space range). When switching to idmap_pg_dir, there also will be a tlb flush all. Afterward, the idmap_cpu_replace_ttbr1_with_flush_tlb will run in idmap_pg_dir pgd and change the pgd to another pgd complying with the parameter ttbr1. So, there is no tlb conflict when switching pgd. Namely, I can change ttbr1 pgd safely without any tlb conflict. > +} > + > /* > * Atomically replaces the active TTBR1_EL1 PGD with a new VA-compatible PGD, > * avoiding the possibility of conflicting TLB entries being allocated. > diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c > index 339ee84..241d27e 100644 > --- a/arch/arm64/mm/init.c > +++ b/arch/arm64/mm/init.c > @@ -190,6 +190,7 @@ static void __init reserve_crashkernel(void) > crashk_res.start = crash_base; > crashk_res.end = crash_base + crash_size - 1; > insert_resource(&iomem_resource, &crashk_res); > + map_crashkernel(); > } > > /* > @@ -388,10 +389,6 @@ void __init arm64_memblock_init(void) > } > > early_init_fdt_scan_reserved_mem(); > - > - if (!IS_ENABLED(CONFIG_ZONE_DMA) && !IS_ENABLED(CONFIG_ZONE_DMA32)) > - reserve_crashkernel(); > - > high_memory = __va(memblock_end_of_DRAM() - 1) + 1; > } > > @@ -438,8 +435,7 @@ void __init bootmem_init(void) > * request_standard_resources() depends on crashkernel's memory being > * reserved, so do it here. > */ > - if (IS_ENABLED(CONFIG_ZONE_DMA) || IS_ENABLED(CONFIG_ZONE_DMA32)) > - reserve_crashkernel(); > + reserve_crashkernel(); > > memblock_dump_all(); > } > diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c > index 626ec32..3e30c82 100644 > --- a/arch/arm64/mm/mmu.c > +++ b/arch/arm64/mm/mmu.c > @@ -42,6 +42,7 @@ > #define NO_BLOCK_MAPPINGS BIT(0) > #define NO_CONT_MAPPINGS BIT(1) > #define NO_EXEC_MAPPINGS BIT(2) /* assumes FEAT_HPDS is not used */ > +#define NO_SEC_REMAPPINGS BIT(3) /* rebuild with non block/sec mapping*/ > > u64 idmap_t0sz = TCR_T0SZ(VA_BITS_MIN); > u64 idmap_ptrs_per_pgd = PTRS_PER_PGD; > @@ -155,8 +156,22 @@ static bool pgattr_change_is_safe(u64 old, u64 new) > return ((old ^ new) & ~mask) == 0; > } > > +static void pte_clear_cont(pte_t *ptep) > +{ > + int i = 0; > + pte_t pte = READ_ONCE(*ptep); > + if (pte_none(pte) || !pte_cont(pte)) > + return; > + ptep -= ((u64)ptep / sizeof(pte_t)) & > + ((1 << CONFIG_ARM64_CONT_PTE_SHIFT) - 1); > + do { > + pte = pte_mknoncont(READ_ONCE(*ptep)); > + set_pte(ptep, pte); > + } while (++ptep, ++i < CONT_PTES); > +} > + > static void init_pte(pmd_t *pmdp, unsigned long addr, unsigned long end, > - phys_addr_t phys, pgprot_t prot) > + phys_addr_t phys, pgprot_t prot, int flags) > { > pte_t *ptep; > > @@ -164,6 +179,9 @@ static void init_pte(pmd_t *pmdp, unsigned long addr, unsigned long end, > do { > pte_t old_pte = READ_ONCE(*ptep); > > + if (flags & NO_SEC_REMAPPINGS) > + pte_clear_cont(ptep); > + > set_pte(ptep, pfn_pte(__phys_to_pfn(phys), prot)); > > /* > @@ -179,6 +197,22 @@ static void init_pte(pmd_t *pmdp, unsigned long addr, unsigned long end, > pte_clear_fixmap(); > } > > +static inline void allock_pte_page(pmd_t *pmdp, > + phys_addr_t (*pgtable_alloc)(int), > + int flags) > +{ > + pmdval_t pmdval = PMD_TYPE_TABLE | PMD_TABLE_UXN; > + phys_addr_t pte_phys; > + if (!pmd_none(READ_ONCE(*pmdp))) > + return; > + > + if (flags & NO_EXEC_MAPPINGS) > + pmdval |= PMD_TABLE_PXN; > + BUG_ON(!pgtable_alloc); > + pte_phys = pgtable_alloc(PAGE_SHIFT); > + __pmd_populate(pmdp, pte_phys, pmdval); > +} > + > static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr, > unsigned long end, phys_addr_t phys, > pgprot_t prot, > @@ -189,17 +223,8 @@ static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr, > pmd_t pmd = READ_ONCE(*pmdp); > > BUG_ON(pmd_sect(pmd)); > - if (pmd_none(pmd)) { > - pmdval_t pmdval = PMD_TYPE_TABLE | PMD_TABLE_UXN; > - phys_addr_t pte_phys; > - > - if (flags & NO_EXEC_MAPPINGS) > - pmdval |= PMD_TABLE_PXN; > - BUG_ON(!pgtable_alloc); > - pte_phys = pgtable_alloc(PAGE_SHIFT); > - __pmd_populate(pmdp, pte_phys, pmdval); > - pmd = READ_ONCE(*pmdp); > - } > + allock_pte_page(pmdp, pgtable_alloc, flags); > + pmd = READ_ONCE(*pmdp); > BUG_ON(pmd_bad(pmd)); > > do { > @@ -208,16 +233,71 @@ static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr, > next = pte_cont_addr_end(addr, end); > > /* use a contiguous mapping if the range is suitably aligned */ > - if ((((addr | next | phys) & ~CONT_PTE_MASK) == 0) && > - (flags & NO_CONT_MAPPINGS) == 0) > + if (!(flags & NO_SEC_REMAPPINGS) && > + (((addr | next | phys) & ~CONT_PTE_MASK) == 0) && > + (flags & NO_CONT_MAPPINGS) == 0) > __prot = __pgprot(pgprot_val(prot) | PTE_CONT); > > - init_pte(pmdp, addr, next, phys, __prot); > + init_pte(pmdp, addr, next, phys, __prot, flags); > > phys += next - addr; > } while (addr = next, addr != end); > } > > +static void pmd_clear_cont(pmd_t *pmdp) > +{ > + int i = 0; > + pmd_t pmd = READ_ONCE(*pmdp); > + if (pmd_none(pmd) || !pmd_sect(pmd) || !pmd_cont(pmd)) > + return; > + pmdp -= ((u64)pmdp / sizeof(pmd_t)) & > + ((1 << CONFIG_ARM64_CONT_PMD_SHIFT) - 1); > + do { > + pmd = READ_ONCE(*pmdp); > + pmd = pte_pmd(pte_mknoncont(pmd_pte(pmd))); > + set_pmd(pmdp, pmd); > + } while (++pmdp, ++i < CONT_PMDS); > +} > + > +static void init_pmd_remap(pud_t *pudp, unsigned long addr, unsigned long end, > + phys_addr_t phys, pgprot_t prot, > + phys_addr_t (*pgtable_alloc)(int), int flags) > +{ > + unsigned long next; > + pmd_t *pmdp; > + phys_addr_t map_offset; > + > + pmdp = pmd_set_fixmap_offset(pudp, addr); > + do { > + next = pmd_addr_end(addr, end); > + > + if (!pmd_none(*pmdp) && pmd_sect(*pmdp)) { > + pmd_clear_cont(pmdp); > + pmd_clear(pmdp); > + allock_pte_page(pmdp, pgtable_alloc, flags); > + > + map_offset = addr - (addr & PMD_MASK); > + if (map_offset) > + alloc_init_cont_pte(pmdp, addr & PMD_MASK, addr, > + phys - map_offset, prot, > + pgtable_alloc, > + flags & (~NO_SEC_REMAPPINGS)); > + > + if (next < (addr & PMD_MASK) + PMD_SIZE) > + alloc_init_cont_pte(pmdp, next, > + (addr & PUD_MASK) + PUD_SIZE, > + next - addr + phys, > + prot, pgtable_alloc, > + flags & (~NO_SEC_REMAPPINGS)); > + } > + alloc_init_cont_pte(pmdp, addr, next, phys, prot, > + pgtable_alloc, flags); > + phys += next - addr; > + } while (pmdp++, addr = next, addr != end); > + > + pmd_clear_fixmap(); > +} > + > static void init_pmd(pud_t *pudp, unsigned long addr, unsigned long end, > phys_addr_t phys, pgprot_t prot, > phys_addr_t (*pgtable_alloc)(int), int flags) > @@ -255,6 +335,22 @@ static void init_pmd(pud_t *pudp, unsigned long addr, unsigned long end, > pmd_clear_fixmap(); > } > > +static inline void alloc_pmd_page(pud_t *pudp, phys_addr_t (*pgtable_alloc)(int), int flags) > +{ > + > + pudval_t pudval = PUD_TYPE_TABLE | PUD_TABLE_UXN; > + phys_addr_t pmd_phys; > + > + if (!pud_none(READ_ONCE(*pudp))) > + return; > + > + if (flags & NO_EXEC_MAPPINGS) > + pudval |= PUD_TABLE_PXN; > + BUG_ON(!pgtable_alloc); > + pmd_phys = pgtable_alloc(PMD_SHIFT); > + __pud_populate(pudp, pmd_phys, pudval); > +} > + > static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr, > unsigned long end, phys_addr_t phys, > pgprot_t prot, > @@ -267,17 +363,8 @@ static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr, > * Check for initial section mappings in the pgd/pud. > */ > BUG_ON(pud_sect(pud)); > - if (pud_none(pud)) { > - pudval_t pudval = PUD_TYPE_TABLE | PUD_TABLE_UXN; > - phys_addr_t pmd_phys; > - > - if (flags & NO_EXEC_MAPPINGS) > - pudval |= PUD_TABLE_PXN; > - BUG_ON(!pgtable_alloc); > - pmd_phys = pgtable_alloc(PMD_SHIFT); > - __pud_populate(pudp, pmd_phys, pudval); > - pud = READ_ONCE(*pudp); > - } > + alloc_pmd_page(pudp, pgtable_alloc, flags); > + pud = READ_ONCE(*pudp); > BUG_ON(pud_bad(pud)); > > do { > @@ -286,16 +373,80 @@ static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr, > next = pmd_cont_addr_end(addr, end); > > /* use a contiguous mapping if the range is suitably aligned */ > - if ((((addr | next | phys) & ~CONT_PMD_MASK) == 0) && > + if (!(flags & NO_SEC_REMAPPINGS) && > + (((addr | next | phys) & ~CONT_PMD_MASK) == 0) && > (flags & NO_CONT_MAPPINGS) == 0) > __prot = __pgprot(pgprot_val(prot) | PTE_CONT); > > - init_pmd(pudp, addr, next, phys, __prot, pgtable_alloc, flags); > + if (flags & NO_SEC_REMAPPINGS) > + init_pmd_remap(pudp, addr, next, phys, __prot, > + pgtable_alloc, flags); > + else > + init_pmd(pudp, addr, next, phys, __prot, > + pgtable_alloc, flags); > > phys += next - addr; > } while (addr = next, addr != end); > } > > +static void init_pud_remap(pud_t *pudp, unsigned long addr, unsigned long next, > + phys_addr_t phys, pgprot_t prot, > + phys_addr_t (*pgtable_alloc)(int), > + int flags) > +{ > + phys_addr_t map_offset; > + > + if (!pud_none(*pudp) && pud_sect(*pudp)) { > + pud_clear(pudp); > + alloc_pmd_page(pudp, pgtable_alloc, flags); > + > + map_offset = addr - (addr & PUD_MASK); > + if (map_offset) > + alloc_init_cont_pmd(pudp, addr & PUD_MASK, > + addr, phys - map_offset, > + prot, pgtable_alloc, > + flags & (~NO_SEC_REMAPPINGS)); > + > + if (next < (addr & PUD_MASK) + PUD_SIZE) > + alloc_init_cont_pmd(pudp, next, > + (addr & PUD_MASK) + PUD_SIZE, > + next - addr + phys, > + prot, pgtable_alloc, > + flags & (~NO_SEC_REMAPPINGS)); > + } > + alloc_init_cont_pmd(pudp, addr, next, phys, prot, > + pgtable_alloc, flags); > +} > + > +static void init_pud(pud_t *pudp, unsigned long addr, unsigned long next, > + phys_addr_t phys, pgprot_t prot, > + phys_addr_t (*pgtable_alloc)(int), > + int flags) > +{ > + pud_t old_pud = READ_ONCE(*pudp); > + /* > + * For 4K granule only, attempt to put down a 1GB block > + */ > + if (pud_sect_supported() && > + ((addr | next | phys) & ~PUD_MASK) == 0 && > + (flags & NO_BLOCK_MAPPINGS) == 0) { > + pud_set_huge(pudp, phys, prot); > + > + /* > + * After the PUD entry has been populated once, we > + * only allow updates to the permission attributes. > + */ > + BUG_ON(!pgattr_change_is_safe(pud_val(old_pud), > + READ_ONCE(pud_val(*pudp)))); > + } else { > + alloc_init_cont_pmd(pudp, addr, next, phys, prot, > + pgtable_alloc, flags); > + > + BUG_ON(pud_val(old_pud) != 0 && > + pud_val(old_pud) != READ_ONCE(pud_val(*pudp))); > + } > +} > + > static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end, > phys_addr_t phys, pgprot_t prot, > phys_addr_t (*pgtable_alloc)(int), > @@ -325,37 +476,22 @@ static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end, > */ > if (system_state != SYSTEM_BOOTING) > mutex_lock(&fixmap_lock); > + > pudp = pud_set_fixmap_offset(p4dp, addr); > do { > - pud_t old_pud = READ_ONCE(*pudp); > - > next = pud_addr_end(addr, end); > > - /* > - * For 4K granule only, attempt to put down a 1GB block > - */ > - if (pud_sect_supported() && > - ((addr | next | phys) & ~PUD_MASK) == 0 && > - (flags & NO_BLOCK_MAPPINGS) == 0) { > - pud_set_huge(pudp, phys, prot); > - > - /* > - * After the PUD entry has been populated once, we > - * only allow updates to the permission attributes. > - */ > - BUG_ON(!pgattr_change_is_safe(pud_val(old_pud), > - READ_ONCE(pud_val(*pudp)))); > - } else { > - alloc_init_cont_pmd(pudp, addr, next, phys, prot, > - pgtable_alloc, flags); > - > - BUG_ON(pud_val(old_pud) != 0 && > - pud_val(old_pud) != READ_ONCE(pud_val(*pudp))); > - } > + if (flags & NO_SEC_REMAPPINGS) > + init_pud_remap(pudp, addr, next, phys, prot, > + pgtable_alloc, flags); > + else > + init_pud(pudp, addr, next, phys, prot, pgtable_alloc, > + flags); > phys += next - addr; > } while (pudp++, addr = next, addr != end); > > pud_clear_fixmap(); > + > if (system_state != SYSTEM_BOOTING) > mutex_unlock(&fixmap_lock); > } > @@ -483,20 +619,37 @@ void __init mark_linear_text_alias_ro(void) > PAGE_KERNEL_RO); > } > > -static bool crash_mem_map __initdata; > - > -static int __init enable_crash_mem_map(char *arg) > +#ifdef CONFIG_KEXEC_CORE > +void __init map_crashkernel(void) > { > - /* > - * Proper parameter parsing is done by reserve_crashkernel(). We only > - * need to know if the linear map has to avoid block mappings so that > - * the crashkernel reservations can be unmapped later. > - */ > - crash_mem_map = true; > + if (can_set_direct_map() || IS_ENABLED(CONFIG_KFENCE)) > + return; > > - return 0; > + if (!crashk_res.end) > + return; > + > + cpu_replace_ttbr1_with_phys(__pa_symbol(init_pg_dir)); > + init_mm.pgd = init_pg_dir; > + > + __create_pgd_mapping(swapper_pg_dir, crashk_res.start, > + __phys_to_virt(crashk_res.start), > + crashk_res.end + 1 - crashk_res.start, PAGE_KERNEL, > + early_pgtable_alloc, > + NO_EXEC_MAPPINGS | NO_SEC_REMAPPINGS); > + > + cpu_replace_ttbr1(lm_alias(swapper_pg_dir)); > + init_mm.pgd = swapper_pg_dir; > + > + memblock_phys_free(__pa_symbol(init_pg_dir), > + __pa_symbol(init_pg_end) - __pa_symbol(init_pg_dir)); > } Because unmap_hotplug_range work with swapper_gp_dir pgd. There are many changes needed for working with init_pg_dir pgd. So that I use the init_pg_dir and __create_pgd_mapping to direct walk/modify swapper_gp_dir pagetable. When finishing it, free the init_pg_dir memblock. > -early_param("crashkernel", enable_crash_mem_map); > +#else > +void __init map_crashkernel(void) > +{ > + memblock_phys_free(__pa_symbol(init_pg_dir), > + __pa_symbol(init_pg_end) - __pa_symbol(init_pg_dir)); > +} > +#endif > > static void __init map_mem(pgd_t *pgdp) > { > @@ -527,17 +680,6 @@ static void __init map_mem(pgd_t *pgdp) > */ > memblock_mark_nomap(kernel_start, kernel_end - kernel_start); > > -#ifdef CONFIG_KEXEC_CORE > - if (crash_mem_map) { > - if (IS_ENABLED(CONFIG_ZONE_DMA) || > - IS_ENABLED(CONFIG_ZONE_DMA32)) > - flags |= NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS; > - else if (crashk_res.end) > - memblock_mark_nomap(crashk_res.start, > - resource_size(&crashk_res)); > - } > -#endif > - > /* map all the memory banks */ > for_each_mem_range(i, &start, &end) { > if (start >= end) > @@ -570,19 +712,6 @@ static void __init map_mem(pgd_t *pgdp) > * in page granularity and put back unused memory to buddy system > * through /sys/kernel/kexec_crash_size interface. > */ > -#ifdef CONFIG_KEXEC_CORE > - if (crash_mem_map && > - !IS_ENABLED(CONFIG_ZONE_DMA) && !IS_ENABLED(CONFIG_ZONE_DMA32)) { > - if (crashk_res.end) { > - __map_memblock(pgdp, crashk_res.start, > - crashk_res.end + 1, > - PAGE_KERNEL, > - NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS); > - memblock_clear_nomap(crashk_res.start, > - resource_size(&crashk_res)); > - } > - } > -#endif > } > > void mark_rodata_ro(void) > @@ -774,8 +903,8 @@ void __init paging_init(void) > cpu_replace_ttbr1(lm_alias(swapper_pg_dir)); > init_mm.pgd = swapper_pg_dir; > > - memblock_phys_free(__pa_symbol(init_pg_dir), > - __pa_symbol(init_pg_end) - __pa_symbol(init_pg_dir)); > + //memblock_phys_free(__pa_symbol(init_pg_dir), > + // __pa_symbol(init_pg_end) - __pa_symbol(init_pg_dir)); > > memblock_allow_resize(); > } > diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S > index 50bbed9..161bae6 100644 > --- a/arch/arm64/mm/proc.S > +++ b/arch/arm64/mm/proc.S > @@ -178,6 +178,25 @@ SYM_FUNC_END(cpu_do_resume) > isb > .endm > > +SYM_FUNC_START(idmap_cpu_replace_ttbr1_with_flush_tlb) > + save_and_disable_daif flags=x2 > + > + __idmap_cpu_set_reserved_ttbr1 x1, x3 > + > + offset_ttbr1 x0, x3 > + msr ttbr1_el1, x0 > + isb > + > + restore_daif x2 > + > + dsb nshst > + tlbi vmalle1 > + dsb nsh > + isb > + > + ret > +SYM_FUNC_END(idmap_cpu_replace_ttbr1_with_flush_tlb) > + Switch ttbr1 to pgd(refer to x0), and flush tlb all. > /* > * void idmap_cpu_replace_ttbr1(phys_addr_t ttbr1) > * 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 3F1D9C43334 for ; Sun, 10 Jul 2022 14:34:27 +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-Type: Content-Transfer-Encoding:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:In-Reply-To:References:Cc:To:From:Subject: MIME-Version:Date:Message-ID:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=aiBkxv++rNGPjWICa91ACAcKnwxTTY2dWg4+TQhCRYw=; b=TTDAFnZZpzAXpc ECwiy3sFLYgp7xfBuk796H6iZqrWjuXydId1zExBJNY4iKc4s28XkPVel2Yorc7Xcj40GtE5N5sO9 j0UyuERyeC5fDBhjRXkVg8uc3q2SLGj5z9sGddX0DYVtgFqPxNKBoyGfVAxewKVqlbjRzmbE7jCxX Mi5DTAykpEqa3a8PM60v/cNCQU4dSE30ao/v3eGu2uvX82cuspXHRCe4Vk2eViHjPO9OWRzHj4qaj VTksE3n7u64wxOiz5ByKAxeXNmbl4VPto8+n/z07JNshcX+q4GDfYFLeAQ8bEzpSe9KI3+mIxOHwi vnn07D00Eelfz8E4oUwA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1oAXzn-00C1aR-4j; Sun, 10 Jul 2022 14:33:15 +0000 Received: from out30-56.freemail.mail.aliyun.com ([115.124.30.56]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1oAXzf-00C1Xf-RT for linux-arm-kernel@lists.infradead.org; Sun, 10 Jul 2022 14:33:13 +0000 X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R391e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=ay29a033018046059;MF=guanghuifeng@linux.alibaba.com;NM=1;PH=DS;RN=21;SR=0;TI=SMTPD_---0VIrYmg6_1657463579; Received: from 30.32.64.246(mailfrom:guanghuifeng@linux.alibaba.com fp:SMTPD_---0VIrYmg6_1657463579) by smtp.aliyun-inc.com; Sun, 10 Jul 2022 22:33:01 +0800 Message-ID: <999cc14c-9fa4-5edb-ef56-160904a5c16e@linux.alibaba.com> Date: Sun, 10 Jul 2022 22:32:59 +0800 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Thunderbird/91.11.0 Subject: Re: [PATCH v5] arm64: mm: fix linear mem mapping access performance degradation From: "guanghui.fgh" To: baolin.wang@linux.alibaba.com, catalin.marinas@arm.com, will@kernel.org, akpm@linux-foundation.org, david@redhat.com, jianyong.wu@arm.com, james.morse@arm.com, quic_qiancai@quicinc.com, christophe.leroy@csgroup.eu, jonathan@marek.ca, mark.rutland@arm.com, thunder.leizhen@huawei.com, anshuman.khandual@arm.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, rppt@kernel.org, geert+renesas@glider.be, ardb@kernel.org, linux-mm@kvack.org, yaohongbo@linux.alibaba.com Cc: alikernel-developer@linux.alibaba.com References: <1657460657-25698-1-git-send-email-guanghuifeng@linux.alibaba.com> In-Reply-To: <1657460657-25698-1-git-send-email-guanghuifeng@linux.alibaba.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220710_073309_902206_141F1E04 X-CRM114-Status: GOOD ( 37.61 ) 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-Transfer-Encoding: base64 Content-Type: text/plain; charset="utf-8"; Format="flowed" Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org SGksIE1pa2UgUmFwb3BvcnQsIENhdGFsaW4gTWFyaW5hcywgSSBoYXZlIHJld3JpdGVkIHRoZSBw YXRjaCB0byBoYW5kbGUgCnRsYiBjb25mbGljdCBhbmQgQ2lyY3VsYXIgZGVwZW5kZW5jeS4KTmFt ZWx5LAoKKDEpV2hlbiBkb2luZyB3b3JrIGZvciByZWJ1aWxpbmcgY3Jhc2hrZXJuZWwgbWVtLCB0 aGUgcGdkIGlzIApzd2FwcGVyX3BnX2RpciBpbiB1c2UuCgooMilGaXJzdGx5LCBJIGNoYW5nZSB0 aGUgc3dhcHBlcl9wZ19kaXIgcGdkIHRvIGlkbWFwX3BnX2Rpci4KICAgIEFzIGlkbWFwX3BnX2Rp ciB1c2UgdHRicjBfZWwxIGFuZCB3aXRob3V0IGFueSB0bGIgY29uZmljdCBpbiB0dGJyMV9lbDEu CkFmdGVyd2FyZCBJIGZsdXNoIGFsbCB0aGUgdGxiKGFsbCB0aGUgc3dhcHBlcl9wZ19kaXIgdGxi IGNhY2hlIGZsdXNoZWQpLgoKTGF0ZXIsIEkgY2hhbmdlIGlkbWFwX3BnX2RpciBwZ2QgdG8gdXNl IGluaXRfcGdfZGlyIGFuZCBmbHVzaCB0bGIgYWdhaW4uIApUaGVyZWZvciwgdGhlcmUgaXMgbm8g dGxiIGNvbmZsaWN0IHdoZW4gcmVidWlkaW5nIHdpdGggCmluaXRfcGdfZGlyKHdpdGhvdXQgYW55 IHRsYiBjYWNoZSBmb3Igc3dhcHBlcl9wZ19kaXIpLgoKKDMpV2hlbiBzd2l0Y2ggdG8gaW5pdF9w Z19kaXIsIEkgY2FuIHNhZnRlbHkgbW9kaWZ5IHN3YXBwZXJfcGdfZGlyIApwYWdldGFibGUgd2l0 aG91IGFueSBbW1tDaXJjdWxhciBkZXBlbmRlbmN5XV1dIGFuZCB0bGIgY29uZmxpY3QuCk5hbWVs eSwgV2hlbiB1bm1hcHBpbmcgb3IgbW9kaWZ5aW5nIGFueSBzd2FwcGVyX3BnX2RpciBwYWdldGFi bGUsIEkgd2lsbCAKdXNlIGZpeCBtYXAgdG8gYWNjZXNzIHRoZSBtZW0uCgpJIGhhdmUgdGVzdCBp dCBhbmQgd29yayB3ZWxsLiBDb3VsZCB5b3UgZ2l2ZSBtZSBzb21lIGFkdmljZT8KClRoYW5rcy4K CuWcqCAyMDIyLzcvMTAgMjE6NDQsIEd1YW5naHVpIEZlbmcg5YaZ6YGTOgo+IFRoZSBhcm02NCBj YW4gYnVpbGQgMk0vMUcgYmxvY2svc2VjdGlpb24gbWFwcGluZy4gV2hlbiB1c2luZyBETUEvRE1B MzIgem9uZQo+IChlbmFibGUgY3Jhc2hrZXJuZWwsIGRpc2FibGUgcm9kYXRhIGZ1bGwsIGRpc2Fi bGUga2ZlbmNlKSwgdGhlIG1lbV9tYXAgd2lsbAo+IHVzZSBub24gYmxvY2svc2VjdGlvbiBtYXBw aW5nKGZvciBjcmFzaGtlcm5lbCByZXF1aXJlcyB0byBzaHJpbmsgdGhlIHJlZ2lvbgo+IGluIHBh Z2UgZ3JhbnVsYXJpdHkpLiBCdXQgaXQgd2lsbCBkZWdyYWRlIHBlcmZvcm1hbmNlIHdoZW4gZG9p bmcgbGFyZ2luZwo+IGNvbnRpbnVvdXMgbWVtIGFjY2VzcyBpbiBrZXJuZWwobWVtY3B5L21lbW1v dmUsIGV0YykuCj4gCj4gVGhlcmUgYXJlIG1hbnkgY2hhbmdlcyBhbmQgZGlzY3Vzc2lvbnM6Cj4g Y29tbWl0IDAzMTQ5NTYzNWI0NiAoImFybTY0OiBEbyBub3QgZGVmZXIgcmVzZXJ2ZV9jcmFzaGtl cm5lbCgpIGZvcgo+IHBsYXRmb3JtcyB3aXRoIG5vIERNQSBtZW1vcnkgem9uZXMiKQo+IGNvbW1p dCAwYTMwYzUzNTczYjAgKCJhcm02NDogbW06IE1vdmUgcmVzZXJ2ZV9jcmFzaGtlcm5lbCgpIGlu dG8KPiBtZW1faW5pdCgpIikKPiBjb21taXQgMjY4NzI3NWE1ODQzICgiYXJtNjQ6IEZvcmNlIE5P X0JMT0NLX01BUFBJTkdTIGlmIGNyYXNoa2VybmVsCj4gcmVzZXJ2YXRpb24gaXMgcmVxdWlyZWQi KQo+IAo+IFRoaXMgcGF0Y2ggY2hhbmdlcyBtZW1fbWFwIHRvIHVzZSBibG9jay9zZWN0aW9uIG1h cHBpbmcgd2l0aCBjcmFzaGtlcm5lbC4KPiBGaXJzdGx5LCBkbyBibG9jay9zZWN0aW9uIG1hcHBp bmcobm9ybWFsbHkgMk0gb3IgMUcpIGZvciBhbGwgYXZhaWwgbWVtIGF0Cj4gbWVtX21hcCwgcmVz ZXJ2ZSBjcmFzaGtlcm5lbCBtZW1vcnkuIEFuZCB0aGVuIHdhbGtpbmcgcGFnZXRhYmxlIHRvIHNw bGl0Cj4gYmxvY2svc2VjdGlvbiBtYXBwaW5nIHRvIG5vbiBibG9jay9zZWN0aW9uIG1hcHBpbmco bm9ybWFsbHkgNEspIFtbW29ubHldXV0KPiBmb3IgY3Jhc2hrZXJuZWwgbWVtLiBTbyB0aGUgbGlu ZWFyIG1lbSBtYXBwaW5nIHVzZSBibG9jay9zZWN0aW9uIG1hcHBpbmcKPiBhcyBtb3JlIGFzIHBv c3NpYmxlLiBXZSB3aWxsIHJlZHVjZSB0aGUgY3B1IGRUTEIgbWlzcyBjb25zcGljdW91c2x5LCBh bmQKPiBhY2NlbGVyYXRlIG1lbSBhY2Nlc3MgYWJvdXQgMTAtMjAlIHBlcmZvcm1hbmNlIGltcHJv dmVtZW50Lgo+IAo+IEkgaGF2ZSB0ZXN0ZWQgaXQgd2l0aCBwZnQoUGFnZSBGYXVsdCBUZXN0KSBh bmQgZmlvLCBvYnRhaW5lZCBncmVhdAo+IHBlcmZvcm1hY2UgaW1wcm92ZW1lbnQuCj4gCj4gRm9y IGZpbyB0ZXN0Ogo+IDEucHJlcGFyZSByYW1kaXNrCj4gICAgbW9kcHJvYmUgLXIgYnJkCj4gICAg bW9kcHJvYmUgYnJkIHJkX25yPTEgcmRfc2l6ZT02NzEwODg2NAo+ICAgIGRtc2V0dXAgcmVtb3Zl X2FsbAo+ICAgIHdpcGVmcyAtYSAtLWZvcmNlIC9kZXYvcmFtMAo+ICAgIG1rZnMgLXQgZXh0NCAt RSBsYXp5X2l0YWJsZV9pbml0PTAsbGF6eV9qb3VybmFsX2luaXQ9MCAtcSAtRiAvZGV2L3JhbTAK PiAgICBta2RpciAtcCAvZnMvcmFtMAo+ICAgIG1vdW50IC10IGV4dDQgL2Rldi9yYW0wIC9mcy9y YW0wCj4gCj4gMi5wcmVwYXJlIGZpbyBwYXJlbWV0ZXIgaW4geC5maW8gZmlsZToKPiBbZ2xvYmFs XQo+IGJzPTRrCj4gaW9lbmdpbmU9cHN5bmMKPiBpb2RlcHRoPTEyOAo+IHNpemU9MzJHCj4gZGly ZWN0PTEKPiBpbnZhbGlkYXRlPTEKPiBncm91cF9yZXBvcnRpbmcKPiB0aHJlYWQ9MQo+IHJ3PXJl YWQKPiBkaXJlY3Rvcnk9L2ZzL3JhbTAKPiBudW1qb2JzPTEKPiAKPiBbdGFza18wXQo+IGNwdXNf YWxsb3dlZD0xNgo+IHN0b25ld2FsbD0xCj4gCj4gMy5ydW4gdGVzdGNhc2U6Cj4gcGVyZiBzdGF0 IC1lIGRUTEItbG9hZC1taXNzZXMgZmlvIHguZmlvCj4gCj4gNC5jb250cmFzdAo+IC0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLQo+IAkJCXdpdGhvdXQgcGF0Y2gJCXdpdGggcGF0Y2gKPiBmaW8gUkVB RAkJYWdncmI9MTQ5My4yTUIvcwlhZ2dyYj0xNzc1LjNNQi9zCj4gZFRMQi1sb2FkLW1pc3Nlcwkx LDgxOCwzMjAsNjkzCQk0MzgsNzI5LDc3NAo+IHRpbWUgZWxhcHNlZChzKQkJNzAuNTAwMzI2NDM0 CQk2Mi44NzczMTY0MDgKPiB1c2VyKHMpCQkJMTUuOTI2MzMyMDAwCQkxNS42ODQ3MjEwMDAKPiBz eXMocykJCQk1NC4yMTE5MzkwMDAJCTQ3LjA0NjE2NTAwMAo+IAo+IDUuY29uY2x1c2lvbgo+IFVz aW5nIHRoaXMgcGF0Y2ggd2lsbCByZWR1Y2UgZFRMQiBtaXNzZXMgYW5kIGltcHJvdmUgcGVyZm9y bWFjZSBncmVhdGx5Lgo+IAo+IFNpZ25lZC1vZmYtYnk6IEd1YW5naHVpIEZlbmcgPGd1YW5naHVp ZmVuZ0BsaW51eC5hbGliYWJhLmNvbT4KPiAtLS0KPiAgIGFyY2gvYXJtNjQvaW5jbHVkZS9hc20v bW11LmggICAgICAgICB8ICAgMSArCj4gICBhcmNoL2FybTY0L2luY2x1ZGUvYXNtL21tdV9jb250 ZXh0LmggfCAgMjggKysrKwo+ICAgYXJjaC9hcm02NC9tbS9pbml0LmMgICAgICAgICAgICAgICAg IHwgICA4ICstCj4gICBhcmNoL2FybTY0L21tL21tdS5jICAgICAgICAgICAgICAgICAgfCAzMDUg KysrKysrKysrKysrKysrKysrKysrKysrKy0tLS0tLS0tLS0KPiAgIGFyY2gvYXJtNjQvbW0vcHJv Yy5TICAgICAgICAgICAgICAgICB8ICAxOSArKysKPiAgIDUgZmlsZXMgY2hhbmdlZCwgMjY3IGlu c2VydGlvbnMoKyksIDk0IGRlbGV0aW9ucygtKQo+IAo+IGRpZmYgLS1naXQgYS9hcmNoL2FybTY0 L2luY2x1ZGUvYXNtL21tdS5oIGIvYXJjaC9hcm02NC9pbmNsdWRlL2FzbS9tbXUuaAo+IGluZGV4 IDQ4Zjg0NjYuLjFhNDZiODEgMTAwNjQ0Cj4gLS0tIGEvYXJjaC9hcm02NC9pbmNsdWRlL2FzbS9t bXUuaAo+ICsrKyBiL2FyY2gvYXJtNjQvaW5jbHVkZS9hc20vbW11LmgKPiBAQCAtNjMsNiArNjMs NyBAQCBzdGF0aWMgaW5saW5lIGJvb2wgYXJtNjRfa2VybmVsX3VubWFwcGVkX2F0X2VsMCh2b2lk KQo+ICAgZXh0ZXJuIHZvaWQgYXJtNjRfbWVtYmxvY2tfaW5pdCh2b2lkKTsKPiAgIGV4dGVybiB2 b2lkIHBhZ2luZ19pbml0KHZvaWQpOwo+ICAgZXh0ZXJuIHZvaWQgYm9vdG1lbV9pbml0KHZvaWQp Owo+ICtleHRlcm4gdm9pZCBtYXBfY3Jhc2hrZXJuZWwodm9pZCk7Cj4gICBleHRlcm4gdm9pZCBf X2lvbWVtICplYXJseV9pb19tYXAocGh5c19hZGRyX3QgcGh5cywgdW5zaWduZWQgbG9uZyB2aXJ0 KTsKPiAgIGV4dGVybiB2b2lkIGluaXRfbWVtX3BncHJvdCh2b2lkKTsKPiAgIGV4dGVybiB2b2lk IGNyZWF0ZV9wZ2RfbWFwcGluZyhzdHJ1Y3QgbW1fc3RydWN0ICptbSwgcGh5c19hZGRyX3QgcGh5 cywKPiBkaWZmIC0tZ2l0IGEvYXJjaC9hcm02NC9pbmNsdWRlL2FzbS9tbXVfY29udGV4dC5oIGIv YXJjaC9hcm02NC9pbmNsdWRlL2FzbS9tbXVfY29udGV4dC5oCj4gaW5kZXggNjc3MDY2Ny4uMTBk ZmZkNCAxMDA2NDQKPiAtLS0gYS9hcmNoL2FybTY0L2luY2x1ZGUvYXNtL21tdV9jb250ZXh0LmgK PiArKysgYi9hcmNoL2FybTY0L2luY2x1ZGUvYXNtL21tdV9jb250ZXh0LmgKPiBAQCAtMTM5LDYg KzEzOSwzNCBAQCBzdGF0aWMgaW5saW5lIHZvaWQgY3B1X2luc3RhbGxfdHRicjAocGh5c19hZGRy X3QgdHRicjAsIHVuc2lnbmVkIGxvbmcgdDBzeikKPiAgIAlpc2IoKTsKPiAgIH0KPiAgIAo+ICtz dGF0aWMgaW5saW5lIHZvaWQgX19ub2NmaSBjcHVfcmVwbGFjZV90dGJyMV93aXRoX3BoeXMocGh5 c19hZGRyX3QgdHRicjEpCj4gK3sKPiArCXR5cGVkZWYgdm9pZCAodHRicl9yZXBsYWNlX2Z1bmMp KHBoeXNfYWRkcl90KTsKPiArCWV4dGVybiB0dGJyX3JlcGxhY2VfZnVuYyBpZG1hcF9jcHVfcmVw bGFjZV90dGJyMV93aXRoX2ZsdXNoX3RsYjsKPiArCXR0YnJfcmVwbGFjZV9mdW5jICpyZXBsYWNl X3BoeXM7Cj4gKwo+ICsJLyogcGh5c190b190dGJyKCkgemVyb3MgbG93ZXIgMiBiaXRzIG9mIHR0 YnIgd2l0aCA1Mi1iaXQgUEEgKi8KPiArCXR0YnIxID0gcGh5c190b190dGJyKHR0YnIxKTsKPiAr Cj4gKwlpZiAoc3lzdGVtX3N1cHBvcnRzX2NucCgpKSB7Cj4gKwkJLyoKPiArCQkgKiBjcHVfcmVw bGFjZV90dGJyMSgpIGlzIHVzZWQgd2hlbiB0aGVyZSdzIGEgYm9vdCBDUFUKPiArCQkgKiB1cCAo aS5lLiBjcHVmZWF0dXJlIGZyYW1ld29yayBpcyBub3QgdXAgeWV0KSBhbmQKPiArCQkgKiBsYXR0 ZXIgb25seSB3aGVuIHdlIGVuYWJsZSBDTlAgdmlhIGNwdWZlYXR1cmUncwo+ICsJCSAqIGVuYWJs ZSgpIGNhbGxiYWNrLgo+ICsJCSAqIEFsc28gd2UgcmVseSBvbiB0aGUgY3B1X2h3Y2FwIGJpdCBi ZWluZyBzZXQgYmVmb3JlCj4gKwkJICogY2FsbGluZyB0aGUgZW5hYmxlKCkgZnVuY3Rpb24uCj4g KwkJICovCj4gKwkJdHRicjEgfD0gVFRCUl9DTlBfQklUOwo+ICsJfQo+ICsKPiArCXJlcGxhY2Vf cGh5cyA9ICh2b2lkICopX19wYV9zeW1ib2woZnVuY3Rpb25fbm9jZmkoaWRtYXBfY3B1X3JlcGxh Y2VfdHRicjFfd2l0aF9mbHVzaF90bGIpKTsKPiArCj4gKwljcHVfaW5zdGFsbF9pZG1hcCgpOwo+ ICsJcmVwbGFjZV9waHlzKHR0YnIxKTsKPiArCWNwdV91bmluc3RhbGxfaWRtYXAoKTsKY3B1X2lu c3RhbGxfaWRtYXAgd2lsbCBTd3RpY2ggdG8gdXNlIGlkbWFwX3BnX2RpciB3aXRoIHVzZSBbW1t0 dGJyMF9lbDFdXV0uCnN3YXBwZXJfZ3BfZGlyIHVzZSB0aGUgW1tbdHRicjFfZWwwXV1dLCBzbyB0 aGVyZSBpcyBubyB0bGIgY29uZmxpdCB0byAKaWRtYXBfcGdfZGlyKHRoZSBkaWZmZXJlbnQgYWRk cmVzcyBzcGFjZSByYW5nZSkuCgpXaGVuIHN3aXRjaGluZyB0byBpZG1hcF9wZ19kaXIsIHRoZXJl IGFsc28gd2lsbCBiZSBhIHRsYiBmbHVzaCBhbGwuCgpBZnRlcndhcmQsIHRoZSBpZG1hcF9jcHVf cmVwbGFjZV90dGJyMV93aXRoX2ZsdXNoX3RsYiB3aWxsIHJ1biBpbiAKaWRtYXBfcGdfZGlyIHBn ZCBhbmQgY2hhbmdlIHRoZSBwZ2QgdG8gYW5vdGhlciBwZ2QgY29tcGx5aW5nIHdpdGggdGhlIApw YXJhbWV0ZXIgdHRicjEuCgpTbywgdGhlcmUgaXMgbm8gdGxiIGNvbmZsaWN0IHdoZW4gc3dpdGNo aW5nIHBnZC4KCk5hbWVseSwgSSBjYW4gY2hhbmdlIHR0YnIxIHBnZCBzYWZlbHkgd2l0aG91dCBh bnkgdGxiIGNvbmZsaWN0LgoKPiArfQo+ICsKPiAgIC8qCj4gICAgKiBBdG9taWNhbGx5IHJlcGxh Y2VzIHRoZSBhY3RpdmUgVFRCUjFfRUwxIFBHRCB3aXRoIGEgbmV3IFZBLWNvbXBhdGlibGUgUEdE LAo+ICAgICogYXZvaWRpbmcgdGhlIHBvc3NpYmlsaXR5IG9mIGNvbmZsaWN0aW5nIFRMQiBlbnRy aWVzIGJlaW5nIGFsbG9jYXRlZC4KPiBkaWZmIC0tZ2l0IGEvYXJjaC9hcm02NC9tbS9pbml0LmMg Yi9hcmNoL2FybTY0L21tL2luaXQuYwo+IGluZGV4IDMzOWVlODQuLjI0MWQyN2UgMTAwNjQ0Cj4g LS0tIGEvYXJjaC9hcm02NC9tbS9pbml0LmMKPiArKysgYi9hcmNoL2FybTY0L21tL2luaXQuYwo+ IEBAIC0xOTAsNiArMTkwLDcgQEAgc3RhdGljIHZvaWQgX19pbml0IHJlc2VydmVfY3Jhc2hrZXJu ZWwodm9pZCkKPiAgIAljcmFzaGtfcmVzLnN0YXJ0ID0gY3Jhc2hfYmFzZTsKPiAgIAljcmFzaGtf cmVzLmVuZCA9IGNyYXNoX2Jhc2UgKyBjcmFzaF9zaXplIC0gMTsKPiAgIAlpbnNlcnRfcmVzb3Vy Y2UoJmlvbWVtX3Jlc291cmNlLCAmY3Jhc2hrX3Jlcyk7Cj4gKwltYXBfY3Jhc2hrZXJuZWwoKTsK PiAgIH0KPiAgIAo+ICAgLyoKPiBAQCAtMzg4LDEwICszODksNiBAQCB2b2lkIF9faW5pdCBhcm02 NF9tZW1ibG9ja19pbml0KHZvaWQpCj4gICAJfQo+ICAgCj4gICAJZWFybHlfaW5pdF9mZHRfc2Nh bl9yZXNlcnZlZF9tZW0oKTsKPiAtCj4gLQlpZiAoIUlTX0VOQUJMRUQoQ09ORklHX1pPTkVfRE1B KSAmJiAhSVNfRU5BQkxFRChDT05GSUdfWk9ORV9ETUEzMikpCj4gLQkJcmVzZXJ2ZV9jcmFzaGtl cm5lbCgpOwo+IC0KPiAgIAloaWdoX21lbW9yeSA9IF9fdmEobWVtYmxvY2tfZW5kX29mX0RSQU0o KSAtIDEpICsgMTsKPiAgIH0KPiAgIAo+IEBAIC00MzgsOCArNDM1LDcgQEAgdm9pZCBfX2luaXQg Ym9vdG1lbV9pbml0KHZvaWQpCj4gICAJICogcmVxdWVzdF9zdGFuZGFyZF9yZXNvdXJjZXMoKSBk ZXBlbmRzIG9uIGNyYXNoa2VybmVsJ3MgbWVtb3J5IGJlaW5nCj4gICAJICogcmVzZXJ2ZWQsIHNv IGRvIGl0IGhlcmUuCj4gICAJICovCj4gLQlpZiAoSVNfRU5BQkxFRChDT05GSUdfWk9ORV9ETUEp IHx8IElTX0VOQUJMRUQoQ09ORklHX1pPTkVfRE1BMzIpKQo+IC0JCXJlc2VydmVfY3Jhc2hrZXJu ZWwoKTsKPiArCXJlc2VydmVfY3Jhc2hrZXJuZWwoKTsKPiAgIAo+ICAgCW1lbWJsb2NrX2R1bXBf YWxsKCk7Cj4gICB9Cj4gZGlmZiAtLWdpdCBhL2FyY2gvYXJtNjQvbW0vbW11LmMgYi9hcmNoL2Fy bTY0L21tL21tdS5jCj4gaW5kZXggNjI2ZWMzMi4uM2UzMGM4MiAxMDA2NDQKPiAtLS0gYS9hcmNo L2FybTY0L21tL21tdS5jCj4gKysrIGIvYXJjaC9hcm02NC9tbS9tbXUuYwo+IEBAIC00Miw2ICs0 Miw3IEBACj4gICAjZGVmaW5lIE5PX0JMT0NLX01BUFBJTkdTCUJJVCgwKQo+ICAgI2RlZmluZSBO T19DT05UX01BUFBJTkdTCUJJVCgxKQo+ICAgI2RlZmluZSBOT19FWEVDX01BUFBJTkdTCUJJVCgy KQkvKiBhc3N1bWVzIEZFQVRfSFBEUyBpcyBub3QgdXNlZCAqLwo+ICsjZGVmaW5lIE5PX1NFQ19S RU1BUFBJTkdTCUJJVCgzKQkvKiByZWJ1aWxkIHdpdGggbm9uIGJsb2NrL3NlYyBtYXBwaW5nKi8K PiAgIAo+ICAgdTY0IGlkbWFwX3Qwc3ogPSBUQ1JfVDBTWihWQV9CSVRTX01JTik7Cj4gICB1NjQg aWRtYXBfcHRyc19wZXJfcGdkID0gUFRSU19QRVJfUEdEOwo+IEBAIC0xNTUsOCArMTU2LDIyIEBA IHN0YXRpYyBib29sIHBnYXR0cl9jaGFuZ2VfaXNfc2FmZSh1NjQgb2xkLCB1NjQgbmV3KQo+ICAg CXJldHVybiAoKG9sZCBeIG5ldykgJiB+bWFzaykgPT0gMDsKPiAgIH0KPiAgIAo+ICtzdGF0aWMg dm9pZCBwdGVfY2xlYXJfY29udChwdGVfdCAqcHRlcCkKPiArewo+ICsJaW50IGkgPSAwOwo+ICsJ cHRlX3QgcHRlID0gUkVBRF9PTkNFKCpwdGVwKTsKPiArCWlmIChwdGVfbm9uZShwdGUpIHx8ICFw dGVfY29udChwdGUpKQo+ICsJCXJldHVybjsKPiArCXB0ZXAgLT0gKCh1NjQpcHRlcCAvIHNpemVv ZihwdGVfdCkpICYKPiArCQkoKDEgPDwgQ09ORklHX0FSTTY0X0NPTlRfUFRFX1NISUZUKSAtIDEp Owo+ICsJZG8gewo+ICsJCXB0ZSA9IHB0ZV9ta25vbmNvbnQoUkVBRF9PTkNFKCpwdGVwKSk7Cj4g KwkJc2V0X3B0ZShwdGVwLCBwdGUpOwo+ICsJfSB3aGlsZSAoKytwdGVwLCArK2kgPCBDT05UX1BU RVMpOwo+ICt9Cj4gKwo+ICAgc3RhdGljIHZvaWQgaW5pdF9wdGUocG1kX3QgKnBtZHAsIHVuc2ln bmVkIGxvbmcgYWRkciwgdW5zaWduZWQgbG9uZyBlbmQsCj4gLQkJICAgICBwaHlzX2FkZHJfdCBw aHlzLCBwZ3Byb3RfdCBwcm90KQo+ICsJCSAgICAgcGh5c19hZGRyX3QgcGh5cywgcGdwcm90X3Qg cHJvdCwgaW50IGZsYWdzKQo+ICAgewo+ICAgCXB0ZV90ICpwdGVwOwo+ICAgCj4gQEAgLTE2NCw2 ICsxNzksOSBAQCBzdGF0aWMgdm9pZCBpbml0X3B0ZShwbWRfdCAqcG1kcCwgdW5zaWduZWQgbG9u ZyBhZGRyLCB1bnNpZ25lZCBsb25nIGVuZCwKPiAgIAlkbyB7Cj4gICAJCXB0ZV90IG9sZF9wdGUg PSBSRUFEX09OQ0UoKnB0ZXApOwo+ICAgCj4gKwkJaWYgKGZsYWdzICYgTk9fU0VDX1JFTUFQUElO R1MpCj4gKwkJCXB0ZV9jbGVhcl9jb250KHB0ZXApOwo+ICsKPiAgIAkJc2V0X3B0ZShwdGVwLCBw Zm5fcHRlKF9fcGh5c190b19wZm4ocGh5cyksIHByb3QpKTsKPiAgIAo+ICAgCQkvKgo+IEBAIC0x NzksNiArMTk3LDIyIEBAIHN0YXRpYyB2b2lkIGluaXRfcHRlKHBtZF90ICpwbWRwLCB1bnNpZ25l ZCBsb25nIGFkZHIsIHVuc2lnbmVkIGxvbmcgZW5kLAo+ICAgCXB0ZV9jbGVhcl9maXhtYXAoKTsK PiAgIH0KPiAgIAo+ICtzdGF0aWMgaW5saW5lIHZvaWQgYWxsb2NrX3B0ZV9wYWdlKHBtZF90ICpw bWRwLAo+ICsJCQkJICAgcGh5c19hZGRyX3QgKCpwZ3RhYmxlX2FsbG9jKShpbnQpLAo+ICsJCQkJ ICAgaW50IGZsYWdzKQo+ICt7Cj4gKwlwbWR2YWxfdCBwbWR2YWwgPSBQTURfVFlQRV9UQUJMRSB8 IFBNRF9UQUJMRV9VWE47Cj4gKwlwaHlzX2FkZHJfdCBwdGVfcGh5czsKPiArCWlmICghcG1kX25v bmUoUkVBRF9PTkNFKCpwbWRwKSkpCj4gKwkJcmV0dXJuOwo+ICsKPiArCWlmIChmbGFncyAmIE5P X0VYRUNfTUFQUElOR1MpCj4gKwkJcG1kdmFsIHw9IFBNRF9UQUJMRV9QWE47Cj4gKwlCVUdfT04o IXBndGFibGVfYWxsb2MpOwo+ICsJcHRlX3BoeXMgPSBwZ3RhYmxlX2FsbG9jKFBBR0VfU0hJRlQp Owo+ICsJX19wbWRfcG9wdWxhdGUocG1kcCwgcHRlX3BoeXMsIHBtZHZhbCk7Cj4gK30KPiArCj4g ICBzdGF0aWMgdm9pZCBhbGxvY19pbml0X2NvbnRfcHRlKHBtZF90ICpwbWRwLCB1bnNpZ25lZCBs b25nIGFkZHIsCj4gICAJCQkJdW5zaWduZWQgbG9uZyBlbmQsIHBoeXNfYWRkcl90IHBoeXMsCj4g ICAJCQkJcGdwcm90X3QgcHJvdCwKPiBAQCAtMTg5LDE3ICsyMjMsOCBAQCBzdGF0aWMgdm9pZCBh bGxvY19pbml0X2NvbnRfcHRlKHBtZF90ICpwbWRwLCB1bnNpZ25lZCBsb25nIGFkZHIsCj4gICAJ cG1kX3QgcG1kID0gUkVBRF9PTkNFKCpwbWRwKTsKPiAgIAo+ICAgCUJVR19PTihwbWRfc2VjdChw bWQpKTsKPiAtCWlmIChwbWRfbm9uZShwbWQpKSB7Cj4gLQkJcG1kdmFsX3QgcG1kdmFsID0gUE1E X1RZUEVfVEFCTEUgfCBQTURfVEFCTEVfVVhOOwo+IC0JCXBoeXNfYWRkcl90IHB0ZV9waHlzOwo+ IC0KPiAtCQlpZiAoZmxhZ3MgJiBOT19FWEVDX01BUFBJTkdTKQo+IC0JCQlwbWR2YWwgfD0gUE1E X1RBQkxFX1BYTjsKPiAtCQlCVUdfT04oIXBndGFibGVfYWxsb2MpOwo+IC0JCXB0ZV9waHlzID0g cGd0YWJsZV9hbGxvYyhQQUdFX1NISUZUKTsKPiAtCQlfX3BtZF9wb3B1bGF0ZShwbWRwLCBwdGVf cGh5cywgcG1kdmFsKTsKPiAtCQlwbWQgPSBSRUFEX09OQ0UoKnBtZHApOwo+IC0JfQo+ICsJYWxs b2NrX3B0ZV9wYWdlKHBtZHAsIHBndGFibGVfYWxsb2MsIGZsYWdzKTsKPiArCXBtZCA9IFJFQURf T05DRSgqcG1kcCk7Cj4gICAJQlVHX09OKHBtZF9iYWQocG1kKSk7Cj4gICAKPiAgIAlkbyB7Cj4g QEAgLTIwOCwxNiArMjMzLDcxIEBAIHN0YXRpYyB2b2lkIGFsbG9jX2luaXRfY29udF9wdGUocG1k X3QgKnBtZHAsIHVuc2lnbmVkIGxvbmcgYWRkciwKPiAgIAkJbmV4dCA9IHB0ZV9jb250X2FkZHJf ZW5kKGFkZHIsIGVuZCk7Cj4gICAKPiAgIAkJLyogdXNlIGEgY29udGlndW91cyBtYXBwaW5nIGlm IHRoZSByYW5nZSBpcyBzdWl0YWJseSBhbGlnbmVkICovCj4gLQkJaWYgKCgoKGFkZHIgfCBuZXh0 IHwgcGh5cykgJiB+Q09OVF9QVEVfTUFTSykgPT0gMCkgJiYKPiAtCQkgICAgKGZsYWdzICYgTk9f Q09OVF9NQVBQSU5HUykgPT0gMCkKPiArCQlpZiAoIShmbGFncyAmIE5PX1NFQ19SRU1BUFBJTkdT KSAmJgo+ICsJCSAgICgoKGFkZHIgfCBuZXh0IHwgcGh5cykgJiB+Q09OVF9QVEVfTUFTSykgPT0g MCkgJiYKPiArCQkgICAoZmxhZ3MgJiBOT19DT05UX01BUFBJTkdTKSA9PSAwKQo+ICAgCQkJX19w cm90ID0gX19wZ3Byb3QocGdwcm90X3ZhbChwcm90KSB8IFBURV9DT05UKTsKPiAgIAo+IC0JCWlu aXRfcHRlKHBtZHAsIGFkZHIsIG5leHQsIHBoeXMsIF9fcHJvdCk7Cj4gKwkJaW5pdF9wdGUocG1k cCwgYWRkciwgbmV4dCwgcGh5cywgX19wcm90LCBmbGFncyk7Cj4gICAKPiAgIAkJcGh5cyArPSBu ZXh0IC0gYWRkcjsKPiAgIAl9IHdoaWxlIChhZGRyID0gbmV4dCwgYWRkciAhPSBlbmQpOwo+ICAg fQo+ICAgCj4gK3N0YXRpYyB2b2lkIHBtZF9jbGVhcl9jb250KHBtZF90ICpwbWRwKQo+ICt7Cj4g KwlpbnQgaSA9IDA7Cj4gKwlwbWRfdCBwbWQgPSBSRUFEX09OQ0UoKnBtZHApOwo+ICsJaWYgKHBt ZF9ub25lKHBtZCkgfHwgIXBtZF9zZWN0KHBtZCkgfHwgIXBtZF9jb250KHBtZCkpCj4gKwkJcmV0 dXJuOwo+ICsJcG1kcCAtPSAoKHU2NClwbWRwIC8gc2l6ZW9mKHBtZF90KSkgJgo+ICsJCSgoMSA8 PCBDT05GSUdfQVJNNjRfQ09OVF9QTURfU0hJRlQpIC0gMSk7Cj4gKwlkbyB7Cj4gKwkJcG1kID0g UkVBRF9PTkNFKCpwbWRwKTsKPiArCQlwbWQgPSBwdGVfcG1kKHB0ZV9ta25vbmNvbnQocG1kX3B0 ZShwbWQpKSk7Cj4gKwkJc2V0X3BtZChwbWRwLCBwbWQpOwo+ICsJfSB3aGlsZSAoKytwbWRwLCAr K2kgPCBDT05UX1BNRFMpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBpbml0X3BtZF9yZW1hcChw dWRfdCAqcHVkcCwgdW5zaWduZWQgbG9uZyBhZGRyLCB1bnNpZ25lZCBsb25nIGVuZCwKPiArCQkJ ICAgcGh5c19hZGRyX3QgcGh5cywgcGdwcm90X3QgcHJvdCwKPiArCQkJICAgcGh5c19hZGRyX3Qg KCpwZ3RhYmxlX2FsbG9jKShpbnQpLCBpbnQgZmxhZ3MpCj4gK3sKPiArCXVuc2lnbmVkIGxvbmcg bmV4dDsKPiArCXBtZF90ICpwbWRwOwo+ICsJcGh5c19hZGRyX3QgbWFwX29mZnNldDsKPiArCj4g KwlwbWRwID0gcG1kX3NldF9maXhtYXBfb2Zmc2V0KHB1ZHAsIGFkZHIpOwo+ICsJZG8gewo+ICsJ CW5leHQgPSBwbWRfYWRkcl9lbmQoYWRkciwgZW5kKTsKPiArCj4gKwkJaWYgKCFwbWRfbm9uZSgq cG1kcCkgJiYgcG1kX3NlY3QoKnBtZHApKSB7Cj4gKwkJCXBtZF9jbGVhcl9jb250KHBtZHApOwo+ ICsJCQlwbWRfY2xlYXIocG1kcCk7Cj4gKwkJCWFsbG9ja19wdGVfcGFnZShwbWRwLCBwZ3RhYmxl X2FsbG9jLCBmbGFncyk7Cj4gKwo+ICsJCQltYXBfb2Zmc2V0ID0gYWRkciAtIChhZGRyICYgUE1E X01BU0spOwo+ICsJCQlpZiAobWFwX29mZnNldCkKPiArCQkJICAgIGFsbG9jX2luaXRfY29udF9w dGUocG1kcCwgYWRkciAmIFBNRF9NQVNLLCBhZGRyLAo+ICsJCQkJCQlwaHlzIC0gbWFwX29mZnNl dCwgcHJvdCwKPiArCQkJCQkJcGd0YWJsZV9hbGxvYywKPiArCQkJCQkJZmxhZ3MgJiAofk5PX1NF Q19SRU1BUFBJTkdTKSk7Cj4gKwo+ICsJCQlpZiAobmV4dCA8IChhZGRyICYgUE1EX01BU0spICsg UE1EX1NJWkUpCj4gKwkJCSAgICBhbGxvY19pbml0X2NvbnRfcHRlKHBtZHAsIG5leHQsCj4gKwkJ CQkJICAgICAgIChhZGRyICYgUFVEX01BU0spICsgUFVEX1NJWkUsCj4gKwkJCQkJICAgICAgICBu ZXh0IC0gYWRkciArIHBoeXMsCj4gKwkJCQkJCXByb3QsIHBndGFibGVfYWxsb2MsCj4gKwkJCQkJ CWZsYWdzICYgKH5OT19TRUNfUkVNQVBQSU5HUykpOwo+ICsJCX0KPiArCQlhbGxvY19pbml0X2Nv bnRfcHRlKHBtZHAsIGFkZHIsIG5leHQsIHBoeXMsIHByb3QsCj4gKwkJCQkgICAgcGd0YWJsZV9h bGxvYywgZmxhZ3MpOwo+ICsJCXBoeXMgKz0gbmV4dCAtIGFkZHI7Cj4gKwl9IHdoaWxlIChwbWRw KyssIGFkZHIgPSBuZXh0LCBhZGRyICE9IGVuZCk7Cj4gKwo+ICsJcG1kX2NsZWFyX2ZpeG1hcCgp Owo+ICt9Cj4gKwo+ICAgc3RhdGljIHZvaWQgaW5pdF9wbWQocHVkX3QgKnB1ZHAsIHVuc2lnbmVk IGxvbmcgYWRkciwgdW5zaWduZWQgbG9uZyBlbmQsCj4gICAJCSAgICAgcGh5c19hZGRyX3QgcGh5 cywgcGdwcm90X3QgcHJvdCwKPiAgIAkJICAgICBwaHlzX2FkZHJfdCAoKnBndGFibGVfYWxsb2Mp KGludCksIGludCBmbGFncykKPiBAQCAtMjU1LDYgKzMzNSwyMiBAQCBzdGF0aWMgdm9pZCBpbml0 X3BtZChwdWRfdCAqcHVkcCwgdW5zaWduZWQgbG9uZyBhZGRyLCB1bnNpZ25lZCBsb25nIGVuZCwK PiAgIAlwbWRfY2xlYXJfZml4bWFwKCk7Cj4gICB9Cj4gICAKPiArc3RhdGljIGlubGluZSB2b2lk IGFsbG9jX3BtZF9wYWdlKHB1ZF90ICpwdWRwLCBwaHlzX2FkZHJfdCAoKnBndGFibGVfYWxsb2Mp KGludCksIGludCBmbGFncykKPiArewo+ICsKPiArCXB1ZHZhbF90IHB1ZHZhbCA9IFBVRF9UWVBF X1RBQkxFIHwgUFVEX1RBQkxFX1VYTjsKPiArCXBoeXNfYWRkcl90IHBtZF9waHlzOwo+ICsKPiAr CWlmICghcHVkX25vbmUoUkVBRF9PTkNFKCpwdWRwKSkpCj4gKwkJcmV0dXJuOwo+ICsKPiArCWlm IChmbGFncyAmIE5PX0VYRUNfTUFQUElOR1MpCj4gKwkJcHVkdmFsIHw9IFBVRF9UQUJMRV9QWE47 Cj4gKwlCVUdfT04oIXBndGFibGVfYWxsb2MpOwo+ICsJcG1kX3BoeXMgPSBwZ3RhYmxlX2FsbG9j KFBNRF9TSElGVCk7Cj4gKwlfX3B1ZF9wb3B1bGF0ZShwdWRwLCBwbWRfcGh5cywgcHVkdmFsKTsK PiArfQo+ICsKPiAgIHN0YXRpYyB2b2lkIGFsbG9jX2luaXRfY29udF9wbWQocHVkX3QgKnB1ZHAs IHVuc2lnbmVkIGxvbmcgYWRkciwKPiAgIAkJCQl1bnNpZ25lZCBsb25nIGVuZCwgcGh5c19hZGRy X3QgcGh5cywKPiAgIAkJCQlwZ3Byb3RfdCBwcm90LAo+IEBAIC0yNjcsMTcgKzM2Myw4IEBAIHN0 YXRpYyB2b2lkIGFsbG9jX2luaXRfY29udF9wbWQocHVkX3QgKnB1ZHAsIHVuc2lnbmVkIGxvbmcg YWRkciwKPiAgIAkgKiBDaGVjayBmb3IgaW5pdGlhbCBzZWN0aW9uIG1hcHBpbmdzIGluIHRoZSBw Z2QvcHVkLgo+ICAgCSAqLwo+ICAgCUJVR19PTihwdWRfc2VjdChwdWQpKTsKPiAtCWlmIChwdWRf bm9uZShwdWQpKSB7Cj4gLQkJcHVkdmFsX3QgcHVkdmFsID0gUFVEX1RZUEVfVEFCTEUgfCBQVURf VEFCTEVfVVhOOwo+IC0JCXBoeXNfYWRkcl90IHBtZF9waHlzOwo+IC0KPiAtCQlpZiAoZmxhZ3Mg JiBOT19FWEVDX01BUFBJTkdTKQo+IC0JCQlwdWR2YWwgfD0gUFVEX1RBQkxFX1BYTjsKPiAtCQlC VUdfT04oIXBndGFibGVfYWxsb2MpOwo+IC0JCXBtZF9waHlzID0gcGd0YWJsZV9hbGxvYyhQTURf U0hJRlQpOwo+IC0JCV9fcHVkX3BvcHVsYXRlKHB1ZHAsIHBtZF9waHlzLCBwdWR2YWwpOwo+IC0J CXB1ZCA9IFJFQURfT05DRSgqcHVkcCk7Cj4gLQl9Cj4gKwlhbGxvY19wbWRfcGFnZShwdWRwLCBw Z3RhYmxlX2FsbG9jLCBmbGFncyk7Cj4gKwlwdWQgPSBSRUFEX09OQ0UoKnB1ZHApOwo+ICAgCUJV R19PTihwdWRfYmFkKHB1ZCkpOwo+ICAgCj4gICAJZG8gewo+IEBAIC0yODYsMTYgKzM3Myw4MCBA QCBzdGF0aWMgdm9pZCBhbGxvY19pbml0X2NvbnRfcG1kKHB1ZF90ICpwdWRwLCB1bnNpZ25lZCBs b25nIGFkZHIsCj4gICAJCW5leHQgPSBwbWRfY29udF9hZGRyX2VuZChhZGRyLCBlbmQpOwo+ICAg Cj4gICAJCS8qIHVzZSBhIGNvbnRpZ3VvdXMgbWFwcGluZyBpZiB0aGUgcmFuZ2UgaXMgc3VpdGFi bHkgYWxpZ25lZCAqLwo+IC0JCWlmICgoKChhZGRyIHwgbmV4dCB8IHBoeXMpICYgfkNPTlRfUE1E X01BU0spID09IDApICYmCj4gKwkJaWYgKCEoZmxhZ3MgJiBOT19TRUNfUkVNQVBQSU5HUykgJiYK PiArCQkgICAoKChhZGRyIHwgbmV4dCB8IHBoeXMpICYgfkNPTlRfUE1EX01BU0spID09IDApICYm Cj4gICAJCSAgICAoZmxhZ3MgJiBOT19DT05UX01BUFBJTkdTKSA9PSAwKQo+ICAgCQkJX19wcm90 ID0gX19wZ3Byb3QocGdwcm90X3ZhbChwcm90KSB8IFBURV9DT05UKTsKPiAgIAo+IC0JCWluaXRf cG1kKHB1ZHAsIGFkZHIsIG5leHQsIHBoeXMsIF9fcHJvdCwgcGd0YWJsZV9hbGxvYywgZmxhZ3Mp Owo+ICsJCWlmIChmbGFncyAmIE5PX1NFQ19SRU1BUFBJTkdTKQo+ICsJCQlpbml0X3BtZF9yZW1h cChwdWRwLCBhZGRyLCBuZXh0LCBwaHlzLCBfX3Byb3QsCj4gKwkJCQkgICAgICAgcGd0YWJsZV9h bGxvYywgZmxhZ3MpOwo+ICsJCWVsc2UKPiArCQkJaW5pdF9wbWQocHVkcCwgYWRkciwgbmV4dCwg cGh5cywgX19wcm90LAo+ICsJCQkJIHBndGFibGVfYWxsb2MsIGZsYWdzKTsKPiAgIAo+ICAgCQlw aHlzICs9IG5leHQgLSBhZGRyOwo+ICAgCX0gd2hpbGUgKGFkZHIgPSBuZXh0LCBhZGRyICE9IGVu ZCk7Cj4gICB9Cj4gICAKPiArc3RhdGljIHZvaWQgaW5pdF9wdWRfcmVtYXAocHVkX3QgKnB1ZHAs IHVuc2lnbmVkIGxvbmcgYWRkciwgdW5zaWduZWQgbG9uZyBuZXh0LAo+ICsJCQkgICBwaHlzX2Fk ZHJfdCBwaHlzLCBwZ3Byb3RfdCBwcm90LAo+ICsJCQkgICBwaHlzX2FkZHJfdCAoKnBndGFibGVf YWxsb2MpKGludCksCj4gKwkJCSAgIGludCBmbGFncykKPiArewo+ICsJcGh5c19hZGRyX3QgbWFw X29mZnNldDsKPiArCj4gKwlpZiAoIXB1ZF9ub25lKCpwdWRwKSAmJiBwdWRfc2VjdCgqcHVkcCkp IHsKPiArCQlwdWRfY2xlYXIocHVkcCk7Cj4gKwkJYWxsb2NfcG1kX3BhZ2UocHVkcCwgcGd0YWJs ZV9hbGxvYywgZmxhZ3MpOwo+ICsKPiArCQltYXBfb2Zmc2V0ID0gYWRkciAtIChhZGRyICYgUFVE X01BU0spOwo+ICsJCWlmIChtYXBfb2Zmc2V0KQo+ICsJCSAgICBhbGxvY19pbml0X2NvbnRfcG1k KHB1ZHAsIGFkZHIgJiBQVURfTUFTSywKPiArCQkJCQlhZGRyLCBwaHlzIC0gbWFwX29mZnNldCwK PiArCQkJCQlwcm90LCBwZ3RhYmxlX2FsbG9jLAo+ICsJCQkJCWZsYWdzICYJKH5OT19TRUNfUkVN QVBQSU5HUykpOwo+ICsKPiArCQlpZiAobmV4dCA8IChhZGRyICYgUFVEX01BU0spICsgUFVEX1NJ WkUpCj4gKwkJICAgIGFsbG9jX2luaXRfY29udF9wbWQocHVkcCwgbmV4dCwKPiArCQkJCSAgICAg ICAoYWRkciAmIFBVRF9NQVNLKSArIFBVRF9TSVpFLAo+ICsJCQkJCW5leHQgLSBhZGRyICsgcGh5 cywKPiArCQkJCQlwcm90LCBwZ3RhYmxlX2FsbG9jLAo+ICsJCQkJCWZsYWdzICYgKH5OT19TRUNf UkVNQVBQSU5HUykpOwo+ICsJfQo+ICsJYWxsb2NfaW5pdF9jb250X3BtZChwdWRwLCBhZGRyLCBu ZXh0LCBwaHlzLCBwcm90LAo+ICsJCQkgICAgcGd0YWJsZV9hbGxvYywgZmxhZ3MpOwo+ICt9Cj4g Kwo+ICtzdGF0aWMgdm9pZCBpbml0X3B1ZChwdWRfdCAqcHVkcCwgdW5zaWduZWQgbG9uZyBhZGRy LCB1bnNpZ25lZCBsb25nIG5leHQsCj4gKwkJICAgICBwaHlzX2FkZHJfdCBwaHlzLCBwZ3Byb3Rf dCBwcm90LAo+ICsJCSAgICAgcGh5c19hZGRyX3QgKCpwZ3RhYmxlX2FsbG9jKShpbnQpLAo+ICsJ CSAgICAgaW50IGZsYWdzKQo+ICt7Cj4gKwlwdWRfdCBvbGRfcHVkID0gUkVBRF9PTkNFKCpwdWRw KTsKPiArCS8qCj4gKwkgKiBGb3IgNEsgZ3JhbnVsZSBvbmx5LCBhdHRlbXB0IHRvIHB1dCBkb3du IGEgMUdCIGJsb2NrCj4gKwkgKi8KPiArCWlmIChwdWRfc2VjdF9zdXBwb3J0ZWQoKSAmJgo+ICsJ ICAgKChhZGRyIHwgbmV4dCB8IHBoeXMpICYgflBVRF9NQVNLKSA9PSAwICYmCj4gKwkgICAoZmxh Z3MgJiBOT19CTE9DS19NQVBQSU5HUykgPT0gMCkgewo+ICsJCXB1ZF9zZXRfaHVnZShwdWRwLCBw aHlzLCBwcm90KTsKPiArCj4gKwkJLyoKPiArCQkgKiBBZnRlciB0aGUgUFVEIGVudHJ5IGhhcyBi ZWVuIHBvcHVsYXRlZCBvbmNlLCB3ZQo+ICsJCSAqIG9ubHkgYWxsb3cgdXBkYXRlcyB0byB0aGUg cGVybWlzc2lvbiBhdHRyaWJ1dGVzLgo+ICsJCSAqLwo+ICsJCUJVR19PTighcGdhdHRyX2NoYW5n ZV9pc19zYWZlKHB1ZF92YWwob2xkX3B1ZCksCj4gKwkJCQkJICAgICAgUkVBRF9PTkNFKHB1ZF92 YWwoKnB1ZHApKSkpOwo+ICsJfSBlbHNlIHsKPiArCQlhbGxvY19pbml0X2NvbnRfcG1kKHB1ZHAs IGFkZHIsIG5leHQsIHBoeXMsIHByb3QsCj4gKwkJCQkgICAgcGd0YWJsZV9hbGxvYywgZmxhZ3Mp Owo+ICsKPiArCQlCVUdfT04ocHVkX3ZhbChvbGRfcHVkKSAhPSAwICYmCj4gKwkJICAgICAgIHB1 ZF92YWwob2xkX3B1ZCkgIT0gUkVBRF9PTkNFKHB1ZF92YWwoKnB1ZHApKSk7Cj4gKwl9Cj4gK30K PiArCj4gICBzdGF0aWMgdm9pZCBhbGxvY19pbml0X3B1ZChwZ2RfdCAqcGdkcCwgdW5zaWduZWQg bG9uZyBhZGRyLCB1bnNpZ25lZCBsb25nIGVuZCwKPiAgIAkJCSAgIHBoeXNfYWRkcl90IHBoeXMs IHBncHJvdF90IHByb3QsCj4gICAJCQkgICBwaHlzX2FkZHJfdCAoKnBndGFibGVfYWxsb2MpKGlu dCksCj4gQEAgLTMyNSwzNyArNDc2LDIyIEBAIHN0YXRpYyB2b2lkIGFsbG9jX2luaXRfcHVkKHBn ZF90ICpwZ2RwLCB1bnNpZ25lZCBsb25nIGFkZHIsIHVuc2lnbmVkIGxvbmcgZW5kLAo+ICAgCSAq Lwo+ICAgCWlmIChzeXN0ZW1fc3RhdGUgIT0gU1lTVEVNX0JPT1RJTkcpCj4gICAJCW11dGV4X2xv Y2soJmZpeG1hcF9sb2NrKTsKPiArCj4gICAJcHVkcCA9IHB1ZF9zZXRfZml4bWFwX29mZnNldChw NGRwLCBhZGRyKTsKPiAgIAlkbyB7Cj4gLQkJcHVkX3Qgb2xkX3B1ZCA9IFJFQURfT05DRSgqcHVk cCk7Cj4gLQo+ICAgCQluZXh0ID0gcHVkX2FkZHJfZW5kKGFkZHIsIGVuZCk7Cj4gICAKPiAtCQkv Kgo+IC0JCSAqIEZvciA0SyBncmFudWxlIG9ubHksIGF0dGVtcHQgdG8gcHV0IGRvd24gYSAxR0Ig YmxvY2sKPiAtCQkgKi8KPiAtCQlpZiAocHVkX3NlY3Rfc3VwcG9ydGVkKCkgJiYKPiAtCQkgICAo KGFkZHIgfCBuZXh0IHwgcGh5cykgJiB+UFVEX01BU0spID09IDAgJiYKPiAtCQkgICAgKGZsYWdz ICYgTk9fQkxPQ0tfTUFQUElOR1MpID09IDApIHsKPiAtCQkJcHVkX3NldF9odWdlKHB1ZHAsIHBo eXMsIHByb3QpOwo+IC0KPiAtCQkJLyoKPiAtCQkJICogQWZ0ZXIgdGhlIFBVRCBlbnRyeSBoYXMg YmVlbiBwb3B1bGF0ZWQgb25jZSwgd2UKPiAtCQkJICogb25seSBhbGxvdyB1cGRhdGVzIHRvIHRo ZSBwZXJtaXNzaW9uIGF0dHJpYnV0ZXMuCj4gLQkJCSAqLwo+IC0JCQlCVUdfT04oIXBnYXR0cl9j aGFuZ2VfaXNfc2FmZShwdWRfdmFsKG9sZF9wdWQpLAo+IC0JCQkJCQkgICAgICBSRUFEX09OQ0Uo cHVkX3ZhbCgqcHVkcCkpKSk7Cj4gLQkJfSBlbHNlIHsKPiAtCQkJYWxsb2NfaW5pdF9jb250X3Bt ZChwdWRwLCBhZGRyLCBuZXh0LCBwaHlzLCBwcm90LAo+IC0JCQkJCSAgICBwZ3RhYmxlX2FsbG9j LCBmbGFncyk7Cj4gLQo+IC0JCQlCVUdfT04ocHVkX3ZhbChvbGRfcHVkKSAhPSAwICYmCj4gLQkJ CSAgICAgICBwdWRfdmFsKG9sZF9wdWQpICE9IFJFQURfT05DRShwdWRfdmFsKCpwdWRwKSkpOwo+ IC0JCX0KPiArCQlpZiAoZmxhZ3MgJiBOT19TRUNfUkVNQVBQSU5HUykKPiArCQkJaW5pdF9wdWRf cmVtYXAocHVkcCwgYWRkciwgbmV4dCwgcGh5cywgcHJvdCwKPiArCQkJCSAgICAgICBwZ3RhYmxl X2FsbG9jLCBmbGFncyk7Cj4gKwkJZWxzZQo+ICsJCQlpbml0X3B1ZChwdWRwLCBhZGRyLCBuZXh0 LCBwaHlzLCBwcm90LCBwZ3RhYmxlX2FsbG9jLAo+ICsJCQkJIGZsYWdzKTsKPiAgIAkJcGh5cyAr PSBuZXh0IC0gYWRkcjsKPiAgIAl9IHdoaWxlIChwdWRwKyssIGFkZHIgPSBuZXh0LCBhZGRyICE9 IGVuZCk7Cj4gICAKPiAgIAlwdWRfY2xlYXJfZml4bWFwKCk7Cj4gKwo+ICAgCWlmIChzeXN0ZW1f c3RhdGUgIT0gU1lTVEVNX0JPT1RJTkcpCj4gICAJCW11dGV4X3VubG9jaygmZml4bWFwX2xvY2sp Owo+ICAgfQo+IEBAIC00ODMsMjAgKzYxOSwzNyBAQCB2b2lkIF9faW5pdCBtYXJrX2xpbmVhcl90 ZXh0X2FsaWFzX3JvKHZvaWQpCj4gICAJCQkgICAgUEFHRV9LRVJORUxfUk8pOwo+ICAgfQo+ICAg Cj4gLXN0YXRpYyBib29sIGNyYXNoX21lbV9tYXAgX19pbml0ZGF0YTsKPiAtCj4gLXN0YXRpYyBp bnQgX19pbml0IGVuYWJsZV9jcmFzaF9tZW1fbWFwKGNoYXIgKmFyZykKPiArI2lmZGVmIENPTkZJ R19LRVhFQ19DT1JFCj4gK3ZvaWQgX19pbml0IG1hcF9jcmFzaGtlcm5lbCh2b2lkKQo+ICAgewo+ IC0JLyoKPiAtCSAqIFByb3BlciBwYXJhbWV0ZXIgcGFyc2luZyBpcyBkb25lIGJ5IHJlc2VydmVf Y3Jhc2hrZXJuZWwoKS4gV2Ugb25seQo+IC0JICogbmVlZCB0byBrbm93IGlmIHRoZSBsaW5lYXIg bWFwIGhhcyB0byBhdm9pZCBibG9jayBtYXBwaW5ncyBzbyB0aGF0Cj4gLQkgKiB0aGUgY3Jhc2hr ZXJuZWwgcmVzZXJ2YXRpb25zIGNhbiBiZSB1bm1hcHBlZCBsYXRlci4KPiAtCSAqLwo+IC0JY3Jh c2hfbWVtX21hcCA9IHRydWU7Cj4gKwlpZiAoY2FuX3NldF9kaXJlY3RfbWFwKCkgfHwgSVNfRU5B QkxFRChDT05GSUdfS0ZFTkNFKSkKPiArCSAgICByZXR1cm47Cj4gICAKPiAtCXJldHVybiAwOwo+ ICsJaWYgKCFjcmFzaGtfcmVzLmVuZCkKPiArCSAgICByZXR1cm47Cj4gKwo+ICsJY3B1X3JlcGxh Y2VfdHRicjFfd2l0aF9waHlzKF9fcGFfc3ltYm9sKGluaXRfcGdfZGlyKSk7Cj4gKwlpbml0X21t LnBnZCA9IGluaXRfcGdfZGlyOwo+ICsKPiArCV9fY3JlYXRlX3BnZF9tYXBwaW5nKHN3YXBwZXJf cGdfZGlyLCBjcmFzaGtfcmVzLnN0YXJ0LAo+ICsJCQkgICAgIF9fcGh5c190b192aXJ0KGNyYXNo a19yZXMuc3RhcnQpLAo+ICsJCQkgICAgIGNyYXNoa19yZXMuZW5kICsgMSAtIGNyYXNoa19yZXMu c3RhcnQsIFBBR0VfS0VSTkVMLAo+ICsJCQkgICAgIGVhcmx5X3BndGFibGVfYWxsb2MsCj4gKwkJ CSAgICAgTk9fRVhFQ19NQVBQSU5HUyB8IE5PX1NFQ19SRU1BUFBJTkdTKTsKPiArCj4gKwljcHVf cmVwbGFjZV90dGJyMShsbV9hbGlhcyhzd2FwcGVyX3BnX2RpcikpOwo+ICsJaW5pdF9tbS5wZ2Qg PSBzd2FwcGVyX3BnX2RpcjsKPiArCj4gKwltZW1ibG9ja19waHlzX2ZyZWUoX19wYV9zeW1ib2wo aW5pdF9wZ19kaXIpLAo+ICsJCQkgICBfX3BhX3N5bWJvbChpbml0X3BnX2VuZCkgLSBfX3BhX3N5 bWJvbChpbml0X3BnX2RpcikpOwo+ICAgfQoKQmVjYXVzZSB1bm1hcF9ob3RwbHVnX3JhbmdlIHdv cmsgd2l0aCBzd2FwcGVyX2dwX2RpciBwZ2QuIFRoZXJlIGFyZSBtYW55IApjaGFuZ2VzIG5lZWRl ZCBmb3Igd29ya2luZyB3aXRoIGluaXRfcGdfZGlyIHBnZC4KU28gdGhhdCBJIHVzZSB0aGUgaW5p dF9wZ19kaXIgYW5kIF9fY3JlYXRlX3BnZF9tYXBwaW5nIHRvIGRpcmVjdCAKd2Fsay9tb2RpZnkg c3dhcHBlcl9ncF9kaXIgcGFnZXRhYmxlLgoKV2hlbiBmaW5pc2hpbmcgaXQsIGZyZWUgdGhlIGlu aXRfcGdfZGlyIG1lbWJsb2NrLgoKPiAtZWFybHlfcGFyYW0oImNyYXNoa2VybmVsIiwgZW5hYmxl X2NyYXNoX21lbV9tYXApOwo+ICsjZWxzZQo+ICt2b2lkIF9faW5pdCBtYXBfY3Jhc2hrZXJuZWwo dm9pZCkKPiArewo+ICsJbWVtYmxvY2tfcGh5c19mcmVlKF9fcGFfc3ltYm9sKGluaXRfcGdfZGly KSwKPiArCQkJICAgX19wYV9zeW1ib2woaW5pdF9wZ19lbmQpIC0gX19wYV9zeW1ib2woaW5pdF9w Z19kaXIpKTsKPiArfQo+ICsjZW5kaWYKPiAgIAo+ICAgc3RhdGljIHZvaWQgX19pbml0IG1hcF9t ZW0ocGdkX3QgKnBnZHApCj4gICB7Cj4gQEAgLTUyNywxNyArNjgwLDYgQEAgc3RhdGljIHZvaWQg X19pbml0IG1hcF9tZW0ocGdkX3QgKnBnZHApCj4gICAJICovCj4gICAJbWVtYmxvY2tfbWFya19u b21hcChrZXJuZWxfc3RhcnQsIGtlcm5lbF9lbmQgLSBrZXJuZWxfc3RhcnQpOwo+ICAgCj4gLSNp ZmRlZiBDT05GSUdfS0VYRUNfQ09SRQo+IC0JaWYgKGNyYXNoX21lbV9tYXApIHsKPiAtCQlpZiAo SVNfRU5BQkxFRChDT05GSUdfWk9ORV9ETUEpIHx8Cj4gLQkJICAgIElTX0VOQUJMRUQoQ09ORklH X1pPTkVfRE1BMzIpKQo+IC0JCQlmbGFncyB8PSBOT19CTE9DS19NQVBQSU5HUyB8IE5PX0NPTlRf TUFQUElOR1M7Cj4gLQkJZWxzZSBpZiAoY3Jhc2hrX3Jlcy5lbmQpCj4gLQkJCW1lbWJsb2NrX21h cmtfbm9tYXAoY3Jhc2hrX3Jlcy5zdGFydCwKPiAtCQkJICAgIHJlc291cmNlX3NpemUoJmNyYXNo a19yZXMpKTsKPiAtCX0KPiAtI2VuZGlmCj4gLQo+ICAgCS8qIG1hcCBhbGwgdGhlIG1lbW9yeSBi YW5rcyAqLwo+ICAgCWZvcl9lYWNoX21lbV9yYW5nZShpLCAmc3RhcnQsICZlbmQpIHsKPiAgIAkJ aWYgKHN0YXJ0ID49IGVuZCkKPiBAQCAtNTcwLDE5ICs3MTIsNiBAQCBzdGF0aWMgdm9pZCBfX2lu aXQgbWFwX21lbShwZ2RfdCAqcGdkcCkKPiAgIAkgKiBpbiBwYWdlIGdyYW51bGFyaXR5IGFuZCBw dXQgYmFjayB1bnVzZWQgbWVtb3J5IHRvIGJ1ZGR5IHN5c3RlbQo+ICAgCSAqIHRocm91Z2ggL3N5 cy9rZXJuZWwva2V4ZWNfY3Jhc2hfc2l6ZSBpbnRlcmZhY2UuCj4gICAJICovCj4gLSNpZmRlZiBD T05GSUdfS0VYRUNfQ09SRQo+IC0JaWYgKGNyYXNoX21lbV9tYXAgJiYKPiAtCSAgICAhSVNfRU5B QkxFRChDT05GSUdfWk9ORV9ETUEpICYmICFJU19FTkFCTEVEKENPTkZJR19aT05FX0RNQTMyKSkg ewo+IC0JCWlmIChjcmFzaGtfcmVzLmVuZCkgewo+IC0JCQlfX21hcF9tZW1ibG9jayhwZ2RwLCBj cmFzaGtfcmVzLnN0YXJ0LAo+IC0JCQkJICAgICAgIGNyYXNoa19yZXMuZW5kICsgMSwKPiAtCQkJ CSAgICAgICBQQUdFX0tFUk5FTCwKPiAtCQkJCSAgICAgICBOT19CTE9DS19NQVBQSU5HUyB8IE5P X0NPTlRfTUFQUElOR1MpOwo+IC0JCQltZW1ibG9ja19jbGVhcl9ub21hcChjcmFzaGtfcmVzLnN0 YXJ0LAo+IC0JCQkJCSAgICAgcmVzb3VyY2Vfc2l6ZSgmY3Jhc2hrX3JlcykpOwo+IC0JCX0KPiAt CX0KPiAtI2VuZGlmCj4gICB9Cj4gICAKPiAgIHZvaWQgbWFya19yb2RhdGFfcm8odm9pZCkKPiBA QCAtNzc0LDggKzkwMyw4IEBAIHZvaWQgX19pbml0IHBhZ2luZ19pbml0KHZvaWQpCj4gICAJY3B1 X3JlcGxhY2VfdHRicjEobG1fYWxpYXMoc3dhcHBlcl9wZ19kaXIpKTsKPiAgIAlpbml0X21tLnBn ZCA9IHN3YXBwZXJfcGdfZGlyOwo+ICAgCj4gLQltZW1ibG9ja19waHlzX2ZyZWUoX19wYV9zeW1i b2woaW5pdF9wZ19kaXIpLAo+IC0JCQkgICBfX3BhX3N5bWJvbChpbml0X3BnX2VuZCkgLSBfX3Bh X3N5bWJvbChpbml0X3BnX2RpcikpOwo+ICsJLy9tZW1ibG9ja19waHlzX2ZyZWUoX19wYV9zeW1i b2woaW5pdF9wZ19kaXIpLAo+ICsJLy8JCSAgIF9fcGFfc3ltYm9sKGluaXRfcGdfZW5kKSAtIF9f cGFfc3ltYm9sKGluaXRfcGdfZGlyKSk7Cj4gICAKPiAgIAltZW1ibG9ja19hbGxvd19yZXNpemUo KTsKPiAgIH0KPiBkaWZmIC0tZ2l0IGEvYXJjaC9hcm02NC9tbS9wcm9jLlMgYi9hcmNoL2FybTY0 L21tL3Byb2MuUwo+IGluZGV4IDUwYmJlZDkuLjE2MWJhZTYgMTAwNjQ0Cj4gLS0tIGEvYXJjaC9h cm02NC9tbS9wcm9jLlMKPiArKysgYi9hcmNoL2FybTY0L21tL3Byb2MuUwo+IEBAIC0xNzgsNiAr MTc4LDI1IEBAIFNZTV9GVU5DX0VORChjcHVfZG9fcmVzdW1lKQo+ICAgCWlzYgo+ICAgLmVuZG0K PiAgIAo+ICtTWU1fRlVOQ19TVEFSVChpZG1hcF9jcHVfcmVwbGFjZV90dGJyMV93aXRoX2ZsdXNo X3RsYikKPiArCXNhdmVfYW5kX2Rpc2FibGVfZGFpZiBmbGFncz14Mgo+ICsKPiArCV9faWRtYXBf Y3B1X3NldF9yZXNlcnZlZF90dGJyMSB4MSwgeDMKPiArCj4gKwlvZmZzZXRfdHRicjEgeDAsIHgz Cj4gKwltc3IJdHRicjFfZWwxLCB4MAo+ICsJaXNiCj4gKwo+ICsJcmVzdG9yZV9kYWlmIHgyCj4g Kwo+ICsJZHNiIG5zaHN0Cj4gKwl0bGJpCXZtYWxsZTEKPiArCWRzYgluc2gKPiArCWlzYgo+ICsK PiArCXJldAo+ICtTWU1fRlVOQ19FTkQoaWRtYXBfY3B1X3JlcGxhY2VfdHRicjFfd2l0aF9mbHVz aF90bGIpCj4gKwpTd2l0Y2ggdHRicjEgdG8gcGdkKHJlZmVyIHRvIHgwKSwgYW5kIGZsdXNoIHRs YiBhbGwuCgo+ICAgLyoKPiAgICAqIHZvaWQgaWRtYXBfY3B1X3JlcGxhY2VfdHRicjEocGh5c19h ZGRyX3QgdHRicjEpCj4gICAgKgoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX18KbGludXgtYXJtLWtlcm5lbCBtYWlsaW5nIGxpc3QKbGludXgtYXJtLWtlcm5l bEBsaXN0cy5pbmZyYWRlYWQub3JnCmh0dHA6Ly9saXN0cy5pbmZyYWRlYWQub3JnL21haWxtYW4v bGlzdGluZm8vbGludXgtYXJtLWtlcm5lbAo=