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 40BAEC433F5 for ; Sun, 24 Apr 2022 10:46:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239166AbiDXKtL (ORCPT ); Sun, 24 Apr 2022 06:49:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56668 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239169AbiDXKtF (ORCPT ); Sun, 24 Apr 2022 06:49:05 -0400 Received: from mail-pl1-x629.google.com (mail-pl1-x629.google.com [IPv6:2607:f8b0:4864:20::629]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 002652B1B3 for ; Sun, 24 Apr 2022 03:45:59 -0700 (PDT) Received: by mail-pl1-x629.google.com with SMTP id n8so20861968plh.1 for ; Sun, 24 Apr 2022 03:45:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bytedance-com.20210112.gappssmtp.com; s=20210112; h=message-id:date:mime-version:user-agent:subject:content-language:to :cc:references:from:in-reply-to:content-transfer-encoding; bh=SP4KfluiuXJHh2KKPumxZZlVV8JF4bhmLHZsgCuesyg=; b=6ozyP0IcpXqdjjAkg8EHiRfhAZbMfNkpv9jJzL9BGeFoG22CJMcJ6zoXKiZGYnhu2C L79mMpYrBbgyIfB6lTfJRq58guVeH4gb5Oxg9a7Xp4UCn/55ErSoWKU9M+E4ObbijwQ3 Mwntf4N27SfCN28JN4upzCI/Zt7rH3qXbxt31MsjiAys328jl0ooocuxww020CEKkota iryZ/81INjhVk2s41DVz+tGawMlZP3oJGkd7soBOgHAidI952MJj9gaa0TFgczQkBHqs n6MGTYJoJLuEhtkYRNQE2mA6H87x2+e4hIy8KWQj0HVABzVVdjtNTD6eJgY0m3YcZiVr XYJg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:date:mime-version:user-agent:subject :content-language:to:cc:references:from:in-reply-to :content-transfer-encoding; bh=SP4KfluiuXJHh2KKPumxZZlVV8JF4bhmLHZsgCuesyg=; b=tt1jm3KP/XOyeOzIK0JdsmZXD4ufHbQP3Cd7qVW7f1dIGrK6R5rv7S6/ijpMV2EuXh 3M/5be4fvcV1r2xHsHXpG1SHijxPL1cGG+u89sm63pvweWJai3Fl5QChT4p5sobowS9I WSWdwAZlgzbA914UWr+Y9enZ/q3wrMXf8Mi5lcMpYXDzcm5O7WkkoEZGgqr+XjpdCyR2 jjNVQ77AqzrhqqVey5/v3Vvfh7aupor5ToTmHgZbK6kXLiIgP3izsCNqyBc6GGBGO5d4 ifCq+T0VkxnCtaz0lOlPfD2nGgQv66XytQAu2n37I1d3xN/9EDp6snc3VsjUmdQWJMWL HC3g== X-Gm-Message-State: AOAM5334rkQa9iXQ5OD2hgIWCuddvxfM+qE4weW9Zg6V87o+WalHfhCW TDqrLI1fOA4LogI2BMF6nHoQYg== X-Google-Smtp-Source: ABdhPJw9iJskJAK8X9cDKl4WEqInvtbQy73L73WnZNFn41K3vl8RcwE08TtWBoVvrRLYp7KbUikXyw== X-Received: by 2002:a17:902:b692:b0:14c:935b:2b03 with SMTP id c18-20020a170902b69200b0014c935b2b03mr12937938pls.81.1650797159217; Sun, 24 Apr 2022 03:45:59 -0700 (PDT) Received: from [10.76.15.169] ([61.120.150.70]) by smtp.gmail.com with ESMTPSA id r13-20020a635d0d000000b003aa482388dbsm6726945pgb.9.2022.04.24.03.45.55 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sun, 24 Apr 2022 03:45:58 -0700 (PDT) Message-ID: Date: Sun, 24 Apr 2022 18:42:07 +0800 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.7.0 Subject: Re: Re: Re: [PATCH v3 1/5] virtio-crypto: use private buffer for control request Content-Language: en-US To: Jason Wang Cc: "Gonglei (Arei)" , mst , Herbert Xu , linux-kernel , virtualization , linux-crypto@vger.kernel.org, helei.sig11@bytedance.com, davem References: <20220421104016.453458-1-pizhenwei@bytedance.com> <20220421104016.453458-2-pizhenwei@bytedance.com> <7996f495-3bb8-fa80-7866-fa1fbff3e80a@redhat.com> From: zhenwei pi In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org On 4/24/22 14:21, Jason Wang wrote: > On Fri, Apr 22, 2022 at 5:12 PM zhenwei pi wrote: >> >> On 4/22/22 15:41, Jason Wang wrote: >>> >>> 在 2022/4/21 18:40, zhenwei pi 写道: >>>> Originally, all of the control requests share a single buffer( >>>> ctrl & input & ctrl_status fields in struct virtio_crypto), this >>>> allows queue depth 1 only, the performance of control queue gets >>>> limited by this design. >>>> >>>> In this patch, each request allocates request buffer dynamically, and >>>> free buffer after request, it's possible to optimize control queue >>>> depth in the next step. >>>> >>>> A necessary comment is already in code, still describe it again: >>>> /* >>>> * Note: there are padding fields in request, clear them to zero before >>>> * sending to host, >>>> * Ex, virtio_crypto_ctrl_request::ctrl::u::destroy_session::padding[48] >>>> */ >>>> So use kzalloc to allocate buffer of struct virtio_crypto_ctrl_request. >>>> >>>> Cc: Michael S. Tsirkin >>>> Cc: Jason Wang >>>> Cc: Gonglei >>>> Signed-off-by: zhenwei pi >>>> --- >>>> drivers/crypto/virtio/Makefile | 1 + >>>> .../virtio/virtio_crypto_akcipher_algs.c | 90 ++++++------ >>>> drivers/crypto/virtio/virtio_crypto_common.c | 39 +++++ >>> >>> >>> Any reason we can't use virtio_crypto_core.c? >>> >> Another patch in this series: [PATCH v3 3/5] virtio-crypto: move helpers >> into virtio_crypto_common.c >> >> Move virtcrypto_clear_request and virtcrypto_dataq_callback into >> virtio_crypto_common.c to make code clear. Then the xx_core.c >> supports: >> - probe/remove/irq affinity seting for a virtio device >> - basic virtio related operations >> >> xx_common.c supports: >> - common helpers/functions for algos >> >> So I put this into a new file. > > I don't see obvious differences but we can leave it to the > virtio-crypto maintainers to decide. > OK! >> >>> >>>> drivers/crypto/virtio/virtio_crypto_common.h | 19 ++- >>>> .../virtio/virtio_crypto_skcipher_algs.c | 133 ++++++++---------- >>>> 5 files changed, 156 insertions(+), 126 deletions(-) >>>> create mode 100644 drivers/crypto/virtio/virtio_crypto_common.c >>>> >>>> diff --git a/drivers/crypto/virtio/Makefile >>>> b/drivers/crypto/virtio/Makefile >>>> index bfa6cbae342e..49c1fa80e465 100644 >>>> --- a/drivers/crypto/virtio/Makefile >>>> +++ b/drivers/crypto/virtio/Makefile >>>> @@ -3,5 +3,6 @@ obj-$(CONFIG_CRYPTO_DEV_VIRTIO) += virtio_crypto.o >>>> virtio_crypto-objs := \ >>>> virtio_crypto_skcipher_algs.o \ >>>> virtio_crypto_akcipher_algs.o \ >>>> + virtio_crypto_common.o \ >>>> virtio_crypto_mgr.o \ >>>> virtio_crypto_core.o >>>> diff --git a/drivers/crypto/virtio/virtio_crypto_akcipher_algs.c >>>> b/drivers/crypto/virtio/virtio_crypto_akcipher_algs.c >>>> index f3ec9420215e..9561bc2df62b 100644 >>>> --- a/drivers/crypto/virtio/virtio_crypto_akcipher_algs.c >>>> +++ b/drivers/crypto/virtio/virtio_crypto_akcipher_algs.c >>>> @@ -102,8 +102,8 @@ static int >>>> virtio_crypto_alg_akcipher_init_session(struct virtio_crypto_akcipher >>>> { >>>> struct scatterlist outhdr_sg, key_sg, inhdr_sg, *sgs[3]; >>>> struct virtio_crypto *vcrypto = ctx->vcrypto; >>>> + struct virtio_crypto_ctrl_request *vc_ctrl_req; >>>> uint8_t *pkey; >>>> - unsigned int inlen; >>>> int err; >>>> unsigned int num_out = 0, num_in = 0; >>>> @@ -111,98 +111,91 @@ static int >>>> virtio_crypto_alg_akcipher_init_session(struct virtio_crypto_akcipher >>>> if (!pkey) >>>> return -ENOMEM; >>>> - spin_lock(&vcrypto->ctrl_lock); >>>> - memcpy(&vcrypto->ctrl.header, header, sizeof(vcrypto->ctrl.header)); >>>> - memcpy(&vcrypto->ctrl.u, para, sizeof(vcrypto->ctrl.u)); >>>> - vcrypto->input.status = cpu_to_le32(VIRTIO_CRYPTO_ERR); >>>> + vc_ctrl_req = kzalloc(sizeof(*vc_ctrl_req), GFP_KERNEL); >>>> + if (!vc_ctrl_req) { >>>> + err = -ENOMEM; >>>> + goto out; >>>> + } >>>> - sg_init_one(&outhdr_sg, &vcrypto->ctrl, sizeof(vcrypto->ctrl)); >>>> + memcpy(&vc_ctrl_req->ctrl.header, header, >>>> sizeof(vc_ctrl_req->ctrl.header)); >>>> + memcpy(&vc_ctrl_req->ctrl.u, para, sizeof(vc_ctrl_req->ctrl.u)); >>>> + sg_init_one(&outhdr_sg, &vc_ctrl_req->ctrl, >>>> sizeof(vc_ctrl_req->ctrl)); >>>> sgs[num_out++] = &outhdr_sg; >>>> sg_init_one(&key_sg, pkey, keylen); >>>> sgs[num_out++] = &key_sg; >>>> - sg_init_one(&inhdr_sg, &vcrypto->input, sizeof(vcrypto->input)); >>>> + vc_ctrl_req->input.status = cpu_to_le32(VIRTIO_CRYPTO_ERR); >>> >>> >>> Nit: if there's no special reason, let's move this after the above >>> memcpys as what's done previously. >>> >>> >>>> + sg_init_one(&inhdr_sg, &vc_ctrl_req->input, >>>> sizeof(vc_ctrl_req->input)); >>>> sgs[num_out + num_in++] = &inhdr_sg; >>>> - err = virtqueue_add_sgs(vcrypto->ctrl_vq, sgs, num_out, num_in, >>>> vcrypto, GFP_ATOMIC); >>>> + err = virtio_crypto_ctrl_vq_request(vcrypto, sgs, num_out, >>>> num_in, vc_ctrl_req); >>> >>> >>> I'd split this into a separate patch. >>> >> >> OK! >>> >>>> if (err < 0) >>>> goto out; >>>> - virtqueue_kick(vcrypto->ctrl_vq); >>>> - while (!virtqueue_get_buf(vcrypto->ctrl_vq, &inlen) && >>>> - !virtqueue_is_broken(vcrypto->ctrl_vq)) >>>> - cpu_relax(); >>>> - >>>> - if (le32_to_cpu(vcrypto->input.status) != VIRTIO_CRYPTO_OK) { >>>> + if (le32_to_cpu(vc_ctrl_req->input.status) != VIRTIO_CRYPTO_OK) { >>>> + pr_err("virtio_crypto: Create session failed status: %u\n", >>>> + le32_to_cpu(vc_ctrl_req->input.status)); >>>> err = -EINVAL; >>>> goto out; >>>> } >>> >>> >>> Do we need a warning for -ENOMEM? >>> >> >> Memory(especially small size) allocation is unlikely case, I also check >> the virtio_net and virtio_blk, both handles -ENOMEM only without error >> reporting. > > Ok. > >> >>> >>>> - ctx->session_id = le64_to_cpu(vcrypto->input.session_id); >>>> + ctx->session_id = le64_to_cpu(vc_ctrl_req->input.session_id); >>>> ctx->session_valid = true; >>>> err = 0; >>>> out: >>>> - spin_unlock(&vcrypto->ctrl_lock); >>>> + kfree(vc_ctrl_req); >>>> kfree_sensitive(pkey); >>>> - if (err < 0) >>>> - pr_err("virtio_crypto: Create session failed status: %u\n", >>>> - le32_to_cpu(vcrypto->input.status)); >>>> - >>>> return err; >>>> } >>>> static int virtio_crypto_alg_akcipher_close_session(struct >>>> virtio_crypto_akcipher_ctx *ctx) >>>> { >>>> struct scatterlist outhdr_sg, inhdr_sg, *sgs[2]; >>>> + struct virtio_crypto_ctrl_request *vc_ctrl_req; >>>> struct virtio_crypto_destroy_session_req *destroy_session; >>>> struct virtio_crypto *vcrypto = ctx->vcrypto; >>>> - unsigned int num_out = 0, num_in = 0, inlen; >>>> + unsigned int num_out = 0, num_in = 0; >>>> int err; >>>> - spin_lock(&vcrypto->ctrl_lock); >>>> - if (!ctx->session_valid) { >>>> - err = 0; >>>> - goto out; >>>> - } >>>> - vcrypto->ctrl_status.status = VIRTIO_CRYPTO_ERR; >>>> - vcrypto->ctrl.header.opcode = >>>> cpu_to_le32(VIRTIO_CRYPTO_AKCIPHER_DESTROY_SESSION); >>>> - vcrypto->ctrl.header.queue_id = 0; >>>> + if (!ctx->session_valid) >>>> + return 0; >>>> - destroy_session = &vcrypto->ctrl.u.destroy_session; >>>> + vc_ctrl_req = kzalloc(sizeof(*vc_ctrl_req), GFP_KERNEL); >>>> + if (!vc_ctrl_req) >>>> + return -ENOMEM; >>>> + >>>> + vc_ctrl_req->ctrl.header.opcode = >>>> cpu_to_le32(VIRTIO_CRYPTO_AKCIPHER_DESTROY_SESSION); >>>> + vc_ctrl_req->ctrl.header.queue_id = 0; >>>> + >>>> + destroy_session = &vc_ctrl_req->ctrl.u.destroy_session; >>>> destroy_session->session_id = cpu_to_le64(ctx->session_id); >>>> - sg_init_one(&outhdr_sg, &vcrypto->ctrl, sizeof(vcrypto->ctrl)); >>>> + sg_init_one(&outhdr_sg, &vc_ctrl_req->ctrl, >>>> sizeof(vc_ctrl_req->ctrl)); >>>> sgs[num_out++] = &outhdr_sg; >>>> - sg_init_one(&inhdr_sg, &vcrypto->ctrl_status.status, >>>> sizeof(vcrypto->ctrl_status.status)); >>>> + vc_ctrl_req->ctrl_status.status = VIRTIO_CRYPTO_ERR; >>> >>> >>> If no special reason, let's move this above: >>> >>> vc_ctrl_req->ctrl.header.opcode = >>> cpu_to_le32(VIRTIO_CRYPTO_AKCIPHER_DESTROY_SESSION); >>> >> >> OK! >>> >>>> + sg_init_one(&inhdr_sg, &vc_ctrl_req->ctrl_status.status, >>>> + sizeof(vc_ctrl_req->ctrl_status.status)); >>>> sgs[num_out + num_in++] = &inhdr_sg; >>>> - err = virtqueue_add_sgs(vcrypto->ctrl_vq, sgs, num_out, num_in, >>>> vcrypto, GFP_ATOMIC); >>>> + err = virtio_crypto_ctrl_vq_request(vcrypto, sgs, num_out, >>>> num_in, vc_ctrl_req); >>>> if (err < 0) >>>> goto out; >>>> - virtqueue_kick(vcrypto->ctrl_vq); >>>> - while (!virtqueue_get_buf(vcrypto->ctrl_vq, &inlen) && >>>> - !virtqueue_is_broken(vcrypto->ctrl_vq)) >>>> - cpu_relax(); >>>> - >>>> - if (vcrypto->ctrl_status.status != VIRTIO_CRYPTO_OK) { >>>> + if (vc_ctrl_req->ctrl_status.status != VIRTIO_CRYPTO_OK) { >>>> err = -EINVAL; >>>> + pr_err("virtio_crypto: Close session failed status: %u, >>>> session_id: 0x%llx\n", >>>> + vc_ctrl_req->ctrl_status.status, >>>> destroy_session->session_id); >>>> goto out; >>>> } >>>> err = 0; >>>> ctx->session_valid = false; >>>> - >>>> out: >>>> - spin_unlock(&vcrypto->ctrl_lock); >>>> - if (err < 0) { >>>> - pr_err("virtio_crypto: Close session failed status: %u, >>>> session_id: 0x%llx\n", >>>> - vcrypto->ctrl_status.status, destroy_session->session_id); >>>> - } >>>> + kfree(vc_ctrl_req); >>>> return err; >>>> } >>>> @@ -210,14 +203,11 @@ static int >>>> virtio_crypto_alg_akcipher_close_session(struct virtio_crypto_akciphe >>>> static int __virtio_crypto_akcipher_do_req(struct >>>> virtio_crypto_akcipher_request *vc_akcipher_req, >>>> struct akcipher_request *req, struct data_queue *data_vq) >>>> { >>>> - struct virtio_crypto_akcipher_ctx *ctx = >>>> vc_akcipher_req->akcipher_ctx; >>>> struct virtio_crypto_request *vc_req = &vc_akcipher_req->base; >>>> - struct virtio_crypto *vcrypto = ctx->vcrypto; >>>> struct virtio_crypto_op_data_req *req_data = vc_req->req_data; >>>> struct scatterlist *sgs[4], outhdr_sg, inhdr_sg, srcdata_sg, >>>> dstdata_sg; >>>> void *src_buf = NULL, *dst_buf = NULL; >>>> unsigned int num_out = 0, num_in = 0; >>>> - int node = dev_to_node(&vcrypto->vdev->dev); >>>> unsigned long flags; >>>> int ret = -ENOMEM; >>>> bool verify = vc_akcipher_req->opcode == >>>> VIRTIO_CRYPTO_AKCIPHER_VERIFY; >>>> @@ -228,7 +218,7 @@ static int __virtio_crypto_akcipher_do_req(struct >>>> virtio_crypto_akcipher_request >>>> sgs[num_out++] = &outhdr_sg; >>>> /* src data */ >>>> - src_buf = kcalloc_node(src_len, 1, GFP_KERNEL, node); >>>> + src_buf = kcalloc(src_len, 1, GFP_KERNEL); >>> >>> >>> This seems not a relevant change. If it is a must we need use a separate >>> for this and describe the rationale. >>> >>> >>>> if (!src_buf) >>>> goto err; >>>> @@ -243,7 +233,7 @@ static int __virtio_crypto_akcipher_do_req(struct >>>> virtio_crypto_akcipher_request >>>> sgs[num_out++] = &srcdata_sg; >>>> /* dst data */ >>>> - dst_buf = kcalloc_node(req->dst_len, 1, GFP_KERNEL, node); >>>> + dst_buf = kcalloc(req->dst_len, 1, GFP_KERNEL); >>> >>> >>> And this. >>> >>> >>>> if (!dst_buf) >>>> goto err; >>>> diff --git a/drivers/crypto/virtio/virtio_crypto_common.c >>>> b/drivers/crypto/virtio/virtio_crypto_common.c >>>> new file mode 100644 >>>> index 000000000000..e65125a74db2 >>>> --- /dev/null >>>> +++ b/drivers/crypto/virtio/virtio_crypto_common.c >>>> @@ -0,0 +1,39 @@ >>>> +// SPDX-License-Identifier: GPL-2.0-or-later >>>> +/* Common functions and helpers >>>> + * >>>> + * Authors: zhenwei pi >>>> + * >>>> + * Copyright 2022 Bytedance CO., LTD. >>>> + */ >>>> + >>>> +#include "virtio_crypto_common.h" >>>> + >>>> +int virtio_crypto_ctrl_vq_request(struct virtio_crypto *vcrypto, >>>> struct scatterlist *sgs[], >>>> + unsigned int out_sgs, unsigned int in_sgs, >>>> + struct virtio_crypto_ctrl_request *vc_ctrl_req) >>>> +{ >>>> + int err; >>>> + unsigned int inlen; >>>> + unsigned long flags; >>>> + >>>> + spin_lock_irqsave(&vcrypto->ctrl_lock, flags); >>>> + err = virtqueue_add_sgs(vcrypto->ctrl_vq, sgs, out_sgs, in_sgs, >>>> vc_ctrl_req, GFP_ATOMIC); >>>> + if (err < 0) { >>>> + spin_unlock_irqrestore(&vcrypto->ctrl_lock, flags); >>>> + return err; >>>> + } >>>> + >>>> + virtqueue_kick(vcrypto->ctrl_vq); >>>> + >>>> + /* >>>> + * Trapping into the hypervisor, so the request should be >>>> + * handled immediately. >>>> + */ >>>> + while (!virtqueue_get_buf(vcrypto->ctrl_vq, &inlen) && >>>> + !virtqueue_is_broken(vcrypto->ctrl_vq)) >>>> + cpu_relax(); >>>> + >>>> + spin_unlock_irqrestore(&vcrypto->ctrl_lock, flags); >>>> + >>>> + return 0; >>>> +} >>>> diff --git a/drivers/crypto/virtio/virtio_crypto_common.h >>>> b/drivers/crypto/virtio/virtio_crypto_common.h >>>> index e693d4ee83a6..d2a20fe6e13e 100644 >>>> --- a/drivers/crypto/virtio/virtio_crypto_common.h >>>> +++ b/drivers/crypto/virtio/virtio_crypto_common.h >>>> @@ -13,6 +13,7 @@ >>>> #include >>>> #include >>>> #include >>>> +#include >>>> /* Internal representation of a data virtqueue */ >>>> @@ -65,11 +66,6 @@ struct virtio_crypto { >>>> /* Maximum size of per request */ >>>> u64 max_size; >>>> - /* Control VQ buffers: protected by the ctrl_lock */ >>>> - struct virtio_crypto_op_ctrl_req ctrl; >>>> - struct virtio_crypto_session_input input; >>>> - struct virtio_crypto_inhdr ctrl_status; >>>> - >>>> unsigned long status; >>>> atomic_t ref_count; >>>> struct list_head list; >>>> @@ -85,6 +81,16 @@ struct virtio_crypto_sym_session_info { >>>> __u64 session_id; >>>> }; >>>> +/* >>>> + * Note: there are padding fields in request, clear them to zero >>>> before sending to host, >>>> + * Ex, virtio_crypto_ctrl_request::ctrl::u::destroy_session::padding[48] >>>> + */ >>>> +struct virtio_crypto_ctrl_request { >>>> + struct virtio_crypto_op_ctrl_req ctrl; >>>> + struct virtio_crypto_session_input input; >>>> + struct virtio_crypto_inhdr ctrl_status; >>>> +}; >>>> + >>>> struct virtio_crypto_request; >>>> typedef void (*virtio_crypto_data_callback) >>>> (struct virtio_crypto_request *vc_req, int len); >>>> @@ -135,4 +141,7 @@ void virtio_crypto_skcipher_algs_unregister(struct >>>> virtio_crypto *vcrypto); >>>> int virtio_crypto_akcipher_algs_register(struct virtio_crypto >>>> *vcrypto); >>>> void virtio_crypto_akcipher_algs_unregister(struct virtio_crypto >>>> *vcrypto); >>>> +int virtio_crypto_ctrl_vq_request(struct virtio_crypto *vcrypto, >>>> struct scatterlist *sgs[], >>>> + unsigned int out_sgs, unsigned int in_sgs, >>>> + struct virtio_crypto_ctrl_request *vc_ctrl_req); >>>> #endif /* _VIRTIO_CRYPTO_COMMON_H */ >>>> diff --git a/drivers/crypto/virtio/virtio_crypto_skcipher_algs.c >>>> b/drivers/crypto/virtio/virtio_crypto_skcipher_algs.c >>>> index a618c46a52b8..fef355ff461c 100644 >>>> --- a/drivers/crypto/virtio/virtio_crypto_skcipher_algs.c >>>> +++ b/drivers/crypto/virtio/virtio_crypto_skcipher_algs.c >>>> @@ -118,11 +118,13 @@ static int virtio_crypto_alg_skcipher_init_session( >>>> int encrypt) >>>> { >>>> struct scatterlist outhdr, key_sg, inhdr, *sgs[3]; >>>> - unsigned int tmp; >>>> struct virtio_crypto *vcrypto = ctx->vcrypto; >>> >>> >>> Can we simply rename this to virtcrypto and then we can use the name >>> "vcrypto" for virtio_crypto_ctrl_request then we save tons lot changes? >>> >>> It simplify the life of reviewers and backporting. >>> >>> Thanks >>> >> >> This series focuses on performance improvment, and keeps the style with >> the orignal style. What about fixing this in another series? (If so, >> I'll fix this later) > > Just in case we are at the same page, what I suggest can save hundreds > lines of codes: > > E.g: > >>>> - vcrypto->ctrl.header.queue_id = 0; >>>> + header->queue_id = 0; > > If we stick to the name of "vcrypto" we don't need this change at all. > > It can simplify: > > 1) future context difference when backporting patches to -stable > 2) reviewing > > Thanks > Oh, sorry, I misunderstood this. I agree with this point, but I notice that 'vcrypto' is always a variable of 'type struct virtio_crypto *' in this driver, should we break this? To simplify reviewing, I have another opinion in the v4 series, could you please review it? >>> >>>> int op = encrypt ? VIRTIO_CRYPTO_OP_ENCRYPT : >>>> VIRTIO_CRYPTO_OP_DECRYPT; >>>> int err; >>>> unsigned int num_out = 0, num_in = 0; >>>> + struct virtio_crypto_ctrl_request *vc_ctrl_req; >>>> + struct virtio_crypto_ctrl_header *header; >>>> + struct virtio_crypto_sym_create_session_req *sym_create_session; >>>> /* >>>> * Avoid to do DMA from the stack, switch to using >>>> @@ -133,26 +135,27 @@ static int virtio_crypto_alg_skcipher_init_session( >>>> if (!cipher_key) >>>> return -ENOMEM; >>>> - spin_lock(&vcrypto->ctrl_lock); >>>> + vc_ctrl_req = kzalloc(sizeof(*vc_ctrl_req), GFP_KERNEL); >>>> + if (!vc_ctrl_req) { >>>> + err = -ENOMEM; >>>> + goto out; >>>> + } >>>> + >>>> /* Pad ctrl header */ >>>> - vcrypto->ctrl.header.opcode = >>>> - cpu_to_le32(VIRTIO_CRYPTO_CIPHER_CREATE_SESSION); >>>> - vcrypto->ctrl.header.algo = cpu_to_le32(alg); >>>> + header = &vc_ctrl_req->ctrl.header; >>>> + header->opcode = cpu_to_le32(VIRTIO_CRYPTO_CIPHER_CREATE_SESSION); >>>> + header->algo = cpu_to_le32(alg); >>>> /* Set the default dataqueue id to 0 */ >>>> - vcrypto->ctrl.header.queue_id = 0; >>>> + header->queue_id = 0; >>>> - vcrypto->input.status = cpu_to_le32(VIRTIO_CRYPTO_ERR); >>>> /* Pad cipher's parameters */ >>>> - vcrypto->ctrl.u.sym_create_session.op_type = >>>> - cpu_to_le32(VIRTIO_CRYPTO_SYM_OP_CIPHER); >>>> - vcrypto->ctrl.u.sym_create_session.u.cipher.para.algo = >>>> - vcrypto->ctrl.header.algo; >>>> - vcrypto->ctrl.u.sym_create_session.u.cipher.para.keylen = >>>> - cpu_to_le32(keylen); >>>> - vcrypto->ctrl.u.sym_create_session.u.cipher.para.op = >>>> - cpu_to_le32(op); >>>> - >>>> - sg_init_one(&outhdr, &vcrypto->ctrl, sizeof(vcrypto->ctrl)); >>>> + sym_create_session = &vc_ctrl_req->ctrl.u.sym_create_session; >>>> + sym_create_session->op_type = >>>> cpu_to_le32(VIRTIO_CRYPTO_SYM_OP_CIPHER); >>>> + sym_create_session->u.cipher.para.algo = header->algo; >>>> + sym_create_session->u.cipher.para.keylen = cpu_to_le32(keylen); >>>> + sym_create_session->u.cipher.para.op = cpu_to_le32(op); >>>> + >>>> + sg_init_one(&outhdr, &vc_ctrl_req->ctrl, sizeof(vc_ctrl_req->ctrl)); >>>> sgs[num_out++] = &outhdr; >>>> /* Set key */ >>>> @@ -160,45 +163,34 @@ static int virtio_crypto_alg_skcipher_init_session( >>>> sgs[num_out++] = &key_sg; >>>> /* Return status and session id back */ >>>> - sg_init_one(&inhdr, &vcrypto->input, sizeof(vcrypto->input)); >>>> + vc_ctrl_req->input.status = cpu_to_le32(VIRTIO_CRYPTO_ERR); >>>> + sg_init_one(&inhdr, &vc_ctrl_req->input, >>>> sizeof(vc_ctrl_req->input)); >>>> sgs[num_out + num_in++] = &inhdr; >>>> - err = virtqueue_add_sgs(vcrypto->ctrl_vq, sgs, num_out, >>>> - num_in, vcrypto, GFP_ATOMIC); >>>> - if (err < 0) { >>>> - spin_unlock(&vcrypto->ctrl_lock); >>>> - kfree_sensitive(cipher_key); >>>> - return err; >>>> - } >>>> - virtqueue_kick(vcrypto->ctrl_vq); >>>> - >>>> - /* >>>> - * Trapping into the hypervisor, so the request should be >>>> - * handled immediately. >>>> - */ >>>> - while (!virtqueue_get_buf(vcrypto->ctrl_vq, &tmp) && >>>> - !virtqueue_is_broken(vcrypto->ctrl_vq)) >>>> - cpu_relax(); >>>> + err = virtio_crypto_ctrl_vq_request(vcrypto, sgs, num_out, >>>> num_in, vc_ctrl_req); >>>> + if (err < 0) >>>> + goto out; >>>> - if (le32_to_cpu(vcrypto->input.status) != VIRTIO_CRYPTO_OK) { >>>> - spin_unlock(&vcrypto->ctrl_lock); >>>> + if (le32_to_cpu(vc_ctrl_req->input.status) != VIRTIO_CRYPTO_OK) { >>>> pr_err("virtio_crypto: Create session failed status: %u\n", >>>> - le32_to_cpu(vcrypto->input.status)); >>>> - kfree_sensitive(cipher_key); >>>> - return -EINVAL; >>>> + le32_to_cpu(vc_ctrl_req->input.status)); >>>> + err = -EINVAL; >>>> + goto out; >>>> } >>>> if (encrypt) >>>> ctx->enc_sess_info.session_id = >>>> - le64_to_cpu(vcrypto->input.session_id); >>>> + le64_to_cpu(vc_ctrl_req->input.session_id); >>>> else >>>> ctx->dec_sess_info.session_id = >>>> - le64_to_cpu(vcrypto->input.session_id); >>>> - >>>> - spin_unlock(&vcrypto->ctrl_lock); >>>> + le64_to_cpu(vc_ctrl_req->input.session_id); >>>> + err = 0; >>>> +out: >>>> + kfree(vc_ctrl_req); >>>> kfree_sensitive(cipher_key); >>>> - return 0; >>>> + >>>> + return err; >>>> } >>>> static int virtio_crypto_alg_skcipher_close_session( >>>> @@ -206,21 +198,24 @@ static int >>>> virtio_crypto_alg_skcipher_close_session( >>>> int encrypt) >>>> { >>>> struct scatterlist outhdr, status_sg, *sgs[2]; >>>> - unsigned int tmp; >>>> struct virtio_crypto_destroy_session_req *destroy_session; >>>> struct virtio_crypto *vcrypto = ctx->vcrypto; >>>> int err; >>>> unsigned int num_out = 0, num_in = 0; >>>> + struct virtio_crypto_ctrl_request *vc_ctrl_req; >>>> + struct virtio_crypto_ctrl_header *header; >>>> + >>>> + vc_ctrl_req = kzalloc(sizeof(*vc_ctrl_req), GFP_KERNEL); >>>> + if (!vc_ctrl_req) >>>> + return -ENOMEM; >>>> - spin_lock(&vcrypto->ctrl_lock); >>>> - vcrypto->ctrl_status.status = VIRTIO_CRYPTO_ERR; >>>> /* Pad ctrl header */ >>>> - vcrypto->ctrl.header.opcode = >>>> - cpu_to_le32(VIRTIO_CRYPTO_CIPHER_DESTROY_SESSION); >>>> + header = &vc_ctrl_req->ctrl.header; >>>> + header->opcode = cpu_to_le32(VIRTIO_CRYPTO_CIPHER_DESTROY_SESSION); >>>> /* Set the default virtqueue id to 0 */ >>>> - vcrypto->ctrl.header.queue_id = 0; >>>> + header->queue_id = 0; >>>> - destroy_session = &vcrypto->ctrl.u.destroy_session; >>>> + destroy_session = &vc_ctrl_req->ctrl.u.destroy_session; >>>> if (encrypt) >>>> destroy_session->session_id = >>>> @@ -229,37 +224,33 @@ static int >>>> virtio_crypto_alg_skcipher_close_session( >>>> destroy_session->session_id = >>>> cpu_to_le64(ctx->dec_sess_info.session_id); >>>> - sg_init_one(&outhdr, &vcrypto->ctrl, sizeof(vcrypto->ctrl)); >>>> + sg_init_one(&outhdr, &vc_ctrl_req->ctrl, sizeof(vc_ctrl_req->ctrl)); >>>> sgs[num_out++] = &outhdr; >>>> /* Return status and session id back */ >>>> - sg_init_one(&status_sg, &vcrypto->ctrl_status.status, >>>> - sizeof(vcrypto->ctrl_status.status)); >>>> + vc_ctrl_req->ctrl_status.status = VIRTIO_CRYPTO_ERR; >>>> + sg_init_one(&status_sg, &vc_ctrl_req->ctrl_status.status, >>>> + sizeof(vc_ctrl_req->ctrl_status.status)); >>>> sgs[num_out + num_in++] = &status_sg; >>>> - err = virtqueue_add_sgs(vcrypto->ctrl_vq, sgs, num_out, >>>> - num_in, vcrypto, GFP_ATOMIC); >>>> - if (err < 0) { >>>> - spin_unlock(&vcrypto->ctrl_lock); >>>> - return err; >>>> - } >>>> - virtqueue_kick(vcrypto->ctrl_vq); >>>> - >>>> - while (!virtqueue_get_buf(vcrypto->ctrl_vq, &tmp) && >>>> - !virtqueue_is_broken(vcrypto->ctrl_vq)) >>>> - cpu_relax(); >>>> + err = virtio_crypto_ctrl_vq_request(vcrypto, sgs, num_out, >>>> num_in, vc_ctrl_req); >>>> + if (err < 0) >>>> + goto out; >>>> - if (vcrypto->ctrl_status.status != VIRTIO_CRYPTO_OK) { >>>> - spin_unlock(&vcrypto->ctrl_lock); >>>> + if (vc_ctrl_req->ctrl_status.status != VIRTIO_CRYPTO_OK) { >>>> pr_err("virtio_crypto: Close session failed status: %u, >>>> session_id: 0x%llx\n", >>>> - vcrypto->ctrl_status.status, >>>> + vc_ctrl_req->ctrl_status.status, >>>> destroy_session->session_id); >>>> - return -EINVAL; >>>> + err = -EINVAL; >>>> + goto out; >>>> } >>>> - spin_unlock(&vcrypto->ctrl_lock); >>>> - return 0; >>>> + err = 0; >>>> +out: >>>> + kfree(vc_ctrl_req); >>>> + >>>> + return err; >>>> } >>>> static int virtio_crypto_alg_skcipher_init_sessions( >>> >> >> -- >> zhenwei pi >> > -- zhenwei pi 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 smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) (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 ED359C4332F for ; Sun, 24 Apr 2022 10:46:04 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id BC6D581CA3; Sun, 24 Apr 2022 10:46:04 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id H4ZgRVh88DJs; Sun, 24 Apr 2022 10:46:03 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp1.osuosl.org (Postfix) with ESMTPS id 8B7B481BB2; Sun, 24 Apr 2022 10:46:02 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 5A4D5C0039; Sun, 24 Apr 2022 10:46:02 +0000 (UTC) Received: from smtp2.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 4F3B7C007C for ; Sun, 24 Apr 2022 10:46:01 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 2825A40A6A for ; Sun, 24 Apr 2022 10:46:01 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Authentication-Results: smtp2.osuosl.org (amavisd-new); dkim=pass (2048-bit key) header.d=bytedance-com.20210112.gappssmtp.com Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id lg2SSZaoHHRD for ; Sun, 24 Apr 2022 10:45:59 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.8.0 Received: from mail-pl1-x62c.google.com (mail-pl1-x62c.google.com [IPv6:2607:f8b0:4864:20::62c]) by smtp2.osuosl.org (Postfix) with ESMTPS id D378140918 for ; Sun, 24 Apr 2022 10:45:59 +0000 (UTC) Received: by mail-pl1-x62c.google.com with SMTP id c12so20787538plr.6 for ; Sun, 24 Apr 2022 03:45:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bytedance-com.20210112.gappssmtp.com; s=20210112; h=message-id:date:mime-version:user-agent:subject:content-language:to :cc:references:from:in-reply-to:content-transfer-encoding; bh=SP4KfluiuXJHh2KKPumxZZlVV8JF4bhmLHZsgCuesyg=; b=6ozyP0IcpXqdjjAkg8EHiRfhAZbMfNkpv9jJzL9BGeFoG22CJMcJ6zoXKiZGYnhu2C L79mMpYrBbgyIfB6lTfJRq58guVeH4gb5Oxg9a7Xp4UCn/55ErSoWKU9M+E4ObbijwQ3 Mwntf4N27SfCN28JN4upzCI/Zt7rH3qXbxt31MsjiAys328jl0ooocuxww020CEKkota iryZ/81INjhVk2s41DVz+tGawMlZP3oJGkd7soBOgHAidI952MJj9gaa0TFgczQkBHqs n6MGTYJoJLuEhtkYRNQE2mA6H87x2+e4hIy8KWQj0HVABzVVdjtNTD6eJgY0m3YcZiVr XYJg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:date:mime-version:user-agent:subject :content-language:to:cc:references:from:in-reply-to :content-transfer-encoding; bh=SP4KfluiuXJHh2KKPumxZZlVV8JF4bhmLHZsgCuesyg=; b=wAI28dRp7hLShszLmMvaU5RkqvQ5jmbUZP6YzI4aMzk2BvY3we09QnwCpyH1sKZxzJ cW1PTSrdD+NMkSXkOYbecA2/ywJ+9e9MsYPBBftP2oA92A8+1M2XAAhSdvi9IHm5/jG1 S5T8JpWdCU+uUnA/3IoMAzqWNplh2etzOoraVpRa+wkvWpc76egqkKMjaG5weyFmPNOO 77lmBbLiSaVGEWBOvuiavbt+j1JcYdd1qrFhDVw6OVNKboAgNTN1qfrhB4QLBGpShJgy GlNwLvR/eDk7rPNQ8ZDt+VgpenZMj5vUi7cpTWU4ygtfGE1+1aPncMV2BElVlKIqZQBE 395g== X-Gm-Message-State: AOAM532197YD/Tij+EE4si1pNzaA0lESlexmXdXwHFA4r231iyGscMTL g3t8xd7C6PFjBZaiE/LsNk+lWw== X-Google-Smtp-Source: ABdhPJw9iJskJAK8X9cDKl4WEqInvtbQy73L73WnZNFn41K3vl8RcwE08TtWBoVvrRLYp7KbUikXyw== X-Received: by 2002:a17:902:b692:b0:14c:935b:2b03 with SMTP id c18-20020a170902b69200b0014c935b2b03mr12937938pls.81.1650797159217; Sun, 24 Apr 2022 03:45:59 -0700 (PDT) Received: from [10.76.15.169] ([61.120.150.70]) by smtp.gmail.com with ESMTPSA id r13-20020a635d0d000000b003aa482388dbsm6726945pgb.9.2022.04.24.03.45.55 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sun, 24 Apr 2022 03:45:58 -0700 (PDT) Message-ID: Date: Sun, 24 Apr 2022 18:42:07 +0800 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.7.0 Subject: Re: Re: Re: [PATCH v3 1/5] virtio-crypto: use private buffer for control request Content-Language: en-US To: Jason Wang References: <20220421104016.453458-1-pizhenwei@bytedance.com> <20220421104016.453458-2-pizhenwei@bytedance.com> <7996f495-3bb8-fa80-7866-fa1fbff3e80a@redhat.com> From: zhenwei pi In-Reply-To: Cc: Herbert Xu , mst , linux-kernel , virtualization , linux-crypto@vger.kernel.org, davem , helei.sig11@bytedance.com X-BeenThere: virtualization@lists.linux-foundation.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Linux virtualization List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: base64 Content-Type: text/plain; charset="utf-8"; Format="flowed" Errors-To: virtualization-bounces@lists.linux-foundation.org Sender: "Virtualization" T24gNC8yNC8yMiAxNDoyMSwgSmFzb24gV2FuZyB3cm90ZToKPiBPbiBGcmksIEFwciAyMiwgMjAy MiBhdCA1OjEyIFBNIHpoZW53ZWkgcGkgPHBpemhlbndlaUBieXRlZGFuY2UuY29tPiB3cm90ZToK Pj4KPj4gT24gNC8yMi8yMiAxNTo0MSwgSmFzb24gV2FuZyB3cm90ZToKPj4+Cj4+PiDlnKggMjAy Mi80LzIxIDE4OjQwLCB6aGVud2VpIHBpIOWGmemBkzoKPj4+PiBPcmlnaW5hbGx5LCBhbGwgb2Yg dGhlIGNvbnRyb2wgcmVxdWVzdHMgc2hhcmUgYSBzaW5nbGUgYnVmZmVyKAo+Pj4+IGN0cmwgJiBp bnB1dCAmIGN0cmxfc3RhdHVzIGZpZWxkcyBpbiBzdHJ1Y3QgdmlydGlvX2NyeXB0byksIHRoaXMK Pj4+PiBhbGxvd3MgcXVldWUgZGVwdGggMSBvbmx5LCB0aGUgcGVyZm9ybWFuY2Ugb2YgY29udHJv bCBxdWV1ZSBnZXRzCj4+Pj4gbGltaXRlZCBieSB0aGlzIGRlc2lnbi4KPj4+Pgo+Pj4+IEluIHRo aXMgcGF0Y2gsIGVhY2ggcmVxdWVzdCBhbGxvY2F0ZXMgcmVxdWVzdCBidWZmZXIgZHluYW1pY2Fs bHksIGFuZAo+Pj4+IGZyZWUgYnVmZmVyIGFmdGVyIHJlcXVlc3QsIGl0J3MgcG9zc2libGUgdG8g b3B0aW1pemUgY29udHJvbCBxdWV1ZQo+Pj4+IGRlcHRoIGluIHRoZSBuZXh0IHN0ZXAuCj4+Pj4K Pj4+PiBBIG5lY2Vzc2FyeSBjb21tZW50IGlzIGFscmVhZHkgaW4gY29kZSwgc3RpbGwgZGVzY3Jp YmUgaXQgYWdhaW46Cj4+Pj4gLyoKPj4+PiAgICAqIE5vdGU6IHRoZXJlIGFyZSBwYWRkaW5nIGZp ZWxkcyBpbiByZXF1ZXN0LCBjbGVhciB0aGVtIHRvIHplcm8gYmVmb3JlCj4+Pj4gICAgKiBzZW5k aW5nIHRvIGhvc3QsCj4+Pj4gICAgKiBFeCwgdmlydGlvX2NyeXB0b19jdHJsX3JlcXVlc3Q6OmN0 cmw6OnU6OmRlc3Ryb3lfc2Vzc2lvbjo6cGFkZGluZ1s0OF0KPj4+PiAgICAqLwo+Pj4+IFNvIHVz ZSBremFsbG9jIHRvIGFsbG9jYXRlIGJ1ZmZlciBvZiBzdHJ1Y3QgdmlydGlvX2NyeXB0b19jdHJs X3JlcXVlc3QuCj4+Pj4KPj4+PiBDYzogTWljaGFlbCBTLiBUc2lya2luIDxtc3RAcmVkaGF0LmNv bT4KPj4+PiBDYzogSmFzb24gV2FuZyA8amFzb3dhbmdAcmVkaGF0LmNvbT4KPj4+PiBDYzogR29u Z2xlaSA8YXJlaS5nb25nbGVpQGh1YXdlaS5jb20+Cj4+Pj4gU2lnbmVkLW9mZi1ieTogemhlbndl aSBwaSA8cGl6aGVud2VpQGJ5dGVkYW5jZS5jb20+Cj4+Pj4gLS0tCj4+Pj4gICAgZHJpdmVycy9j cnlwdG8vdmlydGlvL01ha2VmaWxlICAgICAgICAgICAgICAgIHwgICAxICsKPj4+PiAgICAuLi4v dmlydGlvL3ZpcnRpb19jcnlwdG9fYWtjaXBoZXJfYWxncy5jICAgICAgfCAgOTAgKysrKysrLS0t LS0tCj4+Pj4gICAgZHJpdmVycy9jcnlwdG8vdmlydGlvL3ZpcnRpb19jcnlwdG9fY29tbW9uLmMg IHwgIDM5ICsrKysrCj4+Pgo+Pj4KPj4+IEFueSByZWFzb24gd2UgY2FuJ3QgdXNlIHZpcnRpb19j cnlwdG9fY29yZS5jPwo+Pj4KPj4gQW5vdGhlciBwYXRjaCBpbiB0aGlzIHNlcmllczogW1BBVENI IHYzIDMvNV0gdmlydGlvLWNyeXB0bzogbW92ZSBoZWxwZXJzCj4+IGludG8gdmlydGlvX2NyeXB0 b19jb21tb24uYwo+Pgo+PiBNb3ZlIHZpcnRjcnlwdG9fY2xlYXJfcmVxdWVzdCBhbmQgdmlydGNy eXB0b19kYXRhcV9jYWxsYmFjayBpbnRvCj4+IHZpcnRpb19jcnlwdG9fY29tbW9uLmMgdG8gbWFr ZSBjb2RlIGNsZWFyLiBUaGVuIHRoZSB4eF9jb3JlLmMKPj4gc3VwcG9ydHM6Cj4+ICAgICAtIHBy b2JlL3JlbW92ZS9pcnEgYWZmaW5pdHkgc2V0aW5nIGZvciBhIHZpcnRpbyBkZXZpY2UKPj4gICAg IC0gYmFzaWMgdmlydGlvIHJlbGF0ZWQgb3BlcmF0aW9ucwo+Pgo+PiB4eF9jb21tb24uYyBzdXBw b3J0czoKPj4gICAgIC0gY29tbW9uIGhlbHBlcnMvZnVuY3Rpb25zIGZvciBhbGdvcwo+Pgo+PiBT byBJIHB1dCB0aGlzIGludG8gYSBuZXcgZmlsZS4KPiAKPiBJIGRvbid0IHNlZSBvYnZpb3VzIGRp ZmZlcmVuY2VzIGJ1dCB3ZSBjYW4gbGVhdmUgaXQgdG8gdGhlCj4gdmlydGlvLWNyeXB0byBtYWlu dGFpbmVycyB0byBkZWNpZGUuCj4gCgpPSyEKPj4KPj4+Cj4+Pj4gICAgZHJpdmVycy9jcnlwdG8v dmlydGlvL3ZpcnRpb19jcnlwdG9fY29tbW9uLmggIHwgIDE5ICsrLQo+Pj4+ICAgIC4uLi92aXJ0 aW8vdmlydGlvX2NyeXB0b19za2NpcGhlcl9hbGdzLmMgICAgICB8IDEzMyArKysrKysrKy0tLS0t LS0tLS0KPj4+PiAgICA1IGZpbGVzIGNoYW5nZWQsIDE1NiBpbnNlcnRpb25zKCspLCAxMjYgZGVs ZXRpb25zKC0pCj4+Pj4gICAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvY3J5cHRvL3ZpcnRp by92aXJ0aW9fY3J5cHRvX2NvbW1vbi5jCj4+Pj4KPj4+PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9j cnlwdG8vdmlydGlvL01ha2VmaWxlCj4+Pj4gYi9kcml2ZXJzL2NyeXB0by92aXJ0aW8vTWFrZWZp bGUKPj4+PiBpbmRleCBiZmE2Y2JhZTM0MmUuLjQ5YzFmYTgwZTQ2NSAxMDA2NDQKPj4+PiAtLS0g YS9kcml2ZXJzL2NyeXB0by92aXJ0aW8vTWFrZWZpbGUKPj4+PiArKysgYi9kcml2ZXJzL2NyeXB0 by92aXJ0aW8vTWFrZWZpbGUKPj4+PiBAQCAtMyw1ICszLDYgQEAgb2JqLSQoQ09ORklHX0NSWVBU T19ERVZfVklSVElPKSArPSB2aXJ0aW9fY3J5cHRvLm8KPj4+PiAgICB2aXJ0aW9fY3J5cHRvLW9i anMgOj0gXAo+Pj4+ICAgICAgICB2aXJ0aW9fY3J5cHRvX3NrY2lwaGVyX2FsZ3MubyBcCj4+Pj4g ICAgICAgIHZpcnRpb19jcnlwdG9fYWtjaXBoZXJfYWxncy5vIFwKPj4+PiArICAgIHZpcnRpb19j cnlwdG9fY29tbW9uLm8gXAo+Pj4+ICAgICAgICB2aXJ0aW9fY3J5cHRvX21nci5vIFwKPj4+PiAg ICAgICAgdmlydGlvX2NyeXB0b19jb3JlLm8KPj4+PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9jcnlw dG8vdmlydGlvL3ZpcnRpb19jcnlwdG9fYWtjaXBoZXJfYWxncy5jCj4+Pj4gYi9kcml2ZXJzL2Ny eXB0by92aXJ0aW8vdmlydGlvX2NyeXB0b19ha2NpcGhlcl9hbGdzLmMKPj4+PiBpbmRleCBmM2Vj OTQyMDIxNWUuLjk1NjFiYzJkZjYyYiAxMDA2NDQKPj4+PiAtLS0gYS9kcml2ZXJzL2NyeXB0by92 aXJ0aW8vdmlydGlvX2NyeXB0b19ha2NpcGhlcl9hbGdzLmMKPj4+PiArKysgYi9kcml2ZXJzL2Ny eXB0by92aXJ0aW8vdmlydGlvX2NyeXB0b19ha2NpcGhlcl9hbGdzLmMKPj4+PiBAQCAtMTAyLDgg KzEwMiw4IEBAIHN0YXRpYyBpbnQKPj4+PiB2aXJ0aW9fY3J5cHRvX2FsZ19ha2NpcGhlcl9pbml0 X3Nlc3Npb24oc3RydWN0IHZpcnRpb19jcnlwdG9fYWtjaXBoZXIKPj4+PiAgICB7Cj4+Pj4gICAg ICAgIHN0cnVjdCBzY2F0dGVybGlzdCBvdXRoZHJfc2csIGtleV9zZywgaW5oZHJfc2csICpzZ3Nb M107Cj4+Pj4gICAgICAgIHN0cnVjdCB2aXJ0aW9fY3J5cHRvICp2Y3J5cHRvID0gY3R4LT52Y3J5 cHRvOwo+Pj4+ICsgICAgc3RydWN0IHZpcnRpb19jcnlwdG9fY3RybF9yZXF1ZXN0ICp2Y19jdHJs X3JlcTsKPj4+PiAgICAgICAgdWludDhfdCAqcGtleTsKPj4+PiAtICAgIHVuc2lnbmVkIGludCBp bmxlbjsKPj4+PiAgICAgICAgaW50IGVycjsKPj4+PiAgICAgICAgdW5zaWduZWQgaW50IG51bV9v dXQgPSAwLCBudW1faW4gPSAwOwo+Pj4+IEBAIC0xMTEsOTggKzExMSw5MSBAQCBzdGF0aWMgaW50 Cj4+Pj4gdmlydGlvX2NyeXB0b19hbGdfYWtjaXBoZXJfaW5pdF9zZXNzaW9uKHN0cnVjdCB2aXJ0 aW9fY3J5cHRvX2FrY2lwaGVyCj4+Pj4gICAgICAgIGlmICghcGtleSkKPj4+PiAgICAgICAgICAg IHJldHVybiAtRU5PTUVNOwo+Pj4+IC0gICAgc3Bpbl9sb2NrKCZ2Y3J5cHRvLT5jdHJsX2xvY2sp Owo+Pj4+IC0gICAgbWVtY3B5KCZ2Y3J5cHRvLT5jdHJsLmhlYWRlciwgaGVhZGVyLCBzaXplb2Yo dmNyeXB0by0+Y3RybC5oZWFkZXIpKTsKPj4+PiAtICAgIG1lbWNweSgmdmNyeXB0by0+Y3RybC51 LCBwYXJhLCBzaXplb2YodmNyeXB0by0+Y3RybC51KSk7Cj4+Pj4gLSAgICB2Y3J5cHRvLT5pbnB1 dC5zdGF0dXMgPSBjcHVfdG9fbGUzMihWSVJUSU9fQ1JZUFRPX0VSUik7Cj4+Pj4gKyAgICB2Y19j dHJsX3JlcSA9IGt6YWxsb2Moc2l6ZW9mKCp2Y19jdHJsX3JlcSksIEdGUF9LRVJORUwpOwo+Pj4+ ICsgICAgaWYgKCF2Y19jdHJsX3JlcSkgewo+Pj4+ICsgICAgICAgIGVyciA9IC1FTk9NRU07Cj4+ Pj4gKyAgICAgICAgZ290byBvdXQ7Cj4+Pj4gKyAgICB9Cj4+Pj4gLSAgICBzZ19pbml0X29uZSgm b3V0aGRyX3NnLCAmdmNyeXB0by0+Y3RybCwgc2l6ZW9mKHZjcnlwdG8tPmN0cmwpKTsKPj4+PiAr ICAgIG1lbWNweSgmdmNfY3RybF9yZXEtPmN0cmwuaGVhZGVyLCBoZWFkZXIsCj4+Pj4gc2l6ZW9m KHZjX2N0cmxfcmVxLT5jdHJsLmhlYWRlcikpOwo+Pj4+ICsgICAgbWVtY3B5KCZ2Y19jdHJsX3Jl cS0+Y3RybC51LCBwYXJhLCBzaXplb2YodmNfY3RybF9yZXEtPmN0cmwudSkpOwo+Pj4+ICsgICAg c2dfaW5pdF9vbmUoJm91dGhkcl9zZywgJnZjX2N0cmxfcmVxLT5jdHJsLAo+Pj4+IHNpemVvZih2 Y19jdHJsX3JlcS0+Y3RybCkpOwo+Pj4+ICAgICAgICBzZ3NbbnVtX291dCsrXSA9ICZvdXRoZHJf c2c7Cj4+Pj4gICAgICAgIHNnX2luaXRfb25lKCZrZXlfc2csIHBrZXksIGtleWxlbik7Cj4+Pj4g ICAgICAgIHNnc1tudW1fb3V0KytdID0gJmtleV9zZzsKPj4+PiAtICAgIHNnX2luaXRfb25lKCZp bmhkcl9zZywgJnZjcnlwdG8tPmlucHV0LCBzaXplb2YodmNyeXB0by0+aW5wdXQpKTsKPj4+PiAr ICAgIHZjX2N0cmxfcmVxLT5pbnB1dC5zdGF0dXMgPSBjcHVfdG9fbGUzMihWSVJUSU9fQ1JZUFRP X0VSUik7Cj4+Pgo+Pj4KPj4+IE5pdDogaWYgdGhlcmUncyBubyBzcGVjaWFsIHJlYXNvbiwgbGV0 J3MgbW92ZSB0aGlzIGFmdGVyIHRoZSBhYm92ZQo+Pj4gbWVtY3B5cyBhcyB3aGF0J3MgZG9uZSBw cmV2aW91c2x5Lgo+Pj4KPj4+Cj4+Pj4gKyAgICBzZ19pbml0X29uZSgmaW5oZHJfc2csICZ2Y19j dHJsX3JlcS0+aW5wdXQsCj4+Pj4gc2l6ZW9mKHZjX2N0cmxfcmVxLT5pbnB1dCkpOwo+Pj4+ICAg ICAgICBzZ3NbbnVtX291dCArIG51bV9pbisrXSA9ICZpbmhkcl9zZzsKPj4+PiAtICAgIGVyciA9 IHZpcnRxdWV1ZV9hZGRfc2dzKHZjcnlwdG8tPmN0cmxfdnEsIHNncywgbnVtX291dCwgbnVtX2lu LAo+Pj4+IHZjcnlwdG8sIEdGUF9BVE9NSUMpOwo+Pj4+ICsgICAgZXJyID0gdmlydGlvX2NyeXB0 b19jdHJsX3ZxX3JlcXVlc3QodmNyeXB0bywgc2dzLCBudW1fb3V0LAo+Pj4+IG51bV9pbiwgdmNf Y3RybF9yZXEpOwo+Pj4KPj4+Cj4+PiBJJ2Qgc3BsaXQgdGhpcyBpbnRvIGEgc2VwYXJhdGUgcGF0 Y2guCj4+Pgo+Pgo+PiBPSyEKPj4+Cj4+Pj4gICAgICAgIGlmIChlcnIgPCAwKQo+Pj4+ICAgICAg ICAgICAgZ290byBvdXQ7Cj4+Pj4gLSAgICB2aXJ0cXVldWVfa2ljayh2Y3J5cHRvLT5jdHJsX3Zx KTsKPj4+PiAtICAgIHdoaWxlICghdmlydHF1ZXVlX2dldF9idWYodmNyeXB0by0+Y3RybF92cSwg JmlubGVuKSAmJgo+Pj4+IC0gICAgICAgICAgICF2aXJ0cXVldWVfaXNfYnJva2VuKHZjcnlwdG8t PmN0cmxfdnEpKQo+Pj4+IC0gICAgICAgIGNwdV9yZWxheCgpOwo+Pj4+IC0KPj4+PiAtICAgIGlm IChsZTMyX3RvX2NwdSh2Y3J5cHRvLT5pbnB1dC5zdGF0dXMpICE9IFZJUlRJT19DUllQVE9fT0sp IHsKPj4+PiArICAgIGlmIChsZTMyX3RvX2NwdSh2Y19jdHJsX3JlcS0+aW5wdXQuc3RhdHVzKSAh PSBWSVJUSU9fQ1JZUFRPX09LKSB7Cj4+Pj4gKyAgICAgICAgcHJfZXJyKCJ2aXJ0aW9fY3J5cHRv OiBDcmVhdGUgc2Vzc2lvbiBmYWlsZWQgc3RhdHVzOiAldVxuIiwKPj4+PiArICAgICAgICAgICAg bGUzMl90b19jcHUodmNfY3RybF9yZXEtPmlucHV0LnN0YXR1cykpOwo+Pj4+ICAgICAgICAgICAg ZXJyID0gLUVJTlZBTDsKPj4+PiAgICAgICAgICAgIGdvdG8gb3V0Owo+Pj4+ICAgICAgICB9Cj4+ Pgo+Pj4KPj4+IERvIHdlIG5lZWQgYSB3YXJuaW5nIGZvciAtRU5PTUVNPwo+Pj4KPj4KPj4gTWVt b3J5KGVzcGVjaWFsbHkgc21hbGwgc2l6ZSkgYWxsb2NhdGlvbiBpcyB1bmxpa2VseSBjYXNlLCBJ IGFsc28gY2hlY2sKPj4gdGhlIHZpcnRpb19uZXQgYW5kIHZpcnRpb19ibGssIGJvdGggaGFuZGxl cyAtRU5PTUVNIG9ubHkgd2l0aG91dCBlcnJvcgo+PiByZXBvcnRpbmcuCj4gCj4gT2suCj4gCj4+ Cj4+Pgo+Pj4+IC0gICAgY3R4LT5zZXNzaW9uX2lkID0gbGU2NF90b19jcHUodmNyeXB0by0+aW5w dXQuc2Vzc2lvbl9pZCk7Cj4+Pj4gKyAgICBjdHgtPnNlc3Npb25faWQgPSBsZTY0X3RvX2NwdSh2 Y19jdHJsX3JlcS0+aW5wdXQuc2Vzc2lvbl9pZCk7Cj4+Pj4gICAgICAgIGN0eC0+c2Vzc2lvbl92 YWxpZCA9IHRydWU7Cj4+Pj4gICAgICAgIGVyciA9IDA7Cj4+Pj4gICAgb3V0Ogo+Pj4+IC0gICAg c3Bpbl91bmxvY2soJnZjcnlwdG8tPmN0cmxfbG9jayk7Cj4+Pj4gKyAgICBrZnJlZSh2Y19jdHJs X3JlcSk7Cj4+Pj4gICAgICAgIGtmcmVlX3NlbnNpdGl2ZShwa2V5KTsKPj4+PiAtICAgIGlmIChl cnIgPCAwKQo+Pj4+IC0gICAgICAgIHByX2VycigidmlydGlvX2NyeXB0bzogQ3JlYXRlIHNlc3Np b24gZmFpbGVkIHN0YXR1czogJXVcbiIsCj4+Pj4gLSAgICAgICAgICAgIGxlMzJfdG9fY3B1KHZj cnlwdG8tPmlucHV0LnN0YXR1cykpOwo+Pj4+IC0KPj4+PiAgICAgICAgcmV0dXJuIGVycjsKPj4+ PiAgICB9Cj4+Pj4gICAgc3RhdGljIGludCB2aXJ0aW9fY3J5cHRvX2FsZ19ha2NpcGhlcl9jbG9z ZV9zZXNzaW9uKHN0cnVjdAo+Pj4+IHZpcnRpb19jcnlwdG9fYWtjaXBoZXJfY3R4ICpjdHgpCj4+ Pj4gICAgewo+Pj4+ICAgICAgICBzdHJ1Y3Qgc2NhdHRlcmxpc3Qgb3V0aGRyX3NnLCBpbmhkcl9z ZywgKnNnc1syXTsKPj4+PiArICAgIHN0cnVjdCB2aXJ0aW9fY3J5cHRvX2N0cmxfcmVxdWVzdCAq dmNfY3RybF9yZXE7Cj4+Pj4gICAgICAgIHN0cnVjdCB2aXJ0aW9fY3J5cHRvX2Rlc3Ryb3lfc2Vz c2lvbl9yZXEgKmRlc3Ryb3lfc2Vzc2lvbjsKPj4+PiAgICAgICAgc3RydWN0IHZpcnRpb19jcnlw dG8gKnZjcnlwdG8gPSBjdHgtPnZjcnlwdG87Cj4+Pj4gLSAgICB1bnNpZ25lZCBpbnQgbnVtX291 dCA9IDAsIG51bV9pbiA9IDAsIGlubGVuOwo+Pj4+ICsgICAgdW5zaWduZWQgaW50IG51bV9vdXQg PSAwLCBudW1faW4gPSAwOwo+Pj4+ICAgICAgICBpbnQgZXJyOwo+Pj4+IC0gICAgc3Bpbl9sb2Nr KCZ2Y3J5cHRvLT5jdHJsX2xvY2spOwo+Pj4+IC0gICAgaWYgKCFjdHgtPnNlc3Npb25fdmFsaWQp IHsKPj4+PiAtICAgICAgICBlcnIgPSAwOwo+Pj4+IC0gICAgICAgIGdvdG8gb3V0Owo+Pj4+IC0g ICAgfQo+Pj4+IC0gICAgdmNyeXB0by0+Y3RybF9zdGF0dXMuc3RhdHVzID0gVklSVElPX0NSWVBU T19FUlI7Cj4+Pj4gLSAgICB2Y3J5cHRvLT5jdHJsLmhlYWRlci5vcGNvZGUgPQo+Pj4+IGNwdV90 b19sZTMyKFZJUlRJT19DUllQVE9fQUtDSVBIRVJfREVTVFJPWV9TRVNTSU9OKTsKPj4+PiAtICAg IHZjcnlwdG8tPmN0cmwuaGVhZGVyLnF1ZXVlX2lkID0gMDsKPj4+PiArICAgIGlmICghY3R4LT5z ZXNzaW9uX3ZhbGlkKQo+Pj4+ICsgICAgICAgIHJldHVybiAwOwo+Pj4+IC0gICAgZGVzdHJveV9z ZXNzaW9uID0gJnZjcnlwdG8tPmN0cmwudS5kZXN0cm95X3Nlc3Npb247Cj4+Pj4gKyAgICB2Y19j dHJsX3JlcSA9IGt6YWxsb2Moc2l6ZW9mKCp2Y19jdHJsX3JlcSksIEdGUF9LRVJORUwpOwo+Pj4+ ICsgICAgaWYgKCF2Y19jdHJsX3JlcSkKPj4+PiArICAgICAgICByZXR1cm4gLUVOT01FTTsKPj4+ PiArCj4+Pj4gKyAgICB2Y19jdHJsX3JlcS0+Y3RybC5oZWFkZXIub3Bjb2RlID0KPj4+PiBjcHVf dG9fbGUzMihWSVJUSU9fQ1JZUFRPX0FLQ0lQSEVSX0RFU1RST1lfU0VTU0lPTik7Cj4+Pj4gKyAg ICB2Y19jdHJsX3JlcS0+Y3RybC5oZWFkZXIucXVldWVfaWQgPSAwOwo+Pj4+ICsKPj4+PiArICAg IGRlc3Ryb3lfc2Vzc2lvbiA9ICZ2Y19jdHJsX3JlcS0+Y3RybC51LmRlc3Ryb3lfc2Vzc2lvbjsK Pj4+PiAgICAgICAgZGVzdHJveV9zZXNzaW9uLT5zZXNzaW9uX2lkID0gY3B1X3RvX2xlNjQoY3R4 LT5zZXNzaW9uX2lkKTsKPj4+PiAtICAgIHNnX2luaXRfb25lKCZvdXRoZHJfc2csICZ2Y3J5cHRv LT5jdHJsLCBzaXplb2YodmNyeXB0by0+Y3RybCkpOwo+Pj4+ICsgICAgc2dfaW5pdF9vbmUoJm91 dGhkcl9zZywgJnZjX2N0cmxfcmVxLT5jdHJsLAo+Pj4+IHNpemVvZih2Y19jdHJsX3JlcS0+Y3Ry bCkpOwo+Pj4+ICAgICAgICBzZ3NbbnVtX291dCsrXSA9ICZvdXRoZHJfc2c7Cj4+Pj4gLSAgICBz Z19pbml0X29uZSgmaW5oZHJfc2csICZ2Y3J5cHRvLT5jdHJsX3N0YXR1cy5zdGF0dXMsCj4+Pj4g c2l6ZW9mKHZjcnlwdG8tPmN0cmxfc3RhdHVzLnN0YXR1cykpOwo+Pj4+ICsgICAgdmNfY3RybF9y ZXEtPmN0cmxfc3RhdHVzLnN0YXR1cyA9IFZJUlRJT19DUllQVE9fRVJSOwo+Pj4KPj4+Cj4+PiBJ ZiBubyBzcGVjaWFsIHJlYXNvbiwgbGV0J3MgbW92ZSB0aGlzIGFib3ZlOgo+Pj4KPj4+IHZjX2N0 cmxfcmVxLT5jdHJsLmhlYWRlci5vcGNvZGUgPQo+Pj4gY3B1X3RvX2xlMzIoVklSVElPX0NSWVBU T19BS0NJUEhFUl9ERVNUUk9ZX1NFU1NJT04pOwo+Pj4KPj4KPj4gT0shCj4+Pgo+Pj4+ICsgICAg c2dfaW5pdF9vbmUoJmluaGRyX3NnLCAmdmNfY3RybF9yZXEtPmN0cmxfc3RhdHVzLnN0YXR1cywK Pj4+PiArICAgICAgICBzaXplb2YodmNfY3RybF9yZXEtPmN0cmxfc3RhdHVzLnN0YXR1cykpOwo+ Pj4+ICAgICAgICBzZ3NbbnVtX291dCArIG51bV9pbisrXSA9ICZpbmhkcl9zZzsKPj4+PiAtICAg IGVyciA9IHZpcnRxdWV1ZV9hZGRfc2dzKHZjcnlwdG8tPmN0cmxfdnEsIHNncywgbnVtX291dCwg bnVtX2luLAo+Pj4+IHZjcnlwdG8sIEdGUF9BVE9NSUMpOwo+Pj4+ICsgICAgZXJyID0gdmlydGlv X2NyeXB0b19jdHJsX3ZxX3JlcXVlc3QodmNyeXB0bywgc2dzLCBudW1fb3V0LAo+Pj4+IG51bV9p biwgdmNfY3RybF9yZXEpOwo+Pj4+ICAgICAgICBpZiAoZXJyIDwgMCkKPj4+PiAgICAgICAgICAg IGdvdG8gb3V0Owo+Pj4+IC0gICAgdmlydHF1ZXVlX2tpY2sodmNyeXB0by0+Y3RybF92cSk7Cj4+ Pj4gLSAgICB3aGlsZSAoIXZpcnRxdWV1ZV9nZXRfYnVmKHZjcnlwdG8tPmN0cmxfdnEsICZpbmxl bikgJiYKPj4+PiAtICAgICAgICAgICAhdmlydHF1ZXVlX2lzX2Jyb2tlbih2Y3J5cHRvLT5jdHJs X3ZxKSkKPj4+PiAtICAgICAgICBjcHVfcmVsYXgoKTsKPj4+PiAtCj4+Pj4gLSAgICBpZiAodmNy eXB0by0+Y3RybF9zdGF0dXMuc3RhdHVzICE9IFZJUlRJT19DUllQVE9fT0spIHsKPj4+PiArICAg IGlmICh2Y19jdHJsX3JlcS0+Y3RybF9zdGF0dXMuc3RhdHVzICE9IFZJUlRJT19DUllQVE9fT0sp IHsKPj4+PiAgICAgICAgICAgIGVyciA9IC1FSU5WQUw7Cj4+Pj4gKyAgICAgICAgcHJfZXJyKCJ2 aXJ0aW9fY3J5cHRvOiBDbG9zZSBzZXNzaW9uIGZhaWxlZCBzdGF0dXM6ICV1LAo+Pj4+IHNlc3Np b25faWQ6IDB4JWxseFxuIiwKPj4+PiArICAgICAgICAgICAgdmNfY3RybF9yZXEtPmN0cmxfc3Rh dHVzLnN0YXR1cywKPj4+PiBkZXN0cm95X3Nlc3Npb24tPnNlc3Npb25faWQpOwo+Pj4+ICAgICAg ICAgICAgZ290byBvdXQ7Cj4+Pj4gICAgICAgIH0KPj4+PiAgICAgICAgZXJyID0gMDsKPj4+PiAg ICAgICAgY3R4LT5zZXNzaW9uX3ZhbGlkID0gZmFsc2U7Cj4+Pj4gLQo+Pj4+ICAgIG91dDoKPj4+ PiAtICAgIHNwaW5fdW5sb2NrKCZ2Y3J5cHRvLT5jdHJsX2xvY2spOwo+Pj4+IC0gICAgaWYgKGVy ciA8IDApIHsKPj4+PiAtICAgICAgICBwcl9lcnIoInZpcnRpb19jcnlwdG86IENsb3NlIHNlc3Np b24gZmFpbGVkIHN0YXR1czogJXUsCj4+Pj4gc2Vzc2lvbl9pZDogMHglbGx4XG4iLAo+Pj4+IC0g ICAgICAgICAgICB2Y3J5cHRvLT5jdHJsX3N0YXR1cy5zdGF0dXMsIGRlc3Ryb3lfc2Vzc2lvbi0+ c2Vzc2lvbl9pZCk7Cj4+Pj4gLSAgICB9Cj4+Pj4gKyAgICBrZnJlZSh2Y19jdHJsX3JlcSk7Cj4+ Pj4gICAgICAgIHJldHVybiBlcnI7Cj4+Pj4gICAgfQo+Pj4+IEBAIC0yMTAsMTQgKzIwMywxMSBA QCBzdGF0aWMgaW50Cj4+Pj4gdmlydGlvX2NyeXB0b19hbGdfYWtjaXBoZXJfY2xvc2Vfc2Vzc2lv bihzdHJ1Y3QgdmlydGlvX2NyeXB0b19ha2NpcGhlCj4+Pj4gICAgc3RhdGljIGludCBfX3ZpcnRp b19jcnlwdG9fYWtjaXBoZXJfZG9fcmVxKHN0cnVjdAo+Pj4+IHZpcnRpb19jcnlwdG9fYWtjaXBo ZXJfcmVxdWVzdCAqdmNfYWtjaXBoZXJfcmVxLAo+Pj4+ICAgICAgICAgICAgc3RydWN0IGFrY2lw aGVyX3JlcXVlc3QgKnJlcSwgc3RydWN0IGRhdGFfcXVldWUgKmRhdGFfdnEpCj4+Pj4gICAgewo+ Pj4+IC0gICAgc3RydWN0IHZpcnRpb19jcnlwdG9fYWtjaXBoZXJfY3R4ICpjdHggPQo+Pj4+IHZj X2FrY2lwaGVyX3JlcS0+YWtjaXBoZXJfY3R4Owo+Pj4+ICAgICAgICBzdHJ1Y3QgdmlydGlvX2Ny eXB0b19yZXF1ZXN0ICp2Y19yZXEgPSAmdmNfYWtjaXBoZXJfcmVxLT5iYXNlOwo+Pj4+IC0gICAg c3RydWN0IHZpcnRpb19jcnlwdG8gKnZjcnlwdG8gPSBjdHgtPnZjcnlwdG87Cj4+Pj4gICAgICAg IHN0cnVjdCB2aXJ0aW9fY3J5cHRvX29wX2RhdGFfcmVxICpyZXFfZGF0YSA9IHZjX3JlcS0+cmVx X2RhdGE7Cj4+Pj4gICAgICAgIHN0cnVjdCBzY2F0dGVybGlzdCAqc2dzWzRdLCBvdXRoZHJfc2cs IGluaGRyX3NnLCBzcmNkYXRhX3NnLAo+Pj4+IGRzdGRhdGFfc2c7Cj4+Pj4gICAgICAgIHZvaWQg KnNyY19idWYgPSBOVUxMLCAqZHN0X2J1ZiA9IE5VTEw7Cj4+Pj4gICAgICAgIHVuc2lnbmVkIGlu dCBudW1fb3V0ID0gMCwgbnVtX2luID0gMDsKPj4+PiAtICAgIGludCBub2RlID0gZGV2X3RvX25v ZGUoJnZjcnlwdG8tPnZkZXYtPmRldik7Cj4+Pj4gICAgICAgIHVuc2lnbmVkIGxvbmcgZmxhZ3M7 Cj4+Pj4gICAgICAgIGludCByZXQgPSAtRU5PTUVNOwo+Pj4+ICAgICAgICBib29sIHZlcmlmeSA9 IHZjX2FrY2lwaGVyX3JlcS0+b3Bjb2RlID09Cj4+Pj4gVklSVElPX0NSWVBUT19BS0NJUEhFUl9W RVJJRlk7Cj4+Pj4gQEAgLTIyOCw3ICsyMTgsNyBAQCBzdGF0aWMgaW50IF9fdmlydGlvX2NyeXB0 b19ha2NpcGhlcl9kb19yZXEoc3RydWN0Cj4+Pj4gdmlydGlvX2NyeXB0b19ha2NpcGhlcl9yZXF1 ZXN0Cj4+Pj4gICAgICAgIHNnc1tudW1fb3V0KytdID0gJm91dGhkcl9zZzsKPj4+PiAgICAgICAg Lyogc3JjIGRhdGEgKi8KPj4+PiAtICAgIHNyY19idWYgPSBrY2FsbG9jX25vZGUoc3JjX2xlbiwg MSwgR0ZQX0tFUk5FTCwgbm9kZSk7Cj4+Pj4gKyAgICBzcmNfYnVmID0ga2NhbGxvYyhzcmNfbGVu LCAxLCBHRlBfS0VSTkVMKTsKPj4+Cj4+Pgo+Pj4gVGhpcyBzZWVtcyBub3QgYSByZWxldmFudCBj aGFuZ2UuIElmIGl0IGlzIGEgbXVzdCB3ZSBuZWVkIHVzZSBhIHNlcGFyYXRlCj4+PiBmb3IgdGhp cyBhbmQgZGVzY3JpYmUgdGhlIHJhdGlvbmFsZS4KPj4+Cj4+Pgo+Pj4+ICAgICAgICBpZiAoIXNy Y19idWYpCj4+Pj4gICAgICAgICAgICBnb3RvIGVycjsKPj4+PiBAQCAtMjQzLDcgKzIzMyw3IEBA IHN0YXRpYyBpbnQgX192aXJ0aW9fY3J5cHRvX2FrY2lwaGVyX2RvX3JlcShzdHJ1Y3QKPj4+PiB2 aXJ0aW9fY3J5cHRvX2FrY2lwaGVyX3JlcXVlc3QKPj4+PiAgICAgICAgICAgIHNnc1tudW1fb3V0 KytdID0gJnNyY2RhdGFfc2c7Cj4+Pj4gICAgICAgICAgICAvKiBkc3QgZGF0YSAqLwo+Pj4+IC0g ICAgICAgIGRzdF9idWYgPSBrY2FsbG9jX25vZGUocmVxLT5kc3RfbGVuLCAxLCBHRlBfS0VSTkVM LCBub2RlKTsKPj4+PiArICAgICAgICBkc3RfYnVmID0ga2NhbGxvYyhyZXEtPmRzdF9sZW4sIDEs IEdGUF9LRVJORUwpOwo+Pj4KPj4+Cj4+PiBBbmQgdGhpcy4KPj4+Cj4+Pgo+Pj4+ICAgICAgICAg ICAgaWYgKCFkc3RfYnVmKQo+Pj4+ICAgICAgICAgICAgICAgIGdvdG8gZXJyOwo+Pj4+IGRpZmYg LS1naXQgYS9kcml2ZXJzL2NyeXB0by92aXJ0aW8vdmlydGlvX2NyeXB0b19jb21tb24uYwo+Pj4+ IGIvZHJpdmVycy9jcnlwdG8vdmlydGlvL3ZpcnRpb19jcnlwdG9fY29tbW9uLmMKPj4+PiBuZXcg ZmlsZSBtb2RlIDEwMDY0NAo+Pj4+IGluZGV4IDAwMDAwMDAwMDAwMC4uZTY1MTI1YTc0ZGIyCj4+ Pj4gLS0tIC9kZXYvbnVsbAo+Pj4+ICsrKyBiL2RyaXZlcnMvY3J5cHRvL3ZpcnRpby92aXJ0aW9f Y3J5cHRvX2NvbW1vbi5jCj4+Pj4gQEAgLTAsMCArMSwzOSBAQAo+Pj4+ICsvLyBTUERYLUxpY2Vu c2UtSWRlbnRpZmllcjogR1BMLTIuMC1vci1sYXRlcgo+Pj4+ICsvKiBDb21tb24gZnVuY3Rpb25z IGFuZCBoZWxwZXJzCj4+Pj4gKyAqCj4+Pj4gKyAqIEF1dGhvcnM6IHpoZW53ZWkgcGkgPHBpemhl bndlaUBieXRlZGFuY2UuY29tPgo+Pj4+ICsgKgo+Pj4+ICsgKiBDb3B5cmlnaHQgMjAyMiBCeXRl ZGFuY2UgQ08uLCBMVEQuCj4+Pj4gKyAqLwo+Pj4+ICsKPj4+PiArI2luY2x1ZGUgInZpcnRpb19j cnlwdG9fY29tbW9uLmgiCj4+Pj4gKwo+Pj4+ICtpbnQgdmlydGlvX2NyeXB0b19jdHJsX3ZxX3Jl cXVlc3Qoc3RydWN0IHZpcnRpb19jcnlwdG8gKnZjcnlwdG8sCj4+Pj4gc3RydWN0IHNjYXR0ZXJs aXN0ICpzZ3NbXSwKPj4+PiArICAgICAgICAgICAgICAgICAgdW5zaWduZWQgaW50IG91dF9zZ3Ms IHVuc2lnbmVkIGludCBpbl9zZ3MsCj4+Pj4gKyAgICAgICAgICAgICAgICAgIHN0cnVjdCB2aXJ0 aW9fY3J5cHRvX2N0cmxfcmVxdWVzdCAqdmNfY3RybF9yZXEpCj4+Pj4gK3sKPj4+PiArICAgIGlu dCBlcnI7Cj4+Pj4gKyAgICB1bnNpZ25lZCBpbnQgaW5sZW47Cj4+Pj4gKyAgICB1bnNpZ25lZCBs b25nIGZsYWdzOwo+Pj4+ICsKPj4+PiArICAgIHNwaW5fbG9ja19pcnFzYXZlKCZ2Y3J5cHRvLT5j dHJsX2xvY2ssIGZsYWdzKTsKPj4+PiArICAgIGVyciA9IHZpcnRxdWV1ZV9hZGRfc2dzKHZjcnlw dG8tPmN0cmxfdnEsIHNncywgb3V0X3NncywgaW5fc2dzLAo+Pj4+IHZjX2N0cmxfcmVxLCBHRlBf QVRPTUlDKTsKPj4+PiArICAgIGlmIChlcnIgPCAwKSB7Cj4+Pj4gKyAgICAgICAgc3Bpbl91bmxv Y2tfaXJxcmVzdG9yZSgmdmNyeXB0by0+Y3RybF9sb2NrLCBmbGFncyk7Cj4+Pj4gKyAgICAgICAg cmV0dXJuIGVycjsKPj4+PiArICAgIH0KPj4+PiArCj4+Pj4gKyAgICB2aXJ0cXVldWVfa2ljayh2 Y3J5cHRvLT5jdHJsX3ZxKTsKPj4+PiArCj4+Pj4gKyAgICAvKgo+Pj4+ICsgICAgICogVHJhcHBp bmcgaW50byB0aGUgaHlwZXJ2aXNvciwgc28gdGhlIHJlcXVlc3Qgc2hvdWxkIGJlCj4+Pj4gKyAg ICAgKiBoYW5kbGVkIGltbWVkaWF0ZWx5Lgo+Pj4+ICsgICAgICovCj4+Pj4gKyAgICB3aGlsZSAo IXZpcnRxdWV1ZV9nZXRfYnVmKHZjcnlwdG8tPmN0cmxfdnEsICZpbmxlbikgJiYKPj4+PiArICAg ICAgICAhdmlydHF1ZXVlX2lzX2Jyb2tlbih2Y3J5cHRvLT5jdHJsX3ZxKSkKPj4+PiArICAgICAg ICBjcHVfcmVsYXgoKTsKPj4+PiArCj4+Pj4gKyAgICBzcGluX3VubG9ja19pcnFyZXN0b3JlKCZ2 Y3J5cHRvLT5jdHJsX2xvY2ssIGZsYWdzKTsKPj4+PiArCj4+Pj4gKyAgICByZXR1cm4gMDsKPj4+ PiArfQo+Pj4+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2NyeXB0by92aXJ0aW8vdmlydGlvX2NyeXB0 b19jb21tb24uaAo+Pj4+IGIvZHJpdmVycy9jcnlwdG8vdmlydGlvL3ZpcnRpb19jcnlwdG9fY29t bW9uLmgKPj4+PiBpbmRleCBlNjkzZDRlZTgzYTYuLmQyYTIwZmU2ZTEzZSAxMDA2NDQKPj4+PiAt LS0gYS9kcml2ZXJzL2NyeXB0by92aXJ0aW8vdmlydGlvX2NyeXB0b19jb21tb24uaAo+Pj4+ICsr KyBiL2RyaXZlcnMvY3J5cHRvL3ZpcnRpby92aXJ0aW9fY3J5cHRvX2NvbW1vbi5oCj4+Pj4gQEAg LTEzLDYgKzEzLDcgQEAKPj4+PiAgICAjaW5jbHVkZSA8Y3J5cHRvL2FlYWQuaD4KPj4+PiAgICAj aW5jbHVkZSA8Y3J5cHRvL2Flcy5oPgo+Pj4+ICAgICNpbmNsdWRlIDxjcnlwdG8vZW5naW5lLmg+ Cj4+Pj4gKyNpbmNsdWRlIDx1YXBpL2xpbnV4L3ZpcnRpb19jcnlwdG8uaD4KPj4+PiAgICAvKiBJ bnRlcm5hbCByZXByZXNlbnRhdGlvbiBvZiBhIGRhdGEgdmlydHF1ZXVlICovCj4+Pj4gQEAgLTY1 LDExICs2Niw2IEBAIHN0cnVjdCB2aXJ0aW9fY3J5cHRvIHsKPj4+PiAgICAgICAgLyogTWF4aW11 bSBzaXplIG9mIHBlciByZXF1ZXN0ICovCj4+Pj4gICAgICAgIHU2NCBtYXhfc2l6ZTsKPj4+PiAt ICAgIC8qIENvbnRyb2wgVlEgYnVmZmVyczogcHJvdGVjdGVkIGJ5IHRoZSBjdHJsX2xvY2sgKi8K Pj4+PiAtICAgIHN0cnVjdCB2aXJ0aW9fY3J5cHRvX29wX2N0cmxfcmVxIGN0cmw7Cj4+Pj4gLSAg ICBzdHJ1Y3QgdmlydGlvX2NyeXB0b19zZXNzaW9uX2lucHV0IGlucHV0Owo+Pj4+IC0gICAgc3Ry dWN0IHZpcnRpb19jcnlwdG9faW5oZHIgY3RybF9zdGF0dXM7Cj4+Pj4gLQo+Pj4+ICAgICAgICB1 bnNpZ25lZCBsb25nIHN0YXR1czsKPj4+PiAgICAgICAgYXRvbWljX3QgcmVmX2NvdW50Owo+Pj4+ ICAgICAgICBzdHJ1Y3QgbGlzdF9oZWFkIGxpc3Q7Cj4+Pj4gQEAgLTg1LDYgKzgxLDE2IEBAIHN0 cnVjdCB2aXJ0aW9fY3J5cHRvX3N5bV9zZXNzaW9uX2luZm8gewo+Pj4+ICAgICAgICBfX3U2NCBz ZXNzaW9uX2lkOwo+Pj4+ICAgIH07Cj4+Pj4gKy8qCj4+Pj4gKyAqIE5vdGU6IHRoZXJlIGFyZSBw YWRkaW5nIGZpZWxkcyBpbiByZXF1ZXN0LCBjbGVhciB0aGVtIHRvIHplcm8KPj4+PiBiZWZvcmUg c2VuZGluZyB0byBob3N0LAo+Pj4+ICsgKiBFeCwgdmlydGlvX2NyeXB0b19jdHJsX3JlcXVlc3Q6 OmN0cmw6OnU6OmRlc3Ryb3lfc2Vzc2lvbjo6cGFkZGluZ1s0OF0KPj4+PiArICovCj4+Pj4gK3N0 cnVjdCB2aXJ0aW9fY3J5cHRvX2N0cmxfcmVxdWVzdCB7Cj4+Pj4gKyAgICBzdHJ1Y3QgdmlydGlv X2NyeXB0b19vcF9jdHJsX3JlcSBjdHJsOwo+Pj4+ICsgICAgc3RydWN0IHZpcnRpb19jcnlwdG9f c2Vzc2lvbl9pbnB1dCBpbnB1dDsKPj4+PiArICAgIHN0cnVjdCB2aXJ0aW9fY3J5cHRvX2luaGRy IGN0cmxfc3RhdHVzOwo+Pj4+ICt9Owo+Pj4+ICsKPj4+PiAgICBzdHJ1Y3QgdmlydGlvX2NyeXB0 b19yZXF1ZXN0Owo+Pj4+ICAgIHR5cGVkZWYgdm9pZCAoKnZpcnRpb19jcnlwdG9fZGF0YV9jYWxs YmFjaykKPj4+PiAgICAgICAgICAgIChzdHJ1Y3QgdmlydGlvX2NyeXB0b19yZXF1ZXN0ICp2Y19y ZXEsIGludCBsZW4pOwo+Pj4+IEBAIC0xMzUsNCArMTQxLDcgQEAgdm9pZCB2aXJ0aW9fY3J5cHRv X3NrY2lwaGVyX2FsZ3NfdW5yZWdpc3RlcihzdHJ1Y3QKPj4+PiB2aXJ0aW9fY3J5cHRvICp2Y3J5 cHRvKTsKPj4+PiAgICBpbnQgdmlydGlvX2NyeXB0b19ha2NpcGhlcl9hbGdzX3JlZ2lzdGVyKHN0 cnVjdCB2aXJ0aW9fY3J5cHRvCj4+Pj4gKnZjcnlwdG8pOwo+Pj4+ICAgIHZvaWQgdmlydGlvX2Ny eXB0b19ha2NpcGhlcl9hbGdzX3VucmVnaXN0ZXIoc3RydWN0IHZpcnRpb19jcnlwdG8KPj4+PiAq dmNyeXB0byk7Cj4+Pj4gK2ludCB2aXJ0aW9fY3J5cHRvX2N0cmxfdnFfcmVxdWVzdChzdHJ1Y3Qg dmlydGlvX2NyeXB0byAqdmNyeXB0bywKPj4+PiBzdHJ1Y3Qgc2NhdHRlcmxpc3QgKnNnc1tdLAo+ Pj4+ICsgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgb3V0X3NncywgdW5zaWduZWQgaW50 IGluX3NncywKPj4+PiArICAgICAgICAgICAgICAgICAgc3RydWN0IHZpcnRpb19jcnlwdG9fY3Ry bF9yZXF1ZXN0ICp2Y19jdHJsX3JlcSk7Cj4+Pj4gICAgI2VuZGlmIC8qIF9WSVJUSU9fQ1JZUFRP X0NPTU1PTl9IICovCj4+Pj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvY3J5cHRvL3ZpcnRpby92aXJ0 aW9fY3J5cHRvX3NrY2lwaGVyX2FsZ3MuYwo+Pj4+IGIvZHJpdmVycy9jcnlwdG8vdmlydGlvL3Zp cnRpb19jcnlwdG9fc2tjaXBoZXJfYWxncy5jCj4+Pj4gaW5kZXggYTYxOGM0NmE1MmI4Li5mZWYz NTVmZjQ2MWMgMTAwNjQ0Cj4+Pj4gLS0tIGEvZHJpdmVycy9jcnlwdG8vdmlydGlvL3ZpcnRpb19j cnlwdG9fc2tjaXBoZXJfYWxncy5jCj4+Pj4gKysrIGIvZHJpdmVycy9jcnlwdG8vdmlydGlvL3Zp cnRpb19jcnlwdG9fc2tjaXBoZXJfYWxncy5jCj4+Pj4gQEAgLTExOCwxMSArMTE4LDEzIEBAIHN0 YXRpYyBpbnQgdmlydGlvX2NyeXB0b19hbGdfc2tjaXBoZXJfaW5pdF9zZXNzaW9uKAo+Pj4+ICAg ICAgICAgICAgaW50IGVuY3J5cHQpCj4+Pj4gICAgewo+Pj4+ICAgICAgICBzdHJ1Y3Qgc2NhdHRl cmxpc3Qgb3V0aGRyLCBrZXlfc2csIGluaGRyLCAqc2dzWzNdOwo+Pj4+IC0gICAgdW5zaWduZWQg aW50IHRtcDsKPj4+PiAgICAgICAgc3RydWN0IHZpcnRpb19jcnlwdG8gKnZjcnlwdG8gPSBjdHgt PnZjcnlwdG87Cj4+Pgo+Pj4KPj4+IENhbiB3ZSBzaW1wbHkgcmVuYW1lIHRoaXMgdG8gdmlydGNy eXB0byBhbmQgdGhlbiB3ZSBjYW4gdXNlIHRoZSBuYW1lCj4+PiAidmNyeXB0byIgZm9yIHZpcnRp b19jcnlwdG9fY3RybF9yZXF1ZXN0IHRoZW4gd2Ugc2F2ZSB0b25zIGxvdCBjaGFuZ2VzPwo+Pj4K Pj4+IEl0IHNpbXBsaWZ5IHRoZSBsaWZlIG9mIHJldmlld2VycyBhbmQgYmFja3BvcnRpbmcuCj4+ Pgo+Pj4gVGhhbmtzCj4+Pgo+Pgo+PiBUaGlzIHNlcmllcyBmb2N1c2VzIG9uIHBlcmZvcm1hbmNl IGltcHJvdm1lbnQsIGFuZCBrZWVwcyB0aGUgc3R5bGUgd2l0aAo+PiB0aGUgb3JpZ25hbCBzdHls ZS4gV2hhdCBhYm91dCBmaXhpbmcgdGhpcyBpbiBhbm90aGVyIHNlcmllcz8gKElmIHNvLAo+PiBJ J2xsIGZpeCB0aGlzIGxhdGVyKQo+IAo+IEp1c3QgaW4gY2FzZSB3ZSBhcmUgYXQgdGhlIHNhbWUg cGFnZSwgd2hhdCBJIHN1Z2dlc3QgY2FuIHNhdmUgaHVuZHJlZHMKPiBsaW5lcyBvZiBjb2RlczoK PiAKPiBFLmc6Cj4gCj4+Pj4gLSAgICB2Y3J5cHRvLT5jdHJsLmhlYWRlci5xdWV1ZV9pZCA9IDA7 Cj4+Pj4gKyAgICBoZWFkZXItPnF1ZXVlX2lkID0gMDsKPiAKPiBJZiB3ZSBzdGljayB0byB0aGUg bmFtZSBvZiAidmNyeXB0byIgd2UgZG9uJ3QgbmVlZCB0aGlzIGNoYW5nZSBhdCBhbGwuCj4gCj4g SXQgY2FuIHNpbXBsaWZ5Ogo+IAo+IDEpIGZ1dHVyZSBjb250ZXh0IGRpZmZlcmVuY2Ugd2hlbiBi YWNrcG9ydGluZyBwYXRjaGVzIHRvIC1zdGFibGUKPiAyKSByZXZpZXdpbmcKPiAKPiBUaGFua3MK PiAKCk9oLCBzb3JyeSwgSSBtaXN1bmRlcnN0b29kIHRoaXMuIEkgYWdyZWUgd2l0aCB0aGlzIHBv aW50LCBidXQgSSBub3RpY2UgCnRoYXQgJ3ZjcnlwdG8nIGlzIGFsd2F5cyBhIHZhcmlhYmxlIG9m ICd0eXBlIHN0cnVjdCB2aXJ0aW9fY3J5cHRvIConIGluIAp0aGlzIGRyaXZlciwgc2hvdWxkIHdl IGJyZWFrIHRoaXM/CgpUbyBzaW1wbGlmeSByZXZpZXdpbmcsIEkgaGF2ZSBhbm90aGVyIG9waW5p b24gaW4gdGhlIHY0IHNlcmllcywgY291bGQgCnlvdSBwbGVhc2UgcmV2aWV3IGl0PwoKPj4+Cj4+ Pj4gICAgICAgIGludCBvcCA9IGVuY3J5cHQgPyBWSVJUSU9fQ1JZUFRPX09QX0VOQ1JZUFQgOgo+ Pj4+IFZJUlRJT19DUllQVE9fT1BfREVDUllQVDsKPj4+PiAgICAgICAgaW50IGVycjsKPj4+PiAg ICAgICAgdW5zaWduZWQgaW50IG51bV9vdXQgPSAwLCBudW1faW4gPSAwOwo+Pj4+ICsgICAgc3Ry dWN0IHZpcnRpb19jcnlwdG9fY3RybF9yZXF1ZXN0ICp2Y19jdHJsX3JlcTsKPj4+PiArICAgIHN0 cnVjdCB2aXJ0aW9fY3J5cHRvX2N0cmxfaGVhZGVyICpoZWFkZXI7Cj4+Pj4gKyAgICBzdHJ1Y3Qg dmlydGlvX2NyeXB0b19zeW1fY3JlYXRlX3Nlc3Npb25fcmVxICpzeW1fY3JlYXRlX3Nlc3Npb247 Cj4+Pj4gICAgICAgIC8qCj4+Pj4gICAgICAgICAqIEF2b2lkIHRvIGRvIERNQSBmcm9tIHRoZSBz dGFjaywgc3dpdGNoIHRvIHVzaW5nCj4+Pj4gQEAgLTEzMywyNiArMTM1LDI3IEBAIHN0YXRpYyBp bnQgdmlydGlvX2NyeXB0b19hbGdfc2tjaXBoZXJfaW5pdF9zZXNzaW9uKAo+Pj4+ICAgICAgICBp ZiAoIWNpcGhlcl9rZXkpCj4+Pj4gICAgICAgICAgICByZXR1cm4gLUVOT01FTTsKPj4+PiAtICAg IHNwaW5fbG9jaygmdmNyeXB0by0+Y3RybF9sb2NrKTsKPj4+PiArICAgIHZjX2N0cmxfcmVxID0g a3phbGxvYyhzaXplb2YoKnZjX2N0cmxfcmVxKSwgR0ZQX0tFUk5FTCk7Cj4+Pj4gKyAgICBpZiAo IXZjX2N0cmxfcmVxKSB7Cj4+Pj4gKyAgICAgICAgZXJyID0gLUVOT01FTTsKPj4+PiArICAgICAg ICBnb3RvIG91dDsKPj4+PiArICAgIH0KPj4+PiArCj4+Pj4gICAgICAgIC8qIFBhZCBjdHJsIGhl YWRlciAqLwo+Pj4+IC0gICAgdmNyeXB0by0+Y3RybC5oZWFkZXIub3Bjb2RlID0KPj4+PiAtICAg ICAgICBjcHVfdG9fbGUzMihWSVJUSU9fQ1JZUFRPX0NJUEhFUl9DUkVBVEVfU0VTU0lPTik7Cj4+ Pj4gLSAgICB2Y3J5cHRvLT5jdHJsLmhlYWRlci5hbGdvID0gY3B1X3RvX2xlMzIoYWxnKTsKPj4+ PiArICAgIGhlYWRlciA9ICZ2Y19jdHJsX3JlcS0+Y3RybC5oZWFkZXI7Cj4+Pj4gKyAgICBoZWFk ZXItPm9wY29kZSA9IGNwdV90b19sZTMyKFZJUlRJT19DUllQVE9fQ0lQSEVSX0NSRUFURV9TRVNT SU9OKTsKPj4+PiArICAgIGhlYWRlci0+YWxnbyA9IGNwdV90b19sZTMyKGFsZyk7Cj4+Pj4gICAg ICAgIC8qIFNldCB0aGUgZGVmYXVsdCBkYXRhcXVldWUgaWQgdG8gMCAqLwo+Pj4+IC0gICAgdmNy eXB0by0+Y3RybC5oZWFkZXIucXVldWVfaWQgPSAwOwo+Pj4+ICsgICAgaGVhZGVyLT5xdWV1ZV9p ZCA9IDA7Cj4+Pj4gLSAgICB2Y3J5cHRvLT5pbnB1dC5zdGF0dXMgPSBjcHVfdG9fbGUzMihWSVJU SU9fQ1JZUFRPX0VSUik7Cj4+Pj4gICAgICAgIC8qIFBhZCBjaXBoZXIncyBwYXJhbWV0ZXJzICov Cj4+Pj4gLSAgICB2Y3J5cHRvLT5jdHJsLnUuc3ltX2NyZWF0ZV9zZXNzaW9uLm9wX3R5cGUgPQo+ Pj4+IC0gICAgICAgIGNwdV90b19sZTMyKFZJUlRJT19DUllQVE9fU1lNX09QX0NJUEhFUik7Cj4+ Pj4gLSAgICB2Y3J5cHRvLT5jdHJsLnUuc3ltX2NyZWF0ZV9zZXNzaW9uLnUuY2lwaGVyLnBhcmEu YWxnbyA9Cj4+Pj4gLSAgICAgICAgdmNyeXB0by0+Y3RybC5oZWFkZXIuYWxnbzsKPj4+PiAtICAg IHZjcnlwdG8tPmN0cmwudS5zeW1fY3JlYXRlX3Nlc3Npb24udS5jaXBoZXIucGFyYS5rZXlsZW4g PQo+Pj4+IC0gICAgICAgIGNwdV90b19sZTMyKGtleWxlbik7Cj4+Pj4gLSAgICB2Y3J5cHRvLT5j dHJsLnUuc3ltX2NyZWF0ZV9zZXNzaW9uLnUuY2lwaGVyLnBhcmEub3AgPQo+Pj4+IC0gICAgICAg IGNwdV90b19sZTMyKG9wKTsKPj4+PiAtCj4+Pj4gLSAgICBzZ19pbml0X29uZSgmb3V0aGRyLCAm dmNyeXB0by0+Y3RybCwgc2l6ZW9mKHZjcnlwdG8tPmN0cmwpKTsKPj4+PiArICAgIHN5bV9jcmVh dGVfc2Vzc2lvbiA9ICZ2Y19jdHJsX3JlcS0+Y3RybC51LnN5bV9jcmVhdGVfc2Vzc2lvbjsKPj4+ PiArICAgIHN5bV9jcmVhdGVfc2Vzc2lvbi0+b3BfdHlwZSA9Cj4+Pj4gY3B1X3RvX2xlMzIoVklS VElPX0NSWVBUT19TWU1fT1BfQ0lQSEVSKTsKPj4+PiArICAgIHN5bV9jcmVhdGVfc2Vzc2lvbi0+ dS5jaXBoZXIucGFyYS5hbGdvID0gaGVhZGVyLT5hbGdvOwo+Pj4+ICsgICAgc3ltX2NyZWF0ZV9z ZXNzaW9uLT51LmNpcGhlci5wYXJhLmtleWxlbiA9IGNwdV90b19sZTMyKGtleWxlbik7Cj4+Pj4g KyAgICBzeW1fY3JlYXRlX3Nlc3Npb24tPnUuY2lwaGVyLnBhcmEub3AgPSBjcHVfdG9fbGUzMihv cCk7Cj4+Pj4gKwo+Pj4+ICsgICAgc2dfaW5pdF9vbmUoJm91dGhkciwgJnZjX2N0cmxfcmVxLT5j dHJsLCBzaXplb2YodmNfY3RybF9yZXEtPmN0cmwpKTsKPj4+PiAgICAgICAgc2dzW251bV9vdXQr K10gPSAmb3V0aGRyOwo+Pj4+ICAgICAgICAvKiBTZXQga2V5ICovCj4+Pj4gQEAgLTE2MCw0NSAr MTYzLDM0IEBAIHN0YXRpYyBpbnQgdmlydGlvX2NyeXB0b19hbGdfc2tjaXBoZXJfaW5pdF9zZXNz aW9uKAo+Pj4+ICAgICAgICBzZ3NbbnVtX291dCsrXSA9ICZrZXlfc2c7Cj4+Pj4gICAgICAgIC8q IFJldHVybiBzdGF0dXMgYW5kIHNlc3Npb24gaWQgYmFjayAqLwo+Pj4+IC0gICAgc2dfaW5pdF9v bmUoJmluaGRyLCAmdmNyeXB0by0+aW5wdXQsIHNpemVvZih2Y3J5cHRvLT5pbnB1dCkpOwo+Pj4+ ICsgICAgdmNfY3RybF9yZXEtPmlucHV0LnN0YXR1cyA9IGNwdV90b19sZTMyKFZJUlRJT19DUllQ VE9fRVJSKTsKPj4+PiArICAgIHNnX2luaXRfb25lKCZpbmhkciwgJnZjX2N0cmxfcmVxLT5pbnB1 dCwKPj4+PiBzaXplb2YodmNfY3RybF9yZXEtPmlucHV0KSk7Cj4+Pj4gICAgICAgIHNnc1tudW1f b3V0ICsgbnVtX2luKytdID0gJmluaGRyOwo+Pj4+IC0gICAgZXJyID0gdmlydHF1ZXVlX2FkZF9z Z3ModmNyeXB0by0+Y3RybF92cSwgc2dzLCBudW1fb3V0LAo+Pj4+IC0gICAgICAgICAgICAgICAg bnVtX2luLCB2Y3J5cHRvLCBHRlBfQVRPTUlDKTsKPj4+PiAtICAgIGlmIChlcnIgPCAwKSB7Cj4+ Pj4gLSAgICAgICAgc3Bpbl91bmxvY2soJnZjcnlwdG8tPmN0cmxfbG9jayk7Cj4+Pj4gLSAgICAg ICAga2ZyZWVfc2Vuc2l0aXZlKGNpcGhlcl9rZXkpOwo+Pj4+IC0gICAgICAgIHJldHVybiBlcnI7 Cj4+Pj4gLSAgICB9Cj4+Pj4gLSAgICB2aXJ0cXVldWVfa2ljayh2Y3J5cHRvLT5jdHJsX3ZxKTsK Pj4+PiAtCj4+Pj4gLSAgICAvKgo+Pj4+IC0gICAgICogVHJhcHBpbmcgaW50byB0aGUgaHlwZXJ2 aXNvciwgc28gdGhlIHJlcXVlc3Qgc2hvdWxkIGJlCj4+Pj4gLSAgICAgKiBoYW5kbGVkIGltbWVk aWF0ZWx5Lgo+Pj4+IC0gICAgICovCj4+Pj4gLSAgICB3aGlsZSAoIXZpcnRxdWV1ZV9nZXRfYnVm KHZjcnlwdG8tPmN0cmxfdnEsICZ0bXApICYmCj4+Pj4gLSAgICAgICAgICAgIXZpcnRxdWV1ZV9p c19icm9rZW4odmNyeXB0by0+Y3RybF92cSkpCj4+Pj4gLSAgICAgICAgY3B1X3JlbGF4KCk7Cj4+ Pj4gKyAgICBlcnIgPSB2aXJ0aW9fY3J5cHRvX2N0cmxfdnFfcmVxdWVzdCh2Y3J5cHRvLCBzZ3Ms IG51bV9vdXQsCj4+Pj4gbnVtX2luLCB2Y19jdHJsX3JlcSk7Cj4+Pj4gKyAgICBpZiAoZXJyIDwg MCkKPj4+PiArICAgICAgICBnb3RvIG91dDsKPj4+PiAtICAgIGlmIChsZTMyX3RvX2NwdSh2Y3J5 cHRvLT5pbnB1dC5zdGF0dXMpICE9IFZJUlRJT19DUllQVE9fT0spIHsKPj4+PiAtICAgICAgICBz cGluX3VubG9jaygmdmNyeXB0by0+Y3RybF9sb2NrKTsKPj4+PiArICAgIGlmIChsZTMyX3RvX2Nw dSh2Y19jdHJsX3JlcS0+aW5wdXQuc3RhdHVzKSAhPSBWSVJUSU9fQ1JZUFRPX09LKSB7Cj4+Pj4g ICAgICAgICAgICBwcl9lcnIoInZpcnRpb19jcnlwdG86IENyZWF0ZSBzZXNzaW9uIGZhaWxlZCBz dGF0dXM6ICV1XG4iLAo+Pj4+IC0gICAgICAgICAgICBsZTMyX3RvX2NwdSh2Y3J5cHRvLT5pbnB1 dC5zdGF0dXMpKTsKPj4+PiAtICAgICAgICBrZnJlZV9zZW5zaXRpdmUoY2lwaGVyX2tleSk7Cj4+ Pj4gLSAgICAgICAgcmV0dXJuIC1FSU5WQUw7Cj4+Pj4gKyAgICAgICAgICAgIGxlMzJfdG9fY3B1 KHZjX2N0cmxfcmVxLT5pbnB1dC5zdGF0dXMpKTsKPj4+PiArICAgICAgICBlcnIgPSAtRUlOVkFM Owo+Pj4+ICsgICAgICAgIGdvdG8gb3V0Owo+Pj4+ICAgICAgICB9Cj4+Pj4gICAgICAgIGlmIChl bmNyeXB0KQo+Pj4+ICAgICAgICAgICAgY3R4LT5lbmNfc2Vzc19pbmZvLnNlc3Npb25faWQgPQo+ Pj4+IC0gICAgICAgICAgICBsZTY0X3RvX2NwdSh2Y3J5cHRvLT5pbnB1dC5zZXNzaW9uX2lkKTsK Pj4+PiArICAgICAgICAgICAgbGU2NF90b19jcHUodmNfY3RybF9yZXEtPmlucHV0LnNlc3Npb25f aWQpOwo+Pj4+ICAgICAgICBlbHNlCj4+Pj4gICAgICAgICAgICBjdHgtPmRlY19zZXNzX2luZm8u c2Vzc2lvbl9pZCA9Cj4+Pj4gLSAgICAgICAgICAgIGxlNjRfdG9fY3B1KHZjcnlwdG8tPmlucHV0 LnNlc3Npb25faWQpOwo+Pj4+IC0KPj4+PiAtICAgIHNwaW5fdW5sb2NrKCZ2Y3J5cHRvLT5jdHJs X2xvY2spOwo+Pj4+ICsgICAgICAgICAgICBsZTY0X3RvX2NwdSh2Y19jdHJsX3JlcS0+aW5wdXQu c2Vzc2lvbl9pZCk7Cj4+Pj4gKyAgICBlcnIgPSAwOwo+Pj4+ICtvdXQ6Cj4+Pj4gKyAgICBrZnJl ZSh2Y19jdHJsX3JlcSk7Cj4+Pj4gICAgICAgIGtmcmVlX3NlbnNpdGl2ZShjaXBoZXJfa2V5KTsK Pj4+PiAtICAgIHJldHVybiAwOwo+Pj4+ICsKPj4+PiArICAgIHJldHVybiBlcnI7Cj4+Pj4gICAg fQo+Pj4+ICAgIHN0YXRpYyBpbnQgdmlydGlvX2NyeXB0b19hbGdfc2tjaXBoZXJfY2xvc2Vfc2Vz c2lvbigKPj4+PiBAQCAtMjA2LDIxICsxOTgsMjQgQEAgc3RhdGljIGludAo+Pj4+IHZpcnRpb19j cnlwdG9fYWxnX3NrY2lwaGVyX2Nsb3NlX3Nlc3Npb24oCj4+Pj4gICAgICAgICAgICBpbnQgZW5j cnlwdCkKPj4+PiAgICB7Cj4+Pj4gICAgICAgIHN0cnVjdCBzY2F0dGVybGlzdCBvdXRoZHIsIHN0 YXR1c19zZywgKnNnc1syXTsKPj4+PiAtICAgIHVuc2lnbmVkIGludCB0bXA7Cj4+Pj4gICAgICAg IHN0cnVjdCB2aXJ0aW9fY3J5cHRvX2Rlc3Ryb3lfc2Vzc2lvbl9yZXEgKmRlc3Ryb3lfc2Vzc2lv bjsKPj4+PiAgICAgICAgc3RydWN0IHZpcnRpb19jcnlwdG8gKnZjcnlwdG8gPSBjdHgtPnZjcnlw dG87Cj4+Pj4gICAgICAgIGludCBlcnI7Cj4+Pj4gICAgICAgIHVuc2lnbmVkIGludCBudW1fb3V0 ID0gMCwgbnVtX2luID0gMDsKPj4+PiArICAgIHN0cnVjdCB2aXJ0aW9fY3J5cHRvX2N0cmxfcmVx dWVzdCAqdmNfY3RybF9yZXE7Cj4+Pj4gKyAgICBzdHJ1Y3QgdmlydGlvX2NyeXB0b19jdHJsX2hl YWRlciAqaGVhZGVyOwo+Pj4+ICsKPj4+PiArICAgIHZjX2N0cmxfcmVxID0ga3phbGxvYyhzaXpl b2YoKnZjX2N0cmxfcmVxKSwgR0ZQX0tFUk5FTCk7Cj4+Pj4gKyAgICBpZiAoIXZjX2N0cmxfcmVx KQo+Pj4+ICsgICAgICAgIHJldHVybiAtRU5PTUVNOwo+Pj4+IC0gICAgc3Bpbl9sb2NrKCZ2Y3J5 cHRvLT5jdHJsX2xvY2spOwo+Pj4+IC0gICAgdmNyeXB0by0+Y3RybF9zdGF0dXMuc3RhdHVzID0g VklSVElPX0NSWVBUT19FUlI7Cj4+Pj4gICAgICAgIC8qIFBhZCBjdHJsIGhlYWRlciAqLwo+Pj4+ IC0gICAgdmNyeXB0by0+Y3RybC5oZWFkZXIub3Bjb2RlID0KPj4+PiAtICAgICAgICBjcHVfdG9f bGUzMihWSVJUSU9fQ1JZUFRPX0NJUEhFUl9ERVNUUk9ZX1NFU1NJT04pOwo+Pj4+ICsgICAgaGVh ZGVyID0gJnZjX2N0cmxfcmVxLT5jdHJsLmhlYWRlcjsKPj4+PiArICAgIGhlYWRlci0+b3Bjb2Rl ID0gY3B1X3RvX2xlMzIoVklSVElPX0NSWVBUT19DSVBIRVJfREVTVFJPWV9TRVNTSU9OKTsKPj4+ PiAgICAgICAgLyogU2V0IHRoZSBkZWZhdWx0IHZpcnRxdWV1ZSBpZCB0byAwICovCj4+Pj4gLSAg ICB2Y3J5cHRvLT5jdHJsLmhlYWRlci5xdWV1ZV9pZCA9IDA7Cj4+Pj4gKyAgICBoZWFkZXItPnF1 ZXVlX2lkID0gMDsKPj4+PiAtICAgIGRlc3Ryb3lfc2Vzc2lvbiA9ICZ2Y3J5cHRvLT5jdHJsLnUu ZGVzdHJveV9zZXNzaW9uOwo+Pj4+ICsgICAgZGVzdHJveV9zZXNzaW9uID0gJnZjX2N0cmxfcmVx LT5jdHJsLnUuZGVzdHJveV9zZXNzaW9uOwo+Pj4+ICAgICAgICBpZiAoZW5jcnlwdCkKPj4+PiAg ICAgICAgICAgIGRlc3Ryb3lfc2Vzc2lvbi0+c2Vzc2lvbl9pZCA9Cj4+Pj4gQEAgLTIyOSwzNyAr MjI0LDMzIEBAIHN0YXRpYyBpbnQKPj4+PiB2aXJ0aW9fY3J5cHRvX2FsZ19za2NpcGhlcl9jbG9z ZV9zZXNzaW9uKAo+Pj4+ICAgICAgICAgICAgZGVzdHJveV9zZXNzaW9uLT5zZXNzaW9uX2lkID0K Pj4+PiAgICAgICAgICAgICAgICBjcHVfdG9fbGU2NChjdHgtPmRlY19zZXNzX2luZm8uc2Vzc2lv bl9pZCk7Cj4+Pj4gLSAgICBzZ19pbml0X29uZSgmb3V0aGRyLCAmdmNyeXB0by0+Y3RybCwgc2l6 ZW9mKHZjcnlwdG8tPmN0cmwpKTsKPj4+PiArICAgIHNnX2luaXRfb25lKCZvdXRoZHIsICZ2Y19j dHJsX3JlcS0+Y3RybCwgc2l6ZW9mKHZjX2N0cmxfcmVxLT5jdHJsKSk7Cj4+Pj4gICAgICAgIHNn c1tudW1fb3V0KytdID0gJm91dGhkcjsKPj4+PiAgICAgICAgLyogUmV0dXJuIHN0YXR1cyBhbmQg c2Vzc2lvbiBpZCBiYWNrICovCj4+Pj4gLSAgICBzZ19pbml0X29uZSgmc3RhdHVzX3NnLCAmdmNy eXB0by0+Y3RybF9zdGF0dXMuc3RhdHVzLAo+Pj4+IC0gICAgICAgIHNpemVvZih2Y3J5cHRvLT5j dHJsX3N0YXR1cy5zdGF0dXMpKTsKPj4+PiArICAgIHZjX2N0cmxfcmVxLT5jdHJsX3N0YXR1cy5z dGF0dXMgPSBWSVJUSU9fQ1JZUFRPX0VSUjsKPj4+PiArICAgIHNnX2luaXRfb25lKCZzdGF0dXNf c2csICZ2Y19jdHJsX3JlcS0+Y3RybF9zdGF0dXMuc3RhdHVzLAo+Pj4+ICsgICAgICAgIHNpemVv Zih2Y19jdHJsX3JlcS0+Y3RybF9zdGF0dXMuc3RhdHVzKSk7Cj4+Pj4gICAgICAgIHNnc1tudW1f b3V0ICsgbnVtX2luKytdID0gJnN0YXR1c19zZzsKPj4+PiAtICAgIGVyciA9IHZpcnRxdWV1ZV9h ZGRfc2dzKHZjcnlwdG8tPmN0cmxfdnEsIHNncywgbnVtX291dCwKPj4+PiAtICAgICAgICAgICAg bnVtX2luLCB2Y3J5cHRvLCBHRlBfQVRPTUlDKTsKPj4+PiAtICAgIGlmIChlcnIgPCAwKSB7Cj4+ Pj4gLSAgICAgICAgc3Bpbl91bmxvY2soJnZjcnlwdG8tPmN0cmxfbG9jayk7Cj4+Pj4gLSAgICAg ICAgcmV0dXJuIGVycjsKPj4+PiAtICAgIH0KPj4+PiAtICAgIHZpcnRxdWV1ZV9raWNrKHZjcnlw dG8tPmN0cmxfdnEpOwo+Pj4+IC0KPj4+PiAtICAgIHdoaWxlICghdmlydHF1ZXVlX2dldF9idWYo dmNyeXB0by0+Y3RybF92cSwgJnRtcCkgJiYKPj4+PiAtICAgICAgICAgICAhdmlydHF1ZXVlX2lz X2Jyb2tlbih2Y3J5cHRvLT5jdHJsX3ZxKSkKPj4+PiAtICAgICAgICBjcHVfcmVsYXgoKTsKPj4+ PiArICAgIGVyciA9IHZpcnRpb19jcnlwdG9fY3RybF92cV9yZXF1ZXN0KHZjcnlwdG8sIHNncywg bnVtX291dCwKPj4+PiBudW1faW4sIHZjX2N0cmxfcmVxKTsKPj4+PiArICAgIGlmIChlcnIgPCAw KQo+Pj4+ICsgICAgICAgIGdvdG8gb3V0Owo+Pj4+IC0gICAgaWYgKHZjcnlwdG8tPmN0cmxfc3Rh dHVzLnN0YXR1cyAhPSBWSVJUSU9fQ1JZUFRPX09LKSB7Cj4+Pj4gLSAgICAgICAgc3Bpbl91bmxv Y2soJnZjcnlwdG8tPmN0cmxfbG9jayk7Cj4+Pj4gKyAgICBpZiAodmNfY3RybF9yZXEtPmN0cmxf c3RhdHVzLnN0YXR1cyAhPSBWSVJUSU9fQ1JZUFRPX09LKSB7Cj4+Pj4gICAgICAgICAgICBwcl9l cnIoInZpcnRpb19jcnlwdG86IENsb3NlIHNlc3Npb24gZmFpbGVkIHN0YXR1czogJXUsCj4+Pj4g c2Vzc2lvbl9pZDogMHglbGx4XG4iLAo+Pj4+IC0gICAgICAgICAgICB2Y3J5cHRvLT5jdHJsX3N0 YXR1cy5zdGF0dXMsCj4+Pj4gKyAgICAgICAgICAgIHZjX2N0cmxfcmVxLT5jdHJsX3N0YXR1cy5z dGF0dXMsCj4+Pj4gICAgICAgICAgICAgICAgZGVzdHJveV9zZXNzaW9uLT5zZXNzaW9uX2lkKTsK Pj4+PiAtICAgICAgICByZXR1cm4gLUVJTlZBTDsKPj4+PiArICAgICAgICBlcnIgPSAtRUlOVkFM Owo+Pj4+ICsgICAgICAgIGdvdG8gb3V0Owo+Pj4+ICAgICAgICB9Cj4+Pj4gLSAgICBzcGluX3Vu bG9jaygmdmNyeXB0by0+Y3RybF9sb2NrKTsKPj4+PiAtICAgIHJldHVybiAwOwo+Pj4+ICsgICAg ZXJyID0gMDsKPj4+PiArb3V0Ogo+Pj4+ICsgICAga2ZyZWUodmNfY3RybF9yZXEpOwo+Pj4+ICsK Pj4+PiArICAgIHJldHVybiBlcnI7Cj4+Pj4gICAgfQo+Pj4+ICAgIHN0YXRpYyBpbnQgdmlydGlv X2NyeXB0b19hbGdfc2tjaXBoZXJfaW5pdF9zZXNzaW9ucygKPj4+Cj4+Cj4+IC0tCj4+IHpoZW53 ZWkgcGkKPj4KPiAKCi0tIAp6aGVud2VpIHBpCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fClZpcnR1YWxpemF0aW9uIG1haWxpbmcgbGlzdApWaXJ0dWFsaXph dGlvbkBsaXN0cy5saW51eC1mb3VuZGF0aW9uLm9yZwpodHRwczovL2xpc3RzLmxpbnV4Zm91bmRh dGlvbi5vcmcvbWFpbG1hbi9saXN0aW5mby92aXJ0dWFsaXphdGlvbg==