FAILED: patch "[PATCH] mtd: spi-nor: swp: Improve locking user experience" failed to apply to 5.10-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 5.10-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.10.y
git checkout FETCH_HEAD
git cherry-pick -x e1d456b26bf23e30db305a6184e8abd9ab68bbf2
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026072003-borrowing-opium-38cc@gregkh' --subject-prefix 'PATCH 5.10.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From e1d456b26bf23e30db305a6184e8abd9ab68bbf2 Mon Sep 17 00:00:00 2001
From: Miquel Raynal <[email protected]>
Date: Tue, 26 May 2026 16:56:26 +0200
Subject: [PATCH] mtd: spi-nor: swp: Improve locking user experience
In the case of the first block being locked (or the few first blocks), if the user want to fully unlock the device it has two possibilities:
- either it asks to unlock the entire device, and this works;
- or it asks to unlock just the block(s) that are currently locked, which fails.
It fails because the conditions "can_be_top" and "can_be_bottom" are true. Indeed, in this case, we unlock everything, so the TB bit does not matter. However in the current implementation, use_top would be true (as this is the favourite option) and lock_len, which in practice should be reduced down to 0, is set to "nor->params->size - (ofs + len)" which is a positive number. This is wrong.
An easy way is to simply add an extra condition. In the unlock() path, if we can achieve the same result from both sides, it means we unlock everything and lock_len must simply be 0. A comment is added to clarify that logic.
drivers/mtd/spi-nor/swp.c +9 -2
@@ -282,8 +282,15 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, loff_t ofs, u64 len)/* Prefer top, if both are valid */ use_top = can_be_top; -/* lock_len: length of region that should remain locked */ -if (use_top) +/* +* lock_len: length of region that should remain locked. +* +* When can_be_top and can_be_bottom booleans are true, both adjacent +* regions are unlocked, thus the entire flash can be unlocked. +*/ +if (can_be_top && can_be_bottom) + lock_len =0 ; +else if (use_top) lock_len = nor->params->size - (ofs + len);else lock_len = ofs;
Sasha Levin
maintainerPATCH 1/5 mtd: spi-nor: sst: remove global protection flag
From: Michael Walle <[email protected]>
[ Upstream commit a833383732116c2afe665520bbe6951999631ef1 ]
This is considered bad for the following reasons:
(1) We only support the block protection with BPn bits for write protection. Not all SST parts support this.
(2) Newly added flash chip will automatically inherit the "has locking" support and thus needs to explicitly tested. Better be opt-in instead of opt-out.
(3) There are already supported flashes which doesn't support the locking scheme. So I assume this wasn't properly tested before adding that chip; which enforces my previous argument that locking support should be an opt-in.
Remove the global flag and add individual flags to all flashes which supports BP locking. In particular the following flashes don't support the BP scheme:
- SST26VF016B
- SST26WF016B
- SST26VF064B
Stable-dep-of: e1d456b26bf2 ("mtd: spi-nor: swp: Improve locking user experience")
--- drivers/mtd/spi-nor/sst.c | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-)
drivers/mtd/spi-nor/sst.c +12 -18
@@ -11,27 +11,27 @@static const struct flash_info sst_parts[] = {/* SST -- large erase sizes are "overlays", "sectors" are 4K */ {"sst25vf040b" ,INFO (0xbf258d ,0 ,64 *1024 ,8 , -SECT_4K |SST_WRITE ) }, +SECT_4K |SST_WRITE |SPI_NOR_HAS_LOCK ) }, {"sst25vf080b" ,INFO (0xbf258e ,0 ,64 *1024 ,16 , -SECT_4K |SST_WRITE ) }, +SECT_4K |SST_WRITE |SPI_NOR_HAS_LOCK ) }, {"sst25vf016b" ,INFO (0xbf2541 ,0 ,64 *1024 ,32 , -SECT_4K |SST_WRITE ) }, +SECT_4K |SST_WRITE |SPI_NOR_HAS_LOCK ) }, {"sst25vf032b" ,INFO (0xbf254a ,0 ,64 *1024 ,64 , -SECT_4K |SST_WRITE ) }, +SECT_4K |SST_WRITE |SPI_NOR_HAS_LOCK ) }, {"sst25vf064c" ,INFO (0xbf254b ,0 ,64 *1024 ,128 , -SECT_4K |SPI_NOR_4BIT_BP ) }, +SECT_4K |SPI_NOR_4BIT_BP |SPI_NOR_HAS_LOCK ) }, {"sst25wf512" ,INFO (0xbf2501 ,0 ,64 *1024 ,1 , -SECT_4K |SST_WRITE ) }, +SECT_4K |SST_WRITE |SPI_NOR_HAS_LOCK ) }, {"sst25wf010" ,INFO (0xbf2502 ,0 ,64 *1024 ,2 , -SECT_4K |SST_WRITE ) }, +SECT_4K |SST_WRITE |SPI_NOR_HAS_LOCK ) }, {"sst25wf020" ,INFO (0xbf2503 ,0 ,64 *1024 ,4 , -SECT_4K |SST_WRITE ) }, - {"sst25wf020a" ,INFO (0x621612 ,0 ,64 *1024 ,4 ,SECT_4K ) }, - {"sst25wf040b" ,INFO (0x621613 ,0 ,64 *1024 ,8 ,SECT_4K ) }, +SECT_4K |SST_WRITE |SPI_NOR_HAS_LOCK ) }, + {"sst25wf020a" ,INFO (0x621612 ,0 ,64 *1024 ,4 ,SECT_4K |SPI_NOR_HAS_LOCK ) }, + {"sst25wf040b" ,INFO (0x621613 ,0 ,64 *1024 ,8 ,SECT_4K |SPI_NOR_HAS_LOCK ) }, {"sst25wf040" ,INFO (0xbf2504 ,0 ,64 *1024 ,8 , -SECT_4K |SST_WRITE ) }, +SECT_4K |SST_WRITE |SPI_NOR_HAS_LOCK ) }, {"sst25wf080" ,INFO (0xbf2505 ,0 ,64 *1024 ,16 , -SECT_4K |SST_WRITE ) }, +SECT_4K |SST_WRITE |SPI_NOR_HAS_LOCK ) }, {"sst26wf016b" ,INFO (0xbf2651 ,0 ,64 *1024 ,32 ,SECT_4K |SPI_NOR_DUAL_READ |SPI_NOR_QUAD_READ ) },
@@ -141,11 +141,6 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,return ret; } -static void sst_default_init (struct spi_nor *nor) -{ - nor->flags |=SNOR_F_HAS_LOCK ; -} -static void sst_post_sfdp_fixups (struct spi_nor *nor) {if (nor->info->flags &SST_WRITE )
@@ -153,7 +148,6 @@ static void sst_post_sfdp_fixups(struct spi_nor *nor) }static const struct spi_nor_fixups sst_fixups = { - .default_init = sst_default_init, .post_sfdp = sst_post_sfdp_fixups, };
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/5 mtd: spi-nor: intel: remove global protection flag
From: Michael Walle <[email protected]>
[ Upstream commit afcf93e9d63fc1e15935a2df9457f803394e4f20 ]
For the Atmel and SST parts this flag was already moved to individual flash parts because it is considered bad esp. because newer flash chips will automatically inherit the "has locking" support. While this won't likely be the case for the Intel parts, we do it for consistency reasons.
Stable-dep-of: e1d456b26bf2 ("mtd: spi-nor: swp: Improve locking user experience")
--- drivers/mtd/spi-nor/intel.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-)
drivers/mtd/spi-nor/intel.c +3 -13
@@ -10,23 +10,13 @@static const struct flash_info intel_parts[] = {/* Intel/Numonyx -- xxxs33b */ - {"160s33b" ,INFO (0x898911 ,0 ,64 *1024 ,32 ,0 ) }, - {"320s33b" ,INFO (0x898912 ,0 ,64 *1024 ,64 ,0 ) }, - {"640s33b" ,INFO (0x898913 ,0 ,64 *1024 ,128 ,0 ) }, -}; - -static void intel_default_init (struct spi_nor *nor) -{ - nor->flags |=SNOR_F_HAS_LOCK ; -} - -static const struct spi_nor_fixups intel_fixups = { - .default_init = intel_default_init, + {"160s33b" ,INFO (0x898911 ,0 ,64 *1024 ,32 ,SPI_NOR_HAS_LOCK ) }, + {"320s33b" ,INFO (0x898912 ,0 ,64 *1024 ,64 ,SPI_NOR_HAS_LOCK ) }, + {"640s33b" ,INFO (0x898913 ,0 ,64 *1024 ,128 ,SPI_NOR_HAS_LOCK ) }, };const struct spi_nor_manufacturer spi_nor_intel = { .name ="intel" , .parts = intel_parts, .nparts =ARRAY_SIZE (intel_parts), - .fixups = &intel_fixups, };
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 3/5 mtd: spi-nor: Move Software Write Protection logic out of the core
In reply to Sasha LevinFrom: Tudor Ambarus <[email protected]>
[ Upstream commit c4c795105f2924c80752c30ffd3c7029a8e0ef28 ]
It makes the core file a bit smaller and provides better separation between the Software Write Protection features and the core logic. All the next generic software write protection features (e.g. Individual Block Protection) will reside in swp.c.
Stable-dep-of: e1d456b26bf2 ("mtd: spi-nor: swp: Improve locking user experience")
--- drivers/mtd/spi-nor/Makefile | 2 +- drivers/mtd/spi-nor/core.c | 406 +-------------------------------- drivers/mtd/spi-nor/core.h | 5 + drivers/mtd/spi-nor/swp.c | 421 +++++++++++++++++++++++++++++++++++ 4 files changed, 431 insertions(+), 403 deletions(-) create mode 100644 drivers/mtd/spi-nor/swp.c
drivers/mtd/spi-nor/Makefile +1 -1
@@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 -spi-nor-objs := core.o sfdp.o +spi-nor-objs := core.o sfdp.o swp.o spi-nor-objs += atmel.o spi-nor-objs += catalyst.o spi-nor-objs += eon.o
drivers/mtd/spi-nor/core.c +4 -402
442 lines not on this page · raw message
drivers/mtd/spi-nor/core.h +5 -0
@@ -409,6 +409,7 @@ void spi_nor_unlock_and_unprep(struct spi_nor *nor);int spi_nor_sr1_bit6_quad_enable (struct spi_nor *nor);int spi_nor_sr2_bit1_quad_enable (struct spi_nor *nor);int spi_nor_sr2_bit7_quad_enable (struct spi_nor *nor); +int spi_nor_read_sr (struct spi_nor *nor,u8 *sr);int spi_nor_write_sr_and_check (struct spi_nor *nor,u8 sr1);int spi_nor_xread_sr (struct spi_nor *nor,u8 *sr);
@@ -435,6 +436,10 @@ int spi_nor_post_bfpt_fixups(struct spi_nor *nor,const struct sfdp_bfpt *bfpt, struct spi_nor_flash_parameter *params); +void spi_nor_init_default_locking_ops (struct spi_nor *nor); +void spi_nor_try_unlock_all (struct spi_nor *nor); +void spi_nor_register_locking_ops (struct spi_nor *nor); +static struct spi_nor __maybe_unused *mtd_to_spi_nor (struct mtd_info *mtd) {return mtd->priv;
drivers/mtd/spi-nor/swp.c new file +421 -0
421 lines not on this page · raw message
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 4/5 mtd: spi-nor: Fix spi_nor_try_unlock_all()
In reply to Sasha LevinFrom: Michael Walle <[email protected]>
[ Upstream commit 2e3a7476ec3989e77270b9481e76e137824b17c0 ]
Commit ff67592cbdfc ("mtd: spi-nor: Introduce spi_nor_set_mtd_info()") moved all initialization of the mtd fields at the end of spi_nor_scan(). Normally, the mtd info is only needed for the mtd ops on the device, with one exception: spi_nor_try_unlock_all(), which will also make use of the mtd->size parameter. With that commit, the size will always be zero because it is not initialized. Fix that by not using the size of the mtd_info struct, but use the size from struct spi_nor_flash_parameter.
Stable-dep-of: e1d456b26bf2 ("mtd: spi-nor: swp: Improve locking user experience")
--- drivers/mtd/spi-nor/swp.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-)
drivers/mtd/spi-nor/swp.c +6 -8
@@ -50,7 +50,6 @@ static u64 spi_nor_get_min_prot_length_sr(struct spi_nor *nor)static void spi_nor_get_locked_range_sr (struct spi_nor *nor,u8 sr,loff_t *ofs,uint64_t *len) { -struct mtd_info *mtd = &nor->mtd;u64 min_prot_len;u8 mask =spi_nor_get_sr_bp_mask (nor);u8 tb_mask =spi_nor_get_sr_tb_mask (nor);
@@ -71,13 +70,13 @@ static void spi_nor_get_locked_range_sr(struct spi_nor *nor, u8 sr, loff_t *ofs, min_prot_len =spi_nor_get_min_prot_length_sr (nor); *len = min_prot_len << (bp -1 ); -if (*len > mtd->size) - *len = mtd->size; +if (*len > nor->params->size) + *len = nor->params->size;if (nor->flags &SNOR_F_HAS_SR_TB && sr & tb_mask) *ofs =0 ;else - *ofs = mtd->size - *len; + *ofs = nor->params->size - *len; }/*
@@ -150,7 +149,6 @@ static int spi_nor_is_unlocked_sr(struct spi_nor *nor, loff_t ofs, uint64_t len,*/ static int spi_nor_sr_lock (struct spi_nor *nor,loff_t ofs,uint64_t len) { -struct mtd_info *mtd = &nor->mtd;u64 min_prot_len;int ret, status_old, status_new;u8 mask =spi_nor_get_sr_bp_mask (nor);
@@ -175,7 +173,7 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, uint64_t len) can_be_bottom = false;/* If anything above us is unlocked, we can't use 'top' protection */ -if (!spi_nor_is_locked_sr (nor, ofs + len, mtd->size - (ofs + len), +if (!spi_nor_is_locked_sr (nor, ofs + len, nor->params->size - (ofs + len), status_old)) can_be_top = false;
@@ -187,11 +185,11 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)/* lock_len: length of region that should end up locked */ if (use_top) - lock_len = mtd->size - ofs; + lock_len = nor->params->size - ofs;else lock_len = ofs + len; -if (lock_len == mtd->size) { +if (lock_len == nor->params->size) { val = mask; }else { min_prot_len =spi_nor_get_min_prot_length_sr (nor);
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 5/5 mtd: spi-nor: swp: Improve locking user experience
In reply to Sasha LevinFrom: Miquel Raynal <[email protected]>
[ Upstream commit e1d456b26bf23e30db305a6184e8abd9ab68bbf2 ]
In the case of the first block being locked (or the few first blocks), if the user want to fully unlock the device it has two possibilities:
- either it asks to unlock the entire device, and this works;
- or it asks to unlock just the block(s) that are currently locked, which fails.
It fails because the conditions "can_be_top" and "can_be_bottom" are true. Indeed, in this case, we unlock everything, so the TB bit does not matter. However in the current implementation, use_top would be true (as this is the favourite option) and lock_len, which in practice should be reduced down to 0, is set to "nor->params->size - (ofs + len)" which is a positive number. This is wrong.
An easy way is to simply add an extra condition. In the unlock() path, if we can achieve the same result from both sides, it means we unlock everything and lock_len must simply be 0. A comment is added to clarify that logic.
--- drivers/mtd/spi-nor/swp.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
drivers/mtd/spi-nor/swp.c +9 -2
@@ -267,8 +267,15 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)/* Prefer top, if both are valid */ use_top = can_be_top; -/* lock_len: length of region that should remain locked */ -if (use_top) +/* +* lock_len: length of region that should remain locked. +* +* When can_be_top and can_be_bottom booleans are true, both adjacent +* regions are unlocked, thus the entire flash can be unlocked. +*/ +if (can_be_top && can_be_bottom) + lock_len =0 ; +else if (use_top) lock_len = nor->params->size - (ofs + len);else lock_len = ofs;
Signature · 1 line
2.53.0