From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (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 8476630504D for ; Wed, 19 Nov 2025 09:50:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763545806; cv=none; b=bA9HMPXWVTN5iCyxWoS+SWJb183WDoklTDpgn2LyNSlhDTqD3Bl7K2lEEbQ7Iu4ENe1FLBpajxmPs/Nd3bw0amiO5UPZbmtj2goUwKPim6WYSZHhv49VbB5160zaeT/gG0OXh63A0JgaE3MyFXnwSQPS1ZuUZp/Qb2EmPiv2Ws0= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763545806; c=relaxed/simple; bh=1TOp3TyNqp9fvTognm5EaBymbRnEbazC0vxgnfiwNVQ=; h=From:To:Cc:Subject:In-Reply-To:References:Date:Message-ID: MIME-Version:Content-Type; b=eXbb9ZEjut/8kG9AsapwaDTiDpGNQoZNW0ocbbvDL1RIpaqbzd5C62GNMaZCJ9/XMCtOr7Hb+R3ZfWZVIcrdVp6MulmrQoXUciIFi6+eJgeNxqKwIw8su6Yk6smP3BTyXaTtjI5PgO+harr5ojnu74601Ht6TuskwFCvNNdBdq8= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=NDCz8PCM; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="NDCz8PCM" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id BB6904E41794; Wed, 19 Nov 2025 09:50:02 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 9190460720; Wed, 19 Nov 2025 09:50:02 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id D22C810371A18; Wed, 19 Nov 2025 10:49:58 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1763545802; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=RrIjwcjwliZ95lPsOv8XtZAnAsO3R4A3FRoqGR2mI7g=; b=NDCz8PCM2Nkvg9vaH8fUswy6MvH7QqLHVik27q6zknsVFM3ymgUpBZoCgJOm3wK4ZhAvGg IbY1ET4w44no3ZXy7ziwRYbdlBgyco0O7Sq/IK60yIV8hgvnpPnPeZmINbccHHKHzybi8k /nY8hhDhJUO7g179uU9lCQl8ZQqNgkWOYWz6K+L9VIZjeToDsdIoP1wCzJq0MwSmgo+9LI eQp15tOtt4ArbVhjuRMpiufS0+OM/LZIo2KCHbJNDFl8XoT86W1sGRrIR/vuaOV75KObXw 4kUzbJZCtxN7c5WTJ2Q9VLPgGp81MQXYdBYFXxpQGi3ojTo9JTbuQE3ntc5/pg== From: Miquel Raynal To: "Michael Walle" Cc: "Tudor Ambarus" , "Pratyush Yadav" , "Richard Weinberger" , "Vignesh Raghavendra" , "Jonathan Corbet" , "Sean Anderson" , "Thomas Petazzoni" , "Steam Lin" , , , Subject: Re: [PATCH 15/19] mtd: spi-nor: debugfs: Add locking support In-Reply-To: (Michael Walle's message of "Tue, 18 Nov 2025 13:46:52 +0100") References: <20251114-winbond-v6-18-rc1-spi-nor-swp-v1-0-487bc7129931@bootlin.com> <20251114-winbond-v6-18-rc1-spi-nor-swp-v1-15-487bc7129931@bootlin.com> User-Agent: mu4e 1.12.7; emacs 30.2 Date: Wed, 19 Nov 2025 10:49:57 +0100 Message-ID: <87o6oycpx6.fsf@bootlin.com> Precedence: bulk X-Mailing-List: linux-doc@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Hello, On 18/11/2025 at 13:46:52 +01, "Michael Walle" wrote: > On Fri Nov 14, 2025 at 6:53 PM CET, Miquel Raynal wrote: >> The ioctl output may be counter intuitive in some cases. Asking for a >> "locked status" over a region that is only partially locked will return >> "unlocked" whereas in practice maybe the biggest part is actually >> locked. >> >> Knowing what is the real software locking state through debugfs would be >> very convenient for development/debugging purposes, hence this proposal >> for adding two extra blocks at the end of the file: >> - A "software locked sectors" array which lists every section, if it is >> locked or not, showing both the address ranges and the sizes in numbers >> of blocks. > > I know the file is called software write protection (or swp) but > it's really a hardware write protection, isn't it? Well, it depends on your configuration I guess? Without #WP pin I don't know how to call that. I had in mind that software meant "using the BP pins" and "hardware" meant "toggling #WP". But I have no strong opinion about this wording. >> - Some kind of mapping of the locked sectors, which pictures the entire >> flash. It may be verbose, so perhaps we'll drop it in the end. I found >> it very useful to really get a clearer mental model of what was >> locked/unlocked, but the array just before is already a good source of >> information. >> >> Here is an example of output, what is after the "sector map" is new. >> >> $ cat /sys/kernel/debug/spi-nor/spi0.0/params >> name (null) >> id ef a0 20 00 00 00 >> size 64.0 MiB >> write size 1 >> page size 256 >> address nbytes 4 >> flags HAS_SR_TB | 4B_OPCODES | HAS_4BAIT | HAS_LOCK | HAS_16BIT_SR | HA= S_SR_TB_BIT6 | HAS_4BIT_BP | SOFT_RESET | NO_WP >> >> opcodes >> read 0xec >> dummy cycles 6 >> erase 0xdc >> program 0x34 >> 8D extension none >> >> protocols >> read 1S-4S-4S >> write 1S-1S-4S >> register 1S-1S-1S >> >> erase commands >> 21 (4.00 KiB) [1] >> dc (64.0 KiB) [3] >> c7 (64.0 MiB) >> >> sector map >> region (in hex) | erase mask | overlaid >> ------------------+------------+--------- >> 00000000-03ffffff | [ 3] | no >> >> software locked sectors > > drop "software" here. Okay. > >> region (in hex) | status | #blocks >> ------------------+----------+-------- >> 00000000-03ffffff | unlocked | 1024 > > I really like that. :-) >> 64kiB-sectors locking map (x: locked, .: unlocked) >> |.......................................................................= ...........................................................................= ...........................................................................= ...........................................................................= ...........................................................................= ...........................................................................= ...........................................................................= ...........................................................................= ...........................................................................= ...........................................................................= ...........................................................................= ...........................................................................= ...........................................................................= .......................... >> ...........................| > > Maybe put it into an own file. In any case, a sane line wrapping > would be good. And add a leading offset, ie, "0000: xxxx.....". I was unsure about doing that, but yes that makes sense. May I call it "locked_sectors_map"? [...] >> + sr[0] =3D nor->bouncebuf[0]; >> + >> + if (!(nor->flags & SNOR_F_NO_READ_CR)) { >> + ret =3D spi_nor_read_cr(nor, nor->bouncebuf + 1); >> + if (ret) >> + return ret; >> + } >> + >> + sr[1] =3D nor->bouncebuf[1]; > > Shouldn't that go into the former if conditional? bouncebuf[1] might > never be read. Yes, that's correct. I don't remember why I did it this way, probably a bug, I'll move that line. > Also, until now, reading the "params" debug file never interacts > with the flash, but with this patch it does. We don't do locking > here which looks wrong. Maybe we should just cache the protection > bits. Not sure. I guess caching the status registers makes sense, but we'll still have a possible race when accessing the 2 registers. Is it okay to ignore this very unlikely case in debugfs? Otherwise I might just lock the entire device for the time we access the cached registers. >> + spi_nor_get_locked_range_sr(nor, sr, &lock_start, &lock_length); >> + if (!lock_length || lock_length =3D=3D params->size) { >> + seq_printf(s, " %08llx-%08llx | %s | %llu\n", 0ULL, params->size - 1, >> + lock_length ? " locked" : "unlocked", params->size / min_prot_le= n); >> + } else if (!lock_start) { >> + seq_printf(s, " %08llx-%08llx | %s | %llu\n", 0ULL, lock_length - 1, >> + " locked", lock_length / min_prot_len); >> + seq_printf(s, " %08llx-%08llx | %s | %llu\n", lock_length, params->si= ze - 1, >> + "unlocked", (params->size - lock_length) / min_prot_len); >> + } else { >> + seq_printf(s, " %08llx-%08llx | %s | %llu\n", 0ULL, lock_start - 1, >> + "unlocked", lock_start / min_prot_len); >> + seq_printf(s, " %08llx-%08llx | %s | %llu\n", lock_start, params->siz= e - 1, >> + " locked", lock_length / min_prot_len); >> + } >> + >> + seq_printf(s, "\n%dkiB-sectors locking map (x: locked, .: unlocked)\n", >> + min_prot_len / 1024); >> + seq_puts(s, "|"); >> + for (i =3D 0; i < params->size; i +=3D min_prot_len) >> + seq_printf(s, spi_nor_is_locked_sr(nor, i, min_prot_len, sr) ? "x" : = "."); > > As mentioned above, newlines as well as a leading offset counter > would be nice :) Arf, I was hoping I could escape that step, but ok, fair enough :-) Miqu=C3=A8l 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 BE544CF3186 for ; Wed, 19 Nov 2025 09:50:09 +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:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-ID:Date:References :In-Reply-To:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=TQB40PKwE0WEZfsXh2X84b1NKk6Vfdh9+eVkR47Ytho=; b=WQBOGQN7Pn/71S ZanaRGTZE4alYGVIQKa9qTetyzXrdypt1zBCTKuTLpKohcPgbFVhzhJQDHPFScOyRKrmxD4dCe1mf b9SzOSC5pxFg+ZMLlw3c6jCYNvcSlbY4x+rkWgX9qrFANz4VmD7Z1Vi6JEkNH+7BUXcuPA0cKTFSi qFfTLzkxYnLd8Zoc90dw6kU+t5pjX8ePpTDMQ4yb7LRQ6mip8gyl7shPlpPUJqVR3fDNxMwsz8ARX gRqxdr5cRltSVQnaeTIBBXbC1OYB9mnuJfSj2HQw2xZxizaCNYQRX19a/cVGUdSnCvJ3WTzQJ6ry5 KKAltGqNYGj4scZdA8Og==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) id 1vLepD-00000002tyt-1fb1; Wed, 19 Nov 2025 09:50:07 +0000 Received: from smtpout-04.galae.net ([185.171.202.116]) by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) id 1vLepA-00000002txi-3HWX for linux-mtd@lists.infradead.org; Wed, 19 Nov 2025 09:50:06 +0000 Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id 639B3C11189 for ; Wed, 19 Nov 2025 09:49:40 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 9190460720; Wed, 19 Nov 2025 09:50:02 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id D22C810371A18; Wed, 19 Nov 2025 10:49:58 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1763545802; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=RrIjwcjwliZ95lPsOv8XtZAnAsO3R4A3FRoqGR2mI7g=; b=NDCz8PCM2Nkvg9vaH8fUswy6MvH7QqLHVik27q6zknsVFM3ymgUpBZoCgJOm3wK4ZhAvGg IbY1ET4w44no3ZXy7ziwRYbdlBgyco0O7Sq/IK60yIV8hgvnpPnPeZmINbccHHKHzybi8k /nY8hhDhJUO7g179uU9lCQl8ZQqNgkWOYWz6K+L9VIZjeToDsdIoP1wCzJq0MwSmgo+9LI eQp15tOtt4ArbVhjuRMpiufS0+OM/LZIo2KCHbJNDFl8XoT86W1sGRrIR/vuaOV75KObXw 4kUzbJZCtxN7c5WTJ2Q9VLPgGp81MQXYdBYFXxpQGi3ojTo9JTbuQE3ntc5/pg== From: Miquel Raynal To: "Michael Walle" Cc: "Tudor Ambarus" , "Pratyush Yadav" , "Richard Weinberger" , "Vignesh Raghavendra" , "Jonathan Corbet" , "Sean Anderson" , "Thomas Petazzoni" , "Steam Lin" , , , Subject: Re: [PATCH 15/19] mtd: spi-nor: debugfs: Add locking support In-Reply-To: (Michael Walle's message of "Tue, 18 Nov 2025 13:46:52 +0100") References: <20251114-winbond-v6-18-rc1-spi-nor-swp-v1-0-487bc7129931@bootlin.com> <20251114-winbond-v6-18-rc1-spi-nor-swp-v1-15-487bc7129931@bootlin.com> User-Agent: mu4e 1.12.7; emacs 30.2 Date: Wed, 19 Nov 2025 10:49:57 +0100 Message-ID: <87o6oycpx6.fsf@bootlin.com> MIME-Version: 1.0 X-Last-TLS-Session-Version: TLSv1.3 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20251119_015005_130694_90931700 X-CRM114-Status: GOOD ( 29.01 ) X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+linux-mtd=archiver.kernel.org@lists.infradead.org SGVsbG8sCgpPbiAxOC8xMS8yMDI1IGF0IDEzOjQ2OjUyICswMSwgIk1pY2hhZWwgV2FsbGUiIDxt d2FsbGVAa2VybmVsLm9yZz4gd3JvdGU6Cgo+IE9uIEZyaSBOb3YgMTQsIDIwMjUgYXQgNjo1MyBQ TSBDRVQsIE1pcXVlbCBSYXluYWwgd3JvdGU6Cj4+IFRoZSBpb2N0bCBvdXRwdXQgbWF5IGJlIGNv dW50ZXIgaW50dWl0aXZlIGluIHNvbWUgY2FzZXMuIEFza2luZyBmb3IgYQo+PiAibG9ja2VkIHN0 YXR1cyIgb3ZlciBhIHJlZ2lvbiB0aGF0IGlzIG9ubHkgcGFydGlhbGx5IGxvY2tlZCB3aWxsIHJl dHVybgo+PiAidW5sb2NrZWQiIHdoZXJlYXMgaW4gcHJhY3RpY2UgbWF5YmUgdGhlIGJpZ2dlc3Qg cGFydCBpcyBhY3R1YWxseQo+PiBsb2NrZWQuCj4+Cj4+IEtub3dpbmcgd2hhdCBpcyB0aGUgcmVh bCBzb2Z0d2FyZSBsb2NraW5nIHN0YXRlIHRocm91Z2ggZGVidWdmcyB3b3VsZCBiZQo+PiB2ZXJ5 IGNvbnZlbmllbnQgZm9yIGRldmVsb3BtZW50L2RlYnVnZ2luZyBwdXJwb3NlcywgaGVuY2UgdGhp cyBwcm9wb3NhbAo+PiBmb3IgYWRkaW5nIHR3byBleHRyYSBibG9ja3MgYXQgdGhlIGVuZCBvZiB0 aGUgZmlsZToKPj4gLSBBICJzb2Z0d2FyZSBsb2NrZWQgc2VjdG9ycyIgYXJyYXkgd2hpY2ggbGlz dHMgZXZlcnkgc2VjdGlvbiwgaWYgaXQgaXMKPj4gbG9ja2VkIG9yIG5vdCwgc2hvd2luZyBib3Ro IHRoZSBhZGRyZXNzIHJhbmdlcyBhbmQgdGhlIHNpemVzIGluIG51bWJlcnMKPj4gb2YgYmxvY2tz Lgo+Cj4gSSBrbm93IHRoZSBmaWxlIGlzIGNhbGxlZCBzb2Z0d2FyZSB3cml0ZSBwcm90ZWN0aW9u IChvciBzd3ApIGJ1dAo+IGl0J3MgcmVhbGx5IGEgaGFyZHdhcmUgd3JpdGUgcHJvdGVjdGlvbiwg aXNuJ3QgaXQ/CgpXZWxsLCBpdCBkZXBlbmRzIG9uIHlvdXIgY29uZmlndXJhdGlvbiBJIGd1ZXNz PyBXaXRob3V0ICNXUCBwaW4gSSBkb24ndAprbm93IGhvdyB0byBjYWxsIHRoYXQuIEkgaGFkIGlu IG1pbmQgdGhhdCBzb2Z0d2FyZSBtZWFudCAidXNpbmcgdGhlIEJQCnBpbnMiIGFuZCAiaGFyZHdh cmUiIG1lYW50ICJ0b2dnbGluZyAjV1AiLiBCdXQgSSBoYXZlIG5vIHN0cm9uZyBvcGluaW9uCmFi b3V0IHRoaXMgd29yZGluZy4KCj4+IC0gU29tZSBraW5kIG9mIG1hcHBpbmcgb2YgdGhlIGxvY2tl ZCBzZWN0b3JzLCB3aGljaCBwaWN0dXJlcyB0aGUgZW50aXJlCj4+IGZsYXNoLiBJdCBtYXkgYmUg dmVyYm9zZSwgc28gcGVyaGFwcyB3ZSdsbCBkcm9wIGl0IGluIHRoZSBlbmQuIEkgZm91bmQKPj4g aXQgdmVyeSB1c2VmdWwgdG8gcmVhbGx5IGdldCBhIGNsZWFyZXIgbWVudGFsIG1vZGVsIG9mIHdo YXQgd2FzCj4+IGxvY2tlZC91bmxvY2tlZCwgYnV0IHRoZSBhcnJheSBqdXN0IGJlZm9yZSBpcyBh bHJlYWR5IGEgZ29vZCBzb3VyY2Ugb2YKPj4gaW5mb3JtYXRpb24uCj4+Cj4+IEhlcmUgaXMgYW4g ZXhhbXBsZSBvZiBvdXRwdXQsIHdoYXQgaXMgYWZ0ZXIgdGhlICJzZWN0b3IgbWFwIiBpcyBuZXcu Cj4+Cj4+ICQgY2F0IC9zeXMva2VybmVsL2RlYnVnL3NwaS1ub3Ivc3BpMC4wL3BhcmFtcwo+PiBu YW1lCQkobnVsbCkKPj4gaWQJCWVmIGEwIDIwIDAwIDAwIDAwCj4+IHNpemUJCTY0LjAgTWlCCj4+ IHdyaXRlIHNpemUJMQo+PiBwYWdlIHNpemUJMjU2Cj4+IGFkZHJlc3MgbmJ5dGVzCTQKPj4gZmxh Z3MJCUhBU19TUl9UQiB8IDRCX09QQ09ERVMgfCBIQVNfNEJBSVQgfCBIQVNfTE9DSyB8IEhBU18x NkJJVF9TUiB8IEhBU19TUl9UQl9CSVQ2IHwgSEFTXzRCSVRfQlAgfCBTT0ZUX1JFU0VUIHwgTk9f V1AKPj4KPj4gb3Bjb2Rlcwo+PiAgcmVhZAkJMHhlYwo+PiAgIGR1bW15IGN5Y2xlcwk2Cj4+ICBl cmFzZQkJMHhkYwo+PiAgcHJvZ3JhbQkweDM0Cj4+ICA4RCBleHRlbnNpb24Jbm9uZQo+Pgo+PiBw cm90b2NvbHMKPj4gIHJlYWQJCTFTLTRTLTRTCj4+ICB3cml0ZQkJMVMtMVMtNFMKPj4gIHJlZ2lz dGVyCTFTLTFTLTFTCj4+Cj4+IGVyYXNlIGNvbW1hbmRzCj4+ICAyMSAoNC4wMCBLaUIpIFsxXQo+ PiAgZGMgKDY0LjAgS2lCKSBbM10KPj4gIGM3ICg2NC4wIE1pQikKPj4KPj4gc2VjdG9yIG1hcAo+ PiAgcmVnaW9uIChpbiBoZXgpICAgfCBlcmFzZSBtYXNrIHwgb3ZlcmxhaWQKPj4gIC0tLS0tLS0t LS0tLS0tLS0tLSstLS0tLS0tLS0tLS0rLS0tLS0tLS0tCj4+ICAwMDAwMDAwMC0wM2ZmZmZmZiB8 ICAgICBbICAgM10gfCBubwo+Pgo+PiBzb2Z0d2FyZSBsb2NrZWQgc2VjdG9ycwo+Cj4gZHJvcCAi c29mdHdhcmUiIGhlcmUuCgpPa2F5LgoKPgo+PiAgcmVnaW9uIChpbiBoZXgpICAgfCBzdGF0dXMg ICB8ICNibG9ja3MKPj4gIC0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tKy0tLS0tLS0tCj4+ ICAwMDAwMDAwMC0wM2ZmZmZmZiB8IHVubG9ja2VkIHwgMTAyNAo+Cj4gSSByZWFsbHkgbGlrZSB0 aGF0LgoKOi0pCgo+PiA2NGtpQi1zZWN0b3JzIGxvY2tpbmcgbWFwICh4OiBsb2NrZWQsIC46IHVu bG9ja2VkKQo+PiB8Li4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4u Li4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4u Li4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4u Li4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4u Li4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4u Li4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4u Li4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4u Li4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4u Li4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4u Li4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4u Li4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4u Li4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4u Li4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4u Li4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4u Li4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4u Li4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4u Li4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4u Li4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLgo+PiAgLi4uLi4uLi4uLi4u Li4uLi4uLi4uLi4uLi4ufAo+Cj4gTWF5YmUgcHV0IGl0IGludG8gYW4gb3duIGZpbGUuIEluIGFu eSBjYXNlLCBhIHNhbmUgbGluZSB3cmFwcGluZwo+IHdvdWxkIGJlIGdvb2QuIEFuZCBhZGQgYSBs ZWFkaW5nIG9mZnNldCwgaWUsICIwMDAwOiB4eHh4Li4uLi4iLgoKSSB3YXMgdW5zdXJlIGFib3V0 IGRvaW5nIHRoYXQsIGJ1dCB5ZXMgdGhhdCBtYWtlcyBzZW5zZS4gTWF5IEkgY2FsbCBpdAoibG9j a2VkX3NlY3RvcnNfbWFwIj8KClsuLi5dCgo+PiArCXNyWzBdID0gbm9yLT5ib3VuY2VidWZbMF07 Cj4+ICsKPj4gKwlpZiAoIShub3ItPmZsYWdzICYgU05PUl9GX05PX1JFQURfQ1IpKSB7Cj4+ICsJ CXJldCA9IHNwaV9ub3JfcmVhZF9jcihub3IsIG5vci0+Ym91bmNlYnVmICsgMSk7Cj4+ICsJCWlm IChyZXQpCj4+ICsJCQlyZXR1cm4gcmV0Owo+PiArCX0KPj4gKwo+PiArCXNyWzFdID0gbm9yLT5i b3VuY2VidWZbMV07Cj4KPiBTaG91bGRuJ3QgdGhhdCBnbyBpbnRvIHRoZSBmb3JtZXIgaWYgY29u ZGl0aW9uYWw/IGJvdW5jZWJ1ZlsxXSBtaWdodAo+IG5ldmVyIGJlIHJlYWQuCgpZZXMsIHRoYXQn cyBjb3JyZWN0LiBJIGRvbid0IHJlbWVtYmVyIHdoeSBJIGRpZCBpdCB0aGlzIHdheSwgcHJvYmFi bHkgYQpidWcsIEknbGwgbW92ZSB0aGF0IGxpbmUuCgo+IEFsc28sIHVudGlsIG5vdywgcmVhZGlu ZyB0aGUgInBhcmFtcyIgZGVidWcgZmlsZSBuZXZlciBpbnRlcmFjdHMKPiB3aXRoIHRoZSBmbGFz aCwgYnV0IHdpdGggdGhpcyBwYXRjaCBpdCBkb2VzLiBXZSBkb24ndCBkbyBsb2NraW5nCj4gaGVy ZSB3aGljaCBsb29rcyB3cm9uZy4gTWF5YmUgd2Ugc2hvdWxkIGp1c3QgY2FjaGUgdGhlIHByb3Rl Y3Rpb24KPiBiaXRzLiBOb3Qgc3VyZS4KCkkgZ3Vlc3MgY2FjaGluZyB0aGUgc3RhdHVzIHJlZ2lz dGVycyBtYWtlcyBzZW5zZSwgYnV0IHdlJ2xsIHN0aWxsIGhhdmUgYQpwb3NzaWJsZSByYWNlIHdo ZW4gYWNjZXNzaW5nIHRoZSAyIHJlZ2lzdGVycy4gSXMgaXQgb2theSB0bwppZ25vcmUgdGhpcyB2 ZXJ5IHVubGlrZWx5IGNhc2UgaW4gZGVidWdmcz8gT3RoZXJ3aXNlIEkgbWlnaHQganVzdCBsb2Nr CnRoZSBlbnRpcmUgZGV2aWNlIGZvciB0aGUgdGltZSB3ZSBhY2Nlc3MgdGhlIGNhY2hlZCByZWdp c3RlcnMuCgo+PiArCXNwaV9ub3JfZ2V0X2xvY2tlZF9yYW5nZV9zcihub3IsIHNyLCAmbG9ja19z dGFydCwgJmxvY2tfbGVuZ3RoKTsKPj4gKwlpZiAoIWxvY2tfbGVuZ3RoIHx8IGxvY2tfbGVuZ3Ro ID09IHBhcmFtcy0+c2l6ZSkgewo+PiArCQlzZXFfcHJpbnRmKHMsICIgJTA4bGx4LSUwOGxseCB8 ICVzIHwgJWxsdVxuIiwgMFVMTCwgcGFyYW1zLT5zaXplIC0gMSwKPj4gKwkJCSAgIGxvY2tfbGVu Z3RoID8gIiAgbG9ja2VkIiA6ICJ1bmxvY2tlZCIsIHBhcmFtcy0+c2l6ZSAvIG1pbl9wcm90X2xl bik7Cj4+ICsJfSBlbHNlIGlmICghbG9ja19zdGFydCkgewo+PiArCQlzZXFfcHJpbnRmKHMsICIg JTA4bGx4LSUwOGxseCB8ICVzIHwgJWxsdVxuIiwgMFVMTCwgbG9ja19sZW5ndGggLSAxLAo+PiAr CQkJICAgIiAgbG9ja2VkIiwgbG9ja19sZW5ndGggLyBtaW5fcHJvdF9sZW4pOwo+PiArCQlzZXFf cHJpbnRmKHMsICIgJTA4bGx4LSUwOGxseCB8ICVzIHwgJWxsdVxuIiwgbG9ja19sZW5ndGgsIHBh cmFtcy0+c2l6ZSAtIDEsCj4+ICsJCQkgICAidW5sb2NrZWQiLCAocGFyYW1zLT5zaXplIC0gbG9j a19sZW5ndGgpIC8gbWluX3Byb3RfbGVuKTsKPj4gKwl9IGVsc2Ugewo+PiArCQlzZXFfcHJpbnRm KHMsICIgJTA4bGx4LSUwOGxseCB8ICVzIHwgJWxsdVxuIiwgMFVMTCwgbG9ja19zdGFydCAtIDEs Cj4+ICsJCQkgICAidW5sb2NrZWQiLCBsb2NrX3N0YXJ0IC8gbWluX3Byb3RfbGVuKTsKPj4gKwkJ c2VxX3ByaW50ZihzLCAiICUwOGxseC0lMDhsbHggfCAlcyB8ICVsbHVcbiIsIGxvY2tfc3RhcnQs IHBhcmFtcy0+c2l6ZSAtIDEsCj4+ICsJCQkgICAiICBsb2NrZWQiLCBsb2NrX2xlbmd0aCAvIG1p bl9wcm90X2xlbik7Cj4+ICsJfQo+PiArCj4+ICsJc2VxX3ByaW50ZihzLCAiXG4lZGtpQi1zZWN0 b3JzIGxvY2tpbmcgbWFwICh4OiBsb2NrZWQsIC46IHVubG9ja2VkKVxuIiwKPj4gKwkJICAgbWlu X3Byb3RfbGVuIC8gMTAyNCk7Cj4+ICsJc2VxX3B1dHMocywgInwiKTsKPj4gKwlmb3IgKGkgPSAw OyBpIDwgcGFyYW1zLT5zaXplOyBpICs9IG1pbl9wcm90X2xlbikKPj4gKwkJc2VxX3ByaW50Zihz LCBzcGlfbm9yX2lzX2xvY2tlZF9zcihub3IsIGksIG1pbl9wcm90X2xlbiwgc3IpID8gIngiIDog Ii4iKTsKPgo+IEFzIG1lbnRpb25lZCBhYm92ZSwgbmV3bGluZXMgYXMgd2VsbCBhcyBhIGxlYWRp bmcgb2Zmc2V0IGNvdW50ZXIKPiB3b3VsZCBiZSBuaWNlIDopCgpBcmYsIEkgd2FzIGhvcGluZyBJ IGNvdWxkIGVzY2FwZSB0aGF0IHN0ZXAsIGJ1dCBvaywgZmFpciBlbm91Z2ggOi0pCgpNaXF1w6hs CgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18K TGludXggTVREIGRpc2N1c3Npb24gbWFpbGluZyBsaXN0Cmh0dHA6Ly9saXN0cy5pbmZyYWRlYWQu b3JnL21haWxtYW4vbGlzdGluZm8vbGludXgtbXRkLwo=