From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DEB7E4A3843 for ; Wed, 2 Sep 2026 14:24:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788359071; cv=none; b=XTtCWL13mevAvWcwmwE8xJ/4d3se0rjF+8z2FWDOgwNV+TFatbwILeuDa7YugGSHhbGitknp9XKZ6MfccD/vvfsvTG7fs9GOZKL8BnmWfpdbow9KfTLp1Cwkxi7HiYkLck1/eE5eZo0oTZYoazr2hJ3s3/aSuWp7uyAIYM4+d2w= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788359071; c=relaxed/simple; bh=g4y1dz6cy86SQQvkvMMRWFtslcd5Keg5vCQhDkhFffo=; h=From:Subject:To:Cc:In-Reply-To:References:Content-Type:Date: Message-Id; b=Egq3nkGgn6U3MQIlES/eRhnT3vwli8qy0tNih79Hch5SrN70sJ6HqQTkiKLYtyPL8oxS0s5lnjh/FeMowMgYZr9qNls1lOkvSnrcl5XTqzZ2vzoG6gJ3Rs2/Va1ztH2OHzAcK2jZjUAchND6aBjLr9xVBZlVIbsRKaH4XVb4w2M= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=LsVMR1jN; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="LsVMR1jN" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 543CB1F000E9; Wed, 2 Sep 2026 14:24:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788359069; bh=i2+dIzpSFaCz+LgLzdaac9dB+sniaTlOkA964JKf8Vg=; h=From:Subject:Reply-To:To:Cc:In-Reply-To:References:Date; b=LsVMR1jNVMb7AG4AbVTOgVdTTTaH8wzah0/IZ8taxHPEMTEeqvTpILP80rm0euNgN MBdfXE7gYscRp8uKArnBcDQA3e7OFr+XdVPMoyfIjT/9/tuD2XLTzCreZOsZIzTDtn EkXAUcfrkaMBpy7B6nE+lLXqm04KxCjvjG97RqnhQ3G+TmtmzrFnulZEfj34k5mMx4 nV4Jk78KCN72yr3NJfmaMp1rXUnUQcgb73dbOxohuh107HfYcXDokXDFWqU5FzjHZq V+3Vgsavtk8xmV0L9eQhZ0G3ZenpFnTIQdE5UIHpf/53Z/A0xy3DELkYUDlLu0C6as HTMAFWLexFhVA== From: sashiko-bot@kernel.org Subject: Re: [PATCH v5 2/2] phy: stm32: Add support for ST STM32MP25 USB2-FEMTO PHY Reply-To: sashiko-reviews@lists.linux.dev To: "Marek Vasut" Cc: olteanv@gmail.com, neil.armstrong@linaro.org, robh@kernel.org, vkoul@kernel.org, conor+dt@kernel.org, devicetree@vger.kernel.org, linux-phy@lists.infradead.org In-Reply-To: <20260902141312.649406-2-marex@nabladev.com> References: <20260902141312.649406-1-marex@nabladev.com> <20260902141312.649406-2-marex@nabladev.com> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Date: Wed, 02 Sep 2026 14:24:28 +0000 Message-Id: <20260902142429.543CB1F000E9@smtp.kernel.org> Precedence: bulk X-Mailing-List: devicetree@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Thank you for your contribution! Sashiko AI review found 11 potential issue= (s) to consider: - [High] Lockless atomic counter allows concurrent callers to access uninit= ialized hardware. - [High] Missing decrement of `en_refcnt` on error paths permanently bricks= hardware initialization. - [High] Inconsistent PM suspend/resume logic fails to power down hardware = if the clock provider is actively used. - [High] Logical conflict between Clock Framework and PHY set_mode over the= CMN register bit causes state desynchronization. - [High] Incorrect parsing of `reg` property using `of_get_address()` poten= tially corrupts syscon register 0 on 64-bit platforms. - [Medium] Failure to assert reset in `stm32_usb2phy_disable` leaves clock = and regulator permanently enabled. - [Medium] Driver strictly fails probe if the ostensibly 'optional' vdd33 r= egulator is missing, breaking the `_optional` contract. - [Medium] Inconsistent masking in `stm32_usb2phy_set_mode` prevents cleari= ng `VBUSVLDEXTSEL` on transition to HOST mode. - [Medium] Blind dereferences of `dev->of_node` and `device_get_match_data(= )` will crash if bound manually. - [Low] Build failure due to passing a non-constant mask to `field_prep()`. - [Low] Commit message contradicts code regarding PHY2 set_mode support. -- commit 291cd4f88294f76f9e6908ba105bb434b48f3830 Author: Pankaj Dev phy: stm32: Add support for ST STM32MP25 USB2-FEMTO PHY This commit adds a USB2 PHY driver for STM32MP25 USB2 controllers. It supports two slightly different PHYs on the SoC, each requiring a different compatible string. The driver handles initialization, clocks, resets, and regulators for these PHYs. > V3: - Update copyright years > - Register two sets of clock, one 480 MHz PLL and one CMN > - Split PHY ops per PHY, since the PHY2 does not have set mode ops [Severity: Low] This isn't a bug, but does PHY2 actually support set mode ops? The commit message indicates PHY2 does not have set mode ops, but they are assigned in the code for stm32_usb2phy2_data. > diff --git a/drivers/phy/st/phy-stm32-usb2phy.c b/drivers/phy/st/phy-stm3= 2-usb2phy.c > index 0000000000000..e173557a3cb59 > --- /dev/null > +++ b/drivers/phy/st/phy-stm32-usb2phy.c [ ... ] > +static int stm32_usb2phy_enable(struct stm32_usb2phy *phy_dev) > +{ > + const struct stm32mp2_usb2phy_hw_data *phy_data =3D phy_dev->hw_data; > + unsigned int refsel; > + unsigned long rate; > + int ret; > + > + /* Check if a phy is already init or clkpll in use */ > + if (atomic_inc_return(&phy_dev->en_refcnt) > 1) > + return 0; [Severity: High] Does this lockless early return allow a concurrent caller to proceed with hardware access while initialization is still in flight? If the PHY and Clock frameworks concurrently invoke stm32_usb2phy_enable(), such as phy_init() from one driver and clk_prepare() from another, could thread A increment the counter to 1 and begin enabling regulators, while thread B increments to 2 and returns success immediately, using the uninitialized hardware? > + > + rate =3D clk_get_rate(phy_dev->phyref); > + if (rate =3D=3D 19200000) > + refsel =3D 0; > + else if (rate =3D=3D 20000000) > + refsel =3D 1; > + else if (rate =3D=3D 24000000) > + refsel =3D 2; > + else > + return -EINVAL; [Severity: High] Is it possible this error path permanently bricks hardware initialization? By returning an error without decrementing the en_refcnt, the reference cou= nt becomes artificially elevated. Subsequent initialization attempts might byp= ass initialization entirely while the hardware remains broken. > + > + ret =3D regmap_update_bits(phy_dev->regmap, > + phy_dev->cr_offset, > + phy_data->phyrefsel_mask, > + field_prep(phy_data->phyrefsel_mask, refsel)); [Severity: Low] Will this cause a build failure?=20 field_prep() strictly requires a compile-time constant mask, but phy_data->phyrefsel_mask is resolved at runtime via a pointer dereference. > + if (ret) > + return ret; [Severity: High] Could this error return leave the en_refcnt artificially elevated, preventi= ng subsequent initialization attempts from ever succeeding? > + > + ret =3D regulator_enable(phy_dev->vdd33); > + if (ret) > + return ret; > + > + ret =3D clk_prepare_enable(phy_dev->phyref); > + if (ret) > + goto error_regdis; > + > + ret =3D reset_control_deassert(phy_dev->rstc); > + if (ret) > + goto error_clkdis; > + > + return 0; > + > +error_clkdis: > + clk_disable_unprepare(phy_dev->phyref); > +error_regdis: > + regulator_disable(phy_dev->vdd33); > + > + return ret; [Severity: High] Does this final cleanup error path also leave the en_refcnt incremented? > +} > + > +static int stm32_usb2phy_disable(struct stm32_usb2phy *phy_dev) > +{ > + int ret; > + > + /* Check if a phy is still init or clkpll in use */ > + if (atomic_dec_return(&phy_dev->en_refcnt) > 0) > + return 0; [Severity: High] Does this lockless early return also allow teardown races? > + > + ret =3D reset_control_assert(phy_dev->rstc); > + if (ret) > + return ret; [Severity: Medium] Will failing to assert the reset here leak the clock and regulator resource= s, leaving them permanently enabled? > + > + clk_disable_unprepare(phy_dev->phyref); > + > + return regulator_disable(phy_dev->vdd33); > +} > + > +static int stm32_usb2phy_set_mode(struct phy *phy, enum phy_mode mode, i= nt submode) > +{ > + struct stm32_usb2phy *phy_dev =3D phy_get_drvdata(phy); > + u32 mask =3D SYSCFG_USB2PHY2CR_USB2PHY2CMN | > + SYSCFG_USB2PHY2CR_VBUSVALID | > + SYSCFG_USB2PHY2CR_VBUSVLDEXT; > + u32 val =3D 0; > + int ret; > + > + if (mode =3D=3D PHY_MODE_USB_HOST) { > + if (submode !=3D USB_ROLE_NONE) > + val =3D SYSCFG_USB2PHY2CR_VBUSVALID; > + } else if (mode =3D=3D PHY_MODE_USB_DEVICE) { > + val =3D SYSCFG_USB2PHY2CR_USB2PHY2CMN | > + SYSCFG_USB2PHY2CR_VBUSVLDEXTSEL; [Severity: High] Is there a logical conflict over the SYSCFG_USB2PHY2CR_USB2PHY2CMN bit? The Clock Framework's internal state could become desynchronized if stm32_usb2phy_clkcmn_prepare() clears this bit, but stm32_usb2phy_set_mode() is concurrently called to switch to DEVICE mode and directly sets this exact same bit via regmap_update_bits(). > + if (submode !=3D USB_ROLE_NONE) > + val |=3D SYSCFG_USB2PHY2CR_VBUSVLDEXT; > + mask |=3D SYSCFG_USB2PHY2CR_VBUSVLDEXTSEL; [Severity: Medium] Does adding the VBUSVLDEXTSEL bit to the mask dynamically here instead of in the base mask prevent clearing it on subsequent transitions to HOST mode? If it is omitted from the mask during a transition to PHY_MODE_USB_HOST, regmap_update_bits() won't be able to clear it. > + } else { > + return -EINVAL; > + } [ ... ] > +static int stm32_usb2phy_probe(struct platform_device *pdev) > +{ > + struct phy_provider *phy_provider; > + struct device *dev =3D &pdev->dev; > + struct stm32_usb2phy *phy_dev; > + char *pllname, *cmnname; > + const __be32 *offset; > + struct phy *phy; > + int ret; [ ... ] > + phy_dev->phyref =3D devm_clk_get(dev, NULL); > + if (IS_ERR(phy_dev->phyref)) > + return dev_err_probe(dev, PTR_ERR(phy_dev->phyref), "Failed to get phy= ref clk\n"); > + > + phy_dev->vdd33 =3D devm_regulator_get_optional(dev, "vdd33"); > + if (IS_ERR(phy_dev->vdd33)) > + return dev_err_probe(dev, PTR_ERR(phy_dev->vdd33), "Failed to get vdd3= v3 supply\n"); [Severity: Medium] Since this propagates -ENODEV when the regulator is absent in the DT, does this strictly fail probe for platforms legitimately lacking the optional vdd33 regulator, breaking the _optional contract? > + > + phy_dev->regmap =3D syscon_node_to_regmap(dev->of_node->parent); [Severity: Medium] Will this unconditionally dereference dev->of_node?=20 If the device is instantiated manually, such as via sysfs bind without a backing Device Tree node, dev->of_node will be NULL, leading to a kernel panic. > + if (IS_ERR(phy_dev->regmap)) > + return dev_err_probe(dev, PTR_ERR(phy_dev->regmap), "Failed to get reg= map\n"); > + > + offset =3D of_get_address(dev->of_node, 0, NULL, NULL); > + if (!offset) > + return dev_err_probe(dev, -EINVAL, "Failed to get regmap offset\n"); > + > + phy_dev->cr_offset =3D be32_to_cpu(*offset); [Severity: High] Does this logic incorrectly parse the reg property on 64-bit platforms? If the parent node uses 2 address cells, which is common on STM32MP25, *offset contains the high 32 bits of the address, which is typically 0. This could cause the driver to incorrectly extract 0 and overwrite syscon register 0 instead of the intended PHY control register. > + > + phy_dev->hw_data =3D device_get_match_data(dev); > + > + phy =3D devm_phy_create(dev, NULL, phy_dev->hw_data->phy_ops); [Severity: Medium] Could this unconditionally dereference phy_dev->hw_data if device_get_match_data(dev) returns NULL when the device is bound manually? > + if (IS_ERR(phy)) > + return dev_err_probe(dev, PTR_ERR(phy), "Failed to create PHY\n"); [ ... ] > +static int stm32_usb2phy_suspend(struct device *dev) > +{ > + struct stm32_usb2phy *phy_dev =3D dev_get_drvdata(dev); > + > + if (phy_dev->is_init) > + return stm32_usb2phy_disable(phy_dev); [Severity: High] Does this conditional logic incorrectly assume is_init and disable() correctly account for all framework consumers? If the hardware was enabled via the Clock API, en_refcnt is 1 but is_init is false, so suspend does nothing. If enabled via both, calling stm32_usb2phy_disable() merely decrements en_refcnt to 1 and returns early without powering off the hardware. Could this fail to shut down the hardware if the CCF clock is in use? > + > + return 0; > +} --=20 Sashiko AI review =C2=B7 https://sashiko.dev/#/patchset/20260902141312.6494= 06-1-marex@nabladev.com?part=3D2 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 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 1E04EC624D6 for ; Wed, 2 Sep 2026 14:24:32 +0000 (UTC) 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:MIME-Version:Reply-To:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:Message-Id:Date: References:In-Reply-To:Cc:To:Subject:From:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=hISYzf5XVs8EXDOIaVRU1/WbpTVxQPiOaQRrzS+bruk=; b=I9WKaeJLabIfEa 9Viiekr3/QvyTatgzS6xKRCuthDIoFRWyPGj+f5EXuX2uG2m8fHDqgcLH36uBLXfIBqF6EQeX+IeJ rzLop6CC2U4z1qVObU6NWHHI0YD6QRVoUhlZXmZBaQXCnG/7Q5CHplVD2jBMl5OiRG1+6iFmR//yd 6l9TK2gVxTsnWxS1OgLkG4hqrkLOWu9Dn8qA2EE8gf2T0D1KOZa3ghKSxgVU8V8YJop7ZXQey1JmP E6n8WTl8Y3Hcwb1IhYXobqRU0+qp+a+N6uTdI6+SktGg/Cd2x1dno2UDmOWpV+OYQMe+WRgKdOsTW m61KmoXi7x1tkGx37YAg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1x1lt9-0000000Ew2Q-2oK3; Wed, 02 Sep 2026 14:24:31 +0000 Received: from tor.source.kernel.org ([172.105.4.254]) by bombadil.infradead.org with esmtps (Exim 4.99.1 #2 (Red Hat Linux)) id 1x1lt8-0000000Ew2B-49R4 for linux-phy@lists.infradead.org; Wed, 02 Sep 2026 14:24:31 +0000 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by tor.source.kernel.org (Postfix) with ESMTP id 0BD9F602C2; Wed, 2 Sep 2026 14:24:30 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 543CB1F000E9; Wed, 2 Sep 2026 14:24:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788359069; bh=i2+dIzpSFaCz+LgLzdaac9dB+sniaTlOkA964JKf8Vg=; h=From:Subject:Reply-To:To:Cc:In-Reply-To:References:Date; b=LsVMR1jNVMb7AG4AbVTOgVdTTTaH8wzah0/IZ8taxHPEMTEeqvTpILP80rm0euNgN MBdfXE7gYscRp8uKArnBcDQA3e7OFr+XdVPMoyfIjT/9/tuD2XLTzCreZOsZIzTDtn EkXAUcfrkaMBpy7B6nE+lLXqm04KxCjvjG97RqnhQ3G+TmtmzrFnulZEfj34k5mMx4 nV4Jk78KCN72yr3NJfmaMp1rXUnUQcgb73dbOxohuh107HfYcXDokXDFWqU5FzjHZq V+3Vgsavtk8xmV0L9eQhZ0G3ZenpFnTIQdE5UIHpf/53Z/A0xy3DELkYUDlLu0C6as HTMAFWLexFhVA== From: sashiko-bot@kernel.org Subject: Re: [PATCH v5 2/2] phy: stm32: Add support for ST STM32MP25 USB2-FEMTO PHY To: "Marek Vasut" Cc: olteanv@gmail.com, neil.armstrong@linaro.org, robh@kernel.org, vkoul@kernel.org, conor+dt@kernel.org, devicetree@vger.kernel.org, linux-phy@lists.infradead.org In-Reply-To: <20260902141312.649406-2-marex@nabladev.com> References: <20260902141312.649406-1-marex@nabladev.com> <20260902141312.649406-2-marex@nabladev.com> Date: Wed, 02 Sep 2026 14:24:28 +0000 Message-Id: <20260902142429.543CB1F000E9@smtp.kernel.org> X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: sashiko-reviews@lists.linux.dev MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org VGhhbmsgeW91IGZvciB5b3VyIGNvbnRyaWJ1dGlvbiEgU2FzaGlrbyBBSSByZXZpZXcgZm91bmQg MTEgcG90ZW50aWFsIGlzc3VlKHMpIHRvIGNvbnNpZGVyOgotIFtIaWdoXSBMb2NrbGVzcyBhdG9t aWMgY291bnRlciBhbGxvd3MgY29uY3VycmVudCBjYWxsZXJzIHRvIGFjY2VzcyB1bmluaXRpYWxp emVkIGhhcmR3YXJlLgotIFtIaWdoXSBNaXNzaW5nIGRlY3JlbWVudCBvZiBgZW5fcmVmY250YCBv biBlcnJvciBwYXRocyBwZXJtYW5lbnRseSBicmlja3MgaGFyZHdhcmUgaW5pdGlhbGl6YXRpb24u Ci0gW0hpZ2hdIEluY29uc2lzdGVudCBQTSBzdXNwZW5kL3Jlc3VtZSBsb2dpYyBmYWlscyB0byBw b3dlciBkb3duIGhhcmR3YXJlIGlmIHRoZSBjbG9jayBwcm92aWRlciBpcyBhY3RpdmVseSB1c2Vk LgotIFtIaWdoXSBMb2dpY2FsIGNvbmZsaWN0IGJldHdlZW4gQ2xvY2sgRnJhbWV3b3JrIGFuZCBQ SFkgc2V0X21vZGUgb3ZlciB0aGUgQ01OIHJlZ2lzdGVyIGJpdCBjYXVzZXMgc3RhdGUgZGVzeW5j aHJvbml6YXRpb24uCi0gW0hpZ2hdIEluY29ycmVjdCBwYXJzaW5nIG9mIGByZWdgIHByb3BlcnR5 IHVzaW5nIGBvZl9nZXRfYWRkcmVzcygpYCBwb3RlbnRpYWxseSBjb3JydXB0cyBzeXNjb24gcmVn aXN0ZXIgMCBvbiA2NC1iaXQgcGxhdGZvcm1zLgotIFtNZWRpdW1dIEZhaWx1cmUgdG8gYXNzZXJ0 IHJlc2V0IGluIGBzdG0zMl91c2IycGh5X2Rpc2FibGVgIGxlYXZlcyBjbG9jayBhbmQgcmVndWxh dG9yIHBlcm1hbmVudGx5IGVuYWJsZWQuCi0gW01lZGl1bV0gRHJpdmVyIHN0cmljdGx5IGZhaWxz IHByb2JlIGlmIHRoZSBvc3RlbnNpYmx5ICdvcHRpb25hbCcgdmRkMzMgcmVndWxhdG9yIGlzIG1p c3NpbmcsIGJyZWFraW5nIHRoZSBgX29wdGlvbmFsYCBjb250cmFjdC4KLSBbTWVkaXVtXSBJbmNv bnNpc3RlbnQgbWFza2luZyBpbiBgc3RtMzJfdXNiMnBoeV9zZXRfbW9kZWAgcHJldmVudHMgY2xl YXJpbmcgYFZCVVNWTERFWFRTRUxgIG9uIHRyYW5zaXRpb24gdG8gSE9TVCBtb2RlLgotIFtNZWRp dW1dIEJsaW5kIGRlcmVmZXJlbmNlcyBvZiBgZGV2LT5vZl9ub2RlYCBhbmQgYGRldmljZV9nZXRf bWF0Y2hfZGF0YSgpYCB3aWxsIGNyYXNoIGlmIGJvdW5kIG1hbnVhbGx5LgotIFtMb3ddIEJ1aWxk IGZhaWx1cmUgZHVlIHRvIHBhc3NpbmcgYSBub24tY29uc3RhbnQgbWFzayB0byBgZmllbGRfcHJl cCgpYC4KLSBbTG93XSBDb21taXQgbWVzc2FnZSBjb250cmFkaWN0cyBjb2RlIHJlZ2FyZGluZyBQ SFkyIHNldF9tb2RlIHN1cHBvcnQuCi0tCgpjb21taXQgMjkxY2Q0Zjg4Mjk0Zjc2ZjllNjkwOGJh MTA1YmI0MzRiNDhmMzgzMApBdXRob3I6IFBhbmthaiBEZXYgPHBhbmthai5kZXZAc3QuY29tPgoK cGh5OiBzdG0zMjogQWRkIHN1cHBvcnQgZm9yIFNUIFNUTTMyTVAyNSBVU0IyLUZFTVRPIFBIWQoK VGhpcyBjb21taXQgYWRkcyBhIFVTQjIgUEhZIGRyaXZlciBmb3IgU1RNMzJNUDI1IFVTQjIgY29u dHJvbGxlcnMuIEl0CnN1cHBvcnRzIHR3byBzbGlnaHRseSBkaWZmZXJlbnQgUEhZcyBvbiB0aGUg U29DLCBlYWNoIHJlcXVpcmluZyBhCmRpZmZlcmVudCBjb21wYXRpYmxlIHN0cmluZy4gVGhlIGRy aXZlciBoYW5kbGVzIGluaXRpYWxpemF0aW9uLCBjbG9ja3MsCnJlc2V0cywgYW5kIHJlZ3VsYXRv cnMgZm9yIHRoZXNlIFBIWXMuCgo+IFYzOiAtIFVwZGF0ZSBjb3B5cmlnaHQgeWVhcnMKPiAgICAg LSBSZWdpc3RlciB0d28gc2V0cyBvZiBjbG9jaywgb25lIDQ4MCBNSHogUExMIGFuZCBvbmUgQ01O Cj4gICAgIC0gU3BsaXQgUEhZIG9wcyBwZXIgUEhZLCBzaW5jZSB0aGUgUEhZMiBkb2VzIG5vdCBo YXZlIHNldCBtb2RlIG9wcwoKW1NldmVyaXR5OiBMb3ddClRoaXMgaXNuJ3QgYSBidWcsIGJ1dCBk b2VzIFBIWTIgYWN0dWFsbHkgc3VwcG9ydCBzZXQgbW9kZSBvcHM/ClRoZSBjb21taXQgbWVzc2Fn ZSBpbmRpY2F0ZXMgUEhZMiBkb2VzIG5vdCBoYXZlIHNldCBtb2RlIG9wcywgYnV0IHRoZXkgYXJl CmFzc2lnbmVkIGluIHRoZSBjb2RlIGZvciBzdG0zMl91c2IycGh5Ml9kYXRhLgoKPiBkaWZmIC0t Z2l0IGEvZHJpdmVycy9waHkvc3QvcGh5LXN0bTMyLXVzYjJwaHkuYyBiL2RyaXZlcnMvcGh5L3N0 L3BoeS1zdG0zMi11c2IycGh5LmMKPiBpbmRleCAwMDAwMDAwMDAwMDAwLi5lMTczNTU3YTNjYjU5 Cj4gLS0tIC9kZXYvbnVsbAo+ICsrKyBiL2RyaXZlcnMvcGh5L3N0L3BoeS1zdG0zMi11c2IycGh5 LmMKClsgLi4uIF0KCj4gK3N0YXRpYyBpbnQgc3RtMzJfdXNiMnBoeV9lbmFibGUoc3RydWN0IHN0 bTMyX3VzYjJwaHkgKnBoeV9kZXYpCj4gK3sKPiArCWNvbnN0IHN0cnVjdCBzdG0zMm1wMl91c2Iy cGh5X2h3X2RhdGEgKnBoeV9kYXRhID0gcGh5X2Rldi0+aHdfZGF0YTsKPiArCXVuc2lnbmVkIGlu dCByZWZzZWw7Cj4gKwl1bnNpZ25lZCBsb25nIHJhdGU7Cj4gKwlpbnQgcmV0Owo+ICsKPiArCS8q IENoZWNrIGlmIGEgcGh5IGlzIGFscmVhZHkgaW5pdCBvciBjbGtwbGwgaW4gdXNlICovCj4gKwlp ZiAoYXRvbWljX2luY19yZXR1cm4oJnBoeV9kZXYtPmVuX3JlZmNudCkgPiAxKQo+ICsJCXJldHVy biAwOwoKW1NldmVyaXR5OiBIaWdoXQpEb2VzIHRoaXMgbG9ja2xlc3MgZWFybHkgcmV0dXJuIGFs bG93IGEgY29uY3VycmVudCBjYWxsZXIgdG8gcHJvY2VlZCB3aXRoCmhhcmR3YXJlIGFjY2VzcyB3 aGlsZSBpbml0aWFsaXphdGlvbiBpcyBzdGlsbCBpbiBmbGlnaHQ/CgpJZiB0aGUgUEhZIGFuZCBD bG9jayBmcmFtZXdvcmtzIGNvbmN1cnJlbnRseSBpbnZva2Ugc3RtMzJfdXNiMnBoeV9lbmFibGUo KSwKc3VjaCBhcyBwaHlfaW5pdCgpIGZyb20gb25lIGRyaXZlciBhbmQgY2xrX3ByZXBhcmUoKSBm cm9tIGFub3RoZXIsIGNvdWxkCnRocmVhZCBBIGluY3JlbWVudCB0aGUgY291bnRlciB0byAxIGFu ZCBiZWdpbiBlbmFibGluZyByZWd1bGF0b3JzLCB3aGlsZQp0aHJlYWQgQiBpbmNyZW1lbnRzIHRv IDIgYW5kIHJldHVybnMgc3VjY2VzcyBpbW1lZGlhdGVseSwgdXNpbmcgdGhlCnVuaW5pdGlhbGl6 ZWQgaGFyZHdhcmU/Cgo+ICsKPiArCXJhdGUgPSBjbGtfZ2V0X3JhdGUocGh5X2Rldi0+cGh5cmVm KTsKPiArCWlmIChyYXRlID09IDE5MjAwMDAwKQo+ICsJCXJlZnNlbCA9IDA7Cj4gKwllbHNlIGlm IChyYXRlID09IDIwMDAwMDAwKQo+ICsJCXJlZnNlbCA9IDE7Cj4gKwllbHNlIGlmIChyYXRlID09 IDI0MDAwMDAwKQo+ICsJCXJlZnNlbCA9IDI7Cj4gKwllbHNlCj4gKwkJcmV0dXJuIC1FSU5WQUw7 CgpbU2V2ZXJpdHk6IEhpZ2hdCklzIGl0IHBvc3NpYmxlIHRoaXMgZXJyb3IgcGF0aCBwZXJtYW5l bnRseSBicmlja3MgaGFyZHdhcmUgaW5pdGlhbGl6YXRpb24/CgpCeSByZXR1cm5pbmcgYW4gZXJy b3Igd2l0aG91dCBkZWNyZW1lbnRpbmcgdGhlIGVuX3JlZmNudCwgdGhlIHJlZmVyZW5jZSBjb3Vu dApiZWNvbWVzIGFydGlmaWNpYWxseSBlbGV2YXRlZC4gU3Vic2VxdWVudCBpbml0aWFsaXphdGlv biBhdHRlbXB0cyBtaWdodCBieXBhc3MKaW5pdGlhbGl6YXRpb24gZW50aXJlbHkgd2hpbGUgdGhl IGhhcmR3YXJlIHJlbWFpbnMgYnJva2VuLgoKPiArCj4gKwlyZXQgPSByZWdtYXBfdXBkYXRlX2Jp dHMocGh5X2Rldi0+cmVnbWFwLAo+ICsJCQkJIHBoeV9kZXYtPmNyX29mZnNldCwKPiArCQkJCSBw aHlfZGF0YS0+cGh5cmVmc2VsX21hc2ssCj4gKwkJCQkgZmllbGRfcHJlcChwaHlfZGF0YS0+cGh5 cmVmc2VsX21hc2ssIHJlZnNlbCkpOwoKW1NldmVyaXR5OiBMb3ddCldpbGwgdGhpcyBjYXVzZSBh IGJ1aWxkIGZhaWx1cmU/IAoKZmllbGRfcHJlcCgpIHN0cmljdGx5IHJlcXVpcmVzIGEgY29tcGls ZS10aW1lIGNvbnN0YW50IG1hc2ssIGJ1dApwaHlfZGF0YS0+cGh5cmVmc2VsX21hc2sgaXMgcmVz b2x2ZWQgYXQgcnVudGltZSB2aWEgYSBwb2ludGVyIGRlcmVmZXJlbmNlLgoKPiArCWlmIChyZXQp Cj4gKwkJcmV0dXJuIHJldDsKCltTZXZlcml0eTogSGlnaF0KQ291bGQgdGhpcyBlcnJvciByZXR1 cm4gbGVhdmUgdGhlIGVuX3JlZmNudCBhcnRpZmljaWFsbHkgZWxldmF0ZWQsIHByZXZlbnRpbmcK c3Vic2VxdWVudCBpbml0aWFsaXphdGlvbiBhdHRlbXB0cyBmcm9tIGV2ZXIgc3VjY2VlZGluZz8K Cj4gKwo+ICsJcmV0ID0gcmVndWxhdG9yX2VuYWJsZShwaHlfZGV2LT52ZGQzMyk7Cj4gKwlpZiAo cmV0KQo+ICsJCXJldHVybiByZXQ7Cj4gKwo+ICsJcmV0ID0gY2xrX3ByZXBhcmVfZW5hYmxlKHBo eV9kZXYtPnBoeXJlZik7Cj4gKwlpZiAocmV0KQo+ICsJCWdvdG8gZXJyb3JfcmVnZGlzOwo+ICsK PiArCXJldCA9IHJlc2V0X2NvbnRyb2xfZGVhc3NlcnQocGh5X2Rldi0+cnN0Yyk7Cj4gKwlpZiAo cmV0KQo+ICsJCWdvdG8gZXJyb3JfY2xrZGlzOwo+ICsKPiArCXJldHVybiAwOwo+ICsKPiArZXJy b3JfY2xrZGlzOgo+ICsJY2xrX2Rpc2FibGVfdW5wcmVwYXJlKHBoeV9kZXYtPnBoeXJlZik7Cj4g K2Vycm9yX3JlZ2RpczoKPiArCXJlZ3VsYXRvcl9kaXNhYmxlKHBoeV9kZXYtPnZkZDMzKTsKPiAr Cj4gKwlyZXR1cm4gcmV0OwoKW1NldmVyaXR5OiBIaWdoXQpEb2VzIHRoaXMgZmluYWwgY2xlYW51 cCBlcnJvciBwYXRoIGFsc28gbGVhdmUgdGhlIGVuX3JlZmNudCBpbmNyZW1lbnRlZD8KCj4gK30K PiArCj4gK3N0YXRpYyBpbnQgc3RtMzJfdXNiMnBoeV9kaXNhYmxlKHN0cnVjdCBzdG0zMl91c2Iy cGh5ICpwaHlfZGV2KQo+ICt7Cj4gKwlpbnQgcmV0Owo+ICsKPiArCS8qIENoZWNrIGlmIGEgcGh5 IGlzIHN0aWxsIGluaXQgb3IgY2xrcGxsIGluIHVzZSAqLwo+ICsJaWYgKGF0b21pY19kZWNfcmV0 dXJuKCZwaHlfZGV2LT5lbl9yZWZjbnQpID4gMCkKPiArCQlyZXR1cm4gMDsKCltTZXZlcml0eTog SGlnaF0KRG9lcyB0aGlzIGxvY2tsZXNzIGVhcmx5IHJldHVybiBhbHNvIGFsbG93IHRlYXJkb3du IHJhY2VzPwoKPiArCj4gKwlyZXQgPSByZXNldF9jb250cm9sX2Fzc2VydChwaHlfZGV2LT5yc3Rj KTsKPiArCWlmIChyZXQpCj4gKwkJcmV0dXJuIHJldDsKCltTZXZlcml0eTogTWVkaXVtXQpXaWxs IGZhaWxpbmcgdG8gYXNzZXJ0IHRoZSByZXNldCBoZXJlIGxlYWsgdGhlIGNsb2NrIGFuZCByZWd1 bGF0b3IgcmVzb3VyY2VzLApsZWF2aW5nIHRoZW0gcGVybWFuZW50bHkgZW5hYmxlZD8KCj4gKwo+ ICsJY2xrX2Rpc2FibGVfdW5wcmVwYXJlKHBoeV9kZXYtPnBoeXJlZik7Cj4gKwo+ICsJcmV0dXJu IHJlZ3VsYXRvcl9kaXNhYmxlKHBoeV9kZXYtPnZkZDMzKTsKPiArfQo+ICsKPiArc3RhdGljIGlu dCBzdG0zMl91c2IycGh5X3NldF9tb2RlKHN0cnVjdCBwaHkgKnBoeSwgZW51bSBwaHlfbW9kZSBt b2RlLCBpbnQgc3VibW9kZSkKPiArewo+ICsJc3RydWN0IHN0bTMyX3VzYjJwaHkgKnBoeV9kZXYg PSBwaHlfZ2V0X2RydmRhdGEocGh5KTsKPiArCXUzMiBtYXNrID0gU1lTQ0ZHX1VTQjJQSFkyQ1Jf VVNCMlBIWTJDTU4gfAo+ICsJCSAgIFNZU0NGR19VU0IyUEhZMkNSX1ZCVVNWQUxJRCB8Cj4gKwkJ ICAgU1lTQ0ZHX1VTQjJQSFkyQ1JfVkJVU1ZMREVYVDsKPiArCXUzMiB2YWwgPSAwOwo+ICsJaW50 IHJldDsKPiArCj4gKwlpZiAobW9kZSA9PSBQSFlfTU9ERV9VU0JfSE9TVCkgewo+ICsJCWlmIChz dWJtb2RlICE9IFVTQl9ST0xFX05PTkUpCj4gKwkJCXZhbCA9IFNZU0NGR19VU0IyUEhZMkNSX1ZC VVNWQUxJRDsKPiArCX0gZWxzZSBpZiAobW9kZSA9PSBQSFlfTU9ERV9VU0JfREVWSUNFKSB7Cj4g KwkJdmFsID0gU1lTQ0ZHX1VTQjJQSFkyQ1JfVVNCMlBIWTJDTU4gfAo+ICsJCSAgICAgIFNZU0NG R19VU0IyUEhZMkNSX1ZCVVNWTERFWFRTRUw7CgpbU2V2ZXJpdHk6IEhpZ2hdCklzIHRoZXJlIGEg bG9naWNhbCBjb25mbGljdCBvdmVyIHRoZSBTWVNDRkdfVVNCMlBIWTJDUl9VU0IyUEhZMkNNTiBi aXQ/CgpUaGUgQ2xvY2sgRnJhbWV3b3JrJ3MgaW50ZXJuYWwgc3RhdGUgY291bGQgYmVjb21lIGRl c3luY2hyb25pemVkIGlmCnN0bTMyX3VzYjJwaHlfY2xrY21uX3ByZXBhcmUoKSBjbGVhcnMgdGhp cyBiaXQsIGJ1dCBzdG0zMl91c2IycGh5X3NldF9tb2RlKCkKaXMgY29uY3VycmVudGx5IGNhbGxl ZCB0byBzd2l0Y2ggdG8gREVWSUNFIG1vZGUgYW5kIGRpcmVjdGx5IHNldHMgdGhpcyBleGFjdApz YW1lIGJpdCB2aWEgcmVnbWFwX3VwZGF0ZV9iaXRzKCkuCgo+ICsJCWlmIChzdWJtb2RlICE9IFVT Ql9ST0xFX05PTkUpCj4gKwkJCXZhbCB8PSBTWVNDRkdfVVNCMlBIWTJDUl9WQlVTVkxERVhUOwo+ ICsJCW1hc2sgfD0gU1lTQ0ZHX1VTQjJQSFkyQ1JfVkJVU1ZMREVYVFNFTDsKCltTZXZlcml0eTog TWVkaXVtXQpEb2VzIGFkZGluZyB0aGUgVkJVU1ZMREVYVFNFTCBiaXQgdG8gdGhlIG1hc2sgZHlu YW1pY2FsbHkgaGVyZSBpbnN0ZWFkIG9mIGluCnRoZSBiYXNlIG1hc2sgcHJldmVudCBjbGVhcmlu ZyBpdCBvbiBzdWJzZXF1ZW50IHRyYW5zaXRpb25zIHRvIEhPU1QgbW9kZT8KCklmIGl0IGlzIG9t aXR0ZWQgZnJvbSB0aGUgbWFzayBkdXJpbmcgYSB0cmFuc2l0aW9uIHRvIFBIWV9NT0RFX1VTQl9I T1NULApyZWdtYXBfdXBkYXRlX2JpdHMoKSB3b24ndCBiZSBhYmxlIHRvIGNsZWFyIGl0LgoKPiAr CX0gZWxzZSB7Cj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4gKwl9CgpbIC4uLiBdCgo+ICtzdGF0aWMg aW50IHN0bTMyX3VzYjJwaHlfcHJvYmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKPiAr ewo+ICsJc3RydWN0IHBoeV9wcm92aWRlciAqcGh5X3Byb3ZpZGVyOwo+ICsJc3RydWN0IGRldmlj ZSAqZGV2ID0gJnBkZXYtPmRldjsKPiArCXN0cnVjdCBzdG0zMl91c2IycGh5ICpwaHlfZGV2Owo+ ICsJY2hhciAqcGxsbmFtZSwgKmNtbm5hbWU7Cj4gKwljb25zdCBfX2JlMzIgKm9mZnNldDsKPiAr CXN0cnVjdCBwaHkgKnBoeTsKPiArCWludCByZXQ7CgpbIC4uLiBdCgo+ICsJcGh5X2Rldi0+cGh5 cmVmID0gZGV2bV9jbGtfZ2V0KGRldiwgTlVMTCk7Cj4gKwlpZiAoSVNfRVJSKHBoeV9kZXYtPnBo eXJlZikpCj4gKwkJcmV0dXJuIGRldl9lcnJfcHJvYmUoZGV2LCBQVFJfRVJSKHBoeV9kZXYtPnBo eXJlZiksICJGYWlsZWQgdG8gZ2V0IHBoeXJlZiBjbGtcbiIpOwo+ICsKPiArCXBoeV9kZXYtPnZk ZDMzID0gZGV2bV9yZWd1bGF0b3JfZ2V0X29wdGlvbmFsKGRldiwgInZkZDMzIik7Cj4gKwlpZiAo SVNfRVJSKHBoeV9kZXYtPnZkZDMzKSkKPiArCQlyZXR1cm4gZGV2X2Vycl9wcm9iZShkZXYsIFBU Ul9FUlIocGh5X2Rldi0+dmRkMzMpLCAiRmFpbGVkIHRvIGdldCB2ZGQzdjMgc3VwcGx5XG4iKTsK CltTZXZlcml0eTogTWVkaXVtXQpTaW5jZSB0aGlzIHByb3BhZ2F0ZXMgLUVOT0RFViB3aGVuIHRo ZSByZWd1bGF0b3IgaXMgYWJzZW50IGluIHRoZSBEVCwgZG9lcwp0aGlzIHN0cmljdGx5IGZhaWwg cHJvYmUgZm9yIHBsYXRmb3JtcyBsZWdpdGltYXRlbHkgbGFja2luZyB0aGUgb3B0aW9uYWwKdmRk MzMgcmVndWxhdG9yLCBicmVha2luZyB0aGUgX29wdGlvbmFsIGNvbnRyYWN0PwoKPiArCj4gKwlw aHlfZGV2LT5yZWdtYXAgPSBzeXNjb25fbm9kZV90b19yZWdtYXAoZGV2LT5vZl9ub2RlLT5wYXJl bnQpOwoKW1NldmVyaXR5OiBNZWRpdW1dCldpbGwgdGhpcyB1bmNvbmRpdGlvbmFsbHkgZGVyZWZl cmVuY2UgZGV2LT5vZl9ub2RlPyAKCklmIHRoZSBkZXZpY2UgaXMgaW5zdGFudGlhdGVkIG1hbnVh bGx5LCBzdWNoIGFzIHZpYSBzeXNmcyBiaW5kIHdpdGhvdXQgYQpiYWNraW5nIERldmljZSBUcmVl IG5vZGUsIGRldi0+b2Zfbm9kZSB3aWxsIGJlIE5VTEwsIGxlYWRpbmcgdG8gYSBrZXJuZWwKcGFu aWMuCgo+ICsJaWYgKElTX0VSUihwaHlfZGV2LT5yZWdtYXApKQo+ICsJCXJldHVybiBkZXZfZXJy X3Byb2JlKGRldiwgUFRSX0VSUihwaHlfZGV2LT5yZWdtYXApLCAiRmFpbGVkIHRvIGdldCByZWdt YXBcbiIpOwo+ICsKPiArCW9mZnNldCA9IG9mX2dldF9hZGRyZXNzKGRldi0+b2Zfbm9kZSwgMCwg TlVMTCwgTlVMTCk7Cj4gKwlpZiAoIW9mZnNldCkKPiArCQlyZXR1cm4gZGV2X2Vycl9wcm9iZShk ZXYsIC1FSU5WQUwsICJGYWlsZWQgdG8gZ2V0IHJlZ21hcCBvZmZzZXRcbiIpOwo+ICsKPiArCXBo eV9kZXYtPmNyX29mZnNldCA9IGJlMzJfdG9fY3B1KCpvZmZzZXQpOwoKW1NldmVyaXR5OiBIaWdo XQpEb2VzIHRoaXMgbG9naWMgaW5jb3JyZWN0bHkgcGFyc2UgdGhlIHJlZyBwcm9wZXJ0eSBvbiA2 NC1iaXQgcGxhdGZvcm1zPwoKSWYgdGhlIHBhcmVudCBub2RlIHVzZXMgMiBhZGRyZXNzIGNlbGxz LCB3aGljaCBpcyBjb21tb24gb24gU1RNMzJNUDI1LAoqb2Zmc2V0IGNvbnRhaW5zIHRoZSBoaWdo IDMyIGJpdHMgb2YgdGhlIGFkZHJlc3MsIHdoaWNoIGlzIHR5cGljYWxseSAwLgpUaGlzIGNvdWxk IGNhdXNlIHRoZSBkcml2ZXIgdG8gaW5jb3JyZWN0bHkgZXh0cmFjdCAwIGFuZCBvdmVyd3JpdGUg c3lzY29uCnJlZ2lzdGVyIDAgaW5zdGVhZCBvZiB0aGUgaW50ZW5kZWQgUEhZIGNvbnRyb2wgcmVn aXN0ZXIuCgo+ICsKPiArCXBoeV9kZXYtPmh3X2RhdGEgPSBkZXZpY2VfZ2V0X21hdGNoX2RhdGEo ZGV2KTsKPiArCj4gKwlwaHkgPSBkZXZtX3BoeV9jcmVhdGUoZGV2LCBOVUxMLCBwaHlfZGV2LT5o d19kYXRhLT5waHlfb3BzKTsKCltTZXZlcml0eTogTWVkaXVtXQpDb3VsZCB0aGlzIHVuY29uZGl0 aW9uYWxseSBkZXJlZmVyZW5jZSBwaHlfZGV2LT5od19kYXRhIGlmCmRldmljZV9nZXRfbWF0Y2hf ZGF0YShkZXYpIHJldHVybnMgTlVMTCB3aGVuIHRoZSBkZXZpY2UgaXMgYm91bmQgbWFudWFsbHk/ Cgo+ICsJaWYgKElTX0VSUihwaHkpKQo+ICsJCXJldHVybiBkZXZfZXJyX3Byb2JlKGRldiwgUFRS X0VSUihwaHkpLCAiRmFpbGVkIHRvIGNyZWF0ZSBQSFlcbiIpOwoKWyAuLi4gXQoKPiArc3RhdGlj IGludCBzdG0zMl91c2IycGh5X3N1c3BlbmQoc3RydWN0IGRldmljZSAqZGV2KQo+ICt7Cj4gKwlz dHJ1Y3Qgc3RtMzJfdXNiMnBoeSAqcGh5X2RldiA9IGRldl9nZXRfZHJ2ZGF0YShkZXYpOwo+ICsK PiArCWlmIChwaHlfZGV2LT5pc19pbml0KQo+ICsJCXJldHVybiBzdG0zMl91c2IycGh5X2Rpc2Fi bGUocGh5X2Rldik7CgpbU2V2ZXJpdHk6IEhpZ2hdCkRvZXMgdGhpcyBjb25kaXRpb25hbCBsb2dp YyBpbmNvcnJlY3RseSBhc3N1bWUgaXNfaW5pdCBhbmQgZGlzYWJsZSgpCmNvcnJlY3RseSBhY2Nv dW50IGZvciBhbGwgZnJhbWV3b3JrIGNvbnN1bWVycz8KCklmIHRoZSBoYXJkd2FyZSB3YXMgZW5h YmxlZCB2aWEgdGhlIENsb2NrIEFQSSwgZW5fcmVmY250IGlzIDEgYnV0IGlzX2luaXQKaXMgZmFs c2UsIHNvIHN1c3BlbmQgZG9lcyBub3RoaW5nLiBJZiBlbmFibGVkIHZpYSBib3RoLCBjYWxsaW5n CnN0bTMyX3VzYjJwaHlfZGlzYWJsZSgpIG1lcmVseSBkZWNyZW1lbnRzIGVuX3JlZmNudCB0byAx IGFuZCByZXR1cm5zIGVhcmx5CndpdGhvdXQgcG93ZXJpbmcgb2ZmIHRoZSBoYXJkd2FyZS4gQ291 bGQgdGhpcyBmYWlsIHRvIHNodXQgZG93biB0aGUgaGFyZHdhcmUKaWYgdGhlIENDRiBjbG9jayBp cyBpbiB1c2U/Cgo+ICsKPiArCXJldHVybiAwOwo+ICt9CgotLSAKU2FzaGlrbyBBSSByZXZpZXcg wrcgaHR0cHM6Ly9zYXNoaWtvLmRldi8jL3BhdGNoc2V0LzIwMjYwOTAyMTQxMzEyLjY0OTQwNi0x LW1hcmV4QG5hYmxhZGV2LmNvbT9wYXJ0PTIKCi0tIApsaW51eC1waHkgbWFpbGluZyBsaXN0Cmxp bnV4LXBoeUBsaXN0cy5pbmZyYWRlYWQub3JnCmh0dHBzOi8vbGlzdHMuaW5mcmFkZWFkLm9yZy9t YWlsbWFuL2xpc3RpbmZvL2xpbnV4LXBoeQo=