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 76F18C433F5 for ; Tue, 19 Oct 2021 16:19:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 52B9A61360 for ; Tue, 19 Oct 2021 16:19:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232355AbhJSQWB (ORCPT ); Tue, 19 Oct 2021 12:22:01 -0400 Received: from foss.arm.com ([217.140.110.172]:51406 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229846AbhJSQWA (ORCPT ); Tue, 19 Oct 2021 12:22:00 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 6673C2F; Tue, 19 Oct 2021 09:19:47 -0700 (PDT) Received: from e120937-lin (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 281F13F694; Tue, 19 Oct 2021 09:19:46 -0700 (PDT) Date: Tue, 19 Oct 2021 17:19:43 +0100 From: Cristian Marussi To: Etienne Carriere Cc: linux-kernel@vger.kernel.org, "moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE" , Sudeep Holla , Vincent Guittot Subject: Re: [PATCH v3 2/2] firmware: arm_scmi: Add optee transport Message-ID: <20211019161943.GB6526@e120937-lin> References: <20211018114046.25571-1-etienne.carriere@linaro.org> <20211018114046.25571-2-etienne.carriere@linaro.org> <20211018194317.GA6526@e120937-lin> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: User-Agent: Mutt/1.9.4 (2018-02-28) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, Oct 19, 2021 at 04:24:30PM +0200, Etienne Carriere wrote: > Hi, > Hi Etienne, I was replying to the previous one, so I'll stick all my answers togetehr in this last email instead :D > 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 transport. > > Thanks for all the fixes you sent, i'll integrate them in the patch v4. > > As a side thing on this 'depends on', I'm also a bit puzzled by the fact the depends is on CONFIG_OPTEE but some errors of the above appear really on CONFIG_TEE=m since the scmi_optee is really using the generic tee_ API which in turn needs/uses CONFIG_OPTEE in this case (if I got it right AFAIU...not really an OPTEE expert here :>)...but maybe CONFIG_OPTEE is just the easier and most correct thing we can do. > > I don't know yet how to address your last comment. See my feedback on > > the optee bus dependency issue. > > See below. > > > > > > 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 scmi > > > > 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 transport > > > > allocates the shared memory buffer from the optee driver when no shmem > > > > 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 through > > > > capabilities exchange. > > > > > > > > OP-TEE SCMI service is integrated in OP-TEE since its release tag 3.13.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 for 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 for 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 firmware: > > > arm_scmi: Fix virtio transport Kconfig dependency), that consiste in a broken > > > build when SCMI was compiled built-in with VIRTIO transport support with > > > ARM_SCMI_PROTOCOL=y while the core was CONFIG_VIRTIO=m. > > > > > > So I tried similarly to set CONFIG_OPTEE=m while keeping ARM_SCMI_PROTOCOL=y > > > expecting to see a similar issue as in VirtIO (i.e. not being able to access > > > optee module symbols from the builtin SCMI), instead I spotted a different bug :D > > > > Sorry, I didn't try this config (optee=m / scmi=y). I though expecting > > scmi over optee and scmi=y would mandate optee=y. Well, yes, but due to a dance of circular-deps in Kconfig which I could not find a way to avoid, this awkard ORed depends is what we ended up doing to avoid such scenario. (Arnd advised me on this solution really...I did not have any better idea on my own) > > 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 ‘invoke_process_smt_channel’: > > > /home/crimar01/ARM/dev/src/pdsw/linux/drivers/firmware/arm_scmi/optee.c:233:27: error: ‘scmi_optee_desc’ undeclared (first use in this function); did you mean ‘scmi_smc_desc’? > > > const size_t msg_size = 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 function it appears in > > > /home/crimar01/ARM/dev/src/pdsw/linux/drivers/firmware/arm_scmi/optee.c: In function ‘setup_dynamic_shmem’: > > > /home/crimar01/ARM/dev/src/pdsw/linux/drivers/firmware/arm_scmi/optee.c:266:26: error: ‘scmi_optee_desc’ undeclared (first use in this function); did you mean ‘scmi_smc_desc’? > > > const size_t msg_size = scmi_optee_desc.max_msg_size; > > > ^~~~~~~~~~~~~~~ > > > scmi_smc_desc > > > /home/crimar01/ARM/dev/src/pdsw/linux/scripts/Makefile.build:277: recipe 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<------------------ > > > Saw the -next bot today on this...still I don't get why it is exposed only when compiling as a module OPTEE ? should not this be catched anyway being this C and this being a reference to a global declared well later ? (just to understand...) > > > diff --git a/drivers/firmware/arm_scmi/optee.c b/drivers/firmware/arm_scmi/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 = channel->channel_id; > > > > > > if (channel->tee_shm) { > > > - const size_t msg_size = scmi_optee_desc.max_msg_size; > > > + const size_t msg_size = SCMI_OPTEE_MAX_MSG_SIZE; > > > > > > param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT; > > > param[1].u.memref.shm = 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_channel *channel) > > > { > > > - const size_t msg_size = scmi_optee_desc.max_msg_size; > > > + const size_t msg_size = SCMI_OPTEE_MAX_MSG_SIZE; > > > > > > channel->tee_shm = tee_shm_alloc_kernel_buf(optee_private->tee_ctx, msg_size); > > > if (IS_ERR(channel->tee_shm)) { > > > > > > ----------------------------- > > > > > > After the above change it compiled fine, so I went a step further and configured also > > > CONFIG_TEE=m (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=y and CONFIG_TEE=m) I get: > > > > > > > > > GEN modules.builtin > > > LD .tmp_vmlinux.kallsyms1 > > > /opt/toolchains/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/aarch64-linux-gnu-ld: Unexpected GOT/PLT entries detected! > > > /opt/toolchains/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/aarch64-linux-gnu-ld: Unexpected run-time procedure linkages detected! > > > /opt/toolchains/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/aarch64-linux-gnu-ld: drivers/firmware/arm_scmi/optee.o: in function `invoke_process_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/aarch64-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/aarch64-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/aarch64-linux-gnu-ld: drivers/firmware/arm_scmi/optee.o: in function `open_session': > > > /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/aarch64-linux-gnu-ld: drivers/firmware/arm_scmi/optee.o: in function `optee_service_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/aarch64-linux-gnu-ld: drivers/firmware/arm_scmi/optee.o: in function `optee_service_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/aarch64-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/aarch64-linux-gnu-ld: drivers/firmware/arm_scmi/optee.o: in function `get_capabilities': > > > /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/aarch64-linux-gnu-ld: drivers/firmware/arm_scmi/optee.o: in function `close_session': > > > /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/aarch64-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/aarch64-linux-gnu-ld: drivers/firmware/arm_scmi/optee.o: in function `setup_dynamic_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/aarch64-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/aarch64-linux-gnu-ld: drivers/firmware/arm_scmi/optee.o: in function `close_session': > > > /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/aarch64-linux-gnu-ld: drivers/firmware/arm_scmi/optee.o:(.data+0x10): undefined reference 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_scmi/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=y || OPTEE=ARM_SCMI_PROTOCOL > > > select ARM_SCMI_HAVE_TRANSPORT > > > select ARM_SCMI_HAVE_SHMEM > > > default y > > > > > > which basically disables ARM_SCMI_TRANSPORT_OPTEE when CONFIG_OPTEE=m AND > > > ARM_SCMI_TRANSPORT_OPTEE=y: in this scenario if TEE is =m you have to build > > > ARM_SCMI_PROTOCOL=m too to be able to include ARM_SCMI_TRANSPORT_OPTEE. > > > > Fully makes sense to me. Thanks. I understand. > > As said, not elegant, but some fancy circular-deps in the Kconfig between SCMI core and transports led to this. > > > > > > > > > > config ARM_SCMI_POWER_DOMAIN > > > > diff --git a/drivers/firmware/arm_scmi/Makefile b/drivers/firmware/arm_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) += mailbox.o > > > > scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_SMC) += smc.o > > > > scmi-transport-$(CONFIG_ARM_SCMI_HAVE_MSG) += msg.o > > > > scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO) += virtio.o > > > > +scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_OPTEE) += optee.o > > > > scmi-protocols-y = base.o clock.o perf.o power.o reset.o sensors.o system.o voltage.o > > > > scmi-module-objs := $(scmi-bus-y) $(scmi-driver-y) $(scmi-protocols-y) \ > > > > $(scmi-transport-y) > > > > diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_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/aarch64-linux-gnu-ld: > > > drivers/firmware/arm_scmi/driver.o:(.rodata+0x280): undefined reference > > > 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, void *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/arm_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[] = { > > > > #endif > > > > #ifdef CONFIG_ARM_SCMI_TRANSPORT_VIRTIO > > > > { .compatible = "arm,scmi-virtio", .data = &scmi_virtio_desc}, > > > > +#endif > > > > +#ifdef CONFIG_OPTEE > > > > > > Same as above should be #if CONFIG_ARM_SCMI_TRANSPORT_OPTEE > > > > > > > + { .compatible = "linaro,scmi-optee", .data = &scmi_optee_desc }, > > > > #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 = 0, > > > > + > > > > + /* > > > > + * PTA_SCMI_CMD_PROCESS_SMT_CHANNEL - Process SCMI message in SMT buffer > > > > + * > > > > + * [in] value[0].a: Channel handle > > > > + * > > > > + * Shared memory used for SCMI message/response exhange is expected > > > > + * 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 = 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 payload) > > > > + * > > > > + * Shared memory used for SCMI message/response is a SMT buffer > > > > + * referenced by param[1]. It shall be 128 bytes large to fit response > > > > + * 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 = 2, > > > > + > > > > + /* > > > > + * PTA_SCMI_CMD_GET_CHANNEL - Get channel handle > > > > + * > > > > + * SCMI shm information are 0 if agent expects to use OP-TEE regular SHM > > > > + * > > > > + * [in] value[0].a: Channel identifier > > > > + * [out] value[0].a: Returned channel handle > > > > + * [in] value[0].b: Requested capabilities mask (enum pta_scmi_caps) > > > > + */ > > > > + PTA_SCMI_CMD_GET_CHANNEL = 3, > > > > +}; > > > > + > > > > +/* > > > > + * Capabilities > > > > + */ > > > > +enum pta_scmi_caps { > > > > + PTA_SCMI_CAPS_NONE = 0, > > > > + /* > > > > + * Supports command using SMT header protocol (SCMI shmem) in shared > > > > + * memory buffers to carry SCMI protocol synchronisation information. > > > > + */ > > > > + PTA_SCMI_CAPS_SMT_HEADER = 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 appiicable. > > Thanks, I have not a strong opinion on this, but as an optee-newbie (or ignorant if you want :D) I found it easier to reason about it. > > > > > > > > > +/* Open a session toward SCMI OP-TEE service with REE_KERNEL identity */ > > > > +static int open_session(u32 *tee_session) > > > > +{ > > > > + struct device *dev = optee_private->dev; > > > > + struct tee_client_device *scmi_pta = to_tee_client_device(dev); > > > > + struct tee_ioctl_open_session_arg arg = { }; > > > > + int ret; > > > > + > > > > + memcpy(arg.uuid, scmi_pta->id.uuid.b, TEE_IOCTL_UUID_LEN); > > > > + arg.clnt_login = TEE_IOCTL_LOGIN_REE_KERNEL; > > > > + > > > > + ret = tee_client_open_session(optee_private->tee_ctx, &arg, NULL); > > > > + if (ret < 0 || arg.ret) { > > > > + dev_err(dev, "Can't open tee session: %d / %#x\n", ret, arg.ret); > > > > + > > > > + return -EOPNOTSUPP; > > > > + } > > > > + > > > > + *tee_session = 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 = optee_private; > > > > + struct tee_ioctl_invoke_arg arg = { }; > > > > + struct tee_param param[1] = { }; > > > > + u32 tee_session; > > > > + int ret; > > > > + > > > > + ret = open_session(&tee_session); > > > > + if (ret) > > > > + return ret; > > > > + > > > > + arg.func = PTA_SCMI_CMD_CAPABILITIES; > > > > + arg.session = tee_session; > > > > + arg.num_params = 1; > > > > + > > > > + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT; > > > > + > > > > + ret = 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 = param[0].u.value.a; > > > > + > > > > + if (!(agent->caps & PTA_SCMI_CAPS_SMT_HEADER)) { > > > > + dev_err(agent->dev, "OP-TEE SCMI PTA doesn't support SMT\n"); > > > > + > > > > + return -EOPNOTSUPP; > > > > + } > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +static int get_channel(struct optee_channel *channel) > > > > +{ > > > > + struct device *dev = optee_private->dev; > > > > + struct tee_ioctl_invoke_arg arg = { }; > > > > + struct tee_param param[1] = { }; > > > > + unsigned int caps = PTA_SCMI_CAPS_SMT_HEADER; > > > > + int ret; > > > > + > > > > + arg.func = PTA_SCMI_CMD_GET_CHANNEL; > > > > + arg.session = channel->tee_session; > > > > + arg.num_params = 1; > > > > + > > > > + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT; > > > > + param[0].u.value.a = channel->channel_id; > > > > + param[0].u.value.b = caps; > > > > + > > > > + ret = tee_client_invoke_func(optee_private->tee_ctx, &arg, param); > > > > + > > > > + 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 service */ > > > > + channel->channel_id = param[0].u.value.a; > > > > + channel->caps = caps; > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +static int invoke_process_smt_channel(struct optee_channel *channel) > > > > +{ > > > > + struct tee_ioctl_invoke_arg arg = { }; > > > > + struct tee_param param[2] = { }; > > > > + int ret; > > > > + > > > > + arg.session = channel->tee_session; > > > > + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT; > > > > + param[0].u.value.a = channel->channel_id; > > > > + > > > > + if (channel->tee_shm) { > > > > + const size_t msg_size = scmi_optee_desc.max_msg_size; > > > > + > > > > + param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT; > > > > + param[1].u.memref.shm = channel->tee_shm; > > > > + param[1].u.memref.size = msg_size; > > > > + arg.num_params = 2; > > > > + arg.func = PTA_SCMI_CMD_PROCESS_SMT_CHANNEL_MESSAGE; > > > > + } else { > > > > + arg.num_params = 1; > > > > + arg.func = PTA_SCMI_CMD_PROCESS_SMT_CHANNEL; > > > > + } > > > > + > > > > + ret = tee_client_invoke_func(optee_private->tee_ctx, &arg, param); > > > > + 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_channel *channel) > > > > +{ > > > > + const size_t msg_size = scmi_optee_desc.max_msg_size; > > > > + > > > > + channel->tee_shm = tee_shm_alloc_kernel_buf(optee_private->tee_ctx, msg_size); > > > > + if (IS_ERR(channel->tee_shm)) { > > > > + dev_err(channel->cinfo->dev, "shmem allocation failed\n"); > > > > + return -ENOMEM; > > > > + } > > > > + > > > > + channel->shmem = (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_info *cinfo, > > > > + struct optee_channel *channel) > > > > +{ > > > > + struct device_node *np; > > > > + resource_size_t size; > > > > + struct resource res; > > > > + int ret; > > > > + > > > > + np = of_parse_phandle(cinfo->dev->of_node, "shmem", 0); > > > > + if (!of_device_is_compatible(np, "arm,scmi-shmem")) { > > > > + ret = -ENXIO; > > > > + goto out; > > > > + } > > > > + > > > > + ret = of_address_to_resource(np, 0, &res); > > > > + if (ret) { > > > > + dev_err(dev, "Failed to get SCMI Tx shared memory\n"); > > > > + goto out; > > > > + } > > > > + > > > > + size = resource_size(&res); > > > > + > > > > + channel->shmem = devm_ioremap(dev, res.start, size); > > > > + if (!channel->shmem) { > > > > + dev_err(dev, "Failed to ioremap SCMI Tx shared memory\n"); > > > > + ret = -EADDRNOTAVAIL; > > > > + goto out; > > > > + } > > > > + > > > > + ret = 0; > > > > + > > > > +out: > > > > + of_node_put(np); > > > > + > > > > + return ret; > > > > +} > > > > + > > > > +static int optee_chan_setup_shmem(struct device *dev, struct scmi_chan_info *cinfo, > > > > + bool tx, struct optee_channel *channel) > > > > +{ > > > > + struct device *cdev = 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 = cinfo->transport_info; > > > > + > > > > + shmem_clear_channel(channel->shmem); > > > > +} > > > > + > > > > +static int optee_chan_setup(struct scmi_chan_info *cinfo, struct device *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 = devm_kzalloc(dev, sizeof(*channel), GFP_KERNEL); > > > > + if (!channel) > > > > + return -ENOMEM; > > > > + > > > > + ret = of_property_read_u32_index(cinfo->dev->of_node, "linaro,optee-channel-id", > > > > + 0, &channel_id); > > > > + if (ret) > > > > + return ret; > > > > + > > > > + cinfo->transport_info = channel; > > > > + channel->cinfo = cinfo; > > > > + channel->channel_id = channel_id; > > > > + mutex_init(&channel->mu); > > > > + > > > > + ret = optee_chan_setup_shmem(dev, cinfo, tx, channel); > > > > + if (ret) > > > > + return ret; > > > > + > > > > + ret = open_session(&channel->tee_session); > > > > + if (ret) > > > > + return ret; > > > > + > > > > + ret = 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 = p; > > > > + struct optee_channel *channel = 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 = NULL; > > > > + } > > > > + > > > > + cinfo->transport_info = NULL; > > > > + channel->cinfo = 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 = cinfo->transport_info; > > > > + struct scmi_shared_mem *shmem = get_channel_shm(channel, xfer); > > > > + int ret; > > > > + > > > > + mutex_lock(&channel->mu); > > > > + shmem_tx_prepare(shmem, xfer); > > > > + > > > > + ret = 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. > > Ok. Maybe in the future this could benefit from some new general mechanism I'm adding in the core (with SCMI atomic series) to address this scenario in which you really do not have to wait neither poll for anything after the send and you could/should avoid calling scmi_rx_callback() and just let the SCMI core execute a fetch_response immediately after the send. (with scmi_rx_callback supposed to be called when a completion interrupt is received) So, just a heads up here, that I could revisit this (and bother you) once (if) the above mentioned SCMI atomic seris is in, BUT definitely nothing to be addressed now in this series. > > > > > > > + > > > > + 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 = cinfo->transport_info; > > > > + struct scmi_shared_mem *shmem = 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 = cinfo->transport_info; > > > > + struct scmi_shared_mem *shmem = get_channel_shm(channel, xfer); > > > > + > > > > + return shmem_poll_done(shmem, xfer); > > > > +} > > > > + > > > > +static struct scmi_transport_ops scmi_optee_ops = { > > > > + .chan_available = optee_chan_available, > > > > + .chan_setup = optee_chan_setup, > > > > + .chan_free = optee_chan_free, > > > > + .send_message = optee_send_message, > > > > + .fetch_response = optee_fetch_response, > > > > + .clear_channel = optee_clear_channel, > > > > + .poll_done = optee_poll_done, > > > > +}; > > > > + > > > > +const struct scmi_desc scmi_optee_desc = { > > > > + .ops = &scmi_optee_ops, > > > > + .max_rx_timeout_ms = 30, > > > > + .max_msg = 20, > > > > + .max_msg_size = 128, > > > > +}; > > > > + > > > > +static int optee_ctx_match(struct tee_ioctl_version_data *ver, const void *data) > > > > +{ > > > > + return ver->impl_id == 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 initialized: only one allowed\n"); > > > > + return -EBUSY; > > > > + } > > > > + > > > > + tee_ctx = tee_client_open_context(NULL, optee_ctx_match, NULL, NULL); > > > > + if (IS_ERR(tee_ctx)) > > > > + return -ENODEV; > > > > + > > > > + agent = devm_kzalloc(dev, sizeof(*agent), GFP_KERNEL); > > > > + if (!agent) { > > > > + ret = -ENOMEM; > > > > + goto out; > > > > + } > > > > + > > > > + agent->dev = dev; > > > > + agent->tee_ctx = tee_ctx; > > > > + INIT_LIST_HEAD(&agent->channel_list); > > > > + > > > > + optee_private = 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. > Yes my concern was also about multiple concurrent probing especially, even though we really do not support multiple SCMI server nodes the fact that you could define multiple channels (on optee) could lead to multiple probes, while in virtio you could wrongly try to describe multiple mmios devs (with virtio not supporting multiple devices for now...hence the check) > 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 = 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 = 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 the > * virtio channels will have been already marked NOT ready, causing any > * 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? > So my reasoning was: 1. I want to have ->priv = channels populated before scmi_dev was visible for other PEs as a global. BUT 2. want also to be sure that scmi_dev itself was visible to other PEs: what if another core is concurrently probing for another (wrongly defined in DT) scmi-virtio MMIO device ? Will scmi_dev still be viewed as NULL from another probing core for a while despite scmi_dev = vdev had been executed on the first core probe ? My hope (:D), since smp_store_mb() it's a WRITE_ONCE + __smb_mb() which in turn is a dmb(ish) on arm64, was to draw a line after which I could have been sure that scmi_dev store and all previous mem-accesses (on this core) would have at least been initiated (hit the cache) so that after that point any access from another PE would have been served properly by the magic of cache coeherency protocol on the ish domain. I could be a bit concerned indeed of an additional missing early WRITE_ONCE() on vdev->priv = channels so as to have (to avoid compiler tricks instead on vdev->priv): WRITE_ONCE(vdev->priv, channels); smp_store_mb(scmi_vdev, vdev); ..but really not sure how much this has a chance to happen. Same it goes for the remove path...once in scmi_vio_remove() I want to be at first stop/flush all pending stuff on the vqueues knowing that: 1. virtio_chan_free has been already previously called and it marked all vqueues as NOT ready, so nobody will queue anything on vdev anyway 2. any other possible probe would STILL find scmi_dev != NULL and it 'd bail out till I'm done with the remove ONLY afterwards I would made scmi_dev visible as NULL for everybody. Does this counter-reasoning makes sense ? ...OR, tbh, I have to just re-read another n-times memory-barriers.txt (...and remain a bit puzzled anyway :D) > > > > > > > + > > > > + ret = get_capabilities(); > > > > + > > > > +out: > > > > + if (ret) { > > > > + tee_client_close_context(tee_ctx); > > > > + optee_private = 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 = NULL; > > > > + > > > > > > Barrier ? (not sure as above...) > > > > > > > + return 0; > > > > +} > > > > + > > > > +static const struct tee_client_device_id scmi_optee_service_id[] = { > > > > + { > > > > + UUID_INIT(0xa8cfe406, 0xd4f5, 0x4a2e, > > > > + 0x9f, 0x8d, 0xa2, 0x5d, 0xc7, 0x54, 0xc0, 0x99) > > > > + }, > > > > + { } > > > > +}; > > > > + > > > > +MODULE_DEVICE_TABLE(tee, scmi_optee_service_id); > > > > + > > > > +static struct tee_client_driver scmi_optee_driver = { > > > > + .id_table = scmi_optee_service_id, > > > > + .driver = { > > > > + .name = "scmi-optee", > > > > + .bus = &tee_bus_type, > > > > + .probe = optee_service_probe, > > > > + .remove = 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=m and SCMI OPTEE transport is enabled, > > > since the SCMI transports are not full fledged drivers but they are built into > > > the SCMI stack core module, so if you endup trying to define multiple inits. > > > > > > LD [M] drivers/firmware/arm_scmi/scmi-module.o > > > /opt/toolchains/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/aarch64-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/driver.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/aarch64-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/driver.o:/home/crimar01/ARM/dev/src/pdsw/linux/drivers/firmware/arm_scmi/driver.c:2099: first defined he> /home/crimar01/ARM/dev/src/pdsw/linux/scripts/Makefile.build:474: recipe for target 'drivers/firmware/arm_scmi/scmi-module.o' failed > > > make[4]: *** [drivers/firmware/arm_scmi/scmi-module.o] Error 1 > > > /home/crimar01/ARM/dev/src/pdsw/linux/scripts/Makefile.build:540: recipe 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: recipe 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_initcall(). > > > > 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 = -ENODEV; > > // register to optee bus enumeration if not already successfully done > if (register_to_optee) > register_to_optee = driver_register(&scmi_optee_driver.driver); > > // 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; > } So when you raised this point in the previous mail my initial thought was that, unless we had found a good workaround, I should have started working on something I have in my backlog for long, which is supposed to handle these scenarios better: i.e. making all/or-some SCMI transport as full fledged drivers instead of keeping them embedded into the core. (not done till now since not needed and really did not want to change also that while integrating virtio) I have not started really working on this nor thought it through properly, but having a way to define a full fledged SCMI transport driver that registers with some external subsys (optee/virtio...) and then registers itself with the SCMI core itself as an available transport (with the core DEFERing till the transport layer has appeared), seemed to me the way to go to solve this kind of issues more generally. Having said that, your proposal seems the kind of workaround that could solve fine your issue now simply using what is already in the SCMI core. So I have nothing against it as an immediate solution (I'll double check with Sudeep anyway :D), but I wonder if in the long term the full-fledged transport driver approach would still make sense. > > 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); > Here you mean without the module_exit right ? So the init would be in charge of .link_supplier and its deferral mechanism but the unregister woudld go via .transport_exit = scmi_optee_exit() by the core on SCMI core unload. I would recommend placing a check on 'register_to_optee' also here on exit so that the SCMI core on its unload won't try to deregister a driver which was never successfully registered. > May I get your opinion? > I wrote way too much ... sorry. Thanks, Cristian 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 26994C433F5 for ; Tue, 19 Oct 2021 16:21:23 +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 E019A60F93 for ; Tue, 19 Oct 2021 16:21:22 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org E019A60F93 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=arm.com 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:In-Reply-To:MIME-Version:References: Message-ID:Subject:Cc:To:From:Date:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=bf6GuNydryKnf5XT6eAJ9HKidH8by78KYKoMCg1FLHQ=; b=XwNFprTvy66F5h uNxIbOHs099AxdshYsjejUjA0H0hPd9qpro73eIJAYi0jsWexcb0W/9Rmy5Ab6t9PXyBVqavG/2D9 A1bDVWLeVxof5L68f8BYOT8W0OcPcyw12tl311tGMTWX/l2NnnO4pruMSdKuU7OaCpvhzZel1vko5 0SnOxmvAmBrwByDxYq3E/QA6KT6xlPJKVbEuXoiYJi+LM+SIJQzVOZ6oLHUHXWrayyP5zvrzFpwq1 b/imIm6XZagWGheBLwlpx5uC4FIiDt5ap7OiiU5QJDijENQza2ChE3VTSEEExLLjZ9+DzSgieeKFL etwTgTM40i9Wbbm+s2tQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mcrqG-001u0z-FP; Tue, 19 Oct 2021 16:19:56 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mcrq8-001tz3-68 for linux-arm-kernel@lists.infradead.org; Tue, 19 Oct 2021 16:19:53 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 6673C2F; Tue, 19 Oct 2021 09:19:47 -0700 (PDT) Received: from e120937-lin (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 281F13F694; Tue, 19 Oct 2021 09:19:46 -0700 (PDT) Date: Tue, 19 Oct 2021 17:19:43 +0100 From: Cristian Marussi To: Etienne Carriere Cc: linux-kernel@vger.kernel.org, "moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE" , Sudeep Holla , Vincent Guittot Subject: Re: [PATCH v3 2/2] firmware: arm_scmi: Add optee transport Message-ID: <20211019161943.GB6526@e120937-lin> References: <20211018114046.25571-1-etienne.carriere@linaro.org> <20211018114046.25571-2-etienne.carriere@linaro.org> <20211018194317.GA6526@e120937-lin> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.9.4 (2018-02-28) X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211019_091948_470569_6ECB4309 X-CRM114-Status: GOOD ( 59.95 ) 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 T24gVHVlLCBPY3QgMTksIDIwMjEgYXQgMDQ6MjQ6MzBQTSArMDIwMCwgRXRpZW5uZSBDYXJyaWVy ZSB3cm90ZToKPiBIaSwKPiAKCkhpIEV0aWVubmUsCgpJIHdhcyByZXBseWluZyB0byB0aGUgcHJl dmlvdXMgb25lLCBzbyBJJ2xsIHN0aWNrIGFsbCBteSBhbnN3ZXJzIHRvZ2V0ZWhyCmluIHRoaXMg bGFzdCBlbWFpbCBpbnN0ZWFkIDpECgo+IE9uIFR1ZSwgMTkgT2N0IDIwMjEgYXQgMTE6MTAsIEV0 aWVubmUgQ2FycmllcmUKPiA8ZXRpZW5uZS5jYXJyaWVyZUBsaW5hcm8ub3JnPiB3cm90ZToKPiA+ Cj4gPiAgSGVsbG8gQ3Jpc3RpYW4sCj4gPgo+ID4gVGhhbmtzIGEgbG90IGZvciB0aGUgcmV2aWV3 Lgo+ID4gSSBzZWUgSSBkaWRuJ3QgdW5kZXJzdGFuZCBhbmQgdXNlIGNvcnJlY3RseSB0aGUgY29u ZmlnIHN3aXRjaCBmb3IgdGhlIHRyYW5zcG9ydC4KPiA+IFRoYW5rcyBmb3IgYWxsIHRoZSBmaXhl cyB5b3Ugc2VudCwgaSdsbCBpbnRlZ3JhdGUgdGhlbSBpbiB0aGUgcGF0Y2ggdjQuCj4gPgoKQXMg YSBzaWRlIHRoaW5nIG9uIHRoaXMgJ2RlcGVuZHMgb24nLCBJJ20gYWxzbyBhIGJpdCBwdXp6bGVk IGJ5IHRoZSBmYWN0IHRoZQpkZXBlbmRzIGlzIG9uIENPTkZJR19PUFRFRSBidXQgc29tZSBlcnJv cnMgb2YgdGhlIGFib3ZlIGFwcGVhciByZWFsbHkgb24KQ09ORklHX1RFRT1tIHNpbmNlIHRoZSBz Y21pX29wdGVlIGlzIHJlYWxseSB1c2luZyB0aGUgZ2VuZXJpYyB0ZWVfIEFQSQp3aGljaCBpbiB0 dXJuIG5lZWRzL3VzZXMgQ09ORklHX09QVEVFIGluIHRoaXMgY2FzZSAoaWYgSSBnb3QgaXQgcmln aHQKQUZBSVUuLi5ub3QgcmVhbGx5IGFuIE9QVEVFIGV4cGVydCBoZXJlIDo+KS4uLmJ1dCBtYXli ZSBDT05GSUdfT1BURUUgaXMKanVzdCB0aGUgZWFzaWVyIGFuZCBtb3N0IGNvcnJlY3QgdGhpbmcg d2UgY2FuIGRvLgoKPiA+IEkgZG9uJ3Qga25vdyB5ZXQgaG93IHRvIGFkZHJlc3MgeW91ciBsYXN0 IGNvbW1lbnQuIFNlZSBteSBmZWVkYmFjayBvbgo+ID4gdGhlIG9wdGVlIGJ1cyBkZXBlbmRlbmN5 IGlzc3VlLgo+ID4KClNlZSBiZWxvdy4KCj4gPgo+ID4KPiA+IE9uIE1vbiwgMTggT2N0IDIwMjEg YXQgMjE6NDMsIENyaXN0aWFuIE1hcnVzc2kgPGNyaXN0aWFuLm1hcnVzc2lAYXJtLmNvbT4gd3Jv dGU6Cj4gPiA+Cj4gPiA+IE9uIE1vbiwgT2N0IDE4LCAyMDIxIGF0IDAxOjQwOjQ2UE0gKzAyMDAs IEV0aWVubmUgQ2FycmllcmUgd3JvdGU6Cj4gPiA+ID4gQWRkIGEgbmV3IHRyYW5zcG9ydCBjaGFu bmVsIHRvIHRoZSBTQ01JIGZpcm13YXJlIGludGVyZmFjZSBkcml2ZXIgZm9yCj4gPiA+ID4gU0NN SSBtZXNzYWdlIGV4Y2hhbmdlIGJhc2VkIG9uIG9wdGVlIHRyYW5zcG9ydCBjaGFubmVsLiBUaGUg b3B0ZWUKPiA+ID4gPiB0cmFuc3BvcnQgaXMgcmVhbGl6ZWQgYnkgY29ubmVjdGluZyBhbmQgaW52 b2tpbmcgT1AtVEVFIFNDTUkgc2VydmljZQo+ID4gPiA+IGludGVyZmFjZSBQVEEuCj4gPiA+ID4K PiA+ID4gPiBPcHRlZSB0cmFuc3BvcnQgc3VwcG9ydCAoQ09ORklHX0FSTV9TQ01JX1RSQU5TUE9S VF9PUFRFRSkgaXMgZGVmYXVsdAo+ID4gPiA+IGVuYWJsZWQgd2hlbiBvcHRlZSBkcml2ZXIgKENG R19PUFRFRSkgaXMgZW5hYmxlZC4gRWZmZWN0aXZlIG9wdGVlCj4gPiA+ID4gdHJhbnNwb3J0IGlz IHNldHVwIHVwb24gT1AtVEVFIFNDTUkgc2VydmljZSBkaXNjb3ZlcnkgYXQgb3B0ZWUKPiA+ID4g PiBkZXZpY2UgaW5pdGlhbGl6YXRpb24uIEZvciB0aGlzIFNDTUkgVVVJRCBpcyByZWdpc3RlcmVk IHRvIHRoZSBvcHRlZQo+ID4gPiA+IGJ1cyBmb3IgcHJvYmluZy4gVGhpcyBpcyBkb25lIGF0IGRl dmljZV9pbml0IGluaXRjYWxsIGxldmVsLCBhZnRlcgo+ID4gPiA+IG9wdGVlIGJ1cyBpbml0aWFs aXphdGlvbiB0aGF0IGlzIGRvbmUgYXQgc3Vic3lzX2luaXQgbGV2ZWwsIGFzIHRoZSBzY21pCj4g PiA+ID4gZHJpdmVyIGluaXRpYWxpemF0aW9uLgo+ID4gPiA+Cj4gPiA+ID4gVGhlIG9wdGVlIHRy YW5zcG9ydCBjYW4gdXNlIGEgc3RhdGljYWxseSBkZWZpbmVkIHNoYXJlZCBtZW1vcnkgaW4KPiA+ ID4gPiB3aGljaCBjYXNlIFNDTUkgZGV2aWNlIHRyZWUgbm9kZSBkZWZpbmVzIGl0IHVzaW5nIGFu ICJhcm0sc2NtaS1zaG1lbSIKPiA+ID4gPiBjb21wYXRpYmxlIHBoYW5kbGUgdGhyb3VnaCBwcm9w ZXJ0eSBzaG1lbS4gQWx0ZXJuYXRpdmVseSwgb3B0ZWUgdHJhbnNwb3J0Cj4gPiA+ID4gYWxsb2Nh dGVzIHRoZSBzaGFyZWQgbWVtb3J5IGJ1ZmZlciBmcm9tIHRoZSBvcHRlZSBkcml2ZXIgd2hlbiBu byBzaG1lbQo+ID4gPiA+IHByb3BlcnR5IGlzIGRlZmluZWQuCj4gPiA+ID4KPiA+ID4gPiBUaGUg cHJvdG9jb2wgdXNlZCB0byBleGNoYW5nZSBTQ01JIG1lc3NhZ2Ugb3ZlciB0aGF0IHNoYXJlZCBt ZW1vcnkgaXMKPiA+ID4gPiBuZWdvdGlhdGVkIGJldHdlZW4gb3B0ZWUgdHJhbnNwb3J0IGRyaXZl ciBhbmQgdGhlIE9QLVRFRSBzZXJ2aWNlIHRocm91Z2gKPiA+ID4gPiBjYXBhYmlsaXRpZXMgZXhj aGFuZ2UuCj4gPiA+ID4KPiA+ID4gPiBPUC1URUUgU0NNSSBzZXJ2aWNlIGlzIGludGVncmF0ZWQg aW4gT1AtVEVFIHNpbmNlIGl0cyByZWxlYXNlIHRhZyAzLjEzLjAuCj4gPiA+ID4gVGhlIHNlcnZp Y2UgaW50ZXJmYWNlIGlzIHB1Ymxpc2hlZCBpbiBbMV0uCj4gPiA+ID4KPiA+ID4gPiBMaW5rOiBb MV0gaHR0cHM6Ly9naXRodWIuY29tL09QLVRFRS9vcHRlZV9vcy9ibG9iLzMuMTMuMC9saWIvbGli dXRlZS9pbmNsdWRlL3B0YV9zY21pX2NsaWVudC5oCj4gPiA+ID4gQ2M6IENyaXN0aWFuIE1hcnVz c2kgPGNyaXN0aWFuLm1hcnVzc2lAYXJtLmNvbT4KPiA+ID4gPiBDYzogU3VkZWVwIEhvbGxhIDxz dWRlZXAuaG9sbGFAYXJtLmNvbT4KPiA+ID4gPiBTaWduZWQtb2ZmLWJ5OiBFdGllbm5lIENhcnJp ZXJlIDxldGllbm5lLmNhcnJpZXJlQGxpbmFyby5vcmc+Cj4gPiA+ID4gLS0tCj4gPiA+ID4gQ2hh bmdlcyBzaW5jZSB2MjoKPiA+ID4gPiAtIFJlYmFzZSBvbiBmb3ItbmV4dC9zY21pLCBiYXNlZCBv biBMaW51eCB2NS4xNS1yYzEuCj4gPiA+ID4gLSBJbXBsZW1lbnQgc3VwcG9ydCBmb3IgZHluYW1p YyBhbmQgc3RhdGljIHNoYXJlZCBtZW1vcnkuCj4gPiA+ID4gLSBGYWN0b3JpemUgc29tZSBmdW5j dGlvbnMgYW5kIHNpbXBsaWZ5IHRyYW5zcG9ydCBleGl0IHNlcXVlbmNlLgo+ID4gPiA+IC0gUmVu YW1lIGRyaXZlciBzb3VyY2UgZmlsZSBmcm9tIG9wdGVlX3NlcnZpY2UuYyB0byBvcHRlZS5jLgo+ ID4gPiA+Cj4gPiA+ID4gTm8gY2hhbmdlIHNpbmNlIHYxCj4gPiA+ID4gLS0tCj4gPiA+Cj4gPiA+ IEhpIEV0aWVubmUsCj4gPiA+Cj4gPiA+IGEgZmV3IHJlbWFya3MgYmVsb3cuCj4gPiA+Cj4gPiA+ ID4gIGRyaXZlcnMvZmlybXdhcmUvYXJtX3NjbWkvS2NvbmZpZyAgfCAgMTIgKwo+ID4gPiA+ICBk cml2ZXJzL2Zpcm13YXJlL2FybV9zY21pL01ha2VmaWxlIHwgICAxICsKPiA+ID4gPiAgZHJpdmVy cy9maXJtd2FyZS9hcm1fc2NtaS9jb21tb24uaCB8ICAgMyArCj4gPiA+ID4gIGRyaXZlcnMvZmly bXdhcmUvYXJtX3NjbWkvZHJpdmVyLmMgfCAgIDMgKwo+ID4gPiA+ICBkcml2ZXJzL2Zpcm13YXJl L2FybV9zY21pL29wdGVlLmMgIHwgNTU5ICsrKysrKysrKysrKysrKysrKysrKysrKysrKysrCj4g PiA+ID4gIDUgZmlsZXMgY2hhbmdlZCwgNTc4IGluc2VydGlvbnMoKykKPiA+ID4gPiAgY3JlYXRl IG1vZGUgMTAwNjQ0IGRyaXZlcnMvZmlybXdhcmUvYXJtX3NjbWkvb3B0ZWUuYwo+ID4gPiA+Cj4g PiA+ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZmlybXdhcmUvYXJtX3NjbWkvS2NvbmZpZyBiL2Ry aXZlcnMvZmlybXdhcmUvYXJtX3NjbWkvS2NvbmZpZwo+ID4gPiA+IGluZGV4IDNkNzA4MWU4NDg1 My4uOTEwN2UyNDkwMjNjIDEwMDY0NAo+ID4gPiA+IC0tLSBhL2RyaXZlcnMvZmlybXdhcmUvYXJt X3NjbWkvS2NvbmZpZwo+ID4gPiA+ICsrKyBiL2RyaXZlcnMvZmlybXdhcmUvYXJtX3NjbWkvS2Nv bmZpZwo+ID4gPiA+IEBAIC03Nyw2ICs3NywxOCBAQCBjb25maWcgQVJNX1NDTUlfVFJBTlNQT1JU X1ZJUlRJTwo+ID4gPiA+ICAgICAgICAgSWYgeW91IHdhbnQgdGhlIEFSTSBTQ01JIFBST1RPQ09M IHN0YWNrIHRvIGluY2x1ZGUgc3VwcG9ydCBmb3IgYQo+ID4gPiA+ICAgICAgICAgdHJhbnNwb3J0 IGJhc2VkIG9uIFZpcnRJTywgYW5zd2VyIFkuCj4gPiA+ID4KPiA+ID4gPiArY29uZmlnIEFSTV9T Q01JX1RSQU5TUE9SVF9PUFRFRQo+ID4gPiA+ICsgICAgIGJvb2wgIlNDTUkgdHJhbnNwb3J0IGJh c2VkIG9uIE9QLVRFRSBzZXJ2aWNlIgo+ID4gPiA+ICsgICAgIGRlcGVuZHMgb24gT1BURUUKPiA+ ID4gPiArICAgICBzZWxlY3QgQVJNX1NDTUlfSEFWRV9UUkFOU1BPUlQKPiA+ID4gPiArICAgICBz ZWxlY3QgQVJNX1NDTUlfSEFWRV9TSE1FTQo+ID4gPiA+ICsgICAgIGRlZmF1bHQgeQo+ID4gPiA+ ICsgICAgIGhlbHAKPiA+ID4gPiArICAgICAgIFRoaXMgZW5hYmxlcyB0aGUgT1AtVEVFIHNlcnZp Y2UgYmFzZWQgdHJhbnNwb3J0IGZvciBTQ01JLgo+ID4gPiA+ICsKPiA+ID4gPiArICAgICAgIElm IHlvdSB3YW50IHRoZSBBUk0gU0NNSSBQUk9UT0NPTCBzdGFjayB0byBpbmNsdWRlIHN1cHBvcnQg Zm9yIGEKPiA+ID4gPiArICAgICAgIHRyYW5zcG9ydCBiYXNlZCBvbiBPUC1URUUgU0NNSSBzZXJ2 aWNlLCBhbnN3ZXIgWS4KPiA+ID4gPiArCj4gPiA+ID4gIGVuZGlmICNBUk1fU0NNSV9QUk9UT0NP TAo+ID4gPiA+Cj4gPiA+Cj4gPiA+IFNvIHRoaXMgJ2RlcGVuZHMgb24gT1BURUUnIHJlbWluZGVk IG1lIG9mIGEgc2ltaWxhciBpc3N1ZSBvbiBWSVJUSU8KPiA+ID4gdHJhbnNwb3J0IHNwb3R0ZWQg YnkgYSBib3QgKHNlZSB0aGUgZml4IGZvciBWaXJ0aW8gYXQ6IGM5MDUyMWEwZTk0ZiBmaXJtd2Fy ZToKPiA+ID4gYXJtX3NjbWk6IEZpeCB2aXJ0aW8gdHJhbnNwb3J0IEtjb25maWcgZGVwZW5kZW5j eSksIHRoYXQgY29uc2lzdGUgaW4gYSBicm9rZW4KPiA+ID4gYnVpbGQgd2hlbiBTQ01JIHdhcyBj b21waWxlZCBidWlsdC1pbiB3aXRoIFZJUlRJTyB0cmFuc3BvcnQgc3VwcG9ydCB3aXRoCj4gPiA+ IEFSTV9TQ01JX1BST1RPQ09MPXkgd2hpbGUgdGhlIGNvcmUgd2FzIENPTkZJR19WSVJUSU89bS4K PiA+ID4KPiA+ID4gU28gSSB0cmllZCBzaW1pbGFybHkgdG8gc2V0IENPTkZJR19PUFRFRT1tIHdo aWxlIGtlZXBpbmcgQVJNX1NDTUlfUFJPVE9DT0w9eQo+ID4gPiBleHBlY3RpbmcgdG8gc2VlIGEg c2ltaWxhciBpc3N1ZSBhcyBpbiBWaXJ0SU8gKGkuZS4gbm90IGJlaW5nIGFibGUgdG8gYWNjZXNz Cj4gPiA+IG9wdGVlIG1vZHVsZSBzeW1ib2xzIGZyb20gdGhlIGJ1aWx0aW4gU0NNSSksIGluc3Rl YWQgSSBzcG90dGVkIGEgZGlmZmVyZW50IGJ1ZyA6RAo+ID4KPiA+IFNvcnJ5LCBJIGRpZG4ndCB0 cnkgdGhpcyBjb25maWcgKG9wdGVlPW0gLyBzY21pPXkpLiBJIHRob3VnaCBleHBlY3RpbmcKPiA+ IHNjbWkgb3ZlciBvcHRlZSBhbmQgc2NtaT15IHdvdWxkIG1hbmRhdGUgb3B0ZWU9eS4KCldlbGws IHllcywgYnV0IGR1ZSB0byBhIGRhbmNlIG9mIGNpcmN1bGFyLWRlcHMgaW4gS2NvbmZpZyB3aGlj aCBJIGNvdWxkCm5vdCBmaW5kIGEgd2F5IHRvIGF2b2lkLCB0aGlzIGF3a2FyZCBPUmVkIGRlcGVu ZHMgaXMgd2hhdCB3ZSBlbmRlZCB1cApkb2luZyB0byBhdm9pZCBzdWNoIHNjZW5hcmlvLiAoQXJu ZCBhZHZpc2VkIG1lIG9uIHRoaXMgc29sdXRpb24KcmVhbGx5Li4uSSBkaWQgbm90IGhhdmUgYW55 IGJldHRlciBpZGVhIG9uIG15IG93bikKCj4gPiBGb3IgdGhlIGZpeHVwIHlvdSBwcm9wb3NlIGJl bG93LCBpIHVuZGVyc3RhbmQgaG93IHlvdSBhZGRyZXNzIHRoZQo+ID4gY29uZmlndXJhdGlvbiBk ZXBlbmRlbmNpZXMuCj4gPgo+ID4gPgo+ID4gPiAgIEFSICAgICAgZHJpdmVycy9iYXNlL2J1aWx0 LWluLmEKPiA+ID4gL2hvbWUvY3JpbWFyMDEvQVJNL2Rldi9zcmMvcGRzdy9saW51eC9kcml2ZXJz L2Zpcm13YXJlL2FybV9zY21pL29wdGVlLmM6IEluIGZ1bmN0aW9uIOKAmGludm9rZV9wcm9jZXNz X3NtdF9jaGFubmVs4oCZOgo+ID4gPiAvaG9tZS9jcmltYXIwMS9BUk0vZGV2L3NyYy9wZHN3L2xp bnV4L2RyaXZlcnMvZmlybXdhcmUvYXJtX3NjbWkvb3B0ZWUuYzoyMzM6Mjc6IGVycm9yOiDigJhz Y21pX29wdGVlX2Rlc2PigJkgdW5kZWNsYXJlZCAoZmlyc3QgdXNlIGluIHRoaXMgZnVuY3Rpb24p OyBkaWQgeW91IG1lYW4g4oCYc2NtaV9zbWNfZGVzY+KAmT8KPiA+ID4gICAgY29uc3Qgc2l6ZV90 IG1zZ19zaXplID0gc2NtaV9vcHRlZV9kZXNjLm1heF9tc2dfc2l6ZTsKPiA+ID4gICAgICAgICAg ICAgICAgICAgICAgICAgICAgXn5+fn5+fn5+fn5+fn5+Cj4gPiA+ICAgICAgICAgICAgICAgICAg ICAgICAgICAgIHNjbWlfc21jX2Rlc2MKPiA+ID4gL2hvbWUvY3JpbWFyMDEvQVJNL2Rldi9zcmMv cGRzdy9saW51eC9kcml2ZXJzL2Zpcm13YXJlL2FybV9zY21pL29wdGVlLmM6MjMzOjI3OiBub3Rl OiBlYWNoIHVuZGVjbGFyZWQgaWRlbnRpZmllciBpcyByZXBvcnRlZCBvbmx5IG9uY2UgZm9yIGVh Y2ggZnVuY3Rpb24gaXQgYXBwZWFycyBpbgo+ID4gPiAvaG9tZS9jcmltYXIwMS9BUk0vZGV2L3Ny Yy9wZHN3L2xpbnV4L2RyaXZlcnMvZmlybXdhcmUvYXJtX3NjbWkvb3B0ZWUuYzogSW4gZnVuY3Rp b24g4oCYc2V0dXBfZHluYW1pY19zaG1lbeKAmToKPiA+ID4gL2hvbWUvY3JpbWFyMDEvQVJNL2Rl di9zcmMvcGRzdy9saW51eC9kcml2ZXJzL2Zpcm13YXJlL2FybV9zY21pL29wdGVlLmM6MjY2OjI2 OiBlcnJvcjog4oCYc2NtaV9vcHRlZV9kZXNj4oCZIHVuZGVjbGFyZWQgKGZpcnN0IHVzZSBpbiB0 aGlzIGZ1bmN0aW9uKTsgZGlkIHlvdSBtZWFuIOKAmHNjbWlfc21jX2Rlc2PigJk/Cj4gPiA+ICAg Y29uc3Qgc2l6ZV90IG1zZ19zaXplID0gc2NtaV9vcHRlZV9kZXNjLm1heF9tc2dfc2l6ZTsKPiA+ ID4gICAgICAgICAgICAgICAgICAgICAgICAgICBefn5+fn5+fn5+fn5+fn4KPiA+ID4gICAgICAg ICAgICAgICAgICAgICAgICAgICBzY21pX3NtY19kZXNjCj4gPiA+IC9ob21lL2NyaW1hcjAxL0FS TS9kZXYvc3JjL3Bkc3cvbGludXgvc2NyaXB0cy9NYWtlZmlsZS5idWlsZDoyNzc6IHJlY2lwZSBm b3IgdGFyZ2V0ICdkcml2ZXJzL2Zpcm13YXJlL2FybV9zY21pL29wdGVlLm8nIGZhaWxlZAo+ID4g PiBtYWtlWzRdOiAqKiogW2RyaXZlcnMvZmlybXdhcmUvYXJtX3NjbWkvb3B0ZWUub10gRXJyb3Ig MQo+ID4gPiBtYWtlWzRdOiAqKiogV2FpdGluZyBmb3IgdW5maW5pc2hlZCBqb2JzLi4uLgo+ID4g Pgo+ID4gPiBJbiBmYWN0IHRob3NlIHNjbWlfb3B0ZWVfZGVzYyBhcmUgcmVmZXJlbmNlIHRvIGEg Z2xvYmFsIG9ubHkgZGVjbGFyZWQKPiA+ID4gZG93biBiZWxvdy4gRml4ZWQgd2l0aCBhIGZldyBk ZWZpbmVzIHRvIGNhcnJ5IG9uOgo+ID4gPgo+ID4gPiAtLS04PC0tLS0tLS0tLS0tLS0tLS0tLQo+ ID4gPgoKU2F3IHRoZSAtbmV4dCBib3QgdG9kYXkgb24gdGhpcy4uLnN0aWxsIEkgZG9uJ3QgZ2V0 IHdoeSBpdCBpcyBleHBvc2VkCm9ubHkgd2hlbiBjb21waWxpbmcgYXMgYSBtb2R1bGUgT1BURUUg PyBzaG91bGQgbm90IHRoaXMgYmUgY2F0Y2hlZAphbnl3YXkgYmVpbmcgdGhpcyBDIGFuZCB0aGlz IGJlaW5nIGEgcmVmZXJlbmNlIHRvIGEgZ2xvYmFsIGRlY2xhcmVkCndlbGwgbGF0ZXIgPyAoanVz dCB0byB1bmRlcnN0YW5kLi4uKQoKPiA+ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZmlybXdhcmUv YXJtX3NjbWkvb3B0ZWUuYyBiL2RyaXZlcnMvZmlybXdhcmUvYXJtX3NjbWkvb3B0ZWUuYwo+ID4g PiBpbmRleCA2NGFhYmE0YThiZjIuLjkzYTg0YzkxNDU3YiAxMDA2NDQKPiA+ID4gLS0tIGEvZHJp dmVycy9maXJtd2FyZS9hcm1fc2NtaS9vcHRlZS5jCj4gPiA+ICsrKyBiL2RyaXZlcnMvZmlybXdh cmUvYXJtX3NjbWkvb3B0ZWUuYwo+ID4gPiBAQCAtMTgsNiArMTgsOCBAQAo+ID4gPgo+ID4gPiAg I2RlZmluZSBEUklWRVJfTkFNRSAib3B0ZWUtc2NtaSIKPiA+ID4KPiA+ID4gKyNkZWZpbmUgU0NN SV9PUFRFRV9NQVhfTVNHX1NJWkUgICAgICAgICAgICAgICAgMTI4Cj4gPiA+ICsKPiA+ID4gIGVu dW0gb3B0ZWVfc21jaV9wdGFfY21kIHsKPiA+ID4gICAgICAgICAvKgo+ID4gPiAgICAgICAgICAq IFBUQV9TQ01JX0NNRF9DQVBBQklMSVRJRVMgLSBHZXQgY2hhbm5lbCBjYXBhYmlsaXRpZXMKPiA+ ID4gQEAgLTIzMCw3ICsyMzIsNyBAQCBzdGF0aWMgaW50IGludm9rZV9wcm9jZXNzX3NtdF9jaGFu bmVsKHN0cnVjdCBvcHRlZV9jaGFubmVsICpjaGFubmVsKQo+ID4gPiAgICAgICAgIHBhcmFtWzBd LnUudmFsdWUuYSA9IGNoYW5uZWwtPmNoYW5uZWxfaWQ7Cj4gPiA+Cj4gPiA+ICAgICAgICAgaWYg KGNoYW5uZWwtPnRlZV9zaG0pIHsKPiA+ID4gLSAgICAgICAgICAgICAgIGNvbnN0IHNpemVfdCBt c2dfc2l6ZSA9IHNjbWlfb3B0ZWVfZGVzYy5tYXhfbXNnX3NpemU7Cj4gPiA+ICsgICAgICAgICAg ICAgICBjb25zdCBzaXplX3QgbXNnX3NpemUgPSBTQ01JX09QVEVFX01BWF9NU0dfU0laRTsKPiA+ ID4KPiA+ID4gICAgICAgICAgICAgICAgIHBhcmFtWzFdLmF0dHIgPSBURUVfSU9DVExfUEFSQU1f QVRUUl9UWVBFX01FTVJFRl9JTk9VVDsKPiA+ID4gICAgICAgICAgICAgICAgIHBhcmFtWzFdLnUu bWVtcmVmLnNobSA9IGNoYW5uZWwtPnRlZV9zaG07Cj4gPiA+IEBAIC0yNjMsNyArMjY1LDcgQEAg c3RhdGljIGJvb2wgb3B0ZWVfY2hhbl9hdmFpbGFibGUoc3RydWN0IGRldmljZSAqZGV2LCBpbnQg aWR4KQo+ID4gPgo+ID4gPiAgc3RhdGljIGludCBzZXR1cF9keW5hbWljX3NobWVtKHN0cnVjdCBk ZXZpY2UgKmRldiwgc3RydWN0IG9wdGVlX2NoYW5uZWwgKmNoYW5uZWwpCj4gPiA+ICB7Cj4gPiA+ IC0gICAgICAgY29uc3Qgc2l6ZV90IG1zZ19zaXplID0gc2NtaV9vcHRlZV9kZXNjLm1heF9tc2df c2l6ZTsKPiA+ID4gKyAgICAgICBjb25zdCBzaXplX3QgbXNnX3NpemUgPSBTQ01JX09QVEVFX01B WF9NU0dfU0laRTsKPiA+ID4KPiA+ID4gICAgICAgICBjaGFubmVsLT50ZWVfc2htID0gdGVlX3No bV9hbGxvY19rZXJuZWxfYnVmKG9wdGVlX3ByaXZhdGUtPnRlZV9jdHgsIG1zZ19zaXplKTsKPiA+ ID4gICAgICAgICBpZiAoSVNfRVJSKGNoYW5uZWwtPnRlZV9zaG0pKSB7Cj4gPiA+Cj4gPiA+IC0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCj4gPiA+Cj4gPiA+IEFmdGVyIHRoZSBhYm92ZSBj aGFuZ2UgaXQgY29tcGlsZWQgZmluZSwgc28gSSB3ZW50IGEgc3RlcCBmdXJ0aGVyIGFuZCBjb25m aWd1cmVkIGFsc28KPiA+ID4gQ09ORklHX1RFRT1tIChqdXN0IHRyeWluZyB0byByZXByb2R1Y2Ug d2hhdCBib3Qgc2F3IG9uIHNpbWlsYXIgVmlydElPIGVlaC4uLi4gbm90IHRoYXQKPiA+ID4gSSBh bSBzbyBldmlsIGFuZCBzYWRpYyA6RCkKPiA+ID4KPiA+ID4gQW5kIGluZGVlZCBub3cgKHdpdGgg QVJNX1NDTUlfUFJPVE9DT0w9eSBhbmQgQ09ORklHX1RFRT1tKSBJIGdldDoKPiA+ID4KPiA+ID4K PiA+ID4gICBHRU4gICAgIG1vZHVsZXMuYnVpbHRpbgo+ID4gPiAgIExEICAgICAgLnRtcF92bWxp bnV4LmthbGxzeW1zMQo+ID4gPiAvb3B0L3Rvb2xjaGFpbnMvZ2NjLWFybS04LjMtMjAxOS4wMy14 ODZfNjQtYWFyY2g2NC1saW51eC1nbnUvYmluL2FhcmNoNjQtbGludXgtZ251LWxkOiBVbmV4cGVj dGVkIEdPVC9QTFQgZW50cmllcyBkZXRlY3RlZCEKPiA+ID4gL29wdC90b29sY2hhaW5zL2djYy1h cm0tOC4zLTIwMTkuMDMteDg2XzY0LWFhcmNoNjQtbGludXgtZ251L2Jpbi9hYXJjaDY0LWxpbnV4 LWdudS1sZDogVW5leHBlY3RlZCBydW4tdGltZSBwcm9jZWR1cmUgbGlua2FnZXMgZGV0ZWN0ZWQh Cj4gPiA+IC9vcHQvdG9vbGNoYWlucy9nY2MtYXJtLTguMy0yMDE5LjAzLXg4Nl82NC1hYXJjaDY0 LWxpbnV4LWdudS9iaW4vYWFyY2g2NC1saW51eC1nbnUtbGQ6IGRyaXZlcnMvZmlybXdhcmUvYXJt X3NjbWkvb3B0ZWUubzogaW4gZnVuY3Rpb24gYGludm9rZV9wcm9jZXNzX3NtdF9jaGFubmVsJzoK PiA+ID4gL2hvbWUvY3JpbWFyMDEvQVJNL2Rldi9zcmMvcGRzdy9saW51eC9kcml2ZXJzL2Zpcm13 YXJlL2FybV9zY21pL29wdGVlLmM6MjQ3OiB1bmRlZmluZWQgcmVmZXJlbmNlIHRvIGB0ZWVfY2xp ZW50X2ludm9rZV9mdW5jJwo+ID4gPiAvb3B0L3Rvb2xjaGFpbnMvZ2NjLWFybS04LjMtMjAxOS4w My14ODZfNjQtYWFyY2g2NC1saW51eC1nbnUvYmluL2FhcmNoNjQtbGludXgtZ251LWxkOiAvaG9t ZS9jcmltYXIwMS9BUk0vZGV2L3NyYy9wZHN3L2xpbnV4L2RyaXZlcnMvZmlybXdhcmUvYXJtX3Nj bWkvb3B0ZWUuYzoyNDc6IHVuZGVmaW5lZCByZWZlcmVuY2UgdG8gYHRlZV9jbGllbnRfaW52b2tl X2Z1bmMnCj4gPiA+IC9vcHQvdG9vbGNoYWlucy9nY2MtYXJtLTguMy0yMDE5LjAzLXg4Nl82NC1h YXJjaDY0LWxpbnV4LWdudS9iaW4vYWFyY2g2NC1saW51eC1nbnUtbGQ6IGRyaXZlcnMvZmlybXdh cmUvYXJtX3NjbWkvb3B0ZWUubzogaW4gZnVuY3Rpb24gYG9wdGVlX2NoYW5fZnJlZSc6Cj4gPiA+ IC9ob21lL2NyaW1hcjAxL0FSTS9kZXYvc3JjL3Bkc3cvbGludXgvZHJpdmVycy9maXJtd2FyZS9h cm1fc2NtaS9vcHRlZS5jOjM5NzogdW5kZWZpbmVkIHJlZmVyZW5jZSB0byBgdGVlX3NobV9mcmVl Jwo+ID4gPiAvb3B0L3Rvb2xjaGFpbnMvZ2NjLWFybS04LjMtMjAxOS4wMy14ODZfNjQtYWFyY2g2 NC1saW51eC1nbnUvYmluL2FhcmNoNjQtbGludXgtZ251LWxkOiBkcml2ZXJzL2Zpcm13YXJlL2Fy bV9zY21pL29wdGVlLm86IGluIGZ1bmN0aW9uIGBvcGVuX3Nlc3Npb24nOgo+ID4gPiAvaG9tZS9j cmltYXIwMS9BUk0vZGV2L3NyYy9wZHN3L2xpbnV4L2RyaXZlcnMvZmlybXdhcmUvYXJtX3NjbWkv b3B0ZWUuYzoxMzc6IHVuZGVmaW5lZCByZWZlcmVuY2UgdG8gYHRlZV9jbGllbnRfb3Blbl9zZXNz aW9uJwo+ID4gPiAvb3B0L3Rvb2xjaGFpbnMvZ2NjLWFybS04LjMtMjAxOS4wMy14ODZfNjQtYWFy Y2g2NC1saW51eC1nbnUvYmluL2FhcmNoNjQtbGludXgtZ251LWxkOiBkcml2ZXJzL2Zpcm13YXJl L2FybV9zY21pL29wdGVlLm86IGluIGZ1bmN0aW9uIGBvcHRlZV9zZXJ2aWNlX3JlbW92ZSc6Cj4g PiA+IC9ob21lL2NyaW1hcjAxL0FSTS9kZXYvc3JjL3Bkc3cvbGludXgvZHJpdmVycy9maXJtd2Fy ZS9hcm1fc2NtaS9vcHRlZS5jOjUxNjogdW5kZWZpbmVkIHJlZmVyZW5jZSB0byBgdGVlX2NsaWVu dF9jbG9zZV9jb250ZXh0Jwo+ID4gPiAvb3B0L3Rvb2xjaGFpbnMvZ2NjLWFybS04LjMtMjAxOS4w My14ODZfNjQtYWFyY2g2NC1saW51eC1nbnUvYmluL2FhcmNoNjQtbGludXgtZ251LWxkOiBkcml2 ZXJzL2Zpcm13YXJlL2FybV9zY21pL29wdGVlLm86IGluIGZ1bmN0aW9uIGBvcHRlZV9zZXJ2aWNl X3Byb2JlJzoKPiA+ID4gL2hvbWUvY3JpbWFyMDEvQVJNL2Rldi9zcmMvcGRzdy9saW51eC9kcml2 ZXJzL2Zpcm13YXJlL2FybV9zY21pL29wdGVlLmM6NDgxOiB1bmRlZmluZWQgcmVmZXJlbmNlIHRv IGB0ZWVfY2xpZW50X29wZW5fY29udGV4dCcKPiA+ID4gL29wdC90b29sY2hhaW5zL2djYy1hcm0t OC4zLTIwMTkuMDMteDg2XzY0LWFhcmNoNjQtbGludXgtZ251L2Jpbi9hYXJjaDY0LWxpbnV4LWdu dS1sZDogL2hvbWUvY3JpbWFyMDEvQVJNL2Rldi9zcmMvcGRzdy9saW51eC9kcml2ZXJzL2Zpcm13 YXJlL2FybV9zY21pL29wdGVlLmM6NTAxOiB1bmRlZmluZWQgcmVmZXJlbmNlIHRvIGB0ZWVfY2xp ZW50X2Nsb3NlX2NvbnRleHQnCj4gPiA+IC9vcHQvdG9vbGNoYWlucy9nY2MtYXJtLTguMy0yMDE5 LjAzLXg4Nl82NC1hYXJjaDY0LWxpbnV4LWdudS9iaW4vYWFyY2g2NC1saW51eC1nbnUtbGQ6IGRy aXZlcnMvZmlybXdhcmUvYXJtX3NjbWkvb3B0ZWUubzogaW4gZnVuY3Rpb24gYGdldF9jYXBhYmls aXRpZXMnOgo+ID4gPiAvaG9tZS9jcmltYXIwMS9BUk0vZGV2L3NyYy9wZHN3L2xpbnV4L2RyaXZl cnMvZmlybXdhcmUvYXJtX3NjbWkvb3B0ZWUuYzoxNzI6IHVuZGVmaW5lZCByZWZlcmVuY2UgdG8g YHRlZV9jbGllbnRfaW52b2tlX2Z1bmMnCj4gPiA+IC9vcHQvdG9vbGNoYWlucy9nY2MtYXJtLTgu My0yMDE5LjAzLXg4Nl82NC1hYXJjaDY0LWxpbnV4LWdudS9iaW4vYWFyY2g2NC1saW51eC1nbnUt bGQ6IGRyaXZlcnMvZmlybXdhcmUvYXJtX3NjbWkvb3B0ZWUubzogaW4gZnVuY3Rpb24gYGNsb3Nl X3Nlc3Npb24nOgo+ID4gPiAvaG9tZS9jcmltYXIwMS9BUk0vZGV2L3NyYy9wZHN3L2xpbnV4L2Ry aXZlcnMvZmlybXdhcmUvYXJtX3NjbWkvb3B0ZWUuYzoxNTE6IHVuZGVmaW5lZCByZWZlcmVuY2Ug dG8gYHRlZV9jbGllbnRfY2xvc2Vfc2Vzc2lvbicKPiA+ID4gL29wdC90b29sY2hhaW5zL2djYy1h cm0tOC4zLTIwMTkuMDMteDg2XzY0LWFhcmNoNjQtbGludXgtZ251L2Jpbi9hYXJjaDY0LWxpbnV4 LWdudS1sZDogZHJpdmVycy9maXJtd2FyZS9hcm1fc2NtaS9vcHRlZS5vOiBpbiBmdW5jdGlvbiBg Z2V0X2NoYW5uZWwnOgo+ID4gPiAvaG9tZS9jcmltYXIwMS9BUk0vZGV2L3NyYy9wZHN3L2xpbnV4 L2RyaXZlcnMvZmlybXdhcmUvYXJtX3NjbWkvb3B0ZWUuYzoyMDk6IHVuZGVmaW5lZCByZWZlcmVu Y2UgdG8gYHRlZV9jbGllbnRfaW52b2tlX2Z1bmMnCj4gPiA+IC9vcHQvdG9vbGNoYWlucy9nY2Mt YXJtLTguMy0yMDE5LjAzLXg4Nl82NC1hYXJjaDY0LWxpbnV4LWdudS9iaW4vYWFyY2g2NC1saW51 eC1nbnUtbGQ6IGRyaXZlcnMvZmlybXdhcmUvYXJtX3NjbWkvb3B0ZWUubzogaW4gZnVuY3Rpb24g YHNldHVwX2R5bmFtaWNfc2htZW0nOgo+ID4gPiAvaG9tZS9jcmltYXIwMS9BUk0vZGV2L3NyYy9w ZHN3L2xpbnV4L2RyaXZlcnMvZmlybXdhcmUvYXJtX3NjbWkvb3B0ZWUuYzoyNzA6IHVuZGVmaW5l ZCByZWZlcmVuY2UgdG8gYHRlZV9zaG1fYWxsb2Nfa2VybmVsX2J1ZicKPiA+ID4gL29wdC90b29s Y2hhaW5zL2djYy1hcm0tOC4zLTIwMTkuMDMteDg2XzY0LWFhcmNoNjQtbGludXgtZ251L2Jpbi9h YXJjaDY0LWxpbnV4LWdudS1sZDogL2hvbWUvY3JpbWFyMDEvQVJNL2Rldi9zcmMvcGRzdy9saW51 eC9kcml2ZXJzL2Zpcm13YXJlL2FybV9zY21pL29wdGVlLmM6Mjc2OiB1bmRlZmluZWQgcmVmZXJl bmNlIHRvIGB0ZWVfc2htX2dldF92YScKPiA+ID4gL29wdC90b29sY2hhaW5zL2djYy1hcm0tOC4z LTIwMTkuMDMteDg2XzY0LWFhcmNoNjQtbGludXgtZ251L2Jpbi9hYXJjaDY0LWxpbnV4LWdudS1s ZDogZHJpdmVycy9maXJtd2FyZS9hcm1fc2NtaS9vcHRlZS5vOiBpbiBmdW5jdGlvbiBgY2xvc2Vf c2Vzc2lvbic6Cj4gPiA+IC9ob21lL2NyaW1hcjAxL0FSTS9kZXYvc3JjL3Bkc3cvbGludXgvZHJp dmVycy9maXJtd2FyZS9hcm1fc2NtaS9vcHRlZS5jOjE1MTogdW5kZWZpbmVkIHJlZmVyZW5jZSB0 byBgdGVlX2NsaWVudF9jbG9zZV9zZXNzaW9uJwo+ID4gPiAvb3B0L3Rvb2xjaGFpbnMvZ2NjLWFy bS04LjMtMjAxOS4wMy14ODZfNjQtYWFyY2g2NC1saW51eC1nbnUvYmluL2FhcmNoNjQtbGludXgt Z251LWxkOiBkcml2ZXJzL2Zpcm13YXJlL2FybV9zY21pL29wdGVlLm86KC5kYXRhKzB4MTApOiB1 bmRlZmluZWQgcmVmZXJlbmNlIHRvIGB0ZWVfYnVzX3R5cGUnCj4gPiA+IC9ob21lL2NyaW1hcjAx L0FSTS9kZXYvc3JjL3Bkc3cvbGludXgvTWFrZWZpbGU6MTE4OTogcmVjaXBlIGZvciB0YXJnZXQg J3ZtbGludXgnIGZhaWxlZAo+ID4gPiBtYWtlWzFdOiAqKiogW3ZtbGludXhdIEVycm9yIDEKPiA+ ID4gbWFrZVsxXTogTGVhdmluZyBkaXJlY3RvcnkgJy9ob21lL2NyaW1hcjAxL0FSTS9kZXYvc3Jj L3Bkc3cvb3V0X2xpbnV4Jwo+ID4gPiBNYWtlZmlsZToyMTk6IHJlY2lwZSBmb3IgdGFyZ2V0ICdf X3N1Yi1tYWtlJyBmYWlsZWQKPiA+ID4KPiA+ID4gVGFraW5nIGEgc2ltaWxhciBhcHByb2FjaCB0 byBWaXJ0aW8sIHRoaXMgZml4ZWQgZm9yIG1lCj4gPiA+Cj4gPiA+IGRpZmYgLS1naXQgYS9kcml2 ZXJzL2Zpcm13YXJlL2FybV9zY21pL0tjb25maWcgYi9kcml2ZXJzL2Zpcm13YXJlL2FybV9zY21p L0tjb25maWcKPiA+ID4gaW5kZXggOTEwN2UyNDkwMjNjLi4zMDc0NjM1MDM0OWMgMTAwNjQ0Cj4g PiA+IC0tLSBhL2RyaXZlcnMvZmlybXdhcmUvYXJtX3NjbWkvS2NvbmZpZwo+ID4gPiArKysgYi9k cml2ZXJzL2Zpcm13YXJlL2FybV9zY21pL0tjb25maWcKPiA+ID4gQEAgLTc5LDcgKzc5LDcgQEAg Y29uZmlnIEFSTV9TQ01JX1RSQU5TUE9SVF9WSVJUSU8KPiA+ID4KPiA+ID4gIGNvbmZpZyBBUk1f U0NNSV9UUkFOU1BPUlRfT1BURUUKPiA+ID4gICAgICAgICBib29sICJTQ01JIHRyYW5zcG9ydCBi YXNlZCBvbiBPUC1URUUgc2VydmljZSIKPiA+ID4gLSAgICAgICBkZXBlbmRzIG9uIE9QVEVFCj4g PiA+ICsgICAgICAgZGVwZW5kcyBvbiBPUFRFRT15IHx8IE9QVEVFPUFSTV9TQ01JX1BST1RPQ09M Cj4gPiA+ICAgICAgICAgc2VsZWN0IEFSTV9TQ01JX0hBVkVfVFJBTlNQT1JUCj4gPiA+ICAgICAg ICAgc2VsZWN0IEFSTV9TQ01JX0hBVkVfU0hNRU0KPiA+ID4gICAgICAgICBkZWZhdWx0IHkKPiA+ ID4KPiA+ID4gd2hpY2ggYmFzaWNhbGx5IGRpc2FibGVzIEFSTV9TQ01JX1RSQU5TUE9SVF9PUFRF RSB3aGVuIENPTkZJR19PUFRFRT1tIEFORAo+ID4gPiBBUk1fU0NNSV9UUkFOU1BPUlRfT1BURUU9 eTogaW4gdGhpcyBzY2VuYXJpbyBpZiBURUUgaXMgPW0geW91IGhhdmUgdG8gYnVpbGQKPiA+ID4g QVJNX1NDTUlfUFJPVE9DT0w9bSB0b28gdG8gYmUgYWJsZSB0byBpbmNsdWRlIEFSTV9TQ01JX1RS QU5TUE9SVF9PUFRFRS4KPiA+Cj4gPiBGdWxseSBtYWtlcyBzZW5zZSB0byBtZS4gVGhhbmtzLiBJ IHVuZGVyc3RhbmQuCj4gPgoKQXMgc2FpZCwgbm90IGVsZWdhbnQsIGJ1dCBzb21lIGZhbmN5IGNp cmN1bGFyLWRlcHMgaW4gdGhlIEtjb25maWcgYmV0d2VlbgpTQ01JIGNvcmUgYW5kIHRyYW5zcG9y dHMgbGVkIHRvIHRoaXMuCgo+ID4gPgo+ID4gPgo+ID4gPiA+ICBjb25maWcgQVJNX1NDTUlfUE9X RVJfRE9NQUlOCj4gPiA+ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZmlybXdhcmUvYXJtX3NjbWkv TWFrZWZpbGUgYi9kcml2ZXJzL2Zpcm13YXJlL2FybV9zY21pL01ha2VmaWxlCj4gPiA+ID4gaW5k ZXggMWRjZjEyM2Q2NGFiLi5lZjY2ZWM4Y2E5MTcgMTAwNjQ0Cj4gPiA+ID4gLS0tIGEvZHJpdmVy cy9maXJtd2FyZS9hcm1fc2NtaS9NYWtlZmlsZQo+ID4gPiA+ICsrKyBiL2RyaXZlcnMvZmlybXdh cmUvYXJtX3NjbWkvTWFrZWZpbGUKPiA+ID4gPiBAQCAtNiw2ICs2LDcgQEAgc2NtaS10cmFuc3Bv cnQtJChDT05GSUdfQVJNX1NDTUlfVFJBTlNQT1JUX01BSUxCT1gpICs9IG1haWxib3gubwo+ID4g PiA+ICBzY21pLXRyYW5zcG9ydC0kKENPTkZJR19BUk1fU0NNSV9UUkFOU1BPUlRfU01DKSArPSBz bWMubwo+ID4gPiA+ICBzY21pLXRyYW5zcG9ydC0kKENPTkZJR19BUk1fU0NNSV9IQVZFX01TRykg Kz0gbXNnLm8KPiA+ID4gPiAgc2NtaS10cmFuc3BvcnQtJChDT05GSUdfQVJNX1NDTUlfVFJBTlNQ T1JUX1ZJUlRJTykgKz0gdmlydGlvLm8KPiA+ID4gPiArc2NtaS10cmFuc3BvcnQtJChDT05GSUdf QVJNX1NDTUlfVFJBTlNQT1JUX09QVEVFKSArPSBvcHRlZS5vCj4gPiA+ID4gIHNjbWktcHJvdG9j b2xzLXkgPSBiYXNlLm8gY2xvY2subyBwZXJmLm8gcG93ZXIubyByZXNldC5vIHNlbnNvcnMubyBz eXN0ZW0ubyB2b2x0YWdlLm8KPiA+ID4gPiAgc2NtaS1tb2R1bGUtb2JqcyA6PSAkKHNjbWktYnVz LXkpICQoc2NtaS1kcml2ZXIteSkgJChzY21pLXByb3RvY29scy15KSBcCj4gPiA+ID4gICAgICAg ICAgICAgICAgICAgJChzY21pLXRyYW5zcG9ydC15KQo+ID4gPiA+IGRpZmYgLS1naXQgYS9kcml2 ZXJzL2Zpcm13YXJlL2FybV9zY21pL2NvbW1vbi5oIGIvZHJpdmVycy9maXJtd2FyZS9hcm1fc2Nt aS9jb21tb24uaAo+ID4gPiA+IGluZGV4IGRlYTFiZmJlMTA1Mi4uODJmZjNjM2E2ZDJkIDEwMDY0 NAo+ID4gPiA+IC0tLSBhL2RyaXZlcnMvZmlybXdhcmUvYXJtX3NjbWkvY29tbW9uLmgKPiA+ID4g PiArKysgYi9kcml2ZXJzL2Zpcm13YXJlL2FybV9zY21pL2NvbW1vbi5oCj4gPiA+ID4gQEAgLTQy MSw2ICs0MjEsOSBAQCBleHRlcm4gY29uc3Qgc3RydWN0IHNjbWlfZGVzYyBzY21pX3NtY19kZXNj Owo+ID4gPiA+ICAjaWZkZWYgQ09ORklHX0FSTV9TQ01JX1RSQU5TUE9SVF9WSVJUSU8KPiA+ID4g PiAgZXh0ZXJuIGNvbnN0IHN0cnVjdCBzY21pX2Rlc2Mgc2NtaV92aXJ0aW9fZGVzYzsKPiA+ID4g PiAgI2VuZGlmCj4gPiA+ID4gKyNpZmRlZiBDT05GSUdfT1BURUUKPiA+ID4KPiA+ID4gVGhpcyBz aG91bGQgYmU6Cj4gPiA+Cj4gPiA+ICNpZmRlZiBDT05GSUdfQVJNX1NDTUlfVFJBTlNQT1JUX09Q VEVFCj4gPiA+Cj4gPiA+IGlmIG5vdCBkaXNhYmxpbmcgT1BURUUgdHJhbnNwb3J0IGluIEtjb25m aWcgYnJlYWtzIHRoZSBidWlsZC4KPiA+ID4KPiA+ID4gIExEICAgICAgLnRtcF92bWxpbnV4Lmth bGxzeW1zMQo+ID4gPiAgL29wdC90b29sY2hhaW5zL2djYy1hcm0tOC4zLTIwMTkuMDMteDg2XzY0 LWFhcmNoNjQtbGludXgtZ251L2Jpbi9hYXJjaDY0LWxpbnV4LWdudS1sZDoKPiA+ID4gIGRyaXZl cnMvZmlybXdhcmUvYXJtX3NjbWkvZHJpdmVyLm86KC5yb2RhdGErMHgyODApOiB1bmRlZmluZWQg cmVmZXJlbmNlCj4gPiA+ICB0byBgc2NtaV9vcHRlZV9kZXNjJwo+ID4gPiAgL2hvbWUvY3JpbWFy MDEvQVJNL2Rldi9zcmMvcGRzdy9saW51eC9NYWtlZmlsZToxMTg5OiByZWNpcGUgZm9yIHRhcmdl dAo+ID4gPiAgJ3ZtbGludXgnIGZhaWxlZAo+ID4gPiAgbWFrZVsxXTogKioqIFt2bWxpbnV4XSBF cnJvciAxCj4gPiA+ICBtYWtlWzFdOiBMZWF2aW5nIGRpcmVjdG9yeSAnL2hvbWUvY3JpbWFyMDEv QVJNL2Rldi9zcmMvcGRzdy9vdXRfbGludXgnCj4gPiA+Cj4gPiA+Cj4gPiA+ID4gK2V4dGVybiBj b25zdCBzdHJ1Y3Qgc2NtaV9kZXNjIHNjbWlfb3B0ZWVfZGVzYzsKPiA+ID4gPiArI2VuZGlmCj4g PiA+ID4KPiA+ID4gPiAgdm9pZCBzY21pX3J4X2NhbGxiYWNrKHN0cnVjdCBzY21pX2NoYW5faW5m byAqY2luZm8sIHUzMiBtc2dfaGRyLCB2b2lkICpwcml2KTsKPiA+ID4gPiAgdm9pZCBzY21pX2Zy ZWVfY2hhbm5lbChzdHJ1Y3Qgc2NtaV9jaGFuX2luZm8gKmNpbmZvLCBzdHJ1Y3QgaWRyICppZHIs IGludCBpZCk7Cj4gPiA+ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZmlybXdhcmUvYXJtX3NjbWkv ZHJpdmVyLmMgYi9kcml2ZXJzL2Zpcm13YXJlL2FybV9zY21pL2RyaXZlci5jCj4gPiA+ID4gaW5k ZXggYjQwNmIzZjc4ZjQ2Li4wNmYwYTk4NDZjN2UgMTAwNjQ0Cj4gPiA+ID4gLS0tIGEvZHJpdmVy cy9maXJtd2FyZS9hcm1fc2NtaS9kcml2ZXIuYwo+ID4gPiA+ICsrKyBiL2RyaXZlcnMvZmlybXdh cmUvYXJtX3NjbWkvZHJpdmVyLmMKPiA+ID4gPiBAQCAtMTk5OSw2ICsxOTk5LDkgQEAgc3RhdGlj IGNvbnN0IHN0cnVjdCBvZl9kZXZpY2VfaWQgc2NtaV9vZl9tYXRjaFtdID0gewo+ID4gPiA+ICAj ZW5kaWYKPiA+ID4gPiAgI2lmZGVmIENPTkZJR19BUk1fU0NNSV9UUkFOU1BPUlRfVklSVElPCj4g PiA+ID4gICAgICAgeyAuY29tcGF0aWJsZSA9ICJhcm0sc2NtaS12aXJ0aW8iLCAuZGF0YSA9ICZz Y21pX3ZpcnRpb19kZXNjfSwKPiA+ID4gPiArI2VuZGlmCj4gPiA+ID4gKyNpZmRlZiBDT05GSUdf T1BURUUKPiA+ID4KPiA+ID4gU2FtZSBhcyBhYm92ZSBzaG91bGQgYmUgI2lmIENPTkZJR19BUk1f U0NNSV9UUkFOU1BPUlRfT1BURUUKPiA+ID4KPiA+ID4gPiArICAgICB7IC5jb21wYXRpYmxlID0g ImxpbmFybyxzY21pLW9wdGVlIiwgLmRhdGEgPSAmc2NtaV9vcHRlZV9kZXNjIH0sCj4gPiA+ID4g ICNlbmRpZgo+ID4gPiA+ICAgICAgIHsgLyogU2VudGluZWwgKi8gfSwKPiA+ID4gPiAgfTsKPiA+ ID4gPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9maXJtd2FyZS9hcm1fc2NtaS9vcHRlZS5jIGIvZHJp dmVycy9maXJtd2FyZS9hcm1fc2NtaS9vcHRlZS5jCj4gPiA+ID4gbmV3IGZpbGUgbW9kZSAxMDA2 NDQKPiA+ID4gPiBpbmRleCAwMDAwMDAwMDAwMDAuLmUyOTRjZmYzN2JlYQo+ID4gPiA+IC0tLSAv ZGV2L251bGwKPiA+ID4gPiArKysgYi9kcml2ZXJzL2Zpcm13YXJlL2FybV9zY21pL29wdGVlLmMK PiA+ID4gPiBAQCAtMCwwICsxLDU1OSBAQAo+ID4gPiA+ICsvLyBTUERYLUxpY2Vuc2UtSWRlbnRp ZmllcjogR1BMLTIuMAo+ID4gPiA+ICsvKgo+ID4gPiA+ICsgKiBDb3B5cmlnaHQgKEMpIDIwMTkt MjAyMSBMaW5hcm8gTHRkLgo+ID4gPiA+ICsgKi8KPiA+ID4gPiArCj4gPiA+ID4gKyNpbmNsdWRl IDxsaW51eC9pby5oPgo+ID4gPiA+ICsjaW5jbHVkZSA8bGludXgvb2YuaD4KPiA+ID4gPiArI2lu Y2x1ZGUgPGxpbnV4L29mX2FkZHJlc3MuaD4KPiA+ID4gPiArI2luY2x1ZGUgPGxpbnV4L2tlcm5l bC5oPgo+ID4gPiA+ICsjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+Cj4gPiA+ID4gKyNpbmNsdWRl IDxsaW51eC9tdXRleC5oPgo+ID4gPiA+ICsjaW5jbHVkZSA8bGludXgvc2xhYi5oPgo+ID4gPiA+ ICsjaW5jbHVkZSA8bGludXgvdGVlX2Rydi5oPgo+ID4gPiA+ICsjaW5jbHVkZSA8bGludXgvdXVp ZC5oPgo+ID4gPiA+ICsjaW5jbHVkZSA8dWFwaS9saW51eC90ZWUuaD4KPiA+ID4gPiArCj4gPiA+ ID4gKyNpbmNsdWRlICJjb21tb24uaCIKPiA+ID4gPiArCj4gPiA+ID4gKyNkZWZpbmUgRFJJVkVS X05BTUUgIm9wdGVlLXNjbWkiCj4gPiA+ID4gKwo+ID4gPiA+ICtlbnVtIG9wdGVlX3NtY2lfcHRh X2NtZCB7Cj4gPiA+ICAgICAgICAgICAgICAgXgo+ID4gPiAgICAgICAgICAgICAgIHNjbWkgPyBv ciBpcyBpdCBhbm90aGVyIGZhbmN5IDRsZXR0ZXJzIGFjcm9ueW0gOkQKPiA+Cj4gPiA6KSBuaWNl IGNhdGNoIQo+ID4KPiA+ID4gPiArICAgICAvKgo+ID4gPiA+ICsgICAgICAqIFBUQV9TQ01JX0NN RF9DQVBBQklMSVRJRVMgLSBHZXQgY2hhbm5lbCBjYXBhYmlsaXRpZXMKPiA+ID4gPiArICAgICAg Kgo+ID4gPiA+ICsgICAgICAqIFtvdXRdICAgIHZhbHVlWzBdLmE6IENhcGFiaWxpdHkgYml0IG1h c2sgKGVudW0gcHRhX3NjbWlfY2FwcykKPiA+ID4gPiArICAgICAgKiBbb3V0XSAgICB2YWx1ZVsw XS5iOiBFeHRlbmRlZCBjYXBhYmlsaXRpZXMgb3IgMAo+ID4gPiA+ICsgICAgICAqLwo+ID4gPiA+ ICsgICAgIFBUQV9TQ01JX0NNRF9DQVBBQklMSVRJRVMgPSAwLAo+ID4gPiA+ICsKPiA+ID4gPiAr ICAgICAvKgo+ID4gPiA+ICsgICAgICAqIFBUQV9TQ01JX0NNRF9QUk9DRVNTX1NNVF9DSEFOTkVM IC0gUHJvY2VzcyBTQ01JIG1lc3NhZ2UgaW4gU01UIGJ1ZmZlcgo+ID4gPiA+ICsgICAgICAqCj4g PiA+ID4gKyAgICAgICogW2luXSAgICAgdmFsdWVbMF0uYTogQ2hhbm5lbCBoYW5kbGUKPiA+ID4g PiArICAgICAgKgo+ID4gPiA+ICsgICAgICAqIFNoYXJlZCBtZW1vcnkgdXNlZCBmb3IgU0NNSSBt ZXNzYWdlL3Jlc3BvbnNlIGV4aGFuZ2UgaXMgZXhwZWN0ZWQKPiA+ID4gPiArICAgICAgKiBhbHJl YWR5IGlkZW50aWZpZWQgYW5kIGJvdW5kIHRvIGNoYW5uZWwgaGFuZGxlIGluIGJvdGggU0NNSSBh Z2VudAo+ID4gPiA+ICsgICAgICAqIGFuZCBTQ01JIHNlcnZlciAoT1AtVEVFKSBwYXJ0cy4KPiA+ ID4gPiArICAgICAgKiBUaGUgbWVtb3J5IHVzZXMgU01UIGhlYWRlciB0byBjYXJyeSBTQ01JIG1l dGEtZGF0YSAocHJvdG9jb2wgSUQgYW5kCj4gPiA+ID4gKyAgICAgICogcHJvdG9jb2wgbWVzc2Fn ZSBJRCkuCj4gPiA+ID4gKyAgICAgICovCj4gPiA+ID4gKyAgICAgUFRBX1NDTUlfQ01EX1BST0NF U1NfU01UX0NIQU5ORUwgPSAxLAo+ID4gPiA+ICsKPiA+ID4gPiArICAgICAvKgo+ID4gPiA+ICsg ICAgICAqIFBUQV9TQ01JX0NNRF9QUk9DRVNTX1NNVF9DSEFOTkVMX01FU1NBR0UgLSBQcm9jZXNz IFNNVC9TQ01JIG1lc3NhZ2UKPiA+ID4gPiArICAgICAgKgo+ID4gPiA+ICsgICAgICAqIFtpbl0g ICAgIHZhbHVlWzBdLmE6IENoYW5uZWwgaGFuZGxlCj4gPiA+ID4gKyAgICAgICogW2luL291dF0g bWVtcmVmWzFdOiBNZXNzYWdlL3Jlc3BvbnNlIGJ1ZmZlciAoU01UIGFuZCBTQ01JIHBheWxvYWQp Cj4gPiA+ID4gKyAgICAgICoKPiA+ID4gPiArICAgICAgKiBTaGFyZWQgbWVtb3J5IHVzZWQgZm9y IFNDTUkgbWVzc2FnZS9yZXNwb25zZSBpcyBhIFNNVCBidWZmZXIKPiA+ID4gPiArICAgICAgKiBy ZWZlcmVuY2VkIGJ5IHBhcmFtWzFdLiBJdCBzaGFsbCBiZSAxMjggYnl0ZXMgbGFyZ2UgdG8gZml0 IHJlc3BvbnNlCj4gPiA+ID4gKyAgICAgICogcGF5bG9hZCB3aGF0ZXZlciBtZXNzYWdlIHBsYXls b2FkIHNpemUuCj4gPiA+ID4gKyAgICAgICogVGhlIG1lbW9yeSB1c2VzIFNNVCBoZWFkZXIgdG8g Y2FycnkgU0NNSSBtZXRhLWRhdGEgKHByb3RvY29sIElEIGFuZAo+ID4gPiA+ICsgICAgICAqIHBy b3RvY29sIG1lc3NhZ2UgSUQpLgo+ID4gPiA+ICsgICAgICAqLwo+ID4gPiA+ICsgICAgIFBUQV9T Q01JX0NNRF9QUk9DRVNTX1NNVF9DSEFOTkVMX01FU1NBR0UgPSAyLAo+ID4gPiA+ICsKPiA+ID4g PiArICAgICAvKgo+ID4gPiA+ICsgICAgICAqIFBUQV9TQ01JX0NNRF9HRVRfQ0hBTk5FTCAtIEdl dCBjaGFubmVsIGhhbmRsZQo+ID4gPiA+ICsgICAgICAqCj4gPiA+ID4gKyAgICAgICogU0NNSSBz aG0gaW5mb3JtYXRpb24gYXJlIDAgaWYgYWdlbnQgZXhwZWN0cyB0byB1c2UgT1AtVEVFIHJlZ3Vs YXIgU0hNCj4gPiA+ID4gKyAgICAgICoKPiA+ID4gPiArICAgICAgKiBbaW5dICAgICB2YWx1ZVsw XS5hOiBDaGFubmVsIGlkZW50aWZpZXIKPiA+ID4gPiArICAgICAgKiBbb3V0XSAgICB2YWx1ZVsw XS5hOiBSZXR1cm5lZCBjaGFubmVsIGhhbmRsZQo+ID4gPiA+ICsgICAgICAqIFtpbl0gICAgIHZh bHVlWzBdLmI6IFJlcXVlc3RlZCBjYXBhYmlsaXRpZXMgbWFzayAoZW51bSBwdGFfc2NtaV9jYXBz KQo+ID4gPiA+ICsgICAgICAqLwo+ID4gPiA+ICsgICAgIFBUQV9TQ01JX0NNRF9HRVRfQ0hBTk5F TCA9IDMsCj4gPiA+ID4gK307Cj4gPiA+ID4gKwo+ID4gPiA+ICsvKgo+ID4gPiA+ICsgKiBDYXBh YmlsaXRpZXMKPiA+ID4gPiArICovCj4gPiA+ID4gK2VudW0gcHRhX3NjbWlfY2FwcyB7Cj4gPiA+ ID4gKyAgICAgUFRBX1NDTUlfQ0FQU19OT05FID0gMCwKPiA+ID4gPiArICAgICAvKgo+ID4gPiA+ ICsgICAgICAqIFN1cHBvcnRzIGNvbW1hbmQgdXNpbmcgU01UIGhlYWRlciBwcm90b2NvbCAoU0NN SSBzaG1lbSkgaW4gc2hhcmVkCj4gPiA+ID4gKyAgICAgICogbWVtb3J5IGJ1ZmZlcnMgdG8gY2Fy cnkgU0NNSSBwcm90b2NvbCBzeW5jaHJvbmlzYXRpb24gaW5mb3JtYXRpb24uCj4gPiA+ID4gKyAg ICAgICovCj4gPiA+ID4gKyAgICAgUFRBX1NDTUlfQ0FQU19TTVRfSEVBREVSID0gQklUKDApLAo+ ID4gPiA+ICt9Owo+ID4gPiA+ICsKPiA+ID4gPiArLyoqCj4gPiA+ID4gKyAqIHN0cnVjdCBvcHRl ZV9jaGFubmVsIC0gRGVzY3JpcHRpb24gb2YgYW4gT1AtVEVFIFNDTUkgY2hhbm5lbAo+ID4gPiA+ ICsgKgo+ID4gPiA+ICsgKiBAY2hhbm5lbF9pZDogT1AtVEVFIGNoYW5uZWwgSUQgdXNlZCBmb3Ig dGhpcyB0cmFuc3BvcnQKPiA+ID4gPiArICogQG11OiBNdXRleCBwcm90ZWN0aW9uIG9uIGNoYW5u ZWwgYWNjZXNzCj4gPiA+ID4gKyAqIEB0ZWVfc2Vzc2lvbjogVEVFIHNlc3Npb24gaWRlbnRpZmll cgo+ID4gPiA+ICsgKiBAY2luZm86IFNDTUkgY2hhbm5lbCBpbmZvcm1hdGlvbgo+ID4gPiA+ICsg KiBAc2htZW06IFZpcnR1YWwgYmFzZSBhZGRyZXNzIG9mIHRoZSBzaGFyZWQgbWVtb3J5Cj4gPiA+ ID4gKyAqIEB0ZWVfc2htOiBSZWZlcmVuY2UgdG8gVEVFIHNoYXJlZCBtZW1vcnkgb3IgTlVMTCBp ZiB1c2luZyBzdGF0aWMgc2htZW0KPiA+ID4gPiArICogQGNhcHM6IE9QLVRFRSBTQ01JIGNoYW5u ZWwgY2FwYWJpbGl0aWVzCj4gPiA+ID4gKyAqIEBsaW5rOiBSZWZlcmVuY2UgaW4gYWdlbnQncyBj aGFubmVsIGxpc3QKPiA+ID4gPiArICovCj4gPiA+ID4gK3N0cnVjdCBvcHRlZV9jaGFubmVsIHsK PiA+ID4gPiArICAgICB1MzIgY2hhbm5lbF9pZDsKPiA+ID4gPiArICAgICBzdHJ1Y3QgbXV0ZXgg bXU7Cj4gPiA+ID4gKyAgICAgdTMyIHRlZV9zZXNzaW9uOwo+ID4gPiA+ICsgICAgIHN0cnVjdCBz Y21pX2NoYW5faW5mbyAqY2luZm87Cj4gPiA+ID4gKyAgICAgc3RydWN0IHNjbWlfc2hhcmVkX21l bSBfX2lvbWVtICpzaG1lbTsKPiA+ID4gPiArICAgICBzdHJ1Y3QgdGVlX3NobSAqdGVlX3NobTsK PiA+ID4gPiArICAgICBlbnVtIHB0YV9zY21pX2NhcHMgY2FwczsKPiA+ID4gPiArICAgICBzdHJ1 Y3QgbGlzdF9oZWFkIGxpbms7Cj4gPiA+ID4gK307Cj4gPiA+ID4gKwo+ID4gPiA+ICsvKioKPiA+ ID4gPiArICogc3RydWN0IG9wdGVlX2FnZW50IC0gT1AtVEVFIHRyYW5zcG9ydCBwcml2YXRlIGRh dGEKPiA+ID4gPiArICoKPiA+ID4gPiArICogQGRldjogRGV2aWNlIHVzZWQgZm9yIGNvbW11bmlj YXRpb24gd2l0aCBURUUKPiA+ID4gPiArICogQHRlZV9jdHg6IFRFRSBjb250ZXh0IHVzZWQgZm9y IGNvbW11bmljYXRpb24KPiA+ID4gPiArICogQGNhcHM6IFN1cHBvcnRlZCBjaGFubmVsIGNhcGFi aWxpdGllcwo+ID4gPiA+ICsgKiBAbXU6IE11dGV4IGZvciBwcm90ZWN0aW9uIG9mIEBjaGFubmVs X2xpc3QKPiA+ID4gPiArICogQGNoYW5uZWxfbGlzdDogTGlzdCBvZiBhbGwgY3JlYXRlZCBjaGFu bmVscyBmb3IgdGhlIGFnZW50Cj4gPiA+ID4gKyAqLwo+ID4gPiA+ICtzdHJ1Y3Qgb3B0ZWVfYWdl bnQgewo+ID4gPiA+ICsgICAgIHN0cnVjdCBkZXZpY2UgKmRldjsKPiA+ID4gPiArICAgICBzdHJ1 Y3QgdGVlX2NvbnRleHQgKnRlZV9jdHg7Cj4gPiA+ID4gKyAgICAgZW51bSBwdGFfc2NtaV9jYXBz IGNhcHM7Cj4gPiA+ID4gKyAgICAgc3RydWN0IG11dGV4IG11Owo+ID4gPiA+ICsgICAgIHN0cnVj dCBsaXN0X2hlYWQgY2hhbm5lbF9saXN0Owo+ID4gPiA+ICt9Owo+ID4gPiA+ICsKPiA+ID4gPiAr LyogVGhlcmUgY2FuIGJlIG9ubHkgMSBTQ01JIHNlcnZpY2UgaW4gT1AtVEVFIHdlIGNvbm5lY3Qg dG8gKi8KPiA+ID4gPiArc3RhdGljIHN0cnVjdCBvcHRlZV9hZ2VudCAqb3B0ZWVfcHJpdmF0ZTsK PiA+ID4gPiArCj4gPiA+Cj4gPiA+IE1heWJlIG5hbWluZyB0aGVzZSBsb2NhbGx5IGRlZmluZWQg b3B0ZWVfIHN0cnVjdHMgYXMgc2NtaV9vcHRlZV8gPwo+ID4gPgo+ID4gPiBXaGVuIEkgc2VlIHRo b3NlIG9wdGVlXyByZWZzIGFyb3VuZCBkb3duIGJlbG93IEkgdGVuZCB0byB0aGluayB0aGV5Cj4g PiA+IGFyZSBPUFRFRSBjb3JlIHN0cnVjdHMgbm90IGxvY2FsbHkgZGVmaW5lZCBjb250YWluZXJz Lgo+ID4gPiAoSSB1ZGVyc3RhbmQgdGhhdCBkZXBlbmRzIG9uIG15IHBvb3IgZmFtaWxpYXJpdHkg d2l0aCBPUFRFRSBBUElzCj4gPiA+IHRob3VnaC4uLikKPiA+Cj4gPiBPay4gSWYgdGhhdCBoZWxw IG1haW50ZW5hbmNlLCBJJ20gZmluZS4gSSdsbCB1c2Ugc2NtaV9vcHRlZV8gd2hlcmUgYXBwaWlj YWJsZS4KPiA+CgpUaGFua3MsIEkgaGF2ZSBub3QgYSBzdHJvbmcgb3BpbmlvbiBvbiB0aGlzLCBi dXQgYXMgYW4gb3B0ZWUtbmV3YmllIChvciBpZ25vcmFudAppZiB5b3Ugd2FudCA6RCkgSSBmb3Vu ZCBpdCBlYXNpZXIgdG8gcmVhc29uIGFib3V0IGl0Lgo+ID4KPiA+ID4KPiA+ID4gPiArLyogT3Bl biBhIHNlc3Npb24gdG93YXJkIFNDTUkgT1AtVEVFIHNlcnZpY2Ugd2l0aCBSRUVfS0VSTkVMIGlk ZW50aXR5ICovCj4gPiA+ID4gK3N0YXRpYyBpbnQgb3Blbl9zZXNzaW9uKHUzMiAqdGVlX3Nlc3Np b24pCj4gPiA+ID4gK3sKPiA+ID4gPiArICAgICBzdHJ1Y3QgZGV2aWNlICpkZXYgPSBvcHRlZV9w cml2YXRlLT5kZXY7Cj4gPiA+ID4gKyAgICAgc3RydWN0IHRlZV9jbGllbnRfZGV2aWNlICpzY21p X3B0YSA9IHRvX3RlZV9jbGllbnRfZGV2aWNlKGRldik7Cj4gPiA+ID4gKyAgICAgc3RydWN0IHRl ZV9pb2N0bF9vcGVuX3Nlc3Npb25fYXJnIGFyZyA9IHsgfTsKPiA+ID4gPiArICAgICBpbnQgcmV0 Owo+ID4gPiA+ICsKPiA+ID4gPiArICAgICBtZW1jcHkoYXJnLnV1aWQsIHNjbWlfcHRhLT5pZC51 dWlkLmIsIFRFRV9JT0NUTF9VVUlEX0xFTik7Cj4gPiA+ID4gKyAgICAgYXJnLmNsbnRfbG9naW4g PSBURUVfSU9DVExfTE9HSU5fUkVFX0tFUk5FTDsKPiA+ID4gPiArCj4gPiA+ID4gKyAgICAgcmV0 ID0gdGVlX2NsaWVudF9vcGVuX3Nlc3Npb24ob3B0ZWVfcHJpdmF0ZS0+dGVlX2N0eCwgJmFyZywg TlVMTCk7Cj4gPiA+ID4gKyAgICAgaWYgKHJldCA8IDAgfHwgYXJnLnJldCkgewo+ID4gPiA+ICsg ICAgICAgICAgICAgZGV2X2VycihkZXYsICJDYW4ndCBvcGVuIHRlZSBzZXNzaW9uOiAlZCAvICUj eFxuIiwgcmV0LCBhcmcucmV0KTsKPiA+ID4gPiArCj4gPiA+ID4gKyAgICAgICAgICAgICByZXR1 cm4gLUVPUE5PVFNVUFA7Cj4gPiA+ID4gKyAgICAgfQo+ID4gPiA+ICsKPiA+ID4gPiArICAgICAq dGVlX3Nlc3Npb24gPSBhcmcuc2Vzc2lvbjsKPiA+ID4gPiArCj4gPiA+ID4gKyAgICAgcmV0dXJu IDA7Cj4gPiA+ID4gK30KPiA+ID4gPiArCj4gPiA+ID4gK3N0YXRpYyB2b2lkIGNsb3NlX3Nlc3Np b24odTMyIHRlZV9zZXNzaW9uKQo+ID4gPiA+ICt7Cj4gPiA+ID4gKyAgICAgdGVlX2NsaWVudF9j bG9zZV9zZXNzaW9uKG9wdGVlX3ByaXZhdGUtPnRlZV9jdHgsIHRlZV9zZXNzaW9uKTsKPiA+ID4g PiArfQo+ID4gPiA+ICsKPiA+ID4gPiArc3RhdGljIGludCBnZXRfY2FwYWJpbGl0aWVzKHZvaWQp Cj4gPiA+ID4gK3sKPiA+ID4gPiArICAgICBzdHJ1Y3Qgb3B0ZWVfYWdlbnQgKmFnZW50ID0gb3B0 ZWVfcHJpdmF0ZTsKPiA+ID4gPiArICAgICBzdHJ1Y3QgdGVlX2lvY3RsX2ludm9rZV9hcmcgYXJn ID0geyB9Owo+ID4gPiA+ICsgICAgIHN0cnVjdCB0ZWVfcGFyYW0gcGFyYW1bMV0gPSB7IH07Cj4g PiA+ID4gKyAgICAgdTMyIHRlZV9zZXNzaW9uOwo+ID4gPiA+ICsgICAgIGludCByZXQ7Cj4gPiA+ ID4gKwo+ID4gPiA+ICsgICAgIHJldCA9IG9wZW5fc2Vzc2lvbigmdGVlX3Nlc3Npb24pOwo+ID4g PiA+ICsgICAgIGlmIChyZXQpCj4gPiA+ID4gKyAgICAgICAgICAgICByZXR1cm4gcmV0Owo+ID4g PiA+ICsKPiA+ID4gPiArICAgICBhcmcuZnVuYyA9IFBUQV9TQ01JX0NNRF9DQVBBQklMSVRJRVM7 Cj4gPiA+ID4gKyAgICAgYXJnLnNlc3Npb24gPSB0ZWVfc2Vzc2lvbjsKPiA+ID4gPiArICAgICBh cmcubnVtX3BhcmFtcyA9IDE7Cj4gPiA+ID4gKwo+ID4gPiA+ICsgICAgIHBhcmFtWzBdLmF0dHIg PSBURUVfSU9DVExfUEFSQU1fQVRUUl9UWVBFX1ZBTFVFX09VVFBVVDsKPiA+ID4gPiArCj4gPiA+ ID4gKyAgICAgcmV0ID0gdGVlX2NsaWVudF9pbnZva2VfZnVuYyhhZ2VudC0+dGVlX2N0eCwgJmFy ZywgcGFyYW0pOwo+ID4gPiA+ICsKPiA+ID4gPiArICAgICBjbG9zZV9zZXNzaW9uKHRlZV9zZXNz aW9uKTsKPiA+ID4gPiArCj4gPiA+ID4gKyAgICAgaWYgKHJldCA8IDAgfHwgYXJnLnJldCkgewo+ ID4gPiA+ICsgICAgICAgICAgICAgZGV2X2VycihhZ2VudC0+ZGV2LCAiQ2FuJ3QgZ2V0IGNhcGFi aWxpdGllczogJWQgLyAlI3hcbiIsIHJldCwgYXJnLnJldCk7Cj4gPiA+ID4gKwo+ID4gPiA+ICsg ICAgICAgICAgICAgcmV0dXJuIC1FT1BOT1RTVVBQOwo+ID4gPiA+ICsgICAgIH0KPiA+ID4gPiAr Cj4gPiA+ID4gKyAgICAgYWdlbnQtPmNhcHMgPSBwYXJhbVswXS51LnZhbHVlLmE7Cj4gPiA+ID4g Kwo+ID4gPiA+ICsgICAgIGlmICghKGFnZW50LT5jYXBzICYgUFRBX1NDTUlfQ0FQU19TTVRfSEVB REVSKSkgewo+ID4gPiA+ICsgICAgICAgICAgICAgZGV2X2VycihhZ2VudC0+ZGV2LCAiT1AtVEVF IFNDTUkgUFRBIGRvZXNuJ3Qgc3VwcG9ydCBTTVRcbiIpOwo+ID4gPiA+ICsKPiA+ID4gPiArICAg ICAgICAgICAgIHJldHVybiAtRU9QTk9UU1VQUDsKPiA+ID4gPiArICAgICB9Cj4gPiA+ID4gKwo+ ID4gPiA+ICsgICAgIHJldHVybiAwOwo+ID4gPiA+ICt9Cj4gPiA+ID4gKwo+ID4gPiA+ICtzdGF0 aWMgaW50IGdldF9jaGFubmVsKHN0cnVjdCBvcHRlZV9jaGFubmVsICpjaGFubmVsKQo+ID4gPiA+ ICt7Cj4gPiA+ID4gKyAgICAgc3RydWN0IGRldmljZSAqZGV2ID0gb3B0ZWVfcHJpdmF0ZS0+ZGV2 Owo+ID4gPiA+ICsgICAgIHN0cnVjdCB0ZWVfaW9jdGxfaW52b2tlX2FyZyBhcmcgPSB7IH07Cj4g PiA+ID4gKyAgICAgc3RydWN0IHRlZV9wYXJhbSBwYXJhbVsxXSA9IHsgfTsKPiA+ID4gPiArICAg ICB1bnNpZ25lZCBpbnQgY2FwcyA9IFBUQV9TQ01JX0NBUFNfU01UX0hFQURFUjsKPiA+ID4gPiAr ICAgICBpbnQgcmV0Owo+ID4gPiA+ICsKPiA+ID4gPiArICAgICBhcmcuZnVuYyA9IFBUQV9TQ01J X0NNRF9HRVRfQ0hBTk5FTDsKPiA+ID4gPiArICAgICBhcmcuc2Vzc2lvbiA9IGNoYW5uZWwtPnRl ZV9zZXNzaW9uOwo+ID4gPiA+ICsgICAgIGFyZy5udW1fcGFyYW1zID0gMTsKPiA+ID4gPiArCj4g PiA+ID4gKyAgICAgcGFyYW1bMF0uYXR0ciA9IFRFRV9JT0NUTF9QQVJBTV9BVFRSX1RZUEVfVkFM VUVfSU5PVVQ7Cj4gPiA+ID4gKyAgICAgcGFyYW1bMF0udS52YWx1ZS5hID0gY2hhbm5lbC0+Y2hh bm5lbF9pZDsKPiA+ID4gPiArICAgICBwYXJhbVswXS51LnZhbHVlLmIgPSBjYXBzOwo+ID4gPiA+ ICsKPiA+ID4gPiArICAgICByZXQgPSB0ZWVfY2xpZW50X2ludm9rZV9mdW5jKG9wdGVlX3ByaXZh dGUtPnRlZV9jdHgsICZhcmcsIHBhcmFtKTsKPiA+ID4gPiArCj4gPiA+ID4gKyAgICAgaWYgKHJl dCB8fCBhcmcucmV0KSB7Cj4gPiA+ID4gKyAgICAgICAgICAgICBkZXZfZXJyKGRldiwgIkNhbid0 IGdldCBjaGFubmVsIHdpdGggY2FwcyAlI3g6ICVkIC8gJSN4XG4iLCBjYXBzLCByZXQsIGFyZy5y ZXQpOwo+ID4gPiA+ICsKPiA+ID4gPiArICAgICAgICAgICAgIHJldHVybiAtRU9QTk9UU1VQUDsK PiA+ID4gPiArICAgICB9Cj4gPiA+ID4gKwo+ID4gPiA+ICsgICAgIC8qIEZyb20gbm93IG9uIHVz ZSBjaGFubmVsIGlkZW50aWZlciBwcm92aWRlZCBieSBPUC1URUUgU0NNSSBzZXJ2aWNlICovCj4g PiA+ID4gKyAgICAgY2hhbm5lbC0+Y2hhbm5lbF9pZCA9IHBhcmFtWzBdLnUudmFsdWUuYTsKPiA+ ID4gPiArICAgICBjaGFubmVsLT5jYXBzID0gY2FwczsKPiA+ID4gPiArCj4gPiA+ID4gKyAgICAg cmV0dXJuIDA7Cj4gPiA+ID4gK30KPiA+ID4gPiArCj4gPiA+ID4gK3N0YXRpYyBpbnQgaW52b2tl X3Byb2Nlc3Nfc210X2NoYW5uZWwoc3RydWN0IG9wdGVlX2NoYW5uZWwgKmNoYW5uZWwpCj4gPiA+ ID4gK3sKPiA+ID4gPiArICAgICBzdHJ1Y3QgdGVlX2lvY3RsX2ludm9rZV9hcmcgYXJnID0geyB9 Owo+ID4gPiA+ICsgICAgIHN0cnVjdCB0ZWVfcGFyYW0gcGFyYW1bMl0gPSB7IH07Cj4gPiA+ID4g KyAgICAgaW50IHJldDsKPiA+ID4gPiArCj4gPiA+ID4gKyAgICAgYXJnLnNlc3Npb24gPSBjaGFu bmVsLT50ZWVfc2Vzc2lvbjsKPiA+ID4gPiArICAgICBwYXJhbVswXS5hdHRyID0gVEVFX0lPQ1RM X1BBUkFNX0FUVFJfVFlQRV9WQUxVRV9JTlBVVDsKPiA+ID4gPiArICAgICBwYXJhbVswXS51LnZh bHVlLmEgPSBjaGFubmVsLT5jaGFubmVsX2lkOwo+ID4gPiA+ICsKPiA+ID4gPiArICAgICBpZiAo Y2hhbm5lbC0+dGVlX3NobSkgewo+ID4gPiA+ICsgICAgICAgICAgICAgY29uc3Qgc2l6ZV90IG1z Z19zaXplID0gc2NtaV9vcHRlZV9kZXNjLm1heF9tc2dfc2l6ZTsKPiA+ID4gPiArCj4gPiA+ID4g KyAgICAgICAgICAgICBwYXJhbVsxXS5hdHRyID0gVEVFX0lPQ1RMX1BBUkFNX0FUVFJfVFlQRV9N RU1SRUZfSU5PVVQ7Cj4gPiA+ID4gKyAgICAgICAgICAgICBwYXJhbVsxXS51Lm1lbXJlZi5zaG0g PSBjaGFubmVsLT50ZWVfc2htOwo+ID4gPiA+ICsgICAgICAgICAgICAgcGFyYW1bMV0udS5tZW1y ZWYuc2l6ZSA9IG1zZ19zaXplOwo+ID4gPiA+ICsgICAgICAgICAgICAgYXJnLm51bV9wYXJhbXMg PSAyOwo+ID4gPiA+ICsgICAgICAgICAgICAgYXJnLmZ1bmMgPSBQVEFfU0NNSV9DTURfUFJPQ0VT U19TTVRfQ0hBTk5FTF9NRVNTQUdFOwo+ID4gPiA+ICsgICAgIH0gZWxzZSB7Cj4gPiA+ID4gKyAg ICAgICAgICAgICBhcmcubnVtX3BhcmFtcyA9IDE7Cj4gPiA+ID4gKyAgICAgICAgICAgICBhcmcu ZnVuYyA9IFBUQV9TQ01JX0NNRF9QUk9DRVNTX1NNVF9DSEFOTkVMOwo+ID4gPiA+ICsgICAgIH0K PiA+ID4gPiArCj4gPiA+ID4gKyAgICAgcmV0ID0gdGVlX2NsaWVudF9pbnZva2VfZnVuYyhvcHRl ZV9wcml2YXRlLT50ZWVfY3R4LCAmYXJnLCBwYXJhbSk7Cj4gPiA+ID4gKyAgICAgaWYgKHJldCA8 IDAgfHwgYXJnLnJldCkgewo+ID4gPiA+ICsgICAgICAgICAgICAgZGV2X2VycihvcHRlZV9wcml2 YXRlLT5kZXYsICJGYWlsZWQgb24gY2hhbm5lbCAldTogJWQgLyAlI3hcbiIsCj4gPiA+ID4gKyAg ICAgICAgICAgICAgICAgICAgIGNoYW5uZWwtPmNoYW5uZWxfaWQsIHJldCwgYXJnLnJldCk7Cj4g PiA+ID4gKwo+ID4gPiA+ICsgICAgICAgICAgICAgcmV0dXJuIC1FSU87Cj4gPiA+ID4gKyAgICAg fQo+ID4gPiA+ICsKPiA+ID4gPiArICAgICByZXR1cm4gMDsKPiA+ID4gPiArfQo+ID4gPiA+ICsK PiA+ID4gPiArc3RhdGljIGJvb2wgb3B0ZWVfY2hhbl9hdmFpbGFibGUoc3RydWN0IGRldmljZSAq ZGV2LCBpbnQgaWR4KQo+ID4gPiA+ICt7Cj4gPiA+ID4gKyAgICAgdTMyIGNoYW5uZWxfaWQ7Cj4g PiA+ID4gKwo+ID4gPiA+ICsgICAgIHJldHVybiAhb2ZfcHJvcGVydHlfcmVhZF91MzJfaW5kZXgo ZGV2LT5vZl9ub2RlLCAibGluYXJvLG9wdGVlLWNoYW5uZWwtaWQiLAo+ID4gPiA+ICsgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWR4LCAmY2hhbm5lbF9pZCk7Cj4gPiA+ ID4gK30KPiA+ID4gPiArCj4gPiA+ID4gK3N0YXRpYyBpbnQgc2V0dXBfZHluYW1pY19zaG1lbShz dHJ1Y3QgZGV2aWNlICpkZXYsIHN0cnVjdCBvcHRlZV9jaGFubmVsICpjaGFubmVsKQo+ID4gPiA+ ICt7Cj4gPiA+ID4gKyAgICAgY29uc3Qgc2l6ZV90IG1zZ19zaXplID0gc2NtaV9vcHRlZV9kZXNj Lm1heF9tc2dfc2l6ZTsKPiA+ID4gPiArCj4gPiA+ID4gKyAgICAgY2hhbm5lbC0+dGVlX3NobSA9 IHRlZV9zaG1fYWxsb2Nfa2VybmVsX2J1ZihvcHRlZV9wcml2YXRlLT50ZWVfY3R4LCBtc2dfc2l6 ZSk7Cj4gPiA+ID4gKyAgICAgaWYgKElTX0VSUihjaGFubmVsLT50ZWVfc2htKSkgewo+ID4gPiA+ ICsgICAgICAgICAgICAgZGV2X2VycihjaGFubmVsLT5jaW5mby0+ZGV2LCAic2htZW0gYWxsb2Nh dGlvbiBmYWlsZWRcbiIpOwo+ID4gPiA+ICsgICAgICAgICAgICAgcmV0dXJuIC1FTk9NRU07Cj4g PiA+ID4gKyAgICAgfQo+ID4gPiA+ICsKPiA+ID4gPiArICAgICBjaGFubmVsLT5zaG1lbSA9ICh2 b2lkICopdGVlX3NobV9nZXRfdmEoY2hhbm5lbC0+dGVlX3NobSwgMCk7Cj4gPiA+ID4gKyAgICAg bWVtc2V0KGNoYW5uZWwtPnNobWVtLCAwLCBtc2dfc2l6ZSk7Cj4gPiA+ID4gKyAgICAgc2htZW1f Y2xlYXJfY2hhbm5lbChjaGFubmVsLT5zaG1lbSk7Cj4gPiA+ID4gKwo+ID4gPiA+ICsgICAgIHJl dHVybiAwOwo+ID4gPiA+ICt9Cj4gPiA+ID4gKwo+ID4gPiA+ICtzdGF0aWMgaW50IHNldHVwX3N0 YXRpY19zaG1lbShzdHJ1Y3QgZGV2aWNlICpkZXYsIHN0cnVjdCBzY21pX2NoYW5faW5mbyAqY2lu Zm8sCj4gPiA+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCBvcHRlZV9jaGFu bmVsICpjaGFubmVsKQo+ID4gPiA+ICt7Cj4gPiA+ID4gKyAgICAgc3RydWN0IGRldmljZV9ub2Rl ICpucDsKPiA+ID4gPiArICAgICByZXNvdXJjZV9zaXplX3Qgc2l6ZTsKPiA+ID4gPiArICAgICBz dHJ1Y3QgcmVzb3VyY2UgcmVzOwo+ID4gPiA+ICsgICAgIGludCByZXQ7Cj4gPiA+ID4gKwo+ID4g PiA+ICsgICAgIG5wID0gb2ZfcGFyc2VfcGhhbmRsZShjaW5mby0+ZGV2LT5vZl9ub2RlLCAic2ht ZW0iLCAwKTsKPiA+ID4gPiArICAgICBpZiAoIW9mX2RldmljZV9pc19jb21wYXRpYmxlKG5wLCAi YXJtLHNjbWktc2htZW0iKSkgewo+ID4gPiA+ICsgICAgICAgICAgICAgcmV0ID0gLUVOWElPOwo+ ID4gPiA+ICsgICAgICAgICAgICAgZ290byBvdXQ7Cj4gPiA+ID4gKyAgICAgfQo+ID4gPiA+ICsK PiA+ID4gPiArICAgICByZXQgPSBvZl9hZGRyZXNzX3RvX3Jlc291cmNlKG5wLCAwLCAmcmVzKTsK PiA+ID4gPiArICAgICBpZiAocmV0KSB7Cj4gPiA+ID4gKyAgICAgICAgICAgICBkZXZfZXJyKGRl diwgIkZhaWxlZCB0byBnZXQgU0NNSSBUeCBzaGFyZWQgbWVtb3J5XG4iKTsKPiA+ID4gPiArICAg ICAgICAgICAgIGdvdG8gb3V0Owo+ID4gPiA+ICsgICAgIH0KPiA+ID4gPiArCj4gPiA+ID4gKyAg ICAgc2l6ZSA9IHJlc291cmNlX3NpemUoJnJlcyk7Cj4gPiA+ID4gKwo+ID4gPiA+ICsgICAgIGNo YW5uZWwtPnNobWVtID0gZGV2bV9pb3JlbWFwKGRldiwgcmVzLnN0YXJ0LCBzaXplKTsKPiA+ID4g PiArICAgICBpZiAoIWNoYW5uZWwtPnNobWVtKSB7Cj4gPiA+ID4gKyAgICAgICAgICAgICBkZXZf ZXJyKGRldiwgIkZhaWxlZCB0byBpb3JlbWFwIFNDTUkgVHggc2hhcmVkIG1lbW9yeVxuIik7Cj4g PiA+ID4gKyAgICAgICAgICAgICByZXQgPSAtRUFERFJOT1RBVkFJTDsKPiA+ID4gPiArICAgICAg ICAgICAgIGdvdG8gb3V0Owo+ID4gPiA+ICsgICAgIH0KPiA+ID4gPiArCj4gPiA+ID4gKyAgICAg cmV0ID0gMDsKPiA+ID4gPiArCj4gPiA+ID4gK291dDoKPiA+ID4gPiArICAgICBvZl9ub2RlX3B1 dChucCk7Cj4gPiA+ID4gKwo+ID4gPiA+ICsgICAgIHJldHVybiByZXQ7Cj4gPiA+ID4gK30KPiA+ ID4gPiArCj4gPiA+ID4gK3N0YXRpYyBpbnQgb3B0ZWVfY2hhbl9zZXR1cF9zaG1lbShzdHJ1Y3Qg ZGV2aWNlICpkZXYsIHN0cnVjdCBzY21pX2NoYW5faW5mbyAqY2luZm8sCj4gPiA+ID4gKyAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIHR4LCBzdHJ1Y3Qgb3B0ZWVfY2hhbm5lbCAq Y2hhbm5lbCkKPiA+ID4gPiArewo+ID4gPiA+ICsgICAgIHN0cnVjdCBkZXZpY2UgKmNkZXYgPSBj aW5mby0+ZGV2Owo+ID4gPiA+ICsKPiA+ID4gPiArICAgICBpZiAob2ZfZmluZF9wcm9wZXJ0eShj ZGV2LT5vZl9ub2RlLCAic2htZW0iLCBOVUxMKSkKPiA+ID4gPiArICAgICAgICAgICAgIHJldHVy biBzZXR1cF9zdGF0aWNfc2htZW0oZGV2LCBjaW5mbywgY2hhbm5lbCk7Cj4gPiA+ID4gKyAgICAg ZWxzZQo+ID4gPiA+ICsgICAgICAgICAgICAgcmV0dXJuIHNldHVwX2R5bmFtaWNfc2htZW0oZGV2 LCBjaGFubmVsKTsKPiA+ID4gPiArfQo+ID4gPiA+ICsKPiA+ID4gPiArc3RhdGljIHZvaWQgb3B0 ZWVfY2xlYXJfY2hhbm5lbChzdHJ1Y3Qgc2NtaV9jaGFuX2luZm8gKmNpbmZvKQo+ID4gPiA+ICt7 Cj4gPiA+ID4gKyAgICAgc3RydWN0IG9wdGVlX2NoYW5uZWwgKmNoYW5uZWwgPSBjaW5mby0+dHJh bnNwb3J0X2luZm87Cj4gPiA+ID4gKwo+ID4gPiA+ICsgICAgIHNobWVtX2NsZWFyX2NoYW5uZWwo Y2hhbm5lbC0+c2htZW0pOwo+ID4gPiA+ICt9Cj4gPiA+ID4gKwo+ID4gPiA+ICtzdGF0aWMgaW50 IG9wdGVlX2NoYW5fc2V0dXAoc3RydWN0IHNjbWlfY2hhbl9pbmZvICpjaW5mbywgc3RydWN0IGRl dmljZSAqZGV2LCBib29sIHR4KQo+ID4gPiA+ICt7Cj4gPiA+ID4gKyAgICAgc3RydWN0IG9wdGVl X2NoYW5uZWwgKmNoYW5uZWw7Cj4gPiA+ID4gKyAgICAgdWludDMyX3QgY2hhbm5lbF9pZDsKPiA+ ID4gPiArICAgICBpbnQgcmV0Owo+ID4gPiA+ICsKPiA+ID4gPiArICAgICBpZiAoIXR4KQo+ID4g PiA+ICsgICAgICAgICAgICAgcmV0dXJuIC1FTk9ERVY7Cj4gPiA+ID4gKwo+ID4gPiA+ICsgICAg IC8qIFNoYWxsIHdhaXQgZm9yIE9QLVRFRSBkcml2ZXIgdG8gYmUgdXAgYW5kIHJlYWR5ICovCj4g PiA+ID4gKyAgICAgaWYgKCFvcHRlZV9wcml2YXRlIHx8ICFvcHRlZV9wcml2YXRlLT50ZWVfY3R4 KQo+ID4gPiA+ICsgICAgICAgICAgICAgcmV0dXJuIC1FUFJPQkVfREVGRVI7Cj4gPiA+ID4gKwo+ ID4gPiA+ICsgICAgIGNoYW5uZWwgPSBkZXZtX2t6YWxsb2MoZGV2LCBzaXplb2YoKmNoYW5uZWwp LCBHRlBfS0VSTkVMKTsKPiA+ID4gPiArICAgICBpZiAoIWNoYW5uZWwpCj4gPiA+ID4gKyAgICAg ICAgICAgICByZXR1cm4gLUVOT01FTTsKPiA+ID4gPiArCj4gPiA+ID4gKyAgICAgcmV0ID0gb2Zf cHJvcGVydHlfcmVhZF91MzJfaW5kZXgoY2luZm8tPmRldi0+b2Zfbm9kZSwgImxpbmFybyxvcHRl ZS1jaGFubmVsLWlkIiwKPiA+ID4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAwLCAmY2hhbm5lbF9pZCk7Cj4gPiA+ID4gKyAgICAgaWYgKHJldCkKPiA+ID4gPiArICAg ICAgICAgICAgIHJldHVybiByZXQ7Cj4gPiA+ID4gKwo+ID4gPiA+ICsgICAgIGNpbmZvLT50cmFu c3BvcnRfaW5mbyA9IGNoYW5uZWw7Cj4gPiA+ID4gKyAgICAgY2hhbm5lbC0+Y2luZm8gPSBjaW5m bzsKPiA+ID4gPiArICAgICBjaGFubmVsLT5jaGFubmVsX2lkID0gY2hhbm5lbF9pZDsKPiA+ID4g PiArICAgICBtdXRleF9pbml0KCZjaGFubmVsLT5tdSk7Cj4gPiA+ID4gKwo+ID4gPiA+ICsgICAg IHJldCA9IG9wdGVlX2NoYW5fc2V0dXBfc2htZW0oZGV2LCBjaW5mbywgdHgsIGNoYW5uZWwpOwo+ ID4gPiA+ICsgICAgIGlmIChyZXQpCj4gPiA+ID4gKyAgICAgICAgICAgICByZXR1cm4gcmV0Owo+ ID4gPiA+ICsKPiA+ID4gPiArICAgICByZXQgPSBvcGVuX3Nlc3Npb24oJmNoYW5uZWwtPnRlZV9z ZXNzaW9uKTsKPiA+ID4gPiArICAgICBpZiAocmV0KQo+ID4gPiA+ICsgICAgICAgICAgICAgcmV0 dXJuIHJldDsKPiA+ID4gPiArCj4gPiA+ID4gKyAgICAgcmV0ID0gZ2V0X2NoYW5uZWwoY2hhbm5l bCk7Cj4gPiA+ID4gKyAgICAgaWYgKHJldCkgewo+ID4gPiA+ICsgICAgICAgICAgICAgY2xvc2Vf c2Vzc2lvbihjaGFubmVsLT50ZWVfc2Vzc2lvbik7Cj4gPiA+ID4gKwo+ID4gPiA+ICsgICAgICAg ICAgICAgcmV0dXJuIHJldDsKPiA+ID4gPiArICAgICB9Cj4gPiA+ID4gKwo+ID4gPiA+ICsgICAg IG11dGV4X2xvY2soJm9wdGVlX3ByaXZhdGUtPm11KTsKPiA+ID4gPiArICAgICBsaXN0X2FkZCgm Y2hhbm5lbC0+bGluaywgJm9wdGVlX3ByaXZhdGUtPmNoYW5uZWxfbGlzdCk7Cj4gPiA+ID4gKyAg ICAgbXV0ZXhfdW5sb2NrKCZvcHRlZV9wcml2YXRlLT5tdSk7Cj4gPiA+ID4gKwo+ID4gPiA+ICsg ICAgIHJldHVybiAwOwo+ID4gPiA+ICt9Cj4gPiA+ID4gKwo+ID4gPiA+ICtzdGF0aWMgaW50IG9w dGVlX2NoYW5fZnJlZShpbnQgaWQsIHZvaWQgKnAsIHZvaWQgKmRhdGEpCj4gPiA+ID4gK3sKPiA+ ID4gPiArICAgICBzdHJ1Y3Qgc2NtaV9jaGFuX2luZm8gKmNpbmZvID0gcDsKPiA+ID4gPiArICAg ICBzdHJ1Y3Qgb3B0ZWVfY2hhbm5lbCAqY2hhbm5lbCA9IGNpbmZvLT50cmFuc3BvcnRfaW5mbzsK PiA+ID4gPiArCj4gPiA+ID4gKyAgICAgbXV0ZXhfbG9jaygmb3B0ZWVfcHJpdmF0ZS0+bXUpOwo+ ID4gPiA+ICsgICAgIGxpc3RfZGVsKCZjaGFubmVsLT5saW5rKTsKPiA+ID4gPiArICAgICBtdXRl eF91bmxvY2soJm9wdGVlX3ByaXZhdGUtPm11KTsKPiA+ID4gPiArCj4gPiA+ID4gKyAgICAgaWYg KGNoYW5uZWwtPnRlZV9zaG0pIHsKPiA+ID4gPiArICAgICAgICAgICAgIHRlZV9zaG1fZnJlZShj aGFubmVsLT50ZWVfc2htKTsKPiA+ID4gPiArICAgICAgICAgICAgIGNoYW5uZWwtPnRlZV9zaG0g PSBOVUxMOwo+ID4gPiA+ICsgICAgIH0KPiA+ID4gPiArCj4gPiA+ID4gKyAgICAgY2luZm8tPnRy YW5zcG9ydF9pbmZvID0gTlVMTDsKPiA+ID4gPiArICAgICBjaGFubmVsLT5jaW5mbyA9IE5VTEw7 Cj4gPiA+ID4gKwo+ID4gPiA+ICsgICAgIHNjbWlfZnJlZV9jaGFubmVsKGNpbmZvLCBkYXRhLCBp ZCk7Cj4gPiA+ID4gKwo+ID4gPiA+ICsgICAgIHJldHVybiAwOwo+ID4gPiA+ICt9Cj4gPiA+ID4g Kwo+ID4gPiA+ICtzdGF0aWMgc3RydWN0IHNjbWlfc2hhcmVkX21lbSAqZ2V0X2NoYW5uZWxfc2ht KHN0cnVjdCBvcHRlZV9jaGFubmVsICpjaGFuLCBzdHJ1Y3Qgc2NtaV94ZmVyICp4ZmVyKQo+ID4g PiA+ICt7Cj4gPiA+ID4gKyAgICAgaWYgKCFjaGFuKQo+ID4gPiA+ICsgICAgICAgICAgICAgcmV0 dXJuIE5VTEw7Cj4gPiA+ID4gKwo+ID4gPiA+ICsgICAgIHJldHVybiBjaGFuLT5zaG1lbTsKPiA+ ID4gPiArfQo+ID4gPiA+ICsKPiA+ID4gPiArCj4gPiA+ID4gK3N0YXRpYyBpbnQgb3B0ZWVfc2Vu ZF9tZXNzYWdlKHN0cnVjdCBzY21pX2NoYW5faW5mbyAqY2luZm8sCj4gPiA+ID4gKyAgICAgICAg ICAgICAgICAgICAgICAgICAgIHN0cnVjdCBzY21pX3hmZXIgKnhmZXIpCj4gPiA+ID4gK3sKPiA+ ID4gPiArICAgICBzdHJ1Y3Qgb3B0ZWVfY2hhbm5lbCAqY2hhbm5lbCA9IGNpbmZvLT50cmFuc3Bv cnRfaW5mbzsKPiA+ID4gPiArICAgICBzdHJ1Y3Qgc2NtaV9zaGFyZWRfbWVtICpzaG1lbSA9IGdl dF9jaGFubmVsX3NobShjaGFubmVsLCB4ZmVyKTsKPiA+ID4gPiArICAgICBpbnQgcmV0Owo+ID4g PiA+ICsKPiA+ID4gPiArICAgICBtdXRleF9sb2NrKCZjaGFubmVsLT5tdSk7Cj4gPiA+ID4gKyAg ICAgc2htZW1fdHhfcHJlcGFyZShzaG1lbSwgeGZlcik7Cj4gPiA+ID4gKwo+ID4gPiA+ICsgICAg IHJldCA9IGludm9rZV9wcm9jZXNzX3NtdF9jaGFubmVsKGNoYW5uZWwpOwo+ID4gPgo+ID4gPiBI ZXJlIGFsbCB0aGUgYXNzb2NpYXRlZCBwcm9jZXNzaW5nIGluIHRoZSBUcnVzdGVkT1MgaXMgZnVs bHkgY29tcGxldGVkCj4gPiA+IHJpZ2h0ID8gaS5lLiBhbGwgdGhlIHBvc3NpYmxlIHJlcGx5IHZh bHVlcyBoYXZlIGJlZW4gcHV0IGludG8gc2htZW0gYnkKPiA+ID4gdGhlIFRydXN0ZWRPUyBwcm9j ZXNzIGJlZm9yZSB0aGUgdW5kZXJseWluZyBTTUMgY2FsbCByZXR1cm5zLgo+ID4gPiAoanVzdCB0 byB1bmRlcnN0YW5kIGJldHRlciBob3cgT1BURUUgdHJhbnNwb3J0IGlzIHN1cHBvc2VkIHRvIGJl aGF2ZSkKPiA+Cj4gPiBZZXMsIG9uY2Ugd2UncmUgYmFjayBmcm9tIGludm9rZV9wcm9jZXNzX3Nt dF9jaGFubmVsKCkgdGhlIFNDTUkKPiA+IG1lc3NhZ2UgaGFzIGJlZW4gcHJvY2Vzc2VkIGFuZCB0 aGUgcmVzcG9uc2UgY2FuIGJlIHJlYWQuCj4gPiBJZiBubyByZXNwb25zZSBpcyBmb3VuZCwgaXQg d2lsbCBiZSByZXBvcnRlZCBhcyBhIGNvbW11bmljYXRpb24gZXJyb3IuCj4gPgoKT2suIE1heWJl IGluIHRoZSBmdXR1cmUgdGhpcyBjb3VsZCBiZW5lZml0IGZyb20gc29tZSBuZXcgZ2VuZXJhbCBt ZWNoYW5pc20KSSdtIGFkZGluZyBpbiB0aGUgY29yZSAod2l0aCBTQ01JIGF0b21pYyBzZXJpZXMp IHRvIGFkZHJlc3MgdGhpcyBzY2VuYXJpbyBpbgp3aGljaCB5b3UgcmVhbGx5IGRvIG5vdCBoYXZl IHRvIHdhaXQgbmVpdGhlciBwb2xsIGZvciBhbnl0aGluZyBhZnRlciB0aGUKc2VuZCBhbmQgeW91 IGNvdWxkL3Nob3VsZCBhdm9pZCBjYWxsaW5nIHNjbWlfcnhfY2FsbGJhY2soKSBhbmQganVzdCBs ZXQKdGhlIFNDTUkgY29yZSBleGVjdXRlIGEgZmV0Y2hfcmVzcG9uc2UgaW1tZWRpYXRlbHkgYWZ0 ZXIgdGhlIHNlbmQuCih3aXRoIHNjbWlfcnhfY2FsbGJhY2sgc3VwcG9zZWQgdG8gYmUgY2FsbGVk IHdoZW4gYSBjb21wbGV0aW9uIGludGVycnVwdAppcyByZWNlaXZlZCkKClNvLCBqdXN0IGEgaGVh ZHMgdXAgaGVyZSwgdGhhdCBJIGNvdWxkIHJldmlzaXQgdGhpcyAoYW5kIGJvdGhlciB5b3UpIG9u Y2UgKGlmKQp0aGUgYWJvdmUgbWVudGlvbmVkIFNDTUkgYXRvbWljIHNlcmlzIGlzIGluLCBCVVQg ZGVmaW5pdGVseSBub3RoaW5nIHRvIGJlCmFkZHJlc3NlZCBub3cgaW4gdGhpcyBzZXJpZXMuCgo+ ID4gPgo+ID4gPiA+ICsKPiA+ID4gPiArICAgICBzY21pX3J4X2NhbGxiYWNrKGNpbmZvLCBzaG1l bV9yZWFkX2hlYWRlcihzaG1lbSksIE5VTEwpOwo+ID4gPiA+ICsgICAgIG11dGV4X3VubG9jaygm Y2hhbm5lbC0+bXUpOwo+ID4gPiA+ICsKPiA+ID4gPiArICAgICByZXR1cm4gcmV0Owo+ID4gPiA+ ICt9Cj4gPiA+ID4gKwo+ID4gPiA+ICtzdGF0aWMgdm9pZCBvcHRlZV9mZXRjaF9yZXNwb25zZShz dHJ1Y3Qgc2NtaV9jaGFuX2luZm8gKmNpbmZvLAo+ID4gPiA+ICsgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICBzdHJ1Y3Qgc2NtaV94ZmVyICp4ZmVyKQo+ID4gPiA+ICt7Cj4gPiA+ID4gKyAg ICAgc3RydWN0IG9wdGVlX2NoYW5uZWwgKmNoYW5uZWwgPSBjaW5mby0+dHJhbnNwb3J0X2luZm87 Cj4gPiA+ID4gKyAgICAgc3RydWN0IHNjbWlfc2hhcmVkX21lbSAqc2htZW0gPSBnZXRfY2hhbm5l bF9zaG0oY2hhbm5lbCwgeGZlcik7Cj4gPiA+ID4gKwo+ID4gPiA+ICsgICAgIHNobWVtX2ZldGNo X3Jlc3BvbnNlKHNobWVtLCB4ZmVyKTsKPiA+ID4gPiArfQo+ID4gPiA+ICsKPiA+ID4gPiArc3Rh dGljIGJvb2wgb3B0ZWVfcG9sbF9kb25lKHN0cnVjdCBzY21pX2NoYW5faW5mbyAqY2luZm8sCj4g PiA+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3Qgc2NtaV94ZmVyICp4ZmVyKQo+ ID4gPiA+ICt7Cj4gPiA+ID4gKyAgICAgc3RydWN0IG9wdGVlX2NoYW5uZWwgKmNoYW5uZWwgPSBj aW5mby0+dHJhbnNwb3J0X2luZm87Cj4gPiA+ID4gKyAgICAgc3RydWN0IHNjbWlfc2hhcmVkX21l bSAqc2htZW0gPSBnZXRfY2hhbm5lbF9zaG0oY2hhbm5lbCwgeGZlcik7Cj4gPiA+ID4gKwo+ID4g PiA+ICsgICAgIHJldHVybiBzaG1lbV9wb2xsX2RvbmUoc2htZW0sIHhmZXIpOwo+ID4gPiA+ICt9 Cj4gPiA+ID4gKwo+ID4gPiA+ICtzdGF0aWMgc3RydWN0IHNjbWlfdHJhbnNwb3J0X29wcyBzY21p X29wdGVlX29wcyA9IHsKPiA+ID4gPiArICAgICAuY2hhbl9hdmFpbGFibGUgPSBvcHRlZV9jaGFu X2F2YWlsYWJsZSwKPiA+ID4gPiArICAgICAuY2hhbl9zZXR1cCA9IG9wdGVlX2NoYW5fc2V0dXAs Cj4gPiA+ID4gKyAgICAgLmNoYW5fZnJlZSA9IG9wdGVlX2NoYW5fZnJlZSwKPiA+ID4gPiArICAg ICAuc2VuZF9tZXNzYWdlID0gb3B0ZWVfc2VuZF9tZXNzYWdlLAo+ID4gPiA+ICsgICAgIC5mZXRj aF9yZXNwb25zZSA9IG9wdGVlX2ZldGNoX3Jlc3BvbnNlLAo+ID4gPiA+ICsgICAgIC5jbGVhcl9j aGFubmVsID0gb3B0ZWVfY2xlYXJfY2hhbm5lbCwKPiA+ID4gPiArICAgICAucG9sbF9kb25lID0g b3B0ZWVfcG9sbF9kb25lLAo+ID4gPiA+ICt9Owo+ID4gPiA+ICsKPiA+ID4gPiArY29uc3Qgc3Ry dWN0IHNjbWlfZGVzYyBzY21pX29wdGVlX2Rlc2MgPSB7Cj4gPiA+ID4gKyAgICAgLm9wcyA9ICZz Y21pX29wdGVlX29wcywKPiA+ID4gPiArICAgICAubWF4X3J4X3RpbWVvdXRfbXMgPSAzMCwKPiA+ ID4gPiArICAgICAubWF4X21zZyA9IDIwLAo+ID4gPiA+ICsgICAgIC5tYXhfbXNnX3NpemUgPSAx MjgsCj4gPiA+ID4gK307Cj4gPiA+ID4gKwo+ID4gPiA+ICtzdGF0aWMgaW50IG9wdGVlX2N0eF9t YXRjaChzdHJ1Y3QgdGVlX2lvY3RsX3ZlcnNpb25fZGF0YSAqdmVyLCBjb25zdCB2b2lkICpkYXRh KQo+ID4gPiA+ICt7Cj4gPiA+ID4gKyAgICAgcmV0dXJuIHZlci0+aW1wbF9pZCA9PSBURUVfSU1Q TF9JRF9PUFRFRTsKPiA+ID4gPiArfQo+ID4gPiA+ICsKPiA+ID4gPiArc3RhdGljIGludCBvcHRl ZV9zZXJ2aWNlX3Byb2JlKHN0cnVjdCBkZXZpY2UgKmRldikKPiA+ID4gPiArewo+ID4gPiA+ICsg ICAgIHN0cnVjdCBvcHRlZV9hZ2VudCAqYWdlbnQ7Cj4gPiA+ID4gKyAgICAgc3RydWN0IHRlZV9j b250ZXh0ICp0ZWVfY3R4Owo+ID4gPiA+ICsgICAgIGludCByZXQ7Cj4gPiA+ID4gKwo+ID4gPiA+ ICsgICAgIC8qIE9ubHkgb25lIFNDTUkgT1AtVEVFIGRldmljZSBhbGxvd2VkICovCj4gPiA+ID4g KyAgICAgaWYgKG9wdGVlX3ByaXZhdGUpIHsKPiA+ID4gPiArICAgICAgICAgICAgIGRldl9lcnIo ZGV2LCAiQW4gU0NNSSBPUC1URUUgZGV2aWNlIHdhcyBhbHJlYWR5IGluaXRpYWxpemVkOiBvbmx5 IG9uZSBhbGxvd2VkXG4iKTsKPiA+ID4gPiArICAgICAgICAgICAgIHJldHVybiAtRUJVU1k7Cj4g PiA+ID4gKyAgICAgfQo+ID4gPiA+ICsKPiA+ID4gPiArICAgICB0ZWVfY3R4ID0gdGVlX2NsaWVu dF9vcGVuX2NvbnRleHQoTlVMTCwgb3B0ZWVfY3R4X21hdGNoLCBOVUxMLCBOVUxMKTsKPiA+ID4g PiArICAgICBpZiAoSVNfRVJSKHRlZV9jdHgpKQo+ID4gPiA+ICsgICAgICAgICAgICAgcmV0dXJu IC1FTk9ERVY7Cj4gPiA+ID4gKwo+ID4gPiA+ICsgICAgIGFnZW50ID0gZGV2bV9remFsbG9jKGRl diwgc2l6ZW9mKCphZ2VudCksIEdGUF9LRVJORUwpOwo+ID4gPiA+ICsgICAgIGlmICghYWdlbnQp IHsKPiA+ID4gPiArICAgICAgICAgICAgIHJldCA9IC1FTk9NRU07Cj4gPiA+ID4gKyAgICAgICAg ICAgICBnb3RvIG91dDsKPiA+ID4gPiArICAgICB9Cj4gPiA+ID4gKwo+ID4gPiA+ICsgICAgIGFn ZW50LT5kZXYgPSBkZXY7Cj4gPiA+ID4gKyAgICAgYWdlbnQtPnRlZV9jdHggPSB0ZWVfY3R4Owo+ ID4gPiA+ICsgICAgIElOSVRfTElTVF9IRUFEKCZhZ2VudC0+Y2hhbm5lbF9saXN0KTsKPiA+ID4g PiArCj4gPiA+ID4gKyAgICAgb3B0ZWVfcHJpdmF0ZSA9IGFnZW50Owo+ID4gPgo+ID4gPiBCYXJy aWVyIGhlcmUgdG8gYmUgc3VyZSB0aGlzIGdsb2JhbCBpcyB2aXNpYmxlIGFuZCBub3QgcmVvcmRl cmVkID8KPiA+ID4KPiA+ID4gTm90IHN1cmUgaWYgaXQgaXMgcGxhdXNpYmxlIHRoYXQgd2l0aG91 dCBhIGJhcnJpZXIgdGhlIHN1YnNlcXVlbnQKPiA+ID4gb3B0ZWVfY2hhbl9zZXR1cCBjb3VsZCBy dW4gb24gYW5vdGhlciBjb3JlIGFuZCBzaW1wbHkgbWlzcyB0aGlzIHVwZGF0ZQo+ID4gPiBhbmQg YmFpbCBvdXQuIChjYW5ub3Qgc2VlIGFueSBsb2NraW5nIG9mIGFueSBraW5kIGVpdGhlciBpbiB0 aGUKPiA+ID4gY2hhbl9hdmFpbGFibGUvY2hhbl9zZXR1cCBUWCBwYXRoIHRoYXQgY291bGQgdHJp Z2dlciBhIGltcGxpY2l0IG1lbW9yeQo+ID4gPiBiYXJyaWVyLi4uLmJhaCBtYXliZSBJJ20gcGFy YW5vaWQpCj4gPgo+ID4gTm8gYmFycmllciBuZWVkZWQgSU1PLiBvcHRlZV9wcml2YXRlIGlzIHN0 YW5kYXJkIGNhY2hlZCBtZW1vcnkgdmlzaWJsZQo+ID4gdG8gYWxsIHBhcnRpY2lwYW50IGNvcmVz Cj4gPiBhbmQgY2hhbl9zZXR1cCBjYW5ub3QgYmUgY2FsbGVkIGJlZm9yZSB0aGlzIGZ1bmN0aW9u IGNvbXBsZXRlcy4KPiA+IERvIEkgbWlzcyBzb21ldGhpbmc/Cj4gPgo+IAo+IEkgc2VlIHdoeSB5 b3UgYXNrIGZvciBhIGJhcnJpZXIuIEluZGVlZCwgYXQgbW9kdWxlIGluc2VydGlvbiB3ZSBjYW4K PiBmYWNlIGNvbnNpc3RlbmN5IGlzc3Vlcy4KPiAKClllcyBteSBjb25jZXJuIHdhcyBhbHNvIGFi b3V0IG11bHRpcGxlIGNvbmN1cnJlbnQgcHJvYmluZyBlc3BlY2lhbGx5LApldmVuIHRob3VnaCB3 ZSByZWFsbHkgZG8gbm90IHN1cHBvcnQgbXVsdGlwbGUgU0NNSSBzZXJ2ZXIgbm9kZXMgdGhlCmZh Y3QgdGhhdCB5b3UgY291bGQgZGVmaW5lIG11bHRpcGxlIGNoYW5uZWxzIChvbiBvcHRlZSkgY291 bGQgbGVhZCB0bwptdWx0aXBsZSBwcm9iZXMsIHdoaWxlIGluIHZpcnRpbyB5b3UgY291bGQgd3Jv bmdseSB0cnkgdG8gZGVzY3JpYmUKbXVsdGlwbGUgbW1pb3MgZGV2cyAod2l0aCB2aXJ0aW8gbm90 IHN1cHBvcnRpbmcgbXVsdGlwbGUgZGV2aWNlcyBmb3IKbm93Li4uaGVuY2UgdGhlIGNoZWNrKQoK PiBJIGFncmVlIGJhcnJpZXJzIGFyZSBuZWVkZWQuIExvb2tpbmcgYXQgdGhlIHNjbWlfdmlydGlv Cj4gaW1wbGVtZW50YXRpb24sIGkgdGhpbmsgdGhlIGJhcnJpZXJzIGFyZSBtaXNwbGFjZWQgaW4g dGhlIHNlcXVlbmNlcy4KPiBUaGUgYmFycmllciBzaG91bGQgYmUgcGxhY2VkIGJlZm9yZSB0aGUg Z2xvYmFsIHJlZmVyZW5jZSBpcyBsb2FkZWQgYXQKPiBkZXZpY2UgcHJvYmUsIHNvIHRoYXQgaXRz IGNvbnRlbnQgaXMgdmlzaWJsZSBiZWZvcmUgdGhlIGRldmljZQo+IHJlZmVyZW5jZSBpdHNlbGYu Cj4gT24gdGhlIG90aGVyIGhhbmQgaW4gdGhlIHJlbW92ZSBzZXF1ZW5jZSwgdGhlIGJhcnJpZXIg c2hvdWxkIGJlIHBsYWNlZAo+IGFmdGVyIGRldmljZSByZWYgaXMgY2xlYXJlZCBidXQgYmVmb3Jl IGRldmljZSByZXNvdXJjZXMgYXJlIHJlbGVhc2VkLgo+IE5vdGUgdGhhdCwgaW4gc21wX3N0b3Jl X21iKCkgaW1wbGVtZW50YXRpb24sIHRoZSBtZW1vcnkgYmFycmllciBpcwo+IHBsYWNlcyBhZnRl ciB0aGUgZGF0YSBpcyBsb2FkZWQsIG5vdCBiZWZvcmUuCj4gU2VlIHRoZSBwYXRjaC1saWtlIHNu aXBwZXQgYmVsb3c6Cj4gCj4gIHN0YXRpYyBpbnQgc2NtaV92aW9fcHJvYmUoc3RydWN0IHZpcnRp b19kZXZpY2UgKnZkZXYpCj4gIHsKPiAgICAgICguLi4pCj4gCj4gLSAgICB2ZGV2LT5wcml2ID0g Y2hhbm5lbHM7Cj4gLSAgICAvKiBFbnN1cmUgaW5pdGlhbGl6ZWQgc2NtaV92ZGV2IGlzIHZpc2li bGUgKi8KPiAtICAgIHNtcF9zdG9yZV9tYihzY21pX3ZkZXYsIHZkZXYpOwo+ICsgICAgLyogRW5z dXJlIGluaXRpYWxpemVkIHNjbWlfdmRldiBpcyB2aXNpYmxlIGJlZm9yZSBzY21pX3ZkZXYgaXMg Ki8KPiArICAgIHNtcF9zdG9yZV9tYih2ZGV2LT5wcml2LCBjaGFubmVscyk7Cj4gKyAgICBzY21p X3ZkZXYgPSB2ZGV2Owo+IAo+ICAgICByZXR1cm4gMDsKPiAgfQo+IAo+ICBzdGF0aWMgdm9pZCBz Y21pX3Zpb19yZW1vdmUoc3RydWN0IHZpcnRpb19kZXZpY2UgKnZkZXYpCj4gIHsKPiArICAgIC8q IEVuc3VyZSBzY21pX3ZkZXYgaXMgdmlzaWJsZSBhcyBOVUxMIGJlZm9yZSByZXNvdXJjZXMgYXJl IHJlbGVhc2VkICovCj4gKyAgICBzbXBfc3RvcmVfbWIoc2NtaV92ZGV2LCBOVUxMKTsKPiArCj4g ICAgICAvKgo+ICAgICAgICogT25jZSB3ZSBnZXQgaGVyZSwgdmlydGlvX2NoYW5fZnJlZSgpIHdp bGwgaGF2ZSBhbHJlYWR5IGJlZW4gY2FsbGVkIGJ5Cj4gICAgICAgKiB0aGUgU0NNSSBjb3JlIGZv ciBhbnkgZXhpc3RpbmcgY2hhbm5lbCBhbmQsIGFzIGEgY29uc2VxdWVuY2UsIGFsbCB0aGUKPiAg ICAgICAqIHZpcnRpbyBjaGFubmVscyB3aWxsIGhhdmUgYmVlbiBhbHJlYWR5IG1hcmtlZCBOT1Qg cmVhZHksIGNhdXNpbmcgYW55Cj4gICAgICAgKiBvdXRzdGFuZGluZyBtZXNzYWdlIG9uIGFueSB2 cXVldWUgdG8gYmUgaWdub3JlZCBieSBjb21wbGV0ZV9jYjogbm93Cj4gICAgICAgKiB3ZSBjYW4g anVzdCBzdG9wIHByb2Nlc3NpbmcgYnVmZmVycyBhbmQgZGVzdHJveSB0aGUgdnF1ZXVlcy4KPiAg ICAgICAqLwo+ICAgICAgdmRldi0+Y29uZmlnLT5yZXNldCh2ZGV2KTsKPiAgICAgIHZkZXYtPmNv bmZpZy0+ZGVsX3Zxcyh2ZGV2KTsKPiAtICAgIC8qIEVuc3VyZSBzY21pX3ZkZXYgaXMgdmlzaWJs ZSBhcyBOVUxMICovCj4gLSAgICBzbXBfc3RvcmVfbWIoc2NtaV92ZGV2LCBOVUxMKTsKPiAgfQo+ IAo+IERvZXMgdGhhdCBtYWtlIHNlbnNlIHRvIHlvdT8KPiAKClNvIG15IHJlYXNvbmluZyB3YXM6 CjEuIEkgd2FudCB0byBoYXZlIC0+cHJpdiA9IGNoYW5uZWxzIHBvcHVsYXRlZCBiZWZvcmUgc2Nt aV9kZXYgd2FzIHZpc2libGUgZm9yCm90aGVyIFBFcyBhcyBhIGdsb2JhbC4KCglCVVQKCjIuIHdh bnQgYWxzbyB0byBiZSBzdXJlIHRoYXQgc2NtaV9kZXYgaXRzZWxmIHdhcyB2aXNpYmxlIHRvIG90 aGVyIFBFczogd2hhdAppZiBhbm90aGVyIGNvcmUgaXMgY29uY3VycmVudGx5IHByb2JpbmcgZm9y IGFub3RoZXIgKHdyb25nbHkgZGVmaW5lZCBpbiBEVCkKc2NtaS12aXJ0aW8gTU1JTyBkZXZpY2Ug PwpXaWxsIHNjbWlfZGV2IHN0aWxsIGJlIHZpZXdlZCBhcyBOVUxMIGZyb20gYW5vdGhlciBwcm9i aW5nIGNvcmUgZm9yIGEgd2hpbGUKZGVzcGl0ZSBzY21pX2RldiA9IHZkZXYgaGFkIGJlZW4gZXhl Y3V0ZWQgb24gdGhlIGZpcnN0IGNvcmUgcHJvYmUgPwoKTXkgaG9wZSAoOkQpLCBzaW5jZSBzbXBf c3RvcmVfbWIoKSBpdCdzIGEgV1JJVEVfT05DRSArIF9fc21iX21iKCkgd2hpY2ggaW4gdHVybgpp cyBhIGRtYihpc2gpIG9uIGFybTY0LCB3YXMgdG8gZHJhdyBhIGxpbmUgYWZ0ZXIgd2hpY2ggSSBj b3VsZCBoYXZlIGJlZW4gc3VyZQp0aGF0IHNjbWlfZGV2IHN0b3JlIGFuZCBhbGwgcHJldmlvdXMg bWVtLWFjY2Vzc2VzIChvbiB0aGlzIGNvcmUpIHdvdWxkIGhhdmUgYXQKbGVhc3QgYmVlbiBpbml0 aWF0ZWQgKGhpdCB0aGUgY2FjaGUpIHNvIHRoYXQgYWZ0ZXIgdGhhdCBwb2ludCBhbnkgYWNjZXNz IGZyb20KYW5vdGhlciBQRSB3b3VsZCBoYXZlIGJlZW4gc2VydmVkIHByb3Blcmx5IGJ5IHRoZSBt YWdpYyBvZiBjYWNoZSBjb2VoZXJlbmN5CnByb3RvY29sIG9uIHRoZSBpc2ggZG9tYWluLgoKSSBj b3VsZCBiZSBhIGJpdCBjb25jZXJuZWQgaW5kZWVkIG9mIGFuIGFkZGl0aW9uYWwgbWlzc2luZyBl YXJseSBXUklURV9PTkNFKCkKb24gdmRldi0+cHJpdiA9IGNoYW5uZWxzIHNvIGFzIHRvIGhhdmUg KHRvIGF2b2lkIGNvbXBpbGVyIHRyaWNrcyBpbnN0ZWFkCm9uIHZkZXYtPnByaXYpOgoKCVdSSVRF X09OQ0UodmRldi0+cHJpdiwgY2hhbm5lbHMpOwoJc21wX3N0b3JlX21iKHNjbWlfdmRldiwgdmRl dik7CgouLmJ1dCByZWFsbHkgbm90IHN1cmUgaG93IG11Y2ggdGhpcyBoYXMgYSBjaGFuY2UgdG8g aGFwcGVuLgoKU2FtZSBpdCBnb2VzIGZvciB0aGUgcmVtb3ZlIHBhdGguLi5vbmNlIGluIHNjbWlf dmlvX3JlbW92ZSgpIEkgd2FudCB0bwpiZSBhdCBmaXJzdCBzdG9wL2ZsdXNoIGFsbCBwZW5kaW5n IHN0dWZmIG9uIHRoZSB2cXVldWVzIGtub3dpbmcgdGhhdDoKCiAxLiB2aXJ0aW9fY2hhbl9mcmVl IGhhcyBiZWVuIGFscmVhZHkgcHJldmlvdXNseSBjYWxsZWQgYW5kIGl0IG1hcmtlZCBhbGwKICAg IHZxdWV1ZXMgYXMgTk9UIHJlYWR5LCBzbyBub2JvZHkgd2lsbCBxdWV1ZSBhbnl0aGluZyBvbiB2 ZGV2IGFueXdheQoKIDIuIGFueSBvdGhlciBwb3NzaWJsZSBwcm9iZSB3b3VsZCBTVElMTCBmaW5k IHNjbWlfZGV2ICE9IE5VTEwgYW5kCiAgICBpdCAnZCBiYWlsIG91dCB0aWxsIEknbSBkb25lIHdp dGggdGhlIHJlbW92ZQoKT05MWSBhZnRlcndhcmRzIEkgd291bGQgbWFkZSBzY21pX2RldiB2aXNp YmxlIGFzIE5VTEwgZm9yIGV2ZXJ5Ym9keS4KCkRvZXMgdGhpcyBjb3VudGVyLXJlYXNvbmluZyBt YWtlcyBzZW5zZSA/CgouLi5PUiwgdGJoLCBJIGhhdmUgdG8ganVzdCByZS1yZWFkIGFub3RoZXIg bi10aW1lcyBtZW1vcnktYmFycmllcnMudHh0CiguLi5hbmQgcmVtYWluIGEgYml0IHB1enpsZWQg YW55d2F5IDpEKQoKPiA+ID4KPiA+ID4gPiArCj4gPiA+ID4gKyAgICAgcmV0ID0gZ2V0X2NhcGFi aWxpdGllcygpOwo+ID4gPiA+ICsKPiA+ID4gPiArb3V0Ogo+ID4gPiA+ICsgICAgIGlmIChyZXQp IHsKPiA+ID4gPiArICAgICAgICAgICAgIHRlZV9jbGllbnRfY2xvc2VfY29udGV4dCh0ZWVfY3R4 KTsKPiA+ID4gPiArICAgICAgICAgICAgIG9wdGVlX3ByaXZhdGUgPSBOVUxMOwo+ID4gPgo+ID4g PiBCYXJyaWVyID8gKG5vdCBzdXJlIGFzIGFib3ZlLi4uKQo+ID4gPgo+ID4gPiA+ICsgICAgIH0K PiA+ID4gPiArCj4gPiA+ID4gKyAgICAgcmV0dXJuIHJldDsKPiA+ID4gPiArfQo+ID4gPiA+ICsK PiA+ID4gPiArc3RhdGljIGludCBvcHRlZV9zZXJ2aWNlX3JlbW92ZShzdHJ1Y3QgZGV2aWNlICpk ZXYpCj4gPiA+ID4gK3sKPiA+ID4gPiArICAgICBpZiAob3B0ZWVfcHJpdmF0ZSkKPiA+ID4gPiAr ICAgICAgICAgICAgIHJldHVybiAtRUlOVkFMOwo+ID4gPgo+ID4gPiBJcyBpdCAgaW5zdGVhZDog aWYgKCFvcHRlZV9wcml2YXRlKSA/Cj4gPgo+ID4gT3VwcyEgaW5kZWVkIDooCj4gPgo+ID4gPiA+ ICsKPiA+ID4gPiArICAgICBpZiAoIWxpc3RfZW1wdHkoJm9wdGVlX3ByaXZhdGUtPmNoYW5uZWxf bGlzdCkpCj4gPiA+ID4gKyAgICAgICAgICAgICByZXR1cm4gLUVCVVNZOwo+ID4gPiA+ICsKPiA+ ID4gPiArICAgICB0ZWVfY2xpZW50X2Nsb3NlX2NvbnRleHQob3B0ZWVfcHJpdmF0ZS0+dGVlX2N0 eCk7Cj4gPiA+ID4gKwo+ID4gPiA+ICsgICAgIG9wdGVlX3ByaXZhdGUgPSBOVUxMOwo+ID4gPiA+ ICsKPiA+ID4KPiA+ID4gQmFycmllciA/IChub3Qgc3VyZSBhcyBhYm92ZS4uLikKPiA+ID4KPiA+ ID4gPiArICAgICByZXR1cm4gMDsKPiA+ID4gPiArfQo+ID4gPiA+ICsKPiA+ID4gPiArc3RhdGlj IGNvbnN0IHN0cnVjdCB0ZWVfY2xpZW50X2RldmljZV9pZCBzY21pX29wdGVlX3NlcnZpY2VfaWRb XSA9IHsKPiA+ID4gPiArICAgICB7Cj4gPiA+ID4gKyAgICAgICAgICAgICBVVUlEX0lOSVQoMHhh OGNmZTQwNiwgMHhkNGY1LCAweDRhMmUsCj4gPiA+ID4gKyAgICAgICAgICAgICAgICAgICAgICAg MHg5ZiwgMHg4ZCwgMHhhMiwgMHg1ZCwgMHhjNywgMHg1NCwgMHhjMCwgMHg5OSkKPiA+ID4gPiAr ICAgICB9LAo+ID4gPiA+ICsgICAgIHsgfQo+ID4gPiA+ICt9Owo+ID4gPiA+ICsKPiA+ID4gPiAr TU9EVUxFX0RFVklDRV9UQUJMRSh0ZWUsIHNjbWlfb3B0ZWVfc2VydmljZV9pZCk7Cj4gPiA+ID4g Kwo+ID4gPiA+ICtzdGF0aWMgc3RydWN0IHRlZV9jbGllbnRfZHJpdmVyIHNjbWlfb3B0ZWVfZHJp dmVyID0gewo+ID4gPiA+ICsgICAgIC5pZF90YWJsZSAgICAgICA9IHNjbWlfb3B0ZWVfc2Vydmlj ZV9pZCwKPiA+ID4gPiArICAgICAuZHJpdmVyICAgICAgICAgPSB7Cj4gPiA+ID4gKyAgICAgICAg ICAgICAubmFtZSA9ICJzY21pLW9wdGVlIiwKPiA+ID4gPiArICAgICAgICAgICAgIC5idXMgPSAm dGVlX2J1c190eXBlLAo+ID4gPiA+ICsgICAgICAgICAgICAgLnByb2JlID0gb3B0ZWVfc2Vydmlj ZV9wcm9iZSwKPiA+ID4gPiArICAgICAgICAgICAgIC5yZW1vdmUgPSBvcHRlZV9zZXJ2aWNlX3Jl bW92ZSwKPiA+ID4gPiArICAgICB9LAo+ID4gPiA+ICt9Owo+ID4gPiA+ICsKPiA+ID4gPiArc3Rh dGljIGludCBfX2luaXQgc2NtaV9vcHRlZV9pbml0KHZvaWQpCj4gPiA+ID4gK3sKPiA+ID4gPiAr ICAgICByZXR1cm4gZHJpdmVyX3JlZ2lzdGVyKCZzY21pX29wdGVlX2RyaXZlci5kcml2ZXIpOwo+ ID4gPiA+ICt9Cj4gPiA+ID4gKwo+ID4gPiA+ICtzdGF0aWMgdm9pZCBfX2V4aXQgc2NtaV9vcHRl ZV9leGl0KHZvaWQpCj4gPiA+ID4gK3sKPiA+ID4gPiArICAgICBkcml2ZXJfdW5yZWdpc3Rlcigm c2NtaV9vcHRlZV9kcml2ZXIuZHJpdmVyKTsKPiA+ID4gPiArfQo+ID4gPiA+ICsKPiA+ID4gPiAr ZGV2aWNlX2luaXRjYWxsKHNjbWlfb3B0ZWVfaW5pdCkKPiA+ID4gPiArbW9kdWxlX2V4aXQoc2Nt aV9vcHRlZV9leGl0KTsKPiA+ID4KPiA+ID4gVGhpcyBicmVha3MgdGhlIGJ1aWxkIHdoZW4gQVJN X1NDTUlfUFJPVE9DT0w9bSBhbmQgU0NNSSBPUFRFRSB0cmFuc3BvcnQgaXMgZW5hYmxlZCwKPiA+ ID4gc2luY2UgdGhlIFNDTUkgdHJhbnNwb3J0cyBhcmUgbm90IGZ1bGwgZmxlZGdlZCBkcml2ZXJz IGJ1dCB0aGV5IGFyZSBidWlsdCBpbnRvCj4gPiA+IHRoZSBTQ01JIHN0YWNrIGNvcmUgbW9kdWxl LCBzbyBpZiB5b3UgZW5kdXAgdHJ5aW5nIHRvIGRlZmluZSBtdWx0aXBsZSBpbml0cy4KPiA+ID4K PiA+ID4gIExEIFtNXSAgZHJpdmVycy9maXJtd2FyZS9hcm1fc2NtaS9zY21pLW1vZHVsZS5vCj4g PiA+IC9vcHQvdG9vbGNoYWlucy9nY2MtYXJtLTguMy0yMDE5LjAzLXg4Nl82NC1hYXJjaDY0LWxp bnV4LWdudS9iaW4vYWFyY2g2NC1saW51eC1nbnUtbGQ6IGRyaXZlcnMvZmlybXdhcmUvYXJtX3Nj bWkvb3B0ZWUubzogaW4gZnVuY3Rpb24gYHNjbWlfb3B0ZWVfaW5pdCc6Cj4gPiA+IC9ob21lL2Ny aW1hcjAxL0FSTS9kZXYvc3JjL3Bkc3cvbGludXgvZHJpdmVycy9maXJtd2FyZS9hcm1fc2NtaS9v cHRlZS5jOjU0OTogbXVsdGlwbGUgZGVmaW5pdGlvbiBvZiBgaW5pdF9tb2R1bGUnOyBkcml2ZXJz L2Zpcm13YXJlL2FybV9zY21pL2RyaXZlci5vOi9ob21lL2NyaW1hcjAxL0FSTS9kZXYvc3JjL3Bk c3cvbGludXgvZHJpdmVycy9maXJtd2FyZS9hcm1fc2NtaS9kcml2ZXIuYzoyMDcwOiBmaXJzdCBk ZWZpbmVkIGhlcmUKPiA+ID4gL29wdC90b29sY2hhaW5zL2djYy1hcm0tOC4zLTIwMTkuMDMteDg2 XzY0LWFhcmNoNjQtbGludXgtZ251L2Jpbi9hYXJjaDY0LWxpbnV4LWdudS1sZDogZHJpdmVycy9m aXJtd2FyZS9hcm1fc2NtaS9vcHRlZS5vOiBpbiBmdW5jdGlvbiBgc2NtaV9vcHRlZV9leGl0JzoK PiA+ID4gL2hvbWUvY3JpbWFyMDEvQVJNL2Rldi9zcmMvcGRzdy9saW51eC9kcml2ZXJzL2Zpcm13 YXJlL2FybV9zY21pL29wdGVlLmM6NTU0OiBtdWx0aXBsZSBkZWZpbml0aW9uIG9mIGBjbGVhbnVw X21vZHVsZSc7IGRyaXZlcnMvZmlybXdhcmUvYXJtX3NjbWkvZHJpdmVyLm86L2hvbWUvY3JpbWFy MDEvQVJNL2Rldi9zcmMvcGRzdy9saW51eC9kcml2ZXJzL2Zpcm13YXJlL2FybV9zY21pL2RyaXZl ci5jOjIwOTk6IGZpcnN0IGRlZmluZWQgaGU+IC9ob21lL2NyaW1hcjAxL0FSTS9kZXYvc3JjL3Bk c3cvbGludXgvc2NyaXB0cy9NYWtlZmlsZS5idWlsZDo0NzQ6IHJlY2lwZSBmb3IgdGFyZ2V0ICdk cml2ZXJzL2Zpcm13YXJlL2FybV9zY21pL3NjbWktbW9kdWxlLm8nIGZhaWxlZAo+ID4gPiBtYWtl WzRdOiAqKiogW2RyaXZlcnMvZmlybXdhcmUvYXJtX3NjbWkvc2NtaS1tb2R1bGUub10gRXJyb3Ig MQo+ID4gPiAvaG9tZS9jcmltYXIwMS9BUk0vZGV2L3NyYy9wZHN3L2xpbnV4L3NjcmlwdHMvTWFr ZWZpbGUuYnVpbGQ6NTQwOiByZWNpcGUgZm9yIHRhcmdldCAnZHJpdmVycy9maXJtd2FyZS9hcm1f c2NtaScgZmFpbGVkCj4gPiA+IG1ha2VbM106ICoqKiBbZHJpdmVycy9maXJtd2FyZS9hcm1fc2Nt aV0gRXJyb3IgMgo+ID4gPiAvaG9tZS9jcmltYXIwMS9BUk0vZGV2L3NyYy9wZHN3L2xpbnV4L3Nj cmlwdHMvTWFrZWZpbGUuYnVpbGQ6NTQwOiByZWNpcGUgZm9yIHRhcmdldCAnZHJpdmVycy9maXJt d2FyZScgZmFpbGVkCj4gPiA+IG1ha2VbMl06ICoqKiBbZHJpdmVycy9maXJtd2FyZV0gRXJyb3Ig Mgo+ID4gPiBtYWtlWzJdOiAqKiogV2FpdGluZyBmb3IgdW5maW5pc2hlZCBqb2JzLi4uLgo+ID4g PiAvaG9tZS9jcmltYXIwMS9BUk0vZGV2L3NyYy9wZHN3L2xpbnV4L01ha2VmaWxlOjE4NzQ6IHJl Y2lwZSBmb3IgdGFyZ2V0ICdkcml2ZXJzJyBmYWlsZWQKPiA+ID4gbWFrZVsxXTogKioqIFtkcml2 ZXJzXSBFcnJvciAyCj4gPiA+IG1ha2VbMV06IExlYXZpbmcgZGlyZWN0b3J5ICcvaG9tZS9jcmlt YXIwMS9BUk0vZGV2L3NyYy9wZHN3L291dF9saW51eCcKPiA+ID4gTWFrZWZpbGU6MjE5OiByZWNp cGUgZm9yIHRhcmdldCAnX19zdWItbWFrZScgZmFpbGVkCj4gPiA+Cj4gPiA+IEluIG9yZGVyIHRv IGFkZHJlc3MgdGhpcyBpc3N1ZSAoc2FtZSBoYXBwZW5kZWQgd2l0aCBWaXJ0SU8pIEkgYWRkZWQK PiA+ID4gdHJhbnNwb3J0X2luaXQvdHJhbnNwb3J0X2V4aXQgb3B0aW9uYWwgaG9va3MgaW50byBz Y21pX2Rlc2MsIHNvIHRoYXQKPiA+ID4geW91IGNhbiBhc2sgdGhlIGNvcmUgU0NNSSBzdGFjayB0 byBwZXJmb3JtIHdoYXRldmVyIHlvdXIgdHJhbnNwb3J0Cj4gPiA+IG5lZWRzIGF0IFNDTUkgY29y ZSBpbml0LXRpbWUsIGJlZm9yZSB0aGUgU0NNSSBjb3JlIHN0YWNrIGlzIHByb2JlZC4KPiA+ID4K PiA+ID4gSW4gb3RoZXIgd29yZHMgdGhlIGZpeCBoZXJlIGRvd24gYmVsb3cgZml4ZXMgZm9yIG1l IHRoZSBidWlsZCBhcyBhCj4gPiA+IG1vZHVsZSBvZiB0aGUgU0NNSSBzdGFjay4KPiA+Cj4gPiBU byBlbnN1cmUgc2NtaS9vcHRlZSB0cmFuc3BvcnQgY2FuIHJlZ2lzdGVyIHRvIHRoZSB0ZWUgYnVz LCBpdCBtdXN0Cj4gPiB3YWl0IHRlZSBidXMgaXMgaW5pdGlhbGl6ZWQuCj4gPiBUaGUgaXNzdWUg aXMgb3B0ZWUgZHJpdmVyIGluaXRpYWxpemVzIGl0cyB0ZWUgYnVzIGF0IHN1YnN5c19pbml0Y2Fs bAo+ID4gbGV2ZWwsIHNhbWUgbGV2ZWwgYXMgdGhlIHNjbWkgZHJpdmVyLgo+ID4gU28gSSBoYWQg dG8gY2FsbCBzY21pX29wdGVlX2luaXQoKSBhdCBhbiBlYXJsaWVyIGluaXQgbGV2ZWw6IGRldmlj ZV9pbml0Y2FsbCgpLgo+ID4KPiA+IFZpcnRpbyBidXMgaXMgcmVnaXN0ZXJlZCBhdCBjb3JlX2lu aXRjYWxsIGxldmVsIGhlbmNlIHNjbWkvdmlydGlvIGluaXQKPiA+IGEgc3Vic3lzX2luaXRjYWxs IGhhcyB0aGUgZGVwZW5kZW5jeSByZXNvbHZlZC4KPiAKPiBJIGhhdmUgYSBwcm9wb3NhbCB0byBh ZGRyZXNzIHRoaXMuCj4gCj4gWW91IHN1Z2dlc3RlZCB0byB1c2UgOjp0cmFuc3BvcnRfaW5pdCBv cGVyYXRvciBmcm9tIHN0cnVjdCBzY21pX2Rlc2MKPiBmb3IgdGhpcyByZWdpc3RyYXRpb24gdG8g dGhlIG9wdGVlIGJ1cy4KPiBGb3IgdGhlIHJlYXNvbiBhYm92ZSwgaXQgZG9lcyBub3QgYXBwbHkg dG8gT1AtVEVFLgo+IE15IGlkZWEgaXMgdG8gbm90IHVlIDo6dHJhbnNwb3J0X2luaXQgaG9vayBi dXQgdG8gcmVnaXN0ZXIgZnJvbQo+IDo6bGlua19zdXBwbGllciBob29rIGZyb20gc3RydWN0IHNj bWlfdHJhbnNwb3J0X29wcy4KPiBUaGUgZmlyc3QgdGltZSBhIHNjbWlfb3B0ZWUgY2hhbm5lbCB0 byByZXF1ZXN0ZWQsIGl0IHdpbGwgYmUgZGVmZXJyZWQKPiBhbmQgc2NtaV9vcHRlZSByZWdpc3Rl cmluZyB0byBvcHRlZSBidXMgZG9uZS4KPiBTb21ldGhpbmcgbGlrZSB0aGUgYmVsb3c6Cj4gCj4g ICBzdGF0aWMgaW50IHNjbWlfb3B0ZWVfbGlua19zdXBwbGllcihzdHJ1Y3QgZGV2aWNlICpkZXYp Cj4gICB7Cj4gICAgICAgaWYgKCFzY21pX29wdGVlX3ByaXZhdGUpIHsKPiAgICAgICAgICAgc3Rh dGljIGludCByZWdpc3Rlcl90b19vcHRlZSA9IC1FTk9ERVY7Cj4gCj4gICAgICAgICAgIC8vIHJl Z2lzdGVyIHRvIG9wdGVlIGJ1cyBlbnVtZXJhdGlvbiBpZiBub3QgYWxyZWFkeSBzdWNjZXNzZnVs bHkgZG9uZQo+ICAgICAgICAgICBpZiAocmVnaXN0ZXJfdG9fb3B0ZWUpCj4gICAgICAgICAgICAg ICByZWdpc3Rlcl90b19vcHRlZSA9IGRyaXZlcl9yZWdpc3Rlcigmc2NtaV9vcHRlZV9kcml2ZXIu ZHJpdmVyKTsKPiAKPiAgICAgICAgICAgLy8gZGVmZXIgY2hhbm5lbCBzZXR1cCB1bnRpbAo+ICAg ICAgICAgICByZXR1cm4gLUVQUk9CRV9ERUZFUjsKPiAgICAgICB9Cj4gCj4gICAgICAgaWYgKCFk ZXZpY2VfbGlua19hZGQoZGV2LCBzY21pX29wdGVlX3ByaXZhdGUtPmRldiwKPiBETF9GTEFHX0FV VE9SRU1PVkVfQ09OU1VNRVIpKSB7Cj4gICAgICAgICAgIGRldl9lcnIoZGV2LCAiQWRkaW5nIGxp bmsgdG8gc3VwcGxpZXIgb3B0ZWUgZGV2aWNlIGZhaWxlZFxuIik7Cj4gICAgICAgICAgIHJldHVy biAtRUNBTkNFTEVEOwo+ICAgICAgIH0KPiAKPiAgICAgICByZXR1cm4gMDsKPiAgIH0KClNvIHdo ZW4geW91IHJhaXNlZCB0aGlzIHBvaW50IGluIHRoZSBwcmV2aW91cyBtYWlsIG15IGluaXRpYWwg dGhvdWdodCB3YXMKdGhhdCwgdW5sZXNzIHdlIGhhZCBmb3VuZCBhIGdvb2Qgd29ya2Fyb3VuZCwg SSBzaG91bGQgaGF2ZSBzdGFydGVkCndvcmtpbmcgb24gc29tZXRoaW5nIEkgaGF2ZSBpbiBteSBi YWNrbG9nIGZvciBsb25nLCB3aGljaCBpcyBzdXBwb3NlZCB0bwpoYW5kbGUgdGhlc2Ugc2NlbmFy aW9zIGJldHRlcjogaS5lLiBtYWtpbmcgYWxsL29yLXNvbWUgU0NNSSB0cmFuc3BvcnQgYXMKZnVs bCBmbGVkZ2VkIGRyaXZlcnMgaW5zdGVhZCBvZiBrZWVwaW5nIHRoZW0gZW1iZWRkZWQgaW50byB0 aGUgY29yZS4KKG5vdCBkb25lIHRpbGwgbm93IHNpbmNlIG5vdCBuZWVkZWQgYW5kIHJlYWxseSBk aWQgbm90IHdhbnQgdG8gY2hhbmdlCmFsc28gdGhhdCB3aGlsZSBpbnRlZ3JhdGluZyB2aXJ0aW8p CgpJIGhhdmUgbm90IHN0YXJ0ZWQgcmVhbGx5IHdvcmtpbmcgb24gdGhpcyBub3IgdGhvdWdodCBp dCB0aHJvdWdoCnByb3Blcmx5LCBidXQgaGF2aW5nIGEgd2F5IHRvIGRlZmluZSBhIGZ1bGwgZmxl ZGdlZCBTQ01JIHRyYW5zcG9ydCBkcml2ZXIKdGhhdCByZWdpc3RlcnMgd2l0aCBzb21lIGV4dGVy bmFsIHN1YnN5cyAob3B0ZWUvdmlydGlvLi4uKSBhbmQgdGhlbgpyZWdpc3RlcnMgaXRzZWxmIHdp dGggdGhlIFNDTUkgY29yZSBpdHNlbGYgYXMgYW4gYXZhaWxhYmxlIHRyYW5zcG9ydCAod2l0aAp0 aGUgY29yZSBERUZFUmluZyB0aWxsIHRoZSB0cmFuc3BvcnQgbGF5ZXIgaGFzIGFwcGVhcmVkKSwg c2VlbWVkIHRvIG1lIHRoZQp3YXkgdG8gZ28gdG8gc29sdmUgdGhpcyBraW5kIG9mIGlzc3VlcyBt b3JlIGdlbmVyYWxseS4KCkhhdmluZyBzYWlkIHRoYXQsIHlvdXIgcHJvcG9zYWwgc2VlbXMgdGhl IGtpbmQgb2Ygd29ya2Fyb3VuZCB0aGF0IGNvdWxkCnNvbHZlIGZpbmUgeW91ciBpc3N1ZSBub3cg c2ltcGx5IHVzaW5nIHdoYXQgaXMgYWxyZWFkeSBpbiB0aGUgU0NNSSBjb3JlLgoKU28gSSBoYXZl IG5vdGhpbmcgYWdhaW5zdCBpdCBhcyBhbiBpbW1lZGlhdGUgc29sdXRpb24gKEknbGwgZG91Ymxl CmNoZWNrIHdpdGggU3VkZWVwIGFueXdheSA6RCksIGJ1dCBJIHdvbmRlciBpZiBpbiB0aGUgbG9u ZyB0ZXJtIHRoZQpmdWxsLWZsZWRnZWQgdHJhbnNwb3J0IGRyaXZlciBhcHByb2FjaCB3b3VsZCBz dGlsbCBtYWtlIHNlbnNlLgoKPiAKPiBOb3RlIHRoZSBleGl0IHNlcXVlbmNlIGNhbiBzdGlsbCB1 c2Ugc3RydWN0IHNjbWlfZGVzYzo6dHJhbnNwb3J0X2V4dCBob29rOgo+IAo+ICAgc3RhdGljIHZv aWQgc2NtaV9vcHRlZV9leGl0KHZvaWQpCj4gICB7Cj4gICAgICAgZHJpdmVyX3VucmVnaXN0ZXIo JnNjbWlfb3B0ZWVfZHJpdmVyLmRyaXZlcik7Cj4gICB9Cj4gICBtb2R1bGVfZXhpdChzY21pX29w dGVlX2V4aXQpOwo+IAoKSGVyZSB5b3UgbWVhbiB3aXRob3V0IHRoZSBtb2R1bGVfZXhpdCByaWdo dCA/CgpTbyB0aGUgaW5pdCB3b3VsZCBiZSBpbiBjaGFyZ2Ugb2YgLmxpbmtfc3VwcGxpZXIgYW5k IGl0cyBkZWZlcnJhbAptZWNoYW5pc20gYnV0IHRoZSB1bnJlZ2lzdGVyIHdvdWRsZCBnbyB2aWEK LnRyYW5zcG9ydF9leGl0ID0gc2NtaV9vcHRlZV9leGl0KCkgYnkgdGhlIGNvcmUgb24gU0NNSSBj b3JlIHVubG9hZC4KCkkgd291bGQgcmVjb21tZW5kIHBsYWNpbmcgYSBjaGVjayBvbiAncmVnaXN0 ZXJfdG9fb3B0ZWUnIGFsc28gaGVyZSBvbiBleGl0CnNvIHRoYXQgdGhlIFNDTUkgY29yZSBvbiBp dHMgdW5sb2FkIHdvbid0IHRyeSB0byBkZXJlZ2lzdGVyIGEgZHJpdmVyIHdoaWNoCndhcyBuZXZl ciBzdWNjZXNzZnVsbHkgcmVnaXN0ZXJlZC4KCj4gTWF5IEkgZ2V0IHlvdXIgb3Bpbmlvbj8KPiAK Ckkgd3JvdGUgd2F5IHRvbyBtdWNoIC4uLiBzb3JyeS4KClRoYW5rcywKQ3Jpc3RpYW4KCgpfX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpsaW51eC1hcm0ta2Vy bmVsIG1haWxpbmcgbGlzdApsaW51eC1hcm0ta2VybmVsQGxpc3RzLmluZnJhZGVhZC5vcmcKaHR0 cDovL2xpc3RzLmluZnJhZGVhZC5vcmcvbWFpbG1hbi9saXN0aW5mby9saW51eC1hcm0ta2VybmVs Cg==