diff mbox series

[v2,3/4] mtd: cfi_cmdset_0002: Avoid point less unlocking/locking

Message ID 20180606101330.11071-3-joakim.tjernlund@infinera.com
State Accepted
Delegated to: Boris Brezillon
Headers show
Series [v2,1/4] mtd: cfi_cmdset_0002: Use right chip in do_ppb_xxlock() | expand

Commit Message

Joakim Tjernlund June 6, 2018, 10:13 a.m. UTC
cfi_ppb_unlock() walks all flash chips when unlocking sectors.
testing lock status on each chip which causes relocking of already
locked sectors. Test against offset to aviod this aliasing.

Fixes: 1648eaaa1575 ("mtd: cfi_cmdset_0002: Support Persistent Protection Bits (PPB) locking")
Cc: stable@vger.kernel.org
Signed-off-by: Joakim Tjernlund <joakim.tjernlund@infinera.com>
---

 v2 - Spilt into several patches


 drivers/mtd/chips/cfi_cmdset_0002.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Boris Brezillon June 20, 2018, 9:14 a.m. UTC | #1
On Wed,  6 Jun 2018 12:13:29 +0200
Joakim Tjernlund <joakim.tjernlund@infinera.com> wrote:

> cfi_ppb_unlock() walks all flash chips when unlocking sectors.
> testing lock status on each chip which causes relocking of already
> locked sectors. Test against offset to aviod this aliasing.

					 ^ avoid

As I said before, I think the current code is doing worse than just
relocking already locked sectors. As soon as you cross a chip boundary,
addr is set back to 0, and the (addr < offs || adr >= (ofs + len)) might
be true while it shouldn't be (absolute offset still in the unlock
range), which means you'll lock sectors that the caller expect to be
unlocked.

> 
> Fixes: 1648eaaa1575 ("mtd: cfi_cmdset_0002: Support Persistent Protection Bits (PPB) locking")
> Cc: stable@vger.kernel.org
> Signed-off-by: Joakim Tjernlund <joakim.tjernlund@infinera.com>
> ---
> 
>  v2 - Spilt into several patches
> 
> 
>  drivers/mtd/chips/cfi_cmdset_0002.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
> index cb85cccc48c1..b6273ce83de7 100644
> --- a/drivers/mtd/chips/cfi_cmdset_0002.c
> +++ b/drivers/mtd/chips/cfi_cmdset_0002.c
> @@ -2670,7 +2670,7 @@ static int __maybe_unused cfi_ppb_unlock(struct mtd_info *mtd, loff_t ofs,
>  		 * sectors shall be unlocked, so lets keep their locking
>  		 * status at "unlocked" (locked=0) for the final re-locking.
>  		 */
> -		if ((adr < ofs) || (adr >= (ofs + len))) {
> +		if ((offset < ofs) || (offset >= (ofs + len))) {
>  			sect[sectors].chip = &cfi->chips[chipnum];
>  			sect[sectors].adr = adr;
>  			sect[sectors].locked = do_ppb_xxlock(
Joakim Tjernlund June 20, 2018, 11:10 a.m. UTC | #2
On Wed, 2018-06-20 at 11:14 +0200, Boris Brezillon wrote:
> CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
> 
> 
> On Wed,  6 Jun 2018 12:13:29 +0200
> Joakim Tjernlund <joakim.tjernlund@infinera.com> wrote:
> 
> > cfi_ppb_unlock() walks all flash chips when unlocking sectors.
> > testing lock status on each chip which causes relocking of already
> > locked sectors. Test against offset to aviod this aliasing.
> 
>                                          ^ avoid
> 
> As I said before, I think the current code is doing worse than just
> relocking already locked sectors. As soon as you cross a chip boundary,
> addr is set back to 0, and the (addr < offs || adr >= (ofs + len)) might
> be true while it shouldn't be (absolute offset still in the unlock
> range), which means you'll lock sectors that the caller expect to be
> unlocked.

I don't see how, the code asks for its current lock status and will reapply
those that are locked again.

> 
> > 
> > Fixes: 1648eaaa1575 ("mtd: cfi_cmdset_0002: Support Persistent Protection Bits (PPB) locking")
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Joakim Tjernlund <joakim.tjernlund@infinera.com>
> > ---
> > 
> >  v2 - Spilt into several patches
> > 
> > 
> >  drivers/mtd/chips/cfi_cmdset_0002.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
> > index cb85cccc48c1..b6273ce83de7 100644
> > --- a/drivers/mtd/chips/cfi_cmdset_0002.c
> > +++ b/drivers/mtd/chips/cfi_cmdset_0002.c
> > @@ -2670,7 +2670,7 @@ static int __maybe_unused cfi_ppb_unlock(struct mtd_info *mtd, loff_t ofs,
> >                * sectors shall be unlocked, so lets keep their locking
> >                * status at "unlocked" (locked=0) for the final re-locking.
> >                */
> > -             if ((adr < ofs) || (adr >= (ofs + len))) {
> > +             if ((offset < ofs) || (offset >= (ofs + len))) {
> >                       sect[sectors].chip = &cfi->chips[chipnum];
> >                       sect[sectors].adr = adr;
> >                       sect[sectors].locked = do_ppb_xxlock(
> 
>
Boris Brezillon June 20, 2018, 11:54 a.m. UTC | #3
On Wed, 20 Jun 2018 11:10:23 +0000
Joakim Tjernlund <Joakim.Tjernlund@infinera.com> wrote:

> On Wed, 2018-06-20 at 11:14 +0200, Boris Brezillon wrote:
> > CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
> > 
> > 
> > On Wed,  6 Jun 2018 12:13:29 +0200
> > Joakim Tjernlund <joakim.tjernlund@infinera.com> wrote:
> >   
> > > cfi_ppb_unlock() walks all flash chips when unlocking sectors.
> > > testing lock status on each chip which causes relocking of already
> > > locked sectors. Test against offset to aviod this aliasing.  
> > 
> >                                          ^ avoid
> > 
> > As I said before, I think the current code is doing worse than just
> > relocking already locked sectors. As soon as you cross a chip boundary,
> > addr is set back to 0, and the (addr < offs || adr >= (ofs + len)) might
> > be true while it shouldn't be (absolute offset still in the unlock
> > range), which means you'll lock sectors that the caller expect to be
> > unlocked.  
> 
> I don't see how, the code asks for its current lock status and will reapply
> those that are locked again.

After reading the commit message a second time I think I
misunderstood it. I thought you were implying that the re-locking
operation was harmless and the only reason for fixing the test was to
avoid useless lock operations, but that's not what you wrote.

Sorry for the noise.
diff mbox series

Patch

diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index cb85cccc48c1..b6273ce83de7 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -2670,7 +2670,7 @@  static int __maybe_unused cfi_ppb_unlock(struct mtd_info *mtd, loff_t ofs,
 		 * sectors shall be unlocked, so lets keep their locking
 		 * status at "unlocked" (locked=0) for the final re-locking.
 		 */
-		if ((adr < ofs) || (adr >= (ofs + len))) {
+		if ((offset < ofs) || (offset >= (ofs + len))) {
 			sect[sectors].chip = &cfi->chips[chipnum];
 			sect[sectors].adr = adr;
 			sect[sectors].locked = do_ppb_xxlock(