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 X-Spam-Level: X-Spam-Status: No, score=-14.1 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, MENTIONS_GIT_HOSTING,SIGNED_OFF_BY,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 27B4EC43387 for ; Sun, 13 Jan 2019 02:17:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D48F820870 for ; Sun, 13 Jan 2019 02:17:27 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=sholland.org header.i=@sholland.org header.b="mvmCKr9t"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="Upeefp0O" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726724AbfAMCR1 (ORCPT ); Sat, 12 Jan 2019 21:17:27 -0500 Received: from out1-smtp.messagingengine.com ([66.111.4.25]:36463 "EHLO out1-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726629AbfAMCRZ (ORCPT ); Sat, 12 Jan 2019 21:17:25 -0500 Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailout.nyi.internal (Postfix) with ESMTP id 663DB23174; Sat, 12 Jan 2019 21:17:23 -0500 (EST) Received: from mailfrontend2 ([10.202.2.163]) by compute5.internal (MEProxy); Sat, 12 Jan 2019 21:17:23 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sholland.org; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type:content-transfer-encoding; s=fm1; bh= jKlMXS7XKvXn/szdGKBQgG32+kZpvO4uOo39QB1bolU=; b=mvmCKr9tLbEvZJbP pDROAd6IVm3H+tyjyvewON4VHOYfu+/+ArBujiVhfDXn37l0VEuv9+CnihXwQJz6 4joEh2OkDUy/Q32KvZzaH2GCqpcfAXUzqg4gMHL3z2eF+krzqNFd9EfXRZH4p3zO HP0pa3tHrmZHsG9mnCbzz1JaRXVli6vxQKF/5KOoxpz++tQTllf25u0GpIbfKaOx Z4eKMXxSZvDpYbsxPhgdBnlBZfvOfhsSvTgphvpKdchneqyKUYVjwO68c7ajBeK9 PGEo6YPH30QIE71YUD80IG8ZMrQOWYdlNLKocWTel4ZaJpkw4CIA1H+gnDmSKutJ VDRgYA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:references :subject:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm1; bh=jKlMXS7XKvXn/szdGKBQgG32+kZpvO4uOo39QB1bo lU=; b=Upeefp0OZATDpZxWgrtHSzR2/FFiAwyRjS0PC/HWQehfO8m3OS4/AkyP1 L96BnIrJ3Uk4WRUTblFAJvE+dJAiQeJ1WmOsJ+Dkgshp5OGZ0pUhxf/n45Ro4BuL VTC4QqUzoYnFC/ut2gfaL91yRN5tZmU+2ik5O+8E1vvF/IwhZcLDw6tcR/JX6Ixa X+EWoETX3GQC1Dbwzf9yMctarPw5mxJ8ERUyGHtDuFyzr0v0ReMlCfWqdBd0Ekca /EA5D9Um8kl6S9wVk6XgFvZm2vyzRIhfmLQqoEzcCKywrMv2qiCquAYqWMUFIdM+ 3TkvJqkWkNjRz6J6Dbd2i15CpL/Sw== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedtledrfeekgdduvdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfhuthenuceurghilhhouhhtmecufedt tdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujfgurhephffvufffkffojg hfgggtgfesthekredtredtjeenucfhrhhomhepufgrmhhuvghlucfjohhllhgrnhguuceo shgrmhhuvghlsehshhholhhlrghnugdrohhrgheqnecuffhomhgrihhnpegrrhhmsghirg hnrdgtohhmpdhgihhthhhusgdrtghomhdpfihhihhtvghquhgrrhhkrdhorhhgnecukfhp peejtddrudefhedrudegkedrudehudenucfrrghrrghmpehmrghilhhfrhhomhepshgrmh huvghlsehshhholhhlrghnugdrohhrghenucevlhhushhtvghrufhiiigvpedt X-ME-Proxy: Received: from titanium.stl.sholland.net (70-135-148-151.lightspeed.stlsmo.sbcglobal.net [70.135.148.151]) by mail.messagingengine.com (Postfix) with ESMTPA id 6F2A31026D; Sat, 12 Jan 2019 21:17:21 -0500 (EST) From: Samuel Holland To: Catalin Marinas , Will Deacon , Maxime Ripard , Chen-Yu Tsai , Rob Herring , Mark Rutland , Daniel Lezcano , Thomas Gleixner , Marc Zyngier Cc: devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-sunxi@googlegroups.com, Samuel Holland Subject: [PATCH v3 1/2] arm64: arch_timer: Workaround for Allwinner A64 timer instability Date: Sat, 12 Jan 2019 20:17:18 -0600 Message-Id: <20190113021719.46457-2-samuel@sholland.org> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20190113021719.46457-1-samuel@sholland.org> References: <20190113021719.46457-1-samuel@sholland.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The Allwinner A64 SoC is known[1] to have an unstable architectural timer, which manifests itself most obviously in the time jumping forward a multiple of 95 years[2][3]. This coincides with 2^56 cycles at a timer frequency of 24 MHz, implying that the time went slightly backward (and this was interpreted by the kernel as it jumping forward and wrapping around past the epoch). Investigation revealed instability in the low bits of CNTVCT at the point a high bit rolls over. This leads to power-of-two cycle forward and backward jumps. (Testing shows that forward jumps are about twice as likely as backward jumps.) Since the counter value returns to normal after an indeterminate read, each "jump" really consists of both a forward and backward jump from the software perspective. Unless the kernel is trapping CNTVCT reads, a userspace program is able to read the register in a loop faster than it changes. A test program running on all 4 CPU cores that reported jumps larger than 100 ms was run for 13.6 hours and reported the following: Count | Event -------+--------------------------- 9940 | jumped backward 699ms 268 | jumped backward 1398ms 1 | jumped backward 2097ms 16020 | jumped forward 175ms 6443 | jumped forward 699ms 2976 | jumped forward 1398ms 9 | jumped forward 356516ms 9 | jumped forward 357215ms 4 | jumped forward 714430ms 1 | jumped forward 3578440ms This works out to a jump larger than 100 ms about every 5.5 seconds on each CPU core. The largest jump (almost an hour!) was the following sequence of reads: 0x0000007fffffffff → 0x00000093feffffff → 0x0000008000000000 Note that the middle bits don't necessarily all read as all zeroes or all ones during the anomalous behavior; however the low 10 bits checked by the function in this patch have never been observed with any other value. Also note that smaller jumps are much more common, with backward jumps of 2048 (2^11) cycles observed over 400 times per second on each core. (Of course, this is partially explained by lower bits rolling over more frequently.) Any one of these could have caused the 95 year time skip. Similar anomalies were observed while reading CNTPCT (after patching the kernel to allow reads from userspace). However, the CNTPCT jumps are much less frequent, and only small jumps were observed. The same program as before (except now reading CNTPCT) observed after 72 hours: Count | Event -------+--------------------------- 17 | jumped backward 699ms 52 | jumped forward 175ms 2831 | jumped forward 699ms 5 | jumped forward 1398ms Further investigation showed that the instability in CNTPCT/CNTVCT also affected the respective timer's TVAL register. The following values were observed immediately after writing CNVT_TVAL to 0x10000000: CNTVCT | CNTV_TVAL | CNTV_CVAL | CNTV_TVAL Error --------------------+------------+--------------------+----------------- 0x000000d4a2d8bfff | 0x10003fff | 0x000000d4b2d8bfff | +0x00004000 0x000000d4a2d94000 | 0x0fffffff | 0x000000d4b2d97fff | -0x00004000 0x000000d4a2d97fff | 0x10003fff | 0x000000d4b2d97fff | +0x00004000 0x000000d4a2d9c000 | 0x0fffffff | 0x000000d4b2d9ffff | -0x00004000 The pattern of errors in CNTV_TVAL seemed to depend on exactly which value was written to it. For example, after writing 0x10101010: CNTVCT | CNTV_TVAL | CNTV_CVAL | CNTV_TVAL Error --------------------+------------+--------------------+----------------- 0x000001ac3effffff | 0x1110100f | 0x000001ac4f10100f | +0x1000000 0x000001ac40000000 | 0x1010100f | 0x000001ac5110100f | -0x1000000 0x000001ac58ffffff | 0x1110100f | 0x000001ac6910100f | +0x1000000 0x000001ac66000000 | 0x1010100f | 0x000001ac7710100f | -0x1000000 0x000001ac6affffff | 0x1110100f | 0x000001ac7b10100f | +0x1000000 0x000001ac6e000000 | 0x1010100f | 0x000001ac7f10100f | -0x1000000 I was also twice able to reproduce the issue covered by Allwinner's workaround[4], that writing to TVAL sometimes fails, and both CVAL and TVAL are left with entirely bogus values. One was the following values: CNTVCT | CNTV_TVAL | CNTV_CVAL --------------------+------------+-------------------------------------- 0x000000d4a2d6014c | 0x8fbd5721 | 0x000000d132935fff (615s in the past) ======================================================================== Because the CPU can read the CNTPCT/CNTVCT registers faster than they change, performing two reads of the register and comparing the high bits (like other workarounds) is not a workable solution. And because the timer can jump both forward and backward, no pair of reads can distinguish a good value from a bad one. The only way to guarantee a good value from consecutive reads would be to read _three_ times, and take the middle value only if the three values are 1) each unique and 2) increasing. This takes at minimum 3 counter cycles (125 ns), or more if an anomaly is detected. However, since there is a distinct pattern to the bad values, we can optimize the common case (1022/1024 of the time) to a single read by simply ignoring values that match the error pattern. This still takes no more than 3 cycles in the worst case, and requires much less code. As an additional safety check, we still limit the loop iteration to the number of max-frequency (1.2 GHz) CPU cycles in three 24 MHz counter periods. For the TVAL registers, the simple solution is to not use them. Instead, read or write the CVAL and calculate the TVAL value in software. Although the manufacturer is aware of at least part of the erratum[4], there is no official name for it. For now, use the kernel-internal name "UNKNOWN1". [1]: https://github.com/armbian/build/commit/a08cd6fe7ae9 [2]: https://forum.armbian.com/topic/3458-a64-datetime-clock-issue/ [3]: https://irclog.whitequark.org/linux-sunxi/2018-01-26 [4]: https://github.com/Allwinner-Homlet/H6-BSP4.9-linux/blob/master/drivers/clocksource/arm_arch_timer.c#L272 Acked-by: Maxime Ripard Tested-by: Andre Przywara Signed-off-by: Samuel Holland --- Documentation/arm64/silicon-errata.txt | 2 + drivers/clocksource/Kconfig | 10 +++++ drivers/clocksource/arm_arch_timer.c | 55 ++++++++++++++++++++++++++ 3 files changed, 67 insertions(+) diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt index 8f9577621144..4a269732d2a0 100644 --- a/Documentation/arm64/silicon-errata.txt +++ b/Documentation/arm64/silicon-errata.txt @@ -44,6 +44,8 @@ stable kernels. | Implementor | Component | Erratum ID | Kconfig | +----------------+-----------------+-----------------+-----------------------------+ +| Allwinner | A64/R18 | UNKNOWN1 | SUN50I_ERRATUM_UNKNOWN1 | +| | | | | | ARM | Cortex-A53 | #826319 | ARM64_ERRATUM_826319 | | ARM | Cortex-A53 | #827319 | ARM64_ERRATUM_827319 | | ARM | Cortex-A53 | #824069 | ARM64_ERRATUM_824069 | diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 55c77e44bb2d..d20ff4da07c3 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -364,6 +364,16 @@ config ARM64_ERRATUM_858921 The workaround will be dynamically enabled when an affected core is detected. +config SUN50I_ERRATUM_UNKNOWN1 + bool "Workaround for Allwinner A64 erratum UNKNOWN1" + default y + depends on ARM_ARCH_TIMER && ARM64 && ARCH_SUNXI + select ARM_ARCH_TIMER_OOL_WORKAROUND + help + This option enables a workaround for instability in the timer on + the Allwinner A64 SoC. The workaround will only be active if the + allwinner,erratum-unknown1 property is found in the timer node. + config ARM_GLOBAL_TIMER bool "Support for the ARM global timer" if COMPILE_TEST select TIMER_OF if OF diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 9a7d4dc00b6e..a8b20b65bd4b 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -326,6 +326,48 @@ static u64 notrace arm64_1188873_read_cntvct_el0(void) } #endif +#ifdef CONFIG_SUN50I_ERRATUM_UNKNOWN1 +/* + * The low bits of the counter registers are indeterminate while bit 10 or + * greater is rolling over. Since the counter value can jump both backward + * (7ff -> 000 -> 800) and forward (7ff -> fff -> 800), ignore register values + * with all ones or all zeros in the low bits. Bound the loop by the maximum + * number of CPU cycles in 3 consecutive 24 MHz counter periods. + */ +#define __sun50i_a64_read_reg(reg) ({ \ + u64 _val; \ + int _retries = 150; \ + \ + do { \ + _val = read_sysreg(reg); \ + _retries--; \ + } while (((_val + 1) & GENMASK(9, 0)) <= 1 && _retries); \ + \ + WARN_ON_ONCE(!_retries); \ + _val; \ +}) + +static u64 notrace sun50i_a64_read_cntpct_el0(void) +{ + return __sun50i_a64_read_reg(cntpct_el0); +} + +static u64 notrace sun50i_a64_read_cntvct_el0(void) +{ + return __sun50i_a64_read_reg(cntvct_el0); +} + +static u32 notrace sun50i_a64_read_cntp_tval_el0(void) +{ + return read_sysreg(cntp_cval_el0) - sun50i_a64_read_cntpct_el0(); +} + +static u32 notrace sun50i_a64_read_cntv_tval_el0(void) +{ + return read_sysreg(cntv_cval_el0) - sun50i_a64_read_cntvct_el0(); +} +#endif + #ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND DEFINE_PER_CPU(const struct arch_timer_erratum_workaround *, timer_unstable_counter_workaround); EXPORT_SYMBOL_GPL(timer_unstable_counter_workaround); @@ -423,6 +465,19 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = { .read_cntvct_el0 = arm64_1188873_read_cntvct_el0, }, #endif +#ifdef CONFIG_SUN50I_ERRATUM_UNKNOWN1 + { + .match_type = ate_match_dt, + .id = "allwinner,erratum-unknown1", + .desc = "Allwinner erratum UNKNOWN1", + .read_cntp_tval_el0 = sun50i_a64_read_cntp_tval_el0, + .read_cntv_tval_el0 = sun50i_a64_read_cntv_tval_el0, + .read_cntpct_el0 = sun50i_a64_read_cntpct_el0, + .read_cntvct_el0 = sun50i_a64_read_cntvct_el0, + .set_next_event_phys = erratum_set_next_event_tval_phys, + .set_next_event_virt = erratum_set_next_event_tval_virt, + }, +#endif }; typedef bool (*ate_match_fn_t)(const struct arch_timer_erratum_workaround *, -- 2.19.2 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Samuel Holland Subject: [PATCH v3 1/2] arm64: arch_timer: Workaround for Allwinner A64 timer instability Date: Sat, 12 Jan 2019 20:17:18 -0600 Message-ID: <20190113021719.46457-2-samuel@sholland.org> References: <20190113021719.46457-1-samuel@sholland.org> Reply-To: samuel-RkNLwX/CsU9g9hUCZPvPmw@public.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Return-path: Sender: linux-sunxi-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org In-Reply-To: <20190113021719.46457-1-samuel-RkNLwX/CsU9g9hUCZPvPmw@public.gmane.org> List-Post: , List-Help: , List-Archive: , List-Unsubscribe: , To: Catalin Marinas , Will Deacon , Maxime Ripard , Chen-Yu Tsai , Rob Herring , Mark Rutland , Daniel Lezcano , Thomas Gleixner , Marc Zyngier Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-sunxi-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org, Samuel Holland List-Id: devicetree@vger.kernel.org The Allwinner A64 SoC is known[1] to have an unstable architectural timer, which manifests itself most obviously in the time jumping forward a multiple of 95 years[2][3]. This coincides with 2^56 cycles at a timer frequency of 24 MHz, implying that the time went slightly backward (and this was interpreted by the kernel as it jumping forward and wrapping around past the epoch). Investigation revealed instability in the low bits of CNTVCT at the point a high bit rolls over. This leads to power-of-two cycle forward and backward jumps. (Testing shows that forward jumps are about twice as likely as backward jumps.) Since the counter value returns to normal after an indeterminate read, each "jump" really consists of both a forward and backward jump from the software perspective. Unless the kernel is trapping CNTVCT reads, a userspace program is able to read the register in a loop faster than it changes. A test program running on all 4 CPU cores that reported jumps larger than 100 ms was run for 13.6 hours and reported the following: Count | Event -------+--------------------------- 9940 | jumped backward 699ms 268 | jumped backward 1398ms 1 | jumped backward 2097ms 16020 | jumped forward 175ms 6443 | jumped forward 699ms 2976 | jumped forward 1398ms 9 | jumped forward 356516ms 9 | jumped forward 357215ms 4 | jumped forward 714430ms 1 | jumped forward 3578440ms This works out to a jump larger than 100 ms about every 5.5 seconds on each CPU core. The largest jump (almost an hour!) was the following sequence of reads: 0x0000007fffffffff =E2=86=92 0x00000093feffffff =E2=86=92 0x00000080000= 00000 Note that the middle bits don't necessarily all read as all zeroes or all ones during the anomalous behavior; however the low 10 bits checked by the function in this patch have never been observed with any other value. Also note that smaller jumps are much more common, with backward jumps of 2048 (2^11) cycles observed over 400 times per second on each core. (Of course, this is partially explained by lower bits rolling over more frequently.) Any one of these could have caused the 95 year time skip. Similar anomalies were observed while reading CNTPCT (after patching the kernel to allow reads from userspace). However, the CNTPCT jumps are much less frequent, and only small jumps were observed. The same program as before (except now reading CNTPCT) observed after 72 hours: Count | Event -------+--------------------------- 17 | jumped backward 699ms 52 | jumped forward 175ms 2831 | jumped forward 699ms 5 | jumped forward 1398ms Further investigation showed that the instability in CNTPCT/CNTVCT also affected the respective timer's TVAL register. The following values were observed immediately after writing CNVT_TVAL to 0x10000000: CNTVCT | CNTV_TVAL | CNTV_CVAL | CNTV_TVAL Error --------------------+------------+--------------------+----------------- 0x000000d4a2d8bfff | 0x10003fff | 0x000000d4b2d8bfff | +0x00004000 0x000000d4a2d94000 | 0x0fffffff | 0x000000d4b2d97fff | -0x00004000 0x000000d4a2d97fff | 0x10003fff | 0x000000d4b2d97fff | +0x00004000 0x000000d4a2d9c000 | 0x0fffffff | 0x000000d4b2d9ffff | -0x00004000 The pattern of errors in CNTV_TVAL seemed to depend on exactly which value was written to it. For example, after writing 0x10101010: CNTVCT | CNTV_TVAL | CNTV_CVAL | CNTV_TVAL Error --------------------+------------+--------------------+----------------- 0x000001ac3effffff | 0x1110100f | 0x000001ac4f10100f | +0x1000000 0x000001ac40000000 | 0x1010100f | 0x000001ac5110100f | -0x1000000 0x000001ac58ffffff | 0x1110100f | 0x000001ac6910100f | +0x1000000 0x000001ac66000000 | 0x1010100f | 0x000001ac7710100f | -0x1000000 0x000001ac6affffff | 0x1110100f | 0x000001ac7b10100f | +0x1000000 0x000001ac6e000000 | 0x1010100f | 0x000001ac7f10100f | -0x1000000 I was also twice able to reproduce the issue covered by Allwinner's workaround[4], that writing to TVAL sometimes fails, and both CVAL and TVAL are left with entirely bogus values. One was the following values: CNTVCT | CNTV_TVAL | CNTV_CVAL --------------------+------------+-------------------------------------- 0x000000d4a2d6014c | 0x8fbd5721 | 0x000000d132935fff (615s in the past) =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Because the CPU can read the CNTPCT/CNTVCT registers faster than they change, performing two reads of the register and comparing the high bits (like other workarounds) is not a workable solution. And because the timer can jump both forward and backward, no pair of reads can distinguish a good value from a bad one. The only way to guarantee a good value from consecutive reads would be to read _three_ times, and take the middle value only if the three values are 1) each unique and 2) increasing. This takes at minimum 3 counter cycles (125 ns), or more if an anomaly is detected. However, since there is a distinct pattern to the bad values, we can optimize the common case (1022/1024 of the time) to a single read by simply ignoring values that match the error pattern. This still takes no more than 3 cycles in the worst case, and requires much less code. As an additional safety check, we still limit the loop iteration to the number of max-frequency (1.2 GHz) CPU cycles in three 24 MHz counter periods. For the TVAL registers, the simple solution is to not use them. Instead, read or write the CVAL and calculate the TVAL value in software. Although the manufacturer is aware of at least part of the erratum[4], there is no official name for it. For now, use the kernel-internal name "UNKNOWN1". [1]: https://github.com/armbian/build/commit/a08cd6fe7ae9 [2]: https://forum.armbian.com/topic/3458-a64-datetime-clock-issue/ [3]: https://irclog.whitequark.org/linux-sunxi/2018-01-26 [4]: https://github.com/Allwinner-Homlet/H6-BSP4.9-linux/blob/master/driver= s/clocksource/arm_arch_timer.c#L272 Acked-by: Maxime Ripard Tested-by: Andre Przywara Signed-off-by: Samuel Holland --- Documentation/arm64/silicon-errata.txt | 2 + drivers/clocksource/Kconfig | 10 +++++ drivers/clocksource/arm_arch_timer.c | 55 ++++++++++++++++++++++++++ 3 files changed, 67 insertions(+) diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/s= ilicon-errata.txt index 8f9577621144..4a269732d2a0 100644 --- a/Documentation/arm64/silicon-errata.txt +++ b/Documentation/arm64/silicon-errata.txt @@ -44,6 +44,8 @@ stable kernels. =20 | Implementor | Component | Erratum ID | Kconfig = | +----------------+-----------------+-----------------+--------------------= ---------+ +| Allwinner | A64/R18 | UNKNOWN1 | SUN50I_ERRATUM_UNKN= OWN1 | +| | | | = | | ARM | Cortex-A53 | #826319 | ARM64_ERRATUM_82631= 9 | | ARM | Cortex-A53 | #827319 | ARM64_ERRATUM_82731= 9 | | ARM | Cortex-A53 | #824069 | ARM64_ERRATUM_82406= 9 | diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 55c77e44bb2d..d20ff4da07c3 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -364,6 +364,16 @@ config ARM64_ERRATUM_858921 The workaround will be dynamically enabled when an affected core is detected. =20 +config SUN50I_ERRATUM_UNKNOWN1 + bool "Workaround for Allwinner A64 erratum UNKNOWN1" + default y + depends on ARM_ARCH_TIMER && ARM64 && ARCH_SUNXI + select ARM_ARCH_TIMER_OOL_WORKAROUND + help + This option enables a workaround for instability in the timer on + the Allwinner A64 SoC. The workaround will only be active if the + allwinner,erratum-unknown1 property is found in the timer node. + config ARM_GLOBAL_TIMER bool "Support for the ARM global timer" if COMPILE_TEST select TIMER_OF if OF diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm= _arch_timer.c index 9a7d4dc00b6e..a8b20b65bd4b 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -326,6 +326,48 @@ static u64 notrace arm64_1188873_read_cntvct_el0(void) } #endif =20 +#ifdef CONFIG_SUN50I_ERRATUM_UNKNOWN1 +/* + * The low bits of the counter registers are indeterminate while bit 10 or + * greater is rolling over. Since the counter value can jump both backward + * (7ff -> 000 -> 800) and forward (7ff -> fff -> 800), ignore register va= lues + * with all ones or all zeros in the low bits. Bound the loop by the maxim= um + * number of CPU cycles in 3 consecutive 24 MHz counter periods. + */ +#define __sun50i_a64_read_reg(reg) ({ \ + u64 _val; \ + int _retries =3D 150; \ + \ + do { \ + _val =3D read_sysreg(reg); \ + _retries--; \ + } while (((_val + 1) & GENMASK(9, 0)) <=3D 1 && _retries); \ + \ + WARN_ON_ONCE(!_retries); \ + _val; \ +}) + +static u64 notrace sun50i_a64_read_cntpct_el0(void) +{ + return __sun50i_a64_read_reg(cntpct_el0); +} + +static u64 notrace sun50i_a64_read_cntvct_el0(void) +{ + return __sun50i_a64_read_reg(cntvct_el0); +} + +static u32 notrace sun50i_a64_read_cntp_tval_el0(void) +{ + return read_sysreg(cntp_cval_el0) - sun50i_a64_read_cntpct_el0(); +} + +static u32 notrace sun50i_a64_read_cntv_tval_el0(void) +{ + return read_sysreg(cntv_cval_el0) - sun50i_a64_read_cntvct_el0(); +} +#endif + #ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND DEFINE_PER_CPU(const struct arch_timer_erratum_workaround *, timer_unstabl= e_counter_workaround); EXPORT_SYMBOL_GPL(timer_unstable_counter_workaround); @@ -423,6 +465,19 @@ static const struct arch_timer_erratum_workaround ool_= workarounds[] =3D { .read_cntvct_el0 =3D arm64_1188873_read_cntvct_el0, }, #endif +#ifdef CONFIG_SUN50I_ERRATUM_UNKNOWN1 + { + .match_type =3D ate_match_dt, + .id =3D "allwinner,erratum-unknown1", + .desc =3D "Allwinner erratum UNKNOWN1", + .read_cntp_tval_el0 =3D sun50i_a64_read_cntp_tval_el0, + .read_cntv_tval_el0 =3D sun50i_a64_read_cntv_tval_el0, + .read_cntpct_el0 =3D sun50i_a64_read_cntpct_el0, + .read_cntvct_el0 =3D sun50i_a64_read_cntvct_el0, + .set_next_event_phys =3D erratum_set_next_event_tval_phys, + .set_next_event_virt =3D erratum_set_next_event_tval_virt, + }, +#endif }; =20 typedef bool (*ate_match_fn_t)(const struct arch_timer_erratum_workaround = *, --=20 2.19.2 --=20 You received this message because you are subscribed to the Google Groups "= linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an e= mail to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit https://groups.google.com/d/optout. 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 X-Spam-Level: X-Spam-Status: No, score=-18.6 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, MENTIONS_GIT_HOSTING,SIGNED_OFF_BY,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BB064C43387 for ; Sun, 13 Jan 2019 02:18:08 +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 87ABD20870 for ; Sun, 13 Jan 2019 02:18:08 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="crafG7dY"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=sholland.org header.i=@sholland.org header.b="mvmCKr9t"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="Upeefp0O" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 87ABD20870 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=sholland.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=dQUQoZ0HK445Sd69SbjwJYcQyzVbBeZDboYvSLP8Vdw=; b=crafG7dY4EnzgC DsGSbEccC3W+IWHZ1IT48gptWAu7uAA+F8UlCxFhZjbnIWLSyJJ45p0OPLEpGqbXcAVG1b5PKktc2 fccU3caHf3SodUNh3vGg0xGPPIpak0a3bFcU3kJ2b2HU31TCK7d8u5PPsELEX1044dKRGgelnShpT bWP3zCyZ2BsTJyX72XpZ3xDZTHA6vx0Pk+n6vuRPylDfGX0CIZrDlGFh6szWORsn0emEN+IJOPiXc qhc3Ba3yzsS7ImYjmBkrPlaQpDO15afdFm+LuEx3i0RN9ErPfdG0edtJjd95n/PA7UashuXX2b/5Q TygDejejoCnuJQ1meYBg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1giVLg-0001hn-7W; Sun, 13 Jan 2019 02:18:04 +0000 Received: from out1-smtp.messagingengine.com ([66.111.4.25]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1giVLA-0001BU-Qo for linux-arm-kernel@lists.infradead.org; Sun, 13 Jan 2019 02:17:36 +0000 Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailout.nyi.internal (Postfix) with ESMTP id 663DB23174; Sat, 12 Jan 2019 21:17:23 -0500 (EST) Received: from mailfrontend2 ([10.202.2.163]) by compute5.internal (MEProxy); Sat, 12 Jan 2019 21:17:23 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sholland.org; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type:content-transfer-encoding; s=fm1; bh= jKlMXS7XKvXn/szdGKBQgG32+kZpvO4uOo39QB1bolU=; b=mvmCKr9tLbEvZJbP pDROAd6IVm3H+tyjyvewON4VHOYfu+/+ArBujiVhfDXn37l0VEuv9+CnihXwQJz6 4joEh2OkDUy/Q32KvZzaH2GCqpcfAXUzqg4gMHL3z2eF+krzqNFd9EfXRZH4p3zO HP0pa3tHrmZHsG9mnCbzz1JaRXVli6vxQKF/5KOoxpz++tQTllf25u0GpIbfKaOx Z4eKMXxSZvDpYbsxPhgdBnlBZfvOfhsSvTgphvpKdchneqyKUYVjwO68c7ajBeK9 PGEo6YPH30QIE71YUD80IG8ZMrQOWYdlNLKocWTel4ZaJpkw4CIA1H+gnDmSKutJ VDRgYA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:references :subject:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm1; bh=jKlMXS7XKvXn/szdGKBQgG32+kZpvO4uOo39QB1bo lU=; b=Upeefp0OZATDpZxWgrtHSzR2/FFiAwyRjS0PC/HWQehfO8m3OS4/AkyP1 L96BnIrJ3Uk4WRUTblFAJvE+dJAiQeJ1WmOsJ+Dkgshp5OGZ0pUhxf/n45Ro4BuL VTC4QqUzoYnFC/ut2gfaL91yRN5tZmU+2ik5O+8E1vvF/IwhZcLDw6tcR/JX6Ixa X+EWoETX3GQC1Dbwzf9yMctarPw5mxJ8ERUyGHtDuFyzr0v0ReMlCfWqdBd0Ekca /EA5D9Um8kl6S9wVk6XgFvZm2vyzRIhfmLQqoEzcCKywrMv2qiCquAYqWMUFIdM+ 3TkvJqkWkNjRz6J6Dbd2i15CpL/Sw== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedtledrfeekgdduvdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfhuthenuceurghilhhouhhtmecufedt tdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujfgurhephffvufffkffojg hfgggtgfesthekredtredtjeenucfhrhhomhepufgrmhhuvghlucfjohhllhgrnhguuceo shgrmhhuvghlsehshhholhhlrghnugdrohhrgheqnecuffhomhgrihhnpegrrhhmsghirg hnrdgtohhmpdhgihhthhhusgdrtghomhdpfihhihhtvghquhgrrhhkrdhorhhgnecukfhp peejtddrudefhedrudegkedrudehudenucfrrghrrghmpehmrghilhhfrhhomhepshgrmh huvghlsehshhholhhlrghnugdrohhrghenucevlhhushhtvghrufhiiigvpedt X-ME-Proxy: Received: from titanium.stl.sholland.net (70-135-148-151.lightspeed.stlsmo.sbcglobal.net [70.135.148.151]) by mail.messagingengine.com (Postfix) with ESMTPA id 6F2A31026D; Sat, 12 Jan 2019 21:17:21 -0500 (EST) From: Samuel Holland To: Catalin Marinas , Will Deacon , Maxime Ripard , Chen-Yu Tsai , Rob Herring , Mark Rutland , Daniel Lezcano , Thomas Gleixner , Marc Zyngier Subject: [PATCH v3 1/2] arm64: arch_timer: Workaround for Allwinner A64 timer instability Date: Sat, 12 Jan 2019 20:17:18 -0600 Message-Id: <20190113021719.46457-2-samuel@sholland.org> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20190113021719.46457-1-samuel@sholland.org> References: <20190113021719.46457-1-samuel@sholland.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190112_181733_065120_A96E9A2B X-CRM114-Status: GOOD ( 19.89 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, linux-sunxi@googlegroups.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Samuel Holland Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org VGhlIEFsbHdpbm5lciBBNjQgU29DIGlzIGtub3duWzFdIHRvIGhhdmUgYW4gdW5zdGFibGUgYXJj aGl0ZWN0dXJhbAp0aW1lciwgd2hpY2ggbWFuaWZlc3RzIGl0c2VsZiBtb3N0IG9idmlvdXNseSBp biB0aGUgdGltZSBqdW1waW5nIGZvcndhcmQKYSBtdWx0aXBsZSBvZiA5NSB5ZWFyc1syXVszXS4g VGhpcyBjb2luY2lkZXMgd2l0aCAyXjU2IGN5Y2xlcyBhdCBhCnRpbWVyIGZyZXF1ZW5jeSBvZiAy NCBNSHosIGltcGx5aW5nIHRoYXQgdGhlIHRpbWUgd2VudCBzbGlnaHRseSBiYWNrd2FyZAooYW5k IHRoaXMgd2FzIGludGVycHJldGVkIGJ5IHRoZSBrZXJuZWwgYXMgaXQganVtcGluZyBmb3J3YXJk IGFuZAp3cmFwcGluZyBhcm91bmQgcGFzdCB0aGUgZXBvY2gpLgoKSW52ZXN0aWdhdGlvbiByZXZl YWxlZCBpbnN0YWJpbGl0eSBpbiB0aGUgbG93IGJpdHMgb2YgQ05UVkNUIGF0IHRoZQpwb2ludCBh IGhpZ2ggYml0IHJvbGxzIG92ZXIuIFRoaXMgbGVhZHMgdG8gcG93ZXItb2YtdHdvIGN5Y2xlIGZv cndhcmQKYW5kIGJhY2t3YXJkIGp1bXBzLiAoVGVzdGluZyBzaG93cyB0aGF0IGZvcndhcmQganVt cHMgYXJlIGFib3V0IHR3aWNlIGFzCmxpa2VseSBhcyBiYWNrd2FyZCBqdW1wcy4pIFNpbmNlIHRo ZSBjb3VudGVyIHZhbHVlIHJldHVybnMgdG8gbm9ybWFsCmFmdGVyIGFuIGluZGV0ZXJtaW5hdGUg cmVhZCwgZWFjaCAianVtcCIgcmVhbGx5IGNvbnNpc3RzIG9mIGJvdGggYQpmb3J3YXJkIGFuZCBi YWNrd2FyZCBqdW1wIGZyb20gdGhlIHNvZnR3YXJlIHBlcnNwZWN0aXZlLgoKVW5sZXNzIHRoZSBr ZXJuZWwgaXMgdHJhcHBpbmcgQ05UVkNUIHJlYWRzLCBhIHVzZXJzcGFjZSBwcm9ncmFtIGlzIGFi bGUKdG8gcmVhZCB0aGUgcmVnaXN0ZXIgaW4gYSBsb29wIGZhc3RlciB0aGFuIGl0IGNoYW5nZXMu IEEgdGVzdCBwcm9ncmFtCnJ1bm5pbmcgb24gYWxsIDQgQ1BVIGNvcmVzIHRoYXQgcmVwb3J0ZWQg anVtcHMgbGFyZ2VyIHRoYW4gMTAwIG1zIHdhcwpydW4gZm9yIDEzLjYgaG91cnMgYW5kIHJlcG9y dGVkIHRoZSBmb2xsb3dpbmc6CgogQ291bnQgfCBFdmVudAotLS0tLS0tKy0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLQogIDk5NDAgfCBqdW1wZWQgYmFja3dhcmQgICAgICA2OTltcwogICAyNjgg fCBqdW1wZWQgYmFja3dhcmQgICAgIDEzOThtcwogICAgIDEgfCBqdW1wZWQgYmFja3dhcmQgICAg IDIwOTdtcwogMTYwMjAgfCBqdW1wZWQgZm9yd2FyZCAgICAgICAxNzVtcwogIDY0NDMgfCBqdW1w ZWQgZm9yd2FyZCAgICAgICA2OTltcwogIDI5NzYgfCBqdW1wZWQgZm9yd2FyZCAgICAgIDEzOTht cwogICAgIDkgfCBqdW1wZWQgZm9yd2FyZCAgICAzNTY1MTZtcwogICAgIDkgfCBqdW1wZWQgZm9y d2FyZCAgICAzNTcyMTVtcwogICAgIDQgfCBqdW1wZWQgZm9yd2FyZCAgICA3MTQ0MzBtcwogICAg IDEgfCBqdW1wZWQgZm9yd2FyZCAgIDM1Nzg0NDBtcwoKVGhpcyB3b3JrcyBvdXQgdG8gYSBqdW1w IGxhcmdlciB0aGFuIDEwMCBtcyBhYm91dCBldmVyeSA1LjUgc2Vjb25kcyBvbgplYWNoIENQVSBj b3JlLgoKVGhlIGxhcmdlc3QganVtcCAoYWxtb3N0IGFuIGhvdXIhKSB3YXMgdGhlIGZvbGxvd2lu ZyBzZXF1ZW5jZSBvZiByZWFkczoKICAgIDB4MDAwMDAwN2ZmZmZmZmZmZiDihpIgMHgwMDAwMDA5 M2ZlZmZmZmZmIOKGkiAweDAwMDAwMDgwMDAwMDAwMDAKCk5vdGUgdGhhdCB0aGUgbWlkZGxlIGJp dHMgZG9uJ3QgbmVjZXNzYXJpbHkgYWxsIHJlYWQgYXMgYWxsIHplcm9lcyBvcgphbGwgb25lcyBk dXJpbmcgdGhlIGFub21hbG91cyBiZWhhdmlvcjsgaG93ZXZlciB0aGUgbG93IDEwIGJpdHMgY2hl Y2tlZApieSB0aGUgZnVuY3Rpb24gaW4gdGhpcyBwYXRjaCBoYXZlIG5ldmVyIGJlZW4gb2JzZXJ2 ZWQgd2l0aCBhbnkgb3RoZXIKdmFsdWUuCgpBbHNvIG5vdGUgdGhhdCBzbWFsbGVyIGp1bXBzIGFy ZSBtdWNoIG1vcmUgY29tbW9uLCB3aXRoIGJhY2t3YXJkIGp1bXBzCm9mIDIwNDggKDJeMTEpIGN5 Y2xlcyBvYnNlcnZlZCBvdmVyIDQwMCB0aW1lcyBwZXIgc2Vjb25kIG9uIGVhY2ggY29yZS4KKE9m IGNvdXJzZSwgdGhpcyBpcyBwYXJ0aWFsbHkgZXhwbGFpbmVkIGJ5IGxvd2VyIGJpdHMgcm9sbGlu ZyBvdmVyIG1vcmUKZnJlcXVlbnRseS4pIEFueSBvbmUgb2YgdGhlc2UgY291bGQgaGF2ZSBjYXVz ZWQgdGhlIDk1IHllYXIgdGltZSBza2lwLgoKU2ltaWxhciBhbm9tYWxpZXMgd2VyZSBvYnNlcnZl ZCB3aGlsZSByZWFkaW5nIENOVFBDVCAoYWZ0ZXIgcGF0Y2hpbmcgdGhlCmtlcm5lbCB0byBhbGxv dyByZWFkcyBmcm9tIHVzZXJzcGFjZSkuIEhvd2V2ZXIsIHRoZSBDTlRQQ1QganVtcHMgYXJlCm11 Y2ggbGVzcyBmcmVxdWVudCwgYW5kIG9ubHkgc21hbGwganVtcHMgd2VyZSBvYnNlcnZlZC4gVGhl IHNhbWUgcHJvZ3JhbQphcyBiZWZvcmUgKGV4Y2VwdCBub3cgcmVhZGluZyBDTlRQQ1QpIG9ic2Vy dmVkIGFmdGVyIDcyIGhvdXJzOgoKIENvdW50IHwgRXZlbnQKLS0tLS0tLSstLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0KICAgIDE3IHwganVtcGVkIGJhY2t3YXJkICAgICAgNjk5bXMKICAgIDUy IHwganVtcGVkIGZvcndhcmQgICAgICAgMTc1bXMKICAyODMxIHwganVtcGVkIGZvcndhcmQgICAg ICAgNjk5bXMKICAgICA1IHwganVtcGVkIGZvcndhcmQgICAgICAxMzk4bXMKCkZ1cnRoZXIgaW52 ZXN0aWdhdGlvbiBzaG93ZWQgdGhhdCB0aGUgaW5zdGFiaWxpdHkgaW4gQ05UUENUL0NOVFZDVCBh bHNvCmFmZmVjdGVkIHRoZSByZXNwZWN0aXZlIHRpbWVyJ3MgVFZBTCByZWdpc3Rlci4gVGhlIGZv bGxvd2luZyB2YWx1ZXMgd2VyZQpvYnNlcnZlZCBpbW1lZGlhdGVseSBhZnRlciB3cml0aW5nIENO VlRfVFZBTCB0byAweDEwMDAwMDAwOgoKIENOVFZDVCAgICAgICAgICAgICB8IENOVFZfVFZBTCAg fCBDTlRWX0NWQUwgICAgICAgICAgfCBDTlRWX1RWQUwgRXJyb3IKLS0tLS0tLS0tLS0tLS0tLS0t LS0rLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tCiAw eDAwMDAwMGQ0YTJkOGJmZmYgfCAweDEwMDAzZmZmIHwgMHgwMDAwMDBkNGIyZDhiZmZmIHwgKzB4 MDAwMDQwMDAKIDB4MDAwMDAwZDRhMmQ5NDAwMCB8IDB4MGZmZmZmZmYgfCAweDAwMDAwMGQ0YjJk OTdmZmYgfCAtMHgwMDAwNDAwMAogMHgwMDAwMDBkNGEyZDk3ZmZmIHwgMHgxMDAwM2ZmZiB8IDB4 MDAwMDAwZDRiMmQ5N2ZmZiB8ICsweDAwMDA0MDAwCiAweDAwMDAwMGQ0YTJkOWMwMDAgfCAweDBm ZmZmZmZmIHwgMHgwMDAwMDBkNGIyZDlmZmZmIHwgLTB4MDAwMDQwMDAKClRoZSBwYXR0ZXJuIG9m IGVycm9ycyBpbiBDTlRWX1RWQUwgc2VlbWVkIHRvIGRlcGVuZCBvbiBleGFjdGx5IHdoaWNoCnZh bHVlIHdhcyB3cml0dGVuIHRvIGl0LiBGb3IgZXhhbXBsZSwgYWZ0ZXIgd3JpdGluZyAweDEwMTAx MDEwOgoKIENOVFZDVCAgICAgICAgICAgICB8IENOVFZfVFZBTCAgfCBDTlRWX0NWQUwgICAgICAg ICAgfCBDTlRWX1RWQUwgRXJyb3IKLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tKy0t LS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tCiAweDAwMDAwMWFjM2VmZmZmZmYg fCAweDExMTAxMDBmIHwgMHgwMDAwMDFhYzRmMTAxMDBmIHwgKzB4MTAwMDAwMAogMHgwMDAwMDFh YzQwMDAwMDAwIHwgMHgxMDEwMTAwZiB8IDB4MDAwMDAxYWM1MTEwMTAwZiB8IC0weDEwMDAwMDAK IDB4MDAwMDAxYWM1OGZmZmZmZiB8IDB4MTExMDEwMGYgfCAweDAwMDAwMWFjNjkxMDEwMGYgfCAr MHgxMDAwMDAwCiAweDAwMDAwMWFjNjYwMDAwMDAgfCAweDEwMTAxMDBmIHwgMHgwMDAwMDFhYzc3 MTAxMDBmIHwgLTB4MTAwMDAwMAogMHgwMDAwMDFhYzZhZmZmZmZmIHwgMHgxMTEwMTAwZiB8IDB4 MDAwMDAxYWM3YjEwMTAwZiB8ICsweDEwMDAwMDAKIDB4MDAwMDAxYWM2ZTAwMDAwMCB8IDB4MTAx MDEwMGYgfCAweDAwMDAwMWFjN2YxMDEwMGYgfCAtMHgxMDAwMDAwCgpJIHdhcyBhbHNvIHR3aWNl IGFibGUgdG8gcmVwcm9kdWNlIHRoZSBpc3N1ZSBjb3ZlcmVkIGJ5IEFsbHdpbm5lcidzCndvcmth cm91bmRbNF0sIHRoYXQgd3JpdGluZyB0byBUVkFMIHNvbWV0aW1lcyBmYWlscywgYW5kIGJvdGgg Q1ZBTCBhbmQKVFZBTCBhcmUgbGVmdCB3aXRoIGVudGlyZWx5IGJvZ3VzIHZhbHVlcy4gT25lIHdh cyB0aGUgZm9sbG93aW5nIHZhbHVlczoKCiBDTlRWQ1QgICAgICAgICAgICAgfCBDTlRWX1RWQUwg IHwgQ05UVl9DVkFMCi0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLSstLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogMHgwMDAwMDBkNGEyZDYwMTRjIHwgMHg4ZmJk NTcyMSB8IDB4MDAwMDAwZDEzMjkzNWZmZiAoNjE1cyBpbiB0aGUgcGFzdCkKCj09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09 PT09PQoKQmVjYXVzZSB0aGUgQ1BVIGNhbiByZWFkIHRoZSBDTlRQQ1QvQ05UVkNUIHJlZ2lzdGVy cyBmYXN0ZXIgdGhhbiB0aGV5CmNoYW5nZSwgcGVyZm9ybWluZyB0d28gcmVhZHMgb2YgdGhlIHJl Z2lzdGVyIGFuZCBjb21wYXJpbmcgdGhlIGhpZ2ggYml0cwoobGlrZSBvdGhlciB3b3JrYXJvdW5k cykgaXMgbm90IGEgd29ya2FibGUgc29sdXRpb24uIEFuZCBiZWNhdXNlIHRoZQp0aW1lciBjYW4g anVtcCBib3RoIGZvcndhcmQgYW5kIGJhY2t3YXJkLCBubyBwYWlyIG9mIHJlYWRzIGNhbgpkaXN0 aW5ndWlzaCBhIGdvb2QgdmFsdWUgZnJvbSBhIGJhZCBvbmUuIFRoZSBvbmx5IHdheSB0byBndWFy YW50ZWUgYQpnb29kIHZhbHVlIGZyb20gY29uc2VjdXRpdmUgcmVhZHMgd291bGQgYmUgdG8gcmVh ZCBfdGhyZWVfIHRpbWVzLCBhbmQKdGFrZSB0aGUgbWlkZGxlIHZhbHVlIG9ubHkgaWYgdGhlIHRo cmVlIHZhbHVlcyBhcmUgMSkgZWFjaCB1bmlxdWUgYW5kCjIpIGluY3JlYXNpbmcuIFRoaXMgdGFr ZXMgYXQgbWluaW11bSAzIGNvdW50ZXIgY3ljbGVzICgxMjUgbnMpLCBvciBtb3JlCmlmIGFuIGFu b21hbHkgaXMgZGV0ZWN0ZWQuCgpIb3dldmVyLCBzaW5jZSB0aGVyZSBpcyBhIGRpc3RpbmN0IHBh dHRlcm4gdG8gdGhlIGJhZCB2YWx1ZXMsIHdlIGNhbgpvcHRpbWl6ZSB0aGUgY29tbW9uIGNhc2Ug KDEwMjIvMTAyNCBvZiB0aGUgdGltZSkgdG8gYSBzaW5nbGUgcmVhZCBieQpzaW1wbHkgaWdub3Jp bmcgdmFsdWVzIHRoYXQgbWF0Y2ggdGhlIGVycm9yIHBhdHRlcm4uIFRoaXMgc3RpbGwgdGFrZXMg bm8KbW9yZSB0aGFuIDMgY3ljbGVzIGluIHRoZSB3b3JzdCBjYXNlLCBhbmQgcmVxdWlyZXMgbXVj aCBsZXNzIGNvZGUuIEFzIGFuCmFkZGl0aW9uYWwgc2FmZXR5IGNoZWNrLCB3ZSBzdGlsbCBsaW1p dCB0aGUgbG9vcCBpdGVyYXRpb24gdG8gdGhlIG51bWJlcgpvZiBtYXgtZnJlcXVlbmN5ICgxLjIg R0h6KSBDUFUgY3ljbGVzIGluIHRocmVlIDI0IE1IeiBjb3VudGVyIHBlcmlvZHMuCgpGb3IgdGhl IFRWQUwgcmVnaXN0ZXJzLCB0aGUgc2ltcGxlIHNvbHV0aW9uIGlzIHRvIG5vdCB1c2UgdGhlbS4g SW5zdGVhZCwKcmVhZCBvciB3cml0ZSB0aGUgQ1ZBTCBhbmQgY2FsY3VsYXRlIHRoZSBUVkFMIHZh bHVlIGluIHNvZnR3YXJlLgoKQWx0aG91Z2ggdGhlIG1hbnVmYWN0dXJlciBpcyBhd2FyZSBvZiBh dCBsZWFzdCBwYXJ0IG9mIHRoZSBlcnJhdHVtWzRdLAp0aGVyZSBpcyBubyBvZmZpY2lhbCBuYW1l IGZvciBpdC4gRm9yIG5vdywgdXNlIHRoZSBrZXJuZWwtaW50ZXJuYWwgbmFtZQoiVU5LTk9XTjEi LgoKWzFdOiBodHRwczovL2dpdGh1Yi5jb20vYXJtYmlhbi9idWlsZC9jb21taXQvYTA4Y2Q2ZmU3 YWU5ClsyXTogaHR0cHM6Ly9mb3J1bS5hcm1iaWFuLmNvbS90b3BpYy8zNDU4LWE2NC1kYXRldGlt ZS1jbG9jay1pc3N1ZS8KWzNdOiBodHRwczovL2lyY2xvZy53aGl0ZXF1YXJrLm9yZy9saW51eC1z dW54aS8yMDE4LTAxLTI2Cls0XTogaHR0cHM6Ly9naXRodWIuY29tL0FsbHdpbm5lci1Ib21sZXQv SDYtQlNQNC45LWxpbnV4L2Jsb2IvbWFzdGVyL2RyaXZlcnMvY2xvY2tzb3VyY2UvYXJtX2FyY2hf dGltZXIuYyNMMjcyCgpBY2tlZC1ieTogTWF4aW1lIFJpcGFyZCA8bWF4aW1lLnJpcGFyZEBib290 bGluLmNvbT4KVGVzdGVkLWJ5OiBBbmRyZSBQcnp5d2FyYSA8YW5kcmUucHJ6eXdhcmFAYXJtLmNv bT4KU2lnbmVkLW9mZi1ieTogU2FtdWVsIEhvbGxhbmQgPHNhbXVlbEBzaG9sbGFuZC5vcmc+Ci0t LQogRG9jdW1lbnRhdGlvbi9hcm02NC9zaWxpY29uLWVycmF0YS50eHQgfCAgMiArCiBkcml2ZXJz L2Nsb2Nrc291cmNlL0tjb25maWcgICAgICAgICAgICB8IDEwICsrKysrCiBkcml2ZXJzL2Nsb2Nr c291cmNlL2FybV9hcmNoX3RpbWVyLmMgICB8IDU1ICsrKysrKysrKysrKysrKysrKysrKysrKysr CiAzIGZpbGVzIGNoYW5nZWQsIDY3IGluc2VydGlvbnMoKykKCmRpZmYgLS1naXQgYS9Eb2N1bWVu dGF0aW9uL2FybTY0L3NpbGljb24tZXJyYXRhLnR4dCBiL0RvY3VtZW50YXRpb24vYXJtNjQvc2ls aWNvbi1lcnJhdGEudHh0CmluZGV4IDhmOTU3NzYyMTE0NC4uNGEyNjk3MzJkMmEwIDEwMDY0NAot LS0gYS9Eb2N1bWVudGF0aW9uL2FybTY0L3NpbGljb24tZXJyYXRhLnR4dAorKysgYi9Eb2N1bWVu dGF0aW9uL2FybTY0L3NpbGljb24tZXJyYXRhLnR4dApAQCAtNDQsNiArNDQsOCBAQCBzdGFibGUg a2VybmVscy4KIAogfCBJbXBsZW1lbnRvciAgICB8IENvbXBvbmVudCAgICAgICB8IEVycmF0dW0g SUQgICAgICB8IEtjb25maWcgICAgICAgICAgICAgICAgICAgICB8CiArLS0tLS0tLS0tLS0tLS0t LSstLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLSsKK3wgQWxsd2lubmVyICAgICAgfCBBNjQvUjE4ICAgICAgICAgfCBVTktOT1dO MSAgICAgICAgfCBTVU41MElfRVJSQVRVTV9VTktOT1dOMSAgICAgfAorfCAgICAgICAgICAgICAg ICB8ICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAg ICAgICAgICAgICB8CiB8IEFSTSAgICAgICAgICAgIHwgQ29ydGV4LUE1MyAgICAgIHwgIzgyNjMx OSAgICAgICAgIHwgQVJNNjRfRVJSQVRVTV84MjYzMTkgICAgICAgIHwKIHwgQVJNICAgICAgICAg ICAgfCBDb3J0ZXgtQTUzICAgICAgfCAjODI3MzE5ICAgICAgICAgfCBBUk02NF9FUlJBVFVNXzgy NzMxOSAgICAgICAgfAogfCBBUk0gICAgICAgICAgICB8IENvcnRleC1BNTMgICAgICB8ICM4MjQw NjkgICAgICAgICB8IEFSTTY0X0VSUkFUVU1fODI0MDY5ICAgICAgICB8CmRpZmYgLS1naXQgYS9k cml2ZXJzL2Nsb2Nrc291cmNlL0tjb25maWcgYi9kcml2ZXJzL2Nsb2Nrc291cmNlL0tjb25maWcK aW5kZXggNTVjNzdlNDRiYjJkLi5kMjBmZjRkYTA3YzMgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvY2xv Y2tzb3VyY2UvS2NvbmZpZworKysgYi9kcml2ZXJzL2Nsb2Nrc291cmNlL0tjb25maWcKQEAgLTM2 NCw2ICszNjQsMTYgQEAgY29uZmlnIEFSTTY0X0VSUkFUVU1fODU4OTIxCiAJICBUaGUgd29ya2Fy b3VuZCB3aWxsIGJlIGR5bmFtaWNhbGx5IGVuYWJsZWQgd2hlbiBhbiBhZmZlY3RlZAogCSAgY29y ZSBpcyBkZXRlY3RlZC4KIAorY29uZmlnIFNVTjUwSV9FUlJBVFVNX1VOS05PV04xCisJYm9vbCAi V29ya2Fyb3VuZCBmb3IgQWxsd2lubmVyIEE2NCBlcnJhdHVtIFVOS05PV04xIgorCWRlZmF1bHQg eQorCWRlcGVuZHMgb24gQVJNX0FSQ0hfVElNRVIgJiYgQVJNNjQgJiYgQVJDSF9TVU5YSQorCXNl bGVjdCBBUk1fQVJDSF9USU1FUl9PT0xfV09SS0FST1VORAorCWhlbHAKKwkgIFRoaXMgb3B0aW9u IGVuYWJsZXMgYSB3b3JrYXJvdW5kIGZvciBpbnN0YWJpbGl0eSBpbiB0aGUgdGltZXIgb24KKwkg IHRoZSBBbGx3aW5uZXIgQTY0IFNvQy4gVGhlIHdvcmthcm91bmQgd2lsbCBvbmx5IGJlIGFjdGl2 ZSBpZiB0aGUKKwkgIGFsbHdpbm5lcixlcnJhdHVtLXVua25vd24xIHByb3BlcnR5IGlzIGZvdW5k IGluIHRoZSB0aW1lciBub2RlLgorCiBjb25maWcgQVJNX0dMT0JBTF9USU1FUgogCWJvb2wgIlN1 cHBvcnQgZm9yIHRoZSBBUk0gZ2xvYmFsIHRpbWVyIiBpZiBDT01QSUxFX1RFU1QKIAlzZWxlY3Qg VElNRVJfT0YgaWYgT0YKZGlmZiAtLWdpdCBhL2RyaXZlcnMvY2xvY2tzb3VyY2UvYXJtX2FyY2hf dGltZXIuYyBiL2RyaXZlcnMvY2xvY2tzb3VyY2UvYXJtX2FyY2hfdGltZXIuYwppbmRleCA5YTdk NGRjMDBiNmUuLmE4YjIwYjY1YmQ0YiAxMDA2NDQKLS0tIGEvZHJpdmVycy9jbG9ja3NvdXJjZS9h cm1fYXJjaF90aW1lci5jCisrKyBiL2RyaXZlcnMvY2xvY2tzb3VyY2UvYXJtX2FyY2hfdGltZXIu YwpAQCAtMzI2LDYgKzMyNiw0OCBAQCBzdGF0aWMgdTY0IG5vdHJhY2UgYXJtNjRfMTE4ODg3M19y ZWFkX2NudHZjdF9lbDAodm9pZCkKIH0KICNlbmRpZgogCisjaWZkZWYgQ09ORklHX1NVTjUwSV9F UlJBVFVNX1VOS05PV04xCisvKgorICogVGhlIGxvdyBiaXRzIG9mIHRoZSBjb3VudGVyIHJlZ2lz dGVycyBhcmUgaW5kZXRlcm1pbmF0ZSB3aGlsZSBiaXQgMTAgb3IKKyAqIGdyZWF0ZXIgaXMgcm9s bGluZyBvdmVyLiBTaW5jZSB0aGUgY291bnRlciB2YWx1ZSBjYW4ganVtcCBib3RoIGJhY2t3YXJk CisgKiAoN2ZmIC0+IDAwMCAtPiA4MDApIGFuZCBmb3J3YXJkICg3ZmYgLT4gZmZmIC0+IDgwMCks IGlnbm9yZSByZWdpc3RlciB2YWx1ZXMKKyAqIHdpdGggYWxsIG9uZXMgb3IgYWxsIHplcm9zIGlu IHRoZSBsb3cgYml0cy4gQm91bmQgdGhlIGxvb3AgYnkgdGhlIG1heGltdW0KKyAqIG51bWJlciBv ZiBDUFUgY3ljbGVzIGluIDMgY29uc2VjdXRpdmUgMjQgTUh6IGNvdW50ZXIgcGVyaW9kcy4KKyAq LworI2RlZmluZSBfX3N1bjUwaV9hNjRfcmVhZF9yZWcocmVnKSAoewkJCQkJXAorCXU2NCBfdmFs OwkJCQkJCQlcCisJaW50IF9yZXRyaWVzID0gMTUwOwkJCQkJCVwKKwkJCQkJCQkJCVwKKwlkbyB7 CQkJCQkJCQlcCisJCV92YWwgPSByZWFkX3N5c3JlZyhyZWcpOwkJCQlcCisJCV9yZXRyaWVzLS07 CQkJCQkJXAorCX0gd2hpbGUgKCgoX3ZhbCArIDEpICYgR0VOTUFTSyg5LCAwKSkgPD0gMSAmJiBf cmV0cmllcyk7CVwKKwkJCQkJCQkJCVwKKwlXQVJOX09OX09OQ0UoIV9yZXRyaWVzKTsJCQkJCVwK KwlfdmFsOwkJCQkJCQkJXAorfSkKKworc3RhdGljIHU2NCBub3RyYWNlIHN1bjUwaV9hNjRfcmVh ZF9jbnRwY3RfZWwwKHZvaWQpCit7CisJcmV0dXJuIF9fc3VuNTBpX2E2NF9yZWFkX3JlZyhjbnRw Y3RfZWwwKTsKK30KKworc3RhdGljIHU2NCBub3RyYWNlIHN1bjUwaV9hNjRfcmVhZF9jbnR2Y3Rf ZWwwKHZvaWQpCit7CisJcmV0dXJuIF9fc3VuNTBpX2E2NF9yZWFkX3JlZyhjbnR2Y3RfZWwwKTsK K30KKworc3RhdGljIHUzMiBub3RyYWNlIHN1bjUwaV9hNjRfcmVhZF9jbnRwX3R2YWxfZWwwKHZv aWQpCit7CisJcmV0dXJuIHJlYWRfc3lzcmVnKGNudHBfY3ZhbF9lbDApIC0gc3VuNTBpX2E2NF9y ZWFkX2NudHBjdF9lbDAoKTsKK30KKworc3RhdGljIHUzMiBub3RyYWNlIHN1bjUwaV9hNjRfcmVh ZF9jbnR2X3R2YWxfZWwwKHZvaWQpCit7CisJcmV0dXJuIHJlYWRfc3lzcmVnKGNudHZfY3ZhbF9l bDApIC0gc3VuNTBpX2E2NF9yZWFkX2NudHZjdF9lbDAoKTsKK30KKyNlbmRpZgorCiAjaWZkZWYg Q09ORklHX0FSTV9BUkNIX1RJTUVSX09PTF9XT1JLQVJPVU5ECiBERUZJTkVfUEVSX0NQVShjb25z dCBzdHJ1Y3QgYXJjaF90aW1lcl9lcnJhdHVtX3dvcmthcm91bmQgKiwgdGltZXJfdW5zdGFibGVf Y291bnRlcl93b3JrYXJvdW5kKTsKIEVYUE9SVF9TWU1CT0xfR1BMKHRpbWVyX3Vuc3RhYmxlX2Nv dW50ZXJfd29ya2Fyb3VuZCk7CkBAIC00MjMsNiArNDY1LDE5IEBAIHN0YXRpYyBjb25zdCBzdHJ1 Y3QgYXJjaF90aW1lcl9lcnJhdHVtX3dvcmthcm91bmQgb29sX3dvcmthcm91bmRzW10gPSB7CiAJ CS5yZWFkX2NudHZjdF9lbDAgPSBhcm02NF8xMTg4ODczX3JlYWRfY250dmN0X2VsMCwKIAl9LAog I2VuZGlmCisjaWZkZWYgQ09ORklHX1NVTjUwSV9FUlJBVFVNX1VOS05PV04xCisJeworCQkubWF0 Y2hfdHlwZSA9IGF0ZV9tYXRjaF9kdCwKKwkJLmlkID0gImFsbHdpbm5lcixlcnJhdHVtLXVua25v d24xIiwKKwkJLmRlc2MgPSAiQWxsd2lubmVyIGVycmF0dW0gVU5LTk9XTjEiLAorCQkucmVhZF9j bnRwX3R2YWxfZWwwID0gc3VuNTBpX2E2NF9yZWFkX2NudHBfdHZhbF9lbDAsCisJCS5yZWFkX2Nu dHZfdHZhbF9lbDAgPSBzdW41MGlfYTY0X3JlYWRfY250dl90dmFsX2VsMCwKKwkJLnJlYWRfY250 cGN0X2VsMCA9IHN1bjUwaV9hNjRfcmVhZF9jbnRwY3RfZWwwLAorCQkucmVhZF9jbnR2Y3RfZWww ID0gc3VuNTBpX2E2NF9yZWFkX2NudHZjdF9lbDAsCisJCS5zZXRfbmV4dF9ldmVudF9waHlzID0g ZXJyYXR1bV9zZXRfbmV4dF9ldmVudF90dmFsX3BoeXMsCisJCS5zZXRfbmV4dF9ldmVudF92aXJ0 ID0gZXJyYXR1bV9zZXRfbmV4dF9ldmVudF90dmFsX3ZpcnQsCisJfSwKKyNlbmRpZgogfTsKIAog dHlwZWRlZiBib29sICgqYXRlX21hdGNoX2ZuX3QpKGNvbnN0IHN0cnVjdCBhcmNoX3RpbWVyX2Vy cmF0dW1fd29ya2Fyb3VuZCAqLAotLSAKMi4xOS4yCgoKX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX18KbGludXgtYXJtLWtlcm5lbCBtYWlsaW5nIGxpc3QKbGlu dXgtYXJtLWtlcm5lbEBsaXN0cy5pbmZyYWRlYWQub3JnCmh0dHA6Ly9saXN0cy5pbmZyYWRlYWQu b3JnL21haWxtYW4vbGlzdGluZm8vbGludXgtYXJtLWtlcm5lbAo=