Skip to content

Commit 5fd5c07

Browse files
kamaldasu-cryptogregkh
authored andcommitted
mtd: rawnand: serialize lock/unlock against other NAND operations
[ Upstream commit bab2bc6e850a697a23b9e5f0e21bb8c187615e95 ] nand_lock() and nand_unlock() call into chip->ops.lock_area/unlock_area without holding the NAND device lock. On controllers that implement SET_FEATURES via multiple low-level PIO commands, these can race with concurrent UBI/UBIFS background erase/write operations that hold the device lock, resulting in cmd_pending conflicts on the NAND controller. Add nand_get_device()/nand_release_device() around the lock/unlock operations to serialize them against all other NAND controller access. Fixes: 9227008 ("mtd: rawnand: Add support for manufacturer specific lock/unlock operation") Signed-off-by: Kamal Dasu <kamal.dasu@broadcom.com> Reviewed-by: William Zhang <william.zhang@broadcom.com> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent f8b5b83 commit 5fd5c07

1 file changed

Lines changed: 12 additions & 2 deletions

File tree

drivers/mtd/nand/raw/nand_base.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4737,11 +4737,16 @@ static void nand_shutdown(struct mtd_info *mtd)
47374737
static int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
47384738
{
47394739
struct nand_chip *chip = mtd_to_nand(mtd);
4740+
int ret;
47404741

47414742
if (!chip->ops.lock_area)
47424743
return -ENOTSUPP;
47434744

4744-
return chip->ops.lock_area(chip, ofs, len);
4745+
nand_get_device(chip);
4746+
ret = chip->ops.lock_area(chip, ofs, len);
4747+
nand_release_device(chip);
4748+
4749+
return ret;
47454750
}
47464751

47474752
/**
@@ -4753,11 +4758,16 @@ static int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
47534758
static int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
47544759
{
47554760
struct nand_chip *chip = mtd_to_nand(mtd);
4761+
int ret;
47564762

47574763
if (!chip->ops.unlock_area)
47584764
return -ENOTSUPP;
47594765

4760-
return chip->ops.unlock_area(chip, ofs, len);
4766+
nand_get_device(chip);
4767+
ret = chip->ops.unlock_area(chip, ofs, len);
4768+
nand_release_device(chip);
4769+
4770+
return ret;
47614771
}
47624772

47634773
/* Set default functions */

0 commit comments

Comments
 (0)