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 290DC43C0C; Fri, 1 Mar 2024 17:13:53 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 15C074337B; Fri, 1 Mar 2024 17:13:53 +0100 (CET) Received: from mail-oo1-f45.google.com (mail-oo1-f45.google.com [209.85.161.45]) by mails.dpdk.org (Postfix) with ESMTP id CBFFC402E0 for ; Fri, 1 Mar 2024 17:13:50 +0100 (CET) Received: by mail-oo1-f45.google.com with SMTP id 006d021491bc7-5a0680bc600so780117eaf.0 for ; Fri, 01 Mar 2024 08:13:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iol.unh.edu; s=unh-iol; t=1709309630; x=1709914430; darn=dpdk.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=IdvjWULizvSGeHaYeVJpwvVq5ov/CpJKruzEirJhUDI=; b=iZ4xQ6k3Mg5QRDpsJibCH0BTm8L85mvU+gocOEMIQ0l276futK8Jp0mNHttrMaagc/ ugeEdyX97A9tACnhvQC/kYQXGSjmnM4iCQbdXd+BbIin48YrIogT/w+LYzFimMpAsv2r 4V2R17Q1MrWnYMHAB7gKzw6IEs/2pzU6FnRz8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709309630; x=1709914430; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=IdvjWULizvSGeHaYeVJpwvVq5ov/CpJKruzEirJhUDI=; b=sO0375FOaVANcoOfvCmd+OzkQ7K7SaTnVtRzjO/a3VGEYunBKKgu3vW5/F4Lest4xi 1hYPSERoJ//4xGwxk0QIYaX43uO3qr7fwdbz98NzQtuNamhJrAfRBYD1VdVzyPsUyDvN YlOQr9jmgsc6o7gjJZS9ObmdpRNQifv5No6b41tUi3H1cGvqiSbkb0r++sIDYpyLyPER pn1LDawnAnMAyBu9Qy1hSSHOaA9h2B3mtd2EW1s8+dJPRc2KIjugQ58E6BeE6nGcFHR7 tfsMqraezjrS+BsxKnxTYkMEwVsOlAoK89AcPUsxTicf/SQE3sgJxKvHU8rlXvjvJmXp +u8A== X-Gm-Message-State: AOJu0Yyah3B9BwkMtxHuDeNihLbpTdIc3bfbBfVoNrJU/0uY8QiaQRDW k+9SJ9DcazLg1Q9hr1euewPSVsjH2IvhgT5h1uzp7mw5HRMpqrD5b9/rA0JJVwEVqSy88+waFWj LaXGZzNj3qx3WekBJcSj9cxsZW/8BHDIwaPFLiTRW60mX6WZdvEWyYg== X-Google-Smtp-Source: AGHT+IFAwXWSl5gg3ds1Jm+y9SGJoo6gpONjPsp0OghkOpeZFCJCruA4dgm1U+yXmn4J1RcujSai31PZ8y2ZW99Ss+k= X-Received: by 2002:a4a:80c1:0:b0:5a0:ea46:ffe9 with SMTP id a1-20020a4a80c1000000b005a0ea46ffe9mr1419279oog.7.1709309630034; Fri, 01 Mar 2024 08:13:50 -0800 (PST) MIME-Version: 1.0 References: <20240105101125.2454522-1-mingjinx.ye@intel.com> <20240301095052.460597-1-mingjinx.ye@intel.com> In-Reply-To: <20240301095052.460597-1-mingjinx.ye@intel.com> From: Patrick Robb Date: Fri, 1 Mar 2024 11:13:39 -0500 Message-ID: Subject: Re: [PATCH v3] net/ice: add diagnostic support in TX path To: Mingjin Ye Cc: dev@dpdk.org Content-Type: multipart/alternative; boundary="0000000000004f51e506129ba939" 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 --0000000000004f51e506129ba939 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable The Community CI Testing Lab had an infra failure this morning and some patches including yours were affected with false failures. The issue is now resolved and we are rerunning the tests in question for all patches submitted today. On Fri, Mar 1, 2024 at 5:11=E2=80=AFAM Mingjin Ye w= rote: > Implemented a Tx wrapper to perform a thorough check on mbufs, > categorizing and counting invalid cases by types for diagnostic > purposes. The count of invalid cases is accessible through xstats_get. > > Also, the devarg option "mbuf_check" was introduced to configure the > diagnostic parameters to enable the appropriate diagnostic features. > > supported cases: mbuf, size, segment, offload. > 1. mbuf: check for corrupted mbuf. > 2. size: check min/max packet length according to hw spec. > 3. segment: check number of mbuf segments not exceed hw limitation. > 4. offload: check any unsupported offload flag. > > parameter format: "mbuf_check=3D" or "mbuf_check=3D[,= ]" > eg: dpdk-testpmd -a 0000:81:01.0,mbuf_check=3D[mbuf,size] -- -i > > Signed-off-by: Mingjin Ye > --- > v2: rebase. > --- > v3: Modify comment log. > --- > doc/guides/nics/ice.rst | 13 +++ > drivers/net/ice/ice_ethdev.c | 108 +++++++++++++++++++++++- > drivers/net/ice/ice_ethdev.h | 23 +++++ > drivers/net/ice/ice_rxtx.c | 158 ++++++++++++++++++++++++++++++++--- > drivers/net/ice/ice_rxtx.h | 20 +++++ > 5 files changed, 311 insertions(+), 11 deletions(-) > > diff --git a/doc/guides/nics/ice.rst b/doc/guides/nics/ice.rst > index bafb3ba022..d1aee811b3 100644 > --- a/doc/guides/nics/ice.rst > +++ b/doc/guides/nics/ice.rst > @@ -257,6 +257,19 @@ Runtime Configuration > As a trade-off, this configuration may cause the packet processing > performance > degradation due to the PCI bandwidth limitation. > > +- ``Tx diagnostics`` (default ``not enabled``) > + > + Set the ``devargs`` parameter ``mbuf_check`` to enable TX diagnostics. > For example, > + ``-a 18:01.0,mbuf_check=3D`` or ``-a > 18:01.0,mbuf_check=3D[,...]``. > + Also, ``xstats_get`` can be used to get the error counts, which are > collected in > + ``tx_mbuf_error_packets`` xstats. For example, ``testpmd> show port > xstats all``. > + Supported cases: > + > + * mbuf: Check for corrupted mbuf. > + * size: Check min/max packet length according to hw spec. > + * segment: Check number of mbuf segments not exceed hw limitation. > + * offload: Check any unsupported offload flag. > + > Driver compilation and testing > ------------------------------ > > diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c > index 72e13f95f8..d28e205375 100644 > --- a/drivers/net/ice/ice_ethdev.c > +++ b/drivers/net/ice/ice_ethdev.c > @@ -12,6 +12,7 @@ > #include > > #include > +#include > > #include "eal_firmware.h" > > @@ -34,6 +35,7 @@ > #define ICE_HW_DEBUG_MASK_ARG "hw_debug_mask" > #define ICE_ONE_PPS_OUT_ARG "pps_out" > #define ICE_RX_LOW_LATENCY_ARG "rx_low_latency" > +#define ICE_MBUF_CHECK_ARG "mbuf_check" > > #define ICE_CYCLECOUNTER_MASK 0xffffffffffffffffULL > > @@ -49,6 +51,7 @@ static const char * const ice_valid_args[] =3D { > ICE_ONE_PPS_OUT_ARG, > ICE_RX_LOW_LATENCY_ARG, > ICE_DEFAULT_MAC_DISABLE, > + ICE_MBUF_CHECK_ARG, > NULL > }; > > @@ -319,6 +322,14 @@ static const struct ice_xstats_name_off > ice_stats_strings[] =3D { > #define ICE_NB_ETH_XSTATS (sizeof(ice_stats_strings) / \ > sizeof(ice_stats_strings[0])) > > +static const struct ice_xstats_name_off ice_mbuf_strings[] =3D { > + {"tx_mbuf_error_packets", offsetof(struct ice_mbuf_stats, > + tx_pkt_errors)}, > +}; > + > +#define ICE_NB_MBUF_XSTATS (sizeof(ice_mbuf_strings) / \ > + sizeof(ice_mbuf_strings[0])) > + > static const struct ice_xstats_name_off ice_hw_port_strings[] =3D { > {"tx_link_down_dropped", offsetof(struct ice_hw_port_stats, > tx_dropped_link_down)}, > @@ -2061,6 +2072,58 @@ handle_pps_out_arg(__rte_unused const char *key, > const char *value, > return 0; > } > > +static int > +ice_parse_mbuf_check(__rte_unused const char *key, const char *value, > void *args) > +{ > + char *cur; > + char *tmp; > + int str_len; > + int valid_len; > + > + int ret =3D 0; > + uint64_t *mc_flags =3D args; > + char *str2 =3D strdup(value); > + if (str2 =3D=3D NULL) > + return -1; > + > + str_len =3D strlen(str2); > + if (str_len =3D=3D 0) { > + ret =3D -1; > + goto err_end; > + } > + > + /* Try stripping the outer square brackets of the parameter > string. */ > + str_len =3D strlen(str2); > + if (str2[0] =3D=3D '[' && str2[str_len - 1] =3D=3D ']') { > + if (str_len < 3) { > + ret =3D -1; > + goto err_end; > + } > + valid_len =3D str_len - 2; > + memmove(str2, str2 + 1, valid_len); > + memset(str2 + valid_len, '\0', 2); > + } > + > + cur =3D strtok_r(str2, ",", &tmp); > + while (cur !=3D NULL) { > + if (!strcmp(cur, "mbuf")) > + *mc_flags |=3D ICE_MBUF_CHECK_F_TX_MBUF; > + else if (!strcmp(cur, "size")) > + *mc_flags |=3D ICE_MBUF_CHECK_F_TX_SIZE; > + else if (!strcmp(cur, "segment")) > + *mc_flags |=3D ICE_MBUF_CHECK_F_TX_SEGMENT; > + else if (!strcmp(cur, "offload")) > + *mc_flags |=3D ICE_MBUF_CHECK_F_TX_OFFLOAD; > + else > + PMD_DRV_LOG(ERR, "Unsupported diagnostic type: > %s", cur); > + cur =3D strtok_r(NULL, ",", &tmp); > + } > + > +err_end: > + free(str2); > + return ret; > +} > + > static int ice_parse_devargs(struct rte_eth_dev *dev) > { > struct ice_adapter *ad =3D > @@ -2117,6 +2180,11 @@ static int ice_parse_devargs(struct rte_eth_dev > *dev) > if (ret) > goto bail; > > + ret =3D rte_kvargs_process(kvlist, ICE_MBUF_CHECK_ARG, > + &ice_parse_mbuf_check, > &ad->devargs.mbuf_check); > + if (ret) > + goto bail; > + > ret =3D rte_kvargs_process(kvlist, ICE_RX_LOW_LATENCY_ARG, > &parse_bool, &ad->devargs.rx_low_latency= ); > > @@ -6161,6 +6229,9 @@ ice_stats_reset(struct rte_eth_dev *dev) > /* read the stats, reading current register values into offset */ > ice_read_stats_registers(pf, hw); > > + memset(&pf->mbuf_stats, 0, > + sizeof(struct ice_mbuf_stats)); > + > return 0; > } > > @@ -6169,17 +6240,33 @@ ice_xstats_calc_num(void) > { > uint32_t num; > > - num =3D ICE_NB_ETH_XSTATS + ICE_NB_HW_PORT_XSTATS; > + num =3D ICE_NB_ETH_XSTATS + ICE_NB_MBUF_XSTATS + > ICE_NB_HW_PORT_XSTATS; > > return num; > } > > +static void > +ice_update_mbuf_stats(struct rte_eth_dev *ethdev, > + struct ice_mbuf_stats *mbuf_stats) > +{ > + uint16_t idx; > + struct ice_tx_queue *txq; > + > + for (idx =3D 0; idx < ethdev->data->nb_tx_queues; idx++) { > + txq =3D ethdev->data->tx_queues[idx]; > + mbuf_stats->tx_pkt_errors +=3D txq->mbuf_errors; > + } > +} > + > static int > ice_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, > unsigned int n) > { > struct ice_pf *pf =3D ICE_DEV_PRIVATE_TO_PF(dev->data->dev_privat= e); > struct ice_hw *hw =3D ICE_DEV_PRIVATE_TO_HW(dev->data->dev_privat= e); > + struct ice_adapter *adapter =3D > + ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); > + struct ice_mbuf_stats mbuf_stats =3D {0}; > unsigned int i; > unsigned int count; > struct ice_hw_port_stats *hw_stats =3D &pf->stats; > @@ -6195,6 +6282,9 @@ ice_xstats_get(struct rte_eth_dev *dev, struct > rte_eth_xstat *xstats, > > count =3D 0; > > + if (adapter->devargs.mbuf_check) > + ice_update_mbuf_stats(dev, &mbuf_stats); > + > /* Get stats from ice_eth_stats struct */ > for (i =3D 0; i < ICE_NB_ETH_XSTATS; i++) { > xstats[count].value =3D > @@ -6204,6 +6294,15 @@ ice_xstats_get(struct rte_eth_dev *dev, struct > rte_eth_xstat *xstats, > count++; > } > > + /* Get stats from ice_mbuf_stats struct */ > + for (i =3D 0; i < ICE_NB_MBUF_XSTATS; i++) { > + xstats[count].value =3D > + *(uint64_t *)((char *)&mbuf_stats + > + ice_mbuf_strings[i].offset); > + xstats[count].id =3D count; > + count++; > + } > + > /* Get individual stats from ice_hw_port struct */ > for (i =3D 0; i < ICE_NB_HW_PORT_XSTATS; i++) { > xstats[count].value =3D > @@ -6235,6 +6334,13 @@ static int ice_xstats_get_names(__rte_unused struc= t > rte_eth_dev *dev, > count++; > } > > + /* Get stats from ice_mbuf_stats struct */ > + for (i =3D 0; i < ICE_NB_MBUF_XSTATS; i++) { > + strlcpy(xstats_names[count].name, ice_mbuf_strings[i].nam= e, > + sizeof(xstats_names[count].name)); > + count++; > + } > + > /* Get individual stats from ice_hw_port struct */ > for (i =3D 0; i < ICE_NB_HW_PORT_XSTATS; i++) { > strlcpy(xstats_names[count].name, > ice_hw_port_strings[i].name, > diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h > index fa4981ed14..fa0b7bd226 100644 > --- a/drivers/net/ice/ice_ethdev.h > +++ b/drivers/net/ice/ice_ethdev.h > @@ -507,6 +507,10 @@ struct ice_tm_conf { > bool clear_on_fail; > }; > > +struct ice_mbuf_stats { > + uint64_t tx_pkt_errors; > +}; > + > struct ice_pf { > struct ice_adapter *adapter; /* The adapter this PF associate to = */ > struct ice_vsi *main_vsi; /* pointer to main VSI structure */ > @@ -536,6 +540,7 @@ struct ice_pf { > uint16_t fdir_fltr_cnt[ICE_FLTR_PTYPE_MAX][ICE_FD_HW_SEG_MAX]; > struct ice_hw_port_stats stats_offset; > struct ice_hw_port_stats stats; > + struct ice_mbuf_stats mbuf_stats; > /* internal packet statistics, it should be excluded from the > total */ > struct ice_eth_stats internal_stats_offset; > struct ice_eth_stats internal_stats; > @@ -574,6 +579,7 @@ struct ice_devargs { > uint8_t xtr_flag_offs[PROTO_XTR_MAX]; > /* Name of the field. */ > char xtr_field_name[RTE_MBUF_DYN_NAMESIZE]; > + uint64_t mbuf_check; > }; > > /** > @@ -592,6 +598,21 @@ struct ice_rss_prof_info { > bool symm; > }; > > +#define ICE_MBUF_CHECK_F_TX_MBUF (1ULL << 0) > +#define ICE_MBUF_CHECK_F_TX_SIZE (1ULL << 1) > +#define ICE_MBUF_CHECK_F_TX_SEGMENT (1ULL << 2) > +#define ICE_MBUF_CHECK_F_TX_OFFLOAD (1ULL << 3) > + > +enum ice_tx_burst_type { > + ICE_TX_DEFAULT, > + ICE_TX_SIMPLE, > + ICE_TX_VEC_SSE, > + ICE_TX_VEC_AVX2, > + ICE_TX_VEC_AVX2_OFFLOAD, > + ICE_TX_VEC_AVX512, > + ICE_TX_VEC_AVX512_OFFLOAD, > +}; > + > /** > * Structure to store private data for each PF/VF instance. > */ > @@ -609,6 +630,8 @@ struct ice_adapter { > struct ice_devargs devargs; > enum ice_pkg_type active_pkg_type; /* loaded ddp package type */ > uint16_t fdir_ref_cnt; > + /* For vector PMD */ > + enum ice_tx_burst_type tx_burst_type; > /* For PTP */ > struct rte_timecounter systime_tc; > struct rte_timecounter rx_tstamp_tc; > diff --git a/drivers/net/ice/ice_rxtx.c b/drivers/net/ice/ice_rxtx.c > index 73e47ae92d..fdffe17925 100644 > --- a/drivers/net/ice/ice_rxtx.c > +++ b/drivers/net/ice/ice_rxtx.c > @@ -3678,6 +3678,132 @@ ice_check_empty_mbuf(struct rte_mbuf *tx_pkt) > return 0; > } > > +static > +const eth_tx_burst_t ice_tx_pkt_burst_ops[] =3D { > + [ICE_TX_DEFAULT] =3D ice_xmit_pkts, > + [ICE_TX_SIMPLE] =3D ice_xmit_pkts_simple, > +#ifdef RTE_ARCH_X86 > + [ICE_TX_VEC_SSE] =3D ice_xmit_pkts_vec, > + [ICE_TX_VEC_AVX2] =3D ice_xmit_pkts_vec_avx2, > + [ICE_TX_VEC_AVX2_OFFLOAD] =3D ice_xmit_pkts_vec_avx2_offload, > +#ifdef CC_AVX512_SUPPORT > + [ICE_TX_VEC_AVX512] =3D ice_xmit_pkts_vec_avx512, > + [ICE_TX_VEC_AVX512_OFFLOAD] =3D ice_xmit_pkts_vec_avx512_offload, > +#endif > +#endif > +}; > + > +/* Tx mbuf check */ > +static uint16_t > +ice_xmit_pkts_check(void *tx_queue, struct rte_mbuf **tx_pkts, > + uint16_t nb_pkts) > +{ > + struct ice_tx_queue *txq =3D tx_queue; > + uint16_t idx; > + struct rte_mbuf *mb; > + bool pkt_error =3D false; > + uint16_t good_pkts =3D nb_pkts; > + const char *reason =3D NULL; > + struct ice_adapter *adapter =3D txq->vsi->adapter; > + enum ice_tx_burst_type tx_burst_type =3D > + txq->vsi->adapter->tx_burst_type; > + uint64_t ol_flags; > + > + for (idx =3D 0; idx < nb_pkts; idx++) { > + mb =3D tx_pkts[idx]; > + ol_flags =3D mb->ol_flags; > + > + if ((adapter->devargs.mbuf_check & > ICE_MBUF_CHECK_F_TX_MBUF) && > + (rte_mbuf_check(mb, 0, &reason) !=3D 0)) { > + PMD_TX_LOG(ERR, "INVALID mbuf: %s\n", reason); > + pkt_error =3D true; > + break; > + } > + > + if ((adapter->devargs.mbuf_check & > ICE_MBUF_CHECK_F_TX_SIZE) && > + (mb->data_len > mb->pkt_len || > + mb->data_len < ICE_TX_MIN_PKT_LEN || > + mb->data_len > ICE_FRAME_SIZE_MAX)) { > + PMD_TX_LOG(ERR, "INVALID mbuf: data_len (%u) is > out " > + "of range, reasonable range (%d - %d)\n", > mb->data_len, > + ICE_TX_MIN_PKT_LEN, ICE_FRAME_SIZE_MAX); > + pkt_error =3D true; > + break; > + } > + > + if (adapter->devargs.mbuf_check & > ICE_MBUF_CHECK_F_TX_SEGMENT) { > + if (!(ol_flags & RTE_MBUF_F_TX_TCP_SEG)) { > + /** > + * No TSO case: nb->segs, pkt_len to not > exceed > + * the limites. > + */ > + if (mb->nb_segs > ICE_TX_MTU_SEG_MAX) { > + PMD_TX_LOG(ERR, "INVALID mbuf: > nb_segs (%d) exceeds " > + "HW limit, maximum allowed value > is %d\n", mb->nb_segs, > + ICE_TX_MTU_SEG_MAX); > + pkt_error =3D true; > + break; > + } > + if (mb->pkt_len > ICE_FRAME_SIZE_MAX) { > + PMD_TX_LOG(ERR, "INVALID mbuf: > pkt_len (%d) exceeds " > + "HW limit, maximum allowed value > is %d\n", mb->nb_segs, > + ICE_FRAME_SIZE_MAX); > + pkt_error =3D true; > + break; > + } > + } else if (ol_flags & RTE_MBUF_F_TX_TCP_SEG) { > + /** TSO case: tso_segsz, nb_segs, pkt_len > not exceed > + * the limits. > + */ > + if (mb->tso_segsz < ICE_MIN_TSO_MSS || > + mb->tso_segsz > ICE_MAX_TSO_MSS) = { > + /** > + * MSS outside the range are > considered malicious > + */ > + PMD_TX_LOG(ERR, "INVALID mbuf: > tso_segsz (%u) is out " > + "of range, reasonable range (%d - > %u)\n", mb->tso_segsz, > + ICE_MIN_TSO_MSS, ICE_MAX_TSO_MSS)= ; > + pkt_error =3D true; > + break; > + } > + if (mb->nb_segs > > + ((struct ice_tx_queue > *)tx_queue)->nb_tx_desc) { > + PMD_TX_LOG(ERR, "INVALID mbuf: > nb_segs out " > + "of ring length\n"); > + pkt_error =3D true; > + break; > + } > + } > + } > + > + if (adapter->devargs.mbuf_check & > ICE_MBUF_CHECK_F_TX_OFFLOAD) { > + if (ol_flags & ICE_TX_OFFLOAD_NOTSUP_MASK) { > + PMD_TX_LOG(ERR, "INVALID mbuf: TX offload= " > + "is not supported\n"); > + pkt_error =3D true; > + break; > + } > + > + if (!rte_validate_tx_offload(mb)) { > + PMD_TX_LOG(ERR, "INVALID mbuf: TX offload= " > + "setup error\n"); > + pkt_error =3D true; > + break; > + } > + } > + } > + > + if (pkt_error) { > + txq->mbuf_errors++; > + good_pkts =3D idx; > + if (good_pkts =3D=3D 0) > + return 0; > + } > + > + return ice_tx_pkt_burst_ops[tx_burst_type](tx_queue, > + tx_pkts, good_pkts); > +} > + > uint16_t > ice_prep_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, > uint16_t nb_pkts) > @@ -3746,6 +3872,8 @@ ice_set_tx_function(struct rte_eth_dev *dev) > { > struct ice_adapter *ad =3D > ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); > + enum ice_tx_burst_type tx_burst_type =3D ICE_TX_DEFAULT; > + int mbuf_check =3D ad->devargs.mbuf_check; > #ifdef RTE_ARCH_X86 > struct ice_tx_queue *txq; > int i; > @@ -3800,14 +3928,13 @@ ice_set_tx_function(struct rte_eth_dev *dev) > PMD_DRV_LOG(NOTICE, > "Using AVX512 OFFLOAD Vector > Tx (port %d).", > dev->data->port_id); > - dev->tx_pkt_burst =3D > - ice_xmit_pkts_vec_avx512_offload; > + tx_burst_type =3D ICE_TX_VEC_AVX512_OFFLO= AD; > dev->tx_pkt_prepare =3D ice_prep_pkts; > } else { > PMD_DRV_LOG(NOTICE, > "Using AVX512 Vector Tx (port > %d).", > dev->data->port_id); > - dev->tx_pkt_burst =3D > ice_xmit_pkts_vec_avx512; > + tx_burst_type =3D ICE_TX_VEC_AVX512; > } > #endif > } else { > @@ -3815,32 +3942,43 @@ ice_set_tx_function(struct rte_eth_dev *dev) > PMD_DRV_LOG(NOTICE, > "Using AVX2 OFFLOAD Vector Tx > (port %d).", > dev->data->port_id); > - dev->tx_pkt_burst =3D > - ice_xmit_pkts_vec_avx2_offload; > + tx_burst_type =3D ICE_TX_VEC_AVX2_OFFLOAD= ; > dev->tx_pkt_prepare =3D ice_prep_pkts; > } else { > PMD_DRV_LOG(DEBUG, "Using %sVector Tx > (port %d).", > ad->tx_use_avx2 ? "avx2 " : "= ", > dev->data->port_id); > - dev->tx_pkt_burst =3D ad->tx_use_avx2 ? > - ice_xmit_pkts_vec_avx= 2 > : > - ice_xmit_pkts_vec; > + tx_burst_type =3D ad->tx_use_avx2 ? > + ICE_TX_VEC_AVX2 : > ICE_TX_VEC_SSE; > } > } > > + if (mbuf_check) { > + ad->tx_burst_type =3D tx_burst_type; > + dev->tx_pkt_burst =3D ice_xmit_pkts_check; > + } else { > + dev->tx_pkt_burst =3D > ice_tx_pkt_burst_ops[tx_burst_type]; > + } > return; > } > #endif > > if (ad->tx_simple_allowed) { > PMD_INIT_LOG(DEBUG, "Simple tx finally be used."); > - dev->tx_pkt_burst =3D ice_xmit_pkts_simple; > + tx_burst_type =3D ICE_TX_SIMPLE; > dev->tx_pkt_prepare =3D NULL; > } else { > PMD_INIT_LOG(DEBUG, "Normal tx finally be used."); > - dev->tx_pkt_burst =3D ice_xmit_pkts; > + tx_burst_type =3D ICE_TX_DEFAULT; > dev->tx_pkt_prepare =3D ice_prep_pkts; > } > + > + if (mbuf_check) { > + ad->tx_burst_type =3D tx_burst_type; > + dev->tx_pkt_burst =3D ice_xmit_pkts_check; > + } else { > + dev->tx_pkt_burst =3D ice_tx_pkt_burst_ops[tx_burst_type]= ; > + } > } > > static const struct { > diff --git a/drivers/net/ice/ice_rxtx.h b/drivers/net/ice/ice_rxtx.h > index bd2c4abec9..088ddba600 100644 > --- a/drivers/net/ice/ice_rxtx.h > +++ b/drivers/net/ice/ice_rxtx.h > @@ -45,6 +45,25 @@ > > #define ICE_TX_MIN_PKT_LEN 17 > > +#define ICE_TX_OFFLOAD_MASK ( \ > + RTE_MBUF_F_TX_OUTER_IPV6 | \ > + RTE_MBUF_F_TX_OUTER_IPV4 | \ > + RTE_MBUF_F_TX_OUTER_IP_CKSUM | \ > + RTE_MBUF_F_TX_VLAN | \ > + RTE_MBUF_F_TX_IPV6 | \ > + RTE_MBUF_F_TX_IPV4 | \ > + RTE_MBUF_F_TX_IP_CKSUM | \ > + RTE_MBUF_F_TX_L4_MASK | \ > + RTE_MBUF_F_TX_IEEE1588_TMST | \ > + RTE_MBUF_F_TX_TCP_SEG | \ > + RTE_MBUF_F_TX_QINQ | \ > + RTE_MBUF_F_TX_TUNNEL_MASK | \ > + RTE_MBUF_F_TX_UDP_SEG | \ > + RTE_MBUF_F_TX_OUTER_UDP_CKSUM) > + > +#define ICE_TX_OFFLOAD_NOTSUP_MASK \ > + (RTE_MBUF_F_TX_OFFLOAD_MASK ^ ICE_TX_OFFLOAD_MASK) > + > extern uint64_t ice_timestamp_dynflag; > extern int ice_timestamp_dynfield_offset; > > @@ -164,6 +183,7 @@ struct ice_tx_queue { > struct ice_vsi *vsi; /* the VSI this queue belongs to */ > uint16_t tx_next_dd; > uint16_t tx_next_rs; > + uint64_t mbuf_errors; > bool tx_deferred_start; /* don't start this queue in dev start */ > bool q_set; /* indicate if tx queue has been configured */ > ice_tx_release_mbufs_t tx_rel_mbufs; > -- > 2.25.1 > > --0000000000004f51e506129ba939 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: base64 PGRpdiBkaXI9Imx0ciI+PGRpdiBkaXI9Imx0ciI+VGhlIENvbW11bml0eSBDSSBUZXN0aW5nIExh YiBoYWQgYW4gaW5mcmEgZmFpbHVyZSB0aGlzIG1vcm5pbmcgYW5kIHNvbWUgcGF0Y2hlcyBpbmNs dWRpbmcgeW91cnMgd2VyZSBhZmZlY3RlZCB3aXRoIGZhbHNlIGZhaWx1cmVzLiBUaGUgaXNzdWUg aXMgbm93IHJlc29sdmVkIGFuZCB3ZSBhcmUgcmVydW5uaW5nIHRoZSB0ZXN0cyBpbiBxdWVzdGlv biBmb3IgYWxsIHBhdGNoZXMgc3VibWl0dGVkIHRvZGF5LsKgPGJyPjwvZGl2Pjxicj48ZGl2IGNs YXNzPSJnbWFpbF9xdW90ZSI+PGRpdiBkaXI9Imx0ciIgY2xhc3M9ImdtYWlsX2F0dHIiPk9uIEZy aSwgTWFyIDEsIDIwMjQgYXQgNToxMeKAr0FNIE1pbmdqaW4gWWUgJmx0OzxhIGhyZWY9Im1haWx0 bzptaW5namlueC55ZUBpbnRlbC5jb20iPm1pbmdqaW54LnllQGludGVsLmNvbTwvYT4mZ3Q7IHdy b3RlOjxicj48L2Rpdj48YmxvY2txdW90ZSBjbGFzcz0iZ21haWxfcXVvdGUiIHN0eWxlPSJtYXJn aW46MHB4IDBweCAwcHggMC44ZXg7Ym9yZGVyLWxlZnQ6MXB4IHNvbGlkIHJnYigyMDQsMjA0LDIw NCk7cGFkZGluZy1sZWZ0OjFleCI+SW1wbGVtZW50ZWQgYSBUeCB3cmFwcGVyIHRvIHBlcmZvcm0g YSB0aG9yb3VnaCBjaGVjayBvbiBtYnVmcyw8YnI+DQpjYXRlZ29yaXppbmcgYW5kIGNvdW50aW5n IGludmFsaWQgY2FzZXMgYnkgdHlwZXMgZm9yIGRpYWdub3N0aWM8YnI+DQpwdXJwb3Nlcy4gVGhl IGNvdW50IG9mIGludmFsaWQgY2FzZXMgaXMgYWNjZXNzaWJsZSB0aHJvdWdoIHhzdGF0c19nZXQu PGJyPg0KPGJyPg0KQWxzbywgdGhlIGRldmFyZyBvcHRpb24gJnF1b3Q7bWJ1Zl9jaGVjayZxdW90 OyB3YXMgaW50cm9kdWNlZCB0byBjb25maWd1cmUgdGhlPGJyPg0KZGlhZ25vc3RpYyBwYXJhbWV0 ZXJzIHRvIGVuYWJsZSB0aGUgYXBwcm9wcmlhdGUgZGlhZ25vc3RpYyBmZWF0dXJlcy48YnI+DQo8 YnI+DQpzdXBwb3J0ZWQgY2FzZXM6IG1idWYsIHNpemUsIHNlZ21lbnQsIG9mZmxvYWQuPGJyPg0K wqAxLiBtYnVmOiBjaGVjayBmb3IgY29ycnVwdGVkIG1idWYuPGJyPg0KwqAyLiBzaXplOiBjaGVj ayBtaW4vbWF4IHBhY2tldCBsZW5ndGggYWNjb3JkaW5nIHRvIGh3IHNwZWMuPGJyPg0KwqAzLiBz ZWdtZW50OiBjaGVjayBudW1iZXIgb2YgbWJ1ZiBzZWdtZW50cyBub3QgZXhjZWVkIGh3IGxpbWl0 YXRpb24uPGJyPg0KwqA0LiBvZmZsb2FkOiBjaGVjayBhbnkgdW5zdXBwb3J0ZWQgb2ZmbG9hZCBm bGFnLjxicj4NCjxicj4NCnBhcmFtZXRlciBmb3JtYXQ6ICZxdW90O21idWZfY2hlY2s9Jmx0O2Nh c2UmZ3Q7JnF1b3Q7IG9yICZxdW90O21idWZfY2hlY2s9WyZsdDtjYXNlMSZndDssJmx0O2Nhc2Uy Jmd0O10mcXVvdDs8YnI+DQplZzogZHBkay10ZXN0cG1kIC1hIDAwMDA6ODE6MDEuMCxtYnVmX2No ZWNrPVttYnVmLHNpemVdIC0tIC1pPGJyPg0KPGJyPg0KU2lnbmVkLW9mZi1ieTogTWluZ2ppbiBZ ZSAmbHQ7PGEgaHJlZj0ibWFpbHRvOm1pbmdqaW54LnllQGludGVsLmNvbSIgdGFyZ2V0PSJfYmxh bmsiPm1pbmdqaW54LnllQGludGVsLmNvbTwvYT4mZ3Q7PGJyPg0KLS0tPGJyPg0KdjI6IHJlYmFz ZS48YnI+DQotLS08YnI+DQp2MzogTW9kaWZ5IGNvbW1lbnQgbG9nLjxicj4NCi0tLTxicj4NCsKg ZG9jL2d1aWRlcy9uaWNzL2ljZS5yc3TCoCDCoCDCoCB8wqAgMTMgKysrPGJyPg0KwqBkcml2ZXJz L25ldC9pY2UvaWNlX2V0aGRldi5jIHwgMTA4ICsrKysrKysrKysrKysrKysrKysrKysrLTxicj4N CsKgZHJpdmVycy9uZXQvaWNlL2ljZV9ldGhkZXYuaCB8wqAgMjMgKysrKys8YnI+DQrCoGRyaXZl cnMvbmV0L2ljZS9pY2Vfcnh0eC5jwqAgwqB8IDE1OCArKysrKysrKysrKysrKysrKysrKysrKysr KysrKysrKy0tLTxicj4NCsKgZHJpdmVycy9uZXQvaWNlL2ljZV9yeHR4LmjCoCDCoHzCoCAyMCAr KysrKzxicj4NCsKgNSBmaWxlcyBjaGFuZ2VkLCAzMTEgaW5zZXJ0aW9ucygrKSwgMTEgZGVsZXRp b25zKC0pPGJyPg0KPGJyPg0KZGlmZiAtLWdpdCBhL2RvYy9ndWlkZXMvbmljcy9pY2UucnN0IGIv ZG9jL2d1aWRlcy9uaWNzL2ljZS5yc3Q8YnI+DQppbmRleCBiYWZiM2JhMDIyLi5kMWFlZTgxMWIz IDEwMDY0NDxicj4NCi0tLSBhL2RvYy9ndWlkZXMvbmljcy9pY2UucnN0PGJyPg0KKysrIGIvZG9j L2d1aWRlcy9uaWNzL2ljZS5yc3Q8YnI+DQpAQCAtMjU3LDYgKzI1NywxOSBAQCBSdW50aW1lIENv bmZpZ3VyYXRpb248YnI+DQrCoCDCoEFzIGEgdHJhZGUtb2ZmLCB0aGlzIGNvbmZpZ3VyYXRpb24g bWF5IGNhdXNlIHRoZSBwYWNrZXQgcHJvY2Vzc2luZyBwZXJmb3JtYW5jZTxicj4NCsKgIMKgZGVn cmFkYXRpb24gZHVlIHRvIHRoZSBQQ0kgYmFuZHdpZHRoIGxpbWl0YXRpb24uPGJyPg0KPGJyPg0K Ky0gYGBUeCBkaWFnbm9zdGljc2BgIChkZWZhdWx0IGBgbm90IGVuYWJsZWRgYCk8YnI+DQorPGJy Pg0KK8KgIFNldCB0aGUgYGBkZXZhcmdzYGAgcGFyYW1ldGVyIGBgbWJ1Zl9jaGVja2BgIHRvIGVu YWJsZSBUWCBkaWFnbm9zdGljcy4gRm9yIGV4YW1wbGUsPGJyPg0KK8KgIGBgLWEgMTg6MDEuMCxt YnVmX2NoZWNrPSZsdDtjYXNlJmd0O2BgIG9yIGBgLWEgMTg6MDEuMCxtYnVmX2NoZWNrPVsmbHQ7 Y2FzZTEmZ3Q7LCZsdDtjYXNlMiZndDsuLi5dYGAuPGJyPg0KK8KgIEFsc28sIGBgeHN0YXRzX2dl dGBgIGNhbiBiZSB1c2VkIHRvIGdldCB0aGUgZXJyb3IgY291bnRzLCB3aGljaCBhcmUgY29sbGVj dGVkIGluPGJyPg0KK8KgIGBgdHhfbWJ1Zl9lcnJvcl9wYWNrZXRzYGAgeHN0YXRzLiBGb3IgZXhh bXBsZSwgYGB0ZXN0cG1kJmd0OyBzaG93IHBvcnQgeHN0YXRzIGFsbGBgLjxicj4NCivCoCBTdXBw b3J0ZWQgY2FzZXM6PGJyPg0KKzxicj4NCivCoCAqwqAgwqBtYnVmOiBDaGVjayBmb3IgY29ycnVw dGVkIG1idWYuPGJyPg0KK8KgICrCoCDCoHNpemU6IENoZWNrIG1pbi9tYXggcGFja2V0IGxlbmd0 aCBhY2NvcmRpbmcgdG8gaHcgc3BlYy48YnI+DQorwqAgKsKgIMKgc2VnbWVudDogQ2hlY2sgbnVt YmVyIG9mIG1idWYgc2VnbWVudHMgbm90IGV4Y2VlZCBodyBsaW1pdGF0aW9uLjxicj4NCivCoCAq wqAgwqBvZmZsb2FkOiBDaGVjayBhbnkgdW5zdXBwb3J0ZWQgb2ZmbG9hZCBmbGFnLjxicj4NCis8 YnI+DQrCoERyaXZlciBjb21waWxhdGlvbiBhbmQgdGVzdGluZzxicj4NCsKgLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tPGJyPg0KPGJyPg0KZGlmZiAtLWdpdCBhL2RyaXZlcnMvbmV0L2lj ZS9pY2VfZXRoZGV2LmMgYi9kcml2ZXJzL25ldC9pY2UvaWNlX2V0aGRldi5jPGJyPg0KaW5kZXgg NzJlMTNmOTVmOC4uZDI4ZTIwNTM3NSAxMDA2NDQ8YnI+DQotLS0gYS9kcml2ZXJzL25ldC9pY2Uv aWNlX2V0aGRldi5jPGJyPg0KKysrIGIvZHJpdmVycy9uZXQvaWNlL2ljZV9ldGhkZXYuYzxicj4N CkBAIC0xMiw2ICsxMiw3IEBAPGJyPg0KwqAjaW5jbHVkZSAmbHQ7dW5pc3RkLmgmZ3Q7PGJyPg0K PGJyPg0KwqAjaW5jbHVkZSAmbHQ7cnRlX3RhaWxxLmgmZ3Q7PGJyPg0KKyNpbmNsdWRlICZsdDty dGVfb3Nfc2hpbS5oJmd0Ozxicj4NCjxicj4NCsKgI2luY2x1ZGUgJnF1b3Q7ZWFsX2Zpcm13YXJl LmgmcXVvdDs8YnI+DQo8YnI+DQpAQCAtMzQsNiArMzUsNyBAQDxicj4NCsKgI2RlZmluZSBJQ0Vf SFdfREVCVUdfTUFTS19BUkfCoCDCoCDCoCZxdW90O2h3X2RlYnVnX21hc2smcXVvdDs8YnI+DQrC oCNkZWZpbmUgSUNFX09ORV9QUFNfT1VUX0FSR8KgIMKgIMKgIMKgJnF1b3Q7cHBzX291dCZxdW90 Ozxicj4NCsKgI2RlZmluZSBJQ0VfUlhfTE9XX0xBVEVOQ1lfQVJHwqAgwqAgJnF1b3Q7cnhfbG93 X2xhdGVuY3kmcXVvdDs8YnI+DQorI2RlZmluZSBJQ0VfTUJVRl9DSEVDS19BUkfCoCDCoCDCoCDC oCZxdW90O21idWZfY2hlY2smcXVvdDs8YnI+DQo8YnI+DQrCoCNkZWZpbmUgSUNFX0NZQ0xFQ09V TlRFUl9NQVNLwqAgMHhmZmZmZmZmZmZmZmZmZmZmVUxMPGJyPg0KPGJyPg0KQEAgLTQ5LDYgKzUx LDcgQEAgc3RhdGljIGNvbnN0IGNoYXIgKiBjb25zdCBpY2VfdmFsaWRfYXJnc1tdID0gezxicj4N CsKgIMKgIMKgIMKgIElDRV9PTkVfUFBTX09VVF9BUkcsPGJyPg0KwqAgwqAgwqAgwqAgSUNFX1JY X0xPV19MQVRFTkNZX0FSRyw8YnI+DQrCoCDCoCDCoCDCoCBJQ0VfREVGQVVMVF9NQUNfRElTQUJM RSw8YnI+DQorwqAgwqAgwqAgwqBJQ0VfTUJVRl9DSEVDS19BUkcsPGJyPg0KwqAgwqAgwqAgwqAg TlVMTDxicj4NCsKgfTs8YnI+DQo8YnI+DQpAQCAtMzE5LDYgKzMyMiwxNCBAQCBzdGF0aWMgY29u c3Qgc3RydWN0IGljZV94c3RhdHNfbmFtZV9vZmYgaWNlX3N0YXRzX3N0cmluZ3NbXSA9IHs8YnI+ DQrCoCNkZWZpbmUgSUNFX05CX0VUSF9YU1RBVFMgKHNpemVvZihpY2Vfc3RhdHNfc3RyaW5ncykg LyBcPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgc2l6ZW9mKGljZV9zdGF0c19zdHJpbmdz WzBdKSk8YnI+DQo8YnI+DQorc3RhdGljIGNvbnN0IHN0cnVjdCBpY2VfeHN0YXRzX25hbWVfb2Zm IGljZV9tYnVmX3N0cmluZ3NbXSA9IHs8YnI+DQorwqAgwqAgwqAgwqB7JnF1b3Q7dHhfbWJ1Zl9l cnJvcl9wYWNrZXRzJnF1b3Q7LCBvZmZzZXRvZihzdHJ1Y3QgaWNlX21idWZfc3RhdHMsPGJyPg0K K8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgdHhfcGt0X2Vycm9ycyl9LDxicj4NCit9Ozxicj4NCis8 YnI+DQorI2RlZmluZSBJQ0VfTkJfTUJVRl9YU1RBVFMgKHNpemVvZihpY2VfbWJ1Zl9zdHJpbmdz KSAvIFw8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBzaXplb2YoaWNlX21idWZfc3RyaW5n c1swXSkpPGJyPg0KKzxicj4NCsKgc3RhdGljIGNvbnN0IHN0cnVjdCBpY2VfeHN0YXRzX25hbWVf b2ZmIGljZV9od19wb3J0X3N0cmluZ3NbXSA9IHs8YnI+DQrCoCDCoCDCoCDCoCB7JnF1b3Q7dHhf bGlua19kb3duX2Ryb3BwZWQmcXVvdDssIG9mZnNldG9mKHN0cnVjdCBpY2VfaHdfcG9ydF9zdGF0 cyw8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCB0eF9kcm9wcGVkX2xpbmtfZG93bil9LDxi cj4NCkBAIC0yMDYxLDYgKzIwNzIsNTggQEAgaGFuZGxlX3Bwc19vdXRfYXJnKF9fcnRlX3VudXNl ZCBjb25zdCBjaGFyICprZXksIGNvbnN0IGNoYXIgKnZhbHVlLDxicj4NCsKgIMKgIMKgIMKgIHJl dHVybiAwOzxicj4NCsKgfTxicj4NCjxicj4NCitzdGF0aWMgaW50PGJyPg0KK2ljZV9wYXJzZV9t YnVmX2NoZWNrKF9fcnRlX3VudXNlZCBjb25zdCBjaGFyICprZXksIGNvbnN0IGNoYXIgKnZhbHVl LCB2b2lkICphcmdzKTxicj4NCit7PGJyPg0KK8KgIMKgIMKgIMKgY2hhciAqY3VyOzxicj4NCivC oCDCoCDCoCDCoGNoYXIgKnRtcDs8YnI+DQorwqAgwqAgwqAgwqBpbnQgc3RyX2xlbjs8YnI+DQor wqAgwqAgwqAgwqBpbnQgdmFsaWRfbGVuOzxicj4NCis8YnI+DQorwqAgwqAgwqAgwqBpbnQgcmV0 ID0gMDs8YnI+DQorwqAgwqAgwqAgwqB1aW50NjRfdCAqbWNfZmxhZ3MgPSBhcmdzOzxicj4NCivC oCDCoCDCoCDCoGNoYXIgKnN0cjIgPSBzdHJkdXAodmFsdWUpOzxicj4NCivCoCDCoCDCoCDCoGlm IChzdHIyID09IE5VTEwpPGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgcmV0dXJuIC0xOzxi cj4NCis8YnI+DQorwqAgwqAgwqAgwqBzdHJfbGVuID0gc3RybGVuKHN0cjIpOzxicj4NCivCoCDC oCDCoCDCoGlmIChzdHJfbGVuID09IDApIHs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBy ZXQgPSAtMTs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBnb3RvIGVycl9lbmQ7PGJyPg0K K8KgIMKgIMKgIMKgfTxicj4NCis8YnI+DQorwqAgwqAgwqAgwqAvKiBUcnkgc3RyaXBwaW5nIHRo ZSBvdXRlciBzcXVhcmUgYnJhY2tldHMgb2YgdGhlIHBhcmFtZXRlciBzdHJpbmcuICovPGJyPg0K K8KgIMKgIMKgIMKgc3RyX2xlbiA9IHN0cmxlbihzdHIyKTs8YnI+DQorwqAgwqAgwqAgwqBpZiAo c3RyMlswXSA9PSAmIzM5O1smIzM5OyAmYW1wOyZhbXA7IHN0cjJbc3RyX2xlbiAtIDFdID09ICYj Mzk7XSYjMzk7KSB7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgaWYgKHN0cl9sZW4gJmx0 OyAzKSB7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgcmV0ID0gLTE7 PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgZ290byBlcnJfZW5kOzxi cj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoH08YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqB2YWxpZF9sZW4gPSBzdHJfbGVuIC0gMjs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBt ZW1tb3ZlKHN0cjIsIHN0cjIgKyAxLCB2YWxpZF9sZW4pOzxicj4NCivCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoG1lbXNldChzdHIyICsgdmFsaWRfbGVuLCAmIzM5O1wwJiMzOTssIDIpOzxicj4NCivC oCDCoCDCoCDCoH08YnI+DQorPGJyPg0KK8KgIMKgIMKgIMKgY3VyID0gc3RydG9rX3Ioc3RyMiwg JnF1b3Q7LCZxdW90OywgJmFtcDt0bXApOzxicj4NCivCoCDCoCDCoCDCoHdoaWxlIChjdXIgIT0g TlVMTCkgezxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGlmICghc3RyY21wKGN1ciwgJnF1 b3Q7bWJ1ZiZxdW90OykpPGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg Km1jX2ZsYWdzIHw9IElDRV9NQlVGX0NIRUNLX0ZfVFhfTUJVRjs8YnI+DQorwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqBlbHNlIGlmICghc3RyY21wKGN1ciwgJnF1b3Q7c2l6ZSZxdW90OykpPGJyPg0K K8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgKm1jX2ZsYWdzIHw9IElDRV9NQlVG X0NIRUNLX0ZfVFhfU0laRTs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBlbHNlIGlmICgh c3RyY21wKGN1ciwgJnF1b3Q7c2VnbWVudCZxdW90OykpPGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgKm1jX2ZsYWdzIHw9IElDRV9NQlVGX0NIRUNLX0ZfVFhfU0VHTUVO VDs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBlbHNlIGlmICghc3RyY21wKGN1ciwgJnF1 b3Q7b2ZmbG9hZCZxdW90OykpPGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgKm1jX2ZsYWdzIHw9IElDRV9NQlVGX0NIRUNLX0ZfVFhfT0ZGTE9BRDs8YnI+DQorwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqBlbHNlPGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgUE1EX0RSVl9MT0coRVJSLCAmcXVvdDtVbnN1cHBvcnRlZCBkaWFnbm9zdGljIHR5cGU6 ICVzJnF1b3Q7LCBjdXIpOzxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGN1ciA9IHN0cnRv a19yKE5VTEwsICZxdW90OywmcXVvdDssICZhbXA7dG1wKTs8YnI+DQorwqAgwqAgwqAgwqB9PGJy Pg0KKzxicj4NCitlcnJfZW5kOjxicj4NCivCoCDCoCDCoCDCoGZyZWUoc3RyMik7PGJyPg0KK8Kg IMKgIMKgIMKgcmV0dXJuIHJldDs8YnI+DQorfTxicj4NCis8YnI+DQrCoHN0YXRpYyBpbnQgaWNl X3BhcnNlX2RldmFyZ3Moc3RydWN0IHJ0ZV9ldGhfZGV2ICpkZXYpPGJyPg0KwqB7PGJyPg0KwqAg wqAgwqAgwqAgc3RydWN0IGljZV9hZGFwdGVyICphZCA9PGJyPg0KQEAgLTIxMTcsNiArMjE4MCwx MSBAQCBzdGF0aWMgaW50IGljZV9wYXJzZV9kZXZhcmdzKHN0cnVjdCBydGVfZXRoX2RldiAqZGV2 KTxicj4NCsKgIMKgIMKgIMKgIGlmIChyZXQpPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg Z290byBiYWlsOzxicj4NCjxicj4NCivCoCDCoCDCoCDCoHJldCA9IHJ0ZV9rdmFyZ3NfcHJvY2Vz cyhrdmxpc3QsIElDRV9NQlVGX0NIRUNLX0FSRyw8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgJmFtcDtpY2VfcGFyc2VfbWJ1Zl9jaGVjaywgJmFt cDthZC0mZ3Q7ZGV2YXJncy5tYnVmX2NoZWNrKTs8YnI+DQorwqAgwqAgwqAgwqBpZiAocmV0KTxi cj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGdvdG8gYmFpbDs8YnI+DQorPGJyPg0KwqAgwqAg wqAgwqAgcmV0ID0gcnRlX2t2YXJnc19wcm9jZXNzKGt2bGlzdCwgSUNFX1JYX0xPV19MQVRFTkNZ X0FSRyw8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCZhbXA7cGFyc2VfYm9vbCwgJmFtcDthZC0mZ3Q7ZGV2YXJncy5yeF9sb3dfbGF0ZW5jeSk7 PGJyPg0KPGJyPg0KQEAgLTYxNjEsNiArNjIyOSw5IEBAIGljZV9zdGF0c19yZXNldChzdHJ1Y3Qg cnRlX2V0aF9kZXYgKmRldik8YnI+DQrCoCDCoCDCoCDCoCAvKiByZWFkIHRoZSBzdGF0cywgcmVh ZGluZyBjdXJyZW50IHJlZ2lzdGVyIHZhbHVlcyBpbnRvIG9mZnNldCAqLzxicj4NCsKgIMKgIMKg IMKgIGljZV9yZWFkX3N0YXRzX3JlZ2lzdGVycyhwZiwgaHcpOzxicj4NCjxicj4NCivCoCDCoCDC oCDCoG1lbXNldCgmYW1wO3BmLSZndDttYnVmX3N0YXRzLCAwLDxicj4NCivCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoHNpemVvZihzdHJ1Y3QgaWNlX21idWZfc3RhdHMpKTs8YnI+DQorPGJyPg0KwqAg wqAgwqAgwqAgcmV0dXJuIDA7PGJyPg0KwqB9PGJyPg0KPGJyPg0KQEAgLTYxNjksMTcgKzYyNDAs MzMgQEAgaWNlX3hzdGF0c19jYWxjX251bSh2b2lkKTxicj4NCsKgezxicj4NCsKgIMKgIMKgIMKg IHVpbnQzMl90IG51bTs8YnI+DQo8YnI+DQotwqAgwqAgwqAgwqBudW0gPSBJQ0VfTkJfRVRIX1hT VEFUUyArIElDRV9OQl9IV19QT1JUX1hTVEFUUzs8YnI+DQorwqAgwqAgwqAgwqBudW0gPSBJQ0Vf TkJfRVRIX1hTVEFUUyArIElDRV9OQl9NQlVGX1hTVEFUUyArIElDRV9OQl9IV19QT1JUX1hTVEFU Uzs8YnI+DQo8YnI+DQrCoCDCoCDCoCDCoCByZXR1cm4gbnVtOzxicj4NCsKgfTxicj4NCjxicj4N CitzdGF0aWMgdm9pZDxicj4NCitpY2VfdXBkYXRlX21idWZfc3RhdHMoc3RydWN0IHJ0ZV9ldGhf ZGV2ICpldGhkZXYsPGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgc3RydWN0IGljZV9tYnVm X3N0YXRzICptYnVmX3N0YXRzKTxicj4NCit7PGJyPg0KK8KgIMKgIMKgIMKgdWludDE2X3QgaWR4 Ozxicj4NCivCoCDCoCDCoCDCoHN0cnVjdCBpY2VfdHhfcXVldWUgKnR4cTs8YnI+DQorPGJyPg0K K8KgIMKgIMKgIMKgZm9yIChpZHggPSAwOyBpZHggJmx0OyBldGhkZXYtJmd0O2RhdGEtJmd0O25i X3R4X3F1ZXVlczsgaWR4KyspIHs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB0eHEgPSBl dGhkZXYtJmd0O2RhdGEtJmd0O3R4X3F1ZXVlc1tpZHhdOzxicj4NCivCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoG1idWZfc3RhdHMtJmd0O3R4X3BrdF9lcnJvcnMgKz0gdHhxLSZndDttYnVmX2Vycm9y czs8YnI+DQorwqAgwqAgwqAgwqB9PGJyPg0KK308YnI+DQorPGJyPg0KwqBzdGF0aWMgaW50PGJy Pg0KwqBpY2VfeHN0YXRzX2dldChzdHJ1Y3QgcnRlX2V0aF9kZXYgKmRldiwgc3RydWN0IHJ0ZV9l dGhfeHN0YXQgKnhzdGF0cyw8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHVuc2lnbmVkIGlu dCBuKTxicj4NCsKgezxicj4NCsKgIMKgIMKgIMKgIHN0cnVjdCBpY2VfcGYgKnBmID0gSUNFX0RF Vl9QUklWQVRFX1RPX1BGKGRldi0mZ3Q7ZGF0YS0mZ3Q7ZGV2X3ByaXZhdGUpOzxicj4NCsKgIMKg IMKgIMKgIHN0cnVjdCBpY2VfaHcgKmh3ID0gSUNFX0RFVl9QUklWQVRFX1RPX0hXKGRldi0mZ3Q7 ZGF0YS0mZ3Q7ZGV2X3ByaXZhdGUpOzxicj4NCivCoCDCoCDCoCDCoHN0cnVjdCBpY2VfYWRhcHRl ciAqYWRhcHRlciA9PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgSUNFX0RFVl9QUklWQVRF X1RPX0FEQVBURVIoZGV2LSZndDtkYXRhLSZndDtkZXZfcHJpdmF0ZSk7PGJyPg0KK8KgIMKgIMKg IMKgc3RydWN0IGljZV9tYnVmX3N0YXRzIG1idWZfc3RhdHMgPSB7MH07PGJyPg0KwqAgwqAgwqAg wqAgdW5zaWduZWQgaW50IGk7PGJyPg0KwqAgwqAgwqAgwqAgdW5zaWduZWQgaW50IGNvdW50Ozxi cj4NCsKgIMKgIMKgIMKgIHN0cnVjdCBpY2VfaHdfcG9ydF9zdGF0cyAqaHdfc3RhdHMgPSAmYW1w O3BmLSZndDtzdGF0czs8YnI+DQpAQCAtNjE5NSw2ICs2MjgyLDkgQEAgaWNlX3hzdGF0c19nZXQo c3RydWN0IHJ0ZV9ldGhfZGV2ICpkZXYsIHN0cnVjdCBydGVfZXRoX3hzdGF0ICp4c3RhdHMsPGJy Pg0KPGJyPg0KwqAgwqAgwqAgwqAgY291bnQgPSAwOzxicj4NCjxicj4NCivCoCDCoCDCoCDCoGlm IChhZGFwdGVyLSZndDtkZXZhcmdzLm1idWZfY2hlY2spPGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKg IMKgIMKgaWNlX3VwZGF0ZV9tYnVmX3N0YXRzKGRldiwgJmFtcDttYnVmX3N0YXRzKTs8YnI+DQor PGJyPg0KwqAgwqAgwqAgwqAgLyogR2V0IHN0YXRzIGZyb20gaWNlX2V0aF9zdGF0cyBzdHJ1Y3Qg Ki88YnI+DQrCoCDCoCDCoCDCoCBmb3IgKGkgPSAwOyBpICZsdDsgSUNFX05CX0VUSF9YU1RBVFM7 IGkrKykgezxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHhzdGF0c1tjb3VudF0udmFsdWUg PTxicj4NCkBAIC02MjA0LDYgKzYyOTQsMTUgQEAgaWNlX3hzdGF0c19nZXQoc3RydWN0IHJ0ZV9l dGhfZGV2ICpkZXYsIHN0cnVjdCBydGVfZXRoX3hzdGF0ICp4c3RhdHMsPGJyPg0KwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgY291bnQrKzs8YnI+DQrCoCDCoCDCoCDCoCB9PGJyPg0KPGJyPg0KK8Kg IMKgIMKgIMKgLyogR2V0IHN0YXRzIGZyb20gaWNlX21idWZfc3RhdHMgc3RydWN0ICovPGJyPg0K K8KgIMKgIMKgIMKgZm9yIChpID0gMDsgaSAmbHQ7IElDRV9OQl9NQlVGX1hTVEFUUzsgaSsrKSB7 PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgeHN0YXRzW2NvdW50XS52YWx1ZSA9PGJyPg0K K8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgKih1aW50NjRfdCAqKSgoY2hhciAq KSZhbXA7bWJ1Zl9zdGF0cyArPGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgaWNlX21idWZfc3RyaW5nc1tpXS5vZmZzZXQpOzxi cj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHhzdGF0c1tjb3VudF0uaWQgPSBjb3VudDs8YnI+ DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBjb3VudCsrOzxicj4NCivCoCDCoCDCoCDCoH08YnI+ DQorPGJyPg0KwqAgwqAgwqAgwqAgLyogR2V0IGluZGl2aWR1YWwgc3RhdHMgZnJvbSBpY2VfaHdf cG9ydCBzdHJ1Y3QgKi88YnI+DQrCoCDCoCDCoCDCoCBmb3IgKGkgPSAwOyBpICZsdDsgSUNFX05C X0hXX1BPUlRfWFNUQVRTOyBpKyspIHs8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCB4c3Rh dHNbY291bnRdLnZhbHVlID08YnI+DQpAQCAtNjIzNSw2ICs2MzM0LDEzIEBAIHN0YXRpYyBpbnQg aWNlX3hzdGF0c19nZXRfbmFtZXMoX19ydGVfdW51c2VkIHN0cnVjdCBydGVfZXRoX2RldiAqZGV2 LDxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGNvdW50Kys7PGJyPg0KwqAgwqAgwqAgwqAg fTxicj4NCjxicj4NCivCoCDCoCDCoCDCoC8qIEdldCBzdGF0cyBmcm9tIGljZV9tYnVmX3N0YXRz IHN0cnVjdCAqLzxicj4NCivCoCDCoCDCoCDCoGZvciAoaSA9IDA7IGkgJmx0OyBJQ0VfTkJfTUJV Rl9YU1RBVFM7IGkrKykgezxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHN0cmxjcHkoeHN0 YXRzX25hbWVzW2NvdW50XS5uYW1lLCBpY2VfbWJ1Zl9zdHJpbmdzW2ldLm5hbWUsPGJyPg0KK8Kg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgc2l6ZW9mKHhzdGF0c19uYW1lc1tjb3Vu dF0ubmFtZSkpOzxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGNvdW50Kys7PGJyPg0KK8Kg IMKgIMKgIMKgfTxicj4NCis8YnI+DQrCoCDCoCDCoCDCoCAvKiBHZXQgaW5kaXZpZHVhbCBzdGF0 cyBmcm9tIGljZV9od19wb3J0IHN0cnVjdCAqLzxicj4NCsKgIMKgIMKgIMKgIGZvciAoaSA9IDA7 IGkgJmx0OyBJQ0VfTkJfSFdfUE9SVF9YU1RBVFM7IGkrKykgezxicj4NCsKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIHN0cmxjcHkoeHN0YXRzX25hbWVzW2NvdW50XS5uYW1lLCBpY2VfaHdfcG9ydF9z dHJpbmdzW2ldLm5hbWUsPGJyPg0KZGlmZiAtLWdpdCBhL2RyaXZlcnMvbmV0L2ljZS9pY2VfZXRo ZGV2LmggYi9kcml2ZXJzL25ldC9pY2UvaWNlX2V0aGRldi5oPGJyPg0KaW5kZXggZmE0OTgxZWQx NC4uZmEwYjdiZDIyNiAxMDA2NDQ8YnI+DQotLS0gYS9kcml2ZXJzL25ldC9pY2UvaWNlX2V0aGRl di5oPGJyPg0KKysrIGIvZHJpdmVycy9uZXQvaWNlL2ljZV9ldGhkZXYuaDxicj4NCkBAIC01MDcs NiArNTA3LDEwIEBAIHN0cnVjdCBpY2VfdG1fY29uZiB7PGJyPg0KwqAgwqAgwqAgwqAgYm9vbCBj bGVhcl9vbl9mYWlsOzxicj4NCsKgfTs8YnI+DQo8YnI+DQorc3RydWN0IGljZV9tYnVmX3N0YXRz IHs8YnI+DQorwqAgwqAgwqAgwqB1aW50NjRfdCB0eF9wa3RfZXJyb3JzOzxicj4NCit9Ozxicj4N Cis8YnI+DQrCoHN0cnVjdCBpY2VfcGYgezxicj4NCsKgIMKgIMKgIMKgIHN0cnVjdCBpY2VfYWRh cHRlciAqYWRhcHRlcjsgLyogVGhlIGFkYXB0ZXIgdGhpcyBQRiBhc3NvY2lhdGUgdG8gKi88YnI+ DQrCoCDCoCDCoCDCoCBzdHJ1Y3QgaWNlX3ZzaSAqbWFpbl92c2k7IC8qIHBvaW50ZXIgdG8gbWFp biBWU0kgc3RydWN0dXJlICovPGJyPg0KQEAgLTUzNiw2ICs1NDAsNyBAQCBzdHJ1Y3QgaWNlX3Bm IHs8YnI+DQrCoCDCoCDCoCDCoCB1aW50MTZfdCBmZGlyX2ZsdHJfY250W0lDRV9GTFRSX1BUWVBF X01BWF1bSUNFX0ZEX0hXX1NFR19NQVhdOzxicj4NCsKgIMKgIMKgIMKgIHN0cnVjdCBpY2VfaHdf cG9ydF9zdGF0cyBzdGF0c19vZmZzZXQ7PGJyPg0KwqAgwqAgwqAgwqAgc3RydWN0IGljZV9od19w b3J0X3N0YXRzIHN0YXRzOzxicj4NCivCoCDCoCDCoCDCoHN0cnVjdCBpY2VfbWJ1Zl9zdGF0cyBt YnVmX3N0YXRzOzxicj4NCsKgIMKgIMKgIMKgIC8qIGludGVybmFsIHBhY2tldCBzdGF0aXN0aWNz LCBpdCBzaG91bGQgYmUgZXhjbHVkZWQgZnJvbSB0aGUgdG90YWwgKi88YnI+DQrCoCDCoCDCoCDC oCBzdHJ1Y3QgaWNlX2V0aF9zdGF0cyBpbnRlcm5hbF9zdGF0c19vZmZzZXQ7PGJyPg0KwqAgwqAg wqAgwqAgc3RydWN0IGljZV9ldGhfc3RhdHMgaW50ZXJuYWxfc3RhdHM7PGJyPg0KQEAgLTU3NCw2 ICs1NzksNyBAQCBzdHJ1Y3QgaWNlX2RldmFyZ3Mgezxicj4NCsKgIMKgIMKgIMKgIHVpbnQ4X3Qg eHRyX2ZsYWdfb2Zmc1tQUk9UT19YVFJfTUFYXTs8YnI+DQrCoCDCoCDCoCDCoCAvKiBOYW1lIG9m IHRoZSBmaWVsZC4gKi88YnI+DQrCoCDCoCDCoCDCoCBjaGFyIHh0cl9maWVsZF9uYW1lW1JURV9N QlVGX0RZTl9OQU1FU0laRV07PGJyPg0KK8KgIMKgIMKgIMKgdWludDY0X3QgbWJ1Zl9jaGVjazs8 YnI+DQrCoH07PGJyPg0KPGJyPg0KwqAvKio8YnI+DQpAQCAtNTkyLDYgKzU5OCwyMSBAQCBzdHJ1 Y3QgaWNlX3Jzc19wcm9mX2luZm8gezxicj4NCsKgIMKgIMKgIMKgIGJvb2wgc3ltbTs8YnI+DQrC oH07PGJyPg0KPGJyPg0KKyNkZWZpbmUgSUNFX01CVUZfQ0hFQ0tfRl9UWF9NQlVGwqAgwqAgwqAg wqAgKDFVTEwgJmx0OyZsdDsgMCk8YnI+DQorI2RlZmluZSBJQ0VfTUJVRl9DSEVDS19GX1RYX1NJ WkXCoCDCoCDCoCDCoCAoMVVMTCAmbHQ7Jmx0OyAxKTxicj4NCisjZGVmaW5lIElDRV9NQlVGX0NI RUNLX0ZfVFhfU0VHTUVOVMKgIMKgIMKgKDFVTEwgJmx0OyZsdDsgMik8YnI+DQorI2RlZmluZSBJ Q0VfTUJVRl9DSEVDS19GX1RYX09GRkxPQUTCoCDCoCDCoCgxVUxMICZsdDsmbHQ7IDMpPGJyPg0K Kzxicj4NCitlbnVtIGljZV90eF9idXJzdF90eXBlIHs8YnI+DQorwqAgwqAgwqAgwqBJQ0VfVFhf REVGQVVMVCw8YnI+DQorwqAgwqAgwqAgwqBJQ0VfVFhfU0lNUExFLDxicj4NCivCoCDCoCDCoCDC oElDRV9UWF9WRUNfU1NFLDxicj4NCivCoCDCoCDCoCDCoElDRV9UWF9WRUNfQVZYMiw8YnI+DQor wqAgwqAgwqAgwqBJQ0VfVFhfVkVDX0FWWDJfT0ZGTE9BRCw8YnI+DQorwqAgwqAgwqAgwqBJQ0Vf VFhfVkVDX0FWWDUxMiw8YnI+DQorwqAgwqAgwqAgwqBJQ0VfVFhfVkVDX0FWWDUxMl9PRkZMT0FE LDxicj4NCit9Ozxicj4NCis8YnI+DQrCoC8qKjxicj4NCsKgICogU3RydWN0dXJlIHRvIHN0b3Jl IHByaXZhdGUgZGF0YSBmb3IgZWFjaCBQRi9WRiBpbnN0YW5jZS48YnI+DQrCoCAqLzxicj4NCkBA IC02MDksNiArNjMwLDggQEAgc3RydWN0IGljZV9hZGFwdGVyIHs8YnI+DQrCoCDCoCDCoCDCoCBz dHJ1Y3QgaWNlX2RldmFyZ3MgZGV2YXJnczs8YnI+DQrCoCDCoCDCoCDCoCBlbnVtIGljZV9wa2df dHlwZSBhY3RpdmVfcGtnX3R5cGU7IC8qIGxvYWRlZCBkZHAgcGFja2FnZSB0eXBlICovPGJyPg0K wqAgwqAgwqAgwqAgdWludDE2X3QgZmRpcl9yZWZfY250Ozxicj4NCivCoCDCoCDCoCDCoC8qIEZv ciB2ZWN0b3IgUE1EICovPGJyPg0KK8KgIMKgIMKgIMKgZW51bSBpY2VfdHhfYnVyc3RfdHlwZSB0 eF9idXJzdF90eXBlOzxicj4NCsKgIMKgIMKgIMKgIC8qIEZvciBQVFAgKi88YnI+DQrCoCDCoCDC oCDCoCBzdHJ1Y3QgcnRlX3RpbWVjb3VudGVyIHN5c3RpbWVfdGM7PGJyPg0KwqAgwqAgwqAgwqAg c3RydWN0IHJ0ZV90aW1lY291bnRlciByeF90c3RhbXBfdGM7PGJyPg0KZGlmZiAtLWdpdCBhL2Ry aXZlcnMvbmV0L2ljZS9pY2Vfcnh0eC5jIGIvZHJpdmVycy9uZXQvaWNlL2ljZV9yeHR4LmM8YnI+ DQppbmRleCA3M2U0N2FlOTJkLi5mZGZmZTE3OTI1IDEwMDY0NDxicj4NCi0tLSBhL2RyaXZlcnMv bmV0L2ljZS9pY2Vfcnh0eC5jPGJyPg0KKysrIGIvZHJpdmVycy9uZXQvaWNlL2ljZV9yeHR4LmM8 YnI+DQpAQCAtMzY3OCw2ICszNjc4LDEzMiBAQCBpY2VfY2hlY2tfZW1wdHlfbWJ1ZihzdHJ1Y3Qg cnRlX21idWYgKnR4X3BrdCk8YnI+DQrCoCDCoCDCoCDCoCByZXR1cm4gMDs8YnI+DQrCoH08YnI+ DQo8YnI+DQorc3RhdGljPGJyPg0KK2NvbnN0IGV0aF90eF9idXJzdF90IGljZV90eF9wa3RfYnVy c3Rfb3BzW10gPSB7PGJyPg0KK8KgIMKgIMKgIMKgW0lDRV9UWF9ERUZBVUxUXSA9IGljZV94bWl0 X3BrdHMsPGJyPg0KK8KgIMKgIMKgIMKgW0lDRV9UWF9TSU1QTEVdID0gaWNlX3htaXRfcGt0c19z aW1wbGUsPGJyPg0KKyNpZmRlZiBSVEVfQVJDSF9YODY8YnI+DQorwqAgwqAgwqAgwqBbSUNFX1RY X1ZFQ19TU0VdID0gaWNlX3htaXRfcGt0c192ZWMsPGJyPg0KK8KgIMKgIMKgIMKgW0lDRV9UWF9W RUNfQVZYMl0gPSBpY2VfeG1pdF9wa3RzX3ZlY19hdngyLDxicj4NCivCoCDCoCDCoCDCoFtJQ0Vf VFhfVkVDX0FWWDJfT0ZGTE9BRF0gPSBpY2VfeG1pdF9wa3RzX3ZlY19hdngyX29mZmxvYWQsPGJy Pg0KKyNpZmRlZiBDQ19BVlg1MTJfU1VQUE9SVDxicj4NCivCoCDCoCDCoCDCoFtJQ0VfVFhfVkVD X0FWWDUxMl0gPSBpY2VfeG1pdF9wa3RzX3ZlY19hdng1MTIsPGJyPg0KK8KgIMKgIMKgIMKgW0lD RV9UWF9WRUNfQVZYNTEyX09GRkxPQURdID0gaWNlX3htaXRfcGt0c192ZWNfYXZ4NTEyX29mZmxv YWQsPGJyPg0KKyNlbmRpZjxicj4NCisjZW5kaWY8YnI+DQorfTs8YnI+DQorPGJyPg0KKy8qIFR4 IG1idWYgY2hlY2sgKi88YnI+DQorc3RhdGljIHVpbnQxNl90PGJyPg0KK2ljZV94bWl0X3BrdHNf Y2hlY2sodm9pZCAqdHhfcXVldWUsIHN0cnVjdCBydGVfbWJ1ZiAqKnR4X3BrdHMsPGJyPg0KK8Kg IMKgIMKgIMKgIMKgIMKgIMKgdWludDE2X3QgbmJfcGt0cyk8YnI+DQorezxicj4NCivCoCDCoCDC oCDCoHN0cnVjdCBpY2VfdHhfcXVldWUgKnR4cSA9IHR4X3F1ZXVlOzxicj4NCivCoCDCoCDCoCDC oHVpbnQxNl90IGlkeDs8YnI+DQorwqAgwqAgwqAgwqBzdHJ1Y3QgcnRlX21idWYgKm1iOzxicj4N CivCoCDCoCDCoCDCoGJvb2wgcGt0X2Vycm9yID0gZmFsc2U7PGJyPg0KK8KgIMKgIMKgIMKgdWlu dDE2X3QgZ29vZF9wa3RzID0gbmJfcGt0czs8YnI+DQorwqAgwqAgwqAgwqBjb25zdCBjaGFyICpy ZWFzb24gPSBOVUxMOzxicj4NCivCoCDCoCDCoCDCoHN0cnVjdCBpY2VfYWRhcHRlciAqYWRhcHRl ciA9IHR4cS0mZ3Q7dnNpLSZndDthZGFwdGVyOzxicj4NCivCoCDCoCDCoCDCoGVudW0gaWNlX3R4 X2J1cnN0X3R5cGUgdHhfYnVyc3RfdHlwZSA9PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKg dHhxLSZndDt2c2ktJmd0O2FkYXB0ZXItJmd0O3R4X2J1cnN0X3R5cGU7PGJyPg0KK8KgIMKgIMKg IMKgdWludDY0X3Qgb2xfZmxhZ3M7PGJyPg0KKzxicj4NCivCoCDCoCDCoCDCoGZvciAoaWR4ID0g MDsgaWR4ICZsdDsgbmJfcGt0czsgaWR4KyspIHs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqBtYiA9IHR4X3BrdHNbaWR4XTs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBvbF9mbGFn cyA9IG1iLSZndDtvbF9mbGFnczs8YnI+DQorPGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKg aWYgKChhZGFwdGVyLSZndDtkZXZhcmdzLm1idWZfY2hlY2sgJmFtcDsgSUNFX01CVUZfQ0hFQ0tf Rl9UWF9NQlVGKSAmYW1wOyZhbXA7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgKHJ0ZV9tYnVmX2NoZWNrKG1iLCAwLCAmYW1wO3JlYXNvbikgIT0gMCkpIHs8YnI+DQor wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBQTURfVFhfTE9HKEVSUiwgJnF1b3Q7 SU5WQUxJRCBtYnVmOiAlc1xuJnF1b3Q7LCByZWFzb24pOzxicj4NCivCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoHBrdF9lcnJvciA9IHRydWU7PGJyPg0KK8KgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgYnJlYWs7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKg fTxicj4NCis8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBpZiAoKGFkYXB0ZXItJmd0O2Rl dmFyZ3MubWJ1Zl9jaGVjayAmYW1wOyBJQ0VfTUJVRl9DSEVDS19GX1RYX1NJWkUpICZhbXA7JmFt cDs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAobWItJmd0O2RhdGFf bGVuICZndDsgbWItJmd0O3BrdF9sZW4gfHw8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqBtYi0mZ3Q7ZGF0YV9sZW4gJmx0OyBJQ0VfVFhfTUlOX1BLVF9MRU4gfHw8YnI+ DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBtYi0mZ3Q7ZGF0YV9sZW4gJmd0 OyBJQ0VfRlJBTUVfU0laRV9NQVgpKSB7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgUE1EX1RYX0xPRyhFUlIsICZxdW90O0lOVkFMSUQgbWJ1ZjogZGF0YV9sZW4gKCV1 KSBpcyBvdXQgJnF1b3Q7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg JnF1b3Q7b2YgcmFuZ2UsIHJlYXNvbmFibGUgcmFuZ2UgKCVkIC0gJWQpXG4mcXVvdDssIG1iLSZn dDtkYXRhX2xlbiw8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBJQ0Vf VFhfTUlOX1BLVF9MRU4sIElDRV9GUkFNRV9TSVpFX01BWCk7PGJyPg0KK8KgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgcGt0X2Vycm9yID0gdHJ1ZTs8YnI+DQorwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBicmVhazs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqB9PGJyPg0KKzxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGlmIChhZGFwdGVyLSZndDtk ZXZhcmdzLm1idWZfY2hlY2sgJmFtcDsgSUNFX01CVUZfQ0hFQ0tfRl9UWF9TRUdNRU5UKSB7PGJy Pg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgaWYgKCEob2xfZmxhZ3MgJmFt cDsgUlRFX01CVUZfRl9UWF9UQ1BfU0VHKSkgezxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoC8qKjxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAqIE5vIFRTTyBjYXNlOiBuYi0mZ3Q7c2VncywgcGt0 X2xlbiB0byBub3QgZXhjZWVkPGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgICogdGhlIGxpbWl0ZXMuPGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgICovPGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgaWYgKG1iLSZndDtuYl9zZWdzICZndDsgSUNFX1RY X01UVV9TRUdfTUFYKSB7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgUE1EX1RYX0xPRyhFUlIsICZxdW90O0lOVkFMSUQgbWJ1 ZjogbmJfc2VncyAoJWQpIGV4Y2VlZHMgJnF1b3Q7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgJnF1b3Q7SFcgbGltaXQsIG1h eGltdW0gYWxsb3dlZCB2YWx1ZSBpcyAlZFxuJnF1b3Q7LCBtYi0mZ3Q7bmJfc2Vncyw8YnI+DQor wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqBJQ0VfVFhfTVRVX1NFR19NQVgpOzxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHBrdF9lcnJvciA9IHRydWU7PGJyPg0KK8Kg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg YnJlYWs7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgfTxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oGlmIChtYi0mZ3Q7cGt0X2xlbiAmZ3Q7IElDRV9GUkFNRV9TSVpFX01BWCkgezxicj4NCivCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoFBN RF9UWF9MT0coRVJSLCAmcXVvdDtJTlZBTElEIG1idWY6IHBrdF9sZW4gKCVkKSBleGNlZWRzICZx dW90Ozxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCZxdW90O0hXIGxpbWl0LCBtYXhpbXVtIGFsbG93ZWQgdmFsdWUgaXMgJWRc biZxdW90OywgbWItJmd0O25iX3NlZ3MsPGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgSUNFX0ZSQU1FX1NJWkVfTUFYKTs8YnI+ DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqBwa3RfZXJyb3IgPSB0cnVlOzxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGJyZWFrOzxicj4NCivCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoH08YnI+DQorwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqB9IGVsc2UgaWYgKG9sX2ZsYWdzICZhbXA7IFJURV9NQlVGX0Zf VFhfVENQX1NFRykgezxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoC8qKiBUU08gY2FzZTogdHNvX3NlZ3N6LCBuYl9zZWdzLCBwa3RfbGVuIG5vdCBl eGNlZWQ8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgKiB0aGUgbGltaXRzLjxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCAqLzxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoGlmIChtYi0mZ3Q7dHNvX3NlZ3N6ICZsdDsgSUNFX01JTl9UU09fTVNTIHx8 PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgbWItJmd0O3Rzb19zZWdzeiAmZ3Q7IElDRV9NQVhfVFNPX01TUykgezxicj4NCivC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oC8qKjxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCAqIE1TUyBvdXRzaWRlIHRoZSByYW5nZSBhcmUgY29uc2lkZXJlZCBtYWxp Y2lvdXM8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgKi88YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBQTURfVFhfTE9HKEVSUiwgJnF1b3Q7SU5WQUxJRCBt YnVmOiB0c29fc2Vnc3ogKCV1KSBpcyBvdXQgJnF1b3Q7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgJnF1b3Q7b2YgcmFuZ2Us IHJlYXNvbmFibGUgcmFuZ2UgKCVkIC0gJXUpXG4mcXVvdDssIG1iLSZndDt0c29fc2Vnc3osPGJy Pg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgSUNFX01JTl9UU09fTVNTLCBJQ0VfTUFYX1RTT19NU1MpOzxicj4NCivCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHBrdF9lcnJv ciA9IHRydWU7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgYnJlYWs7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgfTxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoGlmIChtYi0mZ3Q7bmJfc2VncyAmZ3Q7PGJyPg0KK8KgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgKChzdHJ1 Y3QgaWNlX3R4X3F1ZXVlICopdHhfcXVldWUpLSZndDtuYl90eF9kZXNjKSB7PGJyPg0KK8KgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgUE1E X1RYX0xPRyhFUlIsICZxdW90O0lOVkFMSUQgbWJ1ZjogbmJfc2VncyBvdXQgJnF1b3Q7PGJyPg0K K8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgJnF1b3Q7b2YgcmluZyBsZW5ndGhcbiZxdW90Oyk7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgcGt0X2Vycm9yID0gdHJ1 ZTs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqBicmVhazs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqB9PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg fTxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoH08YnI+DQorPGJyPg0KK8KgIMKgIMKgIMKg IMKgIMKgIMKgIMKgaWYgKGFkYXB0ZXItJmd0O2RldmFyZ3MubWJ1Zl9jaGVjayAmYW1wOyBJQ0Vf TUJVRl9DSEVDS19GX1RYX09GRkxPQUQpIHs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqBpZiAob2xfZmxhZ3MgJmFtcDsgSUNFX1RYX09GRkxPQURfTk9UU1VQX01BU0sp IHs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBQ TURfVFhfTE9HKEVSUiwgJnF1b3Q7SU5WQUxJRCBtYnVmOiBUWCBvZmZsb2FkICZxdW90Ozxicj4N CivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCZxdW90O2lz IG5vdCBzdXBwb3J0ZWRcbiZxdW90Oyk7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgcGt0X2Vycm9yID0gdHJ1ZTs8YnI+DQorwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBicmVhazs8YnI+DQorwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB9PGJyPg0KKzxicj4NCivCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoGlmICghcnRlX3ZhbGlkYXRlX3R4X29mZmxvYWQobWIpKSB7PGJy Pg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgUE1EX1RY X0xPRyhFUlIsICZxdW90O0lOVkFMSUQgbWJ1ZjogVFggb2ZmbG9hZCAmcXVvdDs8YnI+DQorwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAmcXVvdDtzZXR1cCBl cnJvclxuJnF1b3Q7KTs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqBwa3RfZXJyb3IgPSB0cnVlOzxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGJyZWFrOzxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoH08YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB9PGJyPg0KK8Kg IMKgIMKgIMKgfTxicj4NCis8YnI+DQorwqAgwqAgwqAgwqBpZiAocGt0X2Vycm9yKSB7PGJyPg0K K8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgdHhxLSZndDttYnVmX2Vycm9ycysrOzxicj4NCivCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoGdvb2RfcGt0cyA9IGlkeDs8YnI+DQorwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqBpZiAoZ29vZF9wa3RzID09IDApPGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgcmV0dXJuIDA7PGJyPg0KK8KgIMKgIMKgIMKgfTxicj4NCis8YnI+DQorwqAg wqAgwqAgwqByZXR1cm4gaWNlX3R4X3BrdF9idXJzdF9vcHNbdHhfYnVyc3RfdHlwZV0odHhfcXVl dWUsPGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg dHhfcGt0cywgZ29vZF9wa3RzKTs8YnI+DQorfTxicj4NCis8YnI+DQrCoHVpbnQxNl90PGJyPg0K wqBpY2VfcHJlcF9wa3RzKHZvaWQgKnR4X3F1ZXVlLCBzdHJ1Y3QgcnRlX21idWYgKip0eF9wa3Rz LDxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIHVpbnQxNl90IG5iX3BrdHMpPGJyPg0KQEAgLTM3 NDYsNiArMzg3Miw4IEBAIGljZV9zZXRfdHhfZnVuY3Rpb24oc3RydWN0IHJ0ZV9ldGhfZGV2ICpk ZXYpPGJyPg0KwqB7PGJyPg0KwqAgwqAgwqAgwqAgc3RydWN0IGljZV9hZGFwdGVyICphZCA9PGJy Pg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgSUNFX0RFVl9QUklWQVRFX1RPX0FEQVBURVIoZGV2 LSZndDtkYXRhLSZndDtkZXZfcHJpdmF0ZSk7PGJyPg0KK8KgIMKgIMKgIMKgZW51bSBpY2VfdHhf YnVyc3RfdHlwZSB0eF9idXJzdF90eXBlID0gSUNFX1RYX0RFRkFVTFQ7PGJyPg0KK8KgIMKgIMKg IMKgaW50IG1idWZfY2hlY2sgPSBhZC0mZ3Q7ZGV2YXJncy5tYnVmX2NoZWNrOzxicj4NCsKgI2lm ZGVmIFJURV9BUkNIX1g4Njxicj4NCsKgIMKgIMKgIMKgIHN0cnVjdCBpY2VfdHhfcXVldWUgKnR4 cTs8YnI+DQrCoCDCoCDCoCDCoCBpbnQgaTs8YnI+DQpAQCAtMzgwMCwxNCArMzkyOCwxMyBAQCBp Y2Vfc2V0X3R4X2Z1bmN0aW9uKHN0cnVjdCBydGVfZXRoX2RldiAqZGV2KTxicj4NCsKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIFBNRF9EUlZfTE9HKE5PVElD RSw8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCAmcXVvdDtVc2luZyBBVlg1MTIgT0ZGTE9BRCBWZWN0b3IgVHggKHBv cnQgJWQpLiZxdW90Oyw8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBkZXYtJmd0O2RhdGEtJmd0O3BvcnRfaWQpOzxi cj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGRldi0m Z3Q7dHhfcGt0X2J1cnN0ID08YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBpY2VfeG1pdF9wa3RzX3ZlY19hdng1MTJfb2ZmbG9h ZDs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB0 eF9idXJzdF90eXBlID0gSUNFX1RYX1ZFQ19BVlg1MTJfT0ZGTE9BRDs8YnI+DQrCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBkZXYtJmd0O3R4X3BrdF9wcmVw YXJlID0gaWNlX3ByZXBfcGt0czs8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCB9IGVsc2Ugezxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIFBNRF9EUlZfTE9HKE5PVElDRSw8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAmcXVvdDtVc2luZyBB Vlg1MTIgVmVjdG9yIFR4IChwb3J0ICVkKS4mcXVvdDssPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgZGV2LSZndDtk YXRhLSZndDtwb3J0X2lkKTs8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqBkZXYtJmd0O3R4X3BrdF9idXJzdCA9IGljZV94bWl0X3BrdHNfdmVjX2F2 eDUxMjs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqB0eF9idXJzdF90eXBlID0gSUNFX1RYX1ZFQ19BVlg1MTI7PGJyPg0KwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgfTxicj4NCsKgI2VuZGlmPGJyPg0KwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgfSBlbHNlIHs8YnI+DQpAQCAtMzgxNSwzMiArMzk0Miw0MyBAQCBpY2Vfc2V0X3R4 X2Z1bmN0aW9uKHN0cnVjdCBydGVfZXRoX2RldiAqZGV2KTxicj4NCsKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIFBNRF9EUlZfTE9HKE5PVElDRSw8YnI+DQrC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCAmcXVvdDtVc2luZyBBVlgyIE9GRkxPQUQgVmVjdG9yIFR4IChwb3J0ICVkKS4mcXVv dDssPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgZGV2LSZndDtkYXRhLSZndDtwb3J0X2lkKTs8YnI+DQotwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBkZXYtJmd0O3R4X3BrdF9i dXJzdCA9PGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgaWNlX3htaXRfcGt0c192ZWNfYXZ4Ml9vZmZsb2FkOzxicj4NCivCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHR4X2J1cnN0X3R5cGUg PSBJQ0VfVFhfVkVDX0FWWDJfT0ZGTE9BRDs8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBkZXYtJmd0O3R4X3BrdF9wcmVwYXJlID0gaWNlX3ByZXBf cGt0czs8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCB9IGVsc2Ugezxi cj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIFBNRF9E UlZfTE9HKERFQlVHLCAmcXVvdDtVc2luZyAlc1ZlY3RvciBUeCAocG9ydCAlZCkuJnF1b3Q7LDxi cj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIGFkLSZndDt0eF91c2VfYXZ4MiA/ICZxdW90O2F2eDIgJnF1b3Q7IDogJnF1 b3Q7JnF1b3Q7LDxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGRldi0mZ3Q7ZGF0YS0mZ3Q7cG9ydF9pZCk7PGJyPg0K LcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgZGV2LSZndDt0 eF9wa3RfYnVyc3QgPSBhZC0mZ3Q7dHhfdXNlX2F2eDIgPzxicj4NCi3CoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoGljZV94bWl0X3BrdHNfdmVjX2F2eDIgOjxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGlj ZV94bWl0X3BrdHNfdmVjOzxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoHR4X2J1cnN0X3R5cGUgPSBhZC0mZ3Q7dHhfdXNlX2F2eDIgPzxicj4NCivC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoElDRV9UWF9WRUNfQVZYMiA6IElDRV9UWF9WRUNfU1NF Ozxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIH08YnI+DQrCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCB9PGJyPg0KPGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgaWYg KG1idWZfY2hlY2spIHs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBh ZC0mZ3Q7dHhfYnVyc3RfdHlwZSA9IHR4X2J1cnN0X3R5cGU7PGJyPg0KK8KgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgZGV2LSZndDt0eF9wa3RfYnVyc3QgPSBpY2VfeG1pdF9wa3Rz X2NoZWNrOzxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoH0gZWxzZSB7PGJyPg0KK8KgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgZGV2LSZndDt0eF9wa3RfYnVyc3QgPSBpY2Vf dHhfcGt0X2J1cnN0X29wc1t0eF9idXJzdF90eXBlXTs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqB9PGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgcmV0dXJuOzxicj4NCsKgIMKgIMKg IMKgIH08YnI+DQrCoCNlbmRpZjxicj4NCjxicj4NCsKgIMKgIMKgIMKgIGlmIChhZC0mZ3Q7dHhf c2ltcGxlX2FsbG93ZWQpIHs8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBQTURfSU5JVF9M T0coREVCVUcsICZxdW90O1NpbXBsZSB0eCBmaW5hbGx5IGJlIHVzZWQuJnF1b3Q7KTs8YnI+DQot wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBkZXYtJmd0O3R4X3BrdF9idXJzdCA9IGljZV94bWl0X3Br dHNfc2ltcGxlOzxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHR4X2J1cnN0X3R5cGUgPSBJ Q0VfVFhfU0lNUExFOzxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGRldi0mZ3Q7dHhfcGt0 X3ByZXBhcmUgPSBOVUxMOzxicj4NCsKgIMKgIMKgIMKgIH0gZWxzZSB7PGJyPg0KwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgUE1EX0lOSVRfTE9HKERFQlVHLCAmcXVvdDtOb3JtYWwgdHggZmluYWxs eSBiZSB1c2VkLiZxdW90Oyk7PGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgZGV2LSZndDt0 eF9wa3RfYnVyc3QgPSBpY2VfeG1pdF9wa3RzOzxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oHR4X2J1cnN0X3R5cGUgPSBJQ0VfVFhfREVGQVVMVDs8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCBkZXYtJmd0O3R4X3BrdF9wcmVwYXJlID0gaWNlX3ByZXBfcGt0czs8YnI+DQrCoCDCoCDC oCDCoCB9PGJyPg0KKzxicj4NCivCoCDCoCDCoCDCoGlmIChtYnVmX2NoZWNrKSB7PGJyPg0KK8Kg IMKgIMKgIMKgIMKgIMKgIMKgIMKgYWQtJmd0O3R4X2J1cnN0X3R5cGUgPSB0eF9idXJzdF90eXBl Ozxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGRldi0mZ3Q7dHhfcGt0X2J1cnN0ID0gaWNl X3htaXRfcGt0c19jaGVjazs8YnI+DQorwqAgwqAgwqAgwqB9IGVsc2Ugezxicj4NCivCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoGRldi0mZ3Q7dHhfcGt0X2J1cnN0ID0gaWNlX3R4X3BrdF9idXJzdF9v cHNbdHhfYnVyc3RfdHlwZV07PGJyPg0KK8KgIMKgIMKgIMKgfTxicj4NCsKgfTxicj4NCjxicj4N CsKgc3RhdGljIGNvbnN0IHN0cnVjdCB7PGJyPg0KZGlmZiAtLWdpdCBhL2RyaXZlcnMvbmV0L2lj ZS9pY2Vfcnh0eC5oIGIvZHJpdmVycy9uZXQvaWNlL2ljZV9yeHR4Lmg8YnI+DQppbmRleCBiZDJj NGFiZWM5Li4wODhkZGJhNjAwIDEwMDY0NDxicj4NCi0tLSBhL2RyaXZlcnMvbmV0L2ljZS9pY2Vf cnh0eC5oPGJyPg0KKysrIGIvZHJpdmVycy9uZXQvaWNlL2ljZV9yeHR4Lmg8YnI+DQpAQCAtNDUs NiArNDUsMjUgQEA8YnI+DQo8YnI+DQrCoCNkZWZpbmUgSUNFX1RYX01JTl9QS1RfTEVOIDE3PGJy Pg0KPGJyPg0KKyNkZWZpbmUgSUNFX1RYX09GRkxPQURfTUFTSyAowqAgwqAgXDxicj4NCivCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoFJURV9NQlVGX0ZfVFhfT1VURVJfSVBWNiB8wqAgwqAgwqAgwqBc PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgUlRFX01CVUZfRl9UWF9PVVRFUl9JUFY0IHzC oCDCoCDCoCDCoFw8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBSVEVfTUJVRl9GX1RYX09V VEVSX0lQX0NLU1VNIHzCoCBcPGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgUlRFX01CVUZf Rl9UWF9WTEFOIHzCoCDCoCDCoCDCoCBcPGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgUlRF X01CVUZfRl9UWF9JUFY2IHzCoCDCoCDCoCDCoCDCoCDCoCDCoFw8YnI+DQorwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqBSVEVfTUJVRl9GX1RYX0lQVjQgfMKgIMKgIMKgIMKgIMKgIMKgIMKgXDxicj4N CivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoFJURV9NQlVGX0ZfVFhfSVBfQ0tTVU0gfMKgIMKgIMKg IMKgIFw8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBSVEVfTUJVRl9GX1RYX0w0X01BU0sg fMKgIMKgIMKgIMKgIMKgXDxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoFJURV9NQlVGX0Zf VFhfSUVFRTE1ODhfVE1TVCB8wqAgwqAgXDxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoFJU RV9NQlVGX0ZfVFhfVENQX1NFRyB8wqAgwqAgwqAgwqAgwqBcPGJyPg0KK8KgIMKgIMKgIMKgIMKg IMKgIMKgIMKgUlRFX01CVUZfRl9UWF9RSU5RIHzCoCDCoCDCoCDCoCBcPGJyPg0KK8KgIMKgIMKg IMKgIMKgIMKgIMKgIMKgUlRFX01CVUZfRl9UWF9UVU5ORUxfTUFTSyB8wqAgwqAgwqAgXDxicj4N CivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoFJURV9NQlVGX0ZfVFhfVURQX1NFRyB8wqAgXDxicj4N CivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoFJURV9NQlVGX0ZfVFhfT1VURVJfVURQX0NLU1VNKTxi cj4NCis8YnI+DQorI2RlZmluZSBJQ0VfVFhfT0ZGTE9BRF9OT1RTVVBfTUFTSyBcPGJyPg0KK8Kg IMKgIMKgIMKgIMKgIMKgIMKgIMKgKFJURV9NQlVGX0ZfVFhfT0ZGTE9BRF9NQVNLIF4gSUNFX1RY X09GRkxPQURfTUFTSyk8YnI+DQorPGJyPg0KwqBleHRlcm4gdWludDY0X3QgaWNlX3RpbWVzdGFt cF9keW5mbGFnOzxicj4NCsKgZXh0ZXJuIGludCBpY2VfdGltZXN0YW1wX2R5bmZpZWxkX29mZnNl dDs8YnI+DQo8YnI+DQpAQCAtMTY0LDYgKzE4Myw3IEBAIHN0cnVjdCBpY2VfdHhfcXVldWUgezxi cj4NCsKgIMKgIMKgIMKgIHN0cnVjdCBpY2VfdnNpICp2c2k7IC8qIHRoZSBWU0kgdGhpcyBxdWV1 ZSBiZWxvbmdzIHRvICovPGJyPg0KwqAgwqAgwqAgwqAgdWludDE2X3QgdHhfbmV4dF9kZDs8YnI+ DQrCoCDCoCDCoCDCoCB1aW50MTZfdCB0eF9uZXh0X3JzOzxicj4NCivCoCDCoCDCoCDCoHVpbnQ2 NF90IG1idWZfZXJyb3JzOzxicj4NCsKgIMKgIMKgIMKgIGJvb2wgdHhfZGVmZXJyZWRfc3RhcnQ7 IC8qIGRvbiYjMzk7dCBzdGFydCB0aGlzIHF1ZXVlIGluIGRldiBzdGFydCAqLzxicj4NCsKgIMKg IMKgIMKgIGJvb2wgcV9zZXQ7IC8qIGluZGljYXRlIGlmIHR4IHF1ZXVlIGhhcyBiZWVuIGNvbmZp Z3VyZWQgKi88YnI+DQrCoCDCoCDCoCDCoCBpY2VfdHhfcmVsZWFzZV9tYnVmc190IHR4X3JlbF9t YnVmczs8YnI+DQotLSA8YnI+DQoyLjI1LjE8YnI+DQo8YnI+DQo8L2Jsb2NrcXVvdGU+PC9kaXY+ PGJyIGNsZWFyPSJhbGwiPjxkaXY+PGJyPjwvZGl2PjwvZGl2Pg0K --0000000000004f51e506129ba939--