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 69A57C3F6B0 for ; Tue, 9 Aug 2022 12:40:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240188AbiHIMkD (ORCPT ); Tue, 9 Aug 2022 08:40:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38082 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230178AbiHIMkD (ORCPT ); Tue, 9 Aug 2022 08:40:03 -0400 Received: from szxga02-in.huawei.com (szxga02-in.huawei.com [45.249.212.188]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E031118355; Tue, 9 Aug 2022 05:39:58 -0700 (PDT) Received: from dggemv703-chm.china.huawei.com (unknown [172.30.72.56]) by szxga02-in.huawei.com (SkyGuard) with ESMTP id 4M2CJ03w5ZzlVqJ; Tue, 9 Aug 2022 20:37:04 +0800 (CST) Received: from kwepemm600005.china.huawei.com (7.193.23.191) by dggemv703-chm.china.huawei.com (10.3.19.46) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.24; Tue, 9 Aug 2022 20:39:56 +0800 Received: from [10.67.102.118] (10.67.102.118) by kwepemm600005.china.huawei.com (7.193.23.191) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.24; Tue, 9 Aug 2022 20:39:55 +0800 Subject: Re: [PATCH v8 1/5] crypto: aspeed: Add HACE hash driver To: Neal Liu , Corentin Labbe , Christophe JAILLET , Randy Dunlap , Herbert Xu , "David S . Miller" , Rob Herring , Krzysztof Kozlowski , Joel Stanley , "Andrew Jeffery" , Dhananjay Phadke , "Johnny Huang" CC: "linux-aspeed@lists.ozlabs.org" , "linux-crypto@vger.kernel.org" , "devicetree@vger.kernel.org" , "linux-arm-kernel@lists.infradead.org" , "linux-kernel@vger.kernel.org" , BMC-SW References: <20220726113448.2964968-1-neal_liu@aspeedtech.com> <20220726113448.2964968-2-neal_liu@aspeedtech.com> <5ca081b1-9a96-5b58-7a27-75c94af119d2@huawei.com> <256d64d6-0a27-7714-60ac-580b371c2502@huawei.com> From: liulongfang Message-ID: <100bb780-39e9-bb8e-f568-e8d8d9112abf@huawei.com> Date: Tue, 9 Aug 2022 20:39:55 +0800 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:60.0) Gecko/20100101 Thunderbird/60.8.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset="gbk" Content-Transfer-Encoding: 8bit X-Originating-IP: [10.67.102.118] X-ClientProxiedBy: dggems701-chm.china.huawei.com (10.3.19.178) To kwepemm600005.china.huawei.com (7.193.23.191) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org On 2022/8/9 15:39, Neal Liu wrote: >>>> On 2022/7/26 19:34, Neal Liu wrote: >>>>> Hash and Crypto Engine (HACE) is designed to accelerate the >>>>> throughput of hash data digest, encryption, and decryption. >>>>> >>>>> Basically, HACE can be divided into two independently engines >>>>> - Hash Engine and Crypto Engine. This patch aims to add HACE hash >>>>> engine driver for hash accelerator. >>>>> >>>>> Signed-off-by: Neal Liu >>>>> Signed-off-by: Johnny Huang >>>>> --- >>>>> MAINTAINERS | 7 + >>>>> drivers/crypto/Kconfig | 1 + >>>>> drivers/crypto/Makefile | 1 + >>>>> drivers/crypto/aspeed/Kconfig | 32 + >>>>> drivers/crypto/aspeed/Makefile | 6 + >>>>> drivers/crypto/aspeed/aspeed-hace-hash.c | 1389 >>>> ++++++++++++++++++++++ >>>>> drivers/crypto/aspeed/aspeed-hace.c | 213 ++++ >>>>> drivers/crypto/aspeed/aspeed-hace.h | 186 +++ >>>>> 8 files changed, 1835 insertions(+) create mode 100644 >>>>> drivers/crypto/aspeed/Kconfig create mode 100644 >>>>> drivers/crypto/aspeed/Makefile create mode 100644 >>>>> drivers/crypto/aspeed/aspeed-hace-hash.c >>>>> create mode 100644 drivers/crypto/aspeed/aspeed-hace.c >>>>> create mode 100644 drivers/crypto/aspeed/aspeed-hace.h >>>>> >>>>> diff --git a/MAINTAINERS b/MAINTAINERS index >>>>> f55aea311af5..23a0215b7e42 100644 >>>>> --- a/MAINTAINERS >>>>> +++ b/MAINTAINERS >>>>> @@ -3140,6 +3140,13 @@ S: Maintained >>>>> F: Documentation/devicetree/bindings/media/aspeed-video.txt >>>>> F: drivers/media/platform/aspeed/ >>>>> >>>>> +ASPEED CRYPTO DRIVER >>>>> +M: Neal Liu >>>>> +L: linux-aspeed@lists.ozlabs.org (moderated for non-subscribers) >>>>> +S: Maintained >>>>> +F: >>>> Documentation/devicetree/bindings/crypto/aspeed,ast2500-hace.yaml >>>>> +F: drivers/crypto/aspeed/ >>>>> + >>>>> ASUS NOTEBOOKS AND EEEPC ACPI/WMI EXTRAS DRIVERS >>>>> M: Corentin Chary >>>>> L: acpi4asus-user@lists.sourceforge.net >>>>> diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index >>>>> ee99c02c84e8..b9f5ee126881 100644 >>>>> --- a/drivers/crypto/Kconfig >>>>> +++ b/drivers/crypto/Kconfig >>>>> @@ -933,5 +933,6 @@ config CRYPTO_DEV_SA2UL >>>>> acceleration for cryptographic algorithms on these devices. >>>>> >>>>> source "drivers/crypto/keembay/Kconfig" >>>>> +source "drivers/crypto/aspeed/Kconfig" >>>>> >>>>> endif # CRYPTO_HW >>>>> diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index >>>>> f81703a86b98..116de173a66c 100644 >>>>> --- a/drivers/crypto/Makefile >>>>> +++ b/drivers/crypto/Makefile >>>>> @@ -1,5 +1,6 @@ >>>>> # SPDX-License-Identifier: GPL-2.0 >>>>> obj-$(CONFIG_CRYPTO_DEV_ALLWINNER) += allwinner/ >>>>> +obj-$(CONFIG_CRYPTO_DEV_ASPEED) += aspeed/ >>>>> obj-$(CONFIG_CRYPTO_DEV_ATMEL_AES) += atmel-aes.o >>>>> obj-$(CONFIG_CRYPTO_DEV_ATMEL_SHA) += atmel-sha.o >>>>> obj-$(CONFIG_CRYPTO_DEV_ATMEL_TDES) += atmel-tdes.o diff --git >>>>> a/drivers/crypto/aspeed/Kconfig b/drivers/crypto/aspeed/Kconfig new >>>>> file mode 100644 index 000000000000..059e627efef8 >>>>> --- /dev/null >>>>> +++ b/drivers/crypto/aspeed/Kconfig >>>>> @@ -0,0 +1,32 @@ >>>>> +config CRYPTO_DEV_ASPEED >>>>> + tristate "Support for Aspeed cryptographic engine driver" >>>>> + depends on ARCH_ASPEED >>>>> + help >>>>> + Hash and Crypto Engine (HACE) is designed to accelerate the >>>>> + throughput of hash data digest, encryption and decryption. >>>>> + >>>>> + Select y here to have support for the cryptographic driver >>>>> + available on Aspeed SoC. >>>>> + >>>>> +config CRYPTO_DEV_ASPEED_HACE_HASH >>>>> + bool "Enable Aspeed Hash & Crypto Engine (HACE) hash" >>>>> + depends on CRYPTO_DEV_ASPEED >>>>> + select CRYPTO_ENGINE >>>>> + select CRYPTO_SHA1 >>>>> + select CRYPTO_SHA256 >>>>> + select CRYPTO_SHA512 >>>>> + select CRYPTO_HMAC >>>>> + help >>>>> + Select here to enable Aspeed Hash & Crypto Engine (HACE) >>>>> + hash driver. >>>>> + Supports multiple message digest standards, including >>>>> + SHA-1, SHA-224, SHA-256, SHA-384, SHA-512, and so on. >>>>> + >>>>> +config CRYPTO_DEV_ASPEED_HACE_HASH_DEBUG >>>>> + bool "Enable HACE hash debug messages" >>>>> + depends on CRYPTO_DEV_ASPEED_HACE_HASH >>>>> + help >>>>> + Print HACE hash debugging messages if you use this option >>>>> + to ask for those messages. >>>>> + Avoid enabling this option for production build to >>>>> + minimize driver timing. >>>>> diff --git a/drivers/crypto/aspeed/Makefile >>>> b/drivers/crypto/aspeed/Makefile >>>>> new file mode 100644 >>>>> index 000000000000..8bc8d4fed5a9 >>>>> --- /dev/null >>>>> +++ b/drivers/crypto/aspeed/Makefile >>>>> @@ -0,0 +1,6 @@ >>>>> +obj-$(CONFIG_CRYPTO_DEV_ASPEED) += aspeed_crypto.o >>>>> +aspeed_crypto-objs := aspeed-hace.o \ >>>>> + $(hace-hash-y) >>>>> + >>>>> +obj-$(CONFIG_CRYPTO_DEV_ASPEED_HACE_HASH) += >> aspeed-hace-hash.o >>>>> +hace-hash-$(CONFIG_CRYPTO_DEV_ASPEED_HACE_HASH) := >>>> aspeed-hace-hash.o >>>>> diff --git a/drivers/crypto/aspeed/aspeed-hace-hash.c >>>> b/drivers/crypto/aspeed/aspeed-hace-hash.c >>>>> new file mode 100644 >>>>> index 000000000000..63a8ad694996 >>>>> --- /dev/null >>>>> +++ b/drivers/crypto/aspeed/aspeed-hace-hash.c >>>>> @@ -0,0 +1,1389 @@ > > [...] > >>>>> +static int aspeed_ahash_dma_prepare_sg(struct aspeed_hace_dev >>>> *hace_dev) >>>>> +{ >>>>> + struct aspeed_engine_hash *hash_engine = >> &hace_dev->hash_engine; >>>>> + struct ahash_request *req = hash_engine->req; >>>>> + struct aspeed_sham_reqctx *rctx = ahash_request_ctx(req); >>>>> + struct aspeed_sg_list *src_list; >>>>> + struct scatterlist *s; >>>>> + int length, remain, sg_len, i; >>>>> + int rc = 0; >>>>> + >>>>> + remain = (rctx->total + rctx->bufcnt) % rctx->block_size; >>>>> + length = rctx->total + rctx->bufcnt - remain; >>>>> + >>>>> + AHASH_DBG(hace_dev, "%s:0x%x, %s:0x%x, %s:0x%x, %s:0x%x\n", >>>>> + "rctx total", rctx->total, "bufcnt", rctx->bufcnt, >>>>> + "length", length, "remain", remain); >>>>> + >>>>> + sg_len = dma_map_sg(hace_dev->dev, rctx->src_sg, rctx->src_nents, >>>>> + DMA_TO_DEVICE); >>>>> + if (!sg_len) { >>>>> + dev_warn(hace_dev->dev, "dma_map_sg() src error\n"); >>>>> + rc = -ENOMEM; >>>>> + goto end; >>>>> + } >>>>> + >>>>> + src_list = (struct aspeed_sg_list *)hash_engine->ahash_src_addr; >>>>> + rctx->digest_dma_addr = dma_map_single(hace_dev->dev, >> rctx->digest, >>>>> + SHA512_DIGEST_SIZE, >>>>> + DMA_BIDIRECTIONAL); >>>>> + if (dma_mapping_error(hace_dev->dev, rctx->digest_dma_addr)) { >>>>> + dev_warn(hace_dev->dev, "dma_map() rctx digest error\n"); >>>>> + rc = -ENOMEM; >>>>> + goto free_src_sg; >>>>> + } >>>>> + >>>>> + if (rctx->bufcnt != 0) { >>>>> + rctx->buffer_dma_addr = dma_map_single(hace_dev->dev, >>>>> + rctx->buffer, >>>>> + rctx->block_size * 2, >>>>> + DMA_TO_DEVICE); >>>>> + if (dma_mapping_error(hace_dev->dev, >> rctx->buffer_dma_addr)) { >>>>> + dev_warn(hace_dev->dev, "dma_map() rctx buffer >> error\n"); >>>>> + rc = -ENOMEM; >>>>> + goto free_rctx_digest; >>>>> + } >>>>> + >>>>> + src_list[0].phy_addr = rctx->buffer_dma_addr; >>>>> + src_list[0].len = rctx->bufcnt; >>>>> + length -= src_list[0].len; >>>>> + >>>>> + /* Last sg list */ >>>>> + if (length == 0) >>>>> + src_list[0].len |= HASH_SG_LAST_LIST; >>>>> + >>>>> + src_list[0].phy_addr = cpu_to_le32(src_list[0].phy_addr); >>>>> + src_list[0].len = cpu_to_le32(src_list[0].len); >>>>> + src_list++; >>>>> + } >>>>> + >>>>> + if (length != 0) { >>>>> + for_each_sg(rctx->src_sg, s, sg_len, i) { >>>>> + src_list[i].phy_addr = sg_dma_address(s); >>>>> + >>>>> + if (length > sg_dma_len(s)) { >>>>> + src_list[i].len = sg_dma_len(s); >>>>> + length -= sg_dma_len(s); >>>>> + >>>>> + } else { >>>>> + /* Last sg list */ >>>>> + src_list[i].len = length; >>>>> + src_list[i].len |= HASH_SG_LAST_LIST; >>>>> + length = 0; >>>>> + } >>>>> + >>>>> + src_list[i].phy_addr = cpu_to_le32(src_list[i].phy_addr); >>>>> + src_list[i].len = cpu_to_le32(src_list[i].len); >>>>> + } >>>>> + } >>>>> + >>>>> + if (length != 0) { >>>>> + rc = -EINVAL; >>>>> + goto free_rctx_buffer; >>>>> + } >>>>> + >>>>> + rctx->offset = rctx->total - remain; >>>>> + hash_engine->src_length = rctx->total + rctx->bufcnt - remain; >>>>> + hash_engine->src_dma = hash_engine->ahash_src_dma_addr; >>>>> + hash_engine->digest_dma = rctx->digest_dma_addr; >>>>> + >>>>> + goto end; >>>> Exiting via "goto xx" is not recommended in normal code logic (this >>>> requires two jumps), exiting via "return 0" is more efficient. >>>> This code method has many times in your entire driver, it is >>>> recommended to modify it. >>> >>> If not exiting via "goto xx", how to release related resources without any >> problem? >>> Is there any proper way to do this? >> maybe I didn't describe it clearly enough. >> "in normal code logic" means rc=0 >> In this scenario (rc=0), "goto xx" is no longer required, it can be replaced with >> "return 0" > > Okay, I got your point. In this case, "goto end" is no longer required of course. > I would send next patch with this fixed included. > >>> >>>>> + >>>>> +free_rctx_buffer: >>>>> + if (rctx->bufcnt != 0) >>>>> + dma_unmap_single(hace_dev->dev, rctx->buffer_dma_addr, >>>>> + rctx->block_size * 2, DMA_TO_DEVICE); >>>>> +free_rctx_digest: >>>>> + dma_unmap_single(hace_dev->dev, rctx->digest_dma_addr, >>>>> + SHA512_DIGEST_SIZE, DMA_BIDIRECTIONAL); >>>>> +free_src_sg: >>>>> + dma_unmap_sg(hace_dev->dev, rctx->src_sg, rctx->src_nents, >>>>> + DMA_TO_DEVICE); >>>>> +end: >>>>> + return rc; >>>>> +} >>>>> + >>>>> +static int aspeed_ahash_complete(struct aspeed_hace_dev *hace_dev) >>>>> +{ >>>>> + struct aspeed_engine_hash *hash_engine = >> &hace_dev->hash_engine; >>>>> + struct ahash_request *req = hash_engine->req; >>>>> + >>>>> + AHASH_DBG(hace_dev, "\n"); >>>>> + >>>>> + hash_engine->flags &= ~CRYPTO_FLAGS_BUSY; >>>>> + >>>>> + crypto_finalize_hash_request(hace_dev->crypt_engine_hash, req, 0); >>>>> + >>>>> + return 0; >>>>> +} >>>>> + >>>>> +/* >>>>> + * Copy digest to the corresponding request result. >>>>> + * This function will be called at final() stage. >>>>> + */ >>>>> +static int aspeed_ahash_transfer(struct aspeed_hace_dev *hace_dev) >>>>> +{ >>>>> + struct aspeed_engine_hash *hash_engine = >> &hace_dev->hash_engine; >>>>> + struct ahash_request *req = hash_engine->req; >>>>> + struct aspeed_sham_reqctx *rctx = ahash_request_ctx(req); >>>>> + >>>>> + AHASH_DBG(hace_dev, "\n"); >>>>> + >>>>> + dma_unmap_single(hace_dev->dev, rctx->digest_dma_addr, >>>>> + SHA512_DIGEST_SIZE, DMA_BIDIRECTIONAL); >>>>> + >>>>> + dma_unmap_single(hace_dev->dev, rctx->buffer_dma_addr, >>>>> + rctx->block_size * 2, DMA_TO_DEVICE); >>>>> + >>>>> + memcpy(req->result, rctx->digest, rctx->digsize); >>>>> + >>>>> + return aspeed_ahash_complete(hace_dev); } >>>>> + >>>>> +/* >>>>> + * Trigger hardware engines to do the math. >>>>> + */ >>>>> +static int aspeed_hace_ahash_trigger(struct aspeed_hace_dev >> *hace_dev, >>>>> + aspeed_hace_fn_t resume) >>>>> +{ >>>>> + struct aspeed_engine_hash *hash_engine = >> &hace_dev->hash_engine; >>>>> + struct ahash_request *req = hash_engine->req; >>>>> + struct aspeed_sham_reqctx *rctx = ahash_request_ctx(req); >>>>> + >>>>> + AHASH_DBG(hace_dev, "src_dma:0x%x, digest_dma:0x%x, >>>> length:0x%x\n", >>>>> + hash_engine->src_dma, hash_engine->digest_dma, >>>>> + hash_engine->src_length); >>>>> + >>>>> + rctx->cmd |= HASH_CMD_INT_ENABLE; >>>>> + hash_engine->resume = resume; >>>>> + >>>>> + ast_hace_write(hace_dev, hash_engine->src_dma, >>>> ASPEED_HACE_HASH_SRC); >>>>> + ast_hace_write(hace_dev, hash_engine->digest_dma, >>>>> + ASPEED_HACE_HASH_DIGEST_BUFF); >>>>> + ast_hace_write(hace_dev, hash_engine->digest_dma, >>>>> + ASPEED_HACE_HASH_KEY_BUFF); >>>>> + ast_hace_write(hace_dev, hash_engine->src_length, >>>>> + ASPEED_HACE_HASH_DATA_LEN); >>>>> + >>>>> + /* Memory barrier to ensure all data setup before engine starts */ >>>>> + mb(); >>>>> + >>>>> + ast_hace_write(hace_dev, rctx->cmd, ASPEED_HACE_HASH_CMD); >>>> A hardware service sending requires 5 hardware commands to complete. >>>> In a multi-concurrency scenario, how to ensure the order of commands? >>>> (If two processes send hardware task at the same time, How to ensure >>>> that the hardware recognizes which task the current command belongs >>>> to?) >>> >>> Linux crypto engine would guarantee that only one request at each time to >> be dequeued from engine queue to process. >>> And there has lock mechanism inside Linux crypto engine to prevent the >> scenario you mentioned. >>> So only 1 aspeed_hace_ahash_trigger() hardware service would go through >> at a time. >>> >>> [...] >>> . >>> >> You may not understand what I mean, the command flow in a normal scenario: >> request_A: Acmd1-->Acmd2-->Acmd3-->Acmd4-->Acmd5 >> request_B: Bcmd1-->Bcmd2-->Bcmd3-->Bcmd4-->Bcmd5 >> In a multi-process concurrent scenario, multiple crypto engines can be enabled, >> and each crypto engine sends a request. If multiple requests here enter >> aspeed_hace_ahash_trigger() at the same time, the command flow will be >> intertwined like this: >> request_A, request_B: >> Acmd1-->Bcmd1-->Acmd2-->Acmd3-->Bcmd2-->Acmd4-->Bcmd3-->Bcmd4-->A >> cmd5-->Bcmd5 >> >> In this command flow, how does your hardware identify whether these >> commands belong to request_A or request_B? >> Thanks. >> Longfang. > > For my understanding, all requests will transfer into engine queue through crypto_transfer_hash_request_to_engine(). > In your example, request_A & request_B would also enqueue into the engine queue, and pump out 1 request which might be FIFO to handle it. > crypto_pump_requests() will dequeue only 1 request at a time and to prepare_request() & do_one_request() if it's registered. > And aspeed_hace_ahash_trigger() is inside do_one_request(), so that means no other requests would come in during aspeed_hace_ahash_trigger() whole process. > The command flow intertwined > Acmd1-->Bcmd1-->Acmd2-->Acmd3-->Bcmd2-->Acmd4-->Bcmd3-->Bcmd4-->Acmd5-->Bcmd5 would not exist in any scenario. > Correct me if I'm misunderstanding, Thanks. > > . > At first£¬You need to understand the difference between threads and processes that I said. In a multi-threaded scenario, all threads will share the engine of a process, there will only be one engine queue to send cmds at the same time. However, in a multi-process scenario, each process will have its own engine queue, and when running at the same time, there will be multiple queues sending cmds. Then, I understand what you mean. Your driver uses the software queue of the encryption engine to ensure the cmds order. This method can ensure that the cmds of multiple threads in one process are sent in order. But you still need to consider the problem of multiple processes, when using your device for hash operations in multiple user processes, there will be multiple crypto engine software queues sending commands at the same time. Thanks Longfang. 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 703C3C19F2D for ; Tue, 9 Aug 2022 12:42:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:Date: Message-ID:From:References:CC:To:Subject:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=GVxCOoHiUr4P2+serqPnfipCIsJs/EfzXGsaVZXbSmU=; b=Xug/mzQm/X0EAiGmSZaFoxe+e3 9OT8keQS64koXMGPihyVkcqD8tAqC0FiWWZKoaEkukgEv4lphFT1nOe+4kpHOu5sXifK51D3+NcL/ sYs62XwmPwA4bsxtkVid8pmA9CRDARimVE9x8wfVNxyI0lHBp/l057UfqOj/6RFR7hE+jxKUmyI75 WhIGuojysUCBSUa+2iOZnBo7b87kCTX3wB11dmZyU0tvPPbCd1Kw98dZDmZ3JGoruysjlvLdCoZo0 wkSle0udzVNIeWCRah7FG+0/sw89wlQO8hLB2CH5GCSmpgc/M3h2K5wqYTkE5ihOzfiHY+qS/7kv+ 0BiBcGTg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1oLOX1-003tFt-SI; Tue, 09 Aug 2022 12:40:23 +0000 Received: from szxga02-in.huawei.com ([45.249.212.188]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1oLOWv-003t8z-M9 for linux-arm-kernel@lists.infradead.org; Tue, 09 Aug 2022 12:40:21 +0000 Received: from dggemv703-chm.china.huawei.com (unknown [172.30.72.56]) by szxga02-in.huawei.com (SkyGuard) with ESMTP id 4M2CJ03w5ZzlVqJ; Tue, 9 Aug 2022 20:37:04 +0800 (CST) Received: from kwepemm600005.china.huawei.com (7.193.23.191) by dggemv703-chm.china.huawei.com (10.3.19.46) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.24; Tue, 9 Aug 2022 20:39:56 +0800 Received: from [10.67.102.118] (10.67.102.118) by kwepemm600005.china.huawei.com (7.193.23.191) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.24; Tue, 9 Aug 2022 20:39:55 +0800 Subject: Re: [PATCH v8 1/5] crypto: aspeed: Add HACE hash driver To: Neal Liu , Corentin Labbe , Christophe JAILLET , Randy Dunlap , Herbert Xu , "David S . Miller" , Rob Herring , Krzysztof Kozlowski , Joel Stanley , "Andrew Jeffery" , Dhananjay Phadke , "Johnny Huang" CC: "linux-aspeed@lists.ozlabs.org" , "linux-crypto@vger.kernel.org" , "devicetree@vger.kernel.org" , "linux-arm-kernel@lists.infradead.org" , "linux-kernel@vger.kernel.org" , BMC-SW References: <20220726113448.2964968-1-neal_liu@aspeedtech.com> <20220726113448.2964968-2-neal_liu@aspeedtech.com> <5ca081b1-9a96-5b58-7a27-75c94af119d2@huawei.com> <256d64d6-0a27-7714-60ac-580b371c2502@huawei.com> From: liulongfang Message-ID: <100bb780-39e9-bb8e-f568-e8d8d9112abf@huawei.com> Date: Tue, 9 Aug 2022 20:39:55 +0800 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:60.0) Gecko/20100101 Thunderbird/60.8.0 MIME-Version: 1.0 In-Reply-To: X-Originating-IP: [10.67.102.118] X-ClientProxiedBy: dggems701-chm.china.huawei.com (10.3.19.178) To kwepemm600005.china.huawei.com (7.193.23.191) X-CFilter-Loop: Reflected X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220809_054018_637993_7B99971D X-CRM114-Status: GOOD ( 26.72 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="gbk" Content-Transfer-Encoding: base64 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org T24gMjAyMi84LzkgMTU6MzksIE5lYWwgTGl1IHdyb3RlOgo+Pj4+IE9uIDIwMjIvNy8yNiAxOToz NCwgTmVhbCBMaXUgd3JvdGU6Cj4+Pj4+IEhhc2ggYW5kIENyeXB0byBFbmdpbmUgKEhBQ0UpIGlz IGRlc2lnbmVkIHRvIGFjY2VsZXJhdGUgdGhlCj4+Pj4+IHRocm91Z2hwdXQgb2YgaGFzaCBkYXRh IGRpZ2VzdCwgZW5jcnlwdGlvbiwgYW5kIGRlY3J5cHRpb24uCj4+Pj4+Cj4+Pj4+IEJhc2ljYWxs eSwgSEFDRSBjYW4gYmUgZGl2aWRlZCBpbnRvIHR3byBpbmRlcGVuZGVudGx5IGVuZ2luZXMKPj4+ Pj4gLSBIYXNoIEVuZ2luZSBhbmQgQ3J5cHRvIEVuZ2luZS4gVGhpcyBwYXRjaCBhaW1zIHRvIGFk ZCBIQUNFIGhhc2gKPj4+Pj4gZW5naW5lIGRyaXZlciBmb3IgaGFzaCBhY2NlbGVyYXRvci4KPj4+ Pj4KPj4+Pj4gU2lnbmVkLW9mZi1ieTogTmVhbCBMaXUgPG5lYWxfbGl1QGFzcGVlZHRlY2guY29t Pgo+Pj4+PiBTaWduZWQtb2ZmLWJ5OiBKb2hubnkgSHVhbmcgPGpvaG5ueV9odWFuZ0Bhc3BlZWR0 ZWNoLmNvbT4KPj4+Pj4gLS0tCj4+Pj4+ICBNQUlOVEFJTkVSUyAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgIHwgICAgNyArCj4+Pj4+ICBkcml2ZXJzL2NyeXB0by9LY29uZmlnICAgICAgICAg ICAgICAgICAgIHwgICAgMSArCj4+Pj4+ICBkcml2ZXJzL2NyeXB0by9NYWtlZmlsZSAgICAgICAg ICAgICAgICAgIHwgICAgMSArCj4+Pj4+ICBkcml2ZXJzL2NyeXB0by9hc3BlZWQvS2NvbmZpZyAg ICAgICAgICAgIHwgICAzMiArCj4+Pj4+ICBkcml2ZXJzL2NyeXB0by9hc3BlZWQvTWFrZWZpbGUg ICAgICAgICAgIHwgICAgNiArCj4+Pj4+ICBkcml2ZXJzL2NyeXB0by9hc3BlZWQvYXNwZWVkLWhh Y2UtaGFzaC5jIHwgMTM4OQo+Pj4+ICsrKysrKysrKysrKysrKysrKysrKysKPj4+Pj4gIGRyaXZl cnMvY3J5cHRvL2FzcGVlZC9hc3BlZWQtaGFjZS5jICAgICAgfCAgMjEzICsrKysKPj4+Pj4gIGRy aXZlcnMvY3J5cHRvL2FzcGVlZC9hc3BlZWQtaGFjZS5oICAgICAgfCAgMTg2ICsrKwo+Pj4+PiAg OCBmaWxlcyBjaGFuZ2VkLCAxODM1IGluc2VydGlvbnMoKykgIGNyZWF0ZSBtb2RlIDEwMDY0NAo+ Pj4+PiBkcml2ZXJzL2NyeXB0by9hc3BlZWQvS2NvbmZpZyAgY3JlYXRlIG1vZGUgMTAwNjQ0Cj4+ Pj4+IGRyaXZlcnMvY3J5cHRvL2FzcGVlZC9NYWtlZmlsZSAgY3JlYXRlIG1vZGUgMTAwNjQ0Cj4+ Pj4+IGRyaXZlcnMvY3J5cHRvL2FzcGVlZC9hc3BlZWQtaGFjZS1oYXNoLmMKPj4+Pj4gIGNyZWF0 ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL2NyeXB0by9hc3BlZWQvYXNwZWVkLWhhY2UuYwo+Pj4+PiAg Y3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvY3J5cHRvL2FzcGVlZC9hc3BlZWQtaGFjZS5oCj4+ Pj4+Cj4+Pj4+IGRpZmYgLS1naXQgYS9NQUlOVEFJTkVSUyBiL01BSU5UQUlORVJTIGluZGV4Cj4+ Pj4+IGY1NWFlYTMxMWFmNS4uMjNhMDIxNWI3ZTQyIDEwMDY0NAo+Pj4+PiAtLS0gYS9NQUlOVEFJ TkVSUwo+Pj4+PiArKysgYi9NQUlOVEFJTkVSUwo+Pj4+PiBAQCAtMzE0MCw2ICszMTQwLDEzIEBA IFM6CU1haW50YWluZWQKPj4+Pj4gIEY6CURvY3VtZW50YXRpb24vZGV2aWNldHJlZS9iaW5kaW5n cy9tZWRpYS9hc3BlZWQtdmlkZW8udHh0Cj4+Pj4+ICBGOglkcml2ZXJzL21lZGlhL3BsYXRmb3Jt L2FzcGVlZC8KPj4+Pj4KPj4+Pj4gK0FTUEVFRCBDUllQVE8gRFJJVkVSCj4+Pj4+ICtNOglOZWFs IExpdSA8bmVhbF9saXVAYXNwZWVkdGVjaC5jb20+Cj4+Pj4+ICtMOglsaW51eC1hc3BlZWRAbGlz dHMub3psYWJzLm9yZyAobW9kZXJhdGVkIGZvciBub24tc3Vic2NyaWJlcnMpCj4+Pj4+ICtTOglN YWludGFpbmVkCj4+Pj4+ICtGOgo+Pj4+IAlEb2N1bWVudGF0aW9uL2RldmljZXRyZWUvYmluZGlu Z3MvY3J5cHRvL2FzcGVlZCxhc3QyNTAwLWhhY2UueWFtbAo+Pj4+PiArRjoJZHJpdmVycy9jcnlw dG8vYXNwZWVkLwo+Pj4+PiArCj4+Pj4+ICBBU1VTIE5PVEVCT09LUyBBTkQgRUVFUEMgQUNQSS9X TUkgRVhUUkFTIERSSVZFUlMKPj4+Pj4gIE06CUNvcmVudGluIENoYXJ5IDxjb3JlbnRpbi5jaGFy eUBnbWFpbC5jb20+Cj4+Pj4+ICBMOglhY3BpNGFzdXMtdXNlckBsaXN0cy5zb3VyY2Vmb3JnZS5u ZXQKPj4+Pj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvY3J5cHRvL0tjb25maWcgYi9kcml2ZXJzL2Ny eXB0by9LY29uZmlnIGluZGV4Cj4+Pj4+IGVlOTljMDJjODRlOC4uYjlmNWVlMTI2ODgxIDEwMDY0 NAo+Pj4+PiAtLS0gYS9kcml2ZXJzL2NyeXB0by9LY29uZmlnCj4+Pj4+ICsrKyBiL2RyaXZlcnMv Y3J5cHRvL0tjb25maWcKPj4+Pj4gQEAgLTkzMyw1ICs5MzMsNiBAQCBjb25maWcgQ1JZUFRPX0RF Vl9TQTJVTAo+Pj4+PiAgCSAgYWNjZWxlcmF0aW9uIGZvciBjcnlwdG9ncmFwaGljIGFsZ29yaXRo bXMgb24gdGhlc2UgZGV2aWNlcy4KPj4+Pj4KPj4+Pj4gIHNvdXJjZSAiZHJpdmVycy9jcnlwdG8v a2VlbWJheS9LY29uZmlnIgo+Pj4+PiArc291cmNlICJkcml2ZXJzL2NyeXB0by9hc3BlZWQvS2Nv bmZpZyIKPj4+Pj4KPj4+Pj4gIGVuZGlmICMgQ1JZUFRPX0hXCj4+Pj4+IGRpZmYgLS1naXQgYS9k cml2ZXJzL2NyeXB0by9NYWtlZmlsZSBiL2RyaXZlcnMvY3J5cHRvL01ha2VmaWxlIGluZGV4Cj4+ Pj4+IGY4MTcwM2E4NmI5OC4uMTE2ZGUxNzNhNjZjIDEwMDY0NAo+Pj4+PiAtLS0gYS9kcml2ZXJz L2NyeXB0by9NYWtlZmlsZQo+Pj4+PiArKysgYi9kcml2ZXJzL2NyeXB0by9NYWtlZmlsZQo+Pj4+ PiBAQCAtMSw1ICsxLDYgQEAKPj4+Pj4gICMgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0y LjAKPj4+Pj4gIG9iai0kKENPTkZJR19DUllQVE9fREVWX0FMTFdJTk5FUikgKz0gYWxsd2lubmVy Lwo+Pj4+PiArb2JqLSQoQ09ORklHX0NSWVBUT19ERVZfQVNQRUVEKSArPSBhc3BlZWQvCj4+Pj4+ ICBvYmotJChDT05GSUdfQ1JZUFRPX0RFVl9BVE1FTF9BRVMpICs9IGF0bWVsLWFlcy5vCj4+Pj4+ ICBvYmotJChDT05GSUdfQ1JZUFRPX0RFVl9BVE1FTF9TSEEpICs9IGF0bWVsLXNoYS5vCj4+Pj4+ ICBvYmotJChDT05GSUdfQ1JZUFRPX0RFVl9BVE1FTF9UREVTKSArPSBhdG1lbC10ZGVzLm8gZGlm ZiAtLWdpdAo+Pj4+PiBhL2RyaXZlcnMvY3J5cHRvL2FzcGVlZC9LY29uZmlnIGIvZHJpdmVycy9j cnlwdG8vYXNwZWVkL0tjb25maWcgbmV3Cj4+Pj4+IGZpbGUgbW9kZSAxMDA2NDQgaW5kZXggMDAw MDAwMDAwMDAwLi4wNTllNjI3ZWZlZjgKPj4+Pj4gLS0tIC9kZXYvbnVsbAo+Pj4+PiArKysgYi9k cml2ZXJzL2NyeXB0by9hc3BlZWQvS2NvbmZpZwo+Pj4+PiBAQCAtMCwwICsxLDMyIEBACj4+Pj4+ ICtjb25maWcgQ1JZUFRPX0RFVl9BU1BFRUQKPj4+Pj4gKwl0cmlzdGF0ZSAiU3VwcG9ydCBmb3Ig QXNwZWVkIGNyeXB0b2dyYXBoaWMgZW5naW5lIGRyaXZlciIKPj4+Pj4gKwlkZXBlbmRzIG9uIEFS Q0hfQVNQRUVECj4+Pj4+ICsJaGVscAo+Pj4+PiArCSAgSGFzaCBhbmQgQ3J5cHRvIEVuZ2luZSAo SEFDRSkgaXMgZGVzaWduZWQgdG8gYWNjZWxlcmF0ZSB0aGUKPj4+Pj4gKwkgIHRocm91Z2hwdXQg b2YgaGFzaCBkYXRhIGRpZ2VzdCwgZW5jcnlwdGlvbiBhbmQgZGVjcnlwdGlvbi4KPj4+Pj4gKwo+ Pj4+PiArCSAgU2VsZWN0IHkgaGVyZSB0byBoYXZlIHN1cHBvcnQgZm9yIHRoZSBjcnlwdG9ncmFw aGljIGRyaXZlcgo+Pj4+PiArCSAgYXZhaWxhYmxlIG9uIEFzcGVlZCBTb0MuCj4+Pj4+ICsKPj4+ Pj4gK2NvbmZpZyBDUllQVE9fREVWX0FTUEVFRF9IQUNFX0hBU0gKPj4+Pj4gKwlib29sICJFbmFi bGUgQXNwZWVkIEhhc2ggJiBDcnlwdG8gRW5naW5lIChIQUNFKSBoYXNoIgo+Pj4+PiArCWRlcGVu ZHMgb24gQ1JZUFRPX0RFVl9BU1BFRUQKPj4+Pj4gKwlzZWxlY3QgQ1JZUFRPX0VOR0lORQo+Pj4+ PiArCXNlbGVjdCBDUllQVE9fU0hBMQo+Pj4+PiArCXNlbGVjdCBDUllQVE9fU0hBMjU2Cj4+Pj4+ ICsJc2VsZWN0IENSWVBUT19TSEE1MTIKPj4+Pj4gKwlzZWxlY3QgQ1JZUFRPX0hNQUMKPj4+Pj4g KwloZWxwCj4+Pj4+ICsJICBTZWxlY3QgaGVyZSB0byBlbmFibGUgQXNwZWVkIEhhc2ggJiBDcnlw dG8gRW5naW5lIChIQUNFKQo+Pj4+PiArCSAgaGFzaCBkcml2ZXIuCj4+Pj4+ICsJICBTdXBwb3J0 cyBtdWx0aXBsZSBtZXNzYWdlIGRpZ2VzdCBzdGFuZGFyZHMsIGluY2x1ZGluZwo+Pj4+PiArCSAg U0hBLTEsIFNIQS0yMjQsIFNIQS0yNTYsIFNIQS0zODQsIFNIQS01MTIsIGFuZCBzbyBvbi4KPj4+ Pj4gKwo+Pj4+PiArY29uZmlnIENSWVBUT19ERVZfQVNQRUVEX0hBQ0VfSEFTSF9ERUJVRwo+Pj4+ PiArCWJvb2wgIkVuYWJsZSBIQUNFIGhhc2ggZGVidWcgbWVzc2FnZXMiCj4+Pj4+ICsJZGVwZW5k cyBvbiBDUllQVE9fREVWX0FTUEVFRF9IQUNFX0hBU0gKPj4+Pj4gKwloZWxwCj4+Pj4+ICsJICBQ cmludCBIQUNFIGhhc2ggZGVidWdnaW5nIG1lc3NhZ2VzIGlmIHlvdSB1c2UgdGhpcyBvcHRpb24K Pj4+Pj4gKwkgIHRvIGFzayBmb3IgdGhvc2UgbWVzc2FnZXMuCj4+Pj4+ICsJICBBdm9pZCBlbmFi bGluZyB0aGlzIG9wdGlvbiBmb3IgcHJvZHVjdGlvbiBidWlsZCB0bwo+Pj4+PiArCSAgbWluaW1p emUgZHJpdmVyIHRpbWluZy4KPj4+Pj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvY3J5cHRvL2FzcGVl ZC9NYWtlZmlsZQo+Pj4+IGIvZHJpdmVycy9jcnlwdG8vYXNwZWVkL01ha2VmaWxlCj4+Pj4+IG5l dyBmaWxlIG1vZGUgMTAwNjQ0Cj4+Pj4+IGluZGV4IDAwMDAwMDAwMDAwMC4uOGJjOGQ0ZmVkNWE5 Cj4+Pj4+IC0tLSAvZGV2L251bGwKPj4+Pj4gKysrIGIvZHJpdmVycy9jcnlwdG8vYXNwZWVkL01h a2VmaWxlCj4+Pj4+IEBAIC0wLDAgKzEsNiBAQAo+Pj4+PiArb2JqLSQoQ09ORklHX0NSWVBUT19E RVZfQVNQRUVEKSArPSBhc3BlZWRfY3J5cHRvLm8KPj4+Pj4gK2FzcGVlZF9jcnlwdG8tb2JqcyA6 PSBhc3BlZWQtaGFjZS5vIFwKPj4+Pj4gKwkJICAgICAgJChoYWNlLWhhc2gteSkKPj4+Pj4gKwo+ Pj4+PiArb2JqLSQoQ09ORklHX0NSWVBUT19ERVZfQVNQRUVEX0hBQ0VfSEFTSCkgKz0KPj4gYXNw ZWVkLWhhY2UtaGFzaC5vCj4+Pj4+ICtoYWNlLWhhc2gtJChDT05GSUdfQ1JZUFRPX0RFVl9BU1BF RURfSEFDRV9IQVNIKSA6PQo+Pj4+IGFzcGVlZC1oYWNlLWhhc2gubwo+Pj4+PiBkaWZmIC0tZ2l0 IGEvZHJpdmVycy9jcnlwdG8vYXNwZWVkL2FzcGVlZC1oYWNlLWhhc2guYwo+Pj4+IGIvZHJpdmVy cy9jcnlwdG8vYXNwZWVkL2FzcGVlZC1oYWNlLWhhc2guYwo+Pj4+PiBuZXcgZmlsZSBtb2RlIDEw MDY0NAo+Pj4+PiBpbmRleCAwMDAwMDAwMDAwMDAuLjYzYThhZDY5NDk5Ngo+Pj4+PiAtLS0gL2Rl di9udWxsCj4+Pj4+ICsrKyBiL2RyaXZlcnMvY3J5cHRvL2FzcGVlZC9hc3BlZWQtaGFjZS1oYXNo LmMKPj4+Pj4gQEAgLTAsMCArMSwxMzg5IEBACj4gCj4gWy4uLl0KPiAKPj4+Pj4gK3N0YXRpYyBp bnQgYXNwZWVkX2FoYXNoX2RtYV9wcmVwYXJlX3NnKHN0cnVjdCBhc3BlZWRfaGFjZV9kZXYKPj4+ PiAqaGFjZV9kZXYpCj4+Pj4+ICt7Cj4+Pj4+ICsJc3RydWN0IGFzcGVlZF9lbmdpbmVfaGFzaCAq aGFzaF9lbmdpbmUgPQo+PiAmaGFjZV9kZXYtPmhhc2hfZW5naW5lOwo+Pj4+PiArCXN0cnVjdCBh aGFzaF9yZXF1ZXN0ICpyZXEgPSBoYXNoX2VuZ2luZS0+cmVxOwo+Pj4+PiArCXN0cnVjdCBhc3Bl ZWRfc2hhbV9yZXFjdHggKnJjdHggPSBhaGFzaF9yZXF1ZXN0X2N0eChyZXEpOwo+Pj4+PiArCXN0 cnVjdCBhc3BlZWRfc2dfbGlzdCAqc3JjX2xpc3Q7Cj4+Pj4+ICsJc3RydWN0IHNjYXR0ZXJsaXN0 ICpzOwo+Pj4+PiArCWludCBsZW5ndGgsIHJlbWFpbiwgc2dfbGVuLCBpOwo+Pj4+PiArCWludCBy YyA9IDA7Cj4+Pj4+ICsKPj4+Pj4gKwlyZW1haW4gPSAocmN0eC0+dG90YWwgKyByY3R4LT5idWZj bnQpICUgcmN0eC0+YmxvY2tfc2l6ZTsKPj4+Pj4gKwlsZW5ndGggPSByY3R4LT50b3RhbCArIHJj dHgtPmJ1ZmNudCAtIHJlbWFpbjsKPj4+Pj4gKwo+Pj4+PiArCUFIQVNIX0RCRyhoYWNlX2Rldiwg IiVzOjB4JXgsICVzOjB4JXgsICVzOjB4JXgsICVzOjB4JXhcbiIsCj4+Pj4+ICsJCSAgInJjdHgg dG90YWwiLCByY3R4LT50b3RhbCwgImJ1ZmNudCIsIHJjdHgtPmJ1ZmNudCwKPj4+Pj4gKwkJICAi bGVuZ3RoIiwgbGVuZ3RoLCAicmVtYWluIiwgcmVtYWluKTsKPj4+Pj4gKwo+Pj4+PiArCXNnX2xl biA9IGRtYV9tYXBfc2coaGFjZV9kZXYtPmRldiwgcmN0eC0+c3JjX3NnLCByY3R4LT5zcmNfbmVu dHMsCj4+Pj4+ICsJCQkgICAgRE1BX1RPX0RFVklDRSk7Cj4+Pj4+ICsJaWYgKCFzZ19sZW4pIHsK Pj4+Pj4gKwkJZGV2X3dhcm4oaGFjZV9kZXYtPmRldiwgImRtYV9tYXBfc2coKSBzcmMgZXJyb3Jc biIpOwo+Pj4+PiArCQlyYyA9IC1FTk9NRU07Cj4+Pj4+ICsJCWdvdG8gZW5kOwo+Pj4+PiArCX0K Pj4+Pj4gKwo+Pj4+PiArCXNyY19saXN0ID0gKHN0cnVjdCBhc3BlZWRfc2dfbGlzdCAqKWhhc2hf ZW5naW5lLT5haGFzaF9zcmNfYWRkcjsKPj4+Pj4gKwlyY3R4LT5kaWdlc3RfZG1hX2FkZHIgPSBk bWFfbWFwX3NpbmdsZShoYWNlX2Rldi0+ZGV2LAo+PiByY3R4LT5kaWdlc3QsCj4+Pj4+ICsJCQkJ CSAgICAgICBTSEE1MTJfRElHRVNUX1NJWkUsCj4+Pj4+ICsJCQkJCSAgICAgICBETUFfQklESVJF Q1RJT05BTCk7Cj4+Pj4+ICsJaWYgKGRtYV9tYXBwaW5nX2Vycm9yKGhhY2VfZGV2LT5kZXYsIHJj dHgtPmRpZ2VzdF9kbWFfYWRkcikpIHsKPj4+Pj4gKwkJZGV2X3dhcm4oaGFjZV9kZXYtPmRldiwg ImRtYV9tYXAoKSByY3R4IGRpZ2VzdCBlcnJvclxuIik7Cj4+Pj4+ICsJCXJjID0gLUVOT01FTTsK Pj4+Pj4gKwkJZ290byBmcmVlX3NyY19zZzsKPj4+Pj4gKwl9Cj4+Pj4+ICsKPj4+Pj4gKwlpZiAo cmN0eC0+YnVmY250ICE9IDApIHsKPj4+Pj4gKwkJcmN0eC0+YnVmZmVyX2RtYV9hZGRyID0gZG1h X21hcF9zaW5nbGUoaGFjZV9kZXYtPmRldiwKPj4+Pj4gKwkJCQkJCSAgICAgICByY3R4LT5idWZm ZXIsCj4+Pj4+ICsJCQkJCQkgICAgICAgcmN0eC0+YmxvY2tfc2l6ZSAqIDIsCj4+Pj4+ICsJCQkJ CQkgICAgICAgRE1BX1RPX0RFVklDRSk7Cj4+Pj4+ICsJCWlmIChkbWFfbWFwcGluZ19lcnJvciho YWNlX2Rldi0+ZGV2LAo+PiByY3R4LT5idWZmZXJfZG1hX2FkZHIpKSB7Cj4+Pj4+ICsJCQlkZXZf d2FybihoYWNlX2Rldi0+ZGV2LCAiZG1hX21hcCgpIHJjdHggYnVmZmVyCj4+IGVycm9yXG4iKTsK Pj4+Pj4gKwkJCXJjID0gLUVOT01FTTsKPj4+Pj4gKwkJCWdvdG8gZnJlZV9yY3R4X2RpZ2VzdDsK Pj4+Pj4gKwkJfQo+Pj4+PiArCj4+Pj4+ICsJCXNyY19saXN0WzBdLnBoeV9hZGRyID0gcmN0eC0+ YnVmZmVyX2RtYV9hZGRyOwo+Pj4+PiArCQlzcmNfbGlzdFswXS5sZW4gPSByY3R4LT5idWZjbnQ7 Cj4+Pj4+ICsJCWxlbmd0aCAtPSBzcmNfbGlzdFswXS5sZW47Cj4+Pj4+ICsKPj4+Pj4gKwkJLyog TGFzdCBzZyBsaXN0ICovCj4+Pj4+ICsJCWlmIChsZW5ndGggPT0gMCkKPj4+Pj4gKwkJCXNyY19s aXN0WzBdLmxlbiB8PSBIQVNIX1NHX0xBU1RfTElTVDsKPj4+Pj4gKwo+Pj4+PiArCQlzcmNfbGlz dFswXS5waHlfYWRkciA9IGNwdV90b19sZTMyKHNyY19saXN0WzBdLnBoeV9hZGRyKTsKPj4+Pj4g KwkJc3JjX2xpc3RbMF0ubGVuID0gY3B1X3RvX2xlMzIoc3JjX2xpc3RbMF0ubGVuKTsKPj4+Pj4g KwkJc3JjX2xpc3QrKzsKPj4+Pj4gKwl9Cj4+Pj4+ICsKPj4+Pj4gKwlpZiAobGVuZ3RoICE9IDAp IHsKPj4+Pj4gKwkJZm9yX2VhY2hfc2cocmN0eC0+c3JjX3NnLCBzLCBzZ19sZW4sIGkpIHsKPj4+ Pj4gKwkJCXNyY19saXN0W2ldLnBoeV9hZGRyID0gc2dfZG1hX2FkZHJlc3Mocyk7Cj4+Pj4+ICsK Pj4+Pj4gKwkJCWlmIChsZW5ndGggPiBzZ19kbWFfbGVuKHMpKSB7Cj4+Pj4+ICsJCQkJc3JjX2xp c3RbaV0ubGVuID0gc2dfZG1hX2xlbihzKTsKPj4+Pj4gKwkJCQlsZW5ndGggLT0gc2dfZG1hX2xl bihzKTsKPj4+Pj4gKwo+Pj4+PiArCQkJfSBlbHNlIHsKPj4+Pj4gKwkJCQkvKiBMYXN0IHNnIGxp c3QgKi8KPj4+Pj4gKwkJCQlzcmNfbGlzdFtpXS5sZW4gPSBsZW5ndGg7Cj4+Pj4+ICsJCQkJc3Jj X2xpc3RbaV0ubGVuIHw9IEhBU0hfU0dfTEFTVF9MSVNUOwo+Pj4+PiArCQkJCWxlbmd0aCA9IDA7 Cj4+Pj4+ICsJCQl9Cj4+Pj4+ICsKPj4+Pj4gKwkJCXNyY19saXN0W2ldLnBoeV9hZGRyID0gY3B1 X3RvX2xlMzIoc3JjX2xpc3RbaV0ucGh5X2FkZHIpOwo+Pj4+PiArCQkJc3JjX2xpc3RbaV0ubGVu ID0gY3B1X3RvX2xlMzIoc3JjX2xpc3RbaV0ubGVuKTsKPj4+Pj4gKwkJfQo+Pj4+PiArCX0KPj4+ Pj4gKwo+Pj4+PiArCWlmIChsZW5ndGggIT0gMCkgewo+Pj4+PiArCQlyYyA9IC1FSU5WQUw7Cj4+ Pj4+ICsJCWdvdG8gZnJlZV9yY3R4X2J1ZmZlcjsKPj4+Pj4gKwl9Cj4+Pj4+ICsKPj4+Pj4gKwly Y3R4LT5vZmZzZXQgPSByY3R4LT50b3RhbCAtIHJlbWFpbjsKPj4+Pj4gKwloYXNoX2VuZ2luZS0+ c3JjX2xlbmd0aCA9IHJjdHgtPnRvdGFsICsgcmN0eC0+YnVmY250IC0gcmVtYWluOwo+Pj4+PiAr CWhhc2hfZW5naW5lLT5zcmNfZG1hID0gaGFzaF9lbmdpbmUtPmFoYXNoX3NyY19kbWFfYWRkcjsK Pj4+Pj4gKwloYXNoX2VuZ2luZS0+ZGlnZXN0X2RtYSA9IHJjdHgtPmRpZ2VzdF9kbWFfYWRkcjsK Pj4+Pj4gKwo+Pj4+PiArCWdvdG8gZW5kOwo+Pj4+IEV4aXRpbmcgdmlhICJnb3RvIHh4IiBpcyBu b3QgcmVjb21tZW5kZWQgaW4gbm9ybWFsIGNvZGUgbG9naWMgKHRoaXMKPj4+PiByZXF1aXJlcyB0 d28ganVtcHMpLCBleGl0aW5nIHZpYSAicmV0dXJuIDAiIGlzIG1vcmUgZWZmaWNpZW50Lgo+Pj4+ IFRoaXMgY29kZSBtZXRob2QgaGFzIG1hbnkgdGltZXMgaW4geW91ciBlbnRpcmUgZHJpdmVyLCBp dCBpcwo+Pj4+IHJlY29tbWVuZGVkIHRvIG1vZGlmeSBpdC4KPj4+Cj4+PiBJZiBub3QgZXhpdGlu ZyB2aWEgImdvdG8geHgiLCBob3cgdG8gcmVsZWFzZSByZWxhdGVkIHJlc291cmNlcyB3aXRob3V0 IGFueQo+PiBwcm9ibGVtPwo+Pj4gSXMgdGhlcmUgYW55IHByb3BlciB3YXkgdG8gZG8gdGhpcz8K Pj4gbWF5YmUgSSBkaWRuJ3QgZGVzY3JpYmUgaXQgY2xlYXJseSBlbm91Z2guCj4+ICJpbiBub3Jt YWwgY29kZSBsb2dpYyIgIG1lYW5zIHJjPTAKPj4gSW4gdGhpcyBzY2VuYXJpbyAocmM9MCksICJn b3RvIHh4IiBpcyBubyBsb25nZXIgcmVxdWlyZWQsIGl0IGNhbiBiZSByZXBsYWNlZCB3aXRoCj4+ ICJyZXR1cm4gMCIKPiAKPiBPa2F5LCBJIGdvdCB5b3VyIHBvaW50LiBJbiB0aGlzIGNhc2UsICJn b3RvIGVuZCIgaXMgbm8gbG9uZ2VyIHJlcXVpcmVkIG9mIGNvdXJzZS4KPiBJIHdvdWxkIHNlbmQg bmV4dCBwYXRjaCB3aXRoIHRoaXMgZml4ZWQgaW5jbHVkZWQuCj4gCj4+Pgo+Pj4+PiArCj4+Pj4+ ICtmcmVlX3JjdHhfYnVmZmVyOgo+Pj4+PiArCWlmIChyY3R4LT5idWZjbnQgIT0gMCkKPj4+Pj4g KwkJZG1hX3VubWFwX3NpbmdsZShoYWNlX2Rldi0+ZGV2LCByY3R4LT5idWZmZXJfZG1hX2FkZHIs Cj4+Pj4+ICsJCQkJIHJjdHgtPmJsb2NrX3NpemUgKiAyLCBETUFfVE9fREVWSUNFKTsKPj4+Pj4g K2ZyZWVfcmN0eF9kaWdlc3Q6Cj4+Pj4+ICsJZG1hX3VubWFwX3NpbmdsZShoYWNlX2Rldi0+ZGV2 LCByY3R4LT5kaWdlc3RfZG1hX2FkZHIsCj4+Pj4+ICsJCQkgU0hBNTEyX0RJR0VTVF9TSVpFLCBE TUFfQklESVJFQ1RJT05BTCk7Cj4+Pj4+ICtmcmVlX3NyY19zZzoKPj4+Pj4gKwlkbWFfdW5tYXBf c2coaGFjZV9kZXYtPmRldiwgcmN0eC0+c3JjX3NnLCByY3R4LT5zcmNfbmVudHMsCj4+Pj4+ICsJ CSAgICAgRE1BX1RPX0RFVklDRSk7Cj4+Pj4+ICtlbmQ6Cj4+Pj4+ICsJcmV0dXJuIHJjOwo+Pj4+ PiArfQo+Pj4+PiArCj4+Pj4+ICtzdGF0aWMgaW50IGFzcGVlZF9haGFzaF9jb21wbGV0ZShzdHJ1 Y3QgYXNwZWVkX2hhY2VfZGV2ICpoYWNlX2RldikKPj4+Pj4gK3sKPj4+Pj4gKwlzdHJ1Y3QgYXNw ZWVkX2VuZ2luZV9oYXNoICpoYXNoX2VuZ2luZSA9Cj4+ICZoYWNlX2Rldi0+aGFzaF9lbmdpbmU7 Cj4+Pj4+ICsJc3RydWN0IGFoYXNoX3JlcXVlc3QgKnJlcSA9IGhhc2hfZW5naW5lLT5yZXE7Cj4+ Pj4+ICsKPj4+Pj4gKwlBSEFTSF9EQkcoaGFjZV9kZXYsICJcbiIpOwo+Pj4+PiArCj4+Pj4+ICsJ aGFzaF9lbmdpbmUtPmZsYWdzICY9IH5DUllQVE9fRkxBR1NfQlVTWTsKPj4+Pj4gKwo+Pj4+PiAr CWNyeXB0b19maW5hbGl6ZV9oYXNoX3JlcXVlc3QoaGFjZV9kZXYtPmNyeXB0X2VuZ2luZV9oYXNo LCByZXEsIDApOwo+Pj4+PiArCj4+Pj4+ICsJcmV0dXJuIDA7Cj4+Pj4+ICt9Cj4+Pj4+ICsKPj4+ Pj4gKy8qCj4+Pj4+ICsgKiBDb3B5IGRpZ2VzdCB0byB0aGUgY29ycmVzcG9uZGluZyByZXF1ZXN0 IHJlc3VsdC4KPj4+Pj4gKyAqIFRoaXMgZnVuY3Rpb24gd2lsbCBiZSBjYWxsZWQgYXQgZmluYWwo KSBzdGFnZS4KPj4+Pj4gKyAqLwo+Pj4+PiArc3RhdGljIGludCBhc3BlZWRfYWhhc2hfdHJhbnNm ZXIoc3RydWN0IGFzcGVlZF9oYWNlX2RldiAqaGFjZV9kZXYpCj4+Pj4+ICt7Cj4+Pj4+ICsJc3Ry dWN0IGFzcGVlZF9lbmdpbmVfaGFzaCAqaGFzaF9lbmdpbmUgPQo+PiAmaGFjZV9kZXYtPmhhc2hf ZW5naW5lOwo+Pj4+PiArCXN0cnVjdCBhaGFzaF9yZXF1ZXN0ICpyZXEgPSBoYXNoX2VuZ2luZS0+ cmVxOwo+Pj4+PiArCXN0cnVjdCBhc3BlZWRfc2hhbV9yZXFjdHggKnJjdHggPSBhaGFzaF9yZXF1 ZXN0X2N0eChyZXEpOwo+Pj4+PiArCj4+Pj4+ICsJQUhBU0hfREJHKGhhY2VfZGV2LCAiXG4iKTsK Pj4+Pj4gKwo+Pj4+PiArCWRtYV91bm1hcF9zaW5nbGUoaGFjZV9kZXYtPmRldiwgcmN0eC0+ZGln ZXN0X2RtYV9hZGRyLAo+Pj4+PiArCQkJIFNIQTUxMl9ESUdFU1RfU0laRSwgRE1BX0JJRElSRUNU SU9OQUwpOwo+Pj4+PiArCj4+Pj4+ICsJZG1hX3VubWFwX3NpbmdsZShoYWNlX2Rldi0+ZGV2LCBy Y3R4LT5idWZmZXJfZG1hX2FkZHIsCj4+Pj4+ICsJCQkgcmN0eC0+YmxvY2tfc2l6ZSAqIDIsIERN QV9UT19ERVZJQ0UpOwo+Pj4+PiArCj4+Pj4+ICsJbWVtY3B5KHJlcS0+cmVzdWx0LCByY3R4LT5k aWdlc3QsIHJjdHgtPmRpZ3NpemUpOwo+Pj4+PiArCj4+Pj4+ICsJcmV0dXJuIGFzcGVlZF9haGFz aF9jb21wbGV0ZShoYWNlX2Rldik7IH0KPj4+Pj4gKwo+Pj4+PiArLyoKPj4+Pj4gKyAqIFRyaWdn ZXIgaGFyZHdhcmUgZW5naW5lcyB0byBkbyB0aGUgbWF0aC4KPj4+Pj4gKyAqLwo+Pj4+PiArc3Rh dGljIGludCBhc3BlZWRfaGFjZV9haGFzaF90cmlnZ2VyKHN0cnVjdCBhc3BlZWRfaGFjZV9kZXYK Pj4gKmhhY2VfZGV2LAo+Pj4+PiArCQkJCSAgICAgYXNwZWVkX2hhY2VfZm5fdCByZXN1bWUpCj4+ Pj4+ICt7Cj4+Pj4+ICsJc3RydWN0IGFzcGVlZF9lbmdpbmVfaGFzaCAqaGFzaF9lbmdpbmUgPQo+ PiAmaGFjZV9kZXYtPmhhc2hfZW5naW5lOwo+Pj4+PiArCXN0cnVjdCBhaGFzaF9yZXF1ZXN0ICpy ZXEgPSBoYXNoX2VuZ2luZS0+cmVxOwo+Pj4+PiArCXN0cnVjdCBhc3BlZWRfc2hhbV9yZXFjdHgg KnJjdHggPSBhaGFzaF9yZXF1ZXN0X2N0eChyZXEpOwo+Pj4+PiArCj4+Pj4+ICsJQUhBU0hfREJH KGhhY2VfZGV2LCAic3JjX2RtYToweCV4LCBkaWdlc3RfZG1hOjB4JXgsCj4+Pj4gbGVuZ3RoOjB4 JXhcbiIsCj4+Pj4+ICsJCSAgaGFzaF9lbmdpbmUtPnNyY19kbWEsIGhhc2hfZW5naW5lLT5kaWdl c3RfZG1hLAo+Pj4+PiArCQkgIGhhc2hfZW5naW5lLT5zcmNfbGVuZ3RoKTsKPj4+Pj4gKwo+Pj4+ PiArCXJjdHgtPmNtZCB8PSBIQVNIX0NNRF9JTlRfRU5BQkxFOwo+Pj4+PiArCWhhc2hfZW5naW5l LT5yZXN1bWUgPSByZXN1bWU7Cj4+Pj4+ICsKPj4+Pj4gKwlhc3RfaGFjZV93cml0ZShoYWNlX2Rl diwgaGFzaF9lbmdpbmUtPnNyY19kbWEsCj4+Pj4gQVNQRUVEX0hBQ0VfSEFTSF9TUkMpOwo+Pj4+ PiArCWFzdF9oYWNlX3dyaXRlKGhhY2VfZGV2LCBoYXNoX2VuZ2luZS0+ZGlnZXN0X2RtYSwKPj4+ Pj4gKwkJICAgICAgIEFTUEVFRF9IQUNFX0hBU0hfRElHRVNUX0JVRkYpOwo+Pj4+PiArCWFzdF9o YWNlX3dyaXRlKGhhY2VfZGV2LCBoYXNoX2VuZ2luZS0+ZGlnZXN0X2RtYSwKPj4+Pj4gKwkJICAg ICAgIEFTUEVFRF9IQUNFX0hBU0hfS0VZX0JVRkYpOwo+Pj4+PiArCWFzdF9oYWNlX3dyaXRlKGhh Y2VfZGV2LCBoYXNoX2VuZ2luZS0+c3JjX2xlbmd0aCwKPj4+Pj4gKwkJICAgICAgIEFTUEVFRF9I QUNFX0hBU0hfREFUQV9MRU4pOwo+Pj4+PiArCj4+Pj4+ICsJLyogTWVtb3J5IGJhcnJpZXIgdG8g ZW5zdXJlIGFsbCBkYXRhIHNldHVwIGJlZm9yZSBlbmdpbmUgc3RhcnRzICovCj4+Pj4+ICsJbWIo KTsKPj4+Pj4gKwo+Pj4+PiArCWFzdF9oYWNlX3dyaXRlKGhhY2VfZGV2LCByY3R4LT5jbWQsIEFT UEVFRF9IQUNFX0hBU0hfQ01EKTsKPj4+PiBBIGhhcmR3YXJlIHNlcnZpY2Ugc2VuZGluZyByZXF1 aXJlcyA1IGhhcmR3YXJlIGNvbW1hbmRzIHRvIGNvbXBsZXRlLgo+Pj4+IEluIGEgbXVsdGktY29u Y3VycmVuY3kgc2NlbmFyaW8sIGhvdyB0byBlbnN1cmUgdGhlIG9yZGVyIG9mIGNvbW1hbmRzPwo+ Pj4+IChJZiB0d28gcHJvY2Vzc2VzIHNlbmQgaGFyZHdhcmUgdGFzayBhdCB0aGUgc2FtZSB0aW1l LCBIb3cgdG8gZW5zdXJlCj4+Pj4gdGhhdCB0aGUgaGFyZHdhcmUgcmVjb2duaXplcyB3aGljaCB0 YXNrIHRoZSBjdXJyZW50IGNvbW1hbmQgYmVsb25ncwo+Pj4+IHRvPykKPj4+Cj4+PiBMaW51eCBj cnlwdG8gZW5naW5lIHdvdWxkIGd1YXJhbnRlZSB0aGF0IG9ubHkgb25lIHJlcXVlc3QgYXQgZWFj aCB0aW1lIHRvCj4+IGJlIGRlcXVldWVkIGZyb20gZW5naW5lIHF1ZXVlIHRvIHByb2Nlc3MuCj4+ PiBBbmQgdGhlcmUgaGFzIGxvY2sgbWVjaGFuaXNtIGluc2lkZSBMaW51eCBjcnlwdG8gZW5naW5l IHRvIHByZXZlbnQgdGhlCj4+IHNjZW5hcmlvIHlvdSBtZW50aW9uZWQuCj4+PiBTbyBvbmx5IDEg YXNwZWVkX2hhY2VfYWhhc2hfdHJpZ2dlcigpIGhhcmR3YXJlIHNlcnZpY2Ugd291bGQgZ28gdGhy b3VnaAo+PiBhdCBhIHRpbWUuCj4+Pgo+Pj4gWy4uLl0KPj4+IC4KPj4+Cj4+IFlvdSBtYXkgbm90 IHVuZGVyc3RhbmQgd2hhdCBJIG1lYW4sIHRoZSBjb21tYW5kIGZsb3cgaW4gYSBub3JtYWwgc2Nl bmFyaW86Cj4+IHJlcXVlc3RfQTogQWNtZDEtLT5BY21kMi0tPkFjbWQzLS0+QWNtZDQtLT5BY21k NQo+PiByZXF1ZXN0X0I6IEJjbWQxLS0+QmNtZDItLT5CY21kMy0tPkJjbWQ0LS0+QmNtZDUKPj4g SW4gYSBtdWx0aS1wcm9jZXNzIGNvbmN1cnJlbnQgc2NlbmFyaW8sIG11bHRpcGxlIGNyeXB0byBl bmdpbmVzIGNhbiBiZSBlbmFibGVkLAo+PiBhbmQgZWFjaCBjcnlwdG8gZW5naW5lIHNlbmRzIGEg cmVxdWVzdC4gSWYgbXVsdGlwbGUgcmVxdWVzdHMgaGVyZSBlbnRlcgo+PiBhc3BlZWRfaGFjZV9h aGFzaF90cmlnZ2VyKCkgYXQgdGhlIHNhbWUgdGltZSwgdGhlIGNvbW1hbmQgZmxvdyB3aWxsIGJl Cj4+IGludGVydHdpbmVkIGxpa2UgdGhpczoKPj4gcmVxdWVzdF9BLCByZXF1ZXN0X0I6Cj4+IEFj bWQxLS0+QmNtZDEtLT5BY21kMi0tPkFjbWQzLS0+QmNtZDItLT5BY21kNC0tPkJjbWQzLS0+QmNt ZDQtLT5BCj4+IGNtZDUtLT5CY21kNQo+Pgo+PiBJbiB0aGlzIGNvbW1hbmQgZmxvdywgaG93IGRv ZXMgeW91ciBoYXJkd2FyZSBpZGVudGlmeSB3aGV0aGVyIHRoZXNlCj4+IGNvbW1hbmRzIGJlbG9u ZyB0byByZXF1ZXN0X0Egb3IgcmVxdWVzdF9CPwo+PiBUaGFua3MuCj4+IExvbmdmYW5nLgo+IAo+ IEZvciBteSB1bmRlcnN0YW5kaW5nLCBhbGwgcmVxdWVzdHMgd2lsbCB0cmFuc2ZlciBpbnRvIGVu Z2luZSBxdWV1ZSB0aHJvdWdoIGNyeXB0b190cmFuc2Zlcl9oYXNoX3JlcXVlc3RfdG9fZW5naW5l KCkuCj4gSW4geW91ciBleGFtcGxlLCByZXF1ZXN0X0EgJiByZXF1ZXN0X0Igd291bGQgYWxzbyBl bnF1ZXVlIGludG8gdGhlIGVuZ2luZSBxdWV1ZSwgYW5kIHB1bXAgb3V0IDEgcmVxdWVzdCB3aGlj aCBtaWdodCBiZSBGSUZPIHRvIGhhbmRsZSBpdC4KPiBjcnlwdG9fcHVtcF9yZXF1ZXN0cygpIHdp bGwgZGVxdWV1ZSBvbmx5IDEgcmVxdWVzdCBhdCBhIHRpbWUgYW5kIHRvIHByZXBhcmVfcmVxdWVz dCgpICYgZG9fb25lX3JlcXVlc3QoKSBpZiBpdCdzIHJlZ2lzdGVyZWQuCj4gQW5kIGFzcGVlZF9o YWNlX2FoYXNoX3RyaWdnZXIoKSBpcyBpbnNpZGUgZG9fb25lX3JlcXVlc3QoKSwgc28gdGhhdCBt ZWFucyBubyBvdGhlciByZXF1ZXN0cyB3b3VsZCBjb21lIGluIGR1cmluZyBhc3BlZWRfaGFjZV9h aGFzaF90cmlnZ2VyKCkgd2hvbGUgcHJvY2Vzcy4KPiBUaGUgY29tbWFuZCBmbG93IGludGVydHdp bmVkCj4gQWNtZDEtLT5CY21kMS0tPkFjbWQyLS0+QWNtZDMtLT5CY21kMi0tPkFjbWQ0LS0+QmNt ZDMtLT5CY21kNC0tPkFjbWQ1LS0+QmNtZDUgd291bGQgbm90IGV4aXN0IGluIGFueSBzY2VuYXJp by4KPiBDb3JyZWN0IG1lIGlmIEknbSBtaXN1bmRlcnN0YW5kaW5nLCBUaGFua3MuCj4gCj4gLgo+ IApBdCBmaXJzdKOsWW91IG5lZWQgdG8gdW5kZXJzdGFuZCB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVu IHRocmVhZHMgYW5kIHByb2Nlc3NlcyB0aGF0IEkgc2FpZC4KSW4gYSBtdWx0aS10aHJlYWRlZCBz Y2VuYXJpbywgYWxsIHRocmVhZHMgd2lsbCBzaGFyZSB0aGUgZW5naW5lIG9mIGEgcHJvY2Vzcywg dGhlcmUgd2lsbCBvbmx5IGJlIG9uZSBlbmdpbmUgcXVldWUKdG8gc2VuZCBjbWRzIGF0IHRoZSBz YW1lIHRpbWUuIEhvd2V2ZXIsIGluIGEgbXVsdGktcHJvY2VzcyBzY2VuYXJpbywgZWFjaCBwcm9j ZXNzIHdpbGwgaGF2ZSBpdHMgb3duIGVuZ2luZSBxdWV1ZSwKYW5kIHdoZW4gcnVubmluZyBhdCB0 aGUgc2FtZSB0aW1lLCB0aGVyZSB3aWxsIGJlIG11bHRpcGxlIHF1ZXVlcyBzZW5kaW5nIGNtZHMu CgpUaGVuLCBJIHVuZGVyc3RhbmQgd2hhdCB5b3UgbWVhbi4gWW91ciBkcml2ZXIgdXNlcyB0aGUg c29mdHdhcmUgcXVldWUgb2YgdGhlIGVuY3J5cHRpb24gZW5naW5lIHRvIGVuc3VyZSB0aGUgY21k cyBvcmRlci4KVGhpcyBtZXRob2QgY2FuIGVuc3VyZSB0aGF0IHRoZSBjbWRzIG9mIG11bHRpcGxl IHRocmVhZHMgaW4gb25lIHByb2Nlc3MgYXJlIHNlbnQgaW4gb3JkZXIuCkJ1dCB5b3Ugc3RpbGwg bmVlZCB0byBjb25zaWRlciB0aGUgcHJvYmxlbSBvZiBtdWx0aXBsZSBwcm9jZXNzZXMsIHdoZW4g dXNpbmcgeW91ciBkZXZpY2UgZm9yIGhhc2ggb3BlcmF0aW9ucwppbiBtdWx0aXBsZSB1c2VyIHBy b2Nlc3NlcywgdGhlcmUgd2lsbCBiZSBtdWx0aXBsZSBjcnlwdG8gZW5naW5lIHNvZnR3YXJlIHF1 ZXVlcyBzZW5kaW5nIGNvbW1hbmRzIGF0IHRoZSBzYW1lIHRpbWUuClRoYW5rcwpMb25nZmFuZy4K Cl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCmxpbnV4LWFy bS1rZXJuZWwgbWFpbGluZyBsaXN0CmxpbnV4LWFybS1rZXJuZWxAbGlzdHMuaW5mcmFkZWFkLm9y ZwpodHRwOi8vbGlzdHMuaW5mcmFkZWFkLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2xpbnV4LWFybS1r ZXJuZWwK