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 69CFF440F4; Tue, 28 May 2024 18:33:56 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 52D33402E4; Tue, 28 May 2024 18:33:56 +0200 (CEST) Received: from mail-lf1-f47.google.com (mail-lf1-f47.google.com [209.85.167.47]) by mails.dpdk.org (Postfix) with ESMTP id AE5334025D for ; Tue, 28 May 2024 18:33:54 +0200 (CEST) Received: by mail-lf1-f47.google.com with SMTP id 2adb3069b0e04-529c0d5001eso141150e87.3 for ; Tue, 28 May 2024 09:33:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iol.unh.edu; s=unh-iol; t=1716914034; x=1717518834; 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=Ty3fn9KLlUbkBYaC8FAcJnuCWyaC/2w1uaNacPgw5QU=; b=HLjgpC3R19m2uNv3XpldTUsq4Zz7e5u9VGMV3qTP4dmlXAHlRD0IRj8PLJ0ZQpuvsY 2MlOl6YareJ2+qbxBXN4itWZo4qcon8Jg0WYP7j0xaCnVCLncoYCdfIvjFVXjsiDrI8f YLjQxX9yvHXOjbpQDScviwBi+xRB2gFsRT4Yk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1716914034; x=1717518834; 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=Ty3fn9KLlUbkBYaC8FAcJnuCWyaC/2w1uaNacPgw5QU=; b=LTbsvX0UYeXO0y9/M+mzRWYmWMAKVodw5KDA4ubQQpTMPUNHLLU9D5HWRd4SF75raN btvMZutre3ZlSTRzFsrO0S9nB8oRwidznZC6I7CtVlTWhnRDb0T0SL2eIIUJLswgAQWz RKwHixMkpSWtneLclH8fI8l9o8fIxtWmUA4pCyPhFF39mHaZofzfHUwQNjTBIuxoyRAk ScHbzd/XwPhxIzbR+d+Dx9GF0Q2MGsHVVhG8+FZ4Va9chmqt37d55NgePDdZKswtUbhO B3mdXRrCV5bpN4ttQINxS2ZEDZ13NUaf+v4lzTgn/T2+4mwptz916BhyT6W07ipFLcWN dCDQ== X-Gm-Message-State: AOJu0YyJj3okLlhSV0megGzu0IbjU2MSUz2Rpcz7XiK/u1E9n4ykyOx6 u9O6crE38PkOGOc2D7eqCSKimbJy2t4s9aW/rZPTPwaaPeGoghsxnSCUHW/hIrD/89yZDXNOqN2 2ZRZPVG4y4wuLUUlkSS1pRUvfJGXR56sF5awcMT5Nx4u+7LMH X-Google-Smtp-Source: AGHT+IHrPkIAak6/Wn7BhDK8ukKZwlPLf7r9dNr9X6HWc9LVaqf6SdFCRxUK19+533mUV1iUtRx06HicLChGHtSlYQY= X-Received: by 2002:a05:6512:3988:b0:51c:5087:909f with SMTP id 2adb3069b0e04-529646e3c01mr10822165e87.10.1716914033993; Tue, 28 May 2024 09:33:53 -0700 (PDT) MIME-Version: 1.0 References: <20240130034925.44869-1-stephen@networkplumber.org> <20240521201410.126116-1-stephen@networkplumber.org> <20240521201410.126116-8-stephen@networkplumber.org> In-Reply-To: <20240521201410.126116-8-stephen@networkplumber.org> From: Cody Cheng Date: Tue, 28 May 2024 12:33:41 -0400 Message-ID: Subject: Re: [PATCH v15 07/11] net/tap: use libbpf to load new BPF program To: Stephen Hemminger Cc: dev@dpdk.org, ferruh.yigit@amd.com Content-Type: multipart/alternative; boundary="0000000000001b42490619863331" 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 --0000000000001b42490619863331 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi, I've added the Ubuntu 24.04 environment to the Community Lab but without werror enabled as the rte_pcapng.c warning would cause them to fail. Once the rte_pcapng.c warning is fixed, I will re-enable werror. I will send an email to the ci mailing list with the logs of the warning so that people are aware of it. Thanks, Cody On Tue, May 21, 2024 at 4:14=E2=80=AFPM Stephen Hemminger < stephen@networkplumber.org> wrote: > There were multiple issues in the RSS queue support in the TAP > driver. This required extensive rework of the BPF support. > > Change the BPF loading to use bpftool to > create a skeleton header file, and load with libbpf. > The BPF is always compiled from source so less chance that > source and instructions diverge. Also resolves issue where > libbpf and source get out of sync. The program > is only loaded once, so if multiple rules are created > only one BPF program is loaded in kernel. > > The new BPF program only needs a single action. > No need for action and re-classification step. > > It also fixes the missing bits from the original. > - supports setting RSS key per flow > - level of hash can be L3 or L3/L4. > > Bugzilla ID: 1329 > > Signed-off-by: Stephen Hemminger > --- > doc/guides/rel_notes/release_24_07.rst | 3 + > drivers/net/tap/bpf/meson.build | 81 +++-- > drivers/net/tap/meson.build | 39 ++- > drivers/net/tap/rte_eth_tap.c | 14 +- > drivers/net/tap/rte_eth_tap.h | 6 +- > drivers/net/tap/tap_flow.c | 416 ++++++------------------- > drivers/net/tap/tap_flow.h | 17 +- > drivers/net/tap/tap_rss.h | 10 +- > drivers/net/tap/tap_tcmsgs.h | 4 +- > 9 files changed, 186 insertions(+), 404 deletions(-) > > diff --git a/doc/guides/rel_notes/release_24_07.rst > b/doc/guides/rel_notes/release_24_07.rst > index a6295359b1..37a6e98637 100644 > --- a/doc/guides/rel_notes/release_24_07.rst > +++ b/doc/guides/rel_notes/release_24_07.rst > @@ -59,6 +59,9 @@ New Features > > * Updated to support up to 8 queues when used by secondary process. > > + * Fixed support of RSS flow action to work with current Linux > + kernels and BPF tooling. Will only be enabled if clang, libbpf 1.0 > + and bpftool are available. > > Removed Items > ------------- > diff --git a/drivers/net/tap/bpf/meson.build > b/drivers/net/tap/bpf/meson.build > index f2c03a19fd..df497948e2 100644 > --- a/drivers/net/tap/bpf/meson.build > +++ b/drivers/net/tap/bpf/meson.build > @@ -1,17 +1,26 @@ > # SPDX-License-Identifier: BSD-3-Clause > # Copyright 2024 Stephen Hemminger > > -enable_tap_rss =3D false > - > -libbpf =3D dependency('libbpf', required: false, method: 'pkg-config') > +# Loading BPF requires libbpf > +# and the bpf_map__XXX API's were introduced in 0.8.0 > +libbpf =3D dependency('libbpf', version: '>=3D 1.0', > + required: false, method: 'pkg-config') > if not libbpf.found() > message('net/tap: no RSS support missing libbpf') > subdir_done() > endif > > +# Making skeleton needs bpftool > # Debian install this in /usr/sbin which is not in $PATH > -bpftool =3D find_program('bpftool', '/usr/sbin/bpftool', required: false= , > version: '>=3D 5.6.0') > -if not bpftool.found() > +bpftool_supports_skel =3D false > +bpftool =3D find_program('bpftool', '/usr/sbin/bpftool', required: false= ) > +if bpftool.found() > + # Some Ubuntu versions have non-functional bpftool > + bpftool_supports_skel =3D run_command(bpftool, 'gen', 'help', > + check:false).returncode() =3D=3D= 0 > +endif > + > +if not bpftool_supports_skel > message('net/tap: no RSS support missing bpftool') > subdir_done() > endif > @@ -39,43 +48,47 @@ machine_name =3D run_command('uname', > '-m').stdout().strip() > march_include_dir =3D '/usr/include/' + machine_name + '-linux-gnu' > > clang_flags =3D [ > - '-O2', > - '-Wall', > - '-Wextra', > - '-target', > - 'bpf', > - '-g', > - '-c', > + # these are flags used to build the BPF code > + '-O2', > + '-Wall', > + '-Wextra', > + max_queues, > + '-target', > + 'bpf', > + '-g', > + '-c', > ] > > +# Command used to compile BPF pgrograme > bpf_o_cmd =3D [ > - clang, > - clang_flags, > - '-idirafter', > - libbpf_include_dir, > - '-idirafter', > - march_include_dir, > - '@INPUT@', > - '-o', > - '@OUTPUT@' > + clang, > + clang_flags, > + '-idirafter', > + libbpf_include_dir, > + '-idirafter', > + march_include_dir, > + '@INPUT@', > + '-o', > + '@OUTPUT@', > ] > > +# Command used to generate header file from BPF object > skel_h_cmd =3D [ > - bpftool, > - 'gen', > - 'skeleton', > - '@INPUT@' > + bpftool, > + 'gen', > + 'skeleton', > + '@INPUT@', > ] > > tap_rss_o =3D custom_target( > - 'tap_rss.bpf.o', > - input: 'tap_rss.c', > - output: 'tap_rss.o', > - command: bpf_o_cmd) > + 'tap_rss.bpf.o', > + input: 'tap_rss.c', > + output: 'tap_rss.o', > + command: bpf_o_cmd) > > tap_rss_skel_h =3D custom_target( > - 'tap_rss.skel.h', > - input: tap_rss_o, > - output: 'tap_rss.skel.h', > - command: skel_h_cmd, > - capture: true) > + 'tap_rss.skel.h', > + input: tap_rss_o, > + output: 'tap_rss.skel.h', > + command: skel_h_cmd, > + capture: true) > diff --git a/drivers/net/tap/meson.build b/drivers/net/tap/meson.build > index 66647a1c62..5e5a3ad3c6 100644 > --- a/drivers/net/tap/meson.build > +++ b/drivers/net/tap/meson.build > @@ -5,36 +5,33 @@ if not is_linux > build =3D false > reason =3D 'only supported on Linux' > endif > + > sources =3D files( > 'rte_eth_tap.c', > 'tap_intr.c', > 'tap_netlink.c', > ) > > +deps =3D ['bus_vdev', 'gso', 'hash'] > + > +max_queues =3D '-DTAP_MAX_QUEUES=3D16' > +cflags +=3D max_queues > + > +require_iova_in_mbuf =3D false > + > if cc.has_header_symbol('linux/pkt_cls.h', 'TCA_FLOWER_ACT') > cflags +=3D '-DHAVE_TCA_FLOWER' > sources +=3D files( > - 'tap_bpf_api.c', > - 'tap_flow.c', > - 'tap_tcmsgs.c', > + 'tap_flow.c', > + 'tap_tcmsgs.c', > ) > -endif > - > -deps =3D ['bus_vdev', 'gso', 'hash'] > > -cflags +=3D '-DTAP_MAX_QUEUES=3D16' > - > -# input array for meson symbol search: > -# [ "MACRO to define if found", "header for the search", > -# "enum/define", "symbol to search" ] > -# > -args =3D [ > - [ 'HAVE_TC_ACT_BPF', 'linux/tc_act/tc_bpf.h', > 'TCA_ACT_BPF_UNSPEC' ], > -] > -config =3D configuration_data() > -foreach arg:args > - config.set(arg[0], cc.has_header_symbol(arg[1], arg[2])) > -endforeach > -configure_file(output : 'tap_autoconf.h', configuration : config) > + enable_tap_rss =3D false > > -require_iova_in_mbuf =3D false > + subdir('bpf') > + if enable_tap_rss > + cflags +=3D '-DHAVE_BPF_RSS' > + ext_deps +=3D libbpf > + sources +=3D tap_rss_skel_h > + endif > +endif > diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.= c > index 9058a47295..d847565073 100644 > --- a/drivers/net/tap/rte_eth_tap.c > +++ b/drivers/net/tap/rte_eth_tap.c > @@ -1140,6 +1140,7 @@ tap_dev_close(struct rte_eth_dev *dev) > tap_flow_implicit_flush(internals, NULL); > tap_nl_final(internals->nlsk_fd); > internals->nlsk_fd =3D -1; > + tap_flow_bpf_destroy(internals); > } > #endif > > @@ -1949,6 +1950,7 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, > const char *tap_name, > strlcpy(pmd->name, tap_name, sizeof(pmd->name)); > pmd->type =3D type; > pmd->ka_fd =3D -1; > + > #ifdef HAVE_TCA_FLOWER > pmd->nlsk_fd =3D -1; > #endif > @@ -2031,13 +2033,6 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, > const char *tap_name, > /* Make network device persist after application exit */ > pmd->persist =3D persist; > > - pmd->if_index =3D if_nametoindex(pmd->name); > - if (!pmd->if_index) { > - TAP_LOG(ERR, "%s: failed to get if_index.", pmd->name); > - goto disable_rte_flow; > - } > - > - > #ifdef HAVE_TCA_FLOWER > /* > * Set up everything related to rte_flow: > @@ -2053,6 +2048,11 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, > const char *tap_name, > pmd->name); > goto disable_rte_flow; > } > + pmd->if_index =3D if_nametoindex(pmd->name); > + if (!pmd->if_index) { > + TAP_LOG(ERR, "%s: failed to get if_index.", pmd->name); > + goto disable_rte_flow; > + } > if (qdisc_create_multiq(pmd->nlsk_fd, pmd->if_index) < 0) { > TAP_LOG(ERR, "%s: failed to create multiq qdisc.", > pmd->name); > diff --git a/drivers/net/tap/rte_eth_tap.h b/drivers/net/tap/rte_eth_tap.= h > index af18b29090..ce4322ad04 100644 > --- a/drivers/net/tap/rte_eth_tap.h > +++ b/drivers/net/tap/rte_eth_tap.h > @@ -81,10 +81,8 @@ struct pmd_internals { > #ifdef HAVE_TCA_FLOWER > int nlsk_fd; /* Netlink socket fd */ > int flow_isolate; /* 1 if flow isolation is > enabled */ > - int rss_enabled; /* 1 if RSS is enabled, else 0 = */ > - /* implicit rules set when RSS is enabled */ > - int map_fd; /* BPF RSS map fd */ > - int bpf_fd[RTE_PMD_TAP_MAX_QUEUES];/* List of bpf fds per queue *= / > + > + struct tap_rss *rss; /* BPF program */ > > LIST_HEAD(tap_flows, rte_flow) flows; /* rte_flow rules */ > /* implicit rte_flow rules set when a remote device is active */ > diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c > index 45321aee86..0a90c0487b 100644 > --- a/drivers/net/tap/tap_flow.c > +++ b/drivers/net/tap/tap_flow.c > @@ -15,25 +15,19 @@ > #include > #include > #include > +#include > > #include > -#include > #include > #include > > -/* RSS key management */ > -enum bpf_rss_key_e { > - KEY_CMD_GET =3D 1, > - KEY_CMD_RELEASE, > - KEY_CMD_INIT, > - KEY_CMD_DEINIT, > -}; > - > -enum key_status_e { > - KEY_STAT_UNSPEC, > - KEY_STAT_USED, > - KEY_STAT_AVAILABLE, > -}; > +#ifdef HAVE_BPF_RSS > +/* Workaround for warning in bpftool generated skeleton code */ > +#pragma GCC diagnostic push > +#pragma GCC diagnostic ignored "-Wcast-qual" > +#include "tap_rss.skel.h" > +#pragma GCC diagnostic pop > +#endif > > #define ISOLATE_HANDLE 1 > #define REMOTE_PROMISCUOUS_HANDLE 2 > @@ -41,8 +35,6 @@ enum key_status_e { > struct rte_flow { > LIST_ENTRY(rte_flow) next; /* Pointer to the next rte_flow > structure */ > struct rte_flow *remote_flow; /* associated remote flow */ > - int bpf_fd[SEC_MAX]; /* list of bfs fds per ELF section */ > - uint32_t key_idx; /* RSS rule key index into BPF map */ > struct nlmsg msg; > }; > > @@ -69,12 +61,16 @@ struct action_data { > struct skbedit { > struct tc_skbedit skbedit; > uint16_t queue; > + uint32_t mark; > } skbedit; > +#ifdef HAVE_BPF_RSS > struct bpf { > struct tc_act_bpf bpf; > + uint32_t map_key; > int bpf_fd; > const char *annotation; > } bpf; > +#endif > }; > }; > > @@ -112,13 +108,12 @@ tap_flow_isolate(struct rte_eth_dev *dev, > int set, > struct rte_flow_error *error); > > -static int bpf_rss_key(enum bpf_rss_key_e cmd, __u32 *key_idx); > -static int rss_enable(struct pmd_internals *pmd, > - const struct rte_flow_attr *attr, > - struct rte_flow_error *error); > +#ifdef HAVE_BPF_RSS > +static int rss_enable(struct pmd_internals *pmd, struct rte_flow_error > *error); > static int rss_add_actions(struct rte_flow *flow, struct pmd_internals > *pmd, > const struct rte_flow_action_rss *rss, > struct rte_flow_error *error); > +#endif > > static const struct rte_flow_ops tap_flow_ops =3D { > .validate =3D tap_flow_validate, > @@ -853,11 +848,13 @@ add_action(struct rte_flow *flow, size_t *act_index= , > struct action_data *adata) > &adata->mirred); > } else if (strcmp("skbedit", adata->id) =3D=3D 0) { > tap_nlattr_add(&msg->nh, TCA_SKBEDIT_PARMS, > - sizeof(adata->skbedit.skbedit), > - &adata->skbedit.skbedit); > - tap_nlattr_add16(&msg->nh, TCA_SKBEDIT_QUEUE_MAPPING, > - adata->skbedit.queue); > + sizeof(adata->skbedit.skbedit), > &adata->skbedit.skbedit); > + if (adata->skbedit.mark) > + tap_nlattr_add32(&msg->nh, TCA_SKBEDIT_MARK, > adata->skbedit.mark); > + else > + tap_nlattr_add16(&msg->nh, > TCA_SKBEDIT_QUEUE_MAPPING, adata->skbedit.queue); > } else if (strcmp("bpf", adata->id) =3D=3D 0) { > +#ifdef HAVE_BPF_RSS > tap_nlattr_add32(&msg->nh, TCA_ACT_BPF_FD, > adata->bpf.bpf_fd); > tap_nlattr_add(&msg->nh, TCA_ACT_BPF_NAME, > strlen(adata->bpf.annotation) + 1, > @@ -865,7 +862,12 @@ add_action(struct rte_flow *flow, size_t *act_index, > struct action_data *adata) > tap_nlattr_add(&msg->nh, TCA_ACT_BPF_PARMS, > sizeof(adata->bpf.bpf), > &adata->bpf.bpf); > +#else > + TAP_LOG(ERR, "Internal error: bpf requested but not > supported"); > + return -1; > +#endif > } else { > + TAP_LOG(ERR, "Internal error: unknown action: %s", > adata->id); > return -1; > } > tap_nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */ > @@ -1104,8 +1106,7 @@ priv_flow_process(struct pmd_internals *pmd, > }, > }; > > - err =3D add_actions(flow, 1, &adata, > - TCA_FLOWER_ACT); > + err =3D add_actions(flow, 1, &adata, > TCA_FLOWER_ACT); > } > } else if (actions->type =3D=3D RTE_FLOW_ACTION_TYPE_QUEU= E) { > const struct rte_flow_action_queue *queue =3D > @@ -1135,6 +1136,7 @@ priv_flow_process(struct pmd_internals *pmd, > err =3D add_actions(flow, 1, &adata, > TCA_FLOWER_ACT); > } > +#ifdef HAVE_BPF_RSS > } else if (actions->type =3D=3D RTE_FLOW_ACTION_TYPE_RSS)= { > const struct rte_flow_action_rss *rss =3D > (const struct rte_flow_action_rss *) > @@ -1143,13 +1145,14 @@ priv_flow_process(struct pmd_internals *pmd, > if (action++) > goto exit_action_not_supported; > > - if (!pmd->rss_enabled) { > - err =3D rss_enable(pmd, attr, error); > + if (pmd->rss =3D=3D NULL) { > + err =3D rss_enable(pmd, error); > if (err) > goto exit_return_error; > } > if (flow) > err =3D rss_add_actions(flow, pmd, rss, > error); > +#endif > } else { > goto exit_action_not_supported; > } > @@ -1246,26 +1249,17 @@ tap_flow_set_handle(struct rte_flow *flow) > * > */ > static void > -tap_flow_free(struct pmd_internals *pmd, struct rte_flow *flow) > +tap_flow_free(struct pmd_internals *pmd __rte_unused, struct rte_flow > *flow) > { > - int i; > - > if (!flow) > return; > > - if (pmd->rss_enabled) { > - /* Close flow BPF file descriptors */ > - for (i =3D 0; i < SEC_MAX; i++) > - if (flow->bpf_fd[i] !=3D 0) { > - close(flow->bpf_fd[i]); > - flow->bpf_fd[i] =3D 0; > - } > - > - /* Release the map key for this RSS rule */ > - bpf_rss_key(KEY_CMD_RELEASE, &flow->key_idx); > - flow->key_idx =3D 0; > - } > - > +#ifdef HAVE_BPF_RSS > + struct tap_rss *rss =3D pmd->rss; > + if (rss) > + bpf_map__delete_elem(rss->maps.rss_map, > + &flow->msg.t.tcm_handle, > sizeof(uint32_t), 0); > +#endif > /* Free flow allocated memory */ > rte_free(flow); > } > @@ -1733,14 +1727,18 @@ tap_flow_implicit_flush(struct pmd_internals *pmd= , > struct rte_flow_error *error) > return 0; > } > > -#define MAX_RSS_KEYS 256 > -#define KEY_IDX_OFFSET (3 * MAX_RSS_KEYS) > -#define SEC_NAME_CLS_Q "cls_q" > - > -static const char *sec_name[SEC_MAX] =3D { > - [SEC_L3_L4] =3D "l3_l4", > -}; > +/** > + * Cleanup when device is closed > + */ > +void tap_flow_bpf_destroy(struct pmd_internals *pmd __rte_unused) > +{ > +#ifdef HAVE_BPF_RSS > + tap_rss__destroy(pmd->rss); > + pmd->rss =3D NULL; > +#endif > +} > > +#ifdef HAVE_BPF_RSS > /** > * Enable RSS on tap: create TC rules for queuing. > * > @@ -1755,225 +1753,32 @@ static const char *sec_name[SEC_MAX] =3D { > * > * @return 0 on success, negative value on failure. > */ > -static int rss_enable(struct pmd_internals *pmd, > - const struct rte_flow_attr *attr, > - struct rte_flow_error *error) > +static int rss_enable(struct pmd_internals *pmd, struct rte_flow_error > *error) > { > - struct rte_flow *rss_flow =3D NULL; > - struct nlmsg *msg =3D NULL; > - /* 4096 is the maximum number of instructions for a BPF program *= / > - char annotation[64]; > - int i; > - int err =3D 0; > - > - /* unlimit locked memory */ > - struct rlimit memlock_limit =3D { > - .rlim_cur =3D RLIM_INFINITY, > - .rlim_max =3D RLIM_INFINITY, > - }; > - setrlimit(RLIMIT_MEMLOCK, &memlock_limit); > - > - /* Get a new map key for a new RSS rule */ > - err =3D bpf_rss_key(KEY_CMD_INIT, NULL); > - if (err < 0) { > - rte_flow_error_set( > - error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL, > - "Failed to initialize BPF RSS keys"); > - > - return -1; > - } > - > - /* > - * Create BPF RSS MAP > - */ > - pmd->map_fd =3D tap_flow_bpf_rss_map_create(sizeof(__u32), /* key > size */ > - sizeof(struct rss_key), > - MAX_RSS_KEYS); > - if (pmd->map_fd < 0) { > - TAP_LOG(ERR, > - "Failed to create BPF map (%d): %s", > - errno, strerror(errno)); > - rte_flow_error_set( > - error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE, NULL, > - "Kernel too old or not configured " > - "to support BPF maps"); > - > - return -ENOTSUP; > - } > - > - /* > - * Add a rule per queue to match reclassified packets and direct > them to > - * the correct queue. > - */ > - for (i =3D 0; i < pmd->dev->data->nb_rx_queues; i++) { > - pmd->bpf_fd[i] =3D tap_flow_bpf_cls_q(i); > - if (pmd->bpf_fd[i] < 0) { > - TAP_LOG(ERR, > - "Failed to load BPF section %s for queue > %d", > - SEC_NAME_CLS_Q, i); > - rte_flow_error_set( > - error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDL= E, > - NULL, > - "Kernel too old or not configured " > - "to support BPF programs loading"); > - > - return -ENOTSUP; > - } > - > - rss_flow =3D rte_zmalloc(__func__, sizeof(struct rte_flow= ), > 0); > - if (!rss_flow) { > - TAP_LOG(ERR, > - "Cannot allocate memory for rte_flow"); > - return -1; > - } > - msg =3D &rss_flow->msg; > - tc_init_msg(msg, pmd->if_index, RTM_NEWTFILTER, > NLM_F_REQUEST | > - NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE); > - msg->t.tcm_info =3D TC_H_MAKE(0, htons(ETH_P_ALL)); > - tap_flow_set_handle(rss_flow); > - uint16_t group =3D attr->group << GROUP_SHIFT; > - uint16_t prio =3D group | (i + PRIORITY_OFFSET); > - msg->t.tcm_info =3D TC_H_MAKE(prio << 16, msg->t.tcm_info= ); > - msg->t.tcm_parent =3D TC_H_MAKE(MULTIQ_MAJOR_HANDLE, 0); > - > - tap_nlattr_add(&msg->nh, TCA_KIND, sizeof("bpf"), "bpf"); > - if (tap_nlattr_nested_start(msg, TCA_OPTIONS) < 0) > - return -1; > - tap_nlattr_add32(&msg->nh, TCA_BPF_FD, pmd->bpf_fd[i]); > - snprintf(annotation, sizeof(annotation), "[%s%d]", > - SEC_NAME_CLS_Q, i); > - tap_nlattr_add(&msg->nh, TCA_BPF_NAME, strlen(annotation) > + 1, > - annotation); > - /* Actions */ > - { > - struct action_data adata =3D { > - .id =3D "skbedit", > - .skbedit =3D { > - .skbedit =3D { > - .action =3D TC_ACT_PIPE, > - }, > - .queue =3D i, > - }, > - }; > - if (add_actions(rss_flow, 1, &adata, TCA_BPF_ACT) > < 0) > - return -1; > - } > - tap_nlattr_nested_finish(msg); /* nested TCA_OPTIONS */ > + int err; > > - /* Netlink message is now ready to be sent */ > - if (tap_nl_send(pmd->nlsk_fd, &msg->nh) < 0) > - return -1; > - err =3D tap_nl_recv_ack(pmd->nlsk_fd); > - if (err < 0) { > - TAP_LOG(ERR, > - "Kernel refused TC filter rule creation > (%d): %s", > - errno, strerror(errno)); > - return err; > - } > + /* Load the BPF program (defined in tap_bpf.h from skeleton) */ > + pmd->rss =3D tap_rss__open_and_load(); > + if (pmd->rss =3D=3D NULL) { > + TAP_LOG(ERR, "Failed to load BPF object: %s", > strerror(errno)); > + rte_flow_error_set(error, errno, > RTE_FLOW_ERROR_TYPE_HANDLE, NULL, > + "BPF object could not be loaded"); > + return -errno; > } > > - pmd->rss_enabled =3D 1; > - return err; > -} > - > -/** > - * Manage bpf RSS keys repository with operations: init, get, release > - * > - * @param[in] cmd > - * Command on RSS keys: init, get, release > - * > - * @param[in, out] key_idx > - * Pointer to RSS Key index (out for get command, in for release > command) > - * > - * @return -1 if couldn't get, release or init the RSS keys, 0 otherwise= . > - */ > -static int bpf_rss_key(enum bpf_rss_key_e cmd, __u32 *key_idx) > -{ > - __u32 i; > - int err =3D 0; > - static __u32 num_used_keys; > - static __u32 rss_keys[MAX_RSS_KEYS] =3D {KEY_STAT_UNSPEC}; > - static __u32 rss_keys_initialized; > - __u32 key; > - > - switch (cmd) { > - case KEY_CMD_GET: > - if (!rss_keys_initialized) { > - err =3D -1; > - break; > - } > - > - if (num_used_keys =3D=3D RTE_DIM(rss_keys)) { > - err =3D -1; > - break; > - } > - > - *key_idx =3D num_used_keys % RTE_DIM(rss_keys); > - while (rss_keys[*key_idx] =3D=3D KEY_STAT_USED) > - *key_idx =3D (*key_idx + 1) % RTE_DIM(rss_keys); > - > - rss_keys[*key_idx] =3D KEY_STAT_USED; > - > - /* > - * Add an offset to key_idx in order to handle a case of > - * RSS and non RSS flows mixture. > - * If a non RSS flow is destroyed it has an eBPF map > - * index 0 (initialized on flow creation) and might > - * unintentionally remove RSS entry 0 from eBPF map. > - * To avoid this issue, add an offset to the real index > - * during a KEY_CMD_GET operation and subtract this offse= t > - * during a KEY_CMD_RELEASE operation in order to restore > - * the real index. > - */ > - *key_idx +=3D KEY_IDX_OFFSET; > - num_used_keys++; > - break; > - > - case KEY_CMD_RELEASE: > - if (!rss_keys_initialized) > - break; > - > - /* > - * Subtract offset to restore real key index > - * If a non RSS flow is falsely trying to release map > - * entry 0 - the offset subtraction will calculate the re= al > - * map index as an out-of-range value and the release > operation > - * will be silently ignored. > - */ > - key =3D *key_idx - KEY_IDX_OFFSET; > - if (key >=3D RTE_DIM(rss_keys)) > - break; > - > - if (rss_keys[key] =3D=3D KEY_STAT_USED) { > - rss_keys[key] =3D KEY_STAT_AVAILABLE; > - num_used_keys--; > - } > - break; > - > - case KEY_CMD_INIT: > - for (i =3D 0; i < RTE_DIM(rss_keys); i++) > - rss_keys[i] =3D KEY_STAT_AVAILABLE; > - > - rss_keys_initialized =3D 1; > - num_used_keys =3D 0; > - break; > - > - case KEY_CMD_DEINIT: > - for (i =3D 0; i < RTE_DIM(rss_keys); i++) > - rss_keys[i] =3D KEY_STAT_UNSPEC; > - > - rss_keys_initialized =3D 0; > - num_used_keys =3D 0; > - break; > - > - default: > - break; > + /* Attach the maps defined in BPF program */ > + err =3D tap_rss__attach(pmd->rss); > + if (err < 0) { > + TAP_LOG(ERR, "Failed to attach BPF object: %d", err); > + rte_flow_error_set(error, -err, > RTE_FLOW_ERROR_TYPE_HANDLE, NULL, > + "BPF object could not be attached"); > + tap_flow_bpf_destroy(pmd); > + return err; > } > > - return err; > + return 0; > } > > - > /* Default RSS hash key also used by mlx devices */ > static const uint8_t rss_hash_default_key[] =3D { > 0x2c, 0xc6, 0x81, 0xd1, > @@ -2006,9 +1811,11 @@ static int rss_add_actions(struct rte_flow *flow, > struct pmd_internals *pmd, > const struct rte_flow_action_rss *rss, > struct rte_flow_error *error) > { > + const struct bpf_program *rss_prog =3D > pmd->rss->progs.rss_flow_action; > struct rss_key rss_entry =3D { }; > const uint8_t *key_in; > uint32_t hash_type =3D 0; > + uint32_t handle =3D flow->msg.t.tcm_handle; > unsigned int i; > int err; > > @@ -2067,34 +1874,24 @@ static int rss_add_actions(struct rte_flow *flow, > struct pmd_internals *pmd, > else if (rss->types & (RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6 | > RTE_ETH_RSS_IPV6_EX)) > hash_type |=3D RTE_BIT32(HASH_FIELD_IPV6_L3); > > - /* Get a new map key for a new RSS rule */ > - err =3D bpf_rss_key(KEY_CMD_GET, &flow->key_idx); > - if (err < 0) { > - rte_flow_error_set( > - error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL, > - "Failed to get BPF RSS key"); > - > - return -1; > - } > + rss_entry.hash_fields =3D hash_type; > + rte_convert_rss_key((const uint32_t *)key_in, (uint32_t > *)rss_entry.key, > + TAP_RSS_HASH_KEY_SIZE); > > /* Update RSS map entry with queues */ > rss_entry.nb_queues =3D rss->queue_num; > for (i =3D 0; i < rss->queue_num; i++) > rss_entry.queues[i] =3D rss->queue[i]; > > - rss_entry.hash_fields =3D hash_type; > - rte_convert_rss_key((const uint32_t *)key_in, (uint32_t > *)rss_entry.key, > - TAP_RSS_HASH_KEY_SIZE); > - > - > - /* Add this RSS entry to map */ > - err =3D tap_flow_bpf_update_rss_elem(pmd->map_fd, > - &flow->key_idx, &rss_entry); > > + /* Add this way for BPF to find entry in map */ > + err =3D bpf_map__update_elem(pmd->rss->maps.rss_map, > + &handle, sizeof(handle), > + &rss_entry, sizeof(rss_entry), 0); > if (err) { > TAP_LOG(ERR, > - "Failed to update BPF map entry #%u (%d): %s", > - flow->key_idx, errno, strerror(errno)); > + "Failed to update BPF map entry %#x (%d): %s", > + handle, errno, strerror(errno)); > rte_flow_error_set( > error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE, NULL, > "Kernel too old or not configured " > @@ -2103,47 +1900,28 @@ static int rss_add_actions(struct rte_flow *flow, > struct pmd_internals *pmd, > return -ENOTSUP; > } > > - > - /* > - * Load bpf rules to calculate hash for this key_idx > - */ > - > - flow->bpf_fd[SEC_L3_L4] =3D > - tap_flow_bpf_calc_l3_l4_hash(flow->key_idx, pmd->map_fd); > - if (flow->bpf_fd[SEC_L3_L4] < 0) { > - TAP_LOG(ERR, > - "Failed to load BPF section %s (%d): %s", > - sec_name[SEC_L3_L4], errno, > strerror(errno)); > - rte_flow_error_set( > - error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE, NULL, > - "Kernel too old or not configured " > - "to support BPF program loading"); > - > - return -ENOTSUP; > - } > - > - /* Actions */ > - { > - struct action_data adata[] =3D { > - { > - .id =3D "bpf", > - .bpf =3D { > - .bpf_fd =3D flow->bpf_fd[SEC_L3_L= 4], > - .annotation =3D sec_name[SEC_L3_L= 4], > - .bpf =3D { > - .action =3D TC_ACT_PIPE, > - }, > - }, > + /* Add actions to mark packet then run the RSS BPF program */ > + struct action_data adata[] =3D { > + { > + .id =3D "skbedit", > + .skbedit =3D { > + .skbedit.action =3D TC_ACT_PIPE, > + .mark =3D handle, > }, > - }; > - > - if (add_actions(flow, RTE_DIM(adata), adata, > - TCA_FLOWER_ACT) < 0) > - return -1; > - } > + }, > + { > + .id =3D "bpf", > + .bpf =3D { > + .bpf.action =3D TC_ACT_PIPE, > + .annotation =3D "tap_rss", > + .bpf_fd =3D bpf_program__fd(rss_prog), > + }, > + }, > + }; > > - return 0; > + return add_actions(flow, RTE_DIM(adata), adata, TCA_FLOWER_ACT); > } > +#endif > > /** > * Get rte_flow operations. > diff --git a/drivers/net/tap/tap_flow.h b/drivers/net/tap/tap_flow.h > index 240fbc3dfa..8b19347a93 100644 > --- a/drivers/net/tap/tap_flow.h > +++ b/drivers/net/tap/tap_flow.h > @@ -9,7 +9,11 @@ > #include > #include > #include > -#include > + > +/** > + * Mask of unsupported RSS types > + */ > +#define TAP_RSS_HF_MASK (~(RTE_ETH_RSS_IP | RTE_ETH_RSS_UDP | > RTE_ETH_RSS_TCP)) > > /** > * In TC, priority 0 means we require the kernel to allocate one for us. > @@ -41,11 +45,6 @@ enum implicit_rule_index { > TAP_REMOTE_MAX_IDX, > }; > > -enum bpf_fd_idx { > - SEC_L3_L4, > - SEC_MAX, > -}; > - > int tap_dev_flow_ops_get(struct rte_eth_dev *dev, > const struct rte_flow_ops **ops); > int tap_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error= ); > @@ -57,10 +56,6 @@ int tap_flow_implicit_destroy(struct pmd_internals *pm= d, > int tap_flow_implicit_flush(struct pmd_internals *pmd, > struct rte_flow_error *error); > > -int tap_flow_bpf_cls_q(__u32 queue_idx); > -int tap_flow_bpf_calc_l3_l4_hash(__u32 key_idx, int map_fd); > -int tap_flow_bpf_rss_map_create(unsigned int key_size, unsigned int > value_size, > - unsigned int max_entries); > -int tap_flow_bpf_update_rss_elem(int fd, void *key, void *value); > +void tap_flow_bpf_destroy(struct pmd_internals *pmd); > > #endif /* _TAP_FLOW_H_ */ > diff --git a/drivers/net/tap/tap_rss.h b/drivers/net/tap/tap_rss.h > index 6009be7031..65bd8991b1 100644 > --- a/drivers/net/tap/tap_rss.h > +++ b/drivers/net/tap/tap_rss.h > @@ -5,16 +5,14 @@ > #ifndef _TAP_RSS_H_ > #define _TAP_RSS_H_ > > -#ifndef TAP_MAX_QUEUES > -#define TAP_MAX_QUEUES 16 > +/* Size of the map from BPF classid to queue table */ > +#ifndef TAP_RSS_MAX > +#define TAP_RSS_MAX 32 > #endif > > -/* Fixed RSS hash key size in bytes. */ > +/* Standard Toeplitz hash key size */ > #define TAP_RSS_HASH_KEY_SIZE 40 > > -/* Supported RSS */ > -#define TAP_RSS_HF_MASK (~(RTE_ETH_RSS_IP | RTE_ETH_RSS_UDP | > RTE_ETH_RSS_TCP)) > - > /* hashed fields for RSS */ > enum hash_field { > HASH_FIELD_IPV4_L3, /* IPv4 src/dst addr */ > diff --git a/drivers/net/tap/tap_tcmsgs.h b/drivers/net/tap/tap_tcmsgs.h > index a64cb29d6f..9411626661 100644 > --- a/drivers/net/tap/tap_tcmsgs.h > +++ b/drivers/net/tap/tap_tcmsgs.h > @@ -6,7 +6,6 @@ > #ifndef _TAP_TCMSGS_H_ > #define _TAP_TCMSGS_H_ > > -#include > #include > #include > #include > @@ -14,9 +13,10 @@ > #include > #include > #include > -#ifdef HAVE_TC_ACT_BPF > +#ifdef HAVE_BPF_RSS > #include > #endif > + > #include > > #include > -- > 2.43.0 > > --0000000000001b42490619863331 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: base64 PGRpdiBkaXI9Imx0ciI+SGksIEkmIzM5O3ZlIGFkZGVkIHRoZSBVYnVudHUgMjQuMDTCoGVudmly b25tZW50IHRvIHRoZSBDb21tdW5pdHkgTGFiIGJ1dCB3aXRob3V0IHdlcnJvciBlbmFibGVkIGFz IHRoZcKgcnRlX3BjYXBuZy5jIHdhcm5pbmcgd291bGQgY2F1c2UgdGhlbSB0byBmYWlsLiBPbmNl IHRoZcKgcnRlX3BjYXBuZy5jIHdhcm5pbmcgaXMgZml4ZWQsIEkgd2lsbCByZS1lbmFibGUgd2Vy cm9yLiBJIHdpbGwgc2VuZCBhbiBlbWFpbCB0byB0aGUgY2kgbWFpbGluZyBsaXN0IHdpdGggdGhl IGxvZ3Mgb2YgdGhlIHdhcm5pbmcgc28gdGhhdCBwZW9wbGUgYXJlIGF3YXJlIG9mIGl0LsKgPGJy Pjxicj5UaGFua3MsPGJyPkNvZHk8L2Rpdj48YnI+PGRpdiBjbGFzcz0iZ21haWxfcXVvdGUiPjxk aXYgZGlyPSJsdHIiIGNsYXNzPSJnbWFpbF9hdHRyIj5PbiBUdWUsIE1heSAyMSwgMjAyNCBhdCA0 OjE04oCvUE0gU3RlcGhlbiBIZW1taW5nZXIgJmx0OzxhIGhyZWY9Im1haWx0bzpzdGVwaGVuQG5l dHdvcmtwbHVtYmVyLm9yZyIgdGFyZ2V0PSJfYmxhbmsiPnN0ZXBoZW5AbmV0d29ya3BsdW1iZXIu b3JnPC9hPiZndDsgd3JvdGU6PGJyPjwvZGl2PjxibG9ja3F1b3RlIGNsYXNzPSJnbWFpbF9xdW90 ZSIgc3R5bGU9Im1hcmdpbjowcHggMHB4IDBweCAwLjhleDtib3JkZXItbGVmdDoxcHggc29saWQg cmdiKDIwNCwyMDQsMjA0KTtwYWRkaW5nLWxlZnQ6MWV4Ij5UaGVyZSB3ZXJlIG11bHRpcGxlIGlz c3VlcyBpbiB0aGUgUlNTIHF1ZXVlIHN1cHBvcnQgaW4gdGhlIFRBUDxicj4NCmRyaXZlci4gVGhp cyByZXF1aXJlZCBleHRlbnNpdmUgcmV3b3JrIG9mIHRoZSBCUEYgc3VwcG9ydC48YnI+DQo8YnI+ DQpDaGFuZ2UgdGhlIEJQRiBsb2FkaW5nIHRvIHVzZSBicGZ0b29sIHRvPGJyPg0KY3JlYXRlIGEg c2tlbGV0b24gaGVhZGVyIGZpbGUsIGFuZCBsb2FkIHdpdGggbGliYnBmLjxicj4NClRoZSBCUEYg aXMgYWx3YXlzIGNvbXBpbGVkIGZyb20gc291cmNlIHNvIGxlc3MgY2hhbmNlIHRoYXQ8YnI+DQpz b3VyY2UgYW5kIGluc3RydWN0aW9ucyBkaXZlcmdlLiBBbHNvIHJlc29sdmVzIGlzc3VlIHdoZXJl PGJyPg0KbGliYnBmIGFuZCBzb3VyY2UgZ2V0IG91dCBvZiBzeW5jLiBUaGUgcHJvZ3JhbTxicj4N CmlzIG9ubHkgbG9hZGVkIG9uY2UsIHNvIGlmIG11bHRpcGxlIHJ1bGVzIGFyZSBjcmVhdGVkPGJy Pg0Kb25seSBvbmUgQlBGIHByb2dyYW0gaXMgbG9hZGVkIGluIGtlcm5lbC48YnI+DQo8YnI+DQpU aGUgbmV3IEJQRiBwcm9ncmFtIG9ubHkgbmVlZHMgYSBzaW5nbGUgYWN0aW9uLjxicj4NCk5vIG5l ZWQgZm9yIGFjdGlvbiBhbmQgcmUtY2xhc3NpZmljYXRpb24gc3RlcC48YnI+DQo8YnI+DQpJdCBh bHNvIGZpeGVzIHRoZSBtaXNzaW5nIGJpdHMgZnJvbSB0aGUgb3JpZ2luYWwuPGJyPg0KwqAgwqAg LSBzdXBwb3J0cyBzZXR0aW5nIFJTUyBrZXkgcGVyIGZsb3c8YnI+DQrCoCDCoCAtIGxldmVsIG9m IGhhc2ggY2FuIGJlIEwzIG9yIEwzL0w0Ljxicj4NCjxicj4NCkJ1Z3ppbGxhIElEOiAxMzI5PGJy Pg0KPGJyPg0KU2lnbmVkLW9mZi1ieTogU3RlcGhlbiBIZW1taW5nZXIgJmx0OzxhIGhyZWY9Im1h aWx0bzpzdGVwaGVuQG5ldHdvcmtwbHVtYmVyLm9yZyIgdGFyZ2V0PSJfYmxhbmsiPnN0ZXBoZW5A bmV0d29ya3BsdW1iZXIub3JnPC9hPiZndDs8YnI+DQotLS08YnI+DQrCoGRvYy9ndWlkZXMvcmVs X25vdGVzL3JlbGVhc2VfMjRfMDcucnN0IHzCoCDCoDMgKzxicj4NCsKgZHJpdmVycy9uZXQvdGFw L2JwZi9tZXNvbi5idWlsZMKgIMKgIMKgIMKgIHzCoCA4MSArKystLTxicj4NCsKgZHJpdmVycy9u ZXQvdGFwL21lc29uLmJ1aWxkwqAgwqAgwqAgwqAgwqAgwqAgfMKgIDM5ICsrLTxicj4NCsKgZHJp dmVycy9uZXQvdGFwL3J0ZV9ldGhfdGFwLmPCoCDCoCDCoCDCoCDCoCB8wqAgMTQgKy08YnI+DQrC oGRyaXZlcnMvbmV0L3RhcC9ydGVfZXRoX3RhcC5owqAgwqAgwqAgwqAgwqAgfMKgIMKgNiArLTxi cj4NCsKgZHJpdmVycy9uZXQvdGFwL3RhcF9mbG93LmPCoCDCoCDCoCDCoCDCoCDCoCDCoHwgNDE2 ICsrKysrKy0tLS0tLS0tLS0tLS0tLS0tLS08YnI+DQrCoGRyaXZlcnMvbmV0L3RhcC90YXBfZmxv dy5owqAgwqAgwqAgwqAgwqAgwqAgwqB8wqAgMTcgKy08YnI+DQrCoGRyaXZlcnMvbmV0L3RhcC90 YXBfcnNzLmjCoCDCoCDCoCDCoCDCoCDCoCDCoCB8wqAgMTAgKy08YnI+DQrCoGRyaXZlcnMvbmV0 L3RhcC90YXBfdGNtc2dzLmjCoCDCoCDCoCDCoCDCoCDCoHzCoCDCoDQgKy08YnI+DQrCoDkgZmls ZXMgY2hhbmdlZCwgMTg2IGluc2VydGlvbnMoKyksIDQwNCBkZWxldGlvbnMoLSk8YnI+DQo8YnI+ DQpkaWZmIC0tZ2l0IGEvZG9jL2d1aWRlcy9yZWxfbm90ZXMvcmVsZWFzZV8yNF8wNy5yc3QgYi9k b2MvZ3VpZGVzL3JlbF9ub3Rlcy9yZWxlYXNlXzI0XzA3LnJzdDxicj4NCmluZGV4IGE2Mjk1MzU5 YjEuLjM3YTZlOTg2MzcgMTAwNjQ0PGJyPg0KLS0tIGEvZG9jL2d1aWRlcy9yZWxfbm90ZXMvcmVs ZWFzZV8yNF8wNy5yc3Q8YnI+DQorKysgYi9kb2MvZ3VpZGVzL3JlbF9ub3Rlcy9yZWxlYXNlXzI0 XzA3LnJzdDxicj4NCkBAIC01OSw2ICs1OSw5IEBAIE5ldyBGZWF0dXJlczxicj4NCjxicj4NCsKg IMKgKiBVcGRhdGVkIHRvIHN1cHBvcnQgdXAgdG8gOCBxdWV1ZXMgd2hlbiB1c2VkIGJ5IHNlY29u ZGFyeSBwcm9jZXNzLjxicj4NCjxicj4NCivCoCAqIEZpeGVkIHN1cHBvcnQgb2YgUlNTIGZsb3cg YWN0aW9uIHRvIHdvcmsgd2l0aCBjdXJyZW50IExpbnV4PGJyPg0KK8KgIMKgIGtlcm5lbHMgYW5k IEJQRiB0b29saW5nLiBXaWxsIG9ubHkgYmUgZW5hYmxlZCBpZiBjbGFuZywgbGliYnBmIDEuMDxi cj4NCivCoCDCoCBhbmQgYnBmdG9vbCBhcmUgYXZhaWxhYmxlLjxicj4NCjxicj4NCsKgUmVtb3Zl ZCBJdGVtczxicj4NCsKgLS0tLS0tLS0tLS0tLTxicj4NCmRpZmYgLS1naXQgYS9kcml2ZXJzL25l dC90YXAvYnBmL21lc29uLmJ1aWxkIGIvZHJpdmVycy9uZXQvdGFwL2JwZi9tZXNvbi5idWlsZDxi cj4NCmluZGV4IGYyYzAzYTE5ZmQuLmRmNDk3OTQ4ZTIgMTAwNjQ0PGJyPg0KLS0tIGEvZHJpdmVy cy9uZXQvdGFwL2JwZi9tZXNvbi5idWlsZDxicj4NCisrKyBiL2RyaXZlcnMvbmV0L3RhcC9icGYv bWVzb24uYnVpbGQ8YnI+DQpAQCAtMSwxNyArMSwyNiBAQDxicj4NCsKgIyBTUERYLUxpY2Vuc2Ut SWRlbnRpZmllcjogQlNELTMtQ2xhdXNlPGJyPg0KwqAjIENvcHlyaWdodCAyMDI0IFN0ZXBoZW4g SGVtbWluZ2VyICZsdDs8YSBocmVmPSJtYWlsdG86c3RlcGhlbkBuZXR3b3JrcGx1bWJlci5vcmci IHRhcmdldD0iX2JsYW5rIj5zdGVwaGVuQG5ldHdvcmtwbHVtYmVyLm9yZzwvYT4mZ3Q7PGJyPg0K PGJyPg0KLWVuYWJsZV90YXBfcnNzID0gZmFsc2U8YnI+DQotPGJyPg0KLWxpYmJwZiA9IGRlcGVu ZGVuY3koJiMzOTtsaWJicGYmIzM5OywgcmVxdWlyZWQ6IGZhbHNlLCBtZXRob2Q6ICYjMzk7cGtn LWNvbmZpZyYjMzk7KTxicj4NCisjIExvYWRpbmcgQlBGIHJlcXVpcmVzIGxpYmJwZjxicj4NCisj IGFuZCB0aGUgYnBmX21hcF9fWFhYIEFQSSYjMzk7cyB3ZXJlIGludHJvZHVjZWQgaW4gMC44LjA8 YnI+DQorbGliYnBmID0gZGVwZW5kZW5jeSgmIzM5O2xpYmJwZiYjMzk7LCB2ZXJzaW9uOiAmIzM5 OyZndDs9IDEuMCYjMzk7LDxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCByZXF1 aXJlZDogZmFsc2UsIG1ldGhvZDogJiMzOTtwa2ctY29uZmlnJiMzOTspPGJyPg0KwqBpZiBub3Qg bGliYnBmLmZvdW5kKCk8YnI+DQrCoCDCoCDCoG1lc3NhZ2UoJiMzOTtuZXQvdGFwOiBubyBSU1Mg c3VwcG9ydCBtaXNzaW5nIGxpYmJwZiYjMzk7KTxicj4NCsKgIMKgIMKgc3ViZGlyX2RvbmUoKTxi cj4NCsKgZW5kaWY8YnI+DQo8YnI+DQorIyBNYWtpbmcgc2tlbGV0b24gbmVlZHMgYnBmdG9vbDxi cj4NCsKgIyBEZWJpYW4gaW5zdGFsbCB0aGlzIGluIC91c3Ivc2JpbiB3aGljaCBpcyBub3QgaW4g JFBBVEg8YnI+DQotYnBmdG9vbCA9IGZpbmRfcHJvZ3JhbSgmIzM5O2JwZnRvb2wmIzM5OywgJiMz OTsvdXNyL3NiaW4vYnBmdG9vbCYjMzk7LCByZXF1aXJlZDogZmFsc2UsIHZlcnNpb246ICYjMzk7 Jmd0Oz0gNS42LjAmIzM5Oyk8YnI+DQotaWYgbm90IGJwZnRvb2wuZm91bmQoKTxicj4NCiticGZ0 b29sX3N1cHBvcnRzX3NrZWwgPSBmYWxzZTxicj4NCiticGZ0b29sID0gZmluZF9wcm9ncmFtKCYj Mzk7YnBmdG9vbCYjMzk7LCAmIzM5Oy91c3Ivc2Jpbi9icGZ0b29sJiMzOTssIHJlcXVpcmVkOiBm YWxzZSk8YnI+DQoraWYgYnBmdG9vbC5mb3VuZCgpPGJyPg0KK8KgIMKgICMgU29tZSBVYnVudHUg dmVyc2lvbnMgaGF2ZSBub24tZnVuY3Rpb25hbCBicGZ0b29sPGJyPg0KK8KgIMKgIGJwZnRvb2xf c3VwcG9ydHNfc2tlbCA9IHJ1bl9jb21tYW5kKGJwZnRvb2wsICYjMzk7Z2VuJiMzOTssICYjMzk7 aGVscCYjMzk7LDxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCBjaGVjazpmYWxzZSkucmV0dXJuY29kZSgpID09IDA8YnI+DQor ZW5kaWY8YnI+DQorPGJyPg0KK2lmIG5vdCBicGZ0b29sX3N1cHBvcnRzX3NrZWw8YnI+DQrCoCDC oCDCoG1lc3NhZ2UoJiMzOTtuZXQvdGFwOiBubyBSU1Mgc3VwcG9ydCBtaXNzaW5nIGJwZnRvb2wm IzM5Oyk8YnI+DQrCoCDCoCDCoHN1YmRpcl9kb25lKCk8YnI+DQrCoGVuZGlmPGJyPg0KQEAgLTM5 LDQzICs0OCw0NyBAQCBtYWNoaW5lX25hbWUgPSBydW5fY29tbWFuZCgmIzM5O3VuYW1lJiMzOTss ICYjMzk7LW0mIzM5Oykuc3Rkb3V0KCkuc3RyaXAoKTxicj4NCsKgbWFyY2hfaW5jbHVkZV9kaXIg PSAmIzM5Oy91c3IvaW5jbHVkZS8mIzM5OyArIG1hY2hpbmVfbmFtZSArICYjMzk7LWxpbnV4LWdu dSYjMzk7PGJyPg0KPGJyPg0KwqBjbGFuZ19mbGFncyA9IFs8YnI+DQotwqAgwqAgJiMzOTstTzIm IzM5Oyw8YnI+DQotwqAgwqAgJiMzOTstV2FsbCYjMzk7LDxicj4NCi3CoCDCoCAmIzM5Oy1XZXh0 cmEmIzM5Oyw8YnI+DQotwqAgwqAgJiMzOTstdGFyZ2V0JiMzOTssPGJyPg0KLcKgIMKgICYjMzk7 YnBmJiMzOTssPGJyPg0KLcKgIMKgICYjMzk7LWcmIzM5Oyw8YnI+DQotwqAgwqAgJiMzOTstYyYj Mzk7LDxicj4NCivCoCDCoCDCoCDCoCAjIHRoZXNlIGFyZSBmbGFncyB1c2VkIHRvIGJ1aWxkIHRo ZSBCUEYgY29kZTxicj4NCivCoCDCoCDCoCDCoCAmIzM5Oy1PMiYjMzk7LDxicj4NCivCoCDCoCDC oCDCoCAmIzM5Oy1XYWxsJiMzOTssPGJyPg0KK8KgIMKgIMKgIMKgICYjMzk7LVdleHRyYSYjMzk7 LDxicj4NCivCoCDCoCDCoCDCoCBtYXhfcXVldWVzLDxicj4NCivCoCDCoCDCoCDCoCAmIzM5Oy10 YXJnZXQmIzM5Oyw8YnI+DQorwqAgwqAgwqAgwqAgJiMzOTticGYmIzM5Oyw8YnI+DQorwqAgwqAg wqAgwqAgJiMzOTstZyYjMzk7LDxicj4NCivCoCDCoCDCoCDCoCAmIzM5Oy1jJiMzOTssPGJyPg0K wqBdPGJyPg0KPGJyPg0KKyMgQ29tbWFuZCB1c2VkIHRvIGNvbXBpbGUgQlBGIHBncm9ncmFtZTxi cj4NCsKgYnBmX29fY21kID0gWzxicj4NCi3CoCDCoCBjbGFuZyw8YnI+DQotwqAgwqAgY2xhbmdf ZmxhZ3MsPGJyPg0KLcKgIMKgICYjMzk7LWlkaXJhZnRlciYjMzk7LDxicj4NCi3CoCDCoCBsaWJi cGZfaW5jbHVkZV9kaXIsPGJyPg0KLcKgIMKgICYjMzk7LWlkaXJhZnRlciYjMzk7LDxicj4NCi3C oCDCoCBtYXJjaF9pbmNsdWRlX2Rpciw8YnI+DQotwqAgwqAgJiMzOTtASU5QVVRAJiMzOTssPGJy Pg0KLcKgIMKgICYjMzk7LW8mIzM5Oyw8YnI+DQotwqAgwqAgJiMzOTtAT1VUUFVUQCYjMzk7PGJy Pg0KK8KgIMKgIMKgIMKgIGNsYW5nLDxicj4NCivCoCDCoCDCoCDCoCBjbGFuZ19mbGFncyw8YnI+ DQorwqAgwqAgwqAgwqAgJiMzOTstaWRpcmFmdGVyJiMzOTssPGJyPg0KK8KgIMKgIMKgIMKgIGxp YmJwZl9pbmNsdWRlX2Rpciw8YnI+DQorwqAgwqAgwqAgwqAgJiMzOTstaWRpcmFmdGVyJiMzOTss PGJyPg0KK8KgIMKgIMKgIMKgIG1hcmNoX2luY2x1ZGVfZGlyLDxicj4NCivCoCDCoCDCoCDCoCAm IzM5O0BJTlBVVEAmIzM5Oyw8YnI+DQorwqAgwqAgwqAgwqAgJiMzOTstbyYjMzk7LDxicj4NCivC oCDCoCDCoCDCoCAmIzM5O0BPVVRQVVRAJiMzOTssPGJyPg0KwqBdPGJyPg0KPGJyPg0KKyMgQ29t bWFuZCB1c2VkIHRvIGdlbmVyYXRlIGhlYWRlciBmaWxlIGZyb20gQlBGIG9iamVjdDxicj4NCsKg c2tlbF9oX2NtZCA9IFs8YnI+DQotwqAgwqAgYnBmdG9vbCw8YnI+DQotwqAgwqAgJiMzOTtnZW4m IzM5Oyw8YnI+DQotwqAgwqAgJiMzOTtza2VsZXRvbiYjMzk7LDxicj4NCi3CoCDCoCAmIzM5O0BJ TlBVVEAmIzM5Ozxicj4NCivCoCDCoCDCoCDCoCBicGZ0b29sLDxicj4NCivCoCDCoCDCoCDCoCAm IzM5O2dlbiYjMzk7LDxicj4NCivCoCDCoCDCoCDCoCAmIzM5O3NrZWxldG9uJiMzOTssPGJyPg0K K8KgIMKgIMKgIMKgICYjMzk7QElOUFVUQCYjMzk7LDxicj4NCsKgXTxicj4NCjxicj4NCsKgdGFw X3Jzc19vID0gY3VzdG9tX3RhcmdldCg8YnI+DQotwqAgwqAgJiMzOTt0YXBfcnNzLmJwZi5vJiMz OTssPGJyPg0KLcKgIMKgIGlucHV0OiAmIzM5O3RhcF9yc3MuYyYjMzk7LDxicj4NCi3CoCDCoCBv dXRwdXQ6ICYjMzk7dGFwX3Jzcy5vJiMzOTssPGJyPg0KLcKgIMKgIGNvbW1hbmQ6IGJwZl9vX2Nt ZCk8YnI+DQorwqAgwqAgwqAgwqAgJiMzOTt0YXBfcnNzLmJwZi5vJiMzOTssPGJyPg0KK8KgIMKg IMKgIMKgIGlucHV0OiAmIzM5O3RhcF9yc3MuYyYjMzk7LDxicj4NCivCoCDCoCDCoCDCoCBvdXRw dXQ6ICYjMzk7dGFwX3Jzcy5vJiMzOTssPGJyPg0KK8KgIMKgIMKgIMKgIGNvbW1hbmQ6IGJwZl9v X2NtZCk8YnI+DQo8YnI+DQrCoHRhcF9yc3Nfc2tlbF9oID0gY3VzdG9tX3RhcmdldCg8YnI+DQot wqAgwqAgJiMzOTt0YXBfcnNzLnNrZWwuaCYjMzk7LDxicj4NCi3CoCDCoCBpbnB1dDogdGFwX3Jz c19vLDxicj4NCi3CoCDCoCBvdXRwdXQ6ICYjMzk7dGFwX3Jzcy5za2VsLmgmIzM5Oyw8YnI+DQot wqAgwqAgY29tbWFuZDogc2tlbF9oX2NtZCw8YnI+DQotwqAgwqAgY2FwdHVyZTogdHJ1ZSk8YnI+ DQorwqAgwqAgwqAgwqAgJiMzOTt0YXBfcnNzLnNrZWwuaCYjMzk7LDxicj4NCivCoCDCoCDCoCDC oCBpbnB1dDogdGFwX3Jzc19vLDxicj4NCivCoCDCoCDCoCDCoCBvdXRwdXQ6ICYjMzk7dGFwX3Jz cy5za2VsLmgmIzM5Oyw8YnI+DQorwqAgwqAgwqAgwqAgY29tbWFuZDogc2tlbF9oX2NtZCw8YnI+ DQorwqAgwqAgwqAgwqAgY2FwdHVyZTogdHJ1ZSk8YnI+DQpkaWZmIC0tZ2l0IGEvZHJpdmVycy9u ZXQvdGFwL21lc29uLmJ1aWxkIGIvZHJpdmVycy9uZXQvdGFwL21lc29uLmJ1aWxkPGJyPg0KaW5k ZXggNjY2NDdhMWM2Mi4uNWU1YTNhZDNjNiAxMDA2NDQ8YnI+DQotLS0gYS9kcml2ZXJzL25ldC90 YXAvbWVzb24uYnVpbGQ8YnI+DQorKysgYi9kcml2ZXJzL25ldC90YXAvbWVzb24uYnVpbGQ8YnI+ DQpAQCAtNSwzNiArNSwzMyBAQCBpZiBub3QgaXNfbGludXg8YnI+DQrCoCDCoCDCoGJ1aWxkID0g ZmFsc2U8YnI+DQrCoCDCoCDCoHJlYXNvbiA9ICYjMzk7b25seSBzdXBwb3J0ZWQgb24gTGludXgm IzM5Ozxicj4NCsKgZW5kaWY8YnI+DQorPGJyPg0KwqBzb3VyY2VzID0gZmlsZXMoPGJyPg0KwqAg wqAgwqAgwqAgwqAmIzM5O3J0ZV9ldGhfdGFwLmMmIzM5Oyw8YnI+DQrCoCDCoCDCoCDCoCDCoCYj Mzk7dGFwX2ludHIuYyYjMzk7LDxicj4NCsKgIMKgIMKgIMKgIMKgJiMzOTt0YXBfbmV0bGluay5j JiMzOTssPGJyPg0KwqApPGJyPg0KPGJyPg0KK2RlcHMgPSBbJiMzOTtidXNfdmRldiYjMzk7LCAm IzM5O2dzbyYjMzk7LCAmIzM5O2hhc2gmIzM5O108YnI+DQorPGJyPg0KK21heF9xdWV1ZXMgPSAm IzM5Oy1EVEFQX01BWF9RVUVVRVM9MTYmIzM5Ozxicj4NCitjZmxhZ3MgKz0gbWF4X3F1ZXVlczxi cj4NCis8YnI+DQorcmVxdWlyZV9pb3ZhX2luX21idWYgPSBmYWxzZTxicj4NCis8YnI+DQrCoGlm IGNjLmhhc19oZWFkZXJfc3ltYm9sKCYjMzk7bGludXgvcGt0X2Nscy5oJiMzOTssICYjMzk7VENB X0ZMT1dFUl9BQ1QmIzM5Oyk8YnI+DQrCoCDCoCDCoGNmbGFncyArPSAmIzM5Oy1ESEFWRV9UQ0Ff RkxPV0VSJiMzOTs8YnI+DQrCoCDCoCDCoHNvdXJjZXMgKz0gZmlsZXMoPGJyPg0KLcKgIMKgIMKg IMKgICYjMzk7dGFwX2JwZl9hcGkuYyYjMzk7LDxicj4NCi3CoCDCoCDCoCDCoCAmIzM5O3RhcF9m bG93LmMmIzM5Oyw8YnI+DQotwqAgwqAgwqAgwqAgJiMzOTt0YXBfdGNtc2dzLmMmIzM5Oyw8YnI+ DQorwqAgwqAgwqAgwqAgwqAgwqAgJiMzOTt0YXBfZmxvdy5jJiMzOTssPGJyPg0KK8KgIMKgIMKg IMKgIMKgIMKgICYjMzk7dGFwX3RjbXNncy5jJiMzOTssPGJyPg0KwqAgwqAgwqApPGJyPg0KLWVu ZGlmPGJyPg0KLTxicj4NCi1kZXBzID0gWyYjMzk7YnVzX3ZkZXYmIzM5OywgJiMzOTtnc28mIzM5 OywgJiMzOTtoYXNoJiMzOTtdPGJyPg0KPGJyPg0KLWNmbGFncyArPSAmIzM5Oy1EVEFQX01BWF9R VUVVRVM9MTYmIzM5Ozxicj4NCi08YnI+DQotIyBpbnB1dCBhcnJheSBmb3IgbWVzb24gc3ltYm9s IHNlYXJjaDo8YnI+DQotIyBbICZxdW90O01BQ1JPIHRvIGRlZmluZSBpZiBmb3VuZCZxdW90Oywg JnF1b3Q7aGVhZGVyIGZvciB0aGUgc2VhcmNoJnF1b3Q7LDxicj4NCi0jwqAgwqAmcXVvdDtlbnVt L2RlZmluZSZxdW90OywgJnF1b3Q7c3ltYm9sIHRvIHNlYXJjaCZxdW90OyBdPGJyPg0KLSM8YnI+ DQotYXJncyA9IFs8YnI+DQotwqAgwqAgwqAgwqAgWyAmIzM5O0hBVkVfVENfQUNUX0JQRiYjMzk7 LCAmIzM5O2xpbnV4L3RjX2FjdC90Y19icGYuaCYjMzk7LCAmIzM5O1RDQV9BQ1RfQlBGX1VOU1BF QyYjMzk7IF0sPGJyPg0KLV08YnI+DQotY29uZmlnID0gY29uZmlndXJhdGlvbl9kYXRhKCk8YnI+ DQotZm9yZWFjaCBhcmc6YXJnczxicj4NCi3CoCDCoCBjb25maWcuc2V0KGFyZ1swXSwgY2MuaGFz X2hlYWRlcl9zeW1ib2woYXJnWzFdLCBhcmdbMl0pKTxicj4NCi1lbmRmb3JlYWNoPGJyPg0KLWNv bmZpZ3VyZV9maWxlKG91dHB1dCA6ICYjMzk7dGFwX2F1dG9jb25mLmgmIzM5OywgY29uZmlndXJh dGlvbiA6IGNvbmZpZyk8YnI+DQorwqAgwqAgZW5hYmxlX3RhcF9yc3MgPSBmYWxzZTxicj4NCjxi cj4NCi1yZXF1aXJlX2lvdmFfaW5fbWJ1ZiA9IGZhbHNlPGJyPg0KK8KgIMKgIHN1YmRpcigmIzM5 O2JwZiYjMzk7KTxicj4NCivCoCDCoCBpZiBlbmFibGVfdGFwX3Jzczxicj4NCivCoCDCoCDCoCDC oCBjZmxhZ3MgKz0gJiMzOTstREhBVkVfQlBGX1JTUyYjMzk7PGJyPg0KK8KgIMKgIMKgIMKgIGV4 dF9kZXBzICs9IGxpYmJwZjxicj4NCivCoCDCoCDCoCDCoCBzb3VyY2VzICs9IHRhcF9yc3Nfc2tl bF9oPGJyPg0KK8KgIMKgIGVuZGlmPGJyPg0KK2VuZGlmPGJyPg0KZGlmZiAtLWdpdCBhL2RyaXZl cnMvbmV0L3RhcC9ydGVfZXRoX3RhcC5jIGIvZHJpdmVycy9uZXQvdGFwL3J0ZV9ldGhfdGFwLmM8 YnI+DQppbmRleCA5MDU4YTQ3Mjk1Li5kODQ3NTY1MDczIDEwMDY0NDxicj4NCi0tLSBhL2RyaXZl cnMvbmV0L3RhcC9ydGVfZXRoX3RhcC5jPGJyPg0KKysrIGIvZHJpdmVycy9uZXQvdGFwL3J0ZV9l dGhfdGFwLmM8YnI+DQpAQCAtMTE0MCw2ICsxMTQwLDcgQEAgdGFwX2Rldl9jbG9zZShzdHJ1Y3Qg cnRlX2V0aF9kZXYgKmRldik8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCB0YXBfZmxvd19p bXBsaWNpdF9mbHVzaChpbnRlcm5hbHMsIE5VTEwpOzxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIHRhcF9ubF9maW5hbChpbnRlcm5hbHMtJmd0O25sc2tfZmQpOzxicj4NCsKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIGludGVybmFscy0mZ3Q7bmxza19mZCA9IC0xOzxicj4NCivCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoHRhcF9mbG93X2JwZl9kZXN0cm95KGludGVybmFscyk7PGJyPg0KwqAgwqAg wqAgwqAgfTxicj4NCsKgI2VuZGlmPGJyPg0KPGJyPg0KQEAgLTE5NDksNiArMTk1MCw3IEBAIGV0 aF9kZXZfdGFwX2NyZWF0ZShzdHJ1Y3QgcnRlX3ZkZXZfZGV2aWNlICp2ZGV2LCBjb25zdCBjaGFy ICp0YXBfbmFtZSw8YnI+DQrCoCDCoCDCoCDCoCBzdHJsY3B5KHBtZC0mZ3Q7bmFtZSwgdGFwX25h bWUsIHNpemVvZihwbWQtJmd0O25hbWUpKTs8YnI+DQrCoCDCoCDCoCDCoCBwbWQtJmd0O3R5cGUg PSB0eXBlOzxicj4NCsKgIMKgIMKgIMKgIHBtZC0mZ3Q7a2FfZmQgPSAtMTs8YnI+DQorPGJyPg0K wqAjaWZkZWYgSEFWRV9UQ0FfRkxPV0VSPGJyPg0KwqAgwqAgwqAgwqAgcG1kLSZndDtubHNrX2Zk ID0gLTE7PGJyPg0KwqAjZW5kaWY8YnI+DQpAQCAtMjAzMSwxMyArMjAzMyw2IEBAIGV0aF9kZXZf dGFwX2NyZWF0ZShzdHJ1Y3QgcnRlX3ZkZXZfZGV2aWNlICp2ZGV2LCBjb25zdCBjaGFyICp0YXBf bmFtZSw8YnI+DQrCoCDCoCDCoCDCoCAvKiBNYWtlIG5ldHdvcmsgZGV2aWNlIHBlcnNpc3QgYWZ0 ZXIgYXBwbGljYXRpb24gZXhpdCAqLzxicj4NCsKgIMKgIMKgIMKgIHBtZC0mZ3Q7cGVyc2lzdCA9 IHBlcnNpc3Q7PGJyPg0KPGJyPg0KLcKgIMKgIMKgIMKgcG1kLSZndDtpZl9pbmRleCA9IGlmX25h bWV0b2luZGV4KHBtZC0mZ3Q7bmFtZSk7PGJyPg0KLcKgIMKgIMKgIMKgaWYgKCFwbWQtJmd0O2lm X2luZGV4KSB7PGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgVEFQX0xPRyhFUlIsICZxdW90 OyVzOiBmYWlsZWQgdG8gZ2V0IGlmX2luZGV4LiZxdW90OywgcG1kLSZndDtuYW1lKTs8YnI+DQot wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBnb3RvIGRpc2FibGVfcnRlX2Zsb3c7PGJyPg0KLcKgIMKg IMKgIMKgfTxicj4NCi08YnI+DQotPGJyPg0KwqAjaWZkZWYgSEFWRV9UQ0FfRkxPV0VSPGJyPg0K wqAgwqAgwqAgwqAgLyo8YnI+DQrCoCDCoCDCoCDCoCDCoCogU2V0IHVwIGV2ZXJ5dGhpbmcgcmVs YXRlZCB0byBydGVfZmxvdzo8YnI+DQpAQCAtMjA1Myw2ICsyMDQ4LDExIEBAIGV0aF9kZXZfdGFw X2NyZWF0ZShzdHJ1Y3QgcnRlX3ZkZXZfZGV2aWNlICp2ZGV2LCBjb25zdCBjaGFyICp0YXBfbmFt ZSw8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBwbWQtJmd0O25hbWUp Ozxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGdvdG8gZGlzYWJsZV9ydGVfZmxvdzs8YnI+ DQrCoCDCoCDCoCDCoCB9PGJyPg0KK8KgIMKgIMKgIMKgcG1kLSZndDtpZl9pbmRleCA9IGlmX25h bWV0b2luZGV4KHBtZC0mZ3Q7bmFtZSk7PGJyPg0KK8KgIMKgIMKgIMKgaWYgKCFwbWQtJmd0O2lm X2luZGV4KSB7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgVEFQX0xPRyhFUlIsICZxdW90 OyVzOiBmYWlsZWQgdG8gZ2V0IGlmX2luZGV4LiZxdW90OywgcG1kLSZndDtuYW1lKTs8YnI+DQor wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBnb3RvIGRpc2FibGVfcnRlX2Zsb3c7PGJyPg0KK8KgIMKg IMKgIMKgfTxicj4NCsKgIMKgIMKgIMKgIGlmIChxZGlzY19jcmVhdGVfbXVsdGlxKHBtZC0mZ3Q7 bmxza19mZCwgcG1kLSZndDtpZl9pbmRleCkgJmx0OyAwKSB7PGJyPg0KwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgVEFQX0xPRyhFUlIsICZxdW90OyVzOiBmYWlsZWQgdG8gY3JlYXRlIG11bHRpcSBx ZGlzYy4mcXVvdDssPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgcG1k LSZndDtuYW1lKTs8YnI+DQpkaWZmIC0tZ2l0IGEvZHJpdmVycy9uZXQvdGFwL3J0ZV9ldGhfdGFw LmggYi9kcml2ZXJzL25ldC90YXAvcnRlX2V0aF90YXAuaDxicj4NCmluZGV4IGFmMThiMjkwOTAu LmNlNDMyMmFkMDQgMTAwNjQ0PGJyPg0KLS0tIGEvZHJpdmVycy9uZXQvdGFwL3J0ZV9ldGhfdGFw Lmg8YnI+DQorKysgYi9kcml2ZXJzL25ldC90YXAvcnRlX2V0aF90YXAuaDxicj4NCkBAIC04MSwx MCArODEsOCBAQCBzdHJ1Y3QgcG1kX2ludGVybmFscyB7PGJyPg0KwqAjaWZkZWYgSEFWRV9UQ0Ff RkxPV0VSPGJyPg0KwqAgwqAgwqAgwqAgaW50IG5sc2tfZmQ7wqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgLyogTmV0bGluayBzb2NrZXQgZmQgKi88YnI+DQrCoCDCoCDCoCDCoCBpbnQg Zmxvd19pc29sYXRlO8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgLyogMSBpZiBmbG93IGlzb2xh dGlvbiBpcyBlbmFibGVkICovPGJyPg0KLcKgIMKgIMKgIMKgaW50IHJzc19lbmFibGVkO8KgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIC8qIDEgaWYgUlNTIGlzIGVuYWJsZWQsIGVsc2UgMCAqLzxi cj4NCi3CoCDCoCDCoCDCoC8qIGltcGxpY2l0IHJ1bGVzIHNldCB3aGVuIFJTUyBpcyBlbmFibGVk ICovPGJyPg0KLcKgIMKgIMKgIMKgaW50IG1hcF9mZDvCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoC8qIEJQRiBSU1MgbWFwIGZkICovPGJyPg0KLcKgIMKgIMKgIMKgaW50IGJwZl9m ZFtSVEVfUE1EX1RBUF9NQVhfUVVFVUVTXTsvKiBMaXN0IG9mIGJwZiBmZHMgcGVyIHF1ZXVlICov PGJyPg0KKzxicj4NCivCoCDCoCDCoCDCoHN0cnVjdCB0YXBfcnNzICpyc3M7wqAgwqAgwqAgwqAg wqAgwqAgwqAgLyogQlBGIHByb2dyYW0gKi88YnI+DQo8YnI+DQrCoCDCoCDCoCDCoCBMSVNUX0hF QUQodGFwX2Zsb3dzLCBydGVfZmxvdykgZmxvd3M7wqAgwqAgwqAgwqAgLyogcnRlX2Zsb3cgcnVs ZXMgKi88YnI+DQrCoCDCoCDCoCDCoCAvKiBpbXBsaWNpdCBydGVfZmxvdyBydWxlcyBzZXQgd2hl biBhIHJlbW90ZSBkZXZpY2UgaXMgYWN0aXZlICovPGJyPg0KZGlmZiAtLWdpdCBhL2RyaXZlcnMv bmV0L3RhcC90YXBfZmxvdy5jIGIvZHJpdmVycy9uZXQvdGFwL3RhcF9mbG93LmM8YnI+DQppbmRl eCA0NTMyMWFlZTg2Li4wYTkwYzA0ODdiIDEwMDY0NDxicj4NCi0tLSBhL2RyaXZlcnMvbmV0L3Rh cC90YXBfZmxvdy5jPGJyPg0KKysrIGIvZHJpdmVycy9uZXQvdGFwL3RhcF9mbG93LmM8YnI+DQpA QCAtMTUsMjUgKzE1LDE5IEBAPGJyPg0KwqAjaW5jbHVkZSAmbHQ7cnRlX3JhbmRvbS5oJmd0Ozxi cj4NCsKgI2luY2x1ZGUgJmx0O3J0ZV9tYWxsb2MuaCZndDs8YnI+DQrCoCNpbmNsdWRlICZsdDty dGVfZXRoX3RhcC5oJmd0Ozxicj4NCisjaW5jbHVkZSAmbHQ7cnRlX3V1aWQuaCZndDs8YnI+DQo8 YnI+DQrCoCNpbmNsdWRlICZsdDt0YXBfZmxvdy5oJmd0Ozxicj4NCi0jaW5jbHVkZSAmbHQ7dGFw X2F1dG9jb25mLmgmZ3Q7PGJyPg0KwqAjaW5jbHVkZSAmbHQ7dGFwX3RjbXNncy5oJmd0Ozxicj4N CsKgI2luY2x1ZGUgJmx0O3RhcF9yc3MuaCZndDs8YnI+DQo8YnI+DQotLyogUlNTIGtleSBtYW5h Z2VtZW50ICovPGJyPg0KLWVudW0gYnBmX3Jzc19rZXlfZSB7PGJyPg0KLcKgIMKgIMKgIMKgS0VZ X0NNRF9HRVQgPSAxLDxicj4NCi3CoCDCoCDCoCDCoEtFWV9DTURfUkVMRUFTRSw8YnI+DQotwqAg wqAgwqAgwqBLRVlfQ01EX0lOSVQsPGJyPg0KLcKgIMKgIMKgIMKgS0VZX0NNRF9ERUlOSVQsPGJy Pg0KLX07PGJyPg0KLTxicj4NCi1lbnVtIGtleV9zdGF0dXNfZSB7PGJyPg0KLcKgIMKgIMKgIMKg S0VZX1NUQVRfVU5TUEVDLDxicj4NCi3CoCDCoCDCoCDCoEtFWV9TVEFUX1VTRUQsPGJyPg0KLcKg IMKgIMKgIMKgS0VZX1NUQVRfQVZBSUxBQkxFLDxicj4NCi19Ozxicj4NCisjaWZkZWYgSEFWRV9C UEZfUlNTPGJyPg0KKy8qIFdvcmthcm91bmQgZm9yIHdhcm5pbmcgaW4gYnBmdG9vbCBnZW5lcmF0 ZWQgc2tlbGV0b24gY29kZSAqLzxicj4NCisjcHJhZ21hIEdDQyBkaWFnbm9zdGljIHB1c2g8YnI+ DQorI3ByYWdtYSBHQ0MgZGlhZ25vc3RpYyBpZ25vcmVkICZxdW90Oy1XY2FzdC1xdWFsJnF1b3Q7 PGJyPg0KKyNpbmNsdWRlICZxdW90O3RhcF9yc3Muc2tlbC5oJnF1b3Q7PGJyPg0KKyNwcmFnbWEg R0NDIGRpYWdub3N0aWMgcG9wPGJyPg0KKyNlbmRpZjxicj4NCjxicj4NCsKgI2RlZmluZSBJU09M QVRFX0hBTkRMRSAxPGJyPg0KwqAjZGVmaW5lIFJFTU9URV9QUk9NSVNDVU9VU19IQU5ETEUgMjxi cj4NCkBAIC00MSw4ICszNSw2IEBAIGVudW0ga2V5X3N0YXR1c19lIHs8YnI+DQrCoHN0cnVjdCBy dGVfZmxvdyB7PGJyPg0KwqAgwqAgwqAgwqAgTElTVF9FTlRSWShydGVfZmxvdykgbmV4dDsgLyog UG9pbnRlciB0byB0aGUgbmV4dCBydGVfZmxvdyBzdHJ1Y3R1cmUgKi88YnI+DQrCoCDCoCDCoCDC oCBzdHJ1Y3QgcnRlX2Zsb3cgKnJlbW90ZV9mbG93OyAvKiBhc3NvY2lhdGVkIHJlbW90ZSBmbG93 ICovPGJyPg0KLcKgIMKgIMKgIMKgaW50IGJwZl9mZFtTRUNfTUFYXTsgLyogbGlzdCBvZiBiZnMg ZmRzIHBlciBFTEYgc2VjdGlvbiAqLzxicj4NCi3CoCDCoCDCoCDCoHVpbnQzMl90IGtleV9pZHg7 IC8qIFJTUyBydWxlIGtleSBpbmRleCBpbnRvIEJQRiBtYXAgKi88YnI+DQrCoCDCoCDCoCDCoCBz dHJ1Y3Qgbmxtc2cgbXNnOzxicj4NCsKgfTs8YnI+DQo8YnI+DQpAQCAtNjksMTIgKzYxLDE2IEBA IHN0cnVjdCBhY3Rpb25fZGF0YSB7PGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgc3RydWN0 IHNrYmVkaXQgezxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHN0cnVj dCB0Y19za2JlZGl0IHNrYmVkaXQ7PGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgdWludDE2X3QgcXVldWU7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgdWludDMyX3QgbWFyazs8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCB9IHNrYmVk aXQ7PGJyPg0KKyNpZmRlZiBIQVZFX0JQRl9SU1M8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCBzdHJ1Y3QgYnBmIHs8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBz dHJ1Y3QgdGNfYWN0X2JwZiBicGY7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgdWludDMyX3QgbWFwX2tleTs8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCBpbnQgYnBmX2ZkOzxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIGNvbnN0IGNoYXIgKmFubm90YXRpb247PGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg fSBicGY7PGJyPg0KKyNlbmRpZjxicj4NCsKgIMKgIMKgIMKgIH07PGJyPg0KwqB9Ozxicj4NCjxi cj4NCkBAIC0xMTIsMTMgKzEwOCwxMiBAQCB0YXBfZmxvd19pc29sYXRlKHN0cnVjdCBydGVfZXRo X2RldiAqZGV2LDxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgaW50IHNldCw8YnI+DQrC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHN0cnVjdCBydGVfZmxvd19lcnJvciAqZXJyb3IpOzxi cj4NCjxicj4NCi1zdGF0aWMgaW50IGJwZl9yc3Nfa2V5KGVudW0gYnBmX3Jzc19rZXlfZSBjbWQs IF9fdTMyICprZXlfaWR4KTs8YnI+DQotc3RhdGljIGludCByc3NfZW5hYmxlKHN0cnVjdCBwbWRf aW50ZXJuYWxzICpwbWQsPGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg Y29uc3Qgc3RydWN0IHJ0ZV9mbG93X2F0dHIgKmF0dHIsPGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgc3RydWN0IHJ0ZV9mbG93X2Vycm9yICplcnJvcik7PGJyPg0KKyNp ZmRlZiBIQVZFX0JQRl9SU1M8YnI+DQorc3RhdGljIGludCByc3NfZW5hYmxlKHN0cnVjdCBwbWRf aW50ZXJuYWxzICpwbWQsIHN0cnVjdCBydGVfZmxvd19lcnJvciAqZXJyb3IpOzxicj4NCsKgc3Rh dGljIGludCByc3NfYWRkX2FjdGlvbnMoc3RydWN0IHJ0ZV9mbG93ICpmbG93LCBzdHJ1Y3QgcG1k X2ludGVybmFscyAqcG1kLDxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IGNvbnN0IHN0cnVjdCBydGVfZmxvd19hY3Rpb25fcnNzICpyc3MsPGJyPg0KwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgc3RydWN0IHJ0ZV9mbG93X2Vycm9yICplcnJvcik7PGJy Pg0KKyNlbmRpZjxicj4NCjxicj4NCsKgc3RhdGljIGNvbnN0IHN0cnVjdCBydGVfZmxvd19vcHMg dGFwX2Zsb3dfb3BzID0gezxicj4NCsKgIMKgIMKgIMKgIC52YWxpZGF0ZSA9IHRhcF9mbG93X3Zh bGlkYXRlLDxicj4NCkBAIC04NTMsMTEgKzg0OCwxMyBAQCBhZGRfYWN0aW9uKHN0cnVjdCBydGVf ZmxvdyAqZmxvdywgc2l6ZV90ICphY3RfaW5kZXgsIHN0cnVjdCBhY3Rpb25fZGF0YSAqYWRhdGEp PGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAmYW1wO2FkYXRh LSZndDttaXJyZWQpOzxicj4NCsKgIMKgIMKgIMKgIH0gZWxzZSBpZiAoc3RyY21wKCZxdW90O3Nr YmVkaXQmcXVvdDssIGFkYXRhLSZndDtpZCkgPT0gMCkgezxicj4NCsKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIHRhcF9ubGF0dHJfYWRkKCZhbXA7bXNnLSZndDtuaCwgVENBX1NLQkVESVRfUEFSTVMs PGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHNpemVvZihhZGF0 YS0mZ3Q7c2tiZWRpdC5za2JlZGl0KSw8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgJmFtcDthZGF0YS0mZ3Q7c2tiZWRpdC5za2JlZGl0KTs8YnI+DQotwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqB0YXBfbmxhdHRyX2FkZDE2KCZhbXA7bXNnLSZndDtuaCwgVENBX1NL QkVESVRfUVVFVUVfTUFQUElORyw8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgYWRhdGEtJmd0O3NrYmVkaXQucXVldWUpOzxicj4NCivCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBzaXplb2YoYWRhdGEtJmd0O3NrYmVkaXQuc2tiZWRp dCksICZhbXA7YWRhdGEtJmd0O3NrYmVkaXQuc2tiZWRpdCk7PGJyPg0KK8KgIMKgIMKgIMKgIMKg IMKgIMKgIMKgaWYgKGFkYXRhLSZndDtza2JlZGl0Lm1hcmspPGJyPg0KK8KgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgdGFwX25sYXR0cl9hZGQzMigmYW1wO21zZy0mZ3Q7bmgsIFRD QV9TS0JFRElUX01BUkssIGFkYXRhLSZndDtza2JlZGl0Lm1hcmspOzxicj4NCivCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoGVsc2U8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqB0YXBfbmxhdHRyX2FkZDE2KCZhbXA7bXNnLSZndDtuaCwgVENBX1NLQkVESVRfUVVFVUVfTUFQ UElORywgYWRhdGEtJmd0O3NrYmVkaXQucXVldWUpOzxicj4NCsKgIMKgIMKgIMKgIH0gZWxzZSBp ZiAoc3RyY21wKCZxdW90O2JwZiZxdW90OywgYWRhdGEtJmd0O2lkKSA9PSAwKSB7PGJyPg0KKyNp ZmRlZiBIQVZFX0JQRl9SU1M8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCB0YXBfbmxhdHRy X2FkZDMyKCZhbXA7bXNnLSZndDtuaCwgVENBX0FDVF9CUEZfRkQsIGFkYXRhLSZndDticGYuYnBm X2ZkKTs8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCB0YXBfbmxhdHRyX2FkZCgmYW1wO21z Zy0mZ3Q7bmgsIFRDQV9BQ1RfQlBGX05BTUUsPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqBzdHJsZW4oYWRhdGEtJmd0O2JwZi5hbm5vdGF0aW9uKSArIDEsPGJy Pg0KQEAgLTg2NSw3ICs4NjIsMTIgQEAgYWRkX2FjdGlvbihzdHJ1Y3QgcnRlX2Zsb3cgKmZsb3cs IHNpemVfdCAqYWN0X2luZGV4LCBzdHJ1Y3QgYWN0aW9uX2RhdGEgKmFkYXRhKTxicj4NCsKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIHRhcF9ubGF0dHJfYWRkKCZhbXA7bXNnLSZndDtuaCwgVENBX0FD VF9CUEZfUEFSTVMsPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqBzaXplb2YoYWRhdGEtJmd0O2JwZi5icGYpLDxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgJmFtcDthZGF0YS0mZ3Q7YnBmLmJwZik7PGJyPg0KKyNlbHNlPGJy Pg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgVEFQX0xPRyhFUlIsICZxdW90O0ludGVybmFsIGVy cm9yOiBicGYgcmVxdWVzdGVkIGJ1dCBub3Qgc3VwcG9ydGVkJnF1b3Q7KTs8YnI+DQorwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqByZXR1cm4gLTE7PGJyPg0KKyNlbmRpZjxicj4NCsKgIMKgIMKgIMKg IH0gZWxzZSB7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgVEFQX0xPRyhFUlIsICZxdW90 O0ludGVybmFsIGVycm9yOiB1bmtub3duIGFjdGlvbjogJXMmcXVvdDssIGFkYXRhLSZndDtpZCk7 PGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgcmV0dXJuIC0xOzxicj4NCsKgIMKgIMKgIMKg IH08YnI+DQrCoCDCoCDCoCDCoCB0YXBfbmxhdHRyX25lc3RlZF9maW5pc2gobXNnKTsgLyogbmVz dGVkIFRDQV9BQ1RfT1BUSU9OUyAqLzxicj4NCkBAIC0xMTA0LDggKzExMDYsNyBAQCBwcml2X2Zs b3dfcHJvY2VzcyhzdHJ1Y3QgcG1kX2ludGVybmFscyAqcG1kLDxicj4NCsKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIH0sPGJyPg0KwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgfTs8YnI+DQo8YnI+ DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBlcnIgPSBh ZGRfYWN0aW9ucyhmbG93LCAxLCAmYW1wO2FkYXRhLDxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoFRD QV9GTE9XRVJfQUNUKTs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqBlcnIgPSBhZGRfYWN0aW9ucyhmbG93LCAxLCAmYW1wO2FkYXRhLCBUQ0FfRkxP V0VSX0FDVCk7PGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgfTxicj4N CsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIH0gZWxzZSBpZiAoYWN0aW9ucy0mZ3Q7dHlwZSA9PSBS VEVfRkxPV19BQ1RJT05fVFlQRV9RVUVVRSkgezxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIGNvbnN0IHN0cnVjdCBydGVfZmxvd19hY3Rpb25fcXVldWUgKnF1ZXVlID08 YnI+DQpAQCAtMTEzNSw2ICsxMTM2LDcgQEAgcHJpdl9mbG93X3Byb2Nlc3Moc3RydWN0IHBtZF9p bnRlcm5hbHMgKnBtZCw8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCBlcnIgPSBhZGRfYWN0aW9ucyhmbG93LCAxLCAmYW1wO2FkYXRhLDxicj4NCsKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IFRDQV9GTE9XRVJfQUNUKTs8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCB9PGJyPg0KKyNpZmRlZiBIQVZFX0JQRl9SU1M8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCB9IGVsc2UgaWYgKGFjdGlvbnMtJmd0O3R5cGUgPT0gUlRFX0ZMT1dfQUNUSU9OX1RZUEVfUlNT KSB7PGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgY29uc3Qgc3RydWN0 IHJ0ZV9mbG93X2FjdGlvbl9yc3MgKnJzcyA9PGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgKGNvbnN0IHN0cnVjdCBydGVfZmxvd19hY3Rpb25fcnNz ICopPGJyPg0KQEAgLTExNDMsMTMgKzExNDUsMTQgQEAgcHJpdl9mbG93X3Byb2Nlc3Moc3RydWN0 IHBtZF9pbnRlcm5hbHMgKnBtZCw8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCBpZiAoYWN0aW9uKyspPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgZ290byBleGl0X2FjdGlvbl9ub3Rfc3VwcG9ydGVkOzxicj4NCjxicj4N Ci3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGlmICghcG1kLSZndDtyc3NfZW5h YmxlZCkgezxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoGVyciA9IHJzc19lbmFibGUocG1kLCBhdHRyLCBlcnJvcik7PGJyPg0KK8KgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgaWYgKHBtZC0mZ3Q7cnNzID09IE5VTEwpIHs8YnI+DQor wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBlcnIgPSByc3Nf ZW5hYmxlKHBtZCwgZXJyb3IpOzxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIGlmIChlcnIpPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgZ290byBleGl0X3JldHVybl9lcnJvcjs8 YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCB9PGJyPg0KwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgaWYgKGZsb3cpPGJyPg0KwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgZXJyID0gcnNzX2FkZF9hY3Rpb25zKGZs b3csIHBtZCwgcnNzLCBlcnJvcik7PGJyPg0KKyNlbmRpZjxicj4NCsKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIH0gZWxzZSB7PGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg Z290byBleGl0X2FjdGlvbl9ub3Rfc3VwcG9ydGVkOzxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIH08YnI+DQpAQCAtMTI0NiwyNiArMTI0OSwxNyBAQCB0YXBfZmxvd19zZXRfaGFuZGxlKHN0 cnVjdCBydGVfZmxvdyAqZmxvdyk8YnI+DQrCoCAqPGJyPg0KwqAgKi88YnI+DQrCoHN0YXRpYyB2 b2lkPGJyPg0KLXRhcF9mbG93X2ZyZWUoc3RydWN0IHBtZF9pbnRlcm5hbHMgKnBtZCwgc3RydWN0 IHJ0ZV9mbG93ICpmbG93KTxicj4NCit0YXBfZmxvd19mcmVlKHN0cnVjdCBwbWRfaW50ZXJuYWxz ICpwbWQgX19ydGVfdW51c2VkLCBzdHJ1Y3QgcnRlX2Zsb3cgKmZsb3cpPGJyPg0KwqB7PGJyPg0K LcKgIMKgIMKgIMKgaW50IGk7PGJyPg0KLTxicj4NCsKgIMKgIMKgIMKgIGlmICghZmxvdyk8YnI+ DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCByZXR1cm47PGJyPg0KPGJyPg0KLcKgIMKgIMKgIMKg aWYgKHBtZC0mZ3Q7cnNzX2VuYWJsZWQpIHs8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAv KiBDbG9zZSBmbG93IEJQRiBmaWxlIGRlc2NyaXB0b3JzICovPGJyPg0KLcKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgZm9yIChpID0gMDsgaSAmbHQ7IFNFQ19NQVg7IGkrKyk8YnI+DQotwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBpZiAoZmxvdy0mZ3Q7YnBmX2ZkW2ldICE9IDApIHs8 YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBjbG9z ZShmbG93LSZndDticGZfZmRbaV0pOzxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoGZsb3ctJmd0O2JwZl9mZFtpXSA9IDA7PGJyPg0KLcKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgfTxicj4NCi08YnI+DQotwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAvKiBSZWxlYXNlIHRoZSBtYXAga2V5IGZvciB0aGlzIFJTUyBydWxlICovPGJyPg0K LcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgYnBmX3Jzc19rZXkoS0VZX0NNRF9SRUxFQVNFLCAmYW1w O2Zsb3ctJmd0O2tleV9pZHgpOzxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGZsb3ctJmd0 O2tleV9pZHggPSAwOzxicj4NCi3CoCDCoCDCoCDCoH08YnI+DQotPGJyPg0KKyNpZmRlZiBIQVZF X0JQRl9SU1M8YnI+DQorwqAgwqAgwqAgwqBzdHJ1Y3QgdGFwX3JzcyAqcnNzID0gcG1kLSZndDty c3M7PGJyPg0KK8KgIMKgIMKgIMKgaWYgKHJzcyk8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqBicGZfbWFwX19kZWxldGVfZWxlbShyc3MtJmd0O21hcHMucnNzX21hcCw8YnI+DQorwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgJmFtcDtmbG93 LSZndDttc2cudC50Y21faGFuZGxlLCBzaXplb2YodWludDMyX3QpLCAwKTs8YnI+DQorI2VuZGlm PGJyPg0KwqAgwqAgwqAgwqAgLyogRnJlZSBmbG93IGFsbG9jYXRlZCBtZW1vcnkgKi88YnI+DQrC oCDCoCDCoCDCoCBydGVfZnJlZShmbG93KTs8YnI+DQrCoH08YnI+DQpAQCAtMTczMywxNCArMTcy NywxOCBAQCB0YXBfZmxvd19pbXBsaWNpdF9mbHVzaChzdHJ1Y3QgcG1kX2ludGVybmFscyAqcG1k LCBzdHJ1Y3QgcnRlX2Zsb3dfZXJyb3IgKmVycm9yKTxicj4NCsKgIMKgIMKgIMKgIHJldHVybiAw Ozxicj4NCsKgfTxicj4NCjxicj4NCi0jZGVmaW5lIE1BWF9SU1NfS0VZUyAyNTY8YnI+DQotI2Rl ZmluZSBLRVlfSURYX09GRlNFVCAoMyAqIE1BWF9SU1NfS0VZUyk8YnI+DQotI2RlZmluZSBTRUNf TkFNRV9DTFNfUSAmcXVvdDtjbHNfcSZxdW90Ozxicj4NCi08YnI+DQotc3RhdGljIGNvbnN0IGNo YXIgKnNlY19uYW1lW1NFQ19NQVhdID0gezxicj4NCi3CoCDCoCDCoCDCoFtTRUNfTDNfTDRdID0g JnF1b3Q7bDNfbDQmcXVvdDssPGJyPg0KLX07PGJyPg0KKy8qKjxicj4NCisgKiBDbGVhbnVwIHdo ZW4gZGV2aWNlIGlzIGNsb3NlZDxicj4NCisgKi88YnI+DQordm9pZCB0YXBfZmxvd19icGZfZGVz dHJveShzdHJ1Y3QgcG1kX2ludGVybmFscyAqcG1kIF9fcnRlX3VudXNlZCk8YnI+DQorezxicj4N CisjaWZkZWYgSEFWRV9CUEZfUlNTPGJyPg0KK8KgIMKgIMKgIMKgdGFwX3Jzc19fZGVzdHJveShw bWQtJmd0O3Jzcyk7PGJyPg0KK8KgIMKgIMKgIMKgcG1kLSZndDtyc3MgPSBOVUxMOzxicj4NCisj ZW5kaWY8YnI+DQorfTxicj4NCjxicj4NCisjaWZkZWYgSEFWRV9CUEZfUlNTPGJyPg0KwqAvKio8 YnI+DQrCoCAqIEVuYWJsZSBSU1Mgb24gdGFwOiBjcmVhdGUgVEMgcnVsZXMgZm9yIHF1ZXVpbmcu PGJyPg0KwqAgKjxicj4NCkBAIC0xNzU1LDIyNSArMTc1MywzMiBAQCBzdGF0aWMgY29uc3QgY2hh ciAqc2VjX25hbWVbU0VDX01BWF0gPSB7PGJyPg0KwqAgKjxicj4NCsKgICogQHJldHVybiAwIG9u IHN1Y2Nlc3MsIG5lZ2F0aXZlIHZhbHVlIG9uIGZhaWx1cmUuPGJyPg0KwqAgKi88YnI+DQotc3Rh dGljIGludCByc3NfZW5hYmxlKHN0cnVjdCBwbWRfaW50ZXJuYWxzICpwbWQsPGJyPg0KLcKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgY29uc3Qgc3RydWN0IHJ0ZV9mbG93X2F0dHIg KmF0dHIsPGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgc3RydWN0IHJ0 ZV9mbG93X2Vycm9yICplcnJvcik8YnI+DQorc3RhdGljIGludCByc3NfZW5hYmxlKHN0cnVjdCBw bWRfaW50ZXJuYWxzICpwbWQsIHN0cnVjdCBydGVfZmxvd19lcnJvciAqZXJyb3IpPGJyPg0KwqB7 PGJyPg0KLcKgIMKgIMKgIMKgc3RydWN0IHJ0ZV9mbG93ICpyc3NfZmxvdyA9IE5VTEw7PGJyPg0K LcKgIMKgIMKgIMKgc3RydWN0IG5sbXNnICptc2cgPSBOVUxMOzxicj4NCi3CoCDCoCDCoCDCoC8q IDQwOTYgaXMgdGhlIG1heGltdW0gbnVtYmVyIG9mIGluc3RydWN0aW9ucyBmb3IgYSBCUEYgcHJv Z3JhbSAqLzxicj4NCi3CoCDCoCDCoCDCoGNoYXIgYW5ub3RhdGlvbls2NF07PGJyPg0KLcKgIMKg IMKgIMKgaW50IGk7PGJyPg0KLcKgIMKgIMKgIMKgaW50IGVyciA9IDA7PGJyPg0KLTxicj4NCi3C oCDCoCDCoCDCoC8qIHVubGltaXQgbG9ja2VkIG1lbW9yeSAqLzxicj4NCi3CoCDCoCDCoCDCoHN0 cnVjdCBybGltaXQgbWVtbG9ja19saW1pdCA9IHs8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAucmxpbV9jdXIgPSBSTElNX0lORklOSVRZLDxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDC oC5ybGltX21heCA9IFJMSU1fSU5GSU5JVFksPGJyPg0KLcKgIMKgIMKgIMKgfTs8YnI+DQotwqAg wqAgwqAgwqBzZXRybGltaXQoUkxJTUlUX01FTUxPQ0ssICZhbXA7bWVtbG9ja19saW1pdCk7PGJy Pg0KLTxicj4NCi3CoCDCoCDCoCDCoCAvKiBHZXQgYSBuZXcgbWFwIGtleSBmb3IgYSBuZXcgUlNT IHJ1bGUgKi88YnI+DQotwqAgwqAgwqAgwqBlcnIgPSBicGZfcnNzX2tleShLRVlfQ01EX0lOSVQs IE5VTEwpOzxicj4NCi3CoCDCoCDCoCDCoGlmIChlcnIgJmx0OyAwKSB7PGJyPg0KLcKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgcnRlX2Zsb3dfZXJyb3Jfc2V0KDxicj4NCi3CoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoGVycm9yLCBFSU5WQUwsIFJURV9GTE9XX0VSUk9SX1RZUEVfSEFO RExFLCBOVUxMLDxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCZxdW90 O0ZhaWxlZCB0byBpbml0aWFsaXplIEJQRiBSU1Mga2V5cyZxdW90Oyk7PGJyPg0KLTxicj4NCi3C oCDCoCDCoCDCoCDCoCDCoCDCoCDCoHJldHVybiAtMTs8YnI+DQotwqAgwqAgwqAgwqB9PGJyPg0K LTxicj4NCi3CoCDCoCDCoCDCoC8qPGJyPg0KLcKgIMKgIMKgIMKgICrCoCBDcmVhdGUgQlBGIFJT UyBNQVA8YnI+DQotwqAgwqAgwqAgwqAgKi88YnI+DQotwqAgwqAgwqAgwqBwbWQtJmd0O21hcF9m ZCA9IHRhcF9mbG93X2JwZl9yc3NfbWFwX2NyZWF0ZShzaXplb2YoX191MzIpLCAvKiBrZXkgc2l6 ZSAqLzxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oHNpemVvZihzdHJ1Y3QgcnNzX2tleSksPGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgTUFYX1JTU19LRVlTKTs8YnI+DQotwqAgwqAgwqAgwqBpZiAo cG1kLSZndDttYXBfZmQgJmx0OyAwKSB7PGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgVEFQ X0xPRyhFUlIsPGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgJnF1b3Q7 RmFpbGVkIHRvIGNyZWF0ZSBCUEYgbWFwICglZCk6ICVzJnF1b3Q7LDxicj4NCi3CoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGVycm5vLCBzdHJlcnJvcihlcnJu bykpOzxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHJ0ZV9mbG93X2Vycm9yX3NldCg8YnI+ DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBlcnJvciwgRU5PVFNVUCwgUlRF X0ZMT1dfRVJST1JfVFlQRV9IQU5ETEUsIE5VTEwsPGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgJnF1b3Q7S2VybmVsIHRvbyBvbGQgb3Igbm90IGNvbmZpZ3VyZWQgJnF1 b3Q7PGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgJnF1b3Q7dG8gc3Vw cG9ydCBCUEYgbWFwcyZxdW90Oyk7PGJyPg0KLTxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDC oHJldHVybiAtRU5PVFNVUDs8YnI+DQotwqAgwqAgwqAgwqB9PGJyPg0KLTxicj4NCi3CoCDCoCDC oCDCoC8qPGJyPg0KLcKgIMKgIMKgIMKgICogQWRkIGEgcnVsZSBwZXIgcXVldWUgdG8gbWF0Y2gg cmVjbGFzc2lmaWVkIHBhY2tldHMgYW5kIGRpcmVjdCB0aGVtIHRvPGJyPg0KLcKgIMKgIMKgIMKg ICogdGhlIGNvcnJlY3QgcXVldWUuPGJyPg0KLcKgIMKgIMKgIMKgICovPGJyPg0KLcKgIMKgIMKg IMKgZm9yIChpID0gMDsgaSAmbHQ7IHBtZC0mZ3Q7ZGV2LSZndDtkYXRhLSZndDtuYl9yeF9xdWV1 ZXM7IGkrKykgezxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHBtZC0mZ3Q7YnBmX2ZkW2ld ID0gdGFwX2Zsb3dfYnBmX2Nsc19xKGkpOzxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGlm IChwbWQtJmd0O2JwZl9mZFtpXSAmbHQ7IDApIHs8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqBUQVBfTE9HKEVSUiw8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAmcXVvdDtGYWlsZWQgdG8gbG9hZCBCUEYgc2VjdGlvbiAl cyBmb3IgcXVldWUgJWQmcXVvdDssPGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgU0VDX05BTUVfQ0xTX1EsIGkpOzxicj4NCi3CoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoHJ0ZV9mbG93X2Vycm9yX3NldCg8YnI+DQotwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBlcnJvciwgRU5PVFNVUCwgUlRF X0ZMT1dfRVJST1JfVFlQRV9IQU5ETEUsPGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgTlVMTCw8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAmcXVvdDtLZXJuZWwgdG9vIG9sZCBvciBub3QgY29uZmln dXJlZCAmcXVvdDs8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAmcXVvdDt0byBzdXBwb3J0IEJQRiBwcm9ncmFtcyBsb2FkaW5nJnF1b3Q7KTs8YnI+ DQotPGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgcmV0dXJuIC1FTk9U U1VQOzxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoH08YnI+DQotPGJyPg0KLcKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgcnNzX2Zsb3cgPSBydGVfem1hbGxvYyhfX2Z1bmNfXywgc2l6ZW9mKHN0 cnVjdCBydGVfZmxvdyksIDApOzxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGlmICghcnNz X2Zsb3cpIHs8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBUQVBfTE9H KEVSUiw8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAmcXVvdDtDYW5ub3QgYWxsb2NhdGUgbWVtb3J5IGZvciBydGVfZmxvdyZxdW90Oyk7PGJyPg0K LcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgcmV0dXJuIC0xOzxicj4NCi3CoCDC oCDCoCDCoCDCoCDCoCDCoCDCoH08YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBtc2cgPSAm YW1wO3Jzc19mbG93LSZndDttc2c7PGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgdGNfaW5p dF9tc2cobXNnLCBwbWQtJmd0O2lmX2luZGV4LCBSVE1fTkVXVEZJTFRFUiwgTkxNX0ZfUkVRVUVT VCB8PGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgTkxNX0Zf QUNLIHwgTkxNX0ZfRVhDTCB8IE5MTV9GX0NSRUFURSk7PGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgbXNnLSZndDt0LnRjbV9pbmZvID0gVENfSF9NQUtFKDAsIGh0b25zKEVUSF9QX0FMTCkp Ozxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHRhcF9mbG93X3NldF9oYW5kbGUocnNzX2Zs b3cpOzxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHVpbnQxNl90IGdyb3VwID0gYXR0ci0m Z3Q7Z3JvdXAgJmx0OyZsdDsgR1JPVVBfU0hJRlQ7PGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgdWludDE2X3QgcHJpbyA9IGdyb3VwIHwgKGkgKyBQUklPUklUWV9PRkZTRVQpOzxicj4NCi3C oCDCoCDCoCDCoCDCoCDCoCDCoCDCoG1zZy0mZ3Q7dC50Y21faW5mbyA9IFRDX0hfTUFLRShwcmlv ICZsdDsmbHQ7IDE2LCBtc2ctJmd0O3QudGNtX2luZm8pOzxicj4NCi3CoCDCoCDCoCDCoCDCoCDC oCDCoCDCoG1zZy0mZ3Q7dC50Y21fcGFyZW50ID0gVENfSF9NQUtFKE1VTFRJUV9NQUpPUl9IQU5E TEUsIDApOzxicj4NCi08YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB0YXBfbmxhdHRyX2Fk ZCgmYW1wO21zZy0mZ3Q7bmgsIFRDQV9LSU5ELCBzaXplb2YoJnF1b3Q7YnBmJnF1b3Q7KSwgJnF1 b3Q7YnBmJnF1b3Q7KTs8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBpZiAodGFwX25sYXR0 cl9uZXN0ZWRfc3RhcnQobXNnLCBUQ0FfT1BUSU9OUykgJmx0OyAwKTxicj4NCi3CoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHJldHVybiAtMTs8YnI+DQotwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqB0YXBfbmxhdHRyX2FkZDMyKCZhbXA7bXNnLSZndDtuaCwgVENBX0JQRl9GRCwgcG1k LSZndDticGZfZmRbaV0pOzxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHNucHJpbnRmKGFu bm90YXRpb24sIHNpemVvZihhbm5vdGF0aW9uKSwgJnF1b3Q7WyVzJWRdJnF1b3Q7LDxicj4NCi3C oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoFNFQ19OQU1FX0NMU19RLCBpKTs8YnI+ DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB0YXBfbmxhdHRyX2FkZCgmYW1wO21zZy0mZ3Q7bmgs IFRDQV9CUEZfTkFNRSwgc3RybGVuKGFubm90YXRpb24pICsgMSw8YnI+DQotwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgYW5ub3RhdGlvbik7PGJyPg0KLcKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgLyogQWN0aW9ucyAqLzxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHs8 YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBzdHJ1Y3QgYWN0aW9uX2Rh dGEgYWRhdGEgPSB7PGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgLmlkID0gJnF1b3Q7c2tiZWRpdCZxdW90Oyw8YnI+DQotwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAuc2tiZWRpdCA9IHs8YnI+DQotwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAuc2ti ZWRpdCA9IHs8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAuYWN0aW9uID0gVENfQUNUX1BJUEUsPGJyPg0K LcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgfSw8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAucXVldWUgPSBpLDxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoH0sPGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgfTs8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBpZiAo YWRkX2FjdGlvbnMocnNzX2Zsb3csIDEsICZhbXA7YWRhdGEsIFRDQV9CUEZfQUNUKSAmbHQ7IDAp PGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgcmV0 dXJuIC0xOzxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoH08YnI+DQotwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqB0YXBfbmxhdHRyX25lc3RlZF9maW5pc2gobXNnKTsgLyogbmVzdGVkIFRDQV9P UFRJT05TICovPGJyPg0KK8KgIMKgIMKgIMKgaW50IGVycjs8YnI+DQo8YnI+DQotwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAvKiBOZXRsaW5rIG1lc3NhZ2UgaXMgbm93IHJlYWR5IHRvIGJlIHNlbnQg Ki88YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBpZiAodGFwX25sX3NlbmQocG1kLSZndDtu bHNrX2ZkLCAmYW1wO21zZy0mZ3Q7bmgpICZsdDsgMCk8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqByZXR1cm4gLTE7PGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg ZXJyID0gdGFwX25sX3JlY3ZfYWNrKHBtZC0mZ3Q7bmxza19mZCk7PGJyPg0KLcKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgaWYgKGVyciAmbHQ7IDApIHs8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqBUQVBfTE9HKEVSUiw8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAmcXVvdDtLZXJuZWwgcmVmdXNlZCBUQyBmaWx0ZXIgcnVs ZSBjcmVhdGlvbiAoJWQpOiAlcyZxdW90Oyw8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBlcnJubywgc3RyZXJyb3IoZXJybm8pKTs8YnI+DQotwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqByZXR1cm4gZXJyOzxicj4NCi3CoCDCoCDC oCDCoCDCoCDCoCDCoCDCoH08YnI+DQorwqAgwqAgwqAgwqAvKiBMb2FkIHRoZSBCUEYgcHJvZ3Jh bSAoZGVmaW5lZCBpbiB0YXBfYnBmLmggZnJvbSBza2VsZXRvbikgKi88YnI+DQorwqAgwqAgwqAg wqBwbWQtJmd0O3JzcyA9IHRhcF9yc3NfX29wZW5fYW5kX2xvYWQoKTs8YnI+DQorwqAgwqAgwqAg wqBpZiAocG1kLSZndDtyc3MgPT0gTlVMTCkgezxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oFRBUF9MT0coRVJSLCAmcXVvdDtGYWlsZWQgdG8gbG9hZCBCUEYgb2JqZWN0OiAlcyZxdW90Oywg c3RyZXJyb3IoZXJybm8pKTs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBydGVfZmxvd19l cnJvcl9zZXQoZXJyb3IsIGVycm5vLCBSVEVfRkxPV19FUlJPUl9UWVBFX0hBTkRMRSwgTlVMTCw8 YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAmcXVvdDtCUEYgb2JqZWN0 IGNvdWxkIG5vdCBiZSBsb2FkZWQmcXVvdDspOzxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oHJldHVybiAtZXJybm87PGJyPg0KwqAgwqAgwqAgwqAgfTxicj4NCjxicj4NCi3CoCDCoCDCoCDC oHBtZC0mZ3Q7cnNzX2VuYWJsZWQgPSAxOzxicj4NCi3CoCDCoCDCoCDCoHJldHVybiBlcnI7PGJy Pg0KLX08YnI+DQotPGJyPg0KLS8qKjxicj4NCi0gKiBNYW5hZ2UgYnBmIFJTUyBrZXlzIHJlcG9z aXRvcnkgd2l0aCBvcGVyYXRpb25zOiBpbml0LCBnZXQsIHJlbGVhc2U8YnI+DQotICo8YnI+DQot ICogQHBhcmFtW2luXSBjbWQ8YnI+DQotICrCoCDCoENvbW1hbmQgb24gUlNTIGtleXM6IGluaXQs IGdldCwgcmVsZWFzZTxicj4NCi0gKjxicj4NCi0gKiBAcGFyYW1baW4sIG91dF0ga2V5X2lkeDxi cj4NCi0gKsKgIMKgUG9pbnRlciB0byBSU1MgS2V5IGluZGV4IChvdXQgZm9yIGdldCBjb21tYW5k LCBpbiBmb3IgcmVsZWFzZSBjb21tYW5kKTxicj4NCi0gKjxicj4NCi0gKiBAcmV0dXJuIC0xIGlm IGNvdWxkbiYjMzk7dCBnZXQsIHJlbGVhc2Ugb3IgaW5pdCB0aGUgUlNTIGtleXMsIDAgb3RoZXJ3 aXNlLjxicj4NCi0gKi88YnI+DQotc3RhdGljIGludCBicGZfcnNzX2tleShlbnVtIGJwZl9yc3Nf a2V5X2UgY21kLCBfX3UzMiAqa2V5X2lkeCk8YnI+DQotezxicj4NCi3CoCDCoCDCoCDCoF9fdTMy IGk7PGJyPg0KLcKgIMKgIMKgIMKgaW50IGVyciA9IDA7PGJyPg0KLcKgIMKgIMKgIMKgc3RhdGlj IF9fdTMyIG51bV91c2VkX2tleXM7PGJyPg0KLcKgIMKgIMKgIMKgc3RhdGljIF9fdTMyIHJzc19r ZXlzW01BWF9SU1NfS0VZU10gPSB7S0VZX1NUQVRfVU5TUEVDfTs8YnI+DQotwqAgwqAgwqAgwqBz dGF0aWMgX191MzIgcnNzX2tleXNfaW5pdGlhbGl6ZWQ7PGJyPg0KLcKgIMKgIMKgIMKgX191MzIg a2V5Ozxicj4NCi08YnI+DQotwqAgwqAgwqAgwqBzd2l0Y2ggKGNtZCkgezxicj4NCi3CoCDCoCDC oCDCoGNhc2UgS0VZX0NNRF9HRVQ6PGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgaWYgKCFy c3Nfa2V5c19pbml0aWFsaXplZCkgezxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoGVyciA9IC0xOzxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oGJyZWFrOzxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoH08YnI+DQotPGJyPg0KLcKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgaWYgKG51bV91c2VkX2tleXMgPT0gUlRFX0RJTShyc3Nfa2V5cykp IHs8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBlcnIgPSAtMTs8YnI+ DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBicmVhazs8YnI+DQotwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqB9PGJyPg0KLTxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCpr ZXlfaWR4ID0gbnVtX3VzZWRfa2V5cyAlIFJURV9ESU0ocnNzX2tleXMpOzxicj4NCi3CoCDCoCDC oCDCoCDCoCDCoCDCoCDCoHdoaWxlIChyc3Nfa2V5c1sqa2V5X2lkeF0gPT0gS0VZX1NUQVRfVVNF RCk8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAqa2V5X2lkeCA9ICgq a2V5X2lkeCArIDEpICUgUlRFX0RJTShyc3Nfa2V5cyk7PGJyPg0KLTxicj4NCi3CoCDCoCDCoCDC oCDCoCDCoCDCoCDCoHJzc19rZXlzWyprZXlfaWR4XSA9IEtFWV9TVEFUX1VTRUQ7PGJyPg0KLTxi cj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoC8qPGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgICogQWRkIGFuIG9mZnNldCB0byBrZXlfaWR4IGluIG9yZGVyIHRvIGhhbmRsZSBhIGNhc2Ug b2Y8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgKiBSU1MgYW5kIG5vbiBSU1MgZmxvd3Mg bWl4dHVyZS48YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgKiBJZiBhIG5vbiBSU1MgZmxv dyBpcyBkZXN0cm95ZWQgaXQgaGFzIGFuIGVCUEYgbWFwPGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgICogaW5kZXggMCAoaW5pdGlhbGl6ZWQgb24gZmxvdyBjcmVhdGlvbikgYW5kIG1pZ2h0 PGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgICogdW5pbnRlbnRpb25hbGx5IHJlbW92ZSBS U1MgZW50cnkgMCBmcm9tIGVCUEYgbWFwLjxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAq IFRvIGF2b2lkIHRoaXMgaXNzdWUsIGFkZCBhbiBvZmZzZXQgdG8gdGhlIHJlYWwgaW5kZXg8YnI+ DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgKiBkdXJpbmcgYSBLRVlfQ01EX0dFVCBvcGVyYXRp b24gYW5kIHN1YnRyYWN0IHRoaXMgb2Zmc2V0PGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg ICogZHVyaW5nIGEgS0VZX0NNRF9SRUxFQVNFIG9wZXJhdGlvbiBpbiBvcmRlciB0byByZXN0b3Jl PGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgICogdGhlIHJlYWwgaW5kZXguPGJyPg0KLcKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgICovPGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgKmtl eV9pZHggKz0gS0VZX0lEWF9PRkZTRVQ7PGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgbnVt X3VzZWRfa2V5cysrOzxicj4NCi3CoCDCoCDCoCDCoGJyZWFrOzxicj4NCi08YnI+DQotwqAgwqAg wqAgwqBjYXNlIEtFWV9DTURfUkVMRUFTRTo8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBp ZiAoIXJzc19rZXlzX2luaXRpYWxpemVkKTxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoGJyZWFrOzxicj4NCi08YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAvKjxi cj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAqIFN1YnRyYWN0IG9mZnNldCB0byByZXN0b3Jl IHJlYWwga2V5IGluZGV4PGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgICogSWYgYSBub24g UlNTIGZsb3cgaXMgZmFsc2VseSB0cnlpbmcgdG8gcmVsZWFzZSBtYXA8YnI+DQotwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgKiBlbnRyeSAwIC0gdGhlIG9mZnNldCBzdWJ0cmFjdGlvbiB3aWxsIGNh bGN1bGF0ZSB0aGUgcmVhbDxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAqIG1hcCBpbmRl eCBhcyBhbiBvdXQtb2YtcmFuZ2UgdmFsdWUgYW5kIHRoZSByZWxlYXNlIG9wZXJhdGlvbjxicj4N Ci3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAqIHdpbGwgYmUgc2lsZW50bHkgaWdub3JlZC48YnI+ DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgKi88YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqBrZXkgPSAqa2V5X2lkeCAtIEtFWV9JRFhfT0ZGU0VUOzxicj4NCi3CoCDCoCDCoCDCoCDCoCDC oCDCoCDCoGlmIChrZXkgJmd0Oz0gUlRFX0RJTShyc3Nfa2V5cykpPGJyPg0KLcKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgYnJlYWs7PGJyPg0KLTxicj4NCi3CoCDCoCDCoCDCoCDC oCDCoCDCoCDCoGlmIChyc3Nfa2V5c1trZXldID09IEtFWV9TVEFUX1VTRUQpIHs8YnI+DQotwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqByc3Nfa2V5c1trZXldID0gS0VZX1NUQVRf QVZBSUxBQkxFOzxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoG51bV91 c2VkX2tleXMtLTs8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB9PGJyPg0KLcKgIMKgIMKg IMKgYnJlYWs7PGJyPg0KLTxicj4NCi3CoCDCoCDCoCDCoGNhc2UgS0VZX0NNRF9JTklUOjxicj4N Ci3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGZvciAoaSA9IDA7IGkgJmx0OyBSVEVfRElNKHJzc19r ZXlzKTsgaSsrKTxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHJzc19r ZXlzW2ldID0gS0VZX1NUQVRfQVZBSUxBQkxFOzxicj4NCi08YnI+DQotwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqByc3Nfa2V5c19pbml0aWFsaXplZCA9IDE7PGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgbnVtX3VzZWRfa2V5cyA9IDA7PGJyPg0KLcKgIMKgIMKgIMKgYnJlYWs7PGJyPg0KLTxi cj4NCi3CoCDCoCDCoCDCoGNhc2UgS0VZX0NNRF9ERUlOSVQ6PGJyPg0KLcKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgZm9yIChpID0gMDsgaSAmbHQ7IFJURV9ESU0ocnNzX2tleXMpOyBpKyspPGJyPg0K LcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgcnNzX2tleXNbaV0gPSBLRVlfU1RB VF9VTlNQRUM7PGJyPg0KLTxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHJzc19rZXlzX2lu aXRpYWxpemVkID0gMDs8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBudW1fdXNlZF9rZXlz ID0gMDs8YnI+DQotwqAgwqAgwqAgwqBicmVhazs8YnI+DQotPGJyPg0KLcKgIMKgIMKgIMKgZGVm YXVsdDo8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBicmVhazs8YnI+DQorwqAgwqAgwqAg wqAvKiBBdHRhY2ggdGhlIG1hcHMgZGVmaW5lZCBpbiBCUEYgcHJvZ3JhbSAqLzxicj4NCivCoCDC oCDCoCDCoGVyciA9IHRhcF9yc3NfX2F0dGFjaChwbWQtJmd0O3Jzcyk7PGJyPg0KK8KgIMKgIMKg IMKgaWYgKGVyciAmbHQ7IDApIHs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBUQVBfTE9H KEVSUiwgJnF1b3Q7RmFpbGVkIHRvIGF0dGFjaCBCUEYgb2JqZWN0OiAlZCZxdW90OywgZXJyKTs8 YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBydGVfZmxvd19lcnJvcl9zZXQoZXJyb3IsIC1l cnIsIFJURV9GTE9XX0VSUk9SX1RZUEVfSEFORExFLCBOVUxMLDxicj4NCivCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCZxdW90O0JQRiBvYmplY3QgY291bGQgbm90IGJlIGF0dGFj aGVkJnF1b3Q7KTs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB0YXBfZmxvd19icGZfZGVz dHJveShwbWQpOzxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHJldHVybiBlcnI7PGJyPg0K wqAgwqAgwqAgwqAgfTxicj4NCjxicj4NCi3CoCDCoCDCoCDCoHJldHVybiBlcnI7PGJyPg0KK8Kg IMKgIMKgIMKgcmV0dXJuIDA7PGJyPg0KwqB9PGJyPg0KPGJyPg0KLTxicj4NCsKgLyogRGVmYXVs dCBSU1MgaGFzaCBrZXkgYWxzbyB1c2VkIGJ5IG1seCBkZXZpY2VzICovPGJyPg0KwqBzdGF0aWMg Y29uc3QgdWludDhfdCByc3NfaGFzaF9kZWZhdWx0X2tleVtdID0gezxicj4NCsKgIMKgIMKgIMKg IDB4MmMsIDB4YzYsIDB4ODEsIDB4ZDEsPGJyPg0KQEAgLTIwMDYsOSArMTgxMSwxMSBAQCBzdGF0 aWMgaW50IHJzc19hZGRfYWN0aW9ucyhzdHJ1Y3QgcnRlX2Zsb3cgKmZsb3csIHN0cnVjdCBwbWRf aW50ZXJuYWxzICpwbWQsPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqBjb25zdCBzdHJ1Y3QgcnRlX2Zsb3dfYWN0aW9uX3JzcyAqcnNzLDxicj4NCsKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgc3RydWN0IHJ0ZV9mbG93X2Vycm9yICpl cnJvcik8YnI+DQrCoHs8YnI+DQorwqAgwqAgwqAgwqBjb25zdCBzdHJ1Y3QgYnBmX3Byb2dyYW0g KnJzc19wcm9nID0gcG1kLSZndDtyc3MtJmd0O3Byb2dzLnJzc19mbG93X2FjdGlvbjs8YnI+DQrC oCDCoCDCoCDCoCBzdHJ1Y3QgcnNzX2tleSByc3NfZW50cnkgPSB7IH07PGJyPg0KwqAgwqAgwqAg wqAgY29uc3QgdWludDhfdCAqa2V5X2luOzxicj4NCsKgIMKgIMKgIMKgIHVpbnQzMl90IGhhc2hf dHlwZSA9IDA7PGJyPg0KK8KgIMKgIMKgIMKgdWludDMyX3QgaGFuZGxlID0gZmxvdy0mZ3Q7bXNn LnQudGNtX2hhbmRsZTs8YnI+DQrCoCDCoCDCoCDCoCB1bnNpZ25lZCBpbnQgaTs8YnI+DQrCoCDC oCDCoCDCoCBpbnQgZXJyOzxicj4NCjxicj4NCkBAIC0yMDY3LDM0ICsxODc0LDI0IEBAIHN0YXRp YyBpbnQgcnNzX2FkZF9hY3Rpb25zKHN0cnVjdCBydGVfZmxvdyAqZmxvdywgc3RydWN0IHBtZF9p bnRlcm5hbHMgKnBtZCw8YnI+DQrCoCDCoCDCoCDCoCBlbHNlIGlmIChyc3MtJmd0O3R5cGVzICZh bXA7IChSVEVfRVRIX1JTU19JUFY2IHwgUlRFX0VUSF9SU1NfRlJBR19JUFY2IHwgUlRFX0VUSF9S U1NfSVBWNl9FWCkpPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgaGFzaF90eXBlIHw9IFJU RV9CSVQzMihIQVNIX0ZJRUxEX0lQVjZfTDMpOzxicj4NCjxicj4NCi3CoCDCoCDCoCDCoC8qIEdl dCBhIG5ldyBtYXAga2V5IGZvciBhIG5ldyBSU1MgcnVsZSAqLzxicj4NCi3CoCDCoCDCoCDCoGVy ciA9IGJwZl9yc3Nfa2V5KEtFWV9DTURfR0VULCAmYW1wO2Zsb3ctJmd0O2tleV9pZHgpOzxicj4N Ci3CoCDCoCDCoCDCoGlmIChlcnIgJmx0OyAwKSB7PGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgcnRlX2Zsb3dfZXJyb3Jfc2V0KDxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoGVycm9yLCBFSU5WQUwsIFJURV9GTE9XX0VSUk9SX1RZUEVfSEFORExFLCBOVUxMLDxi cj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCZxdW90O0ZhaWxlZCB0byBn ZXQgQlBGIFJTUyBrZXkmcXVvdDspOzxicj4NCi08YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqByZXR1cm4gLTE7PGJyPg0KLcKgIMKgIMKgIMKgfTxicj4NCivCoCDCoCDCoCDCoHJzc19lbnRy eS5oYXNoX2ZpZWxkcyA9IGhhc2hfdHlwZTs8YnI+DQorwqAgwqAgwqAgwqBydGVfY29udmVydF9y c3Nfa2V5KChjb25zdCB1aW50MzJfdCAqKWtleV9pbiwgKHVpbnQzMl90ICopcnNzX2VudHJ5Lmtl eSw8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBUQVBfUlNT X0hBU0hfS0VZX1NJWkUpOzxicj4NCjxicj4NCsKgIMKgIMKgIMKgIC8qIFVwZGF0ZSBSU1MgbWFw IGVudHJ5IHdpdGggcXVldWVzICovPGJyPg0KwqAgwqAgwqAgwqAgcnNzX2VudHJ5Lm5iX3F1ZXVl cyA9IHJzcy0mZ3Q7cXVldWVfbnVtOzxicj4NCsKgIMKgIMKgIMKgIGZvciAoaSA9IDA7IGkgJmx0 OyByc3MtJmd0O3F1ZXVlX251bTsgaSsrKTxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHJz c19lbnRyeS5xdWV1ZXNbaV0gPSByc3MtJmd0O3F1ZXVlW2ldOzxicj4NCjxicj4NCi3CoCDCoCDC oCDCoHJzc19lbnRyeS5oYXNoX2ZpZWxkcyA9IGhhc2hfdHlwZTs8YnI+DQotwqAgwqAgwqAgwqBy dGVfY29udmVydF9yc3Nfa2V5KChjb25zdCB1aW50MzJfdCAqKWtleV9pbiwgKHVpbnQzMl90ICop cnNzX2VudHJ5LmtleSw8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqBUQVBfUlNTX0hBU0hfS0VZX1NJWkUpOzxicj4NCi08YnI+DQotPGJyPg0KLcKgIMKgIMKg IMKgLyogQWRkIHRoaXMgUlNTIGVudHJ5IHRvIG1hcCAqLzxicj4NCi3CoCDCoCDCoCDCoGVyciA9 IHRhcF9mbG93X2JwZl91cGRhdGVfcnNzX2VsZW0ocG1kLSZndDttYXBfZmQsPGJyPg0KLcKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgJmFtcDtmbG93LSZndDtr ZXlfaWR4LCAmYW1wO3Jzc19lbnRyeSk7PGJyPg0KPGJyPg0KK8KgIMKgIMKgIMKgLyogQWRkIHRo aXMgd2F5IGZvciBCUEYgdG8gZmluZMKgIGVudHJ5IGluIG1hcCAqLzxicj4NCivCoCDCoCDCoCDC oGVyciA9IGJwZl9tYXBfX3VwZGF0ZV9lbGVtKHBtZC0mZ3Q7cnNzLSZndDttYXBzLnJzc19tYXAs PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg ICZhbXA7aGFuZGxlLCBzaXplb2YoaGFuZGxlKSw8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgJmFtcDtyc3NfZW50cnksIHNpemVvZihyc3Nf ZW50cnkpLCAwKTs8YnI+DQrCoCDCoCDCoCDCoCBpZiAoZXJyKSB7PGJyPg0KwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgVEFQX0xPRyhFUlIsPGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgJnF1b3Q7RmFpbGVkIHRvIHVwZGF0ZSBCUEYgbWFwIGVudHJ5ICMldSAoJWQpOiAl cyZxdW90Oyw8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBmbG93LSZn dDtrZXlfaWR4LCBlcnJubywgc3RyZXJyb3IoZXJybm8pKTs8YnI+DQorwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAmcXVvdDtGYWlsZWQgdG8gdXBkYXRlIEJQRiBtYXAgZW50cnkg JSN4ICglZCk6ICVzJnF1b3Q7LDxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoGhhbmRsZSzCoCBlcnJubywgc3RyZXJyb3IoZXJybm8pKTs8YnI+DQrCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCBydGVfZmxvd19lcnJvcl9zZXQoPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgZXJyb3IsIEVOT1RTVVAsIFJURV9GTE9XX0VSUk9SX1RZUEVfSEFORExF LCBOVUxMLDxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgICZxdW90O0tl cm5lbCB0b28gb2xkIG9yIG5vdCBjb25maWd1cmVkICZxdW90Ozxicj4NCkBAIC0yMTAzLDQ3ICsx OTAwLDI4IEBAIHN0YXRpYyBpbnQgcnNzX2FkZF9hY3Rpb25zKHN0cnVjdCBydGVfZmxvdyAqZmxv dywgc3RydWN0IHBtZF9pbnRlcm5hbHMgKnBtZCw8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCByZXR1cm4gLUVOT1RTVVA7PGJyPg0KwqAgwqAgwqAgwqAgfTxicj4NCjxicj4NCi08YnI+DQot wqAgwqAgwqAgwqAvKjxicj4NCi3CoCDCoCDCoCDCoCAqIExvYWQgYnBmIHJ1bGVzIHRvIGNhbGN1 bGF0ZSBoYXNoIGZvciB0aGlzIGtleV9pZHg8YnI+DQotwqAgwqAgwqAgwqAgKi88YnI+DQotPGJy Pg0KLcKgIMKgIMKgIMKgZmxvdy0mZ3Q7YnBmX2ZkW1NFQ19MM19MNF0gPTxicj4NCi3CoCDCoCDC oCDCoCDCoCDCoCDCoCDCoHRhcF9mbG93X2JwZl9jYWxjX2wzX2w0X2hhc2goZmxvdy0mZ3Q7a2V5 X2lkeCwgcG1kLSZndDttYXBfZmQpOzxicj4NCi3CoCDCoCDCoCDCoGlmIChmbG93LSZndDticGZf ZmRbU0VDX0wzX0w0XSAmbHQ7IDApIHs8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBUQVBf TE9HKEVSUiw8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAmcXVvdDtG YWlsZWQgdG8gbG9hZCBCUEYgc2VjdGlvbiAlcyAoJWQpOiAlcyZxdW90Oyw8YnI+DQotwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBzZWNfbmFtZVtTRUNfTDNf TDRdLCBlcnJubywgc3RyZXJyb3IoZXJybm8pKTs8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqBydGVfZmxvd19lcnJvcl9zZXQoPGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgZXJyb3IsIEVOT1RTVVAsIFJURV9GTE9XX0VSUk9SX1RZUEVfSEFORExFLCBOVUxMLDxi cj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCZxdW90O0tlcm5lbCB0b28g b2xkIG9yIG5vdCBjb25maWd1cmVkICZxdW90Ozxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCZxdW90O3RvIHN1cHBvcnQgQlBGIHByb2dyYW0gbG9hZGluZyZxdW90Oyk7 PGJyPg0KLTxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHJldHVybiAtRU5PVFNVUDs8YnI+ DQotwqAgwqAgwqAgwqB9PGJyPg0KLTxicj4NCi3CoCDCoCDCoCDCoC8qIEFjdGlvbnMgKi88YnI+ DQotwqAgwqAgwqAgwqB7PGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgc3RydWN0IGFjdGlv bl9kYXRhIGFkYXRhW10gPSB7PGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgezxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oC5pZCA9ICZxdW90O2JwZiZxdW90Oyw8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAuYnBmID0gezxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoC5icGZfZmQgPSBmbG93LSZndDti cGZfZmRbU0VDX0wzX0w0XSw8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAuYW5ub3RhdGlvbiA9IHNlY19uYW1lW1NFQ19MM19M NF0sPGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgLmJwZiA9IHs8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAuYWN0aW9uID0gVENfQUNU X1BJUEUsPGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgfSw8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqB9LDxicj4NCivCoCDCoCDCoCDCoC8qIEFkZCBhY3Rpb25zIHRvIG1hcmsg cGFja2V0IHRoZW4gcnVuIHRoZSBSU1MgQlBGIHByb2dyYW0gKi88YnI+DQorwqAgwqAgwqAgwqBz dHJ1Y3QgYWN0aW9uX2RhdGEgYWRhdGFbXSA9IHs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqB7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgLmlkID0gJnF1b3Q7 c2tiZWRpdCZxdW90Oyw8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAu c2tiZWRpdCA9IHs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAuc2tiZWRpdC5hY3Rpb24gPSBUQ19BQ1RfUElQRSw8YnI+DQorwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAubWFyayA9IGhhbmRsZSw8YnI+DQrC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCB9LDxicj4NCi3CoCDCoCDCoCDCoCDC oCDCoCDCoCDCoH07PGJyPg0KLTxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGlmIChhZGRf YWN0aW9ucyhmbG93LCBSVEVfRElNKGFkYXRhKSwgYWRhdGEsPGJyPg0KLcKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgVENBX0ZMT1dFUl9BQ1QpICZsdDsgMCk8YnI+DQotwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqByZXR1cm4gLTE7PGJyPg0KLcKgIMKgIMKgIMKg fTxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoH0sPGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKg IMKgIMKgezxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoC5pZCA9ICZx dW90O2JwZiZxdW90Oyw8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAu YnBmID0gezxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoC5icGYuYWN0aW9uID0gVENfQUNUX1BJUEUsPGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgLmFubm90YXRpb24gPSAmcXVvdDt0YXBfcnNzJnF1 b3Q7LDxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oC5icGZfZmQgPSBicGZfcHJvZ3JhbV9fZmQocnNzX3Byb2cpLDxicj4NCivCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoH0sPGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgfSw8 YnI+DQorwqAgwqAgwqAgwqB9Ozxicj4NCjxicj4NCi3CoCDCoCDCoCDCoHJldHVybiAwOzxicj4N CivCoCDCoCDCoCDCoHJldHVybiBhZGRfYWN0aW9ucyhmbG93LCBSVEVfRElNKGFkYXRhKSwgYWRh dGEsIFRDQV9GTE9XRVJfQUNUKTs8YnI+DQrCoH08YnI+DQorI2VuZGlmPGJyPg0KPGJyPg0KwqAv Kio8YnI+DQrCoCAqIEdldCBydGVfZmxvdyBvcGVyYXRpb25zLjxicj4NCmRpZmYgLS1naXQgYS9k cml2ZXJzL25ldC90YXAvdGFwX2Zsb3cuaCBiL2RyaXZlcnMvbmV0L3RhcC90YXBfZmxvdy5oPGJy Pg0KaW5kZXggMjQwZmJjM2RmYS4uOGIxOTM0N2E5MyAxMDA2NDQ8YnI+DQotLS0gYS9kcml2ZXJz L25ldC90YXAvdGFwX2Zsb3cuaDxicj4NCisrKyBiL2RyaXZlcnMvbmV0L3RhcC90YXBfZmxvdy5o PGJyPg0KQEAgLTksNyArOSwxMSBAQDxicj4NCsKgI2luY2x1ZGUgJmx0O3J0ZV9mbG93LmgmZ3Q7 PGJyPg0KwqAjaW5jbHVkZSAmbHQ7cnRlX2Zsb3dfZHJpdmVyLmgmZ3Q7PGJyPg0KwqAjaW5jbHVk ZSAmbHQ7cnRlX2V0aF90YXAuaCZndDs8YnI+DQotI2luY2x1ZGUgJmx0O3RhcF9hdXRvY29uZi5o Jmd0Ozxicj4NCis8YnI+DQorLyoqPGJyPg0KKyAqIE1hc2sgb2YgdW5zdXBwb3J0ZWQgUlNTIHR5 cGVzPGJyPg0KKyAqLzxicj4NCisjZGVmaW5lIFRBUF9SU1NfSEZfTUFTSyAofihSVEVfRVRIX1JT U19JUCB8IFJURV9FVEhfUlNTX1VEUCB8IFJURV9FVEhfUlNTX1RDUCkpPGJyPg0KPGJyPg0KwqAv Kio8YnI+DQrCoCAqIEluIFRDLCBwcmlvcml0eSAwIG1lYW5zIHdlIHJlcXVpcmUgdGhlIGtlcm5l bCB0byBhbGxvY2F0ZSBvbmUgZm9yIHVzLjxicj4NCkBAIC00MSwxMSArNDUsNiBAQCBlbnVtIGlt cGxpY2l0X3J1bGVfaW5kZXggezxicj4NCsKgIMKgIMKgIMKgIFRBUF9SRU1PVEVfTUFYX0lEWCw8 YnI+DQrCoH07PGJyPg0KPGJyPg0KLWVudW0gYnBmX2ZkX2lkeCB7PGJyPg0KLcKgIMKgIMKgIMKg U0VDX0wzX0w0LDxicj4NCi3CoCDCoCDCoCDCoFNFQ19NQVgsPGJyPg0KLX07PGJyPg0KLTxicj4N CsKgaW50IHRhcF9kZXZfZmxvd19vcHNfZ2V0KHN0cnVjdCBydGVfZXRoX2RldiAqZGV2LDxicj4N CsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgY29uc3Qgc3RydWN0IHJ0ZV9m bG93X29wcyAqKm9wcyk7PGJyPg0KwqBpbnQgdGFwX2Zsb3dfZmx1c2goc3RydWN0IHJ0ZV9ldGhf ZGV2ICpkZXYsIHN0cnVjdCBydGVfZmxvd19lcnJvciAqZXJyb3IpOzxicj4NCkBAIC01NywxMCAr NTYsNiBAQCBpbnQgdGFwX2Zsb3dfaW1wbGljaXRfZGVzdHJveShzdHJ1Y3QgcG1kX2ludGVybmFs cyAqcG1kLDxicj4NCsKgaW50IHRhcF9mbG93X2ltcGxpY2l0X2ZsdXNoKHN0cnVjdCBwbWRfaW50 ZXJuYWxzICpwbWQsPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgc3RydWN0IHJ0ZV9mbG93X2Vycm9yICplcnJvcik7PGJyPg0KPGJyPg0KLWludCB0YXBfZmxv d19icGZfY2xzX3EoX191MzIgcXVldWVfaWR4KTs8YnI+DQotaW50IHRhcF9mbG93X2JwZl9jYWxj X2wzX2w0X2hhc2goX191MzIga2V5X2lkeCwgaW50IG1hcF9mZCk7PGJyPg0KLWludCB0YXBfZmxv d19icGZfcnNzX21hcF9jcmVhdGUodW5zaWduZWQgaW50IGtleV9zaXplLCB1bnNpZ25lZCBpbnQg dmFsdWVfc2l6ZSw8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB1bnNp Z25lZCBpbnQgbWF4X2VudHJpZXMpOzxicj4NCi1pbnQgdGFwX2Zsb3dfYnBmX3VwZGF0ZV9yc3Nf ZWxlbShpbnQgZmQsIHZvaWQgKmtleSwgdm9pZCAqdmFsdWUpOzxicj4NCit2b2lkIHRhcF9mbG93 X2JwZl9kZXN0cm95KHN0cnVjdCBwbWRfaW50ZXJuYWxzICpwbWQpOzxicj4NCjxicj4NCsKgI2Vu ZGlmIC8qIF9UQVBfRkxPV19IXyAqLzxicj4NCmRpZmYgLS1naXQgYS9kcml2ZXJzL25ldC90YXAv dGFwX3Jzcy5oIGIvZHJpdmVycy9uZXQvdGFwL3RhcF9yc3MuaDxicj4NCmluZGV4IDYwMDliZTcw MzEuLjY1YmQ4OTkxYjEgMTAwNjQ0PGJyPg0KLS0tIGEvZHJpdmVycy9uZXQvdGFwL3RhcF9yc3Mu aDxicj4NCisrKyBiL2RyaXZlcnMvbmV0L3RhcC90YXBfcnNzLmg8YnI+DQpAQCAtNSwxNiArNSwx NCBAQDxicj4NCsKgI2lmbmRlZiBfVEFQX1JTU19IXzxicj4NCsKgI2RlZmluZSBfVEFQX1JTU19I Xzxicj4NCjxicj4NCi0jaWZuZGVmIFRBUF9NQVhfUVVFVUVTPGJyPg0KLSNkZWZpbmUgVEFQX01B WF9RVUVVRVMgMTY8YnI+DQorLyogU2l6ZSBvZiB0aGUgbWFwIGZyb20gQlBGIGNsYXNzaWQgdG8g cXVldWUgdGFibGUgKi88YnI+DQorI2lmbmRlZiBUQVBfUlNTX01BWDxicj4NCisjZGVmaW5lIFRB UF9SU1NfTUFYwqAgwqAgMzI8YnI+DQrCoCNlbmRpZjxicj4NCjxicj4NCi0vKiBGaXhlZCBSU1Mg aGFzaCBrZXkgc2l6ZSBpbiBieXRlcy4gKi88YnI+DQorLyogU3RhbmRhcmQgVG9lcGxpdHogaGFz aCBrZXkgc2l6ZSAqLzxicj4NCsKgI2RlZmluZSBUQVBfUlNTX0hBU0hfS0VZX1NJWkUgNDA8YnI+ DQo8YnI+DQotLyogU3VwcG9ydGVkIFJTUyAqLzxicj4NCi0jZGVmaW5lIFRBUF9SU1NfSEZfTUFT SyAofihSVEVfRVRIX1JTU19JUCB8IFJURV9FVEhfUlNTX1VEUCB8IFJURV9FVEhfUlNTX1RDUCkp PGJyPg0KLTxicj4NCsKgLyogaGFzaGVkIGZpZWxkcyBmb3IgUlNTICovPGJyPg0KwqBlbnVtIGhh c2hfZmllbGQgezxicj4NCsKgIMKgIMKgIMKgIEhBU0hfRklFTERfSVBWNF9MMyzCoCDCoCDCoC8q IElQdjQgc3JjL2RzdCBhZGRyICovPGJyPg0KZGlmZiAtLWdpdCBhL2RyaXZlcnMvbmV0L3RhcC90 YXBfdGNtc2dzLmggYi9kcml2ZXJzL25ldC90YXAvdGFwX3RjbXNncy5oPGJyPg0KaW5kZXggYTY0 Y2IyOWQ2Zi4uOTQxMTYyNjY2MSAxMDA2NDQ8YnI+DQotLS0gYS9kcml2ZXJzL25ldC90YXAvdGFw X3RjbXNncy5oPGJyPg0KKysrIGIvZHJpdmVycy9uZXQvdGFwL3RhcF90Y21zZ3MuaDxicj4NCkBA IC02LDcgKzYsNiBAQDxicj4NCsKgI2lmbmRlZiBfVEFQX1RDTVNHU19IXzxicj4NCsKgI2RlZmlu ZSBfVEFQX1RDTVNHU19IXzxicj4NCjxicj4NCi0jaW5jbHVkZSAmbHQ7dGFwX2F1dG9jb25mLmgm Z3Q7PGJyPg0KwqAjaW5jbHVkZSAmbHQ7bGludXgvaWZfZXRoZXIuaCZndDs8YnI+DQrCoCNpbmNs dWRlICZsdDtsaW51eC9ydG5ldGxpbmsuaCZndDs8YnI+DQrCoCNpbmNsdWRlICZsdDtsaW51eC9w a3Rfc2NoZWQuaCZndDs8YnI+DQpAQCAtMTQsOSArMTMsMTAgQEA8YnI+DQrCoCNpbmNsdWRlICZs dDtsaW51eC90Y19hY3QvdGNfbWlycmVkLmgmZ3Q7PGJyPg0KwqAjaW5jbHVkZSAmbHQ7bGludXgv dGNfYWN0L3RjX2dhY3QuaCZndDs8YnI+DQrCoCNpbmNsdWRlICZsdDtsaW51eC90Y19hY3QvdGNf c2tiZWRpdC5oJmd0Ozxicj4NCi0jaWZkZWYgSEFWRV9UQ19BQ1RfQlBGPGJyPg0KKyNpZmRlZiBI QVZFX0JQRl9SU1M8YnI+DQrCoCNpbmNsdWRlICZsdDtsaW51eC90Y19hY3QvdGNfYnBmLmgmZ3Q7 PGJyPg0KwqAjZW5kaWY8YnI+DQorPGJyPg0KwqAjaW5jbHVkZSAmbHQ7aW50dHlwZXMuaCZndDs8 YnI+DQo8YnI+DQrCoCNpbmNsdWRlICZsdDtydGVfZXRoZXIuaCZndDs8YnI+DQotLSA8YnI+DQoy LjQzLjA8YnI+DQo8YnI+DQo8L2Jsb2NrcXVvdGU+PC9kaXY+DQo= --0000000000001b42490619863331--