From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C1C40C433EF for ; Tue, 19 Oct 2021 14:26:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9CDAD60F9E for ; Tue, 19 Oct 2021 14:26:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230158AbhJSO2l (ORCPT ); Tue, 19 Oct 2021 10:28:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35838 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230168AbhJSO2g (ORCPT ); Tue, 19 Oct 2021 10:28:36 -0400 Received: from mail-ed1-x52b.google.com (mail-ed1-x52b.google.com [IPv6:2a00:1450:4864:20::52b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8943AC06161C for ; Tue, 19 Oct 2021 07:26:23 -0700 (PDT) Received: by mail-ed1-x52b.google.com with SMTP id ec8so13752174edb.6 for ; Tue, 19 Oct 2021 07:26:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=yW3YZybIiYOrNDmXT66FEbyuKAadk5Hmp6J68GVcIUo=; b=AslPLw8mXmVkiU4T17lnyvvEhOftOeRtCQsVgDuMcz05jL5pT0I72931u1VuZP/EZz mx81RoMKsffNu0/c5hc8zRHOyZH30r2BNnu7ASqhGUAu2FIJIvK4F2dZx6B0opfTBc1o 6YChtJ1aTTP5qfZNtM5y8FEo6iaw4wss0RSLULKNq/QhVVe2kFyW0whWln0O2DqmGpM9 1VpwJOg6dAi6FVapLR62zrJuMzDQy8tqpAoGHCtjTNJbWnP+v4+dlkBBwheciJUf20M2 TMxqP5QeW6uxiLsiXhDFyZ7vMJ6PxV81s/XcK4qr2kFOd3Hdj7GVaoJtVCCmlZxTMU5y Pdsg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=yW3YZybIiYOrNDmXT66FEbyuKAadk5Hmp6J68GVcIUo=; b=vO/EdS/P3QI2aDhx11Qiq1pnX4zC4Oy7ktK9zPiCxsBGxnSXJ/Dv5RE2oaytM7eJxe TFFW9i1SARvwIuKKTpQwvq96X4VaBa2YHdOYTUSxs22vQ+v482B4nM+Zo8d0OL7Z017E DiLXpcB4XO2YAeN6NUZHVCgmmiml88/M5pJ7OKj+bBzJ4uBAPR9d9AGCEphxlOAgRlmo cm4m7a8JLLxyDykqgV2AmZ+wYuxGLO0DaVpmGXNM9pWRJ0FnODc/AKnAhdhp38uqWe+p yTvp6Kr9nKVsxGpGVDY108MPxq1VPdzCopkTe7VkICT4gmSckh2Gfct1wD20jf1PzD0j 5T0w== X-Gm-Message-State: AOAM531q8VlTsBHCm4PbZDH9q1wMMfsrta/TNLL9aZzYsj7uAdq+du+M x0ex9TgajoZgOUF9uqln3v4QX3IOz3xhqQWeXVHNTw== X-Google-Smtp-Source: ABdhPJxD5ZE6d0FXENcrQN//+yLHsxoCEzGuODuz45f4fwZiAlKhAIrTc/+QRZjP5t7AG69gJBQvmp+/ewoMx6nKcU8= X-Received: by 2002:aa7:c2da:: with SMTP id m26mr55448769edp.89.1634653481834; Tue, 19 Oct 2021 07:24:41 -0700 (PDT) MIME-Version: 1.0 References: <20211018114046.25571-1-etienne.carriere@linaro.org> <20211018114046.25571-2-etienne.carriere@linaro.org> <20211018194317.GA6526@e120937-lin> In-Reply-To: From: Etienne Carriere Date: Tue, 19 Oct 2021 16:24:30 +0200 Message-ID: Subject: Re: [PATCH v3 2/2] firmware: arm_scmi: Add optee transport To: Cristian Marussi Cc: linux-kernel@vger.kernel.org, "moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE" , Sudeep Holla , Vincent Guittot Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi, On Tue, 19 Oct 2021 at 11:10, Etienne Carriere wrote: > > Hello Cristian, > > Thanks a lot for the review. > I see I didn't understand and use correctly the config switch for the tra= nsport. > Thanks for all the fixes you sent, i'll integrate them in the patch v4. > > I don't know yet how to address your last comment. See my feedback on > the optee bus dependency issue. > > > > On Mon, 18 Oct 2021 at 21:43, Cristian Marussi = wrote: > > > > On Mon, Oct 18, 2021 at 01:40:46PM +0200, Etienne Carriere wrote: > > > Add a new transport channel to the SCMI firmware interface driver for > > > SCMI message exchange based on optee transport channel. The optee > > > transport is realized by connecting and invoking OP-TEE SCMI service > > > interface PTA. > > > > > > Optee transport support (CONFIG_ARM_SCMI_TRANSPORT_OPTEE) is default > > > enabled when optee driver (CFG_OPTEE) is enabled. Effective optee > > > transport is setup upon OP-TEE SCMI service discovery at optee > > > device initialization. For this SCMI UUID is registered to the optee > > > bus for probing. This is done at device_init initcall level, after > > > optee bus initialization that is done at subsys_init level, as the sc= mi > > > driver initialization. > > > > > > The optee transport can use a statically defined shared memory in > > > which case SCMI device tree node defines it using an "arm,scmi-shmem" > > > compatible phandle through property shmem. Alternatively, optee trans= port > > > allocates the shared memory buffer from the optee driver when no shme= m > > > property is defined. > > > > > > The protocol used to exchange SCMI message over that shared memory is > > > negotiated between optee transport driver and the OP-TEE service thro= ugh > > > capabilities exchange. > > > > > > OP-TEE SCMI service is integrated in OP-TEE since its release tag 3.1= 3.0. > > > The service interface is published in [1]. > > > > > > Link: [1] https://github.com/OP-TEE/optee_os/blob/3.13.0/lib/libutee/= include/pta_scmi_client.h > > > Cc: Cristian Marussi > > > Cc: Sudeep Holla > > > Signed-off-by: Etienne Carriere > > > --- > > > Changes since v2: > > > - Rebase on for-next/scmi, based on Linux v5.15-rc1. > > > - Implement support for dynamic and static shared memory. > > > - Factorize some functions and simplify transport exit sequence. > > > - Rename driver source file from optee_service.c to optee.c. > > > > > > No change since v1 > > > --- > > > > Hi Etienne, > > > > a few remarks below. > > > > > drivers/firmware/arm_scmi/Kconfig | 12 + > > > drivers/firmware/arm_scmi/Makefile | 1 + > > > drivers/firmware/arm_scmi/common.h | 3 + > > > drivers/firmware/arm_scmi/driver.c | 3 + > > > drivers/firmware/arm_scmi/optee.c | 559 +++++++++++++++++++++++++++= ++ > > > 5 files changed, 578 insertions(+) > > > create mode 100644 drivers/firmware/arm_scmi/optee.c > > > > > > diff --git a/drivers/firmware/arm_scmi/Kconfig b/drivers/firmware/arm= _scmi/Kconfig > > > index 3d7081e84853..9107e249023c 100644 > > > --- a/drivers/firmware/arm_scmi/Kconfig > > > +++ b/drivers/firmware/arm_scmi/Kconfig > > > @@ -77,6 +77,18 @@ config ARM_SCMI_TRANSPORT_VIRTIO > > > If you want the ARM SCMI PROTOCOL stack to include support fo= r a > > > transport based on VirtIO, answer Y. > > > > > > +config ARM_SCMI_TRANSPORT_OPTEE > > > + bool "SCMI transport based on OP-TEE service" > > > + depends on OPTEE > > > + select ARM_SCMI_HAVE_TRANSPORT > > > + select ARM_SCMI_HAVE_SHMEM > > > + default y > > > + help > > > + This enables the OP-TEE service based transport for SCMI. > > > + > > > + If you want the ARM SCMI PROTOCOL stack to include support fo= r a > > > + transport based on OP-TEE SCMI service, answer Y. > > > + > > > endif #ARM_SCMI_PROTOCOL > > > > > > > So this 'depends on OPTEE' reminded me of a similar issue on VIRTIO > > transport spotted by a bot (see the fix for Virtio at: c90521a0e94f fir= mware: > > arm_scmi: Fix virtio transport Kconfig dependency), that consiste in a = broken > > build when SCMI was compiled built-in with VIRTIO transport support wit= h > > ARM_SCMI_PROTOCOL=3Dy while the core was CONFIG_VIRTIO=3Dm. > > > > So I tried similarly to set CONFIG_OPTEE=3Dm while keeping ARM_SCMI_PRO= TOCOL=3Dy > > expecting to see a similar issue as in VirtIO (i.e. not being able to a= ccess > > optee module symbols from the builtin SCMI), instead I spotted a differ= ent bug :D > > Sorry, I didn't try this config (optee=3Dm / scmi=3Dy). I though expectin= g > scmi over optee and scmi=3Dy would mandate optee=3Dy. > For the fixup you propose below, i understand how you address the > configuration dependencies. > > > > > AR drivers/base/built-in.a > > /home/crimar01/ARM/dev/src/pdsw/linux/drivers/firmware/arm_scmi/optee.c= : In function =E2=80=98invoke_process_smt_channel=E2=80=99: > > /home/crimar01/ARM/dev/src/pdsw/linux/drivers/firmware/arm_scmi/optee.c= :233:27: error: =E2=80=98scmi_optee_desc=E2=80=99 undeclared (first use in = this function); did you mean =E2=80=98scmi_smc_desc=E2=80=99? > > const size_t msg_size =3D scmi_optee_desc.max_msg_size; > > ^~~~~~~~~~~~~~~ > > scmi_smc_desc > > /home/crimar01/ARM/dev/src/pdsw/linux/drivers/firmware/arm_scmi/optee.c= :233:27: note: each undeclared identifier is reported only once for each fu= nction it appears in > > /home/crimar01/ARM/dev/src/pdsw/linux/drivers/firmware/arm_scmi/optee.c= : In function =E2=80=98setup_dynamic_shmem=E2=80=99: > > /home/crimar01/ARM/dev/src/pdsw/linux/drivers/firmware/arm_scmi/optee.c= :266:26: error: =E2=80=98scmi_optee_desc=E2=80=99 undeclared (first use in = this function); did you mean =E2=80=98scmi_smc_desc=E2=80=99? > > const size_t msg_size =3D scmi_optee_desc.max_msg_size; > > ^~~~~~~~~~~~~~~ > > scmi_smc_desc > > /home/crimar01/ARM/dev/src/pdsw/linux/scripts/Makefile.build:277: recip= e for target 'drivers/firmware/arm_scmi/optee.o' failed > > make[4]: *** [drivers/firmware/arm_scmi/optee.o] Error 1 > > make[4]: *** Waiting for unfinished jobs.... > > > > In fact those scmi_optee_desc are reference to a global only declared > > down below. Fixed with a few defines to carry on: > > > > ---8<------------------ > > > > diff --git a/drivers/firmware/arm_scmi/optee.c b/drivers/firmware/arm_s= cmi/optee.c > > index 64aaba4a8bf2..93a84c91457b 100644 > > --- a/drivers/firmware/arm_scmi/optee.c > > +++ b/drivers/firmware/arm_scmi/optee.c > > @@ -18,6 +18,8 @@ > > > > #define DRIVER_NAME "optee-scmi" > > > > +#define SCMI_OPTEE_MAX_MSG_SIZE 128 > > + > > enum optee_smci_pta_cmd { > > /* > > * PTA_SCMI_CMD_CAPABILITIES - Get channel capabilities > > @@ -230,7 +232,7 @@ static int invoke_process_smt_channel(struct optee_= channel *channel) > > param[0].u.value.a =3D channel->channel_id; > > > > if (channel->tee_shm) { > > - const size_t msg_size =3D scmi_optee_desc.max_msg_size; > > + const size_t msg_size =3D SCMI_OPTEE_MAX_MSG_SIZE; > > > > param[1].attr =3D TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOU= T; > > param[1].u.memref.shm =3D channel->tee_shm; > > @@ -263,7 +265,7 @@ static bool optee_chan_available(struct device *dev= , int idx) > > > > static int setup_dynamic_shmem(struct device *dev, struct optee_channe= l *channel) > > { > > - const size_t msg_size =3D scmi_optee_desc.max_msg_size; > > + const size_t msg_size =3D SCMI_OPTEE_MAX_MSG_SIZE; > > > > channel->tee_shm =3D tee_shm_alloc_kernel_buf(optee_private->te= e_ctx, msg_size); > > if (IS_ERR(channel->tee_shm)) { > > > > ----------------------------- > > > > After the above change it compiled fine, so I went a step further and c= onfigured also > > CONFIG_TEE=3Dm (just trying to reproduce what bot saw on similar VirtIO= eeh.... not that > > I am so evil and sadic :D) > > > > And indeed now (with ARM_SCMI_PROTOCOL=3Dy and CONFIG_TEE=3Dm) I get: > > > > > > GEN modules.builtin > > LD .tmp_vmlinux.kallsyms1 > > /opt/toolchains/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/aarch6= 4-linux-gnu-ld: Unexpected GOT/PLT entries detected! > > /opt/toolchains/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/aarch6= 4-linux-gnu-ld: Unexpected run-time procedure linkages detected! > > /opt/toolchains/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/aarch6= 4-linux-gnu-ld: drivers/firmware/arm_scmi/optee.o: in function `invoke_proc= ess_smt_channel': > > /home/crimar01/ARM/dev/src/pdsw/linux/drivers/firmware/arm_scmi/optee.c= :247: undefined reference to `tee_client_invoke_func' > > /opt/toolchains/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/aarch6= 4-linux-gnu-ld: /home/crimar01/ARM/dev/src/pdsw/linux/drivers/firmware/arm_= scmi/optee.c:247: undefined reference to `tee_client_invoke_func' > > /opt/toolchains/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/aarch6= 4-linux-gnu-ld: drivers/firmware/arm_scmi/optee.o: in function `optee_chan_= free': > > /home/crimar01/ARM/dev/src/pdsw/linux/drivers/firmware/arm_scmi/optee.c= :397: undefined reference to `tee_shm_free' > > /opt/toolchains/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/aarch6= 4-linux-gnu-ld: drivers/firmware/arm_scmi/optee.o: in function `open_sessio= n': > > /home/crimar01/ARM/dev/src/pdsw/linux/drivers/firmware/arm_scmi/optee.c= :137: undefined reference to `tee_client_open_session' > > /opt/toolchains/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/aarch6= 4-linux-gnu-ld: drivers/firmware/arm_scmi/optee.o: in function `optee_servi= ce_remove': > > /home/crimar01/ARM/dev/src/pdsw/linux/drivers/firmware/arm_scmi/optee.c= :516: undefined reference to `tee_client_close_context' > > /opt/toolchains/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/aarch6= 4-linux-gnu-ld: drivers/firmware/arm_scmi/optee.o: in function `optee_servi= ce_probe': > > /home/crimar01/ARM/dev/src/pdsw/linux/drivers/firmware/arm_scmi/optee.c= :481: undefined reference to `tee_client_open_context' > > /opt/toolchains/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/aarch6= 4-linux-gnu-ld: /home/crimar01/ARM/dev/src/pdsw/linux/drivers/firmware/arm_= scmi/optee.c:501: undefined reference to `tee_client_close_context' > > /opt/toolchains/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/aarch6= 4-linux-gnu-ld: drivers/firmware/arm_scmi/optee.o: in function `get_capabil= ities': > > /home/crimar01/ARM/dev/src/pdsw/linux/drivers/firmware/arm_scmi/optee.c= :172: undefined reference to `tee_client_invoke_func' > > /opt/toolchains/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/aarch6= 4-linux-gnu-ld: drivers/firmware/arm_scmi/optee.o: in function `close_sessi= on': > > /home/crimar01/ARM/dev/src/pdsw/linux/drivers/firmware/arm_scmi/optee.c= :151: undefined reference to `tee_client_close_session' > > /opt/toolchains/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/aarch6= 4-linux-gnu-ld: drivers/firmware/arm_scmi/optee.o: in function `get_channel= ': > > /home/crimar01/ARM/dev/src/pdsw/linux/drivers/firmware/arm_scmi/optee.c= :209: undefined reference to `tee_client_invoke_func' > > /opt/toolchains/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/aarch6= 4-linux-gnu-ld: drivers/firmware/arm_scmi/optee.o: in function `setup_dynam= ic_shmem': > > /home/crimar01/ARM/dev/src/pdsw/linux/drivers/firmware/arm_scmi/optee.c= :270: undefined reference to `tee_shm_alloc_kernel_buf' > > /opt/toolchains/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/aarch6= 4-linux-gnu-ld: /home/crimar01/ARM/dev/src/pdsw/linux/drivers/firmware/arm_= scmi/optee.c:276: undefined reference to `tee_shm_get_va' > > /opt/toolchains/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/aarch6= 4-linux-gnu-ld: drivers/firmware/arm_scmi/optee.o: in function `close_sessi= on': > > /home/crimar01/ARM/dev/src/pdsw/linux/drivers/firmware/arm_scmi/optee.c= :151: undefined reference to `tee_client_close_session' > > /opt/toolchains/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/aarch6= 4-linux-gnu-ld: drivers/firmware/arm_scmi/optee.o:(.data+0x10): undefined r= eference to `tee_bus_type' > > /home/crimar01/ARM/dev/src/pdsw/linux/Makefile:1189: recipe for target = 'vmlinux' failed > > make[1]: *** [vmlinux] Error 1 > > make[1]: Leaving directory '/home/crimar01/ARM/dev/src/pdsw/out_linux' > > Makefile:219: recipe for target '__sub-make' failed > > > > Taking a similar approach to Virtio, this fixed for me > > > > diff --git a/drivers/firmware/arm_scmi/Kconfig b/drivers/firmware/arm_s= cmi/Kconfig > > index 9107e249023c..30746350349c 100644 > > --- a/drivers/firmware/arm_scmi/Kconfig > > +++ b/drivers/firmware/arm_scmi/Kconfig > > @@ -79,7 +79,7 @@ config ARM_SCMI_TRANSPORT_VIRTIO > > > > config ARM_SCMI_TRANSPORT_OPTEE > > bool "SCMI transport based on OP-TEE service" > > - depends on OPTEE > > + depends on OPTEE=3Dy || OPTEE=3DARM_SCMI_PROTOCOL > > select ARM_SCMI_HAVE_TRANSPORT > > select ARM_SCMI_HAVE_SHMEM > > default y > > > > which basically disables ARM_SCMI_TRANSPORT_OPTEE when CONFIG_OPTEE=3Dm= AND > > ARM_SCMI_TRANSPORT_OPTEE=3Dy: in this scenario if TEE is =3Dm you have = to build > > ARM_SCMI_PROTOCOL=3Dm too to be able to include ARM_SCMI_TRANSPORT_OPTE= E. > > Fully makes sense to me. Thanks. I understand. > > > > > > > > config ARM_SCMI_POWER_DOMAIN > > > diff --git a/drivers/firmware/arm_scmi/Makefile b/drivers/firmware/ar= m_scmi/Makefile > > > index 1dcf123d64ab..ef66ec8ca917 100644 > > > --- a/drivers/firmware/arm_scmi/Makefile > > > +++ b/drivers/firmware/arm_scmi/Makefile > > > @@ -6,6 +6,7 @@ scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_MAILBOX) += =3D mailbox.o > > > scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_SMC) +=3D smc.o > > > scmi-transport-$(CONFIG_ARM_SCMI_HAVE_MSG) +=3D msg.o > > > scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO) +=3D virtio.o > > > +scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_OPTEE) +=3D optee.o > > > scmi-protocols-y =3D base.o clock.o perf.o power.o reset.o sensors.o= system.o voltage.o > > > scmi-module-objs :=3D $(scmi-bus-y) $(scmi-driver-y) $(scmi-protocol= s-y) \ > > > $(scmi-transport-y) > > > diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/ar= m_scmi/common.h > > > index dea1bfbe1052..82ff3c3a6d2d 100644 > > > --- a/drivers/firmware/arm_scmi/common.h > > > +++ b/drivers/firmware/arm_scmi/common.h > > > @@ -421,6 +421,9 @@ extern const struct scmi_desc scmi_smc_desc; > > > #ifdef CONFIG_ARM_SCMI_TRANSPORT_VIRTIO > > > extern const struct scmi_desc scmi_virtio_desc; > > > #endif > > > +#ifdef CONFIG_OPTEE > > > > This should be: > > > > #ifdef CONFIG_ARM_SCMI_TRANSPORT_OPTEE > > > > if not disabling OPTEE transport in Kconfig breaks the build. > > > > LD .tmp_vmlinux.kallsyms1 > > /opt/toolchains/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/aarch= 64-linux-gnu-ld: > > drivers/firmware/arm_scmi/driver.o:(.rodata+0x280): undefined referenc= e > > to `scmi_optee_desc' > > /home/crimar01/ARM/dev/src/pdsw/linux/Makefile:1189: recipe for target > > 'vmlinux' failed > > make[1]: *** [vmlinux] Error 1 > > make[1]: Leaving directory '/home/crimar01/ARM/dev/src/pdsw/out_linux' > > > > > > > +extern const struct scmi_desc scmi_optee_desc; > > > +#endif > > > > > > void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr, voi= d *priv); > > > void scmi_free_channel(struct scmi_chan_info *cinfo, struct idr *idr= , int id); > > > diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/ar= m_scmi/driver.c > > > index b406b3f78f46..06f0a9846c7e 100644 > > > --- a/drivers/firmware/arm_scmi/driver.c > > > +++ b/drivers/firmware/arm_scmi/driver.c > > > @@ -1999,6 +1999,9 @@ static const struct of_device_id scmi_of_match[= ] =3D { > > > #endif > > > #ifdef CONFIG_ARM_SCMI_TRANSPORT_VIRTIO > > > { .compatible =3D "arm,scmi-virtio", .data =3D &scmi_virtio_des= c}, > > > +#endif > > > +#ifdef CONFIG_OPTEE > > > > Same as above should be #if CONFIG_ARM_SCMI_TRANSPORT_OPTEE > > > > > + { .compatible =3D "linaro,scmi-optee", .data =3D &scmi_optee_de= sc }, > > > #endif > > > { /* Sentinel */ }, > > > }; > > > diff --git a/drivers/firmware/arm_scmi/optee.c b/drivers/firmware/arm= _scmi/optee.c > > > new file mode 100644 > > > index 000000000000..e294cff37bea > > > --- /dev/null > > > +++ b/drivers/firmware/arm_scmi/optee.c > > > @@ -0,0 +1,559 @@ > > > +// SPDX-License-Identifier: GPL-2.0 > > > +/* > > > + * Copyright (C) 2019-2021 Linaro Ltd. > > > + */ > > > + > > > +#include > > > +#include > > > +#include > > > +#include > > > +#include > > > +#include > > > +#include > > > +#include > > > +#include > > > +#include > > > + > > > +#include "common.h" > > > + > > > +#define DRIVER_NAME "optee-scmi" > > > + > > > +enum optee_smci_pta_cmd { > > ^ > > scmi ? or is it another fancy 4letters acronym :D > > :) nice catch! > > > > + /* > > > + * PTA_SCMI_CMD_CAPABILITIES - Get channel capabilities > > > + * > > > + * [out] value[0].a: Capability bit mask (enum pta_scmi_caps= ) > > > + * [out] value[0].b: Extended capabilities or 0 > > > + */ > > > + PTA_SCMI_CMD_CAPABILITIES =3D 0, > > > + > > > + /* > > > + * PTA_SCMI_CMD_PROCESS_SMT_CHANNEL - Process SCMI message in S= MT buffer > > > + * > > > + * [in] value[0].a: Channel handle > > > + * > > > + * Shared memory used for SCMI message/response exhange is expe= cted > > > + * already identified and bound to channel handle in both SCMI = agent > > > + * and SCMI server (OP-TEE) parts. > > > + * The memory uses SMT header to carry SCMI meta-data (protocol= ID and > > > + * protocol message ID). > > > + */ > > > + PTA_SCMI_CMD_PROCESS_SMT_CHANNEL =3D 1, > > > + > > > + /* > > > + * PTA_SCMI_CMD_PROCESS_SMT_CHANNEL_MESSAGE - Process SMT/SCMI = message > > > + * > > > + * [in] value[0].a: Channel handle > > > + * [in/out] memref[1]: Message/response buffer (SMT and SCMI pa= yload) > > > + * > > > + * Shared memory used for SCMI message/response is a SMT buffer > > > + * referenced by param[1]. It shall be 128 bytes large to fit r= esponse > > > + * payload whatever message playload size. > > > + * The memory uses SMT header to carry SCMI meta-data (protocol= ID and > > > + * protocol message ID). > > > + */ > > > + PTA_SCMI_CMD_PROCESS_SMT_CHANNEL_MESSAGE =3D 2, > > > + > > > + /* > > > + * PTA_SCMI_CMD_GET_CHANNEL - Get channel handle > > > + * > > > + * SCMI shm information are 0 if agent expects to use OP-TEE re= gular SHM > > > + * > > > + * [in] value[0].a: Channel identifier > > > + * [out] value[0].a: Returned channel handle > > > + * [in] value[0].b: Requested capabilities mask (enum pta_s= cmi_caps) > > > + */ > > > + PTA_SCMI_CMD_GET_CHANNEL =3D 3, > > > +}; > > > + > > > +/* > > > + * Capabilities > > > + */ > > > +enum pta_scmi_caps { > > > + PTA_SCMI_CAPS_NONE =3D 0, > > > + /* > > > + * Supports command using SMT header protocol (SCMI shmem) in s= hared > > > + * memory buffers to carry SCMI protocol synchronisation inform= ation. > > > + */ > > > + PTA_SCMI_CAPS_SMT_HEADER =3D BIT(0), > > > +}; > > > + > > > +/** > > > + * struct optee_channel - Description of an OP-TEE SCMI channel > > > + * > > > + * @channel_id: OP-TEE channel ID used for this transport > > > + * @mu: Mutex protection on channel access > > > + * @tee_session: TEE session identifier > > > + * @cinfo: SCMI channel information > > > + * @shmem: Virtual base address of the shared memory > > > + * @tee_shm: Reference to TEE shared memory or NULL if using static = shmem > > > + * @caps: OP-TEE SCMI channel capabilities > > > + * @link: Reference in agent's channel list > > > + */ > > > +struct optee_channel { > > > + u32 channel_id; > > > + struct mutex mu; > > > + u32 tee_session; > > > + struct scmi_chan_info *cinfo; > > > + struct scmi_shared_mem __iomem *shmem; > > > + struct tee_shm *tee_shm; > > > + enum pta_scmi_caps caps; > > > + struct list_head link; > > > +}; > > > + > > > +/** > > > + * struct optee_agent - OP-TEE transport private data > > > + * > > > + * @dev: Device used for communication with TEE > > > + * @tee_ctx: TEE context used for communication > > > + * @caps: Supported channel capabilities > > > + * @mu: Mutex for protection of @channel_list > > > + * @channel_list: List of all created channels for the agent > > > + */ > > > +struct optee_agent { > > > + struct device *dev; > > > + struct tee_context *tee_ctx; > > > + enum pta_scmi_caps caps; > > > + struct mutex mu; > > > + struct list_head channel_list; > > > +}; > > > + > > > +/* There can be only 1 SCMI service in OP-TEE we connect to */ > > > +static struct optee_agent *optee_private; > > > + > > > > Maybe naming these locally defined optee_ structs as scmi_optee_ ? > > > > When I see those optee_ refs around down below I tend to think they > > are OPTEE core structs not locally defined containers. > > (I uderstand that depends on my poor familiarity with OPTEE APIs > > though...) > > Ok. If that help maintenance, I'm fine. I'll use scmi_optee_ where appiic= able. > > > > > > > +/* Open a session toward SCMI OP-TEE service with REE_KERNEL identit= y */ > > > +static int open_session(u32 *tee_session) > > > +{ > > > + struct device *dev =3D optee_private->dev; > > > + struct tee_client_device *scmi_pta =3D to_tee_client_device(dev= ); > > > + struct tee_ioctl_open_session_arg arg =3D { }; > > > + int ret; > > > + > > > + memcpy(arg.uuid, scmi_pta->id.uuid.b, TEE_IOCTL_UUID_LEN); > > > + arg.clnt_login =3D TEE_IOCTL_LOGIN_REE_KERNEL; > > > + > > > + ret =3D tee_client_open_session(optee_private->tee_ctx, &arg, N= ULL); > > > + if (ret < 0 || arg.ret) { > > > + dev_err(dev, "Can't open tee session: %d / %#x\n", ret,= arg.ret); > > > + > > > + return -EOPNOTSUPP; > > > + } > > > + > > > + *tee_session =3D arg.session; > > > + > > > + return 0; > > > +} > > > + > > > +static void close_session(u32 tee_session) > > > +{ > > > + tee_client_close_session(optee_private->tee_ctx, tee_session); > > > +} > > > + > > > +static int get_capabilities(void) > > > +{ > > > + struct optee_agent *agent =3D optee_private; > > > + struct tee_ioctl_invoke_arg arg =3D { }; > > > + struct tee_param param[1] =3D { }; > > > + u32 tee_session; > > > + int ret; > > > + > > > + ret =3D open_session(&tee_session); > > > + if (ret) > > > + return ret; > > > + > > > + arg.func =3D PTA_SCMI_CMD_CAPABILITIES; > > > + arg.session =3D tee_session; > > > + arg.num_params =3D 1; > > > + > > > + param[0].attr =3D TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT; > > > + > > > + ret =3D tee_client_invoke_func(agent->tee_ctx, &arg, param); > > > + > > > + close_session(tee_session); > > > + > > > + if (ret < 0 || arg.ret) { > > > + dev_err(agent->dev, "Can't get capabilities: %d / %#x\n= ", ret, arg.ret); > > > + > > > + return -EOPNOTSUPP; > > > + } > > > + > > > + agent->caps =3D param[0].u.value.a; > > > + > > > + if (!(agent->caps & PTA_SCMI_CAPS_SMT_HEADER)) { > > > + dev_err(agent->dev, "OP-TEE SCMI PTA doesn't support SM= T\n"); > > > + > > > + return -EOPNOTSUPP; > > > + } > > > + > > > + return 0; > > > +} > > > + > > > +static int get_channel(struct optee_channel *channel) > > > +{ > > > + struct device *dev =3D optee_private->dev; > > > + struct tee_ioctl_invoke_arg arg =3D { }; > > > + struct tee_param param[1] =3D { }; > > > + unsigned int caps =3D PTA_SCMI_CAPS_SMT_HEADER; > > > + int ret; > > > + > > > + arg.func =3D PTA_SCMI_CMD_GET_CHANNEL; > > > + arg.session =3D channel->tee_session; > > > + arg.num_params =3D 1; > > > + > > > + param[0].attr =3D TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT; > > > + param[0].u.value.a =3D channel->channel_id; > > > + param[0].u.value.b =3D caps; > > > + > > > + ret =3D tee_client_invoke_func(optee_private->tee_ctx, &arg, pa= ram); > > > + > > > + if (ret || arg.ret) { > > > + dev_err(dev, "Can't get channel with caps %#x: %d / %#x= \n", caps, ret, arg.ret); > > > + > > > + return -EOPNOTSUPP; > > > + } > > > + > > > + /* From now on use channel identifer provided by OP-TEE SCMI se= rvice */ > > > + channel->channel_id =3D param[0].u.value.a; > > > + channel->caps =3D caps; > > > + > > > + return 0; > > > +} > > > + > > > +static int invoke_process_smt_channel(struct optee_channel *channel) > > > +{ > > > + struct tee_ioctl_invoke_arg arg =3D { }; > > > + struct tee_param param[2] =3D { }; > > > + int ret; > > > + > > > + arg.session =3D channel->tee_session; > > > + param[0].attr =3D TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT; > > > + param[0].u.value.a =3D channel->channel_id; > > > + > > > + if (channel->tee_shm) { > > > + const size_t msg_size =3D scmi_optee_desc.max_msg_size; > > > + > > > + param[1].attr =3D TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOU= T; > > > + param[1].u.memref.shm =3D channel->tee_shm; > > > + param[1].u.memref.size =3D msg_size; > > > + arg.num_params =3D 2; > > > + arg.func =3D PTA_SCMI_CMD_PROCESS_SMT_CHANNEL_MESSAGE; > > > + } else { > > > + arg.num_params =3D 1; > > > + arg.func =3D PTA_SCMI_CMD_PROCESS_SMT_CHANNEL; > > > + } > > > + > > > + ret =3D tee_client_invoke_func(optee_private->tee_ctx, &arg, pa= ram); > > > + if (ret < 0 || arg.ret) { > > > + dev_err(optee_private->dev, "Failed on channel %u: %d /= %#x\n", > > > + channel->channel_id, ret, arg.ret); > > > + > > > + return -EIO; > > > + } > > > + > > > + return 0; > > > +} > > > + > > > +static bool optee_chan_available(struct device *dev, int idx) > > > +{ > > > + u32 channel_id; > > > + > > > + return !of_property_read_u32_index(dev->of_node, "linaro,optee-= channel-id", > > > + idx, &channel_id); > > > +} > > > + > > > +static int setup_dynamic_shmem(struct device *dev, struct optee_chan= nel *channel) > > > +{ > > > + const size_t msg_size =3D scmi_optee_desc.max_msg_size; > > > + > > > + channel->tee_shm =3D tee_shm_alloc_kernel_buf(optee_private->te= e_ctx, msg_size); > > > + if (IS_ERR(channel->tee_shm)) { > > > + dev_err(channel->cinfo->dev, "shmem allocation failed\n= "); > > > + return -ENOMEM; > > > + } > > > + > > > + channel->shmem =3D (void *)tee_shm_get_va(channel->tee_shm, 0); > > > + memset(channel->shmem, 0, msg_size); > > > + shmem_clear_channel(channel->shmem); > > > + > > > + return 0; > > > +} > > > + > > > +static int setup_static_shmem(struct device *dev, struct scmi_chan_i= nfo *cinfo, > > > + struct optee_channel *channel) > > > +{ > > > + struct device_node *np; > > > + resource_size_t size; > > > + struct resource res; > > > + int ret; > > > + > > > + np =3D of_parse_phandle(cinfo->dev->of_node, "shmem", 0); > > > + if (!of_device_is_compatible(np, "arm,scmi-shmem")) { > > > + ret =3D -ENXIO; > > > + goto out; > > > + } > > > + > > > + ret =3D of_address_to_resource(np, 0, &res); > > > + if (ret) { > > > + dev_err(dev, "Failed to get SCMI Tx shared memory\n"); > > > + goto out; > > > + } > > > + > > > + size =3D resource_size(&res); > > > + > > > + channel->shmem =3D devm_ioremap(dev, res.start, size); > > > + if (!channel->shmem) { > > > + dev_err(dev, "Failed to ioremap SCMI Tx shared memory\n= "); > > > + ret =3D -EADDRNOTAVAIL; > > > + goto out; > > > + } > > > + > > > + ret =3D 0; > > > + > > > +out: > > > + of_node_put(np); > > > + > > > + return ret; > > > +} > > > + > > > +static int optee_chan_setup_shmem(struct device *dev, struct scmi_ch= an_info *cinfo, > > > + bool tx, struct optee_channel *channe= l) > > > +{ > > > + struct device *cdev =3D cinfo->dev; > > > + > > > + if (of_find_property(cdev->of_node, "shmem", NULL)) > > > + return setup_static_shmem(dev, cinfo, channel); > > > + else > > > + return setup_dynamic_shmem(dev, channel); > > > +} > > > + > > > +static void optee_clear_channel(struct scmi_chan_info *cinfo) > > > +{ > > > + struct optee_channel *channel =3D cinfo->transport_info; > > > + > > > + shmem_clear_channel(channel->shmem); > > > +} > > > + > > > +static int optee_chan_setup(struct scmi_chan_info *cinfo, struct dev= ice *dev, bool tx) > > > +{ > > > + struct optee_channel *channel; > > > + uint32_t channel_id; > > > + int ret; > > > + > > > + if (!tx) > > > + return -ENODEV; > > > + > > > + /* Shall wait for OP-TEE driver to be up and ready */ > > > + if (!optee_private || !optee_private->tee_ctx) > > > + return -EPROBE_DEFER; > > > + > > > + channel =3D devm_kzalloc(dev, sizeof(*channel), GFP_KERNEL); > > > + if (!channel) > > > + return -ENOMEM; > > > + > > > + ret =3D of_property_read_u32_index(cinfo->dev->of_node, "linaro= ,optee-channel-id", > > > + 0, &channel_id); > > > + if (ret) > > > + return ret; > > > + > > > + cinfo->transport_info =3D channel; > > > + channel->cinfo =3D cinfo; > > > + channel->channel_id =3D channel_id; > > > + mutex_init(&channel->mu); > > > + > > > + ret =3D optee_chan_setup_shmem(dev, cinfo, tx, channel); > > > + if (ret) > > > + return ret; > > > + > > > + ret =3D open_session(&channel->tee_session); > > > + if (ret) > > > + return ret; > > > + > > > + ret =3D get_channel(channel); > > > + if (ret) { > > > + close_session(channel->tee_session); > > > + > > > + return ret; > > > + } > > > + > > > + mutex_lock(&optee_private->mu); > > > + list_add(&channel->link, &optee_private->channel_list); > > > + mutex_unlock(&optee_private->mu); > > > + > > > + return 0; > > > +} > > > + > > > +static int optee_chan_free(int id, void *p, void *data) > > > +{ > > > + struct scmi_chan_info *cinfo =3D p; > > > + struct optee_channel *channel =3D cinfo->transport_info; > > > + > > > + mutex_lock(&optee_private->mu); > > > + list_del(&channel->link); > > > + mutex_unlock(&optee_private->mu); > > > + > > > + if (channel->tee_shm) { > > > + tee_shm_free(channel->tee_shm); > > > + channel->tee_shm =3D NULL; > > > + } > > > + > > > + cinfo->transport_info =3D NULL; > > > + channel->cinfo =3D NULL; > > > + > > > + scmi_free_channel(cinfo, data, id); > > > + > > > + return 0; > > > +} > > > + > > > +static struct scmi_shared_mem *get_channel_shm(struct optee_channel = *chan, struct scmi_xfer *xfer) > > > +{ > > > + if (!chan) > > > + return NULL; > > > + > > > + return chan->shmem; > > > +} > > > + > > > + > > > +static int optee_send_message(struct scmi_chan_info *cinfo, > > > + struct scmi_xfer *xfer) > > > +{ > > > + struct optee_channel *channel =3D cinfo->transport_info; > > > + struct scmi_shared_mem *shmem =3D get_channel_shm(channel, xfer= ); > > > + int ret; > > > + > > > + mutex_lock(&channel->mu); > > > + shmem_tx_prepare(shmem, xfer); > > > + > > > + ret =3D invoke_process_smt_channel(channel); > > > > Here all the associated processing in the TrustedOS is fully completed > > right ? i.e. all the possible reply values have been put into shmem by > > the TrustedOS process before the underlying SMC call returns. > > (just to understand better how OPTEE transport is supposed to behave) > > Yes, once we're back from invoke_process_smt_channel() the SCMI > message has been processed and the response can be read. > If no response is found, it will be reported as a communication error. > > > > > > + > > > + scmi_rx_callback(cinfo, shmem_read_header(shmem), NULL); > > > + mutex_unlock(&channel->mu); > > > + > > > + return ret; > > > +} > > > + > > > +static void optee_fetch_response(struct scmi_chan_info *cinfo, > > > + struct scmi_xfer *xfer) > > > +{ > > > + struct optee_channel *channel =3D cinfo->transport_info; > > > + struct scmi_shared_mem *shmem =3D get_channel_shm(channel, xfer= ); > > > + > > > + shmem_fetch_response(shmem, xfer); > > > +} > > > + > > > +static bool optee_poll_done(struct scmi_chan_info *cinfo, > > > + struct scmi_xfer *xfer) > > > +{ > > > + struct optee_channel *channel =3D cinfo->transport_info; > > > + struct scmi_shared_mem *shmem =3D get_channel_shm(channel, xfer= ); > > > + > > > + return shmem_poll_done(shmem, xfer); > > > +} > > > + > > > +static struct scmi_transport_ops scmi_optee_ops =3D { > > > + .chan_available =3D optee_chan_available, > > > + .chan_setup =3D optee_chan_setup, > > > + .chan_free =3D optee_chan_free, > > > + .send_message =3D optee_send_message, > > > + .fetch_response =3D optee_fetch_response, > > > + .clear_channel =3D optee_clear_channel, > > > + .poll_done =3D optee_poll_done, > > > +}; > > > + > > > +const struct scmi_desc scmi_optee_desc =3D { > > > + .ops =3D &scmi_optee_ops, > > > + .max_rx_timeout_ms =3D 30, > > > + .max_msg =3D 20, > > > + .max_msg_size =3D 128, > > > +}; > > > + > > > +static int optee_ctx_match(struct tee_ioctl_version_data *ver, const= void *data) > > > +{ > > > + return ver->impl_id =3D=3D TEE_IMPL_ID_OPTEE; > > > +} > > > + > > > +static int optee_service_probe(struct device *dev) > > > +{ > > > + struct optee_agent *agent; > > > + struct tee_context *tee_ctx; > > > + int ret; > > > + > > > + /* Only one SCMI OP-TEE device allowed */ > > > + if (optee_private) { > > > + dev_err(dev, "An SCMI OP-TEE device was already initial= ized: only one allowed\n"); > > > + return -EBUSY; > > > + } > > > + > > > + tee_ctx =3D tee_client_open_context(NULL, optee_ctx_match, NULL= , NULL); > > > + if (IS_ERR(tee_ctx)) > > > + return -ENODEV; > > > + > > > + agent =3D devm_kzalloc(dev, sizeof(*agent), GFP_KERNEL); > > > + if (!agent) { > > > + ret =3D -ENOMEM; > > > + goto out; > > > + } > > > + > > > + agent->dev =3D dev; > > > + agent->tee_ctx =3D tee_ctx; > > > + INIT_LIST_HEAD(&agent->channel_list); > > > + > > > + optee_private =3D agent; > > > > Barrier here to be sure this global is visible and not reordered ? > > > > Not sure if it is plausible that without a barrier the subsequent > > optee_chan_setup could run on another core and simply miss this update > > and bail out. (cannot see any locking of any kind either in the > > chan_available/chan_setup TX path that could trigger a implicit memory > > barrier....bah maybe I'm paranoid) > > No barrier needed IMO. optee_private is standard cached memory visible > to all participant cores > and chan_setup cannot be called before this function completes. > Do I miss something? > I see why you ask for a barrier. Indeed, at module insertion we can face consistency issues. I agree barriers are needed. Looking at the scmi_virtio implementation, i think the barriers are misplaced in the sequences. The barrier should be placed before the global reference is loaded at device probe, so that its content is visible before the device reference itself. On the other hand in the remove sequence, the barrier should be placed after device ref is cleared but before device resources are released. Note that, in smp_store_mb() implementation, the memory barrier is places after the data is loaded, not before. See the patch-like snippet below: static int scmi_vio_probe(struct virtio_device *vdev) { (...) - vdev->priv =3D channels; - /* Ensure initialized scmi_vdev is visible */ - smp_store_mb(scmi_vdev, vdev); + /* Ensure initialized scmi_vdev is visible before scmi_vdev is */ + smp_store_mb(vdev->priv, channels); + scmi_vdev =3D vdev; return 0; } static void scmi_vio_remove(struct virtio_device *vdev) { + /* Ensure scmi_vdev is visible as NULL before resources are released *= / + smp_store_mb(scmi_vdev, NULL); + /* * Once we get here, virtio_chan_free() will have already been called = by * the SCMI core for any existing channel and, as a consequence, all t= he * virtio channels will have been already marked NOT ready, causing an= y * outstanding message on any vqueue to be ignored by complete_cb: now * we can just stop processing buffers and destroy the vqueues. */ vdev->config->reset(vdev); vdev->config->del_vqs(vdev); - /* Ensure scmi_vdev is visible as NULL */ - smp_store_mb(scmi_vdev, NULL); } Does that make sense to you? > > > > > + > > > + ret =3D get_capabilities(); > > > + > > > +out: > > > + if (ret) { > > > + tee_client_close_context(tee_ctx); > > > + optee_private =3D NULL; > > > > Barrier ? (not sure as above...) > > > > > + } > > > + > > > + return ret; > > > +} > > > + > > > +static int optee_service_remove(struct device *dev) > > > +{ > > > + if (optee_private) > > > + return -EINVAL; > > > > Is it instead: if (!optee_private) ? > > Oups! indeed :( > > > > + > > > + if (!list_empty(&optee_private->channel_list)) > > > + return -EBUSY; > > > + > > > + tee_client_close_context(optee_private->tee_ctx); > > > + > > > + optee_private =3D NULL; > > > + > > > > Barrier ? (not sure as above...) > > > > > + return 0; > > > +} > > > + > > > +static const struct tee_client_device_id scmi_optee_service_id[] =3D= { > > > + { > > > + UUID_INIT(0xa8cfe406, 0xd4f5, 0x4a2e, > > > + 0x9f, 0x8d, 0xa2, 0x5d, 0xc7, 0x54, 0xc0, 0x9= 9) > > > + }, > > > + { } > > > +}; > > > + > > > +MODULE_DEVICE_TABLE(tee, scmi_optee_service_id); > > > + > > > +static struct tee_client_driver scmi_optee_driver =3D { > > > + .id_table =3D scmi_optee_service_id, > > > + .driver =3D { > > > + .name =3D "scmi-optee", > > > + .bus =3D &tee_bus_type, > > > + .probe =3D optee_service_probe, > > > + .remove =3D optee_service_remove, > > > + }, > > > +}; > > > + > > > +static int __init scmi_optee_init(void) > > > +{ > > > + return driver_register(&scmi_optee_driver.driver); > > > +} > > > + > > > +static void __exit scmi_optee_exit(void) > > > +{ > > > + driver_unregister(&scmi_optee_driver.driver); > > > +} > > > + > > > +device_initcall(scmi_optee_init) > > > +module_exit(scmi_optee_exit); > > > > This breaks the build when ARM_SCMI_PROTOCOL=3Dm and SCMI OPTEE transpo= rt is enabled, > > since the SCMI transports are not full fledged drivers but they are bui= lt into > > the SCMI stack core module, so if you endup trying to define multiple i= nits. > > > > LD [M] drivers/firmware/arm_scmi/scmi-module.o > > /opt/toolchains/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/aarch6= 4-linux-gnu-ld: drivers/firmware/arm_scmi/optee.o: in function `scmi_optee_= init': > > /home/crimar01/ARM/dev/src/pdsw/linux/drivers/firmware/arm_scmi/optee.c= :549: multiple definition of `init_module'; drivers/firmware/arm_scmi/drive= r.o:/home/crimar01/ARM/dev/src/pdsw/linux/drivers/firmware/arm_scmi/driver.= c:2070: first defined here > > /opt/toolchains/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/aarch6= 4-linux-gnu-ld: drivers/firmware/arm_scmi/optee.o: in function `scmi_optee_= exit': > > /home/crimar01/ARM/dev/src/pdsw/linux/drivers/firmware/arm_scmi/optee.c= :554: multiple definition of `cleanup_module'; drivers/firmware/arm_scmi/dr= iver.o:/home/crimar01/ARM/dev/src/pdsw/linux/drivers/firmware/arm_scmi/driv= er.c:2099: first defined he> /home/crimar01/ARM/dev/src/pdsw/linux/scripts/= Makefile.build:474: recipe for target 'drivers/firmware/arm_scmi/scmi-modul= e.o' failed > > make[4]: *** [drivers/firmware/arm_scmi/scmi-module.o] Error 1 > > /home/crimar01/ARM/dev/src/pdsw/linux/scripts/Makefile.build:540: recip= e for target 'drivers/firmware/arm_scmi' failed > > make[3]: *** [drivers/firmware/arm_scmi] Error 2 > > /home/crimar01/ARM/dev/src/pdsw/linux/scripts/Makefile.build:540: recip= e for target 'drivers/firmware' failed > > make[2]: *** [drivers/firmware] Error 2 > > make[2]: *** Waiting for unfinished jobs.... > > /home/crimar01/ARM/dev/src/pdsw/linux/Makefile:1874: recipe for target = 'drivers' failed > > make[1]: *** [drivers] Error 2 > > make[1]: Leaving directory '/home/crimar01/ARM/dev/src/pdsw/out_linux' > > Makefile:219: recipe for target '__sub-make' failed > > > > In order to address this issue (same happended with VirtIO) I added > > transport_init/transport_exit optional hooks into scmi_desc, so that > > you can ask the core SCMI stack to perform whatever your transport > > needs at SCMI core init-time, before the SCMI core stack is probed. > > > > In other words the fix here down below fixes for me the build as a > > module of the SCMI stack. > > To ensure scmi/optee transport can register to the tee bus, it must > wait tee bus is initialized. > The issue is optee driver initializes its tee bus at subsys_initcall > level, same level as the scmi driver. > So I had to call scmi_optee_init() at an earlier init level: device_initc= all(). > > Virtio bus is registered at core_initcall level hence scmi/virtio init > a subsys_initcall has the dependency resolved. I have a proposal to address this. You suggested to use ::transport_init operator from struct scmi_desc for this registration to the optee bus. For the reason above, it does not apply to OP-TEE. My idea is to not ue ::transport_init hook but to register from ::link_supplier hook from struct scmi_transport_ops. The first time a scmi_optee channel to requested, it will be deferred and scmi_optee registering to optee bus done. Something like the below: static int scmi_optee_link_supplier(struct device *dev) { if (!scmi_optee_private) { static int register_to_optee =3D -ENODEV; // register to optee bus enumeration if not already successfully = done if (register_to_optee) register_to_optee =3D driver_register(&scmi_optee_driver.driv= er); // defer channel setup until return -EPROBE_DEFER; } if (!device_link_add(dev, scmi_optee_private->dev, DL_FLAG_AUTOREMOVE_CONSUMER)) { dev_err(dev, "Adding link to supplier optee device failed\n"); return -ECANCELED; } return 0; } Note the exit sequence can still use struct scmi_desc::transport_ext hook: static void scmi_optee_exit(void) { driver_unregister(&scmi_optee_driver.driver); } module_exit(scmi_optee_exit); May I get your opinion? Regards, Etienne > > > > > > Note that also __exit on scmi_optee_exit( )ha sbeen removed to avoid > > some complains spotted by Arnd on SCMI VirtIO (1cd73200dad2 firmware: > > arm_scmi: Remove __exit annotation) > > Ok, thanks. > > Regards, > Etienne > > > > > Thanks, > > Cristian > > > > ---8<----------------------- > > > > diff --git a/drivers/firmware/arm_scmi/optee.c b/drivers/firmware/arm_s= cmi/optee.c > > index e294cff37bea..af6d52438b04 100644 > > --- a/drivers/firmware/arm_scmi/optee.c > > +++ b/drivers/firmware/arm_scmi/optee.c > > @@ -459,13 +459,6 @@ static struct scmi_transport_ops scmi_optee_ops = =3D { > > .poll_done =3D optee_poll_done, > > }; > > > > -const struct scmi_desc scmi_optee_desc =3D { > > - .ops =3D &scmi_optee_ops, > > - .max_rx_timeout_ms =3D 30, > > - .max_msg =3D 20, > > - .max_msg_size =3D 128, > > -}; > > - > > static int optee_ctx_match(struct tee_ioctl_version_data *ver, const v= oid *data) > > { > > return ver->impl_id =3D=3D TEE_IMPL_ID_OPTEE; > > @@ -550,10 +543,16 @@ static int __init scmi_optee_init(void) > > return driver_register(&scmi_optee_driver.driver); > > } > > > > -static void __exit scmi_optee_exit(void) > > +static void scmi_optee_exit(void) > > { > > driver_unregister(&scmi_optee_driver.driver); > > } > > > > -device_initcall(scmi_optee_init) > > -module_exit(scmi_optee_exit); > > +const struct scmi_desc scmi_optee_desc =3D { > > + .transport_init =3D scmi_optee_init, > > + .transport_exit =3D scmi_optee_exit, > > + .ops =3D &scmi_optee_ops, > > + .max_rx_timeout_ms =3D 30, > > + .max_msg =3D 20, > > + .max_msg_size =3D 128, > > +}; > > > > > -- > > > 2.17.1 > > > From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E16BFC433F5 for ; Tue, 19 Oct 2021 14:28:17 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A1DED60FC1 for ; Tue, 19 Oct 2021 14:28:17 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org A1DED60FC1 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:Subject:Message-ID:Date:From: In-Reply-To:References:MIME-Version:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=JXcOhIHvAJIKwYihMyY+E13q8VYLOO178nZU9cFcB4g=; b=YSruJ+lHpxZ6aO SkSH0snWVfzAKctoIoq7L12rG/8Ewu2W6mc/ayttPLGecYhBknIANQYZiXLZWNHplatq5jkwNltdR eH8HuO+pfATqQekoejjBJvhT+c47IdMLQ46Nbpwu9fsjPyswqzs5A1mKSUWLZ/u/Zd2N+GWwUzhIE QaE2PpM25eKhzRS8KLDUJLdryoJcsCk3drNUsm2YHMGbQNEZAARq9BbqZovjTtnmiI0B93eGRwb0i TI72ztnr+x399EzWBRszRZdKHOCEH5sHjQfASveCJIo79eZhHAkhJZkgGt/+CT6ZOx0W6ek3lSCKl yHNij/xMQ+le4qVArj8w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mcq4f-001X4V-23; Tue, 19 Oct 2021 14:26:41 +0000 Received: from mail-ed1-x531.google.com ([2a00:1450:4864:20::531]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mcq4W-001X3s-Vs for linux-arm-kernel@lists.infradead.org; Tue, 19 Oct 2021 14:26:37 +0000 Received: by mail-ed1-x531.google.com with SMTP id t16so13735174eds.9 for ; Tue, 19 Oct 2021 07:26:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=yW3YZybIiYOrNDmXT66FEbyuKAadk5Hmp6J68GVcIUo=; b=AslPLw8mXmVkiU4T17lnyvvEhOftOeRtCQsVgDuMcz05jL5pT0I72931u1VuZP/EZz mx81RoMKsffNu0/c5hc8zRHOyZH30r2BNnu7ASqhGUAu2FIJIvK4F2dZx6B0opfTBc1o 6YChtJ1aTTP5qfZNtM5y8FEo6iaw4wss0RSLULKNq/QhVVe2kFyW0whWln0O2DqmGpM9 1VpwJOg6dAi6FVapLR62zrJuMzDQy8tqpAoGHCtjTNJbWnP+v4+dlkBBwheciJUf20M2 TMxqP5QeW6uxiLsiXhDFyZ7vMJ6PxV81s/XcK4qr2kFOd3Hdj7GVaoJtVCCmlZxTMU5y Pdsg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=yW3YZybIiYOrNDmXT66FEbyuKAadk5Hmp6J68GVcIUo=; b=xXCEkOkZyDRke/ahjZMdvLzcauiLCSiReoar4oQJgTzENjjSr+MdACEyu3GvVPsCN5 nzWojFTyEt63uQdwovYh2N7IHtve6f5ye+NSL44LUbNfqTq0h6sh6VotFHMippRWWCi9 Q4t7TLNxnawJ8GKK1B1Swn+N1BZ3TWHxsJ7y2KziyO5Vm4U1HAc/p5vO+BDrIctLujGW /8UzfH4FtxjYkjMnybix4AWxRf7uhZCXZyrF0U3KSGHZOeyPOq6mZYYp1jHErih7RwYp nmXF/voctGERck2GD66EbhEfvma6vliIRA0pMWbZzTrZWGGPsvPJwj0R8Z3wZp9g6CEd Zpjw== X-Gm-Message-State: AOAM5320fpOFYorOc+L/MIwSFBPBI/gN1HHLZAk1MhmLXBt2SuCGlcr9 jzCe399CAXQtLSIowm5dzqovNLnsI9x3/H7wSnJnxQ== X-Google-Smtp-Source: ABdhPJxD5ZE6d0FXENcrQN//+yLHsxoCEzGuODuz45f4fwZiAlKhAIrTc/+QRZjP5t7AG69gJBQvmp+/ewoMx6nKcU8= X-Received: by 2002:aa7:c2da:: with SMTP id m26mr55448769edp.89.1634653481834; Tue, 19 Oct 2021 07:24:41 -0700 (PDT) MIME-Version: 1.0 References: <20211018114046.25571-1-etienne.carriere@linaro.org> <20211018114046.25571-2-etienne.carriere@linaro.org> <20211018194317.GA6526@e120937-lin> In-Reply-To: From: Etienne Carriere Date: Tue, 19 Oct 2021 16:24:30 +0200 Message-ID: Subject: Re: [PATCH v3 2/2] firmware: arm_scmi: Add optee transport To: Cristian Marussi Cc: linux-kernel@vger.kernel.org, "moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE" , Sudeep Holla , Vincent Guittot X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211019_072633_105904_CF316B9E X-CRM114-Status: GOOD ( 51.41 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org SGksCgpPbiBUdWUsIDE5IE9jdCAyMDIxIGF0IDExOjEwLCBFdGllbm5lIENhcnJpZXJlCjxldGll bm5lLmNhcnJpZXJlQGxpbmFyby5vcmc+IHdyb3RlOgo+Cj4gIEhlbGxvIENyaXN0aWFuLAo+Cj4g VGhhbmtzIGEgbG90IGZvciB0aGUgcmV2aWV3Lgo+IEkgc2VlIEkgZGlkbid0IHVuZGVyc3RhbmQg YW5kIHVzZSBjb3JyZWN0bHkgdGhlIGNvbmZpZyBzd2l0Y2ggZm9yIHRoZSB0cmFuc3BvcnQuCj4g VGhhbmtzIGZvciBhbGwgdGhlIGZpeGVzIHlvdSBzZW50LCBpJ2xsIGludGVncmF0ZSB0aGVtIGlu IHRoZSBwYXRjaCB2NC4KPgo+IEkgZG9uJ3Qga25vdyB5ZXQgaG93IHRvIGFkZHJlc3MgeW91ciBs YXN0IGNvbW1lbnQuIFNlZSBteSBmZWVkYmFjayBvbgo+IHRoZSBvcHRlZSBidXMgZGVwZW5kZW5j eSBpc3N1ZS4KPgo+Cj4KPiBPbiBNb24sIDE4IE9jdCAyMDIxIGF0IDIxOjQzLCBDcmlzdGlhbiBN YXJ1c3NpIDxjcmlzdGlhbi5tYXJ1c3NpQGFybS5jb20+IHdyb3RlOgo+ID4KPiA+IE9uIE1vbiwg T2N0IDE4LCAyMDIxIGF0IDAxOjQwOjQ2UE0gKzAyMDAsIEV0aWVubmUgQ2FycmllcmUgd3JvdGU6 Cj4gPiA+IEFkZCBhIG5ldyB0cmFuc3BvcnQgY2hhbm5lbCB0byB0aGUgU0NNSSBmaXJtd2FyZSBp bnRlcmZhY2UgZHJpdmVyIGZvcgo+ID4gPiBTQ01JIG1lc3NhZ2UgZXhjaGFuZ2UgYmFzZWQgb24g b3B0ZWUgdHJhbnNwb3J0IGNoYW5uZWwuIFRoZSBvcHRlZQo+ID4gPiB0cmFuc3BvcnQgaXMgcmVh bGl6ZWQgYnkgY29ubmVjdGluZyBhbmQgaW52b2tpbmcgT1AtVEVFIFNDTUkgc2VydmljZQo+ID4g PiBpbnRlcmZhY2UgUFRBLgo+ID4gPgo+ID4gPiBPcHRlZSB0cmFuc3BvcnQgc3VwcG9ydCAoQ09O RklHX0FSTV9TQ01JX1RSQU5TUE9SVF9PUFRFRSkgaXMgZGVmYXVsdAo+ID4gPiBlbmFibGVkIHdo ZW4gb3B0ZWUgZHJpdmVyIChDRkdfT1BURUUpIGlzIGVuYWJsZWQuIEVmZmVjdGl2ZSBvcHRlZQo+ ID4gPiB0cmFuc3BvcnQgaXMgc2V0dXAgdXBvbiBPUC1URUUgU0NNSSBzZXJ2aWNlIGRpc2NvdmVy eSBhdCBvcHRlZQo+ID4gPiBkZXZpY2UgaW5pdGlhbGl6YXRpb24uIEZvciB0aGlzIFNDTUkgVVVJ RCBpcyByZWdpc3RlcmVkIHRvIHRoZSBvcHRlZQo+ID4gPiBidXMgZm9yIHByb2JpbmcuIFRoaXMg aXMgZG9uZSBhdCBkZXZpY2VfaW5pdCBpbml0Y2FsbCBsZXZlbCwgYWZ0ZXIKPiA+ID4gb3B0ZWUg YnVzIGluaXRpYWxpemF0aW9uIHRoYXQgaXMgZG9uZSBhdCBzdWJzeXNfaW5pdCBsZXZlbCwgYXMg dGhlIHNjbWkKPiA+ID4gZHJpdmVyIGluaXRpYWxpemF0aW9uLgo+ID4gPgo+ID4gPiBUaGUgb3B0 ZWUgdHJhbnNwb3J0IGNhbiB1c2UgYSBzdGF0aWNhbGx5IGRlZmluZWQgc2hhcmVkIG1lbW9yeSBp bgo+ID4gPiB3aGljaCBjYXNlIFNDTUkgZGV2aWNlIHRyZWUgbm9kZSBkZWZpbmVzIGl0IHVzaW5n IGFuICJhcm0sc2NtaS1zaG1lbSIKPiA+ID4gY29tcGF0aWJsZSBwaGFuZGxlIHRocm91Z2ggcHJv cGVydHkgc2htZW0uIEFsdGVybmF0aXZlbHksIG9wdGVlIHRyYW5zcG9ydAo+ID4gPiBhbGxvY2F0 ZXMgdGhlIHNoYXJlZCBtZW1vcnkgYnVmZmVyIGZyb20gdGhlIG9wdGVlIGRyaXZlciB3aGVuIG5v IHNobWVtCj4gPiA+IHByb3BlcnR5IGlzIGRlZmluZWQuCj4gPiA+Cj4gPiA+IFRoZSBwcm90b2Nv bCB1c2VkIHRvIGV4Y2hhbmdlIFNDTUkgbWVzc2FnZSBvdmVyIHRoYXQgc2hhcmVkIG1lbW9yeSBp cwo+ID4gPiBuZWdvdGlhdGVkIGJldHdlZW4gb3B0ZWUgdHJhbnNwb3J0IGRyaXZlciBhbmQgdGhl IE9QLVRFRSBzZXJ2aWNlIHRocm91Z2gKPiA+ID4gY2FwYWJpbGl0aWVzIGV4Y2hhbmdlLgo+ID4g Pgo+ID4gPiBPUC1URUUgU0NNSSBzZXJ2aWNlIGlzIGludGVncmF0ZWQgaW4gT1AtVEVFIHNpbmNl IGl0cyByZWxlYXNlIHRhZyAzLjEzLjAuCj4gPiA+IFRoZSBzZXJ2aWNlIGludGVyZmFjZSBpcyBw dWJsaXNoZWQgaW4gWzFdLgo+ID4gPgo+ID4gPiBMaW5rOiBbMV0gaHR0cHM6Ly9naXRodWIuY29t L09QLVRFRS9vcHRlZV9vcy9ibG9iLzMuMTMuMC9saWIvbGlidXRlZS9pbmNsdWRlL3B0YV9zY21p X2NsaWVudC5oCj4gPiA+IENjOiBDcmlzdGlhbiBNYXJ1c3NpIDxjcmlzdGlhbi5tYXJ1c3NpQGFy bS5jb20+Cj4gPiA+IENjOiBTdWRlZXAgSG9sbGEgPHN1ZGVlcC5ob2xsYUBhcm0uY29tPgo+ID4g PiBTaWduZWQtb2ZmLWJ5OiBFdGllbm5lIENhcnJpZXJlIDxldGllbm5lLmNhcnJpZXJlQGxpbmFy by5vcmc+Cj4gPiA+IC0tLQo+ID4gPiBDaGFuZ2VzIHNpbmNlIHYyOgo+ID4gPiAtIFJlYmFzZSBv biBmb3ItbmV4dC9zY21pLCBiYXNlZCBvbiBMaW51eCB2NS4xNS1yYzEuCj4gPiA+IC0gSW1wbGVt ZW50IHN1cHBvcnQgZm9yIGR5bmFtaWMgYW5kIHN0YXRpYyBzaGFyZWQgbWVtb3J5Lgo+ID4gPiAt IEZhY3Rvcml6ZSBzb21lIGZ1bmN0aW9ucyBhbmQgc2ltcGxpZnkgdHJhbnNwb3J0IGV4aXQgc2Vx dWVuY2UuCj4gPiA+IC0gUmVuYW1lIGRyaXZlciBzb3VyY2UgZmlsZSBmcm9tIG9wdGVlX3NlcnZp Y2UuYyB0byBvcHRlZS5jLgo+ID4gPgo+ID4gPiBObyBjaGFuZ2Ugc2luY2UgdjEKPiA+ID4gLS0t Cj4gPgo+ID4gSGkgRXRpZW5uZSwKPiA+Cj4gPiBhIGZldyByZW1hcmtzIGJlbG93Lgo+ID4KPiA+ ID4gIGRyaXZlcnMvZmlybXdhcmUvYXJtX3NjbWkvS2NvbmZpZyAgfCAgMTIgKwo+ID4gPiAgZHJp dmVycy9maXJtd2FyZS9hcm1fc2NtaS9NYWtlZmlsZSB8ICAgMSArCj4gPiA+ICBkcml2ZXJzL2Zp cm13YXJlL2FybV9zY21pL2NvbW1vbi5oIHwgICAzICsKPiA+ID4gIGRyaXZlcnMvZmlybXdhcmUv YXJtX3NjbWkvZHJpdmVyLmMgfCAgIDMgKwo+ID4gPiAgZHJpdmVycy9maXJtd2FyZS9hcm1fc2Nt aS9vcHRlZS5jICB8IDU1OSArKysrKysrKysrKysrKysrKysrKysrKysrKysrKwo+ID4gPiAgNSBm aWxlcyBjaGFuZ2VkLCA1NzggaW5zZXJ0aW9ucygrKQo+ID4gPiAgY3JlYXRlIG1vZGUgMTAwNjQ0 IGRyaXZlcnMvZmlybXdhcmUvYXJtX3NjbWkvb3B0ZWUuYwo+ID4gPgo+ID4gPiBkaWZmIC0tZ2l0 IGEvZHJpdmVycy9maXJtd2FyZS9hcm1fc2NtaS9LY29uZmlnIGIvZHJpdmVycy9maXJtd2FyZS9h cm1fc2NtaS9LY29uZmlnCj4gPiA+IGluZGV4IDNkNzA4MWU4NDg1My4uOTEwN2UyNDkwMjNjIDEw MDY0NAo+ID4gPiAtLS0gYS9kcml2ZXJzL2Zpcm13YXJlL2FybV9zY21pL0tjb25maWcKPiA+ID4g KysrIGIvZHJpdmVycy9maXJtd2FyZS9hcm1fc2NtaS9LY29uZmlnCj4gPiA+IEBAIC03Nyw2ICs3 NywxOCBAQCBjb25maWcgQVJNX1NDTUlfVFJBTlNQT1JUX1ZJUlRJTwo+ID4gPiAgICAgICAgIElm IHlvdSB3YW50IHRoZSBBUk0gU0NNSSBQUk9UT0NPTCBzdGFjayB0byBpbmNsdWRlIHN1cHBvcnQg Zm9yIGEKPiA+ID4gICAgICAgICB0cmFuc3BvcnQgYmFzZWQgb24gVmlydElPLCBhbnN3ZXIgWS4K PiA+ID4KPiA+ID4gK2NvbmZpZyBBUk1fU0NNSV9UUkFOU1BPUlRfT1BURUUKPiA+ID4gKyAgICAg Ym9vbCAiU0NNSSB0cmFuc3BvcnQgYmFzZWQgb24gT1AtVEVFIHNlcnZpY2UiCj4gPiA+ICsgICAg IGRlcGVuZHMgb24gT1BURUUKPiA+ID4gKyAgICAgc2VsZWN0IEFSTV9TQ01JX0hBVkVfVFJBTlNQ T1JUCj4gPiA+ICsgICAgIHNlbGVjdCBBUk1fU0NNSV9IQVZFX1NITUVNCj4gPiA+ICsgICAgIGRl ZmF1bHQgeQo+ID4gPiArICAgICBoZWxwCj4gPiA+ICsgICAgICAgVGhpcyBlbmFibGVzIHRoZSBP UC1URUUgc2VydmljZSBiYXNlZCB0cmFuc3BvcnQgZm9yIFNDTUkuCj4gPiA+ICsKPiA+ID4gKyAg ICAgICBJZiB5b3Ugd2FudCB0aGUgQVJNIFNDTUkgUFJPVE9DT0wgc3RhY2sgdG8gaW5jbHVkZSBz dXBwb3J0IGZvciBhCj4gPiA+ICsgICAgICAgdHJhbnNwb3J0IGJhc2VkIG9uIE9QLVRFRSBTQ01J IHNlcnZpY2UsIGFuc3dlciBZLgo+ID4gPiArCj4gPiA+ICBlbmRpZiAjQVJNX1NDTUlfUFJPVE9D T0wKPiA+ID4KPiA+Cj4gPiBTbyB0aGlzICdkZXBlbmRzIG9uIE9QVEVFJyByZW1pbmRlZCBtZSBv ZiBhIHNpbWlsYXIgaXNzdWUgb24gVklSVElPCj4gPiB0cmFuc3BvcnQgc3BvdHRlZCBieSBhIGJv dCAoc2VlIHRoZSBmaXggZm9yIFZpcnRpbyBhdDogYzkwNTIxYTBlOTRmIGZpcm13YXJlOgo+ID4g YXJtX3NjbWk6IEZpeCB2aXJ0aW8gdHJhbnNwb3J0IEtjb25maWcgZGVwZW5kZW5jeSksIHRoYXQg Y29uc2lzdGUgaW4gYSBicm9rZW4KPiA+IGJ1aWxkIHdoZW4gU0NNSSB3YXMgY29tcGlsZWQgYnVp bHQtaW4gd2l0aCBWSVJUSU8gdHJhbnNwb3J0IHN1cHBvcnQgd2l0aAo+ID4gQVJNX1NDTUlfUFJP VE9DT0w9eSB3aGlsZSB0aGUgY29yZSB3YXMgQ09ORklHX1ZJUlRJTz1tLgo+ID4KPiA+IFNvIEkg dHJpZWQgc2ltaWxhcmx5IHRvIHNldCBDT05GSUdfT1BURUU9bSB3aGlsZSBrZWVwaW5nIEFSTV9T Q01JX1BST1RPQ09MPXkKPiA+IGV4cGVjdGluZyB0byBzZWUgYSBzaW1pbGFyIGlzc3VlIGFzIGlu IFZpcnRJTyAoaS5lLiBub3QgYmVpbmcgYWJsZSB0byBhY2Nlc3MKPiA+IG9wdGVlIG1vZHVsZSBz eW1ib2xzIGZyb20gdGhlIGJ1aWx0aW4gU0NNSSksIGluc3RlYWQgSSBzcG90dGVkIGEgZGlmZmVy ZW50IGJ1ZyA6RAo+Cj4gU29ycnksIEkgZGlkbid0IHRyeSB0aGlzIGNvbmZpZyAob3B0ZWU9bSAv IHNjbWk9eSkuIEkgdGhvdWdoIGV4cGVjdGluZwo+IHNjbWkgb3ZlciBvcHRlZSBhbmQgc2NtaT15 IHdvdWxkIG1hbmRhdGUgb3B0ZWU9eS4KPiBGb3IgdGhlIGZpeHVwIHlvdSBwcm9wb3NlIGJlbG93 LCBpIHVuZGVyc3RhbmQgaG93IHlvdSBhZGRyZXNzIHRoZQo+IGNvbmZpZ3VyYXRpb24gZGVwZW5k ZW5jaWVzLgo+Cj4gPgo+ID4gICBBUiAgICAgIGRyaXZlcnMvYmFzZS9idWlsdC1pbi5hCj4gPiAv aG9tZS9jcmltYXIwMS9BUk0vZGV2L3NyYy9wZHN3L2xpbnV4L2RyaXZlcnMvZmlybXdhcmUvYXJt X3NjbWkvb3B0ZWUuYzogSW4gZnVuY3Rpb24g4oCYaW52b2tlX3Byb2Nlc3Nfc210X2NoYW5uZWzi gJk6Cj4gPiAvaG9tZS9jcmltYXIwMS9BUk0vZGV2L3NyYy9wZHN3L2xpbnV4L2RyaXZlcnMvZmly bXdhcmUvYXJtX3NjbWkvb3B0ZWUuYzoyMzM6Mjc6IGVycm9yOiDigJhzY21pX29wdGVlX2Rlc2Pi gJkgdW5kZWNsYXJlZCAoZmlyc3QgdXNlIGluIHRoaXMgZnVuY3Rpb24pOyBkaWQgeW91IG1lYW4g 4oCYc2NtaV9zbWNfZGVzY+KAmT8KPiA+ICAgIGNvbnN0IHNpemVfdCBtc2dfc2l6ZSA9IHNjbWlf b3B0ZWVfZGVzYy5tYXhfbXNnX3NpemU7Cj4gPiAgICAgICAgICAgICAgICAgICAgICAgICAgICBe fn5+fn5+fn5+fn5+fn4KPiA+ICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjbWlfc21jX2Rl c2MKPiA+IC9ob21lL2NyaW1hcjAxL0FSTS9kZXYvc3JjL3Bkc3cvbGludXgvZHJpdmVycy9maXJt d2FyZS9hcm1fc2NtaS9vcHRlZS5jOjIzMzoyNzogbm90ZTogZWFjaCB1bmRlY2xhcmVkIGlkZW50 aWZpZXIgaXMgcmVwb3J0ZWQgb25seSBvbmNlIGZvciBlYWNoIGZ1bmN0aW9uIGl0IGFwcGVhcnMg aW4KPiA+IC9ob21lL2NyaW1hcjAxL0FSTS9kZXYvc3JjL3Bkc3cvbGludXgvZHJpdmVycy9maXJt d2FyZS9hcm1fc2NtaS9vcHRlZS5jOiBJbiBmdW5jdGlvbiDigJhzZXR1cF9keW5hbWljX3NobWVt 4oCZOgo+ID4gL2hvbWUvY3JpbWFyMDEvQVJNL2Rldi9zcmMvcGRzdy9saW51eC9kcml2ZXJzL2Zp cm13YXJlL2FybV9zY21pL29wdGVlLmM6MjY2OjI2OiBlcnJvcjog4oCYc2NtaV9vcHRlZV9kZXNj 4oCZIHVuZGVjbGFyZWQgKGZpcnN0IHVzZSBpbiB0aGlzIGZ1bmN0aW9uKTsgZGlkIHlvdSBtZWFu IOKAmHNjbWlfc21jX2Rlc2PigJk/Cj4gPiAgIGNvbnN0IHNpemVfdCBtc2dfc2l6ZSA9IHNjbWlf b3B0ZWVfZGVzYy5tYXhfbXNnX3NpemU7Cj4gPiAgICAgICAgICAgICAgICAgICAgICAgICAgIF5+ fn5+fn5+fn5+fn5+fgo+ID4gICAgICAgICAgICAgICAgICAgICAgICAgICBzY21pX3NtY19kZXNj Cj4gPiAvaG9tZS9jcmltYXIwMS9BUk0vZGV2L3NyYy9wZHN3L2xpbnV4L3NjcmlwdHMvTWFrZWZp bGUuYnVpbGQ6Mjc3OiByZWNpcGUgZm9yIHRhcmdldCAnZHJpdmVycy9maXJtd2FyZS9hcm1fc2Nt aS9vcHRlZS5vJyBmYWlsZWQKPiA+IG1ha2VbNF06ICoqKiBbZHJpdmVycy9maXJtd2FyZS9hcm1f c2NtaS9vcHRlZS5vXSBFcnJvciAxCj4gPiBtYWtlWzRdOiAqKiogV2FpdGluZyBmb3IgdW5maW5p c2hlZCBqb2JzLi4uLgo+ID4KPiA+IEluIGZhY3QgdGhvc2Ugc2NtaV9vcHRlZV9kZXNjIGFyZSBy ZWZlcmVuY2UgdG8gYSBnbG9iYWwgb25seSBkZWNsYXJlZAo+ID4gZG93biBiZWxvdy4gRml4ZWQg d2l0aCBhIGZldyBkZWZpbmVzIHRvIGNhcnJ5IG9uOgo+ID4KPiA+IC0tLTg8LS0tLS0tLS0tLS0t LS0tLS0tCj4gPgo+ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZmlybXdhcmUvYXJtX3NjbWkvb3B0 ZWUuYyBiL2RyaXZlcnMvZmlybXdhcmUvYXJtX3NjbWkvb3B0ZWUuYwo+ID4gaW5kZXggNjRhYWJh NGE4YmYyLi45M2E4NGM5MTQ1N2IgMTAwNjQ0Cj4gPiAtLS0gYS9kcml2ZXJzL2Zpcm13YXJlL2Fy bV9zY21pL29wdGVlLmMKPiA+ICsrKyBiL2RyaXZlcnMvZmlybXdhcmUvYXJtX3NjbWkvb3B0ZWUu Ywo+ID4gQEAgLTE4LDYgKzE4LDggQEAKPiA+Cj4gPiAgI2RlZmluZSBEUklWRVJfTkFNRSAib3B0 ZWUtc2NtaSIKPiA+Cj4gPiArI2RlZmluZSBTQ01JX09QVEVFX01BWF9NU0dfU0laRSAgICAgICAg ICAgICAgICAxMjgKPiA+ICsKPiA+ICBlbnVtIG9wdGVlX3NtY2lfcHRhX2NtZCB7Cj4gPiAgICAg ICAgIC8qCj4gPiAgICAgICAgICAqIFBUQV9TQ01JX0NNRF9DQVBBQklMSVRJRVMgLSBHZXQgY2hh bm5lbCBjYXBhYmlsaXRpZXMKPiA+IEBAIC0yMzAsNyArMjMyLDcgQEAgc3RhdGljIGludCBpbnZv a2VfcHJvY2Vzc19zbXRfY2hhbm5lbChzdHJ1Y3Qgb3B0ZWVfY2hhbm5lbCAqY2hhbm5lbCkKPiA+ ICAgICAgICAgcGFyYW1bMF0udS52YWx1ZS5hID0gY2hhbm5lbC0+Y2hhbm5lbF9pZDsKPiA+Cj4g PiAgICAgICAgIGlmIChjaGFubmVsLT50ZWVfc2htKSB7Cj4gPiAtICAgICAgICAgICAgICAgY29u c3Qgc2l6ZV90IG1zZ19zaXplID0gc2NtaV9vcHRlZV9kZXNjLm1heF9tc2dfc2l6ZTsKPiA+ICsg ICAgICAgICAgICAgICBjb25zdCBzaXplX3QgbXNnX3NpemUgPSBTQ01JX09QVEVFX01BWF9NU0df U0laRTsKPiA+Cj4gPiAgICAgICAgICAgICAgICAgcGFyYW1bMV0uYXR0ciA9IFRFRV9JT0NUTF9Q QVJBTV9BVFRSX1RZUEVfTUVNUkVGX0lOT1VUOwo+ID4gICAgICAgICAgICAgICAgIHBhcmFtWzFd LnUubWVtcmVmLnNobSA9IGNoYW5uZWwtPnRlZV9zaG07Cj4gPiBAQCAtMjYzLDcgKzI2NSw3IEBA IHN0YXRpYyBib29sIG9wdGVlX2NoYW5fYXZhaWxhYmxlKHN0cnVjdCBkZXZpY2UgKmRldiwgaW50 IGlkeCkKPiA+Cj4gPiAgc3RhdGljIGludCBzZXR1cF9keW5hbWljX3NobWVtKHN0cnVjdCBkZXZp Y2UgKmRldiwgc3RydWN0IG9wdGVlX2NoYW5uZWwgKmNoYW5uZWwpCj4gPiAgewo+ID4gLSAgICAg ICBjb25zdCBzaXplX3QgbXNnX3NpemUgPSBzY21pX29wdGVlX2Rlc2MubWF4X21zZ19zaXplOwo+ ID4gKyAgICAgICBjb25zdCBzaXplX3QgbXNnX3NpemUgPSBTQ01JX09QVEVFX01BWF9NU0dfU0la RTsKPiA+Cj4gPiAgICAgICAgIGNoYW5uZWwtPnRlZV9zaG0gPSB0ZWVfc2htX2FsbG9jX2tlcm5l bF9idWYob3B0ZWVfcHJpdmF0ZS0+dGVlX2N0eCwgbXNnX3NpemUpOwo+ID4gICAgICAgICBpZiAo SVNfRVJSKGNoYW5uZWwtPnRlZV9zaG0pKSB7Cj4gPgo+ID4gLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0KPiA+Cj4gPiBBZnRlciB0aGUgYWJvdmUgY2hhbmdlIGl0IGNvbXBpbGVkIGZpbmUs IHNvIEkgd2VudCBhIHN0ZXAgZnVydGhlciBhbmQgY29uZmlndXJlZCBhbHNvCj4gPiBDT05GSUdf VEVFPW0gKGp1c3QgdHJ5aW5nIHRvIHJlcHJvZHVjZSB3aGF0IGJvdCBzYXcgb24gc2ltaWxhciBW aXJ0SU8gZWVoLi4uLiBub3QgdGhhdAo+ID4gSSBhbSBzbyBldmlsIGFuZCBzYWRpYyA6RCkKPiA+ Cj4gPiBBbmQgaW5kZWVkIG5vdyAod2l0aCBBUk1fU0NNSV9QUk9UT0NPTD15IGFuZCBDT05GSUdf VEVFPW0pIEkgZ2V0Ogo+ID4KPiA+Cj4gPiAgIEdFTiAgICAgbW9kdWxlcy5idWlsdGluCj4gPiAg IExEICAgICAgLnRtcF92bWxpbnV4LmthbGxzeW1zMQo+ID4gL29wdC90b29sY2hhaW5zL2djYy1h cm0tOC4zLTIwMTkuMDMteDg2XzY0LWFhcmNoNjQtbGludXgtZ251L2Jpbi9hYXJjaDY0LWxpbnV4 LWdudS1sZDogVW5leHBlY3RlZCBHT1QvUExUIGVudHJpZXMgZGV0ZWN0ZWQhCj4gPiAvb3B0L3Rv b2xjaGFpbnMvZ2NjLWFybS04LjMtMjAxOS4wMy14ODZfNjQtYWFyY2g2NC1saW51eC1nbnUvYmlu L2FhcmNoNjQtbGludXgtZ251LWxkOiBVbmV4cGVjdGVkIHJ1bi10aW1lIHByb2NlZHVyZSBsaW5r YWdlcyBkZXRlY3RlZCEKPiA+IC9vcHQvdG9vbGNoYWlucy9nY2MtYXJtLTguMy0yMDE5LjAzLXg4 Nl82NC1hYXJjaDY0LWxpbnV4LWdudS9iaW4vYWFyY2g2NC1saW51eC1nbnUtbGQ6IGRyaXZlcnMv ZmlybXdhcmUvYXJtX3NjbWkvb3B0ZWUubzogaW4gZnVuY3Rpb24gYGludm9rZV9wcm9jZXNzX3Nt dF9jaGFubmVsJzoKPiA+IC9ob21lL2NyaW1hcjAxL0FSTS9kZXYvc3JjL3Bkc3cvbGludXgvZHJp dmVycy9maXJtd2FyZS9hcm1fc2NtaS9vcHRlZS5jOjI0NzogdW5kZWZpbmVkIHJlZmVyZW5jZSB0 byBgdGVlX2NsaWVudF9pbnZva2VfZnVuYycKPiA+IC9vcHQvdG9vbGNoYWlucy9nY2MtYXJtLTgu My0yMDE5LjAzLXg4Nl82NC1hYXJjaDY0LWxpbnV4LWdudS9iaW4vYWFyY2g2NC1saW51eC1nbnUt bGQ6IC9ob21lL2NyaW1hcjAxL0FSTS9kZXYvc3JjL3Bkc3cvbGludXgvZHJpdmVycy9maXJtd2Fy ZS9hcm1fc2NtaS9vcHRlZS5jOjI0NzogdW5kZWZpbmVkIHJlZmVyZW5jZSB0byBgdGVlX2NsaWVu dF9pbnZva2VfZnVuYycKPiA+IC9vcHQvdG9vbGNoYWlucy9nY2MtYXJtLTguMy0yMDE5LjAzLXg4 Nl82NC1hYXJjaDY0LWxpbnV4LWdudS9iaW4vYWFyY2g2NC1saW51eC1nbnUtbGQ6IGRyaXZlcnMv ZmlybXdhcmUvYXJtX3NjbWkvb3B0ZWUubzogaW4gZnVuY3Rpb24gYG9wdGVlX2NoYW5fZnJlZSc6 Cj4gPiAvaG9tZS9jcmltYXIwMS9BUk0vZGV2L3NyYy9wZHN3L2xpbnV4L2RyaXZlcnMvZmlybXdh cmUvYXJtX3NjbWkvb3B0ZWUuYzozOTc6IHVuZGVmaW5lZCByZWZlcmVuY2UgdG8gYHRlZV9zaG1f ZnJlZScKPiA+IC9vcHQvdG9vbGNoYWlucy9nY2MtYXJtLTguMy0yMDE5LjAzLXg4Nl82NC1hYXJj aDY0LWxpbnV4LWdudS9iaW4vYWFyY2g2NC1saW51eC1nbnUtbGQ6IGRyaXZlcnMvZmlybXdhcmUv YXJtX3NjbWkvb3B0ZWUubzogaW4gZnVuY3Rpb24gYG9wZW5fc2Vzc2lvbic6Cj4gPiAvaG9tZS9j cmltYXIwMS9BUk0vZGV2L3NyYy9wZHN3L2xpbnV4L2RyaXZlcnMvZmlybXdhcmUvYXJtX3NjbWkv b3B0ZWUuYzoxMzc6IHVuZGVmaW5lZCByZWZlcmVuY2UgdG8gYHRlZV9jbGllbnRfb3Blbl9zZXNz aW9uJwo+ID4gL29wdC90b29sY2hhaW5zL2djYy1hcm0tOC4zLTIwMTkuMDMteDg2XzY0LWFhcmNo NjQtbGludXgtZ251L2Jpbi9hYXJjaDY0LWxpbnV4LWdudS1sZDogZHJpdmVycy9maXJtd2FyZS9h cm1fc2NtaS9vcHRlZS5vOiBpbiBmdW5jdGlvbiBgb3B0ZWVfc2VydmljZV9yZW1vdmUnOgo+ID4g L2hvbWUvY3JpbWFyMDEvQVJNL2Rldi9zcmMvcGRzdy9saW51eC9kcml2ZXJzL2Zpcm13YXJlL2Fy bV9zY21pL29wdGVlLmM6NTE2OiB1bmRlZmluZWQgcmVmZXJlbmNlIHRvIGB0ZWVfY2xpZW50X2Ns b3NlX2NvbnRleHQnCj4gPiAvb3B0L3Rvb2xjaGFpbnMvZ2NjLWFybS04LjMtMjAxOS4wMy14ODZf NjQtYWFyY2g2NC1saW51eC1nbnUvYmluL2FhcmNoNjQtbGludXgtZ251LWxkOiBkcml2ZXJzL2Zp cm13YXJlL2FybV9zY21pL29wdGVlLm86IGluIGZ1bmN0aW9uIGBvcHRlZV9zZXJ2aWNlX3Byb2Jl JzoKPiA+IC9ob21lL2NyaW1hcjAxL0FSTS9kZXYvc3JjL3Bkc3cvbGludXgvZHJpdmVycy9maXJt d2FyZS9hcm1fc2NtaS9vcHRlZS5jOjQ4MTogdW5kZWZpbmVkIHJlZmVyZW5jZSB0byBgdGVlX2Ns aWVudF9vcGVuX2NvbnRleHQnCj4gPiAvb3B0L3Rvb2xjaGFpbnMvZ2NjLWFybS04LjMtMjAxOS4w My14ODZfNjQtYWFyY2g2NC1saW51eC1nbnUvYmluL2FhcmNoNjQtbGludXgtZ251LWxkOiAvaG9t ZS9jcmltYXIwMS9BUk0vZGV2L3NyYy9wZHN3L2xpbnV4L2RyaXZlcnMvZmlybXdhcmUvYXJtX3Nj bWkvb3B0ZWUuYzo1MDE6IHVuZGVmaW5lZCByZWZlcmVuY2UgdG8gYHRlZV9jbGllbnRfY2xvc2Vf Y29udGV4dCcKPiA+IC9vcHQvdG9vbGNoYWlucy9nY2MtYXJtLTguMy0yMDE5LjAzLXg4Nl82NC1h YXJjaDY0LWxpbnV4LWdudS9iaW4vYWFyY2g2NC1saW51eC1nbnUtbGQ6IGRyaXZlcnMvZmlybXdh cmUvYXJtX3NjbWkvb3B0ZWUubzogaW4gZnVuY3Rpb24gYGdldF9jYXBhYmlsaXRpZXMnOgo+ID4g L2hvbWUvY3JpbWFyMDEvQVJNL2Rldi9zcmMvcGRzdy9saW51eC9kcml2ZXJzL2Zpcm13YXJlL2Fy bV9zY21pL29wdGVlLmM6MTcyOiB1bmRlZmluZWQgcmVmZXJlbmNlIHRvIGB0ZWVfY2xpZW50X2lu dm9rZV9mdW5jJwo+ID4gL29wdC90b29sY2hhaW5zL2djYy1hcm0tOC4zLTIwMTkuMDMteDg2XzY0 LWFhcmNoNjQtbGludXgtZ251L2Jpbi9hYXJjaDY0LWxpbnV4LWdudS1sZDogZHJpdmVycy9maXJt d2FyZS9hcm1fc2NtaS9vcHRlZS5vOiBpbiBmdW5jdGlvbiBgY2xvc2Vfc2Vzc2lvbic6Cj4gPiAv aG9tZS9jcmltYXIwMS9BUk0vZGV2L3NyYy9wZHN3L2xpbnV4L2RyaXZlcnMvZmlybXdhcmUvYXJt X3NjbWkvb3B0ZWUuYzoxNTE6IHVuZGVmaW5lZCByZWZlcmVuY2UgdG8gYHRlZV9jbGllbnRfY2xv c2Vfc2Vzc2lvbicKPiA+IC9vcHQvdG9vbGNoYWlucy9nY2MtYXJtLTguMy0yMDE5LjAzLXg4Nl82 NC1hYXJjaDY0LWxpbnV4LWdudS9iaW4vYWFyY2g2NC1saW51eC1nbnUtbGQ6IGRyaXZlcnMvZmly bXdhcmUvYXJtX3NjbWkvb3B0ZWUubzogaW4gZnVuY3Rpb24gYGdldF9jaGFubmVsJzoKPiA+IC9o b21lL2NyaW1hcjAxL0FSTS9kZXYvc3JjL3Bkc3cvbGludXgvZHJpdmVycy9maXJtd2FyZS9hcm1f c2NtaS9vcHRlZS5jOjIwOTogdW5kZWZpbmVkIHJlZmVyZW5jZSB0byBgdGVlX2NsaWVudF9pbnZv a2VfZnVuYycKPiA+IC9vcHQvdG9vbGNoYWlucy9nY2MtYXJtLTguMy0yMDE5LjAzLXg4Nl82NC1h YXJjaDY0LWxpbnV4LWdudS9iaW4vYWFyY2g2NC1saW51eC1nbnUtbGQ6IGRyaXZlcnMvZmlybXdh cmUvYXJtX3NjbWkvb3B0ZWUubzogaW4gZnVuY3Rpb24gYHNldHVwX2R5bmFtaWNfc2htZW0nOgo+ ID4gL2hvbWUvY3JpbWFyMDEvQVJNL2Rldi9zcmMvcGRzdy9saW51eC9kcml2ZXJzL2Zpcm13YXJl L2FybV9zY21pL29wdGVlLmM6MjcwOiB1bmRlZmluZWQgcmVmZXJlbmNlIHRvIGB0ZWVfc2htX2Fs bG9jX2tlcm5lbF9idWYnCj4gPiAvb3B0L3Rvb2xjaGFpbnMvZ2NjLWFybS04LjMtMjAxOS4wMy14 ODZfNjQtYWFyY2g2NC1saW51eC1nbnUvYmluL2FhcmNoNjQtbGludXgtZ251LWxkOiAvaG9tZS9j cmltYXIwMS9BUk0vZGV2L3NyYy9wZHN3L2xpbnV4L2RyaXZlcnMvZmlybXdhcmUvYXJtX3NjbWkv b3B0ZWUuYzoyNzY6IHVuZGVmaW5lZCByZWZlcmVuY2UgdG8gYHRlZV9zaG1fZ2V0X3ZhJwo+ID4g L29wdC90b29sY2hhaW5zL2djYy1hcm0tOC4zLTIwMTkuMDMteDg2XzY0LWFhcmNoNjQtbGludXgt Z251L2Jpbi9hYXJjaDY0LWxpbnV4LWdudS1sZDogZHJpdmVycy9maXJtd2FyZS9hcm1fc2NtaS9v cHRlZS5vOiBpbiBmdW5jdGlvbiBgY2xvc2Vfc2Vzc2lvbic6Cj4gPiAvaG9tZS9jcmltYXIwMS9B Uk0vZGV2L3NyYy9wZHN3L2xpbnV4L2RyaXZlcnMvZmlybXdhcmUvYXJtX3NjbWkvb3B0ZWUuYzox NTE6IHVuZGVmaW5lZCByZWZlcmVuY2UgdG8gYHRlZV9jbGllbnRfY2xvc2Vfc2Vzc2lvbicKPiA+ IC9vcHQvdG9vbGNoYWlucy9nY2MtYXJtLTguMy0yMDE5LjAzLXg4Nl82NC1hYXJjaDY0LWxpbnV4 LWdudS9iaW4vYWFyY2g2NC1saW51eC1nbnUtbGQ6IGRyaXZlcnMvZmlybXdhcmUvYXJtX3NjbWkv b3B0ZWUubzooLmRhdGErMHgxMCk6IHVuZGVmaW5lZCByZWZlcmVuY2UgdG8gYHRlZV9idXNfdHlw ZScKPiA+IC9ob21lL2NyaW1hcjAxL0FSTS9kZXYvc3JjL3Bkc3cvbGludXgvTWFrZWZpbGU6MTE4 OTogcmVjaXBlIGZvciB0YXJnZXQgJ3ZtbGludXgnIGZhaWxlZAo+ID4gbWFrZVsxXTogKioqIFt2 bWxpbnV4XSBFcnJvciAxCj4gPiBtYWtlWzFdOiBMZWF2aW5nIGRpcmVjdG9yeSAnL2hvbWUvY3Jp bWFyMDEvQVJNL2Rldi9zcmMvcGRzdy9vdXRfbGludXgnCj4gPiBNYWtlZmlsZToyMTk6IHJlY2lw ZSBmb3IgdGFyZ2V0ICdfX3N1Yi1tYWtlJyBmYWlsZWQKPiA+Cj4gPiBUYWtpbmcgYSBzaW1pbGFy IGFwcHJvYWNoIHRvIFZpcnRpbywgdGhpcyBmaXhlZCBmb3IgbWUKPiA+Cj4gPiBkaWZmIC0tZ2l0 IGEvZHJpdmVycy9maXJtd2FyZS9hcm1fc2NtaS9LY29uZmlnIGIvZHJpdmVycy9maXJtd2FyZS9h cm1fc2NtaS9LY29uZmlnCj4gPiBpbmRleCA5MTA3ZTI0OTAyM2MuLjMwNzQ2MzUwMzQ5YyAxMDA2 NDQKPiA+IC0tLSBhL2RyaXZlcnMvZmlybXdhcmUvYXJtX3NjbWkvS2NvbmZpZwo+ID4gKysrIGIv ZHJpdmVycy9maXJtd2FyZS9hcm1fc2NtaS9LY29uZmlnCj4gPiBAQCAtNzksNyArNzksNyBAQCBj b25maWcgQVJNX1NDTUlfVFJBTlNQT1JUX1ZJUlRJTwo+ID4KPiA+ICBjb25maWcgQVJNX1NDTUlf VFJBTlNQT1JUX09QVEVFCj4gPiAgICAgICAgIGJvb2wgIlNDTUkgdHJhbnNwb3J0IGJhc2VkIG9u IE9QLVRFRSBzZXJ2aWNlIgo+ID4gLSAgICAgICBkZXBlbmRzIG9uIE9QVEVFCj4gPiArICAgICAg IGRlcGVuZHMgb24gT1BURUU9eSB8fCBPUFRFRT1BUk1fU0NNSV9QUk9UT0NPTAo+ID4gICAgICAg ICBzZWxlY3QgQVJNX1NDTUlfSEFWRV9UUkFOU1BPUlQKPiA+ICAgICAgICAgc2VsZWN0IEFSTV9T Q01JX0hBVkVfU0hNRU0KPiA+ICAgICAgICAgZGVmYXVsdCB5Cj4gPgo+ID4gd2hpY2ggYmFzaWNh bGx5IGRpc2FibGVzIEFSTV9TQ01JX1RSQU5TUE9SVF9PUFRFRSB3aGVuIENPTkZJR19PUFRFRT1t IEFORAo+ID4gQVJNX1NDTUlfVFJBTlNQT1JUX09QVEVFPXk6IGluIHRoaXMgc2NlbmFyaW8gaWYg VEVFIGlzID1tIHlvdSBoYXZlIHRvIGJ1aWxkCj4gPiBBUk1fU0NNSV9QUk9UT0NPTD1tIHRvbyB0 byBiZSBhYmxlIHRvIGluY2x1ZGUgQVJNX1NDTUlfVFJBTlNQT1JUX09QVEVFLgo+Cj4gRnVsbHkg bWFrZXMgc2Vuc2UgdG8gbWUuIFRoYW5rcy4gSSB1bmRlcnN0YW5kLgo+Cj4gPgo+ID4KPiA+ID4g IGNvbmZpZyBBUk1fU0NNSV9QT1dFUl9ET01BSU4KPiA+ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMv ZmlybXdhcmUvYXJtX3NjbWkvTWFrZWZpbGUgYi9kcml2ZXJzL2Zpcm13YXJlL2FybV9zY21pL01h a2VmaWxlCj4gPiA+IGluZGV4IDFkY2YxMjNkNjRhYi4uZWY2NmVjOGNhOTE3IDEwMDY0NAo+ID4g PiAtLS0gYS9kcml2ZXJzL2Zpcm13YXJlL2FybV9zY21pL01ha2VmaWxlCj4gPiA+ICsrKyBiL2Ry aXZlcnMvZmlybXdhcmUvYXJtX3NjbWkvTWFrZWZpbGUKPiA+ID4gQEAgLTYsNiArNiw3IEBAIHNj bWktdHJhbnNwb3J0LSQoQ09ORklHX0FSTV9TQ01JX1RSQU5TUE9SVF9NQUlMQk9YKSArPSBtYWls Ym94Lm8KPiA+ID4gIHNjbWktdHJhbnNwb3J0LSQoQ09ORklHX0FSTV9TQ01JX1RSQU5TUE9SVF9T TUMpICs9IHNtYy5vCj4gPiA+ICBzY21pLXRyYW5zcG9ydC0kKENPTkZJR19BUk1fU0NNSV9IQVZF X01TRykgKz0gbXNnLm8KPiA+ID4gIHNjbWktdHJhbnNwb3J0LSQoQ09ORklHX0FSTV9TQ01JX1RS QU5TUE9SVF9WSVJUSU8pICs9IHZpcnRpby5vCj4gPiA+ICtzY21pLXRyYW5zcG9ydC0kKENPTkZJ R19BUk1fU0NNSV9UUkFOU1BPUlRfT1BURUUpICs9IG9wdGVlLm8KPiA+ID4gIHNjbWktcHJvdG9j b2xzLXkgPSBiYXNlLm8gY2xvY2subyBwZXJmLm8gcG93ZXIubyByZXNldC5vIHNlbnNvcnMubyBz eXN0ZW0ubyB2b2x0YWdlLm8KPiA+ID4gIHNjbWktbW9kdWxlLW9ianMgOj0gJChzY21pLWJ1cy15 KSAkKHNjbWktZHJpdmVyLXkpICQoc2NtaS1wcm90b2NvbHMteSkgXAo+ID4gPiAgICAgICAgICAg ICAgICAgICAkKHNjbWktdHJhbnNwb3J0LXkpCj4gPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2Zp cm13YXJlL2FybV9zY21pL2NvbW1vbi5oIGIvZHJpdmVycy9maXJtd2FyZS9hcm1fc2NtaS9jb21t b24uaAo+ID4gPiBpbmRleCBkZWExYmZiZTEwNTIuLjgyZmYzYzNhNmQyZCAxMDA2NDQKPiA+ID4g LS0tIGEvZHJpdmVycy9maXJtd2FyZS9hcm1fc2NtaS9jb21tb24uaAo+ID4gPiArKysgYi9kcml2 ZXJzL2Zpcm13YXJlL2FybV9zY21pL2NvbW1vbi5oCj4gPiA+IEBAIC00MjEsNiArNDIxLDkgQEAg ZXh0ZXJuIGNvbnN0IHN0cnVjdCBzY21pX2Rlc2Mgc2NtaV9zbWNfZGVzYzsKPiA+ID4gICNpZmRl ZiBDT05GSUdfQVJNX1NDTUlfVFJBTlNQT1JUX1ZJUlRJTwo+ID4gPiAgZXh0ZXJuIGNvbnN0IHN0 cnVjdCBzY21pX2Rlc2Mgc2NtaV92aXJ0aW9fZGVzYzsKPiA+ID4gICNlbmRpZgo+ID4gPiArI2lm ZGVmIENPTkZJR19PUFRFRQo+ID4KPiA+IFRoaXMgc2hvdWxkIGJlOgo+ID4KPiA+ICNpZmRlZiBD T05GSUdfQVJNX1NDTUlfVFJBTlNQT1JUX09QVEVFCj4gPgo+ID4gaWYgbm90IGRpc2FibGluZyBP UFRFRSB0cmFuc3BvcnQgaW4gS2NvbmZpZyBicmVha3MgdGhlIGJ1aWxkLgo+ID4KPiA+ICBMRCAg ICAgIC50bXBfdm1saW51eC5rYWxsc3ltczEKPiA+ICAvb3B0L3Rvb2xjaGFpbnMvZ2NjLWFybS04 LjMtMjAxOS4wMy14ODZfNjQtYWFyY2g2NC1saW51eC1nbnUvYmluL2FhcmNoNjQtbGludXgtZ251 LWxkOgo+ID4gIGRyaXZlcnMvZmlybXdhcmUvYXJtX3NjbWkvZHJpdmVyLm86KC5yb2RhdGErMHgy ODApOiB1bmRlZmluZWQgcmVmZXJlbmNlCj4gPiAgdG8gYHNjbWlfb3B0ZWVfZGVzYycKPiA+ICAv aG9tZS9jcmltYXIwMS9BUk0vZGV2L3NyYy9wZHN3L2xpbnV4L01ha2VmaWxlOjExODk6IHJlY2lw ZSBmb3IgdGFyZ2V0Cj4gPiAgJ3ZtbGludXgnIGZhaWxlZAo+ID4gIG1ha2VbMV06ICoqKiBbdm1s aW51eF0gRXJyb3IgMQo+ID4gIG1ha2VbMV06IExlYXZpbmcgZGlyZWN0b3J5ICcvaG9tZS9jcmlt YXIwMS9BUk0vZGV2L3NyYy9wZHN3L291dF9saW51eCcKPiA+Cj4gPgo+ID4gPiArZXh0ZXJuIGNv bnN0IHN0cnVjdCBzY21pX2Rlc2Mgc2NtaV9vcHRlZV9kZXNjOwo+ID4gPiArI2VuZGlmCj4gPiA+ Cj4gPiA+ICB2b2lkIHNjbWlfcnhfY2FsbGJhY2soc3RydWN0IHNjbWlfY2hhbl9pbmZvICpjaW5m bywgdTMyIG1zZ19oZHIsIHZvaWQgKnByaXYpOwo+ID4gPiAgdm9pZCBzY21pX2ZyZWVfY2hhbm5l bChzdHJ1Y3Qgc2NtaV9jaGFuX2luZm8gKmNpbmZvLCBzdHJ1Y3QgaWRyICppZHIsIGludCBpZCk7 Cj4gPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2Zpcm13YXJlL2FybV9zY21pL2RyaXZlci5jIGIv ZHJpdmVycy9maXJtd2FyZS9hcm1fc2NtaS9kcml2ZXIuYwo+ID4gPiBpbmRleCBiNDA2YjNmNzhm NDYuLjA2ZjBhOTg0NmM3ZSAxMDA2NDQKPiA+ID4gLS0tIGEvZHJpdmVycy9maXJtd2FyZS9hcm1f c2NtaS9kcml2ZXIuYwo+ID4gPiArKysgYi9kcml2ZXJzL2Zpcm13YXJlL2FybV9zY21pL2RyaXZl ci5jCj4gPiA+IEBAIC0xOTk5LDYgKzE5OTksOSBAQCBzdGF0aWMgY29uc3Qgc3RydWN0IG9mX2Rl dmljZV9pZCBzY21pX29mX21hdGNoW10gPSB7Cj4gPiA+ICAjZW5kaWYKPiA+ID4gICNpZmRlZiBD T05GSUdfQVJNX1NDTUlfVFJBTlNQT1JUX1ZJUlRJTwo+ID4gPiAgICAgICB7IC5jb21wYXRpYmxl ID0gImFybSxzY21pLXZpcnRpbyIsIC5kYXRhID0gJnNjbWlfdmlydGlvX2Rlc2N9LAo+ID4gPiAr I2VuZGlmCj4gPiA+ICsjaWZkZWYgQ09ORklHX09QVEVFCj4gPgo+ID4gU2FtZSBhcyBhYm92ZSBz aG91bGQgYmUgI2lmIENPTkZJR19BUk1fU0NNSV9UUkFOU1BPUlRfT1BURUUKPiA+Cj4gPiA+ICsg ICAgIHsgLmNvbXBhdGlibGUgPSAibGluYXJvLHNjbWktb3B0ZWUiLCAuZGF0YSA9ICZzY21pX29w dGVlX2Rlc2MgfSwKPiA+ID4gICNlbmRpZgo+ID4gPiAgICAgICB7IC8qIFNlbnRpbmVsICovIH0s Cj4gPiA+ICB9Owo+ID4gPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9maXJtd2FyZS9hcm1fc2NtaS9v cHRlZS5jIGIvZHJpdmVycy9maXJtd2FyZS9hcm1fc2NtaS9vcHRlZS5jCj4gPiA+IG5ldyBmaWxl IG1vZGUgMTAwNjQ0Cj4gPiA+IGluZGV4IDAwMDAwMDAwMDAwMC4uZTI5NGNmZjM3YmVhCj4gPiA+ IC0tLSAvZGV2L251bGwKPiA+ID4gKysrIGIvZHJpdmVycy9maXJtd2FyZS9hcm1fc2NtaS9vcHRl ZS5jCj4gPiA+IEBAIC0wLDAgKzEsNTU5IEBACj4gPiA+ICsvLyBTUERYLUxpY2Vuc2UtSWRlbnRp ZmllcjogR1BMLTIuMAo+ID4gPiArLyoKPiA+ID4gKyAqIENvcHlyaWdodCAoQykgMjAxOS0yMDIx IExpbmFybyBMdGQuCj4gPiA+ICsgKi8KPiA+ID4gKwo+ID4gPiArI2luY2x1ZGUgPGxpbnV4L2lv Lmg+Cj4gPiA+ICsjaW5jbHVkZSA8bGludXgvb2YuaD4KPiA+ID4gKyNpbmNsdWRlIDxsaW51eC9v Zl9hZGRyZXNzLmg+Cj4gPiA+ICsjaW5jbHVkZSA8bGludXgva2VybmVsLmg+Cj4gPiA+ICsjaW5j bHVkZSA8bGludXgvbW9kdWxlLmg+Cj4gPiA+ICsjaW5jbHVkZSA8bGludXgvbXV0ZXguaD4KPiA+ ID4gKyNpbmNsdWRlIDxsaW51eC9zbGFiLmg+Cj4gPiA+ICsjaW5jbHVkZSA8bGludXgvdGVlX2Ry di5oPgo+ID4gPiArI2luY2x1ZGUgPGxpbnV4L3V1aWQuaD4KPiA+ID4gKyNpbmNsdWRlIDx1YXBp L2xpbnV4L3RlZS5oPgo+ID4gPiArCj4gPiA+ICsjaW5jbHVkZSAiY29tbW9uLmgiCj4gPiA+ICsK PiA+ID4gKyNkZWZpbmUgRFJJVkVSX05BTUUgIm9wdGVlLXNjbWkiCj4gPiA+ICsKPiA+ID4gK2Vu dW0gb3B0ZWVfc21jaV9wdGFfY21kIHsKPiA+ICAgICAgICAgICAgICAgXgo+ID4gICAgICAgICAg ICAgICBzY21pID8gb3IgaXMgaXQgYW5vdGhlciBmYW5jeSA0bGV0dGVycyBhY3JvbnltIDpECj4K PiA6KSBuaWNlIGNhdGNoIQo+Cj4gPiA+ICsgICAgIC8qCj4gPiA+ICsgICAgICAqIFBUQV9TQ01J X0NNRF9DQVBBQklMSVRJRVMgLSBHZXQgY2hhbm5lbCBjYXBhYmlsaXRpZXMKPiA+ID4gKyAgICAg ICoKPiA+ID4gKyAgICAgICogW291dF0gICAgdmFsdWVbMF0uYTogQ2FwYWJpbGl0eSBiaXQgbWFz ayAoZW51bSBwdGFfc2NtaV9jYXBzKQo+ID4gPiArICAgICAgKiBbb3V0XSAgICB2YWx1ZVswXS5i OiBFeHRlbmRlZCBjYXBhYmlsaXRpZXMgb3IgMAo+ID4gPiArICAgICAgKi8KPiA+ID4gKyAgICAg UFRBX1NDTUlfQ01EX0NBUEFCSUxJVElFUyA9IDAsCj4gPiA+ICsKPiA+ID4gKyAgICAgLyoKPiA+ ID4gKyAgICAgICogUFRBX1NDTUlfQ01EX1BST0NFU1NfU01UX0NIQU5ORUwgLSBQcm9jZXNzIFND TUkgbWVzc2FnZSBpbiBTTVQgYnVmZmVyCj4gPiA+ICsgICAgICAqCj4gPiA+ICsgICAgICAqIFtp bl0gICAgIHZhbHVlWzBdLmE6IENoYW5uZWwgaGFuZGxlCj4gPiA+ICsgICAgICAqCj4gPiA+ICsg ICAgICAqIFNoYXJlZCBtZW1vcnkgdXNlZCBmb3IgU0NNSSBtZXNzYWdlL3Jlc3BvbnNlIGV4aGFu Z2UgaXMgZXhwZWN0ZWQKPiA+ID4gKyAgICAgICogYWxyZWFkeSBpZGVudGlmaWVkIGFuZCBib3Vu ZCB0byBjaGFubmVsIGhhbmRsZSBpbiBib3RoIFNDTUkgYWdlbnQKPiA+ID4gKyAgICAgICogYW5k IFNDTUkgc2VydmVyIChPUC1URUUpIHBhcnRzLgo+ID4gPiArICAgICAgKiBUaGUgbWVtb3J5IHVz ZXMgU01UIGhlYWRlciB0byBjYXJyeSBTQ01JIG1ldGEtZGF0YSAocHJvdG9jb2wgSUQgYW5kCj4g PiA+ICsgICAgICAqIHByb3RvY29sIG1lc3NhZ2UgSUQpLgo+ID4gPiArICAgICAgKi8KPiA+ID4g KyAgICAgUFRBX1NDTUlfQ01EX1BST0NFU1NfU01UX0NIQU5ORUwgPSAxLAo+ID4gPiArCj4gPiA+ ICsgICAgIC8qCj4gPiA+ICsgICAgICAqIFBUQV9TQ01JX0NNRF9QUk9DRVNTX1NNVF9DSEFOTkVM X01FU1NBR0UgLSBQcm9jZXNzIFNNVC9TQ01JIG1lc3NhZ2UKPiA+ID4gKyAgICAgICoKPiA+ID4g KyAgICAgICogW2luXSAgICAgdmFsdWVbMF0uYTogQ2hhbm5lbCBoYW5kbGUKPiA+ID4gKyAgICAg ICogW2luL291dF0gbWVtcmVmWzFdOiBNZXNzYWdlL3Jlc3BvbnNlIGJ1ZmZlciAoU01UIGFuZCBT Q01JIHBheWxvYWQpCj4gPiA+ICsgICAgICAqCj4gPiA+ICsgICAgICAqIFNoYXJlZCBtZW1vcnkg dXNlZCBmb3IgU0NNSSBtZXNzYWdlL3Jlc3BvbnNlIGlzIGEgU01UIGJ1ZmZlcgo+ID4gPiArICAg ICAgKiByZWZlcmVuY2VkIGJ5IHBhcmFtWzFdLiBJdCBzaGFsbCBiZSAxMjggYnl0ZXMgbGFyZ2Ug dG8gZml0IHJlc3BvbnNlCj4gPiA+ICsgICAgICAqIHBheWxvYWQgd2hhdGV2ZXIgbWVzc2FnZSBw bGF5bG9hZCBzaXplLgo+ID4gPiArICAgICAgKiBUaGUgbWVtb3J5IHVzZXMgU01UIGhlYWRlciB0 byBjYXJyeSBTQ01JIG1ldGEtZGF0YSAocHJvdG9jb2wgSUQgYW5kCj4gPiA+ICsgICAgICAqIHBy b3RvY29sIG1lc3NhZ2UgSUQpLgo+ID4gPiArICAgICAgKi8KPiA+ID4gKyAgICAgUFRBX1NDTUlf Q01EX1BST0NFU1NfU01UX0NIQU5ORUxfTUVTU0FHRSA9IDIsCj4gPiA+ICsKPiA+ID4gKyAgICAg LyoKPiA+ID4gKyAgICAgICogUFRBX1NDTUlfQ01EX0dFVF9DSEFOTkVMIC0gR2V0IGNoYW5uZWwg aGFuZGxlCj4gPiA+ICsgICAgICAqCj4gPiA+ICsgICAgICAqIFNDTUkgc2htIGluZm9ybWF0aW9u IGFyZSAwIGlmIGFnZW50IGV4cGVjdHMgdG8gdXNlIE9QLVRFRSByZWd1bGFyIFNITQo+ID4gPiAr ICAgICAgKgo+ID4gPiArICAgICAgKiBbaW5dICAgICB2YWx1ZVswXS5hOiBDaGFubmVsIGlkZW50 aWZpZXIKPiA+ID4gKyAgICAgICogW291dF0gICAgdmFsdWVbMF0uYTogUmV0dXJuZWQgY2hhbm5l bCBoYW5kbGUKPiA+ID4gKyAgICAgICogW2luXSAgICAgdmFsdWVbMF0uYjogUmVxdWVzdGVkIGNh cGFiaWxpdGllcyBtYXNrIChlbnVtIHB0YV9zY21pX2NhcHMpCj4gPiA+ICsgICAgICAqLwo+ID4g PiArICAgICBQVEFfU0NNSV9DTURfR0VUX0NIQU5ORUwgPSAzLAo+ID4gPiArfTsKPiA+ID4gKwo+ ID4gPiArLyoKPiA+ID4gKyAqIENhcGFiaWxpdGllcwo+ID4gPiArICovCj4gPiA+ICtlbnVtIHB0 YV9zY21pX2NhcHMgewo+ID4gPiArICAgICBQVEFfU0NNSV9DQVBTX05PTkUgPSAwLAo+ID4gPiAr ICAgICAvKgo+ID4gPiArICAgICAgKiBTdXBwb3J0cyBjb21tYW5kIHVzaW5nIFNNVCBoZWFkZXIg cHJvdG9jb2wgKFNDTUkgc2htZW0pIGluIHNoYXJlZAo+ID4gPiArICAgICAgKiBtZW1vcnkgYnVm ZmVycyB0byBjYXJyeSBTQ01JIHByb3RvY29sIHN5bmNocm9uaXNhdGlvbiBpbmZvcm1hdGlvbi4K PiA+ID4gKyAgICAgICovCj4gPiA+ICsgICAgIFBUQV9TQ01JX0NBUFNfU01UX0hFQURFUiA9IEJJ VCgwKSwKPiA+ID4gK307Cj4gPiA+ICsKPiA+ID4gKy8qKgo+ID4gPiArICogc3RydWN0IG9wdGVl X2NoYW5uZWwgLSBEZXNjcmlwdGlvbiBvZiBhbiBPUC1URUUgU0NNSSBjaGFubmVsCj4gPiA+ICsg Kgo+ID4gPiArICogQGNoYW5uZWxfaWQ6IE9QLVRFRSBjaGFubmVsIElEIHVzZWQgZm9yIHRoaXMg dHJhbnNwb3J0Cj4gPiA+ICsgKiBAbXU6IE11dGV4IHByb3RlY3Rpb24gb24gY2hhbm5lbCBhY2Nl c3MKPiA+ID4gKyAqIEB0ZWVfc2Vzc2lvbjogVEVFIHNlc3Npb24gaWRlbnRpZmllcgo+ID4gPiAr ICogQGNpbmZvOiBTQ01JIGNoYW5uZWwgaW5mb3JtYXRpb24KPiA+ID4gKyAqIEBzaG1lbTogVmly dHVhbCBiYXNlIGFkZHJlc3Mgb2YgdGhlIHNoYXJlZCBtZW1vcnkKPiA+ID4gKyAqIEB0ZWVfc2ht OiBSZWZlcmVuY2UgdG8gVEVFIHNoYXJlZCBtZW1vcnkgb3IgTlVMTCBpZiB1c2luZyBzdGF0aWMg c2htZW0KPiA+ID4gKyAqIEBjYXBzOiBPUC1URUUgU0NNSSBjaGFubmVsIGNhcGFiaWxpdGllcwo+ ID4gPiArICogQGxpbms6IFJlZmVyZW5jZSBpbiBhZ2VudCdzIGNoYW5uZWwgbGlzdAo+ID4gPiAr ICovCj4gPiA+ICtzdHJ1Y3Qgb3B0ZWVfY2hhbm5lbCB7Cj4gPiA+ICsgICAgIHUzMiBjaGFubmVs X2lkOwo+ID4gPiArICAgICBzdHJ1Y3QgbXV0ZXggbXU7Cj4gPiA+ICsgICAgIHUzMiB0ZWVfc2Vz c2lvbjsKPiA+ID4gKyAgICAgc3RydWN0IHNjbWlfY2hhbl9pbmZvICpjaW5mbzsKPiA+ID4gKyAg ICAgc3RydWN0IHNjbWlfc2hhcmVkX21lbSBfX2lvbWVtICpzaG1lbTsKPiA+ID4gKyAgICAgc3Ry dWN0IHRlZV9zaG0gKnRlZV9zaG07Cj4gPiA+ICsgICAgIGVudW0gcHRhX3NjbWlfY2FwcyBjYXBz Owo+ID4gPiArICAgICBzdHJ1Y3QgbGlzdF9oZWFkIGxpbms7Cj4gPiA+ICt9Owo+ID4gPiArCj4g PiA+ICsvKioKPiA+ID4gKyAqIHN0cnVjdCBvcHRlZV9hZ2VudCAtIE9QLVRFRSB0cmFuc3BvcnQg cHJpdmF0ZSBkYXRhCj4gPiA+ICsgKgo+ID4gPiArICogQGRldjogRGV2aWNlIHVzZWQgZm9yIGNv bW11bmljYXRpb24gd2l0aCBURUUKPiA+ID4gKyAqIEB0ZWVfY3R4OiBURUUgY29udGV4dCB1c2Vk IGZvciBjb21tdW5pY2F0aW9uCj4gPiA+ICsgKiBAY2FwczogU3VwcG9ydGVkIGNoYW5uZWwgY2Fw YWJpbGl0aWVzCj4gPiA+ICsgKiBAbXU6IE11dGV4IGZvciBwcm90ZWN0aW9uIG9mIEBjaGFubmVs X2xpc3QKPiA+ID4gKyAqIEBjaGFubmVsX2xpc3Q6IExpc3Qgb2YgYWxsIGNyZWF0ZWQgY2hhbm5l bHMgZm9yIHRoZSBhZ2VudAo+ID4gPiArICovCj4gPiA+ICtzdHJ1Y3Qgb3B0ZWVfYWdlbnQgewo+ ID4gPiArICAgICBzdHJ1Y3QgZGV2aWNlICpkZXY7Cj4gPiA+ICsgICAgIHN0cnVjdCB0ZWVfY29u dGV4dCAqdGVlX2N0eDsKPiA+ID4gKyAgICAgZW51bSBwdGFfc2NtaV9jYXBzIGNhcHM7Cj4gPiA+ ICsgICAgIHN0cnVjdCBtdXRleCBtdTsKPiA+ID4gKyAgICAgc3RydWN0IGxpc3RfaGVhZCBjaGFu bmVsX2xpc3Q7Cj4gPiA+ICt9Owo+ID4gPiArCj4gPiA+ICsvKiBUaGVyZSBjYW4gYmUgb25seSAx IFNDTUkgc2VydmljZSBpbiBPUC1URUUgd2UgY29ubmVjdCB0byAqLwo+ID4gPiArc3RhdGljIHN0 cnVjdCBvcHRlZV9hZ2VudCAqb3B0ZWVfcHJpdmF0ZTsKPiA+ID4gKwo+ID4KPiA+IE1heWJlIG5h bWluZyB0aGVzZSBsb2NhbGx5IGRlZmluZWQgb3B0ZWVfIHN0cnVjdHMgYXMgc2NtaV9vcHRlZV8g Pwo+ID4KPiA+IFdoZW4gSSBzZWUgdGhvc2Ugb3B0ZWVfIHJlZnMgYXJvdW5kIGRvd24gYmVsb3cg SSB0ZW5kIHRvIHRoaW5rIHRoZXkKPiA+IGFyZSBPUFRFRSBjb3JlIHN0cnVjdHMgbm90IGxvY2Fs bHkgZGVmaW5lZCBjb250YWluZXJzLgo+ID4gKEkgdWRlcnN0YW5kIHRoYXQgZGVwZW5kcyBvbiBt eSBwb29yIGZhbWlsaWFyaXR5IHdpdGggT1BURUUgQVBJcwo+ID4gdGhvdWdoLi4uKQo+Cj4gT2su IElmIHRoYXQgaGVscCBtYWludGVuYW5jZSwgSSdtIGZpbmUuIEknbGwgdXNlIHNjbWlfb3B0ZWVf IHdoZXJlIGFwcGlpY2FibGUuCj4KPgo+ID4KPiA+ID4gKy8qIE9wZW4gYSBzZXNzaW9uIHRvd2Fy ZCBTQ01JIE9QLVRFRSBzZXJ2aWNlIHdpdGggUkVFX0tFUk5FTCBpZGVudGl0eSAqLwo+ID4gPiAr c3RhdGljIGludCBvcGVuX3Nlc3Npb24odTMyICp0ZWVfc2Vzc2lvbikKPiA+ID4gK3sKPiA+ID4g KyAgICAgc3RydWN0IGRldmljZSAqZGV2ID0gb3B0ZWVfcHJpdmF0ZS0+ZGV2Owo+ID4gPiArICAg ICBzdHJ1Y3QgdGVlX2NsaWVudF9kZXZpY2UgKnNjbWlfcHRhID0gdG9fdGVlX2NsaWVudF9kZXZp Y2UoZGV2KTsKPiA+ID4gKyAgICAgc3RydWN0IHRlZV9pb2N0bF9vcGVuX3Nlc3Npb25fYXJnIGFy ZyA9IHsgfTsKPiA+ID4gKyAgICAgaW50IHJldDsKPiA+ID4gKwo+ID4gPiArICAgICBtZW1jcHko YXJnLnV1aWQsIHNjbWlfcHRhLT5pZC51dWlkLmIsIFRFRV9JT0NUTF9VVUlEX0xFTik7Cj4gPiA+ ICsgICAgIGFyZy5jbG50X2xvZ2luID0gVEVFX0lPQ1RMX0xPR0lOX1JFRV9LRVJORUw7Cj4gPiA+ ICsKPiA+ID4gKyAgICAgcmV0ID0gdGVlX2NsaWVudF9vcGVuX3Nlc3Npb24ob3B0ZWVfcHJpdmF0 ZS0+dGVlX2N0eCwgJmFyZywgTlVMTCk7Cj4gPiA+ICsgICAgIGlmIChyZXQgPCAwIHx8IGFyZy5y ZXQpIHsKPiA+ID4gKyAgICAgICAgICAgICBkZXZfZXJyKGRldiwgIkNhbid0IG9wZW4gdGVlIHNl c3Npb246ICVkIC8gJSN4XG4iLCByZXQsIGFyZy5yZXQpOwo+ID4gPiArCj4gPiA+ICsgICAgICAg ICAgICAgcmV0dXJuIC1FT1BOT1RTVVBQOwo+ID4gPiArICAgICB9Cj4gPiA+ICsKPiA+ID4gKyAg ICAgKnRlZV9zZXNzaW9uID0gYXJnLnNlc3Npb247Cj4gPiA+ICsKPiA+ID4gKyAgICAgcmV0dXJu IDA7Cj4gPiA+ICt9Cj4gPiA+ICsKPiA+ID4gK3N0YXRpYyB2b2lkIGNsb3NlX3Nlc3Npb24odTMy IHRlZV9zZXNzaW9uKQo+ID4gPiArewo+ID4gPiArICAgICB0ZWVfY2xpZW50X2Nsb3NlX3Nlc3Np b24ob3B0ZWVfcHJpdmF0ZS0+dGVlX2N0eCwgdGVlX3Nlc3Npb24pOwo+ID4gPiArfQo+ID4gPiAr Cj4gPiA+ICtzdGF0aWMgaW50IGdldF9jYXBhYmlsaXRpZXModm9pZCkKPiA+ID4gK3sKPiA+ID4g KyAgICAgc3RydWN0IG9wdGVlX2FnZW50ICphZ2VudCA9IG9wdGVlX3ByaXZhdGU7Cj4gPiA+ICsg ICAgIHN0cnVjdCB0ZWVfaW9jdGxfaW52b2tlX2FyZyBhcmcgPSB7IH07Cj4gPiA+ICsgICAgIHN0 cnVjdCB0ZWVfcGFyYW0gcGFyYW1bMV0gPSB7IH07Cj4gPiA+ICsgICAgIHUzMiB0ZWVfc2Vzc2lv bjsKPiA+ID4gKyAgICAgaW50IHJldDsKPiA+ID4gKwo+ID4gPiArICAgICByZXQgPSBvcGVuX3Nl c3Npb24oJnRlZV9zZXNzaW9uKTsKPiA+ID4gKyAgICAgaWYgKHJldCkKPiA+ID4gKyAgICAgICAg ICAgICByZXR1cm4gcmV0Owo+ID4gPiArCj4gPiA+ICsgICAgIGFyZy5mdW5jID0gUFRBX1NDTUlf Q01EX0NBUEFCSUxJVElFUzsKPiA+ID4gKyAgICAgYXJnLnNlc3Npb24gPSB0ZWVfc2Vzc2lvbjsK PiA+ID4gKyAgICAgYXJnLm51bV9wYXJhbXMgPSAxOwo+ID4gPiArCj4gPiA+ICsgICAgIHBhcmFt WzBdLmF0dHIgPSBURUVfSU9DVExfUEFSQU1fQVRUUl9UWVBFX1ZBTFVFX09VVFBVVDsKPiA+ID4g Kwo+ID4gPiArICAgICByZXQgPSB0ZWVfY2xpZW50X2ludm9rZV9mdW5jKGFnZW50LT50ZWVfY3R4 LCAmYXJnLCBwYXJhbSk7Cj4gPiA+ICsKPiA+ID4gKyAgICAgY2xvc2Vfc2Vzc2lvbih0ZWVfc2Vz c2lvbik7Cj4gPiA+ICsKPiA+ID4gKyAgICAgaWYgKHJldCA8IDAgfHwgYXJnLnJldCkgewo+ID4g PiArICAgICAgICAgICAgIGRldl9lcnIoYWdlbnQtPmRldiwgIkNhbid0IGdldCBjYXBhYmlsaXRp ZXM6ICVkIC8gJSN4XG4iLCByZXQsIGFyZy5yZXQpOwo+ID4gPiArCj4gPiA+ICsgICAgICAgICAg ICAgcmV0dXJuIC1FT1BOT1RTVVBQOwo+ID4gPiArICAgICB9Cj4gPiA+ICsKPiA+ID4gKyAgICAg YWdlbnQtPmNhcHMgPSBwYXJhbVswXS51LnZhbHVlLmE7Cj4gPiA+ICsKPiA+ID4gKyAgICAgaWYg KCEoYWdlbnQtPmNhcHMgJiBQVEFfU0NNSV9DQVBTX1NNVF9IRUFERVIpKSB7Cj4gPiA+ICsgICAg ICAgICAgICAgZGV2X2VycihhZ2VudC0+ZGV2LCAiT1AtVEVFIFNDTUkgUFRBIGRvZXNuJ3Qgc3Vw cG9ydCBTTVRcbiIpOwo+ID4gPiArCj4gPiA+ICsgICAgICAgICAgICAgcmV0dXJuIC1FT1BOT1RT VVBQOwo+ID4gPiArICAgICB9Cj4gPiA+ICsKPiA+ID4gKyAgICAgcmV0dXJuIDA7Cj4gPiA+ICt9 Cj4gPiA+ICsKPiA+ID4gK3N0YXRpYyBpbnQgZ2V0X2NoYW5uZWwoc3RydWN0IG9wdGVlX2NoYW5u ZWwgKmNoYW5uZWwpCj4gPiA+ICt7Cj4gPiA+ICsgICAgIHN0cnVjdCBkZXZpY2UgKmRldiA9IG9w dGVlX3ByaXZhdGUtPmRldjsKPiA+ID4gKyAgICAgc3RydWN0IHRlZV9pb2N0bF9pbnZva2VfYXJn IGFyZyA9IHsgfTsKPiA+ID4gKyAgICAgc3RydWN0IHRlZV9wYXJhbSBwYXJhbVsxXSA9IHsgfTsK PiA+ID4gKyAgICAgdW5zaWduZWQgaW50IGNhcHMgPSBQVEFfU0NNSV9DQVBTX1NNVF9IRUFERVI7 Cj4gPiA+ICsgICAgIGludCByZXQ7Cj4gPiA+ICsKPiA+ID4gKyAgICAgYXJnLmZ1bmMgPSBQVEFf U0NNSV9DTURfR0VUX0NIQU5ORUw7Cj4gPiA+ICsgICAgIGFyZy5zZXNzaW9uID0gY2hhbm5lbC0+ dGVlX3Nlc3Npb247Cj4gPiA+ICsgICAgIGFyZy5udW1fcGFyYW1zID0gMTsKPiA+ID4gKwo+ID4g PiArICAgICBwYXJhbVswXS5hdHRyID0gVEVFX0lPQ1RMX1BBUkFNX0FUVFJfVFlQRV9WQUxVRV9J Tk9VVDsKPiA+ID4gKyAgICAgcGFyYW1bMF0udS52YWx1ZS5hID0gY2hhbm5lbC0+Y2hhbm5lbF9p ZDsKPiA+ID4gKyAgICAgcGFyYW1bMF0udS52YWx1ZS5iID0gY2FwczsKPiA+ID4gKwo+ID4gPiAr ICAgICByZXQgPSB0ZWVfY2xpZW50X2ludm9rZV9mdW5jKG9wdGVlX3ByaXZhdGUtPnRlZV9jdHgs ICZhcmcsIHBhcmFtKTsKPiA+ID4gKwo+ID4gPiArICAgICBpZiAocmV0IHx8IGFyZy5yZXQpIHsK PiA+ID4gKyAgICAgICAgICAgICBkZXZfZXJyKGRldiwgIkNhbid0IGdldCBjaGFubmVsIHdpdGgg Y2FwcyAlI3g6ICVkIC8gJSN4XG4iLCBjYXBzLCByZXQsIGFyZy5yZXQpOwo+ID4gPiArCj4gPiA+ ICsgICAgICAgICAgICAgcmV0dXJuIC1FT1BOT1RTVVBQOwo+ID4gPiArICAgICB9Cj4gPiA+ICsK PiA+ID4gKyAgICAgLyogRnJvbSBub3cgb24gdXNlIGNoYW5uZWwgaWRlbnRpZmVyIHByb3ZpZGVk IGJ5IE9QLVRFRSBTQ01JIHNlcnZpY2UgKi8KPiA+ID4gKyAgICAgY2hhbm5lbC0+Y2hhbm5lbF9p ZCA9IHBhcmFtWzBdLnUudmFsdWUuYTsKPiA+ID4gKyAgICAgY2hhbm5lbC0+Y2FwcyA9IGNhcHM7 Cj4gPiA+ICsKPiA+ID4gKyAgICAgcmV0dXJuIDA7Cj4gPiA+ICt9Cj4gPiA+ICsKPiA+ID4gK3N0 YXRpYyBpbnQgaW52b2tlX3Byb2Nlc3Nfc210X2NoYW5uZWwoc3RydWN0IG9wdGVlX2NoYW5uZWwg KmNoYW5uZWwpCj4gPiA+ICt7Cj4gPiA+ICsgICAgIHN0cnVjdCB0ZWVfaW9jdGxfaW52b2tlX2Fy ZyBhcmcgPSB7IH07Cj4gPiA+ICsgICAgIHN0cnVjdCB0ZWVfcGFyYW0gcGFyYW1bMl0gPSB7IH07 Cj4gPiA+ICsgICAgIGludCByZXQ7Cj4gPiA+ICsKPiA+ID4gKyAgICAgYXJnLnNlc3Npb24gPSBj aGFubmVsLT50ZWVfc2Vzc2lvbjsKPiA+ID4gKyAgICAgcGFyYW1bMF0uYXR0ciA9IFRFRV9JT0NU TF9QQVJBTV9BVFRSX1RZUEVfVkFMVUVfSU5QVVQ7Cj4gPiA+ICsgICAgIHBhcmFtWzBdLnUudmFs dWUuYSA9IGNoYW5uZWwtPmNoYW5uZWxfaWQ7Cj4gPiA+ICsKPiA+ID4gKyAgICAgaWYgKGNoYW5u ZWwtPnRlZV9zaG0pIHsKPiA+ID4gKyAgICAgICAgICAgICBjb25zdCBzaXplX3QgbXNnX3NpemUg PSBzY21pX29wdGVlX2Rlc2MubWF4X21zZ19zaXplOwo+ID4gPiArCj4gPiA+ICsgICAgICAgICAg ICAgcGFyYW1bMV0uYXR0ciA9IFRFRV9JT0NUTF9QQVJBTV9BVFRSX1RZUEVfTUVNUkVGX0lOT1VU Owo+ID4gPiArICAgICAgICAgICAgIHBhcmFtWzFdLnUubWVtcmVmLnNobSA9IGNoYW5uZWwtPnRl ZV9zaG07Cj4gPiA+ICsgICAgICAgICAgICAgcGFyYW1bMV0udS5tZW1yZWYuc2l6ZSA9IG1zZ19z aXplOwo+ID4gPiArICAgICAgICAgICAgIGFyZy5udW1fcGFyYW1zID0gMjsKPiA+ID4gKyAgICAg ICAgICAgICBhcmcuZnVuYyA9IFBUQV9TQ01JX0NNRF9QUk9DRVNTX1NNVF9DSEFOTkVMX01FU1NB R0U7Cj4gPiA+ICsgICAgIH0gZWxzZSB7Cj4gPiA+ICsgICAgICAgICAgICAgYXJnLm51bV9wYXJh bXMgPSAxOwo+ID4gPiArICAgICAgICAgICAgIGFyZy5mdW5jID0gUFRBX1NDTUlfQ01EX1BST0NF U1NfU01UX0NIQU5ORUw7Cj4gPiA+ICsgICAgIH0KPiA+ID4gKwo+ID4gPiArICAgICByZXQgPSB0 ZWVfY2xpZW50X2ludm9rZV9mdW5jKG9wdGVlX3ByaXZhdGUtPnRlZV9jdHgsICZhcmcsIHBhcmFt KTsKPiA+ID4gKyAgICAgaWYgKHJldCA8IDAgfHwgYXJnLnJldCkgewo+ID4gPiArICAgICAgICAg ICAgIGRldl9lcnIob3B0ZWVfcHJpdmF0ZS0+ZGV2LCAiRmFpbGVkIG9uIGNoYW5uZWwgJXU6ICVk IC8gJSN4XG4iLAo+ID4gPiArICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbC0+Y2hhbm5lbF9p ZCwgcmV0LCBhcmcucmV0KTsKPiA+ID4gKwo+ID4gPiArICAgICAgICAgICAgIHJldHVybiAtRUlP Owo+ID4gPiArICAgICB9Cj4gPiA+ICsKPiA+ID4gKyAgICAgcmV0dXJuIDA7Cj4gPiA+ICt9Cj4g PiA+ICsKPiA+ID4gK3N0YXRpYyBib29sIG9wdGVlX2NoYW5fYXZhaWxhYmxlKHN0cnVjdCBkZXZp Y2UgKmRldiwgaW50IGlkeCkKPiA+ID4gK3sKPiA+ID4gKyAgICAgdTMyIGNoYW5uZWxfaWQ7Cj4g PiA+ICsKPiA+ID4gKyAgICAgcmV0dXJuICFvZl9wcm9wZXJ0eV9yZWFkX3UzMl9pbmRleChkZXYt Pm9mX25vZGUsICJsaW5hcm8sb3B0ZWUtY2hhbm5lbC1pZCIsCj4gPiA+ICsgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgaWR4LCAmY2hhbm5lbF9pZCk7Cj4gPiA+ICt9Cj4g PiA+ICsKPiA+ID4gK3N0YXRpYyBpbnQgc2V0dXBfZHluYW1pY19zaG1lbShzdHJ1Y3QgZGV2aWNl ICpkZXYsIHN0cnVjdCBvcHRlZV9jaGFubmVsICpjaGFubmVsKQo+ID4gPiArewo+ID4gPiArICAg ICBjb25zdCBzaXplX3QgbXNnX3NpemUgPSBzY21pX29wdGVlX2Rlc2MubWF4X21zZ19zaXplOwo+ ID4gPiArCj4gPiA+ICsgICAgIGNoYW5uZWwtPnRlZV9zaG0gPSB0ZWVfc2htX2FsbG9jX2tlcm5l bF9idWYob3B0ZWVfcHJpdmF0ZS0+dGVlX2N0eCwgbXNnX3NpemUpOwo+ID4gPiArICAgICBpZiAo SVNfRVJSKGNoYW5uZWwtPnRlZV9zaG0pKSB7Cj4gPiA+ICsgICAgICAgICAgICAgZGV2X2Vycihj aGFubmVsLT5jaW5mby0+ZGV2LCAic2htZW0gYWxsb2NhdGlvbiBmYWlsZWRcbiIpOwo+ID4gPiAr ICAgICAgICAgICAgIHJldHVybiAtRU5PTUVNOwo+ID4gPiArICAgICB9Cj4gPiA+ICsKPiA+ID4g KyAgICAgY2hhbm5lbC0+c2htZW0gPSAodm9pZCAqKXRlZV9zaG1fZ2V0X3ZhKGNoYW5uZWwtPnRl ZV9zaG0sIDApOwo+ID4gPiArICAgICBtZW1zZXQoY2hhbm5lbC0+c2htZW0sIDAsIG1zZ19zaXpl KTsKPiA+ID4gKyAgICAgc2htZW1fY2xlYXJfY2hhbm5lbChjaGFubmVsLT5zaG1lbSk7Cj4gPiA+ ICsKPiA+ID4gKyAgICAgcmV0dXJuIDA7Cj4gPiA+ICt9Cj4gPiA+ICsKPiA+ID4gK3N0YXRpYyBp bnQgc2V0dXBfc3RhdGljX3NobWVtKHN0cnVjdCBkZXZpY2UgKmRldiwgc3RydWN0IHNjbWlfY2hh bl9pbmZvICpjaW5mbywKPiA+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCBv cHRlZV9jaGFubmVsICpjaGFubmVsKQo+ID4gPiArewo+ID4gPiArICAgICBzdHJ1Y3QgZGV2aWNl X25vZGUgKm5wOwo+ID4gPiArICAgICByZXNvdXJjZV9zaXplX3Qgc2l6ZTsKPiA+ID4gKyAgICAg c3RydWN0IHJlc291cmNlIHJlczsKPiA+ID4gKyAgICAgaW50IHJldDsKPiA+ID4gKwo+ID4gPiAr ICAgICBucCA9IG9mX3BhcnNlX3BoYW5kbGUoY2luZm8tPmRldi0+b2Zfbm9kZSwgInNobWVtIiwg MCk7Cj4gPiA+ICsgICAgIGlmICghb2ZfZGV2aWNlX2lzX2NvbXBhdGlibGUobnAsICJhcm0sc2Nt aS1zaG1lbSIpKSB7Cj4gPiA+ICsgICAgICAgICAgICAgcmV0ID0gLUVOWElPOwo+ID4gPiArICAg ICAgICAgICAgIGdvdG8gb3V0Owo+ID4gPiArICAgICB9Cj4gPiA+ICsKPiA+ID4gKyAgICAgcmV0 ID0gb2ZfYWRkcmVzc190b19yZXNvdXJjZShucCwgMCwgJnJlcyk7Cj4gPiA+ICsgICAgIGlmIChy ZXQpIHsKPiA+ID4gKyAgICAgICAgICAgICBkZXZfZXJyKGRldiwgIkZhaWxlZCB0byBnZXQgU0NN SSBUeCBzaGFyZWQgbWVtb3J5XG4iKTsKPiA+ID4gKyAgICAgICAgICAgICBnb3RvIG91dDsKPiA+ ID4gKyAgICAgfQo+ID4gPiArCj4gPiA+ICsgICAgIHNpemUgPSByZXNvdXJjZV9zaXplKCZyZXMp Owo+ID4gPiArCj4gPiA+ICsgICAgIGNoYW5uZWwtPnNobWVtID0gZGV2bV9pb3JlbWFwKGRldiwg cmVzLnN0YXJ0LCBzaXplKTsKPiA+ID4gKyAgICAgaWYgKCFjaGFubmVsLT5zaG1lbSkgewo+ID4g PiArICAgICAgICAgICAgIGRldl9lcnIoZGV2LCAiRmFpbGVkIHRvIGlvcmVtYXAgU0NNSSBUeCBz aGFyZWQgbWVtb3J5XG4iKTsKPiA+ID4gKyAgICAgICAgICAgICByZXQgPSAtRUFERFJOT1RBVkFJ TDsKPiA+ID4gKyAgICAgICAgICAgICBnb3RvIG91dDsKPiA+ID4gKyAgICAgfQo+ID4gPiArCj4g PiA+ICsgICAgIHJldCA9IDA7Cj4gPiA+ICsKPiA+ID4gK291dDoKPiA+ID4gKyAgICAgb2Zfbm9k ZV9wdXQobnApOwo+ID4gPiArCj4gPiA+ICsgICAgIHJldHVybiByZXQ7Cj4gPiA+ICt9Cj4gPiA+ ICsKPiA+ID4gK3N0YXRpYyBpbnQgb3B0ZWVfY2hhbl9zZXR1cF9zaG1lbShzdHJ1Y3QgZGV2aWNl ICpkZXYsIHN0cnVjdCBzY21pX2NoYW5faW5mbyAqY2luZm8sCj4gPiA+ICsgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgYm9vbCB0eCwgc3RydWN0IG9wdGVlX2NoYW5uZWwgKmNoYW5uZWwp Cj4gPiA+ICt7Cj4gPiA+ICsgICAgIHN0cnVjdCBkZXZpY2UgKmNkZXYgPSBjaW5mby0+ZGV2Owo+ ID4gPiArCj4gPiA+ICsgICAgIGlmIChvZl9maW5kX3Byb3BlcnR5KGNkZXYtPm9mX25vZGUsICJz aG1lbSIsIE5VTEwpKQo+ID4gPiArICAgICAgICAgICAgIHJldHVybiBzZXR1cF9zdGF0aWNfc2ht ZW0oZGV2LCBjaW5mbywgY2hhbm5lbCk7Cj4gPiA+ICsgICAgIGVsc2UKPiA+ID4gKyAgICAgICAg ICAgICByZXR1cm4gc2V0dXBfZHluYW1pY19zaG1lbShkZXYsIGNoYW5uZWwpOwo+ID4gPiArfQo+ ID4gPiArCj4gPiA+ICtzdGF0aWMgdm9pZCBvcHRlZV9jbGVhcl9jaGFubmVsKHN0cnVjdCBzY21p X2NoYW5faW5mbyAqY2luZm8pCj4gPiA+ICt7Cj4gPiA+ICsgICAgIHN0cnVjdCBvcHRlZV9jaGFu bmVsICpjaGFubmVsID0gY2luZm8tPnRyYW5zcG9ydF9pbmZvOwo+ID4gPiArCj4gPiA+ICsgICAg IHNobWVtX2NsZWFyX2NoYW5uZWwoY2hhbm5lbC0+c2htZW0pOwo+ID4gPiArfQo+ID4gPiArCj4g PiA+ICtzdGF0aWMgaW50IG9wdGVlX2NoYW5fc2V0dXAoc3RydWN0IHNjbWlfY2hhbl9pbmZvICpj aW5mbywgc3RydWN0IGRldmljZSAqZGV2LCBib29sIHR4KQo+ID4gPiArewo+ID4gPiArICAgICBz dHJ1Y3Qgb3B0ZWVfY2hhbm5lbCAqY2hhbm5lbDsKPiA+ID4gKyAgICAgdWludDMyX3QgY2hhbm5l bF9pZDsKPiA+ID4gKyAgICAgaW50IHJldDsKPiA+ID4gKwo+ID4gPiArICAgICBpZiAoIXR4KQo+ ID4gPiArICAgICAgICAgICAgIHJldHVybiAtRU5PREVWOwo+ID4gPiArCj4gPiA+ICsgICAgIC8q IFNoYWxsIHdhaXQgZm9yIE9QLVRFRSBkcml2ZXIgdG8gYmUgdXAgYW5kIHJlYWR5ICovCj4gPiA+ ICsgICAgIGlmICghb3B0ZWVfcHJpdmF0ZSB8fCAhb3B0ZWVfcHJpdmF0ZS0+dGVlX2N0eCkKPiA+ ID4gKyAgICAgICAgICAgICByZXR1cm4gLUVQUk9CRV9ERUZFUjsKPiA+ID4gKwo+ID4gPiArICAg ICBjaGFubmVsID0gZGV2bV9remFsbG9jKGRldiwgc2l6ZW9mKCpjaGFubmVsKSwgR0ZQX0tFUk5F TCk7Cj4gPiA+ICsgICAgIGlmICghY2hhbm5lbCkKPiA+ID4gKyAgICAgICAgICAgICByZXR1cm4g LUVOT01FTTsKPiA+ID4gKwo+ID4gPiArICAgICByZXQgPSBvZl9wcm9wZXJ0eV9yZWFkX3UzMl9p bmRleChjaW5mby0+ZGV2LT5vZl9ub2RlLCAibGluYXJvLG9wdGVlLWNoYW5uZWwtaWQiLAo+ID4g PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAmY2hhbm5lbF9pZCk7 Cj4gPiA+ICsgICAgIGlmIChyZXQpCj4gPiA+ICsgICAgICAgICAgICAgcmV0dXJuIHJldDsKPiA+ ID4gKwo+ID4gPiArICAgICBjaW5mby0+dHJhbnNwb3J0X2luZm8gPSBjaGFubmVsOwo+ID4gPiAr ICAgICBjaGFubmVsLT5jaW5mbyA9IGNpbmZvOwo+ID4gPiArICAgICBjaGFubmVsLT5jaGFubmVs X2lkID0gY2hhbm5lbF9pZDsKPiA+ID4gKyAgICAgbXV0ZXhfaW5pdCgmY2hhbm5lbC0+bXUpOwo+ ID4gPiArCj4gPiA+ICsgICAgIHJldCA9IG9wdGVlX2NoYW5fc2V0dXBfc2htZW0oZGV2LCBjaW5m bywgdHgsIGNoYW5uZWwpOwo+ID4gPiArICAgICBpZiAocmV0KQo+ID4gPiArICAgICAgICAgICAg IHJldHVybiByZXQ7Cj4gPiA+ICsKPiA+ID4gKyAgICAgcmV0ID0gb3Blbl9zZXNzaW9uKCZjaGFu bmVsLT50ZWVfc2Vzc2lvbik7Cj4gPiA+ICsgICAgIGlmIChyZXQpCj4gPiA+ICsgICAgICAgICAg ICAgcmV0dXJuIHJldDsKPiA+ID4gKwo+ID4gPiArICAgICByZXQgPSBnZXRfY2hhbm5lbChjaGFu bmVsKTsKPiA+ID4gKyAgICAgaWYgKHJldCkgewo+ID4gPiArICAgICAgICAgICAgIGNsb3NlX3Nl c3Npb24oY2hhbm5lbC0+dGVlX3Nlc3Npb24pOwo+ID4gPiArCj4gPiA+ICsgICAgICAgICAgICAg cmV0dXJuIHJldDsKPiA+ID4gKyAgICAgfQo+ID4gPiArCj4gPiA+ICsgICAgIG11dGV4X2xvY2so Jm9wdGVlX3ByaXZhdGUtPm11KTsKPiA+ID4gKyAgICAgbGlzdF9hZGQoJmNoYW5uZWwtPmxpbmss ICZvcHRlZV9wcml2YXRlLT5jaGFubmVsX2xpc3QpOwo+ID4gPiArICAgICBtdXRleF91bmxvY2so Jm9wdGVlX3ByaXZhdGUtPm11KTsKPiA+ID4gKwo+ID4gPiArICAgICByZXR1cm4gMDsKPiA+ID4g K30KPiA+ID4gKwo+ID4gPiArc3RhdGljIGludCBvcHRlZV9jaGFuX2ZyZWUoaW50IGlkLCB2b2lk ICpwLCB2b2lkICpkYXRhKQo+ID4gPiArewo+ID4gPiArICAgICBzdHJ1Y3Qgc2NtaV9jaGFuX2lu Zm8gKmNpbmZvID0gcDsKPiA+ID4gKyAgICAgc3RydWN0IG9wdGVlX2NoYW5uZWwgKmNoYW5uZWwg PSBjaW5mby0+dHJhbnNwb3J0X2luZm87Cj4gPiA+ICsKPiA+ID4gKyAgICAgbXV0ZXhfbG9jaygm b3B0ZWVfcHJpdmF0ZS0+bXUpOwo+ID4gPiArICAgICBsaXN0X2RlbCgmY2hhbm5lbC0+bGluayk7 Cj4gPiA+ICsgICAgIG11dGV4X3VubG9jaygmb3B0ZWVfcHJpdmF0ZS0+bXUpOwo+ID4gPiArCj4g PiA+ICsgICAgIGlmIChjaGFubmVsLT50ZWVfc2htKSB7Cj4gPiA+ICsgICAgICAgICAgICAgdGVl X3NobV9mcmVlKGNoYW5uZWwtPnRlZV9zaG0pOwo+ID4gPiArICAgICAgICAgICAgIGNoYW5uZWwt PnRlZV9zaG0gPSBOVUxMOwo+ID4gPiArICAgICB9Cj4gPiA+ICsKPiA+ID4gKyAgICAgY2luZm8t PnRyYW5zcG9ydF9pbmZvID0gTlVMTDsKPiA+ID4gKyAgICAgY2hhbm5lbC0+Y2luZm8gPSBOVUxM Owo+ID4gPiArCj4gPiA+ICsgICAgIHNjbWlfZnJlZV9jaGFubmVsKGNpbmZvLCBkYXRhLCBpZCk7 Cj4gPiA+ICsKPiA+ID4gKyAgICAgcmV0dXJuIDA7Cj4gPiA+ICt9Cj4gPiA+ICsKPiA+ID4gK3N0 YXRpYyBzdHJ1Y3Qgc2NtaV9zaGFyZWRfbWVtICpnZXRfY2hhbm5lbF9zaG0oc3RydWN0IG9wdGVl X2NoYW5uZWwgKmNoYW4sIHN0cnVjdCBzY21pX3hmZXIgKnhmZXIpCj4gPiA+ICt7Cj4gPiA+ICsg ICAgIGlmICghY2hhbikKPiA+ID4gKyAgICAgICAgICAgICByZXR1cm4gTlVMTDsKPiA+ID4gKwo+ ID4gPiArICAgICByZXR1cm4gY2hhbi0+c2htZW07Cj4gPiA+ICt9Cj4gPiA+ICsKPiA+ID4gKwo+ ID4gPiArc3RhdGljIGludCBvcHRlZV9zZW5kX21lc3NhZ2Uoc3RydWN0IHNjbWlfY2hhbl9pbmZv ICpjaW5mbywKPiA+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCBzY21pX3hm ZXIgKnhmZXIpCj4gPiA+ICt7Cj4gPiA+ICsgICAgIHN0cnVjdCBvcHRlZV9jaGFubmVsICpjaGFu bmVsID0gY2luZm8tPnRyYW5zcG9ydF9pbmZvOwo+ID4gPiArICAgICBzdHJ1Y3Qgc2NtaV9zaGFy ZWRfbWVtICpzaG1lbSA9IGdldF9jaGFubmVsX3NobShjaGFubmVsLCB4ZmVyKTsKPiA+ID4gKyAg ICAgaW50IHJldDsKPiA+ID4gKwo+ID4gPiArICAgICBtdXRleF9sb2NrKCZjaGFubmVsLT5tdSk7 Cj4gPiA+ICsgICAgIHNobWVtX3R4X3ByZXBhcmUoc2htZW0sIHhmZXIpOwo+ID4gPiArCj4gPiA+ ICsgICAgIHJldCA9IGludm9rZV9wcm9jZXNzX3NtdF9jaGFubmVsKGNoYW5uZWwpOwo+ID4KPiA+ IEhlcmUgYWxsIHRoZSBhc3NvY2lhdGVkIHByb2Nlc3NpbmcgaW4gdGhlIFRydXN0ZWRPUyBpcyBm dWxseSBjb21wbGV0ZWQKPiA+IHJpZ2h0ID8gaS5lLiBhbGwgdGhlIHBvc3NpYmxlIHJlcGx5IHZh bHVlcyBoYXZlIGJlZW4gcHV0IGludG8gc2htZW0gYnkKPiA+IHRoZSBUcnVzdGVkT1MgcHJvY2Vz cyBiZWZvcmUgdGhlIHVuZGVybHlpbmcgU01DIGNhbGwgcmV0dXJucy4KPiA+IChqdXN0IHRvIHVu ZGVyc3RhbmQgYmV0dGVyIGhvdyBPUFRFRSB0cmFuc3BvcnQgaXMgc3VwcG9zZWQgdG8gYmVoYXZl KQo+Cj4gWWVzLCBvbmNlIHdlJ3JlIGJhY2sgZnJvbSBpbnZva2VfcHJvY2Vzc19zbXRfY2hhbm5l bCgpIHRoZSBTQ01JCj4gbWVzc2FnZSBoYXMgYmVlbiBwcm9jZXNzZWQgYW5kIHRoZSByZXNwb25z ZSBjYW4gYmUgcmVhZC4KPiBJZiBubyByZXNwb25zZSBpcyBmb3VuZCwgaXQgd2lsbCBiZSByZXBv cnRlZCBhcyBhIGNvbW11bmljYXRpb24gZXJyb3IuCj4KPiA+Cj4gPiA+ICsKPiA+ID4gKyAgICAg c2NtaV9yeF9jYWxsYmFjayhjaW5mbywgc2htZW1fcmVhZF9oZWFkZXIoc2htZW0pLCBOVUxMKTsK PiA+ID4gKyAgICAgbXV0ZXhfdW5sb2NrKCZjaGFubmVsLT5tdSk7Cj4gPiA+ICsKPiA+ID4gKyAg ICAgcmV0dXJuIHJldDsKPiA+ID4gK30KPiA+ID4gKwo+ID4gPiArc3RhdGljIHZvaWQgb3B0ZWVf ZmV0Y2hfcmVzcG9uc2Uoc3RydWN0IHNjbWlfY2hhbl9pbmZvICpjaW5mbywKPiA+ID4gKyAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCBzY21pX3hmZXIgKnhmZXIpCj4gPiA+ICt7 Cj4gPiA+ICsgICAgIHN0cnVjdCBvcHRlZV9jaGFubmVsICpjaGFubmVsID0gY2luZm8tPnRyYW5z cG9ydF9pbmZvOwo+ID4gPiArICAgICBzdHJ1Y3Qgc2NtaV9zaGFyZWRfbWVtICpzaG1lbSA9IGdl dF9jaGFubmVsX3NobShjaGFubmVsLCB4ZmVyKTsKPiA+ID4gKwo+ID4gPiArICAgICBzaG1lbV9m ZXRjaF9yZXNwb25zZShzaG1lbSwgeGZlcik7Cj4gPiA+ICt9Cj4gPiA+ICsKPiA+ID4gK3N0YXRp YyBib29sIG9wdGVlX3BvbGxfZG9uZShzdHJ1Y3Qgc2NtaV9jaGFuX2luZm8gKmNpbmZvLAo+ID4g PiArICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCBzY21pX3hmZXIgKnhmZXIpCj4gPiA+ ICt7Cj4gPiA+ICsgICAgIHN0cnVjdCBvcHRlZV9jaGFubmVsICpjaGFubmVsID0gY2luZm8tPnRy YW5zcG9ydF9pbmZvOwo+ID4gPiArICAgICBzdHJ1Y3Qgc2NtaV9zaGFyZWRfbWVtICpzaG1lbSA9 IGdldF9jaGFubmVsX3NobShjaGFubmVsLCB4ZmVyKTsKPiA+ID4gKwo+ID4gPiArICAgICByZXR1 cm4gc2htZW1fcG9sbF9kb25lKHNobWVtLCB4ZmVyKTsKPiA+ID4gK30KPiA+ID4gKwo+ID4gPiAr c3RhdGljIHN0cnVjdCBzY21pX3RyYW5zcG9ydF9vcHMgc2NtaV9vcHRlZV9vcHMgPSB7Cj4gPiA+ ICsgICAgIC5jaGFuX2F2YWlsYWJsZSA9IG9wdGVlX2NoYW5fYXZhaWxhYmxlLAo+ID4gPiArICAg ICAuY2hhbl9zZXR1cCA9IG9wdGVlX2NoYW5fc2V0dXAsCj4gPiA+ICsgICAgIC5jaGFuX2ZyZWUg PSBvcHRlZV9jaGFuX2ZyZWUsCj4gPiA+ICsgICAgIC5zZW5kX21lc3NhZ2UgPSBvcHRlZV9zZW5k X21lc3NhZ2UsCj4gPiA+ICsgICAgIC5mZXRjaF9yZXNwb25zZSA9IG9wdGVlX2ZldGNoX3Jlc3Bv bnNlLAo+ID4gPiArICAgICAuY2xlYXJfY2hhbm5lbCA9IG9wdGVlX2NsZWFyX2NoYW5uZWwsCj4g PiA+ICsgICAgIC5wb2xsX2RvbmUgPSBvcHRlZV9wb2xsX2RvbmUsCj4gPiA+ICt9Owo+ID4gPiAr Cj4gPiA+ICtjb25zdCBzdHJ1Y3Qgc2NtaV9kZXNjIHNjbWlfb3B0ZWVfZGVzYyA9IHsKPiA+ID4g KyAgICAgLm9wcyA9ICZzY21pX29wdGVlX29wcywKPiA+ID4gKyAgICAgLm1heF9yeF90aW1lb3V0 X21zID0gMzAsCj4gPiA+ICsgICAgIC5tYXhfbXNnID0gMjAsCj4gPiA+ICsgICAgIC5tYXhfbXNn X3NpemUgPSAxMjgsCj4gPiA+ICt9Owo+ID4gPiArCj4gPiA+ICtzdGF0aWMgaW50IG9wdGVlX2N0 eF9tYXRjaChzdHJ1Y3QgdGVlX2lvY3RsX3ZlcnNpb25fZGF0YSAqdmVyLCBjb25zdCB2b2lkICpk YXRhKQo+ID4gPiArewo+ID4gPiArICAgICByZXR1cm4gdmVyLT5pbXBsX2lkID09IFRFRV9JTVBM X0lEX09QVEVFOwo+ID4gPiArfQo+ID4gPiArCj4gPiA+ICtzdGF0aWMgaW50IG9wdGVlX3NlcnZp Y2VfcHJvYmUoc3RydWN0IGRldmljZSAqZGV2KQo+ID4gPiArewo+ID4gPiArICAgICBzdHJ1Y3Qg b3B0ZWVfYWdlbnQgKmFnZW50Owo+ID4gPiArICAgICBzdHJ1Y3QgdGVlX2NvbnRleHQgKnRlZV9j dHg7Cj4gPiA+ICsgICAgIGludCByZXQ7Cj4gPiA+ICsKPiA+ID4gKyAgICAgLyogT25seSBvbmUg U0NNSSBPUC1URUUgZGV2aWNlIGFsbG93ZWQgKi8KPiA+ID4gKyAgICAgaWYgKG9wdGVlX3ByaXZh dGUpIHsKPiA+ID4gKyAgICAgICAgICAgICBkZXZfZXJyKGRldiwgIkFuIFNDTUkgT1AtVEVFIGRl dmljZSB3YXMgYWxyZWFkeSBpbml0aWFsaXplZDogb25seSBvbmUgYWxsb3dlZFxuIik7Cj4gPiA+ ICsgICAgICAgICAgICAgcmV0dXJuIC1FQlVTWTsKPiA+ID4gKyAgICAgfQo+ID4gPiArCj4gPiA+ ICsgICAgIHRlZV9jdHggPSB0ZWVfY2xpZW50X29wZW5fY29udGV4dChOVUxMLCBvcHRlZV9jdHhf bWF0Y2gsIE5VTEwsIE5VTEwpOwo+ID4gPiArICAgICBpZiAoSVNfRVJSKHRlZV9jdHgpKQo+ID4g PiArICAgICAgICAgICAgIHJldHVybiAtRU5PREVWOwo+ID4gPiArCj4gPiA+ICsgICAgIGFnZW50 ID0gZGV2bV9remFsbG9jKGRldiwgc2l6ZW9mKCphZ2VudCksIEdGUF9LRVJORUwpOwo+ID4gPiAr ICAgICBpZiAoIWFnZW50KSB7Cj4gPiA+ICsgICAgICAgICAgICAgcmV0ID0gLUVOT01FTTsKPiA+ ID4gKyAgICAgICAgICAgICBnb3RvIG91dDsKPiA+ID4gKyAgICAgfQo+ID4gPiArCj4gPiA+ICsg ICAgIGFnZW50LT5kZXYgPSBkZXY7Cj4gPiA+ICsgICAgIGFnZW50LT50ZWVfY3R4ID0gdGVlX2N0 eDsKPiA+ID4gKyAgICAgSU5JVF9MSVNUX0hFQUQoJmFnZW50LT5jaGFubmVsX2xpc3QpOwo+ID4g PiArCj4gPiA+ICsgICAgIG9wdGVlX3ByaXZhdGUgPSBhZ2VudDsKPiA+Cj4gPiBCYXJyaWVyIGhl cmUgdG8gYmUgc3VyZSB0aGlzIGdsb2JhbCBpcyB2aXNpYmxlIGFuZCBub3QgcmVvcmRlcmVkID8K PiA+Cj4gPiBOb3Qgc3VyZSBpZiBpdCBpcyBwbGF1c2libGUgdGhhdCB3aXRob3V0IGEgYmFycmll ciB0aGUgc3Vic2VxdWVudAo+ID4gb3B0ZWVfY2hhbl9zZXR1cCBjb3VsZCBydW4gb24gYW5vdGhl ciBjb3JlIGFuZCBzaW1wbHkgbWlzcyB0aGlzIHVwZGF0ZQo+ID4gYW5kIGJhaWwgb3V0LiAoY2Fu bm90IHNlZSBhbnkgbG9ja2luZyBvZiBhbnkga2luZCBlaXRoZXIgaW4gdGhlCj4gPiBjaGFuX2F2 YWlsYWJsZS9jaGFuX3NldHVwIFRYIHBhdGggdGhhdCBjb3VsZCB0cmlnZ2VyIGEgaW1wbGljaXQg bWVtb3J5Cj4gPiBiYXJyaWVyLi4uLmJhaCBtYXliZSBJJ20gcGFyYW5vaWQpCj4KPiBObyBiYXJy aWVyIG5lZWRlZCBJTU8uIG9wdGVlX3ByaXZhdGUgaXMgc3RhbmRhcmQgY2FjaGVkIG1lbW9yeSB2 aXNpYmxlCj4gdG8gYWxsIHBhcnRpY2lwYW50IGNvcmVzCj4gYW5kIGNoYW5fc2V0dXAgY2Fubm90 IGJlIGNhbGxlZCBiZWZvcmUgdGhpcyBmdW5jdGlvbiBjb21wbGV0ZXMuCj4gRG8gSSBtaXNzIHNv bWV0aGluZz8KPgoKSSBzZWUgd2h5IHlvdSBhc2sgZm9yIGEgYmFycmllci4gSW5kZWVkLCBhdCBt b2R1bGUgaW5zZXJ0aW9uIHdlIGNhbgpmYWNlIGNvbnNpc3RlbmN5IGlzc3Vlcy4KCkkgYWdyZWUg YmFycmllcnMgYXJlIG5lZWRlZC4gTG9va2luZyBhdCB0aGUgc2NtaV92aXJ0aW8KaW1wbGVtZW50 YXRpb24sIGkgdGhpbmsgdGhlIGJhcnJpZXJzIGFyZSBtaXNwbGFjZWQgaW4gdGhlIHNlcXVlbmNl cy4KVGhlIGJhcnJpZXIgc2hvdWxkIGJlIHBsYWNlZCBiZWZvcmUgdGhlIGdsb2JhbCByZWZlcmVu Y2UgaXMgbG9hZGVkIGF0CmRldmljZSBwcm9iZSwgc28gdGhhdCBpdHMgY29udGVudCBpcyB2aXNp YmxlIGJlZm9yZSB0aGUgZGV2aWNlCnJlZmVyZW5jZSBpdHNlbGYuCk9uIHRoZSBvdGhlciBoYW5k IGluIHRoZSByZW1vdmUgc2VxdWVuY2UsIHRoZSBiYXJyaWVyIHNob3VsZCBiZSBwbGFjZWQKYWZ0 ZXIgZGV2aWNlIHJlZiBpcyBjbGVhcmVkIGJ1dCBiZWZvcmUgZGV2aWNlIHJlc291cmNlcyBhcmUg cmVsZWFzZWQuCk5vdGUgdGhhdCwgaW4gc21wX3N0b3JlX21iKCkgaW1wbGVtZW50YXRpb24sIHRo ZSBtZW1vcnkgYmFycmllciBpcwpwbGFjZXMgYWZ0ZXIgdGhlIGRhdGEgaXMgbG9hZGVkLCBub3Qg YmVmb3JlLgpTZWUgdGhlIHBhdGNoLWxpa2Ugc25pcHBldCBiZWxvdzoKCiBzdGF0aWMgaW50IHNj bWlfdmlvX3Byb2JlKHN0cnVjdCB2aXJ0aW9fZGV2aWNlICp2ZGV2KQogewogICAgICguLi4pCgot ICAgIHZkZXYtPnByaXYgPSBjaGFubmVsczsKLSAgICAvKiBFbnN1cmUgaW5pdGlhbGl6ZWQgc2Nt aV92ZGV2IGlzIHZpc2libGUgKi8KLSAgICBzbXBfc3RvcmVfbWIoc2NtaV92ZGV2LCB2ZGV2KTsK KyAgICAvKiBFbnN1cmUgaW5pdGlhbGl6ZWQgc2NtaV92ZGV2IGlzIHZpc2libGUgYmVmb3JlIHNj bWlfdmRldiBpcyAqLworICAgIHNtcF9zdG9yZV9tYih2ZGV2LT5wcml2LCBjaGFubmVscyk7Cisg ICAgc2NtaV92ZGV2ID0gdmRldjsKCiAgICByZXR1cm4gMDsKIH0KCiBzdGF0aWMgdm9pZCBzY21p X3Zpb19yZW1vdmUoc3RydWN0IHZpcnRpb19kZXZpY2UgKnZkZXYpCiB7CisgICAgLyogRW5zdXJl IHNjbWlfdmRldiBpcyB2aXNpYmxlIGFzIE5VTEwgYmVmb3JlIHJlc291cmNlcyBhcmUgcmVsZWFz ZWQgKi8KKyAgICBzbXBfc3RvcmVfbWIoc2NtaV92ZGV2LCBOVUxMKTsKKwogICAgIC8qCiAgICAg ICogT25jZSB3ZSBnZXQgaGVyZSwgdmlydGlvX2NoYW5fZnJlZSgpIHdpbGwgaGF2ZSBhbHJlYWR5 IGJlZW4gY2FsbGVkIGJ5CiAgICAgICogdGhlIFNDTUkgY29yZSBmb3IgYW55IGV4aXN0aW5nIGNo YW5uZWwgYW5kLCBhcyBhIGNvbnNlcXVlbmNlLCBhbGwgdGhlCiAgICAgICogdmlydGlvIGNoYW5u ZWxzIHdpbGwgaGF2ZSBiZWVuIGFscmVhZHkgbWFya2VkIE5PVCByZWFkeSwgY2F1c2luZyBhbnkK ICAgICAgKiBvdXRzdGFuZGluZyBtZXNzYWdlIG9uIGFueSB2cXVldWUgdG8gYmUgaWdub3JlZCBi eSBjb21wbGV0ZV9jYjogbm93CiAgICAgICogd2UgY2FuIGp1c3Qgc3RvcCBwcm9jZXNzaW5nIGJ1 ZmZlcnMgYW5kIGRlc3Ryb3kgdGhlIHZxdWV1ZXMuCiAgICAgICovCiAgICAgdmRldi0+Y29uZmln LT5yZXNldCh2ZGV2KTsKICAgICB2ZGV2LT5jb25maWctPmRlbF92cXModmRldik7Ci0gICAgLyog RW5zdXJlIHNjbWlfdmRldiBpcyB2aXNpYmxlIGFzIE5VTEwgKi8KLSAgICBzbXBfc3RvcmVfbWIo c2NtaV92ZGV2LCBOVUxMKTsKIH0KCkRvZXMgdGhhdCBtYWtlIHNlbnNlIHRvIHlvdT8KCj4gPgo+ ID4gPiArCj4gPiA+ICsgICAgIHJldCA9IGdldF9jYXBhYmlsaXRpZXMoKTsKPiA+ID4gKwo+ID4g PiArb3V0Ogo+ID4gPiArICAgICBpZiAocmV0KSB7Cj4gPiA+ICsgICAgICAgICAgICAgdGVlX2Ns aWVudF9jbG9zZV9jb250ZXh0KHRlZV9jdHgpOwo+ID4gPiArICAgICAgICAgICAgIG9wdGVlX3By aXZhdGUgPSBOVUxMOwo+ID4KPiA+IEJhcnJpZXIgPyAobm90IHN1cmUgYXMgYWJvdmUuLi4pCj4g Pgo+ID4gPiArICAgICB9Cj4gPiA+ICsKPiA+ID4gKyAgICAgcmV0dXJuIHJldDsKPiA+ID4gK30K PiA+ID4gKwo+ID4gPiArc3RhdGljIGludCBvcHRlZV9zZXJ2aWNlX3JlbW92ZShzdHJ1Y3QgZGV2 aWNlICpkZXYpCj4gPiA+ICt7Cj4gPiA+ICsgICAgIGlmIChvcHRlZV9wcml2YXRlKQo+ID4gPiAr ICAgICAgICAgICAgIHJldHVybiAtRUlOVkFMOwo+ID4KPiA+IElzIGl0ICBpbnN0ZWFkOiBpZiAo IW9wdGVlX3ByaXZhdGUpID8KPgo+IE91cHMhIGluZGVlZCA6KAo+Cj4gPiA+ICsKPiA+ID4gKyAg ICAgaWYgKCFsaXN0X2VtcHR5KCZvcHRlZV9wcml2YXRlLT5jaGFubmVsX2xpc3QpKQo+ID4gPiAr ICAgICAgICAgICAgIHJldHVybiAtRUJVU1k7Cj4gPiA+ICsKPiA+ID4gKyAgICAgdGVlX2NsaWVu dF9jbG9zZV9jb250ZXh0KG9wdGVlX3ByaXZhdGUtPnRlZV9jdHgpOwo+ID4gPiArCj4gPiA+ICsg ICAgIG9wdGVlX3ByaXZhdGUgPSBOVUxMOwo+ID4gPiArCj4gPgo+ID4gQmFycmllciA/IChub3Qg c3VyZSBhcyBhYm92ZS4uLikKPiA+Cj4gPiA+ICsgICAgIHJldHVybiAwOwo+ID4gPiArfQo+ID4g PiArCj4gPiA+ICtzdGF0aWMgY29uc3Qgc3RydWN0IHRlZV9jbGllbnRfZGV2aWNlX2lkIHNjbWlf b3B0ZWVfc2VydmljZV9pZFtdID0gewo+ID4gPiArICAgICB7Cj4gPiA+ICsgICAgICAgICAgICAg VVVJRF9JTklUKDB4YThjZmU0MDYsIDB4ZDRmNSwgMHg0YTJlLAo+ID4gPiArICAgICAgICAgICAg ICAgICAgICAgICAweDlmLCAweDhkLCAweGEyLCAweDVkLCAweGM3LCAweDU0LCAweGMwLCAweDk5 KQo+ID4gPiArICAgICB9LAo+ID4gPiArICAgICB7IH0KPiA+ID4gK307Cj4gPiA+ICsKPiA+ID4g K01PRFVMRV9ERVZJQ0VfVEFCTEUodGVlLCBzY21pX29wdGVlX3NlcnZpY2VfaWQpOwo+ID4gPiAr Cj4gPiA+ICtzdGF0aWMgc3RydWN0IHRlZV9jbGllbnRfZHJpdmVyIHNjbWlfb3B0ZWVfZHJpdmVy ID0gewo+ID4gPiArICAgICAuaWRfdGFibGUgICAgICAgPSBzY21pX29wdGVlX3NlcnZpY2VfaWQs Cj4gPiA+ICsgICAgIC5kcml2ZXIgICAgICAgICA9IHsKPiA+ID4gKyAgICAgICAgICAgICAubmFt ZSA9ICJzY21pLW9wdGVlIiwKPiA+ID4gKyAgICAgICAgICAgICAuYnVzID0gJnRlZV9idXNfdHlw ZSwKPiA+ID4gKyAgICAgICAgICAgICAucHJvYmUgPSBvcHRlZV9zZXJ2aWNlX3Byb2JlLAo+ID4g PiArICAgICAgICAgICAgIC5yZW1vdmUgPSBvcHRlZV9zZXJ2aWNlX3JlbW92ZSwKPiA+ID4gKyAg ICAgfSwKPiA+ID4gK307Cj4gPiA+ICsKPiA+ID4gK3N0YXRpYyBpbnQgX19pbml0IHNjbWlfb3B0 ZWVfaW5pdCh2b2lkKQo+ID4gPiArewo+ID4gPiArICAgICByZXR1cm4gZHJpdmVyX3JlZ2lzdGVy KCZzY21pX29wdGVlX2RyaXZlci5kcml2ZXIpOwo+ID4gPiArfQo+ID4gPiArCj4gPiA+ICtzdGF0 aWMgdm9pZCBfX2V4aXQgc2NtaV9vcHRlZV9leGl0KHZvaWQpCj4gPiA+ICt7Cj4gPiA+ICsgICAg IGRyaXZlcl91bnJlZ2lzdGVyKCZzY21pX29wdGVlX2RyaXZlci5kcml2ZXIpOwo+ID4gPiArfQo+ ID4gPiArCj4gPiA+ICtkZXZpY2VfaW5pdGNhbGwoc2NtaV9vcHRlZV9pbml0KQo+ID4gPiArbW9k dWxlX2V4aXQoc2NtaV9vcHRlZV9leGl0KTsKPiA+Cj4gPiBUaGlzIGJyZWFrcyB0aGUgYnVpbGQg d2hlbiBBUk1fU0NNSV9QUk9UT0NPTD1tIGFuZCBTQ01JIE9QVEVFIHRyYW5zcG9ydCBpcyBlbmFi bGVkLAo+ID4gc2luY2UgdGhlIFNDTUkgdHJhbnNwb3J0cyBhcmUgbm90IGZ1bGwgZmxlZGdlZCBk cml2ZXJzIGJ1dCB0aGV5IGFyZSBidWlsdCBpbnRvCj4gPiB0aGUgU0NNSSBzdGFjayBjb3JlIG1v ZHVsZSwgc28gaWYgeW91IGVuZHVwIHRyeWluZyB0byBkZWZpbmUgbXVsdGlwbGUgaW5pdHMuCj4g Pgo+ID4gIExEIFtNXSAgZHJpdmVycy9maXJtd2FyZS9hcm1fc2NtaS9zY21pLW1vZHVsZS5vCj4g PiAvb3B0L3Rvb2xjaGFpbnMvZ2NjLWFybS04LjMtMjAxOS4wMy14ODZfNjQtYWFyY2g2NC1saW51 eC1nbnUvYmluL2FhcmNoNjQtbGludXgtZ251LWxkOiBkcml2ZXJzL2Zpcm13YXJlL2FybV9zY21p L29wdGVlLm86IGluIGZ1bmN0aW9uIGBzY21pX29wdGVlX2luaXQnOgo+ID4gL2hvbWUvY3JpbWFy MDEvQVJNL2Rldi9zcmMvcGRzdy9saW51eC9kcml2ZXJzL2Zpcm13YXJlL2FybV9zY21pL29wdGVl LmM6NTQ5OiBtdWx0aXBsZSBkZWZpbml0aW9uIG9mIGBpbml0X21vZHVsZSc7IGRyaXZlcnMvZmly bXdhcmUvYXJtX3NjbWkvZHJpdmVyLm86L2hvbWUvY3JpbWFyMDEvQVJNL2Rldi9zcmMvcGRzdy9s aW51eC9kcml2ZXJzL2Zpcm13YXJlL2FybV9zY21pL2RyaXZlci5jOjIwNzA6IGZpcnN0IGRlZmlu ZWQgaGVyZQo+ID4gL29wdC90b29sY2hhaW5zL2djYy1hcm0tOC4zLTIwMTkuMDMteDg2XzY0LWFh cmNoNjQtbGludXgtZ251L2Jpbi9hYXJjaDY0LWxpbnV4LWdudS1sZDogZHJpdmVycy9maXJtd2Fy ZS9hcm1fc2NtaS9vcHRlZS5vOiBpbiBmdW5jdGlvbiBgc2NtaV9vcHRlZV9leGl0JzoKPiA+IC9o b21lL2NyaW1hcjAxL0FSTS9kZXYvc3JjL3Bkc3cvbGludXgvZHJpdmVycy9maXJtd2FyZS9hcm1f c2NtaS9vcHRlZS5jOjU1NDogbXVsdGlwbGUgZGVmaW5pdGlvbiBvZiBgY2xlYW51cF9tb2R1bGUn OyBkcml2ZXJzL2Zpcm13YXJlL2FybV9zY21pL2RyaXZlci5vOi9ob21lL2NyaW1hcjAxL0FSTS9k ZXYvc3JjL3Bkc3cvbGludXgvZHJpdmVycy9maXJtd2FyZS9hcm1fc2NtaS9kcml2ZXIuYzoyMDk5 OiBmaXJzdCBkZWZpbmVkIGhlPiAvaG9tZS9jcmltYXIwMS9BUk0vZGV2L3NyYy9wZHN3L2xpbnV4 L3NjcmlwdHMvTWFrZWZpbGUuYnVpbGQ6NDc0OiByZWNpcGUgZm9yIHRhcmdldCAnZHJpdmVycy9m aXJtd2FyZS9hcm1fc2NtaS9zY21pLW1vZHVsZS5vJyBmYWlsZWQKPiA+IG1ha2VbNF06ICoqKiBb ZHJpdmVycy9maXJtd2FyZS9hcm1fc2NtaS9zY21pLW1vZHVsZS5vXSBFcnJvciAxCj4gPiAvaG9t ZS9jcmltYXIwMS9BUk0vZGV2L3NyYy9wZHN3L2xpbnV4L3NjcmlwdHMvTWFrZWZpbGUuYnVpbGQ6 NTQwOiByZWNpcGUgZm9yIHRhcmdldCAnZHJpdmVycy9maXJtd2FyZS9hcm1fc2NtaScgZmFpbGVk Cj4gPiBtYWtlWzNdOiAqKiogW2RyaXZlcnMvZmlybXdhcmUvYXJtX3NjbWldIEVycm9yIDIKPiA+ IC9ob21lL2NyaW1hcjAxL0FSTS9kZXYvc3JjL3Bkc3cvbGludXgvc2NyaXB0cy9NYWtlZmlsZS5i dWlsZDo1NDA6IHJlY2lwZSBmb3IgdGFyZ2V0ICdkcml2ZXJzL2Zpcm13YXJlJyBmYWlsZWQKPiA+ IG1ha2VbMl06ICoqKiBbZHJpdmVycy9maXJtd2FyZV0gRXJyb3IgMgo+ID4gbWFrZVsyXTogKioq IFdhaXRpbmcgZm9yIHVuZmluaXNoZWQgam9icy4uLi4KPiA+IC9ob21lL2NyaW1hcjAxL0FSTS9k ZXYvc3JjL3Bkc3cvbGludXgvTWFrZWZpbGU6MTg3NDogcmVjaXBlIGZvciB0YXJnZXQgJ2RyaXZl cnMnIGZhaWxlZAo+ID4gbWFrZVsxXTogKioqIFtkcml2ZXJzXSBFcnJvciAyCj4gPiBtYWtlWzFd OiBMZWF2aW5nIGRpcmVjdG9yeSAnL2hvbWUvY3JpbWFyMDEvQVJNL2Rldi9zcmMvcGRzdy9vdXRf bGludXgnCj4gPiBNYWtlZmlsZToyMTk6IHJlY2lwZSBmb3IgdGFyZ2V0ICdfX3N1Yi1tYWtlJyBm YWlsZWQKPiA+Cj4gPiBJbiBvcmRlciB0byBhZGRyZXNzIHRoaXMgaXNzdWUgKHNhbWUgaGFwcGVu ZGVkIHdpdGggVmlydElPKSBJIGFkZGVkCj4gPiB0cmFuc3BvcnRfaW5pdC90cmFuc3BvcnRfZXhp dCBvcHRpb25hbCBob29rcyBpbnRvIHNjbWlfZGVzYywgc28gdGhhdAo+ID4geW91IGNhbiBhc2sg dGhlIGNvcmUgU0NNSSBzdGFjayB0byBwZXJmb3JtIHdoYXRldmVyIHlvdXIgdHJhbnNwb3J0Cj4g PiBuZWVkcyBhdCBTQ01JIGNvcmUgaW5pdC10aW1lLCBiZWZvcmUgdGhlIFNDTUkgY29yZSBzdGFj ayBpcyBwcm9iZWQuCj4gPgo+ID4gSW4gb3RoZXIgd29yZHMgdGhlIGZpeCBoZXJlIGRvd24gYmVs b3cgZml4ZXMgZm9yIG1lIHRoZSBidWlsZCBhcyBhCj4gPiBtb2R1bGUgb2YgdGhlIFNDTUkgc3Rh Y2suCj4KPiBUbyBlbnN1cmUgc2NtaS9vcHRlZSB0cmFuc3BvcnQgY2FuIHJlZ2lzdGVyIHRvIHRo ZSB0ZWUgYnVzLCBpdCBtdXN0Cj4gd2FpdCB0ZWUgYnVzIGlzIGluaXRpYWxpemVkLgo+IFRoZSBp c3N1ZSBpcyBvcHRlZSBkcml2ZXIgaW5pdGlhbGl6ZXMgaXRzIHRlZSBidXMgYXQgc3Vic3lzX2lu aXRjYWxsCj4gbGV2ZWwsIHNhbWUgbGV2ZWwgYXMgdGhlIHNjbWkgZHJpdmVyLgo+IFNvIEkgaGFk IHRvIGNhbGwgc2NtaV9vcHRlZV9pbml0KCkgYXQgYW4gZWFybGllciBpbml0IGxldmVsOiBkZXZp Y2VfaW5pdGNhbGwoKS4KPgo+IFZpcnRpbyBidXMgaXMgcmVnaXN0ZXJlZCBhdCBjb3JlX2luaXRj YWxsIGxldmVsIGhlbmNlIHNjbWkvdmlydGlvIGluaXQKPiBhIHN1YnN5c19pbml0Y2FsbCBoYXMg dGhlIGRlcGVuZGVuY3kgcmVzb2x2ZWQuCgpJIGhhdmUgYSBwcm9wb3NhbCB0byBhZGRyZXNzIHRo aXMuCgpZb3Ugc3VnZ2VzdGVkIHRvIHVzZSA6OnRyYW5zcG9ydF9pbml0IG9wZXJhdG9yIGZyb20g c3RydWN0IHNjbWlfZGVzYwpmb3IgdGhpcyByZWdpc3RyYXRpb24gdG8gdGhlIG9wdGVlIGJ1cy4K Rm9yIHRoZSByZWFzb24gYWJvdmUsIGl0IGRvZXMgbm90IGFwcGx5IHRvIE9QLVRFRS4KTXkgaWRl YSBpcyB0byBub3QgdWUgOjp0cmFuc3BvcnRfaW5pdCBob29rIGJ1dCB0byByZWdpc3RlciBmcm9t Cjo6bGlua19zdXBwbGllciBob29rIGZyb20gc3RydWN0IHNjbWlfdHJhbnNwb3J0X29wcy4KVGhl IGZpcnN0IHRpbWUgYSBzY21pX29wdGVlIGNoYW5uZWwgdG8gcmVxdWVzdGVkLCBpdCB3aWxsIGJl IGRlZmVycmVkCmFuZCBzY21pX29wdGVlIHJlZ2lzdGVyaW5nIHRvIG9wdGVlIGJ1cyBkb25lLgpT b21ldGhpbmcgbGlrZSB0aGUgYmVsb3c6CgogIHN0YXRpYyBpbnQgc2NtaV9vcHRlZV9saW5rX3N1 cHBsaWVyKHN0cnVjdCBkZXZpY2UgKmRldikKICB7CiAgICAgIGlmICghc2NtaV9vcHRlZV9wcml2 YXRlKSB7CiAgICAgICAgICBzdGF0aWMgaW50IHJlZ2lzdGVyX3RvX29wdGVlID0gLUVOT0RFVjsK CiAgICAgICAgICAvLyByZWdpc3RlciB0byBvcHRlZSBidXMgZW51bWVyYXRpb24gaWYgbm90IGFs cmVhZHkgc3VjY2Vzc2Z1bGx5IGRvbmUKICAgICAgICAgIGlmIChyZWdpc3Rlcl90b19vcHRlZSkK ICAgICAgICAgICAgICByZWdpc3Rlcl90b19vcHRlZSA9IGRyaXZlcl9yZWdpc3Rlcigmc2NtaV9v cHRlZV9kcml2ZXIuZHJpdmVyKTsKCiAgICAgICAgICAvLyBkZWZlciBjaGFubmVsIHNldHVwIHVu dGlsCiAgICAgICAgICByZXR1cm4gLUVQUk9CRV9ERUZFUjsKICAgICAgfQoKICAgICAgaWYgKCFk ZXZpY2VfbGlua19hZGQoZGV2LCBzY21pX29wdGVlX3ByaXZhdGUtPmRldiwKRExfRkxBR19BVVRP UkVNT1ZFX0NPTlNVTUVSKSkgewogICAgICAgICAgZGV2X2VycihkZXYsICJBZGRpbmcgbGluayB0 byBzdXBwbGllciBvcHRlZSBkZXZpY2UgZmFpbGVkXG4iKTsKICAgICAgICAgIHJldHVybiAtRUNB TkNFTEVEOwogICAgICB9CgogICAgICByZXR1cm4gMDsKICB9CgpOb3RlIHRoZSBleGl0IHNlcXVl bmNlIGNhbiBzdGlsbCB1c2Ugc3RydWN0IHNjbWlfZGVzYzo6dHJhbnNwb3J0X2V4dCBob29rOgoK ICBzdGF0aWMgdm9pZCBzY21pX29wdGVlX2V4aXQodm9pZCkKICB7CiAgICAgIGRyaXZlcl91bnJl Z2lzdGVyKCZzY21pX29wdGVlX2RyaXZlci5kcml2ZXIpOwogIH0KICBtb2R1bGVfZXhpdChzY21p X29wdGVlX2V4aXQpOwoKTWF5IEkgZ2V0IHlvdXIgb3Bpbmlvbj8KClJlZ2FyZHMsCkV0aWVubmUK Cj4KPgo+ID4KPiA+IE5vdGUgdGhhdCBhbHNvIF9fZXhpdCBvbiBzY21pX29wdGVlX2V4aXQoIClo YSBzYmVlbiByZW1vdmVkIHRvIGF2b2lkCj4gPiBzb21lIGNvbXBsYWlucyBzcG90dGVkIGJ5IEFy bmQgb24gU0NNSSBWaXJ0SU8gKDFjZDczMjAwZGFkMiBmaXJtd2FyZToKPiA+IGFybV9zY21pOiBS ZW1vdmUgX19leGl0IGFubm90YXRpb24pCj4KPiBPaywgdGhhbmtzLgo+Cj4gUmVnYXJkcywKPiBF dGllbm5lCj4KPiA+Cj4gPiBUaGFua3MsCj4gPiBDcmlzdGlhbgo+ID4KPiA+IC0tLTg8LS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0KPiA+Cj4gPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9maXJtd2FyZS9h cm1fc2NtaS9vcHRlZS5jIGIvZHJpdmVycy9maXJtd2FyZS9hcm1fc2NtaS9vcHRlZS5jCj4gPiBp bmRleCBlMjk0Y2ZmMzdiZWEuLmFmNmQ1MjQzOGIwNCAxMDA2NDQKPiA+IC0tLSBhL2RyaXZlcnMv ZmlybXdhcmUvYXJtX3NjbWkvb3B0ZWUuYwo+ID4gKysrIGIvZHJpdmVycy9maXJtd2FyZS9hcm1f c2NtaS9vcHRlZS5jCj4gPiBAQCAtNDU5LDEzICs0NTksNiBAQCBzdGF0aWMgc3RydWN0IHNjbWlf dHJhbnNwb3J0X29wcyBzY21pX29wdGVlX29wcyA9IHsKPiA+ICAgICAgICAgLnBvbGxfZG9uZSA9 IG9wdGVlX3BvbGxfZG9uZSwKPiA+ICB9Owo+ID4KPiA+IC1jb25zdCBzdHJ1Y3Qgc2NtaV9kZXNj IHNjbWlfb3B0ZWVfZGVzYyA9IHsKPiA+IC0gICAgICAgLm9wcyA9ICZzY21pX29wdGVlX29wcywK PiA+IC0gICAgICAgLm1heF9yeF90aW1lb3V0X21zID0gMzAsCj4gPiAtICAgICAgIC5tYXhfbXNn ID0gMjAsCj4gPiAtICAgICAgIC5tYXhfbXNnX3NpemUgPSAxMjgsCj4gPiAtfTsKPiA+IC0KPiA+ ICBzdGF0aWMgaW50IG9wdGVlX2N0eF9tYXRjaChzdHJ1Y3QgdGVlX2lvY3RsX3ZlcnNpb25fZGF0 YSAqdmVyLCBjb25zdCB2b2lkICpkYXRhKQo+ID4gIHsKPiA+ICAgICAgICAgcmV0dXJuIHZlci0+ aW1wbF9pZCA9PSBURUVfSU1QTF9JRF9PUFRFRTsKPiA+IEBAIC01NTAsMTAgKzU0MywxNiBAQCBz dGF0aWMgaW50IF9faW5pdCBzY21pX29wdGVlX2luaXQodm9pZCkKPiA+ICAgICAgICAgcmV0dXJu IGRyaXZlcl9yZWdpc3Rlcigmc2NtaV9vcHRlZV9kcml2ZXIuZHJpdmVyKTsKPiA+ICB9Cj4gPgo+ ID4gLXN0YXRpYyB2b2lkIF9fZXhpdCBzY21pX29wdGVlX2V4aXQodm9pZCkKPiA+ICtzdGF0aWMg dm9pZCBzY21pX29wdGVlX2V4aXQodm9pZCkKPiA+ICB7Cj4gPiAgICAgICAgIGRyaXZlcl91bnJl Z2lzdGVyKCZzY21pX29wdGVlX2RyaXZlci5kcml2ZXIpOwo+ID4gIH0KPiA+Cj4gPiAtZGV2aWNl X2luaXRjYWxsKHNjbWlfb3B0ZWVfaW5pdCkKPiA+IC1tb2R1bGVfZXhpdChzY21pX29wdGVlX2V4 aXQpOwo+ID4gK2NvbnN0IHN0cnVjdCBzY21pX2Rlc2Mgc2NtaV9vcHRlZV9kZXNjID0gewo+ID4g KyAgICAgICAudHJhbnNwb3J0X2luaXQgPSBzY21pX29wdGVlX2luaXQsCj4gPiArICAgICAgIC50 cmFuc3BvcnRfZXhpdCA9IHNjbWlfb3B0ZWVfZXhpdCwKPiA+ICsgICAgICAgLm9wcyA9ICZzY21p X29wdGVlX29wcywKPiA+ICsgICAgICAgLm1heF9yeF90aW1lb3V0X21zID0gMzAsCj4gPiArICAg ICAgIC5tYXhfbXNnID0gMjAsCj4gPiArICAgICAgIC5tYXhfbXNnX3NpemUgPSAxMjgsCj4gPiAr fTsKPiA+Cj4gPiA+IC0tCj4gPiA+IDIuMTcuMQo+ID4gPgoKX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX18KbGludXgtYXJtLWtlcm5lbCBtYWlsaW5nIGxpc3QK bGludXgtYXJtLWtlcm5lbEBsaXN0cy5pbmZyYWRlYWQub3JnCmh0dHA6Ly9saXN0cy5pbmZyYWRl YWQub3JnL21haWxtYW4vbGlzdGluZm8vbGludXgtYXJtLWtlcm5lbAo=