From: Miquel Raynal <miquel.raynal@bootlin.com>
To: "Michael Walle" <mwalle@kernel.org>
Cc: "Tudor Ambarus" <tudor.ambarus@linaro.org>,
"Pratyush Yadav" <pratyush@kernel.org>,
"Richard Weinberger" <richard@nod.at>,
"Vignesh Raghavendra" <vigneshr@ti.com>,
"Jonathan Corbet" <corbet@lwn.net>,
"Sean Anderson" <sean.anderson@linux.dev>,
"Thomas Petazzoni" <thomas.petazzoni@bootlin.com>,
"Steam Lin" <STLin2@winbond.com>,
<linux-mtd@lists.infradead.org>, <linux-kernel@vger.kernel.org>,
<linux-doc@vger.kernel.org>
Subject: Re: [PATCH 15/19] mtd: spi-nor: debugfs: Add locking support
Date: Wed, 19 Nov 2025 10:49:57 +0100 [thread overview]
Message-ID: <87o6oycpx6.fsf@bootlin.com> (raw)
In-Reply-To: <DEBTY3TV74T2.2N3VRS6HGWDXD@kernel.org> (Michael Walle's message of "Tue, 18 Nov 2025 13:46:52 +0100")
Hello,
On 18/11/2025 at 13:46:52 +01, "Michael Walle" <mwalle@kernel.org> 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 | HAS_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] = nor->bouncebuf[0];
>> +
>> + if (!(nor->flags & SNOR_F_NO_READ_CR)) {
>> + ret = spi_nor_read_cr(nor, nor->bouncebuf + 1);
>> + if (ret)
>> + return ret;
>> + }
>> +
>> + sr[1] = 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 == params->size) {
>> + seq_printf(s, " %08llx-%08llx | %s | %llu\n", 0ULL, params->size - 1,
>> + lock_length ? " locked" : "unlocked", params->size / min_prot_len);
>> + } 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->size - 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->size - 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 = 0; i < params->size; i += 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èl
WARNING: multiple messages have this Message-ID (diff)
From: Miquel Raynal <miquel.raynal@bootlin.com>
To: "Michael Walle" <mwalle@kernel.org>
Cc: "Tudor Ambarus" <tudor.ambarus@linaro.org>,
"Pratyush Yadav" <pratyush@kernel.org>,
"Richard Weinberger" <richard@nod.at>,
"Vignesh Raghavendra" <vigneshr@ti.com>,
"Jonathan Corbet" <corbet@lwn.net>,
"Sean Anderson" <sean.anderson@linux.dev>,
"Thomas Petazzoni" <thomas.petazzoni@bootlin.com>,
"Steam Lin" <STLin2@winbond.com>,
<linux-mtd@lists.infradead.org>, <linux-kernel@vger.kernel.org>,
<linux-doc@vger.kernel.org>
Subject: Re: [PATCH 15/19] mtd: spi-nor: debugfs: Add locking support
Date: Wed, 19 Nov 2025 10:49:57 +0100 [thread overview]
Message-ID: <87o6oycpx6.fsf@bootlin.com> (raw)
In-Reply-To: <DEBTY3TV74T2.2N3VRS6HGWDXD@kernel.org> (Michael Walle's message of "Tue, 18 Nov 2025 13:46:52 +0100")
Hello,
On 18/11/2025 at 13:46:52 +01, "Michael Walle" <mwalle@kernel.org> 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 | HAS_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] = nor->bouncebuf[0];
>> +
>> + if (!(nor->flags & SNOR_F_NO_READ_CR)) {
>> + ret = spi_nor_read_cr(nor, nor->bouncebuf + 1);
>> + if (ret)
>> + return ret;
>> + }
>> +
>> + sr[1] = 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 == params->size) {
>> + seq_printf(s, " %08llx-%08llx | %s | %llu\n", 0ULL, params->size - 1,
>> + lock_length ? " locked" : "unlocked", params->size / min_prot_len);
>> + } 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->size - 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->size - 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 = 0; i < params->size; i += 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èl
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
next prev parent reply other threads:[~2025-11-19 9:50 UTC|newest]
Thread overview: 76+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-14 17:53 [PATCH 00/19] mtd: spi-nor: Enhance software protection Miquel Raynal
2025-11-14 17:53 ` Miquel Raynal
2025-11-14 17:53 ` [PATCH 01/19] mtd: spi-nor: debugfs: Fix the flags list Miquel Raynal
2025-11-14 17:53 ` Miquel Raynal
2025-11-18 7:43 ` Michael Walle
2025-11-18 7:43 ` Michael Walle
2025-11-14 17:53 ` [PATCH 02/19] mtd: spi-nor: swp: Improve locking user experience Miquel Raynal
2025-11-14 17:53 ` Miquel Raynal
2025-11-18 9:17 ` Michael Walle
2025-11-18 9:17 ` Michael Walle
2025-11-19 9:13 ` Miquel Raynal
2025-11-19 9:13 ` Miquel Raynal
2025-11-14 17:53 ` [PATCH 03/19] mtd: spi-nor: Improve opcodes documentation Miquel Raynal
2025-11-14 17:53 ` Miquel Raynal
2025-11-18 9:22 ` Michael Walle
2025-11-18 9:22 ` Michael Walle
2025-11-14 17:53 ` [PATCH 04/19] mtd: spi-nor: debugfs: Align variable access with the rest of the file Miquel Raynal
2025-11-14 17:53 ` Miquel Raynal
2025-11-18 9:23 ` Michael Walle
2025-11-18 9:23 ` Michael Walle
2025-11-14 17:53 ` [PATCH 05/19] mtd: spi-nor: debugfs: Enhance output Miquel Raynal
2025-11-14 17:53 ` Miquel Raynal
2025-11-18 9:24 ` Michael Walle
2025-11-18 9:24 ` Michael Walle
2025-11-14 17:53 ` [PATCH 06/19] mtd: spi-nor: swp: Explain the MEMLOCK ioctl implementation behaviour Miquel Raynal
2025-11-14 17:53 ` Miquel Raynal
2025-11-18 9:53 ` Michael Walle
2025-11-18 9:53 ` Michael Walle
2025-11-19 9:18 ` Miquel Raynal
2025-11-19 9:18 ` Miquel Raynal
2025-11-14 17:53 ` [PATCH 07/19] mtd: spi-nor: swp: Clarify a comment Miquel Raynal
2025-11-14 17:53 ` Miquel Raynal
2025-11-18 9:55 ` Michael Walle
2025-11-18 9:55 ` Michael Walle
2025-11-19 9:19 ` Miquel Raynal
2025-11-19 9:19 ` Miquel Raynal
2025-11-14 17:53 ` [PATCH 08/19] mtd: spi-nor: swp: Use a pointer for SR instead of a single byte Miquel Raynal
2025-11-14 17:53 ` Miquel Raynal
2025-11-14 17:53 ` [PATCH 09/19] mtd: spi-nor: swp: Create a helper that writes SR, CR and checks Miquel Raynal
2025-11-14 17:53 ` Miquel Raynal
2025-11-14 17:53 ` [PATCH 10/19] mtd: spi-nor: swp: Rename a mask Miquel Raynal
2025-11-14 17:53 ` Miquel Raynal
2025-11-14 17:53 ` [PATCH 11/19] mtd: spi-nor: swp: Create a TB intermediate variable Miquel Raynal
2025-11-14 17:53 ` Miquel Raynal
2025-11-14 17:53 ` [PATCH 12/19] mtd: spi-nor: swp: Create helpers for building the SR register Miquel Raynal
2025-11-14 17:53 ` Miquel Raynal
2025-11-14 17:53 ` [PATCH 13/19] mtd: spi-nor: swp: Simplify checking the locked/unlocked range Miquel Raynal
2025-11-14 17:53 ` Miquel Raynal
2025-11-14 17:53 ` [PATCH 14/19] mtd: spi-nor: swp: Cosmetic changes Miquel Raynal
2025-11-14 17:53 ` Miquel Raynal
2025-11-14 17:53 ` [PATCH 15/19] mtd: spi-nor: debugfs: Add locking support Miquel Raynal
2025-11-14 17:53 ` Miquel Raynal
2025-11-18 12:46 ` Michael Walle
2025-11-18 12:46 ` Michael Walle
2025-11-19 9:49 ` Miquel Raynal [this message]
2025-11-19 9:49 ` Miquel Raynal
2025-11-19 10:50 ` Michael Walle
2025-11-19 10:50 ` Michael Walle
2025-11-19 17:43 ` Miquel Raynal
2025-11-19 17:43 ` Miquel Raynal
2025-11-14 17:53 ` [PATCH 16/19] mtd: spi-nor: Add steps for testing " Miquel Raynal
2025-11-14 17:53 ` Miquel Raynal
2025-11-18 12:24 ` Michael Walle
2025-11-18 12:24 ` Michael Walle
2025-11-19 9:40 ` Miquel Raynal
2025-11-19 9:40 ` Miquel Raynal
2025-11-19 10:27 ` Michael Walle
2025-11-19 10:27 ` Michael Walle
2025-11-19 17:35 ` Miquel Raynal
2025-11-19 17:35 ` Miquel Raynal
2025-11-14 17:53 ` [PATCH 17/19] mtd: spi-nor: swp: Add support for the complement feature Miquel Raynal
2025-11-14 17:53 ` Miquel Raynal
2025-11-14 17:53 ` [PATCH 18/19] mtd: spi-nor: Add steps for testing locking with CMP Miquel Raynal
2025-11-14 17:53 ` Miquel Raynal
2025-11-14 17:53 ` [PATCH 19/19] mtd: spi-nor: winbond: Add CMP locking support Miquel Raynal
2025-11-14 17:53 ` Miquel Raynal
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87o6oycpx6.fsf@bootlin.com \
--to=miquel.raynal@bootlin.com \
--cc=STLin2@winbond.com \
--cc=corbet@lwn.net \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mtd@lists.infradead.org \
--cc=mwalle@kernel.org \
--cc=pratyush@kernel.org \
--cc=richard@nod.at \
--cc=sean.anderson@linux.dev \
--cc=thomas.petazzoni@bootlin.com \
--cc=tudor.ambarus@linaro.org \
--cc=vigneshr@ti.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.