From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 1E32EA0553; Fri, 10 Jun 2022 16:27:34 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id BD12C4069C; Fri, 10 Jun 2022 16:27:33 +0200 (CEST) Received: from mail-wm1-f45.google.com (mail-wm1-f45.google.com [209.85.128.45]) by mails.dpdk.org (Postfix) with ESMTP id 4A48B40689 for ; Fri, 10 Jun 2022 16:27:32 +0200 (CEST) Received: by mail-wm1-f45.google.com with SMTP id m32-20020a05600c3b2000b0039756bb41f2so1149884wms.3 for ; Fri, 10 Jun 2022 07:27:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=E3vwSGofI34cL6G8RDU043CQG0f676XdQy3w/B7gef4=; b=nMp/Ftdb9VAbj43dB2ORv6flcZSOloLjlXUP2eOtEp8HyAbFfkr5fck32DGztbPiTA fQaLxkRvSxNsghSA23VscpFGJjS8ZAIlZi7/73bBLKDNMhah1rISQhl26Ep4OcZwa/Bn rBHARECTAwGAjfcmwMATAyxyKxVTWo+vIBVQoAXd5l9oFb8/4wWaHY1E1AdVLSQDmh1J J0fjd5NfqZdyGZv6lMwKAC531EjU7XMa5T4zwz9NqC3nfw9w65PSp1jzkK1+d/Zp9nm9 +z2BEr18VxegrwotArTt/HKCsDKd/MVyQmQbmvrDYI0EVi9A7+MGIR/X7mDwkg0Cojxs k1Xg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=E3vwSGofI34cL6G8RDU043CQG0f676XdQy3w/B7gef4=; b=5qMZUdyg1bjJoCjTTByVP2iNsiQiN1tXVFdy+63YquVgfdEeordLRs3GsxUKBX4Vdr mI2/0CHs7TPcPfxWyhCcsYIaResvhiQswRgSMVw0QXPpgGU6xd4dF+0k/erOvS0aLUuU 1p9O0ljBKxh4LcbBzmUDBez67SHbzO25bmEtECee0TE2UAhxxNj4aoRW/SN0KFn5lnki Juh8lK516TqvVlAACj/zhf2v0TidDW1KJYMPPpGz/NibNEC6zhakbSYn98WdsMlaROu6 zOUNIMcISCjxh8EwAJF7dH1n7KutQl4xdY9zwuAovDmqLCfXASN2QosO7bjqxB7Uoarv 6icQ== X-Gm-Message-State: AOAM531Zk8VgTXTdDYIcQtD+hwJuOe07zAaQVpe3JAG8khEovG9wLYk3 gm6ht1HPH8/MiWAuOju7CAYPIQtRacNNAXUyxbd7Rft5 X-Google-Smtp-Source: ABdhPJxkK/jeK+EOcDjtffoGY0xflvvrbOPD4VnOTCzfQR7wMABWYQpRQ1/uIjGL2se7kjfuHOYZRoBwgwQwjo5HXvc= X-Received: by 2002:a05:600c:6020:b0:39c:5cec:da86 with SMTP id az32-20020a05600c602000b0039c5cecda86mr22834wmb.75.1654871251794; Fri, 10 Jun 2022 07:27:31 -0700 (PDT) MIME-Version: 1.0 References: <20220610155216.81289-1-kevinx.liu@intel.com> <20220610162944.99526-1-kevinx.liu@intel.com> In-Reply-To: <20220610162944.99526-1-kevinx.liu@intel.com> From: Ben Magistro Date: Fri, 10 Jun 2022 10:27:20 -0400 Message-ID: Subject: Re: [PATCH v7] net/i40e: add outer VLAN processing To: Kevin Liu Cc: dev@dpdk.org, Yuying.Zhang@intel.com, beilei.xing@intel.com, stevex.yang@intel.com, Robin Zhang Content-Type: multipart/alternative; boundary="0000000000001cbdd205e118bd87" X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org --0000000000001cbdd205e118bd87 Content-Type: text/plain; charset="UTF-8" I'm trying to understand if this change is at all related to an issue we are experiencing with newer firmwares ( https://mails.dpdk.org/archives/dev/2022-April/238621.html) that happened to start with 8.4 and affected qinq offload processing. I can say loading this patch and running testpmd does not seem to have any effect on the issue we are experiencing. Side note, there is also a minor typo in the comment block "i40e_vlan_tpie_set" vs "i40e_vlan_tpid_set". Thanks On Fri, Jun 10, 2022 at 4:30 AM Kevin Liu wrote: > From: Robin Zhang > > Outer VLAN processing is supported after firmware v8.4, kernel driver > also change the default behavior to support this feature. To align with > kernel driver, add support for outer VLAN processing in DPDK. > > But it is forbidden for firmware to change the Inner/Outer VLAN > configuration while there are MAC/VLAN filters in the switch table. > Therefore, we need to clear the MAC table before setting config, > and then restore the MAC table after setting. > > This will not impact on an old firmware. > > Signed-off-by: Robin Zhang > Signed-off-by: Kevin Liu > --- > drivers/net/i40e/i40e_ethdev.c | 94 ++++++++++++++++++++++++++++++++-- > drivers/net/i40e/i40e_ethdev.h | 3 ++ > 2 files changed, 92 insertions(+), 5 deletions(-) > > diff --git a/drivers/net/i40e/i40e_ethdev.c > b/drivers/net/i40e/i40e_ethdev.c > index 755786dc10..4cae163cb9 100644 > --- a/drivers/net/i40e/i40e_ethdev.c > +++ b/drivers/net/i40e/i40e_ethdev.c > @@ -2575,6 +2575,7 @@ i40e_dev_close(struct rte_eth_dev *dev) > struct i40e_hw *hw = > I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); > struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); > struct rte_intr_handle *intr_handle = pci_dev->intr_handle; > + struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode; > struct i40e_filter_control_settings settings; > struct rte_flow *p_flow; > uint32_t reg; > @@ -2587,6 +2588,18 @@ i40e_dev_close(struct rte_eth_dev *dev) > if (rte_eal_process_type() != RTE_PROC_PRIMARY) > return 0; > > + /* > + * It is a workaround, if the double VLAN is disabled when > + * the program exits, an abnormal error will occur on the > + * NIC. Need to enable double VLAN when dev is closed. > + */ > + if (pf->fw8_3gt) { > + if (!(rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_EXTEND)) { > + rxmode->offloads |= RTE_ETH_RX_OFFLOAD_VLAN_EXTEND; > + i40e_vlan_offload_set(dev, > RTE_ETH_VLAN_EXTEND_MASK); > + } > + } > + > ret = rte_eth_switch_domain_free(pf->switch_domain_id); > if (ret) > PMD_INIT_LOG(WARNING, "failed to free switch domain: %d", > ret); > @@ -3909,6 +3922,7 @@ i40e_vlan_tpid_set(struct rte_eth_dev *dev, > struct i40e_pf *pf = > I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); > int qinq = dev->data->dev_conf.rxmode.offloads & > RTE_ETH_RX_OFFLOAD_VLAN_EXTEND; > + u16 sw_flags = 0, valid_flags = 0; > int ret = 0; > > if ((vlan_type != RTE_ETH_VLAN_TYPE_INNER && > @@ -3927,15 +3941,32 @@ i40e_vlan_tpid_set(struct rte_eth_dev *dev, > /* 802.1ad frames ability is added in NVM API 1.7*/ > if (hw->flags & I40E_HW_FLAG_802_1AD_CAPABLE) { > if (qinq) { > + if (pf->fw8_3gt) { > + sw_flags = > I40E_AQ_SET_SWITCH_CFG_OUTER_VLAN; > + valid_flags = > I40E_AQ_SET_SWITCH_CFG_OUTER_VLAN; > + } > if (vlan_type == RTE_ETH_VLAN_TYPE_OUTER) > hw->first_tag = rte_cpu_to_le_16(tpid); > else if (vlan_type == RTE_ETH_VLAN_TYPE_INNER) > hw->second_tag = rte_cpu_to_le_16(tpid); > } else { > - if (vlan_type == RTE_ETH_VLAN_TYPE_OUTER) > - hw->second_tag = rte_cpu_to_le_16(tpid); > + /* > + * If tpid is equal to 0x88A8, indicates that the > + * disable double VLAN operation is in progress. > + * Need set switch configuration back to default. > + */ > + if (pf->fw8_3gt && tpid == RTE_ETHER_TYPE_QINQ) { > + sw_flags = 0; > + valid_flags = > I40E_AQ_SET_SWITCH_CFG_OUTER_VLAN; > + if (vlan_type == RTE_ETH_VLAN_TYPE_OUTER) > + hw->first_tag = > rte_cpu_to_le_16(tpid); > + } else { > + if (vlan_type == RTE_ETH_VLAN_TYPE_OUTER) > + hw->second_tag = > rte_cpu_to_le_16(tpid); > + } > } > - ret = i40e_aq_set_switch_config(hw, 0, 0, 0, NULL); > + ret = i40e_aq_set_switch_config(hw, sw_flags, > + valid_flags, 0, NULL); > if (ret != I40E_SUCCESS) { > PMD_DRV_LOG(ERR, > "Set switch config failed aq_err: %d", > @@ -3987,8 +4018,13 @@ static int > i40e_vlan_offload_set(struct rte_eth_dev *dev, int mask) > { > struct i40e_pf *pf = > I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); > + struct i40e_mac_filter_info *mac_filter; > struct i40e_vsi *vsi = pf->main_vsi; > struct rte_eth_rxmode *rxmode; > + struct i40e_mac_filter *f; > + int i, num; > + void *temp; > + int ret; > > rxmode = &dev->data->dev_conf.rxmode; > if (mask & RTE_ETH_VLAN_FILTER_MASK) { > @@ -4007,6 +4043,33 @@ i40e_vlan_offload_set(struct rte_eth_dev *dev, int > mask) > } > > if (mask & RTE_ETH_VLAN_EXTEND_MASK) { > + i = 0; > + num = vsi->mac_num; > + mac_filter = rte_zmalloc("mac_filter_info_data", > + num * sizeof(*mac_filter), 0); > + if (mac_filter == NULL) { > + PMD_DRV_LOG(ERR, "failed to allocate memory"); > + return I40E_ERR_NO_MEMORY; > + } > + > + /* > + * Outer VLAN processing is supported after firmware v8.4, > kernel driver > + * also change the default behavior to support this > feature. To align with > + * kernel driver, set switch config in > 'i40e_vlan_tpie_set' to support for > + * outer VLAN processing. But it is forbidden for firmware > to change the > + * Inner/Outer VLAN configuration while there are MAC/VLAN > filters in the > + * switch table. Therefore, we need to clear the MAC table > before setting > + * config, and then restore the MAC table after setting. > This feature is > + * recommended to be used in firmware v8.6. > + */ > + /* Remove all existing mac */ > + RTE_TAILQ_FOREACH_SAFE(f, &vsi->mac_list, next, temp) { > + mac_filter[i] = f->mac_info; > + ret = i40e_vsi_delete_mac(vsi, > &f->mac_info.mac_addr); > + if (ret) > + PMD_DRV_LOG(ERR, "i40e vsi delete mac > fail."); > + i++; > + } > if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_EXTEND) { > i40e_vsi_config_double_vlan(vsi, TRUE); > /* Set global registers with default ethertype. */ > @@ -4014,9 +4077,19 @@ i40e_vlan_offload_set(struct rte_eth_dev *dev, int > mask) > RTE_ETHER_TYPE_VLAN); > i40e_vlan_tpid_set(dev, RTE_ETH_VLAN_TYPE_INNER, > RTE_ETHER_TYPE_VLAN); > - } > - else > + } else { > + if (pf->fw8_3gt) > + i40e_vlan_tpid_set(dev, > RTE_ETH_VLAN_TYPE_OUTER, > + RTE_ETHER_TYPE_QINQ); > i40e_vsi_config_double_vlan(vsi, FALSE); > + } > + /* Restore all mac */ > + for (i = 0; i < num; i++) { > + ret = i40e_vsi_add_mac(vsi, &mac_filter[i]); > + if (ret) > + PMD_DRV_LOG(ERR, "i40e vsi add mac fail."); > + } > + rte_free(mac_filter); > } > > if (mask & RTE_ETH_QINQ_STRIP_MASK) { > @@ -4846,6 +4919,17 @@ i40e_pf_parameter_init(struct rte_eth_dev *dev) > return -EINVAL; > } > > + /** > + * Enable outer VLAN processing if firmware version is greater > + * than v8.3 > + */ > + if (hw->aq.fw_maj_ver > 8 || > + (hw->aq.fw_maj_ver == 8 && hw->aq.fw_min_ver > 3)) { > + pf->fw8_3gt = true; > + } else { > + pf->fw8_3gt = false; > + } > + > return 0; > } > > diff --git a/drivers/net/i40e/i40e_ethdev.h > b/drivers/net/i40e/i40e_ethdev.h > index a1ebdc093c..fe943a45ff 100644 > --- a/drivers/net/i40e/i40e_ethdev.h > +++ b/drivers/net/i40e/i40e_ethdev.h > @@ -1188,6 +1188,9 @@ struct i40e_pf { > /* Switch Domain Id */ > uint16_t switch_domain_id; > > + /* When firmware > 8.3, the enable flag for outer VLAN processing > */ > + bool fw8_3gt; > + > struct i40e_vf_msg_cfg vf_msg_cfg; > uint64_t prev_rx_bytes; > uint64_t prev_tx_bytes; > -- > 2.34.1 > > --0000000000001cbdd205e118bd87 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: base64 PGRpdiBkaXI9Imx0ciI+SSYjMzk7bSB0cnlpbmcgdG8gdW5kZXJzdGFuZCBpZiB0aGlzIGNoYW5n ZSBpcyBhdCBhbGwgcmVsYXRlZCB0byBhbiBpc3N1ZSB3ZSBhcmUgZXhwZXJpZW5jaW5nIHdpdGgg bmV3ZXIgZmlybXdhcmVzICg8YSBocmVmPSJodHRwczovL21haWxzLmRwZGsub3JnL2FyY2hpdmVz L2Rldi8yMDIyLUFwcmlsLzIzODYyMS5odG1sIiB0YXJnZXQ9Il9ibGFuayI+aHR0cHM6Ly9tYWls cy5kcGRrLm9yZy9hcmNoaXZlcy9kZXYvMjAyMi1BcHJpbC8yMzg2MjEuaHRtbDwvYT4pIHRoYXQg aGFwcGVuZWQgdG8gc3RhcnQgd2l0aCA4LjQgYW5kIGFmZmVjdGVkIHFpbnEgb2ZmbG9hZCBwcm9j ZXNzaW5nLsKgIEkgY2FuIHNheSBsb2FkaW5nIHRoaXMgcGF0Y2ggYW5kIHJ1bm5pbmcgdGVzdHBt ZCBkb2VzIG5vdCBzZWVtIHRvIGhhdmUgYW55IGVmZmVjdCBvbiB0aGUgaXNzdWUgd2UgYXJlIGV4 cGVyaWVuY2luZy48ZGl2Pjxicj48L2Rpdj48ZGl2PlNpZGUgbm90ZSwgdGhlcmUgaXMgYWxzbyBh IG1pbm9yIHR5cG8gaW4gdGhlwqBjb21tZW50IGJsb2NrICZxdW90O2k0MGVfdmxhbl90cGllX3Nl dCZxdW90OyB2cyAmcXVvdDtpNDBlX3ZsYW5fdHBpZF9zZXQmcXVvdDsuPC9kaXY+PGRpdj48YnI+ PC9kaXY+PGRpdj5UaGFua3M8L2Rpdj48L2Rpdj48YnI+PGRpdiBjbGFzcz0iZ21haWxfcXVvdGUi PjxkaXYgZGlyPSJsdHIiIGNsYXNzPSJnbWFpbF9hdHRyIj5PbiBGcmksIEp1biAxMCwgMjAyMiBh dCA0OjMwIEFNIEtldmluIExpdSAmbHQ7PGEgaHJlZj0ibWFpbHRvOmtldmlueC5saXVAaW50ZWwu Y29tIiB0YXJnZXQ9Il9ibGFuayI+a2V2aW54LmxpdUBpbnRlbC5jb208L2E+Jmd0OyB3cm90ZTo8 YnI+PC9kaXY+PGJsb2NrcXVvdGUgY2xhc3M9ImdtYWlsX3F1b3RlIiBzdHlsZT0ibWFyZ2luOjBw eCAwcHggMHB4IDAuOGV4O2JvcmRlci1sZWZ0OjFweCBzb2xpZCByZ2IoMjA0LDIwNCwyMDQpO3Bh ZGRpbmctbGVmdDoxZXgiPkZyb206IFJvYmluIFpoYW5nICZsdDs8YSBocmVmPSJtYWlsdG86cm9i aW54LnpoYW5nQGludGVsLmNvbSIgdGFyZ2V0PSJfYmxhbmsiPnJvYmlueC56aGFuZ0BpbnRlbC5j b208L2E+Jmd0Ozxicj4NCjxicj4NCk91dGVyIFZMQU4gcHJvY2Vzc2luZyBpcyBzdXBwb3J0ZWQg YWZ0ZXIgZmlybXdhcmUgdjguNCwga2VybmVsIGRyaXZlcjxicj4NCmFsc28gY2hhbmdlIHRoZSBk ZWZhdWx0IGJlaGF2aW9yIHRvIHN1cHBvcnQgdGhpcyBmZWF0dXJlLiBUbyBhbGlnbiB3aXRoPGJy Pg0Ka2VybmVsIGRyaXZlciwgYWRkIHN1cHBvcnQgZm9yIG91dGVyIFZMQU4gcHJvY2Vzc2luZyBp biBEUERLLjxicj4NCjxicj4NCkJ1dCBpdCBpcyBmb3JiaWRkZW4gZm9yIGZpcm13YXJlIHRvIGNo YW5nZSB0aGUgSW5uZXIvT3V0ZXIgVkxBTjxicj4NCmNvbmZpZ3VyYXRpb24gd2hpbGUgdGhlcmUg YXJlIE1BQy9WTEFOIGZpbHRlcnMgaW4gdGhlIHN3aXRjaCB0YWJsZS48YnI+DQpUaGVyZWZvcmUs IHdlIG5lZWQgdG8gY2xlYXIgdGhlIE1BQyB0YWJsZSBiZWZvcmUgc2V0dGluZyBjb25maWcsPGJy Pg0KYW5kIHRoZW4gcmVzdG9yZSB0aGUgTUFDIHRhYmxlIGFmdGVyIHNldHRpbmcuPGJyPg0KPGJy Pg0KVGhpcyB3aWxsIG5vdCBpbXBhY3Qgb24gYW4gb2xkIGZpcm13YXJlLjxicj4NCjxicj4NClNp Z25lZC1vZmYtYnk6IFJvYmluIFpoYW5nICZsdDs8YSBocmVmPSJtYWlsdG86cm9iaW54LnpoYW5n QGludGVsLmNvbSIgdGFyZ2V0PSJfYmxhbmsiPnJvYmlueC56aGFuZ0BpbnRlbC5jb208L2E+Jmd0 Ozxicj4NClNpZ25lZC1vZmYtYnk6IEtldmluIExpdSAmbHQ7PGEgaHJlZj0ibWFpbHRvOmtldmlu eC5saXVAaW50ZWwuY29tIiB0YXJnZXQ9Il9ibGFuayI+a2V2aW54LmxpdUBpbnRlbC5jb208L2E+ Jmd0Ozxicj4NCi0tLTxicj4NCsKgZHJpdmVycy9uZXQvaTQwZS9pNDBlX2V0aGRldi5jIHwgOTQg KysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKystLTxicj4NCsKgZHJpdmVycy9uZXQvaTQw ZS9pNDBlX2V0aGRldi5oIHzCoCAzICsrPGJyPg0KwqAyIGZpbGVzIGNoYW5nZWQsIDkyIGluc2Vy dGlvbnMoKyksIDUgZGVsZXRpb25zKC0pPGJyPg0KPGJyPg0KZGlmZiAtLWdpdCBhL2RyaXZlcnMv bmV0L2k0MGUvaTQwZV9ldGhkZXYuYyBiL2RyaXZlcnMvbmV0L2k0MGUvaTQwZV9ldGhkZXYuYzxi cj4NCmluZGV4IDc1NTc4NmRjMTAuLjRjYWUxNjNjYjkgMTAwNjQ0PGJyPg0KLS0tIGEvZHJpdmVy cy9uZXQvaTQwZS9pNDBlX2V0aGRldi5jPGJyPg0KKysrIGIvZHJpdmVycy9uZXQvaTQwZS9pNDBl X2V0aGRldi5jPGJyPg0KQEAgLTI1NzUsNiArMjU3NSw3IEBAIGk0MGVfZGV2X2Nsb3NlKHN0cnVj dCBydGVfZXRoX2RldiAqZGV2KTxicj4NCsKgIMKgIMKgIMKgIHN0cnVjdCBpNDBlX2h3ICpodyA9 IEk0MEVfREVWX1BSSVZBVEVfVE9fSFcoZGV2LSZndDtkYXRhLSZndDtkZXZfcHJpdmF0ZSk7PGJy Pg0KwqAgwqAgwqAgwqAgc3RydWN0IHJ0ZV9wY2lfZGV2aWNlICpwY2lfZGV2ID0gUlRFX0VUSF9E RVZfVE9fUENJKGRldik7PGJyPg0KwqAgwqAgwqAgwqAgc3RydWN0IHJ0ZV9pbnRyX2hhbmRsZSAq aW50cl9oYW5kbGUgPSBwY2lfZGV2LSZndDtpbnRyX2hhbmRsZTs8YnI+DQorwqAgwqAgwqAgwqBz dHJ1Y3QgcnRlX2V0aF9yeG1vZGUgKnJ4bW9kZSA9ICZhbXA7ZGV2LSZndDtkYXRhLSZndDtkZXZf Y29uZi5yeG1vZGU7PGJyPg0KwqAgwqAgwqAgwqAgc3RydWN0IGk0MGVfZmlsdGVyX2NvbnRyb2xf c2V0dGluZ3Mgc2V0dGluZ3M7PGJyPg0KwqAgwqAgwqAgwqAgc3RydWN0IHJ0ZV9mbG93ICpwX2Zs b3c7PGJyPg0KwqAgwqAgwqAgwqAgdWludDMyX3QgcmVnOzxicj4NCkBAIC0yNTg3LDYgKzI1ODgs MTggQEAgaTQwZV9kZXZfY2xvc2Uoc3RydWN0IHJ0ZV9ldGhfZGV2ICpkZXYpPGJyPg0KwqAgwqAg wqAgwqAgaWYgKHJ0ZV9lYWxfcHJvY2Vzc190eXBlKCkgIT0gUlRFX1BST0NfUFJJTUFSWSk8YnI+ DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCByZXR1cm4gMDs8YnI+DQo8YnI+DQorwqAgwqAgwqAg wqAvKjxicj4NCivCoCDCoCDCoCDCoCAqIEl0IGlzIGEgd29ya2Fyb3VuZCwgaWYgdGhlIGRvdWJs ZSBWTEFOIGlzIGRpc2FibGVkIHdoZW48YnI+DQorwqAgwqAgwqAgwqAgKiB0aGUgcHJvZ3JhbSBl eGl0cywgYW4gYWJub3JtYWwgZXJyb3Igd2lsbCBvY2N1ciBvbiB0aGU8YnI+DQorwqAgwqAgwqAg wqAgKiBOSUMuIE5lZWQgdG8gZW5hYmxlIGRvdWJsZSBWTEFOIHdoZW4gZGV2IGlzIGNsb3NlZC48 YnI+DQorwqAgwqAgwqAgwqAgKi88YnI+DQorwqAgwqAgwqAgwqBpZiAocGYtJmd0O2Z3OF8zZ3Qp IHs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBpZiAoIShyeG1vZGUtJmd0O29mZmxvYWRz ICZhbXA7IFJURV9FVEhfUlhfT0ZGTE9BRF9WTEFOX0VYVEVORCkpIHs8YnI+DQorwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqByeG1vZGUtJmd0O29mZmxvYWRzIHw9IFJURV9FVEhf UlhfT0ZGTE9BRF9WTEFOX0VYVEVORDs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqBpNDBlX3ZsYW5fb2ZmbG9hZF9zZXQoZGV2LCBSVEVfRVRIX1ZMQU5fRVhURU5EX01B U0spOzxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoH08YnI+DQorwqAgwqAgwqAgwqB9PGJy Pg0KKzxicj4NCsKgIMKgIMKgIMKgIHJldCA9IHJ0ZV9ldGhfc3dpdGNoX2RvbWFpbl9mcmVlKHBm LSZndDtzd2l0Y2hfZG9tYWluX2lkKTs8YnI+DQrCoCDCoCDCoCDCoCBpZiAocmV0KTxicj4NCsKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIFBNRF9JTklUX0xPRyhXQVJOSU5HLCAmcXVvdDtmYWlsZWQg dG8gZnJlZSBzd2l0Y2ggZG9tYWluOiAlZCZxdW90OywgcmV0KTs8YnI+DQpAQCAtMzkwOSw2ICsz OTIyLDcgQEAgaTQwZV92bGFuX3RwaWRfc2V0KHN0cnVjdCBydGVfZXRoX2RldiAqZGV2LDxicj4N CsKgIMKgIMKgIMKgIHN0cnVjdCBpNDBlX3BmICpwZiA9IEk0MEVfREVWX1BSSVZBVEVfVE9fUEYo ZGV2LSZndDtkYXRhLSZndDtkZXZfcHJpdmF0ZSk7PGJyPg0KwqAgwqAgwqAgwqAgaW50IHFpbnEg PSBkZXYtJmd0O2RhdGEtJmd0O2Rldl9jb25mLnJ4bW9kZS5vZmZsb2FkcyAmYW1wOzxicj4NCsKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgUlRFX0VUSF9SWF9PRkZMT0FEX1ZMQU5fRVhURU5E Ozxicj4NCivCoCDCoCDCoCDCoHUxNiBzd19mbGFncyA9IDAsIHZhbGlkX2ZsYWdzID0gMDs8YnI+ DQrCoCDCoCDCoCDCoCBpbnQgcmV0ID0gMDs8YnI+DQo8YnI+DQrCoCDCoCDCoCDCoCBpZiAoKHZs YW5fdHlwZSAhPSBSVEVfRVRIX1ZMQU5fVFlQRV9JTk5FUiAmYW1wOyZhbXA7PGJyPg0KQEAgLTM5 MjcsMTUgKzM5NDEsMzIgQEAgaTQwZV92bGFuX3RwaWRfc2V0KHN0cnVjdCBydGVfZXRoX2RldiAq ZGV2LDxicj4NCsKgIMKgIMKgIMKgIC8qIDgwMi4xYWQgZnJhbWVzIGFiaWxpdHkgaXMgYWRkZWQg aW4gTlZNIEFQSSAxLjcqLzxicj4NCsKgIMKgIMKgIMKgIGlmIChody0mZ3Q7ZmxhZ3MgJmFtcDsg STQwRV9IV19GTEFHXzgwMl8xQURfQ0FQQUJMRSkgezxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIGlmIChxaW5xKSB7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg aWYgKHBmLSZndDtmdzhfM2d0KSB7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgc3dfZmxhZ3MgPSBJNDBFX0FRX1NFVF9TV0lUQ0hfQ0ZHX09VVEVS X1ZMQU47PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgdmFsaWRfZmxhZ3MgPSBJNDBFX0FRX1NFVF9TV0lUQ0hfQ0ZHX09VVEVSX1ZMQU47PGJyPg0K K8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgfTxicj4NCsKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIGlmICh2bGFuX3R5cGUgPT0gUlRFX0VUSF9WTEFOX1RZUEVf T1VURVIpPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgaHctJmd0O2ZpcnN0X3RhZyA9IHJ0ZV9jcHVfdG9fbGVfMTYodHBpZCk7PGJyPg0KwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgZWxzZSBpZiAodmxhbl90eXBlID09IFJURV9F VEhfVkxBTl9UWVBFX0lOTkVSKTxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIGh3LSZndDtzZWNvbmRfdGFnID0gcnRlX2NwdV90b19sZV8xNih0cGlk KTs8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCB9IGVsc2Ugezxicj4NCi3CoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGlmICh2bGFuX3R5cGUgPT0gUlRFX0VUSF9WTEFOX1RZ UEVfT1VURVIpPGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgaHctJmd0O3NlY29uZF90YWcgPSBydGVfY3B1X3RvX2xlXzE2KHRwaWQpOzxicj4NCivC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoC8qPGJyPg0KK8KgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgICogSWYgdHBpZCBpcyBlcXVhbCB0byAweDg4QTgsIGluZGlj YXRlcyB0aGF0IHRoZTxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAq IGRpc2FibGUgZG91YmxlIFZMQU4gb3BlcmF0aW9uIGlzIGluIHByb2dyZXNzLjxicj4NCivCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAqIE5lZWQgc2V0IHN3aXRjaCBjb25maWd1 cmF0aW9uIGJhY2sgdG8gZGVmYXVsdC48YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgKi88YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBpZiAo cGYtJmd0O2Z3OF8zZ3QgJmFtcDsmYW1wOyB0cGlkID09IFJURV9FVEhFUl9UWVBFX1FJTlEpIHs8 YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBzd19m bGFncyA9IDA7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgdmFsaWRfZmxhZ3MgPSBJNDBFX0FRX1NFVF9TV0lUQ0hfQ0ZHX09VVEVSX1ZMQU47PGJy Pg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgaWYgKHZs YW5fdHlwZSA9PSBSVEVfRVRIX1ZMQU5fVFlQRV9PVVRFUik8YnI+DQorwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBody0mZ3Q7Zmlyc3Rf dGFnID0gcnRlX2NwdV90b19sZV8xNih0cGlkKTs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqB9IGVsc2Ugezxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoGlmICh2bGFuX3R5cGUgPT0gUlRFX0VUSF9WTEFOX1RZUEVfT1VU RVIpPGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgaHctJmd0O3NlY29uZF90YWcgPSBydGVfY3B1X3RvX2xlXzE2KHRwaWQpOzxi cj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoH08YnI+DQrCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCB9PGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgcmV0ID0gaTQwZV9h cV9zZXRfc3dpdGNoX2NvbmZpZyhodywgMCwgMCwgMCwgTlVMTCk7PGJyPg0KK8KgIMKgIMKgIMKg IMKgIMKgIMKgIMKgcmV0ID0gaTQwZV9hcV9zZXRfc3dpdGNoX2NvbmZpZyhodywgc3dfZmxhZ3Ms PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgdmFsaWRfZmxhZ3MsIDAsIE5VTEwpOzxicj4NCsKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIGlmIChyZXQgIT0gSTQwRV9TVUNDRVNTKSB7PGJyPg0KwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgUE1EX0RSVl9MT0coRVJSLDxicj4NCsKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgICZxdW90O1NldCBz d2l0Y2ggY29uZmlnIGZhaWxlZCBhcV9lcnI6ICVkJnF1b3Q7LDxicj4NCkBAIC0zOTg3LDggKzQw MTgsMTMgQEAgc3RhdGljIGludDxicj4NCsKgaTQwZV92bGFuX29mZmxvYWRfc2V0KHN0cnVjdCBy dGVfZXRoX2RldiAqZGV2LCBpbnQgbWFzayk8YnI+DQrCoHs8YnI+DQrCoCDCoCDCoCDCoCBzdHJ1 Y3QgaTQwZV9wZiAqcGYgPSBJNDBFX0RFVl9QUklWQVRFX1RPX1BGKGRldi0mZ3Q7ZGF0YS0mZ3Q7 ZGV2X3ByaXZhdGUpOzxicj4NCivCoCDCoCDCoCDCoHN0cnVjdCBpNDBlX21hY19maWx0ZXJfaW5m byAqbWFjX2ZpbHRlcjs8YnI+DQrCoCDCoCDCoCDCoCBzdHJ1Y3QgaTQwZV92c2kgKnZzaSA9IHBm LSZndDttYWluX3ZzaTs8YnI+DQrCoCDCoCDCoCDCoCBzdHJ1Y3QgcnRlX2V0aF9yeG1vZGUgKnJ4 bW9kZTs8YnI+DQorwqAgwqAgwqAgwqBzdHJ1Y3QgaTQwZV9tYWNfZmlsdGVyICpmOzxicj4NCivC oCDCoCDCoCDCoGludCBpLCBudW07PGJyPg0KK8KgIMKgIMKgIMKgdm9pZCAqdGVtcDs8YnI+DQor wqAgwqAgwqAgwqBpbnQgcmV0Ozxicj4NCjxicj4NCsKgIMKgIMKgIMKgIHJ4bW9kZSA9ICZhbXA7 ZGV2LSZndDtkYXRhLSZndDtkZXZfY29uZi5yeG1vZGU7PGJyPg0KwqAgwqAgwqAgwqAgaWYgKG1h c2sgJmFtcDsgUlRFX0VUSF9WTEFOX0ZJTFRFUl9NQVNLKSB7PGJyPg0KQEAgLTQwMDcsNiArNDA0 MywzMyBAQCBpNDBlX3ZsYW5fb2ZmbG9hZF9zZXQoc3RydWN0IHJ0ZV9ldGhfZGV2ICpkZXYsIGlu dCBtYXNrKTxicj4NCsKgIMKgIMKgIMKgIH08YnI+DQo8YnI+DQrCoCDCoCDCoCDCoCBpZiAobWFz ayAmYW1wOyBSVEVfRVRIX1ZMQU5fRVhURU5EX01BU0spIHs8YnI+DQorwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqBpID0gMDs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBudW0gPSB2c2ktJmd0 O21hY19udW07PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgbWFjX2ZpbHRlciA9IHJ0ZV96 bWFsbG9jKCZxdW90O21hY19maWx0ZXJfaW5mb19kYXRhJnF1b3Q7LDxicj4NCivCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBudW0gKiBzaXplb2YoKm1hY19m aWx0ZXIpLCAwKTs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBpZiAobWFjX2ZpbHRlciA9 PSBOVUxMKSB7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgUE1EX0RS Vl9MT0coRVJSLCAmcXVvdDtmYWlsZWQgdG8gYWxsb2NhdGUgbWVtb3J5JnF1b3Q7KTs8YnI+DQor wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqByZXR1cm4gSTQwRV9FUlJfTk9fTUVN T1JZOzxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoH08YnI+DQorPGJyPg0KK8KgIMKgIMKg IMKgIMKgIMKgIMKgIMKgLyo8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgKiBPdXRlciBW TEFOIHByb2Nlc3NpbmcgaXMgc3VwcG9ydGVkIGFmdGVyIGZpcm13YXJlIHY4LjQsIGtlcm5lbCBk cml2ZXI8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgKiBhbHNvIGNoYW5nZSB0aGUgZGVm YXVsdCBiZWhhdmlvciB0byBzdXBwb3J0IHRoaXMgZmVhdHVyZS4gVG8gYWxpZ24gd2l0aDxicj4N CivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAqIGtlcm5lbCBkcml2ZXIsIHNldCBzd2l0Y2ggY29u ZmlnIGluICYjMzk7aTQwZV92bGFuX3RwaWVfc2V0JiMzOTsgdG8gc3VwcG9ydCBmb3I8YnI+DQor wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgKiBvdXRlciBWTEFOIHByb2Nlc3NpbmcuIEJ1dCBpdCBp cyBmb3JiaWRkZW4gZm9yIGZpcm13YXJlIHRvIGNoYW5nZSB0aGU8YnI+DQorwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgKiBJbm5lci9PdXRlciBWTEFOIGNvbmZpZ3VyYXRpb24gd2hpbGUgdGhlcmUg YXJlIE1BQy9WTEFOIGZpbHRlcnMgaW4gdGhlPGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKg ICogc3dpdGNoIHRhYmxlLiBUaGVyZWZvcmUsIHdlIG5lZWQgdG8gY2xlYXIgdGhlIE1BQyB0YWJs ZSBiZWZvcmUgc2V0dGluZzxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAqIGNvbmZpZywg YW5kIHRoZW4gcmVzdG9yZSB0aGUgTUFDIHRhYmxlIGFmdGVyIHNldHRpbmcuIFRoaXMgZmVhdHVy ZSBpczxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAqIHJlY29tbWVuZGVkIHRvIGJlIHVz ZWQgaW4gZmlybXdhcmUgdjguNi48YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgKi88YnI+ DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAvKiBSZW1vdmUgYWxsIGV4aXN0aW5nIG1hYyAqLzxi cj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoFJURV9UQUlMUV9GT1JFQUNIX1NBRkUoZiwgJmFt cDt2c2ktJmd0O21hY19saXN0LCBuZXh0LCB0ZW1wKSB7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgbWFjX2ZpbHRlcltpXSA9IGYtJmd0O21hY19pbmZvOzxicj4NCivC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHJldCA9IGk0MGVfdnNpX2RlbGV0ZV9t YWModnNpLCAmYW1wO2YtJmd0O21hY19pbmZvLm1hY19hZGRyKTs8YnI+DQorwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBpZiAocmV0KTxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoFBNRF9EUlZfTE9HKEVSUiwgJnF1b3Q7aTQwZSB2 c2kgZGVsZXRlIG1hYyBmYWlsLiZxdW90Oyk7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgaSsrOzxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoH08YnI+DQrCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCBpZiAocnhtb2RlLSZndDtvZmZsb2FkcyAmYW1wOyBSVEVfRVRI X1JYX09GRkxPQURfVkxBTl9FWFRFTkQpIHs8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCBpNDBlX3ZzaV9jb25maWdfZG91YmxlX3ZsYW4odnNpLCBUUlVFKTs8YnI+DQrC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAvKiBTZXQgZ2xvYmFsIHJlZ2lzdGVy cyB3aXRoIGRlZmF1bHQgZXRoZXJ0eXBlLiAqLzxicj4NCkBAIC00MDE0LDkgKzQwNzcsMTkgQEAg aTQwZV92bGFuX29mZmxvYWRfc2V0KHN0cnVjdCBydGVfZXRoX2RldiAqZGV2LCBpbnQgbWFzayk8 YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoFJURV9FVEhFUl9UWVBFX1ZMQU4pOzxicj4NCsKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIGk0MGVfdmxhbl90cGlkX3NldChkZXYsIFJURV9FVEhfVkxBTl9U WVBFX0lOTkVSLDxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgUlRFX0VUSEVSX1RZUEVfVkxBTik7PGJyPg0KLcKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgfTxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGVsc2U8YnI+ DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB9IGVsc2Ugezxicj4NCivCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoGlmIChwZi0mZ3Q7Znc4XzNndCk8YnI+DQorwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBpNDBlX3ZsYW5fdHBpZF9zZXQoZGV2 LCBSVEVfRVRIX1ZMQU5fVFlQRV9PVVRFUiw8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgUlRFX0VUSEVSX1RZUEVfUUlO USk7PGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgaTQwZV92c2lfY29u ZmlnX2RvdWJsZV92bGFuKHZzaSwgRkFMU0UpOzxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oH08YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAvKiBSZXN0b3JlIGFsbCBtYWMgKi88YnI+ DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBmb3IgKGkgPSAwOyBpICZsdDsgbnVtOyBpKyspIHs8 YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqByZXQgPSBpNDBlX3ZzaV9h ZGRfbWFjKHZzaSwgJmFtcDttYWNfZmlsdGVyW2ldKTs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqBpZiAocmV0KTxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoFBNRF9EUlZfTE9HKEVSUiwgJnF1b3Q7aTQwZSB2c2kgYWRk IG1hYyBmYWlsLiZxdW90Oyk7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgfTxicj4NCivC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoHJ0ZV9mcmVlKG1hY19maWx0ZXIpOzxicj4NCsKgIMKgIMKg IMKgIH08YnI+DQo8YnI+DQrCoCDCoCDCoCDCoCBpZiAobWFzayAmYW1wOyBSVEVfRVRIX1FJTlFf U1RSSVBfTUFTSykgezxicj4NCkBAIC00ODQ2LDYgKzQ5MTksMTcgQEAgaTQwZV9wZl9wYXJhbWV0 ZXJfaW5pdChzdHJ1Y3QgcnRlX2V0aF9kZXYgKmRldik8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCByZXR1cm4gLUVJTlZBTDs8YnI+DQrCoCDCoCDCoCDCoCB9PGJyPg0KPGJyPg0KK8KgIMKg IMKgIMKgLyoqPGJyPg0KK8KgIMKgIMKgIMKgICogRW5hYmxlIG91dGVyIFZMQU4gcHJvY2Vzc2lu ZyBpZiBmaXJtd2FyZSB2ZXJzaW9uIGlzIGdyZWF0ZXI8YnI+DQorwqAgwqAgwqAgwqAgKiB0aGFu IHY4LjM8YnI+DQorwqAgwqAgwqAgwqAgKi88YnI+DQorwqAgwqAgwqAgwqBpZiAoaHctJmd0O2Fx LmZ3X21hal92ZXIgJmd0OyA4IHx8PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgKGh3LSZndDthcS5m d19tYWpfdmVyID09IDggJmFtcDsmYW1wOyBody0mZ3Q7YXEuZndfbWluX3ZlciAmZ3Q7IDMpKSB7 PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgcGYtJmd0O2Z3OF8zZ3QgPSB0cnVlOzxicj4N CivCoCDCoCDCoCDCoH0gZWxzZSB7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgcGYtJmd0 O2Z3OF8zZ3QgPSBmYWxzZTs8YnI+DQorwqAgwqAgwqAgwqB9PGJyPg0KKzxicj4NCsKgIMKgIMKg IMKgIHJldHVybiAwOzxicj4NCsKgfTxicj4NCjxicj4NCmRpZmYgLS1naXQgYS9kcml2ZXJzL25l dC9pNDBlL2k0MGVfZXRoZGV2LmggYi9kcml2ZXJzL25ldC9pNDBlL2k0MGVfZXRoZGV2Lmg8YnI+ DQppbmRleCBhMWViZGMwOTNjLi5mZTk0M2E0NWZmIDEwMDY0NDxicj4NCi0tLSBhL2RyaXZlcnMv bmV0L2k0MGUvaTQwZV9ldGhkZXYuaDxicj4NCisrKyBiL2RyaXZlcnMvbmV0L2k0MGUvaTQwZV9l dGhkZXYuaDxicj4NCkBAIC0xMTg4LDYgKzExODgsOSBAQCBzdHJ1Y3QgaTQwZV9wZiB7PGJyPg0K wqAgwqAgwqAgwqAgLyogU3dpdGNoIERvbWFpbiBJZCAqLzxicj4NCsKgIMKgIMKgIMKgIHVpbnQx Nl90IHN3aXRjaF9kb21haW5faWQ7PGJyPg0KPGJyPg0KK8KgIMKgIMKgIMKgLyogV2hlbiBmaXJt d2FyZSAmZ3Q7IDguMywgdGhlIGVuYWJsZSBmbGFnIGZvciBvdXRlciBWTEFOIHByb2Nlc3Npbmcg Ki88YnI+DQorwqAgwqAgwqAgwqBib29sIGZ3OF8zZ3Q7PGJyPg0KKzxicj4NCsKgIMKgIMKgIMKg IHN0cnVjdCBpNDBlX3ZmX21zZ19jZmcgdmZfbXNnX2NmZzs8YnI+DQrCoCDCoCDCoCDCoCB1aW50 NjRfdCBwcmV2X3J4X2J5dGVzOzxicj4NCsKgIMKgIMKgIMKgIHVpbnQ2NF90IHByZXZfdHhfYnl0 ZXM7PGJyPg0KLS0gPGJyPg0KMi4zNC4xPGJyPg0KPGJyPg0KPC9ibG9ja3F1b3RlPjwvZGl2Pg0K --0000000000001cbdd205e118bd87--