linux-doc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Michael Walle" <mwalle@kernel.org>
To: "Miquel Raynal" <miquel.raynal@bootlin.com>,
	"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>
Cc: "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: Tue, 18 Nov 2025 13:46:52 +0100	[thread overview]
Message-ID: <DEBTY3TV74T2.2N3VRS6HGWDXD@kernel.org> (raw)
In-Reply-To: <20251114-winbond-v6-18-rc1-spi-nor-swp-v1-15-487bc7129931@bootlin.com>

[-- Attachment #1: Type: text/plain, Size: 9523 bytes --]

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?

> - 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.

>  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.....".

..

>  drivers/mtd/spi-nor/core.h    |  4 ++++
>  drivers/mtd/spi-nor/debugfs.c | 45 +++++++++++++++++++++++++++++++++++++++++++
>  drivers/mtd/spi-nor/swp.c     | 11 +++++++----
>  3 files changed, 56 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
> index 516ab19dc7b86a5c6ba8729d2ba18904b922df23..8a95592994f749a62b2cc70ab85f54d36681e760 100644
> --- a/drivers/mtd/spi-nor/core.h
> +++ b/drivers/mtd/spi-nor/core.h
> @@ -700,6 +700,10 @@ static inline bool spi_nor_needs_sfdp(const struct spi_nor *nor)
>  	return !nor->info->size;
>  }
>  
> +u64 spi_nor_get_min_prot_length_sr(struct spi_nor *nor);
> +void spi_nor_get_locked_range_sr(struct spi_nor *nor, const u8 *sr, loff_t *ofs, u64 *len);
> +bool spi_nor_is_locked_sr(struct spi_nor *nor, loff_t ofs, u64 len, const u8 *sr);
> +
>  #ifdef CONFIG_DEBUG_FS
>  void spi_nor_debugfs_register(struct spi_nor *nor);
>  void spi_nor_debugfs_shutdown(void);
> diff --git a/drivers/mtd/spi-nor/debugfs.c b/drivers/mtd/spi-nor/debugfs.c
> index d0191eb9f87956418dfd964fc1f16b21e3345049..d2af4c189aad68bab78c1c68688b5865eebef9b9 100644
> --- a/drivers/mtd/spi-nor/debugfs.c
> +++ b/drivers/mtd/spi-nor/debugfs.c
> @@ -77,12 +77,16 @@ static void spi_nor_print_flags(struct seq_file *s, unsigned long flags,
>  static int spi_nor_params_show(struct seq_file *s, void *data)
>  {
>  	struct spi_nor *nor = s->private;
> +	unsigned int min_prot_len = spi_nor_get_min_prot_length_sr(nor);
>  	struct spi_nor_flash_parameter *params = nor->params;
>  	struct spi_nor_erase_map *erase_map = &params->erase_map;
>  	struct spi_nor_erase_region *region = erase_map->regions;
>  	const struct flash_info *info = nor->info;
> +	loff_t lock_start, lock_length;
>  	char buf[16], *str;
>  	unsigned int i;
> +	u8 sr[2] = {};
> +	int ret;
>  
>  	seq_printf(s, "name\t\t%s\n", info->name);
>  	seq_printf(s, "id\t\t%*ph\n", SPI_NOR_MAX_ID_LEN, nor->id);
> @@ -159,6 +163,47 @@ static int spi_nor_params_show(struct seq_file *s, void *data)
>  			   region[i].overlaid ? "yes" : "no");
>  	}
>  
> +	seq_puts(s, "\nsoftware locked sectors\n");
> +	seq_puts(s, " region (in hex)   | status   | #blocks\n");
> +	seq_puts(s, " ------------------+----------+--------\n");
> +
> +	ret = spi_nor_read_sr(nor, nor->bouncebuf);
> +	if (ret)
> +		return ret;
> +
> +	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.

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.

> +
> +	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 :)

-michael

