From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.2 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_SANE_1 autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 57A6CC2D0A3 for ; Wed, 4 Nov 2020 14:49:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D3AD720756 for ; Wed, 4 Nov 2020 14:49:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730061AbgKDOtZ (ORCPT ); Wed, 4 Nov 2020 09:49:25 -0500 Received: from foss.arm.com ([217.140.110.172]:38268 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726564AbgKDOtX (ORCPT ); Wed, 4 Nov 2020 09:49:23 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 5B5CA139F; Wed, 4 Nov 2020 06:49:21 -0800 (PST) Received: from arm.com (usa-sjc-imap-foss1.foss.arm.com [10.121.207.14]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id E361A3F719; Wed, 4 Nov 2020 06:49:19 -0800 (PST) Date: Wed, 4 Nov 2020 14:49:16 +0000 From: Dave Martin To: Li Qiang Cc: Ard Biesheuvel , Alexandre Torgue , Catalin Marinas , Linux Crypto Mailing List , Maxime Coquelin , Will Deacon , "David S. Miller" , Linux ARM , Herbert Xu Subject: Re: [PATCH 1/1] arm64: Accelerate Adler32 using arm64 SVE instructions. Message-ID: <20201104144914.GZ6882@arm.com> References: <20201103121506.1533-1-liqiang64@huawei.com> <20201103121506.1533-2-liqiang64@huawei.com> <20201103180031.GO6882@arm.com> <8c62099c-46b5-924f-d044-e442af4aab08@huawei.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <8c62099c-46b5-924f-d044-e442af4aab08@huawei.com> User-Agent: Mutt/1.5.23 (2014-03-12) Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org On Wed, Nov 04, 2020 at 05:19:18PM +0800, Li Qiang wrote: > Hi Dave, > > Thank you very much for your reply and suggestions. :) > > 在 2020/11/4 2:00, Dave Martin 写道: > > On Tue, Nov 03, 2020 at 03:34:27PM +0100, Ard Biesheuvel wrote: > >> (+ Dave) > >> > >> Hello liqiang, > >> > >> First of all, I don't think it is safe at the moment to use SVE in the > >> kernel, as we don't preserve all state IIRC. My memory is a bit hazy, > > > > I'm not convinced that it's safe right now. SVE in the kernel is > > unsupported, partly due to cost and partly due to the lack of a > > compelling use case. > > > > I think it would be preferable to see this algo accelerated for NEON > > first, since all AArch64 hardware can benefit from that. > > Yes i am trying it seriously. :) OK, that's good. > > > > > It's good to see someone experimenting with SVE though -- so feel > > free to experiment with this in userspace and see what sort of benchmark > > you can achieve. But there's no guarantee this can be merged in the > > kernel any time soon. If there's a big enough advantage over NEON, then > > it becomes more interesting. > > Oh yes, I think so too! :) > > > > > > >> though, so perhaps Dave can elaborate? > > > > Historically there was another reason: for every nested > > kernel_neon_begin(), we would have potentially needed to save the entire > > SVE state, which is a problem -- we'd likely run out of kernel stack, > > plus it could get costly, especially for latency. Since we refactored > > the kernel-mode NEON support to remove nesting support, this is not so > > much of a problem. kernel_neon_begin() may incur a save of the full SVE > > state anyway, so in some ways it would be a good thing if we could > > actually make use of all those registers. > > > > SVE hardware remains rare, so as a general policy I don't think we > > should accept SVE implementations of any algorithm that does not > > already have a NEON implementation -- unless the contributor can > > explain why nobody with non-SVE hardware is going to care about the > > performance of that algo. > > > > > >> > >> I'll give my feedback on the code itself below, but please don't > >> consider this an ack on the intent of using SVE in the kernel. > >> > >> Could you explain why SVE is so much better than NEON here? > > > >>From my end, I think that SVE probably doesn't offer special advantages > > here beyond less messy code and more number-crunching per loop > > iteration. > > > > That doesn't mean that SVE can't beat NEON, but NEON should still offer > > a big advantage over scalar code. > > > > Since the calculations are quite simple, even the NEON version may > > tend to saturate load/store bandwidth on some hardware, in which case > > the additional performance from SVE may be limited. Experimentation > > would be needed in order to know for sure. > > Yes, I found this problem when I was testing the SVE version and NEON > version of other algorithms (higher data throughput). The load/store > unit limits the performance of SVE, resulting in just a slight improvement > in the performance of SVE compared to NEON. Right. Which suggests that NEON is the place to start. > > > > I've made some random comments on the code below -- but my knowledge of > > the SVE instruction set is a little rusty, and I haven't tried to > > understand precisely what this algo is trying to do! > > > >> > >> On Tue, 3 Nov 2020 at 13:16, l00374334 wrote: > >>> > >>> From: liqiang > >>> > >>> In the libz library, the checksum algorithm adler32 usually occupies > >>> a relatively high hot spot, and the SVE instruction set can easily > >>> accelerate it, so that the performance of libz library will be > >>> significantly improved. > >>> > >>> We can divides buf into blocks according to the bit width of SVE, > >>> and then uses vector registers to perform operations in units of blocks > >>> to achieve the purpose of acceleration. > >>> > >>> On machines that support ARM64 sve instructions, this algorithm is > >>> about 3~4 times faster than the algorithm implemented in C language > >>> in libz. The wider the SVE instruction, the better the acceleration effect. > >>> > >>> Measured on a Taishan 1951 machine that supports 256bit width SVE, > >>> below are the results of my measured random data of 1M and 10M: > >>> > >>> [root@xxx adler32]# ./benchmark 1000000 > >>> Libz alg: Time used: 608 us, 1644.7 Mb/s. > >>> SVE alg: Time used: 166 us, 6024.1 Mb/s. > >>> > >>> [root@xxx adler32]# ./benchmark 10000000 > >>> Libz alg: Time used: 6484 us, 1542.3 Mb/s. > >>> SVE alg: Time used: 2034 us, 4916.4 Mb/s. > >>> > >>> The blocks can be of any size, so the algorithm can automatically adapt > >>> to SVE hardware with different bit widths without modifying the code. > >>> > >> > >> Please drop this indentation from the commit log. > >> > >>> > >>> Signed-off-by: liqiang > >>> --- > >>> arch/arm64/crypto/Kconfig | 5 ++ > >>> arch/arm64/crypto/Makefile | 3 + > >>> arch/arm64/crypto/adler32-sve-glue.c | 93 ++++++++++++++++++++ > >>> arch/arm64/crypto/adler32-sve.S | 127 +++++++++++++++++++++++++++ > >>> crypto/testmgr.c | 8 +- > >>> crypto/testmgr.h | 13 +++ > >> > >> Please split into two patches. Also, who is going to use this "adler32" shash? > >> > >>> 6 files changed, 248 insertions(+), 1 deletion(-) > >>> create mode 100644 arch/arm64/crypto/adler32-sve-glue.c > >>> create mode 100644 arch/arm64/crypto/adler32-sve.S > >>> > >>> diff --git a/arch/arm64/crypto/Kconfig b/arch/arm64/crypto/Kconfig > >>> index b8eb045..cfe58b9 100644 > >>> --- a/arch/arm64/crypto/Kconfig > >>> +++ b/arch/arm64/crypto/Kconfig > >>> @@ -126,4 +126,9 @@ config CRYPTO_AES_ARM64_BS > >>> select CRYPTO_LIB_AES > >>> select CRYPTO_SIMD > >>> > >>> +config SVE_ADLER32 > >>> + tristate "Accelerate Adler32 using arm64 SVE instructions." > >>> + depends on ARM64_SVE > >>> + select CRYPTO_HASH > >>> + > >>> endif > >>> diff --git a/arch/arm64/crypto/Makefile b/arch/arm64/crypto/Makefile > >>> index d0901e6..45fe649 100644 > >>> --- a/arch/arm64/crypto/Makefile > >>> +++ b/arch/arm64/crypto/Makefile > >>> @@ -63,6 +63,9 @@ aes-arm64-y := aes-cipher-core.o aes-cipher-glue.o > >>> obj-$(CONFIG_CRYPTO_AES_ARM64_BS) += aes-neon-bs.o > >>> aes-neon-bs-y := aes-neonbs-core.o aes-neonbs-glue.o > >>> > >>> +obj-$(CONFIG_SVE_ADLER32) += sve-adler32.o > >>> +sve-adler32-y := adler32-sve.o adler32-sve-glue.o > >>> + > >>> CFLAGS_aes-glue-ce.o := -DUSE_V8_CRYPTO_EXTENSIONS > >>> > >>> $(obj)/aes-glue-%.o: $(src)/aes-glue.c FORCE > >>> diff --git a/arch/arm64/crypto/adler32-sve-glue.c b/arch/arm64/crypto/adler32-sve-glue.c > >>> new file mode 100644 > >>> index 0000000..cb74514 > >>> --- /dev/null > >>> +++ b/arch/arm64/crypto/adler32-sve-glue.c > >>> @@ -0,0 +1,93 @@ > >>> +// SPDX-License-Identifier: GPL-2.0-only > >>> +/* > >>> + * Accelerate Adler32 using arm64 SVE instructions. > >>> + * Automatically support all bit width of SVE > >>> + * vector(128~2048). > >>> + * > >>> + * Copyright (C) 2020 Huawei Technologies Co., Ltd. > >>> + * > >>> + * Author: Li Qiang > >>> + */ > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> + > >>> +#include > >>> +#include > >>> + > >>> +#include > >>> +#include > >>> + > >>> +/* Scalable vector extension min size 128bit */ > >>> +#define SVE_ADLER32_MIN_SIZE 16U > >>> +#define SVE_ADLER32_DIGEST_SIZE 4 > >>> +#define SVE_ADLER32_BLOCKSIZE 1 > >>> + > >>> +asmlinkage u32 adler32_sve(u32 adler, const u8 *buf, u32 len); > >>> + > >>> +static int adler32_sve_init(struct shash_desc *desc) > >>> +{ > >>> + u32 *adler32 = shash_desc_ctx(desc); > >>> + > >>> + *adler32 = 1; > >>> + return 0; > >>> +} > >>> + > >>> +static int adler32_sve_update(struct shash_desc *desc, const u8 *data, > >>> + unsigned int length) > >> > >> Please indent function parameters > >> > >>> +{ > >>> + u32 *adler32 = shash_desc_ctx(desc); > >>> + > >>> + if (length >= SVE_ADLER32_MIN_SIZE && crypto_simd_usable()) { > >>> + kernel_neon_begin(); > >>> + *adler32 = adler32_sve(*adler32, data, length); > >>> + kernel_neon_end(); > >>> + } else { > >>> + *adler32 = zlib_adler32(*adler32, data, length); > >>> + } > >>> + return 0; > >>> +} > >>> + > >>> +static int adler32_sve_final(struct shash_desc *desc, u8 *out) > >>> +{ > >>> + u32 *adler32 = shash_desc_ctx(desc); > >>> + > >>> + *(u32 *)out = *adler32; > >> > >> Please use put_unaligned here > >> > >>> + return 0; > >>> +} > >>> + > >>> +static struct shash_alg adler32_sve_alg[] = {{ > >>> + .digestsize = SVE_ADLER32_DIGEST_SIZE, > >>> + .descsize = SVE_ADLER32_DIGEST_SIZE, > >>> + .init = adler32_sve_init, > >>> + .update = adler32_sve_update, > >>> + .final = adler32_sve_final, > >>> + > >>> + .base.cra_name = "adler32", > >>> + .base.cra_driver_name = "adler32-arm64-sve", > >>> + .base.cra_priority = 200, > >>> + .base.cra_blocksize = SVE_ADLER32_BLOCKSIZE, > >>> + .base.cra_module = THIS_MODULE, > >> > >> Please make sure the indentation is correct here. > >> > >>> +}}; > >>> + > >>> +static int __init adler32_sve_mod_init(void) > >>> +{ > >>> + if (!cpu_have_named_feature(SVE)) > >>> + return 0; > >>> + > >>> + return crypto_register_shash(adler32_sve_alg); > >>> +} > >>> + > >>> +static void __exit adler32_sve_mod_exit(void) > >>> +{ > >>> + crypto_unregister_shash(adler32_sve_alg); > >>> +} > >>> + > >>> +module_init(adler32_sve_mod_init); > >>> +module_exit(adler32_sve_mod_exit); > >>> + > >>> +MODULE_AUTHOR("Li Qiang "); > >>> +MODULE_LICENSE("GPL v2"); > >>> +MODULE_ALIAS_CRYPTO("adler32"); > >>> +MODULE_ALIAS_CRYPTO("adler32-arm64-sve"); > >>> diff --git a/arch/arm64/crypto/adler32-sve.S b/arch/arm64/crypto/adler32-sve.S > >>> new file mode 100644 > >>> index 0000000..34ee4bb > >>> --- /dev/null > >>> +++ b/arch/arm64/crypto/adler32-sve.S > >>> @@ -0,0 +1,127 @@ > >>> +/* SPDX-License-Identifier: GPL-2.0-only */ > >>> +/* > >>> + * Accelerate Adler32 using arm64 SVE instructions. Automatically support all bit > >>> + * width of SVE vector(128~2048). > >>> + * > >>> + * Copyright (C) 2020 Huawei Technologies Co., Ltd. > >>> + * > >>> + * Author: Li Qiang > >>> + */ > >>> + > >>> +#include > >>> +#include > >>> + > >>> +.arch armv8-a+sve > > > > Use .arch_extension sve instead. > > > > The compiler frontend already sets .arch to the the appropriate base > > architecture already; that shouldn't be overridden unless there is a > > good reason. > > > >>> +.file "adler32_sve.S" > >> > >> Drop the .file > >> > >> Please indent the rest 1 tab > >> > >>> +.text > >>> +.align 6 > >>> + > >>> +//The supported sve vector length range is 128~2048 by this Adler_sequence > >>> +.Adler_sequence: > >> > >> This should be in .rodata. Also, if you use . or L prefixes, use .L > >> because that is what you need to make these local symbols. > >> > >> > >>> + .short 256,255,254,253,252,251,250,249,248,247,246,245,244,243,242,241 > >>> + .short 240,239,238,237,236,235,234,233,232,231,230,229,228,227,226,225 > >>> + .short 224,223,222,221,220,219,218,217,216,215,214,213,212,211,210,209 > >>> + .short 208,207,206,205,204,203,202,201,200,199,198,197,196,195,194,193 > >>> + .short 192,191,190,189,188,187,186,185,184,183,182,181,180,179,178,177 > >>> + .short 176,175,174,173,172,171,170,169,168,167,166,165,164,163,162,161 > >>> + .short 160,159,158,157,156,155,154,153,152,151,150,149,148,147,146,145 > >>> + .short 144,143,142,141,140,139,138,137,136,135,134,133,132,131,130,129 > >>> + .short 128,127,126,125,124,123,122,121,120,119,118,117,116,115,114,113 > >>> + .short 112,111,110,109,108,107,106,105,104,103,102,101,100, 99, 98, 97 > >>> + .short 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81 > >>> + .short 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65 > >>> + .short 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49 > >>> + .short 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33 > >>> + .short 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17 > >>> + .short 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 > >>> + > >>> +SYM_FUNC_START(adler32_sve) > >>> + and w10, w0, #0xffff > >>> + lsr w11, w0, #16 > >>> + > >> > >> Please put the instruction mnemonics in different columns using tabs > >> > >>> + // Get the length of the sve vector to x6. > >>> + mov x6, #0 > >>> + mov x9, #256 > >>> + addvl x6, x6, #1 > >>> + adr x12, .Adler_sequence > >>> + ptrue p1.h > >>> + > >>> + // Get the starting position of the required sequence. > >>> + sub x9, x9, x6 > >>> + ld1h z24.h, p1/z, [x12, x9, lsl #1] // taps1 to z24.h > >>> + inch x9 > >>> + ld1h z25.h, p1/z, [x12, x9, lsl #1] // taps2 to z25.h > > > > This seems cumbersome, and will explode if SVE is ever extended to > > support vectors larger than 256 bytes (though that's probably not very > > likely any time soon). > > > > Can you do something like the following (untested)? > > > > ptrue p0.h > > index z0.h, #0, #1 > > mov z1.d, z0.d > > dech z0.h > > dech z1.h, all, mul #2 > > negh z0.h, p0/m, z0.h > > negh z1.h, p0/m, z1.h > > > > > >>> + mov x9, #0 > >>> + // A little of byte, jumper to normal proc > >> > >> What does this comment mean? > >> > >>> + mov x14, #3 > >>> + mul x15, x14, x6 > >>> + cmp x2, x15 > >>> + b.le Lnormal_proc > >>> + > >>> + ptrue p0.b > >>> +.align 6 > >> > >> Ident. > >> > >>> +LBig_loop: > >> > >> Use .L prefix > >> > >>> + // x is SVE vector length (byte). > >>> + // Bn = Bn-1 + An-1 * x + x * D1 + (x-1) * D2 + ... + 1 * Dx > >>> + // An = An-1 + D1 + D2 + D3 + ... + Dx > >>> + > >>> + .macro ADLER_BLOCK_X > >> > >> Please use lower case for asm macros, to distinguish them from CPP macros > >> Also, indent the name, and move the macro out of the function for legibility. > >> > >>> + ld1b z0.b, p0/z, [x1, x9] > >>> + incb x9 > >>> + uaddv d20, p0, z0.b // D1 + D2 + ... + Dx > >>> + mov x12, v20.2d[0] > >>> + madd x11, x10, x6, x11 // Bn = An-1 * x + Bn-1 > >>> + > >>> + uunpklo z26.h, z0.b > >>> + uunpkhi z27.h, z0.b > > > > Instead of loading and then unpacking elements, it's best to do it in > > one go. If you increment the base address as you go, this becomes > > something like (untested): > > > > ld1b z26.h, p0/z, [x1] > > ld1b z27.h, p0/z, [x1, #1, mul vl] > > inch x1, all, mul #2 > > > > (you could keep a pre-incremented version of x1 or x9 in some other > > register to eliminate one of these inch instructions). > > > >>> + mul z26.h, p1/m, z26.h, z24.h // x * D1 + (x-1) * D2 + ... + (x/2 + 1) * D(x/2) > >>> + mul z27.h, p1/m, z27.h, z25.h // (x/2) * D(x/2 + 1) + (x/2 - 1) * D(x/2 + 2) + ... + 1 * Dx > >>> + > >>> + uaddv d21, p1, z26.h > >>> + uaddv d22, p1, z27.h > >>> + mov x13, v21.2d[0] > >>> + mov x14, v22.2d[0] > >>> + > >>> + add x11, x13, x11 > >>> + add x11, x14, x11 // Bn += x * D1 + (x-1) * D2 + ... + 1 * Dx > >>> + add x10, x12, x10 // An += D1 + D2 + ... + Dx > > > > If you want best performance, you should do accumulations outside the > > core loop. Vertical reduction instructions such as UADDV need to > > collect the results of multiple element-by-element calculations which > > can otherwise proceed independenly, so doing this too often will heavily > > constrain the ways in which the hardware can schedule the calculations. > > > > Instead, you can accumulate column-wise partial sums with vector MAD > > instructions (maybe with MOXPRFX, since MAD is overwrites a source > > operand). > > > > To avoid frequent overflows, it may make sense to operate on quite wide > > elements within the loop, but you will still need to limit the number of > > loop interations to ensure that an overflow cannot happen. > > I will carefully read and test your code suggestions next, thank you. > > > > >>> + .endm > >>> + ADLER_BLOCK_X > >>> + ADLER_BLOCK_X > >>> + ADLER_BLOCK_X > >>> + // calc = reg0 % 65521 > >>> + .macro mod65521, reg0, reg1, reg2 > >>> + mov w\reg1, #0x8071 > >>> + mov w\reg2, #0xfff1 > >>> + movk w\reg1, #0x8007, lsl #16 > >>> + umull x\reg1, w\reg0, w\reg1 > >>> + lsr x\reg1, x\reg1, #47 > >>> + msub w\reg0, w\reg1, w\reg2, w\reg0 > >>> + .endm > >>> + > >> > >> Same as above > >> > >>> + mod65521 10, 14, 12 > >>> + mod65521 11, 14, 12 > >>> + > >>> + sub x2, x2, x15 > >>> + cmp x2, x15 > >>> + b.ge LBig_loop > >>> + > >>> +.align 6 > >> > >> Indent > >> > >>> +Lnormal_proc: > >> > >> .L > >> > >> > >>> + cmp x2, #0 > >>> + b.eq Lret > >>> + > >>> + ldrb w12, [x1, x9] > >>> + add x9, x9, #1 > >>> + add x10, x12, x10 > >>> + add x11, x10, x11 > >>> + sub x2, x2, #1 > > > > I haven't tried to understand this algorithm in detail, but there should > > probably be no need for this special case to handle the trailing bytes. > > > > You should search for examples of speculative vectorization using > > WHILELO etc., to get a better feel for how to do this. > > Yes, I have considered this problem, but I have not found a good way to achieve it, > because before the end of the loop is reached, the decreasing sequence used for > calculation is determined. > > For example, buf is divided into 32-byte blocks. This sequence should be 32,31,...,2,1, > if there are only 10 bytes left at the end of the loop, then this sequence > should be 10,9,8,...,2,1. > > If I judge whether the end of the loop has been reached in the body of the loop, > and reset the starting point of the sequence according to the length of the tail, > it does not seem very good. That would indeed be inefficient, since the adjustment is only needed on the last iteration. Can you do instead do the adjustment after the loop ends? For example, if y = x[n] * 32 + x[n+1] * 31 + x[n+2] * 30 ... then y - (x[n] * 22 + x[n+1] * 22 + x[n+2] * 22 ...) equals x[n] + 10 + x[n+1] * 9 + x[n+2] * 8 + ,,, (This isn't exactly what the algorithm demands, but hopefully you see the general idea.) [...] Cheers ---Dave From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.2 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_SANE_1 autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 25E26C2D0A3 for ; Wed, 4 Nov 2020 14:49:58 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 9B74D20704 for ; Wed, 4 Nov 2020 14:49:57 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="kpCeRj1U" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9B74D20704 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=arm.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:References:Message-ID: Subject:To:From:Date:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=B8o9n2pKWw3VpOrJaQ6aILBH7XYNIEux1ckKBvLGQ0w=; b=kpCeRj1UQXUXU6Jn2evzmjbrg A7FFALqUl7KOUTsU+APrVSxefShfzYcSGOctI5zoCufqkKb6WXALQ3JWZMp2PuKIdZXxUacF9Lagk NxVh/t64sE1O++tlHEQaLSFJg2CSdBljT0UiRRikF0PNGB1x2LG6a6d2Rsjj0Vxg2imDHMrhtTe3d fP4EbwpPPqO8QWhGlELf/SiyZFDF4d7ZRfZYdoePOMB3fwGpbtp5ZEDtW4VpUmPD7UD196KtOxu2T di/NGERqpoqccxEZhV+yoytJLP1Wk76flVg47LpuTMYfWXxMidAcxvEnbFbGgqK+EHUq/bZLA/pBH hk8zFq+AA==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kaK6H-0006ga-U8; Wed, 04 Nov 2020 14:49:25 +0000 Received: from foss.arm.com ([217.140.110.172]) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kaK6E-0006fV-CX for linux-arm-kernel@lists.infradead.org; Wed, 04 Nov 2020 14:49:24 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 5B5CA139F; Wed, 4 Nov 2020 06:49:21 -0800 (PST) Received: from arm.com (usa-sjc-imap-foss1.foss.arm.com [10.121.207.14]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id E361A3F719; Wed, 4 Nov 2020 06:49:19 -0800 (PST) Date: Wed, 4 Nov 2020 14:49:16 +0000 From: Dave Martin To: Li Qiang Subject: Re: [PATCH 1/1] arm64: Accelerate Adler32 using arm64 SVE instructions. Message-ID: <20201104144914.GZ6882@arm.com> References: <20201103121506.1533-1-liqiang64@huawei.com> <20201103121506.1533-2-liqiang64@huawei.com> <20201103180031.GO6882@arm.com> <8c62099c-46b5-924f-d044-e442af4aab08@huawei.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <8c62099c-46b5-924f-d044-e442af4aab08@huawei.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20201104_094922_543674_440A0D57 X-CRM114-Status: GOOD ( 65.44 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexandre Torgue , Catalin Marinas , "David S. Miller" , Linux Crypto Mailing List , Maxime Coquelin , Will Deacon , Ard Biesheuvel , Linux ARM , Herbert Xu Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org T24gV2VkLCBOb3YgMDQsIDIwMjAgYXQgMDU6MTk6MThQTSArMDgwMCwgTGkgUWlhbmcgd3JvdGU6 Cj4gSGkgRGF2ZSwKPiAKPiBUaGFuayB5b3UgdmVyeSBtdWNoIGZvciB5b3VyIHJlcGx5IGFuZCBz dWdnZXN0aW9ucy4gOikKPiAKPiDlnKggMjAyMC8xMS80IDI6MDAsIERhdmUgTWFydGluIOWGmemB kzoKPiA+IE9uIFR1ZSwgTm92IDAzLCAyMDIwIGF0IDAzOjM0OjI3UE0gKzAxMDAsIEFyZCBCaWVz aGV1dmVsIHdyb3RlOgo+ID4+ICgrIERhdmUpCj4gPj4KPiA+PiBIZWxsbyBsaXFpYW5nLAo+ID4+ Cj4gPj4gRmlyc3Qgb2YgYWxsLCBJIGRvbid0IHRoaW5rIGl0IGlzIHNhZmUgYXQgdGhlIG1vbWVu dCB0byB1c2UgU1ZFIGluIHRoZQo+ID4+IGtlcm5lbCwgYXMgd2UgZG9uJ3QgcHJlc2VydmUgYWxs IHN0YXRlIElJUkMuIE15IG1lbW9yeSBpcyBhIGJpdCBoYXp5LAo+ID4gCj4gPiBJJ20gbm90IGNv bnZpbmNlZCB0aGF0IGl0J3Mgc2FmZSByaWdodCBub3cuICBTVkUgaW4gdGhlIGtlcm5lbCBpcwo+ ID4gdW5zdXBwb3J0ZWQsIHBhcnRseSBkdWUgdG8gY29zdCBhbmQgcGFydGx5IGR1ZSB0byB0aGUg bGFjayBvZiBhCj4gPiBjb21wZWxsaW5nIHVzZSBjYXNlLgo+ID4gCj4gPiBJIHRoaW5rIGl0IHdv dWxkIGJlIHByZWZlcmFibGUgdG8gc2VlIHRoaXMgYWxnbyBhY2NlbGVyYXRlZCBmb3IgTkVPTgo+ ID4gZmlyc3QsIHNpbmNlIGFsbCBBQXJjaDY0IGhhcmR3YXJlIGNhbiBiZW5lZml0IGZyb20gdGhh dC4KPiAKPiBZZXMgaSBhbSB0cnlpbmcgaXQgc2VyaW91c2x5LiA6KQoKT0ssIHRoYXQncyBnb29k LgoKPiAKPiA+IAo+ID4gSXQncyBnb29kIHRvIHNlZSBzb21lb25lIGV4cGVyaW1lbnRpbmcgd2l0 aCBTVkUgdGhvdWdoIC0tIHNvIGZlZWwKPiA+IGZyZWUgdG8gZXhwZXJpbWVudCB3aXRoIHRoaXMg aW4gdXNlcnNwYWNlIGFuZCBzZWUgd2hhdCBzb3J0IG9mIGJlbmNobWFyawo+ID4geW91IGNhbiBh Y2hpZXZlLiAgQnV0IHRoZXJlJ3Mgbm8gZ3VhcmFudGVlIHRoaXMgY2FuIGJlIG1lcmdlZCBpbiB0 aGUKPiA+IGtlcm5lbCBhbnkgdGltZSBzb29uLiAgSWYgdGhlcmUncyBhIGJpZyBlbm91Z2ggYWR2 YW50YWdlIG92ZXIgTkVPTiwgdGhlbgo+ID4gaXQgYmVjb21lcyBtb3JlIGludGVyZXN0aW5nLgo+ IAo+IE9oIHllcywgSSB0aGluayBzbyB0b28hIDopCj4gCj4gPiAKPiA+IAo+ID4+IHRob3VnaCwg c28gcGVyaGFwcyBEYXZlIGNhbiBlbGFib3JhdGU/Cj4gPiAKPiA+IEhpc3RvcmljYWxseSB0aGVy ZSB3YXMgYW5vdGhlciByZWFzb246IGZvciBldmVyeSBuZXN0ZWQKPiA+IGtlcm5lbF9uZW9uX2Jl Z2luKCksIHdlIHdvdWxkIGhhdmUgcG90ZW50aWFsbHkgbmVlZGVkIHRvIHNhdmUgdGhlIGVudGly ZQo+ID4gU1ZFIHN0YXRlLCB3aGljaCBpcyBhIHByb2JsZW0gLS0gd2UnZCBsaWtlbHkgcnVuIG91 dCBvZiBrZXJuZWwgc3RhY2ssCj4gPiBwbHVzIGl0IGNvdWxkIGdldCBjb3N0bHksIGVzcGVjaWFs bHkgZm9yIGxhdGVuY3kuICBTaW5jZSB3ZSByZWZhY3RvcmVkCj4gPiB0aGUga2VybmVsLW1vZGUg TkVPTiBzdXBwb3J0IHRvIHJlbW92ZSBuZXN0aW5nIHN1cHBvcnQsIHRoaXMgaXMgbm90IHNvCj4g PiBtdWNoIG9mIGEgcHJvYmxlbS4gIGtlcm5lbF9uZW9uX2JlZ2luKCkgbWF5IGluY3VyIGEgc2F2 ZSBvZiB0aGUgZnVsbCBTVkUKPiA+IHN0YXRlIGFueXdheSwgc28gaW4gc29tZSB3YXlzIGl0IHdv dWxkIGJlIGEgZ29vZCB0aGluZyBpZiB3ZSBjb3VsZAo+ID4gYWN0dWFsbHkgbWFrZSB1c2Ugb2Yg YWxsIHRob3NlIHJlZ2lzdGVycy4KPiA+IAo+ID4gU1ZFIGhhcmR3YXJlIHJlbWFpbnMgcmFyZSwg c28gYXMgYSBnZW5lcmFsIHBvbGljeSBJIGRvbid0IHRoaW5rIHdlCj4gPiBzaG91bGQgYWNjZXB0 IFNWRSBpbXBsZW1lbnRhdGlvbnMgb2YgYW55IGFsZ29yaXRobSB0aGF0IGRvZXMgbm90Cj4gPiBh bHJlYWR5IGhhdmUgYSBORU9OIGltcGxlbWVudGF0aW9uIC0tIHVubGVzcyB0aGUgY29udHJpYnV0 b3IgY2FuCj4gPiBleHBsYWluIHdoeSBub2JvZHkgd2l0aCBub24tU1ZFIGhhcmR3YXJlIGlzIGdv aW5nIHRvIGNhcmUgYWJvdXQgdGhlCj4gPiBwZXJmb3JtYW5jZSBvZiB0aGF0IGFsZ28uCj4gPiAK PiA+IAo+ID4+Cj4gPj4gSSdsbCBnaXZlIG15IGZlZWRiYWNrIG9uIHRoZSBjb2RlIGl0c2VsZiBi ZWxvdywgYnV0IHBsZWFzZSBkb24ndAo+ID4+IGNvbnNpZGVyIHRoaXMgYW4gYWNrIG9uIHRoZSBp bnRlbnQgb2YgdXNpbmcgU1ZFIGluIHRoZSBrZXJuZWwuCj4gPj4KPiA+PiBDb3VsZCB5b3UgZXhw bGFpbiB3aHkgU1ZFIGlzIHNvIG11Y2ggYmV0dGVyIHRoYW4gTkVPTiBoZXJlPwo+ID4gCj4gPj5G cm9tIG15IGVuZCwgSSB0aGluayB0aGF0IFNWRSBwcm9iYWJseSBkb2Vzbid0IG9mZmVyIHNwZWNp YWwgYWR2YW50YWdlcwo+ID4gaGVyZSBiZXlvbmQgbGVzcyBtZXNzeSBjb2RlIGFuZCBtb3JlIG51 bWJlci1jcnVuY2hpbmcgcGVyIGxvb3AKPiA+IGl0ZXJhdGlvbi4KPiA+IAo+ID4gVGhhdCBkb2Vz bid0IG1lYW4gdGhhdCBTVkUgY2FuJ3QgYmVhdCBORU9OLCBidXQgTkVPTiBzaG91bGQgc3RpbGwg b2ZmZXIKPiA+IGEgYmlnIGFkdmFudGFnZSBvdmVyIHNjYWxhciBjb2RlLgo+ID4gCj4gPiBTaW5j ZSB0aGUgY2FsY3VsYXRpb25zIGFyZSBxdWl0ZSBzaW1wbGUsIGV2ZW4gdGhlIE5FT04gdmVyc2lv biBtYXkKPiA+IHRlbmQgdG8gc2F0dXJhdGUgbG9hZC9zdG9yZSBiYW5kd2lkdGggb24gc29tZSBo YXJkd2FyZSwgaW4gd2hpY2ggY2FzZQo+ID4gdGhlIGFkZGl0aW9uYWwgcGVyZm9ybWFuY2UgZnJv bSBTVkUgbWF5IGJlIGxpbWl0ZWQuICBFeHBlcmltZW50YXRpb24KPiA+IHdvdWxkIGJlIG5lZWRl ZCBpbiBvcmRlciB0byBrbm93IGZvciBzdXJlLgo+IAo+IFllcywgSSBmb3VuZCB0aGlzIHByb2Js ZW0gd2hlbiBJIHdhcyB0ZXN0aW5nIHRoZSBTVkUgdmVyc2lvbiBhbmQgTkVPTgo+IHZlcnNpb24g b2Ygb3RoZXIgYWxnb3JpdGhtcyAoaGlnaGVyIGRhdGEgdGhyb3VnaHB1dCkuIFRoZSBsb2FkL3N0 b3JlCj4gdW5pdCBsaW1pdHMgdGhlIHBlcmZvcm1hbmNlIG9mIFNWRSwgcmVzdWx0aW5nIGluIGp1 c3QgYSBzbGlnaHQgaW1wcm92ZW1lbnQKPiBpbiB0aGUgcGVyZm9ybWFuY2Ugb2YgU1ZFIGNvbXBh cmVkIHRvIE5FT04uCgpSaWdodC4gIFdoaWNoIHN1Z2dlc3RzIHRoYXQgTkVPTiBpcyB0aGUgcGxh Y2UgdG8gc3RhcnQuCgo+ID4gCj4gPiBJJ3ZlIG1hZGUgc29tZSByYW5kb20gY29tbWVudHMgb24g dGhlIGNvZGUgYmVsb3cgLS0gYnV0IG15IGtub3dsZWRnZSBvZgo+ID4gdGhlIFNWRSBpbnN0cnVj dGlvbiBzZXQgaXMgYSBsaXR0bGUgcnVzdHksIGFuZCBJIGhhdmVuJ3QgdHJpZWQgdG8KPiA+IHVu ZGVyc3RhbmQgcHJlY2lzZWx5IHdoYXQgdGhpcyBhbGdvIGlzIHRyeWluZyB0byBkbyEKPiA+IAo+ ID4+Cj4gPj4gT24gVHVlLCAzIE5vdiAyMDIwIGF0IDEzOjE2LCBsMDAzNzQzMzQgPGxpcWlhbmc2 NEBodWF3ZWkuY29tPiB3cm90ZToKPiA+Pj4KPiA+Pj4gRnJvbTogbGlxaWFuZyA8bGlxaWFuZzY0 QGh1YXdlaS5jb20+Cj4gPj4+Cj4gPj4+ICAgICAgICAgSW4gdGhlIGxpYnogbGlicmFyeSwgdGhl IGNoZWNrc3VtIGFsZ29yaXRobSBhZGxlcjMyIHVzdWFsbHkgb2NjdXBpZXMKPiA+Pj4gICAgICAg ICBhIHJlbGF0aXZlbHkgaGlnaCBob3Qgc3BvdCwgYW5kIHRoZSBTVkUgaW5zdHJ1Y3Rpb24gc2V0 IGNhbiBlYXNpbHkKPiA+Pj4gICAgICAgICBhY2NlbGVyYXRlIGl0LCBzbyB0aGF0IHRoZSBwZXJm b3JtYW5jZSBvZiBsaWJ6IGxpYnJhcnkgd2lsbCBiZQo+ID4+PiAgICAgICAgIHNpZ25pZmljYW50 bHkgaW1wcm92ZWQuCj4gPj4+Cj4gPj4+ICAgICAgICAgV2UgY2FuIGRpdmlkZXMgYnVmIGludG8g YmxvY2tzIGFjY29yZGluZyB0byB0aGUgYml0IHdpZHRoIG9mIFNWRSwKPiA+Pj4gICAgICAgICBh bmQgdGhlbiB1c2VzIHZlY3RvciByZWdpc3RlcnMgdG8gcGVyZm9ybSBvcGVyYXRpb25zIGluIHVu aXRzIG9mIGJsb2Nrcwo+ID4+PiAgICAgICAgIHRvIGFjaGlldmUgdGhlIHB1cnBvc2Ugb2YgYWNj ZWxlcmF0aW9uLgo+ID4+Pgo+ID4+PiAgICAgICAgIE9uIG1hY2hpbmVzIHRoYXQgc3VwcG9ydCBB Uk02NCBzdmUgaW5zdHJ1Y3Rpb25zLCB0aGlzIGFsZ29yaXRobSBpcwo+ID4+PiAgICAgICAgIGFi b3V0IDN+NCB0aW1lcyBmYXN0ZXIgdGhhbiB0aGUgYWxnb3JpdGhtIGltcGxlbWVudGVkIGluIEMg bGFuZ3VhZ2UKPiA+Pj4gICAgICAgICBpbiBsaWJ6LiBUaGUgd2lkZXIgdGhlIFNWRSBpbnN0cnVj dGlvbiwgdGhlIGJldHRlciB0aGUgYWNjZWxlcmF0aW9uIGVmZmVjdC4KPiA+Pj4KPiA+Pj4gICAg ICAgICBNZWFzdXJlZCBvbiBhIFRhaXNoYW4gMTk1MSBtYWNoaW5lIHRoYXQgc3VwcG9ydHMgMjU2 Yml0IHdpZHRoIFNWRSwKPiA+Pj4gICAgICAgICBiZWxvdyBhcmUgdGhlIHJlc3VsdHMgb2YgbXkg bWVhc3VyZWQgcmFuZG9tIGRhdGEgb2YgMU0gYW5kIDEwTToKPiA+Pj4KPiA+Pj4gICAgICAgICAg ICAgICAgIFtyb290QHh4eCBhZGxlcjMyXSMgLi9iZW5jaG1hcmsgMTAwMDAwMAo+ID4+PiAgICAg ICAgICAgICAgICAgTGlieiBhbGc6IFRpbWUgdXNlZDogICAgNjA4IHVzLCAxNjQ0LjcgTWIvcy4K PiA+Pj4gICAgICAgICAgICAgICAgIFNWRSAgYWxnOiBUaW1lIHVzZWQ6ICAgIDE2NiB1cywgNjAy NC4xIE1iL3MuCj4gPj4+Cj4gPj4+ICAgICAgICAgICAgICAgICBbcm9vdEB4eHggYWRsZXIzMl0j IC4vYmVuY2htYXJrIDEwMDAwMDAwCj4gPj4+ICAgICAgICAgICAgICAgICBMaWJ6IGFsZzogVGlt ZSB1c2VkOiAgIDY0ODQgdXMsIDE1NDIuMyBNYi9zLgo+ID4+PiAgICAgICAgICAgICAgICAgU1ZF ICBhbGc6IFRpbWUgdXNlZDogICAyMDM0IHVzLCA0OTE2LjQgTWIvcy4KPiA+Pj4KPiA+Pj4gICAg ICAgICBUaGUgYmxvY2tzIGNhbiBiZSBvZiBhbnkgc2l6ZSwgc28gdGhlIGFsZ29yaXRobSBjYW4g YXV0b21hdGljYWxseSBhZGFwdAo+ID4+PiAgICAgICAgIHRvIFNWRSBoYXJkd2FyZSB3aXRoIGRp ZmZlcmVudCBiaXQgd2lkdGhzIHdpdGhvdXQgbW9kaWZ5aW5nIHRoZSBjb2RlLgo+ID4+Pgo+ID4+ Cj4gPj4gUGxlYXNlIGRyb3AgdGhpcyBpbmRlbnRhdGlvbiBmcm9tIHRoZSBjb21taXQgbG9nLgo+ ID4+Cj4gPj4+Cj4gPj4+IFNpZ25lZC1vZmYtYnk6IGxpcWlhbmcgPGxpcWlhbmc2NEBodWF3ZWku Y29tPgo+ID4+PiAtLS0KPiA+Pj4gIGFyY2gvYXJtNjQvY3J5cHRvL0tjb25maWcgICAgICAgICAg ICB8ICAgNSArKwo+ID4+PiAgYXJjaC9hcm02NC9jcnlwdG8vTWFrZWZpbGUgICAgICAgICAgIHwg ICAzICsKPiA+Pj4gIGFyY2gvYXJtNjQvY3J5cHRvL2FkbGVyMzItc3ZlLWdsdWUuYyB8ICA5MyAr KysrKysrKysrKysrKysrKysrKwo+ID4+PiAgYXJjaC9hcm02NC9jcnlwdG8vYWRsZXIzMi1zdmUu UyAgICAgIHwgMTI3ICsrKysrKysrKysrKysrKysrKysrKysrKysrKwo+ID4+PiAgY3J5cHRvL3Rl c3RtZ3IuYyAgICAgICAgICAgICAgICAgICAgIHwgICA4ICstCj4gPj4+ICBjcnlwdG8vdGVzdG1n ci5oICAgICAgICAgICAgICAgICAgICAgfCAgMTMgKysrCj4gPj4KPiA+PiBQbGVhc2Ugc3BsaXQg aW50byB0d28gcGF0Y2hlcy4gQWxzbywgd2hvIGlzIGdvaW5nIHRvIHVzZSB0aGlzICJhZGxlcjMy IiBzaGFzaD8KPiA+Pgo+ID4+PiAgNiBmaWxlcyBjaGFuZ2VkLCAyNDggaW5zZXJ0aW9ucygrKSwg MSBkZWxldGlvbigtKQo+ID4+PiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGFyY2gvYXJtNjQvY3J5cHRv L2FkbGVyMzItc3ZlLWdsdWUuYwo+ID4+PiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGFyY2gvYXJtNjQv Y3J5cHRvL2FkbGVyMzItc3ZlLlMKPiA+Pj4KPiA+Pj4gZGlmZiAtLWdpdCBhL2FyY2gvYXJtNjQv Y3J5cHRvL0tjb25maWcgYi9hcmNoL2FybTY0L2NyeXB0by9LY29uZmlnCj4gPj4+IGluZGV4IGI4 ZWIwNDUuLmNmZTU4YjkgMTAwNjQ0Cj4gPj4+IC0tLSBhL2FyY2gvYXJtNjQvY3J5cHRvL0tjb25m aWcKPiA+Pj4gKysrIGIvYXJjaC9hcm02NC9jcnlwdG8vS2NvbmZpZwo+ID4+PiBAQCAtMTI2LDQg KzEyNiw5IEBAIGNvbmZpZyBDUllQVE9fQUVTX0FSTTY0X0JTCj4gPj4+ICAgICAgICAgc2VsZWN0 IENSWVBUT19MSUJfQUVTCj4gPj4+ICAgICAgICAgc2VsZWN0IENSWVBUT19TSU1ECj4gPj4+Cj4g Pj4+ICtjb25maWcgU1ZFX0FETEVSMzIKPiA+Pj4gKyAgICAgICB0cmlzdGF0ZSAiQWNjZWxlcmF0 ZSBBZGxlcjMyIHVzaW5nIGFybTY0IFNWRSBpbnN0cnVjdGlvbnMuIgo+ID4+PiArICAgICAgIGRl cGVuZHMgb24gQVJNNjRfU1ZFCj4gPj4+ICsgICAgICAgc2VsZWN0IENSWVBUT19IQVNICj4gPj4+ ICsKPiA+Pj4gIGVuZGlmCj4gPj4+IGRpZmYgLS1naXQgYS9hcmNoL2FybTY0L2NyeXB0by9NYWtl ZmlsZSBiL2FyY2gvYXJtNjQvY3J5cHRvL01ha2VmaWxlCj4gPj4+IGluZGV4IGQwOTAxZTYuLjQ1 ZmU2NDkgMTAwNjQ0Cj4gPj4+IC0tLSBhL2FyY2gvYXJtNjQvY3J5cHRvL01ha2VmaWxlCj4gPj4+ ICsrKyBiL2FyY2gvYXJtNjQvY3J5cHRvL01ha2VmaWxlCj4gPj4+IEBAIC02Myw2ICs2Myw5IEBA IGFlcy1hcm02NC15IDo9IGFlcy1jaXBoZXItY29yZS5vIGFlcy1jaXBoZXItZ2x1ZS5vCj4gPj4+ ICBvYmotJChDT05GSUdfQ1JZUFRPX0FFU19BUk02NF9CUykgKz0gYWVzLW5lb24tYnMubwo+ID4+ PiAgYWVzLW5lb24tYnMteSA6PSBhZXMtbmVvbmJzLWNvcmUubyBhZXMtbmVvbmJzLWdsdWUubwo+ ID4+Pgo+ID4+PiArb2JqLSQoQ09ORklHX1NWRV9BRExFUjMyKSArPSBzdmUtYWRsZXIzMi5vCj4g Pj4+ICtzdmUtYWRsZXIzMi15IDo9IGFkbGVyMzItc3ZlLm8gYWRsZXIzMi1zdmUtZ2x1ZS5vCj4g Pj4+ICsKPiA+Pj4gIENGTEFHU19hZXMtZ2x1ZS1jZS5vICAgOj0gLURVU0VfVjhfQ1JZUFRPX0VY VEVOU0lPTlMKPiA+Pj4KPiA+Pj4gICQob2JqKS9hZXMtZ2x1ZS0lLm86ICQoc3JjKS9hZXMtZ2x1 ZS5jIEZPUkNFCj4gPj4+IGRpZmYgLS1naXQgYS9hcmNoL2FybTY0L2NyeXB0by9hZGxlcjMyLXN2 ZS1nbHVlLmMgYi9hcmNoL2FybTY0L2NyeXB0by9hZGxlcjMyLXN2ZS1nbHVlLmMKPiA+Pj4gbmV3 IGZpbGUgbW9kZSAxMDA2NDQKPiA+Pj4gaW5kZXggMDAwMDAwMC4uY2I3NDUxNAo+ID4+PiAtLS0g L2Rldi9udWxsCj4gPj4+ICsrKyBiL2FyY2gvYXJtNjQvY3J5cHRvL2FkbGVyMzItc3ZlLWdsdWUu Ywo+ID4+PiBAQCAtMCwwICsxLDkzIEBACj4gPj4+ICsvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmll cjogR1BMLTIuMC1vbmx5Cj4gPj4+ICsvKgo+ID4+PiArICogQWNjZWxlcmF0ZSBBZGxlcjMyIHVz aW5nIGFybTY0IFNWRSBpbnN0cnVjdGlvbnMuCj4gPj4+ICsgKiBBdXRvbWF0aWNhbGx5IHN1cHBv cnQgYWxsIGJpdCB3aWR0aCBvZiBTVkUKPiA+Pj4gKyAqIHZlY3RvcigxMjh+MjA0OCkuCj4gPj4+ ICsgKgo+ID4+PiArICogQ29weXJpZ2h0IChDKSAyMDIwIEh1YXdlaSBUZWNobm9sb2dpZXMgQ28u LCBMdGQuCj4gPj4+ICsgKgo+ID4+PiArICogQXV0aG9yOiBMaSBRaWFuZyA8bGlxaWFuZzY0QGh1 YXdlaS5jb20+Cj4gPj4+ICsgKi8KPiA+Pj4gKyNpbmNsdWRlIDxsaW51eC9jcHVmZWF0dXJlLmg+ Cj4gPj4+ICsjaW5jbHVkZSA8bGludXgva2VybmVsLmg+Cj4gPj4+ICsjaW5jbHVkZSA8bGludXgv bW9kdWxlLmg+Cj4gPj4+ICsjaW5jbHVkZSA8bGludXgvenV0aWwuaD4KPiA+Pj4gKwo+ID4+PiAr I2luY2x1ZGUgPGNyeXB0by9pbnRlcm5hbC9oYXNoLmg+Cj4gPj4+ICsjaW5jbHVkZSA8Y3J5cHRv L2ludGVybmFsL3NpbWQuaD4KPiA+Pj4gKwo+ID4+PiArI2luY2x1ZGUgPGFzbS9uZW9uLmg+Cj4g Pj4+ICsjaW5jbHVkZSA8YXNtL3NpbWQuaD4KPiA+Pj4gKwo+ID4+PiArLyogU2NhbGFibGUgdmVj dG9yIGV4dGVuc2lvbiBtaW4gc2l6ZSAxMjhiaXQgKi8KPiA+Pj4gKyNkZWZpbmUgU1ZFX0FETEVS MzJfTUlOX1NJWkUgMTZVCj4gPj4+ICsjZGVmaW5lIFNWRV9BRExFUjMyX0RJR0VTVF9TSVpFIDQK PiA+Pj4gKyNkZWZpbmUgU1ZFX0FETEVSMzJfQkxPQ0tTSVpFIDEKPiA+Pj4gKwo+ID4+PiArYXNt bGlua2FnZSB1MzIgYWRsZXIzMl9zdmUodTMyIGFkbGVyLCBjb25zdCB1OCAqYnVmLCB1MzIgbGVu KTsKPiA+Pj4gKwo+ID4+PiArc3RhdGljIGludCBhZGxlcjMyX3N2ZV9pbml0KHN0cnVjdCBzaGFz aF9kZXNjICpkZXNjKQo+ID4+PiArewo+ID4+PiArICAgICAgIHUzMiAqYWRsZXIzMiA9IHNoYXNo X2Rlc2NfY3R4KGRlc2MpOwo+ID4+PiArCj4gPj4+ICsgICAgICAgKmFkbGVyMzIgPSAxOwo+ID4+ PiArICAgICAgIHJldHVybiAwOwo+ID4+PiArfQo+ID4+PiArCj4gPj4+ICtzdGF0aWMgaW50IGFk bGVyMzJfc3ZlX3VwZGF0ZShzdHJ1Y3Qgc2hhc2hfZGVzYyAqZGVzYywgY29uc3QgdTggKmRhdGEs Cj4gPj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgbGVu Z3RoKQo+ID4+Cj4gPj4gUGxlYXNlIGluZGVudCBmdW5jdGlvbiBwYXJhbWV0ZXJzCj4gPj4KPiA+ Pj4gK3sKPiA+Pj4gKyAgICAgICB1MzIgKmFkbGVyMzIgPSBzaGFzaF9kZXNjX2N0eChkZXNjKTsK PiA+Pj4gKwo+ID4+PiArICAgICAgIGlmIChsZW5ndGggPj0gU1ZFX0FETEVSMzJfTUlOX1NJWkUg JiYgY3J5cHRvX3NpbWRfdXNhYmxlKCkpIHsKPiA+Pj4gKyAgICAgICAgICAgICAgIGtlcm5lbF9u ZW9uX2JlZ2luKCk7Cj4gPj4+ICsgICAgICAgICAgICAgICAqYWRsZXIzMiA9IGFkbGVyMzJfc3Zl KCphZGxlcjMyLCBkYXRhLCBsZW5ndGgpOwo+ID4+PiArICAgICAgICAgICAgICAga2VybmVsX25l b25fZW5kKCk7Cj4gPj4+ICsgICAgICAgfSBlbHNlIHsKPiA+Pj4gKyAgICAgICAgICAgICAgICph ZGxlcjMyID0gemxpYl9hZGxlcjMyKCphZGxlcjMyLCBkYXRhLCBsZW5ndGgpOwo+ID4+PiArICAg ICAgIH0KPiA+Pj4gKyAgICAgICByZXR1cm4gMDsKPiA+Pj4gK30KPiA+Pj4gKwo+ID4+PiArc3Rh dGljIGludCBhZGxlcjMyX3N2ZV9maW5hbChzdHJ1Y3Qgc2hhc2hfZGVzYyAqZGVzYywgdTggKm91 dCkKPiA+Pj4gK3sKPiA+Pj4gKyAgICAgICB1MzIgKmFkbGVyMzIgPSBzaGFzaF9kZXNjX2N0eChk ZXNjKTsKPiA+Pj4gKwo+ID4+PiArICAgICAgICoodTMyICopb3V0ID0gKmFkbGVyMzI7Cj4gPj4K PiA+PiBQbGVhc2UgdXNlIHB1dF91bmFsaWduZWQgaGVyZQo+ID4+Cj4gPj4+ICsgICAgICAgcmV0 dXJuIDA7Cj4gPj4+ICt9Cj4gPj4+ICsKPiA+Pj4gK3N0YXRpYyBzdHJ1Y3Qgc2hhc2hfYWxnIGFk bGVyMzJfc3ZlX2FsZ1tdID0ge3sKPiA+Pj4gKyAgICAgICAuZGlnZXN0c2l6ZSAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgPSBTVkVfQURMRVIzMl9ESUdFU1RfU0laRSwKPiA+Pj4gKyAgICAg ICAuZGVzY3NpemUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSBTVkVfQURMRVIzMl9E SUdFU1RfU0laRSwKPiA+Pj4gKyAgICAgICAuaW5pdCAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgPSBhZGxlcjMyX3N2ZV9pbml0LAo+ID4+PiArICAgICAgIC51cGRhdGUgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICA9IGFkbGVyMzJfc3ZlX3VwZGF0ZSwKPiA+Pj4gKyAg ICAgICAuZmluYWwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSBhZGxlcjMyX3N2 ZV9maW5hbCwKPiA+Pj4gKwo+ID4+PiArICAgICAgIC5iYXNlLmNyYV9uYW1lICAgICAgICAgICAg ICAgICAgPSAiYWRsZXIzMiIsCj4gPj4+ICsgICAgICAgLmJhc2UuY3JhX2RyaXZlcl9uYW1lICAg PSAiYWRsZXIzMi1hcm02NC1zdmUiLAo+ID4+PiArICAgICAgIC5iYXNlLmNyYV9wcmlvcml0eSAg ICAgICAgICAgICAgPSAyMDAsCj4gPj4+ICsgICAgICAgLmJhc2UuY3JhX2Jsb2Nrc2l6ZSAgICAg ICAgICAgICA9IFNWRV9BRExFUjMyX0JMT0NLU0laRSwKPiA+Pj4gKyAgICAgICAuYmFzZS5jcmFf bW9kdWxlICAgICAgICAgICAgICAgID0gVEhJU19NT0RVTEUsCj4gPj4KPiA+PiBQbGVhc2UgbWFr ZSBzdXJlIHRoZSBpbmRlbnRhdGlvbiBpcyBjb3JyZWN0IGhlcmUuCj4gPj4KPiA+Pj4gK319Owo+ ID4+PiArCj4gPj4+ICtzdGF0aWMgaW50IF9faW5pdCBhZGxlcjMyX3N2ZV9tb2RfaW5pdCh2b2lk KQo+ID4+PiArewo+ID4+PiArICAgICAgIGlmICghY3B1X2hhdmVfbmFtZWRfZmVhdHVyZShTVkUp KQo+ID4+PiArICAgICAgICAgICAgICAgcmV0dXJuIDA7Cj4gPj4+ICsKPiA+Pj4gKyAgICAgICBy ZXR1cm4gY3J5cHRvX3JlZ2lzdGVyX3NoYXNoKGFkbGVyMzJfc3ZlX2FsZyk7Cj4gPj4+ICt9Cj4g Pj4+ICsKPiA+Pj4gK3N0YXRpYyB2b2lkIF9fZXhpdCBhZGxlcjMyX3N2ZV9tb2RfZXhpdCh2b2lk KQo+ID4+PiArewo+ID4+PiArICAgICAgIGNyeXB0b191bnJlZ2lzdGVyX3NoYXNoKGFkbGVyMzJf c3ZlX2FsZyk7Cj4gPj4+ICt9Cj4gPj4+ICsKPiA+Pj4gK21vZHVsZV9pbml0KGFkbGVyMzJfc3Zl X21vZF9pbml0KTsKPiA+Pj4gK21vZHVsZV9leGl0KGFkbGVyMzJfc3ZlX21vZF9leGl0KTsKPiA+ Pj4gKwo+ID4+PiArTU9EVUxFX0FVVEhPUigiTGkgUWlhbmcgPGxpcWlhbmc2NEBodWF3ZWkuY29t PiIpOwo+ID4+PiArTU9EVUxFX0xJQ0VOU0UoIkdQTCB2MiIpOwo+ID4+PiArTU9EVUxFX0FMSUFT X0NSWVBUTygiYWRsZXIzMiIpOwo+ID4+PiArTU9EVUxFX0FMSUFTX0NSWVBUTygiYWRsZXIzMi1h cm02NC1zdmUiKTsKPiA+Pj4gZGlmZiAtLWdpdCBhL2FyY2gvYXJtNjQvY3J5cHRvL2FkbGVyMzIt c3ZlLlMgYi9hcmNoL2FybTY0L2NyeXB0by9hZGxlcjMyLXN2ZS5TCj4gPj4+IG5ldyBmaWxlIG1v ZGUgMTAwNjQ0Cj4gPj4+IGluZGV4IDAwMDAwMDAuLjM0ZWU0YmIKPiA+Pj4gLS0tIC9kZXYvbnVs bAo+ID4+PiArKysgYi9hcmNoL2FybTY0L2NyeXB0by9hZGxlcjMyLXN2ZS5TCj4gPj4+IEBAIC0w LDAgKzEsMTI3IEBACj4gPj4+ICsvKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMC1v bmx5ICovCj4gPj4+ICsvKgo+ID4+PiArICogQWNjZWxlcmF0ZSBBZGxlcjMyIHVzaW5nIGFybTY0 IFNWRSBpbnN0cnVjdGlvbnMuIEF1dG9tYXRpY2FsbHkgc3VwcG9ydCBhbGwgYml0Cj4gPj4+ICsg KiAgICAgIHdpZHRoIG9mIFNWRSB2ZWN0b3IoMTI4fjIwNDgpLgo+ID4+PiArICoKPiA+Pj4gKyAq IENvcHlyaWdodCAoQykgMjAyMCBIdWF3ZWkgVGVjaG5vbG9naWVzIENvLiwgTHRkLgo+ID4+PiAr ICoKPiA+Pj4gKyAqIEF1dGhvcjogTGkgUWlhbmcgPGxpcWlhbmc2NEBodWF3ZWkuY29tPgo+ID4+ PiArICovCj4gPj4+ICsKPiA+Pj4gKyNpbmNsdWRlIDxsaW51eC9saW5rYWdlLmg+Cj4gPj4+ICsj aW5jbHVkZSA8YXNtL2Fzc2VtYmxlci5oPgo+ID4+PiArCj4gPj4+ICsuYXJjaCBhcm12OC1hK3N2 ZQo+ID4gCj4gPiBVc2UgLmFyY2hfZXh0ZW5zaW9uIHN2ZSBpbnN0ZWFkLgo+ID4gCj4gPiBUaGUg Y29tcGlsZXIgZnJvbnRlbmQgYWxyZWFkeSBzZXRzIC5hcmNoIHRvIHRoZSB0aGUgYXBwcm9wcmlh dGUgYmFzZQo+ID4gYXJjaGl0ZWN0dXJlIGFscmVhZHk7IHRoYXQgc2hvdWxkbid0IGJlIG92ZXJy aWRkZW4gdW5sZXNzIHRoZXJlIGlzIGEKPiA+IGdvb2QgcmVhc29uLgo+ID4gCj4gPj4+ICsuZmls ZSAiYWRsZXIzMl9zdmUuUyIKPiA+Pgo+ID4+IERyb3AgdGhlIC5maWxlCj4gPj4KPiA+PiBQbGVh c2UgaW5kZW50IHRoZSByZXN0IDEgdGFiCj4gPj4KPiA+Pj4gKy50ZXh0Cj4gPj4+ICsuYWxpZ24g Ngo+ID4+PiArCj4gPj4+ICsvL1RoZSBzdXBwb3J0ZWQgc3ZlIHZlY3RvciBsZW5ndGggcmFuZ2Ug aXMgMTI4fjIwNDggYnkgdGhpcyBBZGxlcl9zZXF1ZW5jZQo+ID4+PiArLkFkbGVyX3NlcXVlbmNl Ogo+ID4+Cj4gPj4gVGhpcyBzaG91bGQgYmUgaW4gLnJvZGF0YS4gQWxzbywgaWYgeW91IHVzZSAu IG9yIEwgcHJlZml4ZXMsIHVzZSAuTAo+ID4+IGJlY2F1c2UgdGhhdCBpcyB3aGF0IHlvdSBuZWVk IHRvIG1ha2UgdGhlc2UgbG9jYWwgc3ltYm9scy4KPiA+Pgo+ID4+Cj4gPj4+ICsgICAgICAgLnNo b3J0IDI1NiwyNTUsMjU0LDI1MywyNTIsMjUxLDI1MCwyNDksMjQ4LDI0NywyNDYsMjQ1LDI0NCwy NDMsMjQyLDI0MQo+ID4+PiArICAgICAgIC5zaG9ydCAyNDAsMjM5LDIzOCwyMzcsMjM2LDIzNSwy MzQsMjMzLDIzMiwyMzEsMjMwLDIyOSwyMjgsMjI3LDIyNiwyMjUKPiA+Pj4gKyAgICAgICAuc2hv cnQgMjI0LDIyMywyMjIsMjIxLDIyMCwyMTksMjE4LDIxNywyMTYsMjE1LDIxNCwyMTMsMjEyLDIx MSwyMTAsMjA5Cj4gPj4+ICsgICAgICAgLnNob3J0IDIwOCwyMDcsMjA2LDIwNSwyMDQsMjAzLDIw MiwyMDEsMjAwLDE5OSwxOTgsMTk3LDE5NiwxOTUsMTk0LDE5Mwo+ID4+PiArICAgICAgIC5zaG9y dCAxOTIsMTkxLDE5MCwxODksMTg4LDE4NywxODYsMTg1LDE4NCwxODMsMTgyLDE4MSwxODAsMTc5 LDE3OCwxNzcKPiA+Pj4gKyAgICAgICAuc2hvcnQgMTc2LDE3NSwxNzQsMTczLDE3MiwxNzEsMTcw LDE2OSwxNjgsMTY3LDE2NiwxNjUsMTY0LDE2MywxNjIsMTYxCj4gPj4+ICsgICAgICAgLnNob3J0 IDE2MCwxNTksMTU4LDE1NywxNTYsMTU1LDE1NCwxNTMsMTUyLDE1MSwxNTAsMTQ5LDE0OCwxNDcs MTQ2LDE0NQo+ID4+PiArICAgICAgIC5zaG9ydCAxNDQsMTQzLDE0MiwxNDEsMTQwLDEzOSwxMzgs MTM3LDEzNiwxMzUsMTM0LDEzMywxMzIsMTMxLDEzMCwxMjkKPiA+Pj4gKyAgICAgICAuc2hvcnQg MTI4LDEyNywxMjYsMTI1LDEyNCwxMjMsMTIyLDEyMSwxMjAsMTE5LDExOCwxMTcsMTE2LDExNSwx MTQsMTEzCj4gPj4+ICsgICAgICAgLnNob3J0IDExMiwxMTEsMTEwLDEwOSwxMDgsMTA3LDEwNiwx MDUsMTA0LDEwMywxMDIsMTAxLDEwMCwgOTksIDk4LCA5Nwo+ID4+PiArICAgICAgIC5zaG9ydCAg OTYsIDk1LCA5NCwgOTMsIDkyLCA5MSwgOTAsIDg5LCA4OCwgODcsIDg2LCA4NSwgODQsIDgzLCA4 MiwgODEKPiA+Pj4gKyAgICAgICAuc2hvcnQgIDgwLCA3OSwgNzgsIDc3LCA3NiwgNzUsIDc0LCA3 MywgNzIsIDcxLCA3MCwgNjksIDY4LCA2NywgNjYsIDY1Cj4gPj4+ICsgICAgICAgLnNob3J0ICA2 NCwgNjMsIDYyLCA2MSwgNjAsIDU5LCA1OCwgNTcsIDU2LCA1NSwgNTQsIDUzLCA1MiwgNTEsIDUw LCA0OQo+ID4+PiArICAgICAgIC5zaG9ydCAgNDgsIDQ3LCA0NiwgNDUsIDQ0LCA0MywgNDIsIDQx LCA0MCwgMzksIDM4LCAzNywgMzYsIDM1LCAzNCwgMzMKPiA+Pj4gKyAgICAgICAuc2hvcnQgIDMy LCAzMSwgMzAsIDI5LCAyOCwgMjcsIDI2LCAyNSwgMjQsIDIzLCAyMiwgMjEsIDIwLCAxOSwgMTgs IDE3Cj4gPj4+ICsgICAgICAgLnNob3J0ICAxNiwgMTUsIDE0LCAxMywgMTIsIDExLCAxMCwgIDks ICA4LCAgNywgIDYsICA1LCAgNCwgIDMsICAyLCAgMQo+ID4+PiArCj4gPj4+ICtTWU1fRlVOQ19T VEFSVChhZGxlcjMyX3N2ZSkKPiA+Pj4gKyAgICAgICBhbmQgdzEwLCB3MCwgIzB4ZmZmZgo+ID4+ PiArICAgICAgIGxzciB3MTEsIHcwLCAjMTYKPiA+Pj4gKwo+ID4+Cj4gPj4gUGxlYXNlIHB1dCB0 aGUgaW5zdHJ1Y3Rpb24gbW5lbW9uaWNzIGluIGRpZmZlcmVudCBjb2x1bW5zIHVzaW5nIHRhYnMK PiA+Pgo+ID4+PiArICAgICAgIC8vIEdldCB0aGUgbGVuZ3RoIG9mIHRoZSBzdmUgdmVjdG9yIHRv IHg2Lgo+ID4+PiArICAgICAgIG1vdiB4NiwgIzAKPiA+Pj4gKyAgICAgICBtb3YgeDksICMyNTYK PiA+Pj4gKyAgICAgICBhZGR2bCB4NiwgeDYsICMxCj4gPj4+ICsgICAgICAgYWRyIHgxMiwgLkFk bGVyX3NlcXVlbmNlCj4gPj4+ICsgICAgICAgcHRydWUgcDEuaAo+ID4+PiArCj4gPj4+ICsgICAg ICAgLy8gR2V0IHRoZSBzdGFydGluZyBwb3NpdGlvbiBvZiB0aGUgcmVxdWlyZWQgc2VxdWVuY2Uu Cj4gPj4+ICsgICAgICAgc3ViIHg5LCB4OSwgeDYKPiA+Pj4gKyAgICAgICBsZDFoIHoyNC5oLCBw MS96LCBbeDEyLCB4OSwgbHNsICMxXSAvLyB0YXBzMSB0byB6MjQuaAo+ID4+PiArICAgICAgIGlu Y2ggeDkKPiA+Pj4gKyAgICAgICBsZDFoIHoyNS5oLCBwMS96LCBbeDEyLCB4OSwgbHNsICMxXSAv LyB0YXBzMiB0byB6MjUuaAo+ID4gCj4gPiBUaGlzIHNlZW1zIGN1bWJlcnNvbWUsIGFuZCB3aWxs IGV4cGxvZGUgaWYgU1ZFIGlzIGV2ZXIgZXh0ZW5kZWQgdG8KPiA+IHN1cHBvcnQgdmVjdG9ycyBs YXJnZXIgdGhhbiAyNTYgYnl0ZXMgKHRob3VnaCB0aGF0J3MgcHJvYmFibHkgbm90IHZlcnkKPiA+ IGxpa2VseSBhbnkgdGltZSBzb29uKS4KPiA+IAo+ID4gQ2FuIHlvdSBkbyBzb21ldGhpbmcgbGlr ZSB0aGUgZm9sbG93aW5nICh1bnRlc3RlZCk/Cj4gPiAKPiA+IAlwdHJ1ZQlwMC5oCj4gPiAJaW5k ZXgJejAuaCwgIzAsICMxCj4gPiAJbW92CXoxLmQsIHowLmQKPiA+IAlkZWNoCXowLmgKPiA+IAlk ZWNoCXoxLmgsIGFsbCwgbXVsICMyCj4gPiAJbmVnaAl6MC5oLCBwMC9tLCB6MC5oCj4gPiAJbmVn aAl6MS5oLCBwMC9tLCB6MS5oCj4gPiAKPiA+IAo+ID4+PiArICAgICAgIG1vdiB4OSwgIzAKPiA+ Pj4gKyAgICAgICAvLyBBIGxpdHRsZSBvZiBieXRlLCBqdW1wZXIgdG8gbm9ybWFsIHByb2MKPiA+ Pgo+ID4+IFdoYXQgZG9lcyB0aGlzIGNvbW1lbnQgbWVhbj8KPiA+Pgo+ID4+PiArICAgICAgIG1v diB4MTQsICMzCj4gPj4+ICsgICAgICAgbXVsIHgxNSwgeDE0LCB4Ngo+ID4+PiArICAgICAgIGNt cCB4MiwgeDE1Cj4gPj4+ICsgICAgICAgYi5sZSBMbm9ybWFsX3Byb2MKPiA+Pj4gKwo+ID4+PiAr ICAgICAgIHB0cnVlIHAwLmIKPiA+Pj4gKy5hbGlnbiA2Cj4gPj4KPiA+PiBJZGVudC4KPiA+Pgo+ ID4+PiArTEJpZ19sb29wOgo+ID4+Cj4gPj4gVXNlIC5MIHByZWZpeAo+ID4+Cj4gPj4+ICsgICAg ICAgLy8geCBpcyBTVkUgdmVjdG9yIGxlbmd0aCAoYnl0ZSkuCj4gPj4+ICsgICAgICAgLy8gQm4g PSBCbi0xICsgQW4tMSAqIHggKyB4ICogRDEgKyAoeC0xKSAqIEQyICsgLi4uICsgMSAqIER4Cj4g Pj4+ICsgICAgICAgLy8gQW4gPSBBbi0xICsgRDEgKyBEMiArIEQzICsgLi4uICsgRHgKPiA+Pj4g Kwo+ID4+PiArICAgICAgIC5tYWNybyBBRExFUl9CTE9DS19YCj4gPj4KPiA+PiBQbGVhc2UgdXNl IGxvd2VyIGNhc2UgZm9yIGFzbSBtYWNyb3MsIHRvIGRpc3Rpbmd1aXNoIHRoZW0gZnJvbSBDUFAg bWFjcm9zCj4gPj4gQWxzbywgaW5kZW50IHRoZSBuYW1lLCBhbmQgbW92ZSB0aGUgbWFjcm8gb3V0 IG9mIHRoZSBmdW5jdGlvbiBmb3IgbGVnaWJpbGl0eS4KPiA+Pgo+ID4+PiArICAgICAgIGxkMWIg ejAuYiwgcDAveiwgW3gxLCB4OV0KPiA+Pj4gKyAgICAgICBpbmNiIHg5Cj4gPj4+ICsgICAgICAg dWFkZHYgZDIwLCBwMCwgejAuYiAvLyBEMSArIEQyICsgLi4uICsgRHgKPiA+Pj4gKyAgICAgICBt b3YgeDEyLCB2MjAuMmRbMF0KPiA+Pj4gKyAgICAgICBtYWRkIHgxMSwgeDEwLCB4NiwgeDExIC8v IEJuID0gQW4tMSAqIHggKyBCbi0xCj4gPj4+ICsKPiA+Pj4gKyAgICAgICB1dW5wa2xvIHoyNi5o LCB6MC5iCj4gPj4+ICsgICAgICAgdXVucGtoaSB6MjcuaCwgejAuYgo+ID4gCj4gPiBJbnN0ZWFk IG9mIGxvYWRpbmcgYW5kIHRoZW4gdW5wYWNraW5nIGVsZW1lbnRzLCBpdCdzIGJlc3QgdG8gZG8g aXQgaW4KPiA+IG9uZSBnby4gIElmIHlvdSBpbmNyZW1lbnQgdGhlIGJhc2UgYWRkcmVzcyBhcyB5 b3UgZ28sIHRoaXMgYmVjb21lcwo+ID4gc29tZXRoaW5nIGxpa2UgKHVudGVzdGVkKToKPiA+IAo+ ID4gCWxkMWIJejI2LmgsIHAwL3osIFt4MV0KPiA+IAlsZDFiCXoyNy5oLCBwMC96LCBbeDEsICMx LCBtdWwgdmxdCj4gPiAJaW5jaAl4MSwgYWxsLCBtdWwgIzIKPiA+IAo+ID4gKHlvdSBjb3VsZCBr ZWVwIGEgcHJlLWluY3JlbWVudGVkIHZlcnNpb24gb2YgeDEgb3IgeDkgaW4gc29tZSBvdGhlcgo+ ID4gcmVnaXN0ZXIgdG8gZWxpbWluYXRlIG9uZSBvZiB0aGVzZSBpbmNoIGluc3RydWN0aW9ucyku Cj4gPiAKPiA+Pj4gKyAgICAgICBtdWwgejI2LmgsIHAxL20sIHoyNi5oLCB6MjQuaCAvLyB4ICog RDEgKyAoeC0xKSAqIEQyICsgLi4uICsgKHgvMiArIDEpICogRCh4LzIpCj4gPj4+ICsgICAgICAg bXVsIHoyNy5oLCBwMS9tLCB6MjcuaCwgejI1LmggLy8gKHgvMikgKiBEKHgvMiArIDEpICsgKHgv MiAtIDEpICogRCh4LzIgKyAyKSArIC4uLiArIDEgKiBEeAo+ID4+PiArCj4gPj4+ICsgICAgICAg dWFkZHYgZDIxLCBwMSwgejI2LmgKPiA+Pj4gKyAgICAgICB1YWRkdiBkMjIsIHAxLCB6MjcuaAo+ ID4+PiArICAgICAgIG1vdiB4MTMsIHYyMS4yZFswXQo+ID4+PiArICAgICAgIG1vdiB4MTQsIHYy Mi4yZFswXQo+ID4+PiArCj4gPj4+ICsgICAgICAgYWRkIHgxMSwgeDEzLCB4MTEKPiA+Pj4gKyAg ICAgICBhZGQgeDExLCB4MTQsIHgxMSAgICAgICAgIC8vIEJuICs9IHggKiBEMSArICh4LTEpICog RDIgKyAuLi4gKyAxICogRHgKPiA+Pj4gKyAgICAgICBhZGQgeDEwLCB4MTIsIHgxMCAgICAgICAg IC8vIEFuICs9IEQxICsgRDIgKyAuLi4gKyBEeAo+ID4gCj4gPiBJZiB5b3Ugd2FudCBiZXN0IHBl cmZvcm1hbmNlLCB5b3Ugc2hvdWxkIGRvIGFjY3VtdWxhdGlvbnMgb3V0c2lkZSB0aGUKPiA+IGNv cmUgbG9vcC4gIFZlcnRpY2FsIHJlZHVjdGlvbiBpbnN0cnVjdGlvbnMgc3VjaCBhcyBVQUREViBu ZWVkIHRvCj4gPiBjb2xsZWN0IHRoZSByZXN1bHRzIG9mIG11bHRpcGxlIGVsZW1lbnQtYnktZWxl bWVudCBjYWxjdWxhdGlvbnMgd2hpY2gKPiA+IGNhbiBvdGhlcndpc2UgcHJvY2VlZCBpbmRlcGVu ZGVubHksIHNvIGRvaW5nIHRoaXMgdG9vIG9mdGVuIHdpbGwgaGVhdmlseQo+ID4gY29uc3RyYWlu IHRoZSB3YXlzIGluIHdoaWNoIHRoZSBoYXJkd2FyZSBjYW4gc2NoZWR1bGUgdGhlIGNhbGN1bGF0 aW9ucy4KPiA+IAo+ID4gSW5zdGVhZCwgeW91IGNhbiBhY2N1bXVsYXRlIGNvbHVtbi13aXNlIHBh cnRpYWwgc3VtcyB3aXRoIHZlY3RvciBNQUQKPiA+IGluc3RydWN0aW9ucyAobWF5YmUgd2l0aCBN T1hQUkZYLCBzaW5jZSBNQUQgaXMgb3ZlcndyaXRlcyBhIHNvdXJjZQo+ID4gb3BlcmFuZCkuCj4g PiAKPiA+IFRvIGF2b2lkIGZyZXF1ZW50IG92ZXJmbG93cywgaXQgbWF5IG1ha2Ugc2Vuc2UgdG8g b3BlcmF0ZSBvbiBxdWl0ZSB3aWRlCj4gPiBlbGVtZW50cyB3aXRoaW4gdGhlIGxvb3AsIGJ1dCB5 b3Ugd2lsbCBzdGlsbCBuZWVkIHRvIGxpbWl0IHRoZSBudW1iZXIgb2YKPiA+IGxvb3AgaW50ZXJh dGlvbnMgdG8gZW5zdXJlIHRoYXQgYW4gb3ZlcmZsb3cgY2Fubm90IGhhcHBlbi4KPiAKPiBJIHdp bGwgY2FyZWZ1bGx5IHJlYWQgYW5kIHRlc3QgeW91ciBjb2RlIHN1Z2dlc3Rpb25zIG5leHQsIHRo YW5rIHlvdS4KPiAKPiA+IAo+ID4+PiArICAgICAgIC5lbmRtCj4gPj4+ICsgICAgICAgQURMRVJf QkxPQ0tfWAo+ID4+PiArICAgICAgIEFETEVSX0JMT0NLX1gKPiA+Pj4gKyAgICAgICBBRExFUl9C TE9DS19YCj4gPj4+ICsgICAgICAgLy8gY2FsYyA9IHJlZzAgJSA2NTUyMQo+ID4+PiArICAgICAg IC5tYWNybyBtb2Q2NTUyMSwgcmVnMCwgcmVnMSwgcmVnMgo+ID4+PiArICAgICAgIG1vdiB3XHJl ZzEsICMweDgwNzEKPiA+Pj4gKyAgICAgICBtb3Ygd1xyZWcyLCAjMHhmZmYxCj4gPj4+ICsgICAg ICAgbW92ayB3XHJlZzEsICMweDgwMDcsIGxzbCAjMTYKPiA+Pj4gKyAgICAgICB1bXVsbCB4XHJl ZzEsIHdccmVnMCwgd1xyZWcxCj4gPj4+ICsgICAgICAgbHNyIHhccmVnMSwgeFxyZWcxLCAjNDcK PiA+Pj4gKyAgICAgICBtc3ViIHdccmVnMCwgd1xyZWcxLCB3XHJlZzIsIHdccmVnMAo+ID4+PiAr ICAgICAgIC5lbmRtCj4gPj4+ICsKPiA+Pgo+ID4+IFNhbWUgYXMgYWJvdmUKPiA+Pgo+ID4+PiAr ICAgICAgIG1vZDY1NTIxIDEwLCAxNCwgMTIKPiA+Pj4gKyAgICAgICBtb2Q2NTUyMSAxMSwgMTQs IDEyCj4gPj4+ICsKPiA+Pj4gKyAgICAgICBzdWIgeDIsIHgyLCB4MTUKPiA+Pj4gKyAgICAgICBj bXAgeDIsIHgxNQo+ID4+PiArICAgICAgIGIuZ2UgTEJpZ19sb29wCj4gPj4+ICsKPiA+Pj4gKy5h bGlnbiA2Cj4gPj4KPiA+PiBJbmRlbnQKPiA+Pgo+ID4+PiArTG5vcm1hbF9wcm9jOgo+ID4+Cj4g Pj4gLkwKPiA+Pgo+ID4+Cj4gPj4+ICsgICAgICAgY21wIHgyLCAjMAo+ID4+PiArICAgICAgIGIu ZXEgTHJldAo+ID4+PiArCj4gPj4+ICsgICAgICAgbGRyYiB3MTIsIFt4MSwgeDldCj4gPj4+ICsg ICAgICAgYWRkIHg5LCB4OSwgIzEKPiA+Pj4gKyAgICAgICBhZGQgeDEwLCB4MTIsIHgxMAo+ID4+ PiArICAgICAgIGFkZCB4MTEsIHgxMCwgeDExCj4gPj4+ICsgICAgICAgc3ViIHgyLCB4MiwgIzEK PiA+IAo+ID4gSSBoYXZlbid0IHRyaWVkIHRvIHVuZGVyc3RhbmQgdGhpcyBhbGdvcml0aG0gaW4g ZGV0YWlsLCBidXQgdGhlcmUgc2hvdWxkCj4gPiBwcm9iYWJseSBiZSBubyBuZWVkIGZvciB0aGlz IHNwZWNpYWwgY2FzZSB0byBoYW5kbGUgdGhlIHRyYWlsaW5nIGJ5dGVzLgo+ID4gCj4gPiBZb3Ug c2hvdWxkIHNlYXJjaCBmb3IgZXhhbXBsZXMgb2Ygc3BlY3VsYXRpdmUgdmVjdG9yaXphdGlvbiB1 c2luZwo+ID4gV0hJTEVMTyBldGMuLCB0byBnZXQgYSBiZXR0ZXIgZmVlbCBmb3IgaG93IHRvIGRv IHRoaXMuCj4gCj4gWWVzLCBJIGhhdmUgY29uc2lkZXJlZCB0aGlzIHByb2JsZW0sIGJ1dCBJIGhh dmUgbm90IGZvdW5kIGEgZ29vZCB3YXkgdG8gYWNoaWV2ZSBpdCwKPiBiZWNhdXNlIGJlZm9yZSB0 aGUgZW5kIG9mIHRoZSBsb29wIGlzIHJlYWNoZWQsIHRoZSBkZWNyZWFzaW5nIHNlcXVlbmNlIHVz ZWQgZm9yCj4gY2FsY3VsYXRpb24gaXMgZGV0ZXJtaW5lZC4KPiAKPiBGb3IgZXhhbXBsZSwgYnVm IGlzIGRpdmlkZWQgaW50byAzMi1ieXRlIGJsb2Nrcy4gVGhpcyBzZXF1ZW5jZSBzaG91bGQgYmUg MzIsMzEsLi4uLDIsMSwKPiBpZiB0aGVyZSBhcmUgb25seSAxMCBieXRlcyBsZWZ0IGF0IHRoZSBl bmQgb2YgdGhlIGxvb3AsIHRoZW4gdGhpcyBzZXF1ZW5jZQo+IHNob3VsZCBiZSAxMCw5LDgsLi4u LDIsMS4KPiAKPiBJZiBJIGp1ZGdlIHdoZXRoZXIgdGhlIGVuZCBvZiB0aGUgbG9vcCBoYXMgYmVl biByZWFjaGVkIGluIHRoZSBib2R5IG9mIHRoZSBsb29wLAo+IGFuZCByZXNldCB0aGUgc3RhcnRp bmcgcG9pbnQgb2YgdGhlIHNlcXVlbmNlIGFjY29yZGluZyB0byB0aGUgbGVuZ3RoIG9mIHRoZSB0 YWlsLAo+IGl0IGRvZXMgbm90IHNlZW0gdmVyeSBnb29kLgoKVGhhdCB3b3VsZCBpbmRlZWQgYmUg aW5lZmZpY2llbnQsIHNpbmNlIHRoZSBhZGp1c3RtZW50IGlzIG9ubHkgbmVlZGVkIG9uCnRoZSBs YXN0IGl0ZXJhdGlvbi4KCkNhbiB5b3UgZG8gaW5zdGVhZCBkbyB0aGUgYWRqdXN0bWVudCBhZnRl ciB0aGUgbG9vcCBlbmRzPwoKRm9yIGV4YW1wbGUsIGlmCgoJeSA9IHhbbl0gKiAzMiArIHhbbisx XSAqIDMxICsgeFtuKzJdICogMzAgLi4uCgp0aGVuIAoKCXkgLSAoeFtuXSAqIDIyICsgeFtuKzFd ICogMjIgKyB4W24rMl0gKiAyMiAuLi4pCgplcXVhbHMKCgl4W25dICsgMTAgKyB4W24rMV0gKiA5 ICsgeFtuKzJdICogOCArICwsLAoKKFRoaXMgaXNuJ3QgZXhhY3RseSB3aGF0IHRoZSBhbGdvcml0 aG0gZGVtYW5kcywgYnV0IGhvcGVmdWxseSB5b3Ugc2VlIHRoZQpnZW5lcmFsIGlkZWEuKQoKWy4u Ll0KCkNoZWVycwotLS1EYXZlCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fXwpsaW51eC1hcm0ta2VybmVsIG1haWxpbmcgbGlzdApsaW51eC1hcm0ta2VybmVs QGxpc3RzLmluZnJhZGVhZC5vcmcKaHR0cDovL2xpc3RzLmluZnJhZGVhZC5vcmcvbWFpbG1hbi9s aXN0aW5mby9saW51eC1hcm0ta2VybmVsCg==