Skip to content

Commit f71ce0a

Browse files
kamaldasu-cryptogregkh
authored andcommitted
mtd: rawnand: serialize lock/unlock against other NAND operations
[ Upstream commit bab2bc6 ] 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 1bfd188 commit f71ce0a

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
@@ -4868,11 +4868,16 @@ static void nand_shutdown(struct mtd_info *mtd)
48684868
static int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
48694869
{
48704870
struct nand_chip *chip = mtd_to_nand(mtd);
4871+
int ret;
48714872

48724873
if (!chip->ops.lock_area)
48734874
return -ENOTSUPP;
48744875

4875-
return chip->ops.lock_area(chip, ofs, len);
4876+
nand_get_device(chip);
4877+
ret = chip->ops.lock_area(chip, ofs, len);
4878+
nand_release_device(chip);
4879+
4880+
return ret;
48764881
}
48774882

48784883
/**
@@ -4884,11 +4889,16 @@ static int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
48844889
static int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
48854890
{
48864891
struct nand_chip *chip = mtd_to_nand(mtd);
4892+
int ret;
48874893

48884894
if (!chip->ops.unlock_area)
48894895
return -ENOTSUPP;
48904896

4891-
return chip->ops.unlock_area(chip, ofs, len);
4897+
nand_get_device(chip);
4898+
ret = chip->ops.unlock_area(chip, ofs, len);
4899+
nand_release_device(chip);
4900+
4901+
return ret;
48924902
}
48934903

48944904
/* Set default functions */

0 commit comments

Comments
 (0)