> +	seq_puts(s, "|\n");
> +
>  	return 0;
>  }
>  DEFINE_SHOW_ATTRIBUTE(spi_nor_params);
> diff --git a/drivers/mtd/spi-nor/swp.c b/drivers/mtd/spi-nor/swp.c
> index f5ec05d6f2680113332f47e0efbcb4d88f0d3e3c..0e685aa3a4fdc3100b5259659a3083c14a2cf127 100644
> --- a/drivers/mtd/spi-nor/swp.c
> +++ b/drivers/mtd/spi-nor/swp.c
> @@ -32,7 +32,7 @@ static u8 spi_nor_get_sr_tb_mask(struct spi_nor *nor)
>  		return SR_TB_BIT5;
>  }
>  
> -static u64 spi_nor_get_min_prot_length_sr(struct spi_nor *nor)
> +u64 spi_nor_get_min_prot_length_sr(struct spi_nor *nor)
>  {
>  	unsigned int bp_slots, bp_slots_needed;
>  	/*
> @@ -53,8 +53,8 @@ static u64 spi_nor_get_min_prot_length_sr(struct spi_nor *nor)
>  		return sector_size;
>  }
>  
> -static void spi_nor_get_locked_range_sr(struct spi_nor *nor, const u8 *sr, loff_t *ofs,
> -					u64 *len)
> +void spi_nor_get_locked_range_sr(struct spi_nor *nor, const u8 *sr, loff_t *ofs,
> +				 u64 *len)
>  {
>  	u64 min_prot_len;
>  	u8 bp_mask = spi_nor_get_sr_bp_mask(nor);
> @@ -112,7 +112,7 @@ static bool spi_nor_check_lock_status_sr(struct spi_nor *nor, loff_t ofs,
>  		return (ofs >= lock_offs_max) || (offs_max <= lock_offs);
>  }
>  
> -static bool spi_nor_is_locked_sr(struct spi_nor *nor, loff_t ofs, u64 len, const u8 *sr)
> +bool spi_nor_is_locked_sr(struct spi_nor *nor, loff_t ofs, u64 len, const u8 *sr)
>  {
>  	return spi_nor_check_lock_status_sr(nor, ofs, len, sr, true);
>  }
> @@ -374,6 +374,9 @@ static int spi_nor_sr_is_locked(struct spi_nor *nor, loff_t ofs, u64 len)
>   * -is_locked(): Checks if the region is *fully* locked, returns false otherwise.
>   *               This feeback may be misleading because users may get an "unlocked"
>   *               status even though a subpart of the region is effectively locked.
> + *
> + * If in doubt during development, check-out the debugfs output which tries to
> + * be more user friendly.
>   */
>  static const struct spi_nor_locking_ops spi_nor_sr_locking_ops = {
>  	.lock = spi_nor_sr_lock,


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 297 bytes --]

  reply	other threads:[~2025-11-18 12:47 UTC|newest]

Thread overview: 38+ 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 ` [PATCH 01/19] mtd: spi-nor: debugfs: Fix the flags list Miquel Raynal
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-18  9:17   ` Michael Walle
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-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-18  9:23   ` Michael Walle
2025-11-14 17:53 ` [PATCH 05/19] mtd: spi-nor: debugfs: Enhance output Miquel Raynal
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-18  9:53   ` Michael Walle
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-18  9:55   ` Michael Walle
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 ` [PATCH 09/19] mtd: spi-nor: swp: Create a helper that writes SR, CR and checks Miquel Raynal
2025-11-14 17:53 ` [PATCH 10/19] mtd: spi-nor: swp: Rename a mask 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 ` [PATCH 12/19] mtd: spi-nor: swp: Create helpers for building the SR register 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 ` [PATCH 14/19] mtd: spi-nor: swp: Cosmetic changes Miquel Raynal
2025-11-14 17:53 ` [PATCH 15/19] mtd: spi-nor: debugfs: Add locking support Miquel Raynal
2025-11-18 12:46   ` Michael Walle [this message]
2025-11-19  9:49     ` Miquel Raynal
2025-11-19 10:50       ` Michael Walle
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-18 12:24   ` Michael Walle
2025-11-19  9:40     ` Miquel Raynal
2025-11-19 10:27       ` Michael Walle
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 ` [PATCH 18/19] mtd: spi-nor: Add steps for testing locking with CMP Miquel Raynal
2025-11-14 17:53 ` [PATCH 19/19] mtd: spi-nor: winbond: Add CMP locking support 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=DEBTY3TV74T2.2N3VRS6HGWDXD@kernel.org \
    --to=mwalle@kernel.org \
    --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=miquel.raynal@bootlin.com \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).